Skip to content

feat: add --description-file and stdin input for long bodies - #47

Closed
seraph-pixelperfect wants to merge 1 commit into
feat/sub-issuesfrom
feat/description-file
Closed

seraph-pixelperfect wants to merge 1 commit into
feat/sub-issuesfrom
feat/description-file

Conversation

@seraph-pixelperfect

Copy link
Copy Markdown
Collaborator

Closes #28
Depends on #46

What

--description-file <path> on issue create and issue update, mirroring the existing --body-file on comment — plus - to read the description from stdin to EOF (new capability, file case only on --body-file). Long markdown bodies without shell-quoting hazards.

  • src/commands/issue.ts: flag added to CREATE_FLAGS/UPDATE_FLAGS; shared readDescriptionInput guard (mutual exclusion with --description using comment's "Pass only one of…" convention, blank-value guard); exported readDescriptionFile(path, read?) reader — a UTF-8 file path, or - mapped to fd 0 (readFileSync(0, 'utf-8')). Both flags absent → field omitted exactly as before.
  • All guards + the read run before any network request.
  • test/description-file.test.ts: 17 new tests (create/update content lands in mutation variables, stdin end-to-end for both subcommands, mutual exclusion, unreadable path, empty file, blank value, default-unchanged, reader semantics, help).
  • Parent-stack test expectations updated for the new flag in the usage lines (2 one-line assertion strings).

Demo (real CLI, fake key — proves the flag parses and the file is read; content transport is proven by the stubbed tests)

$ printf 'Long **markdown** body\nwith a second line\n' > /tmp/demo-desc.md
$ pnpm exec tsx bin/linear-axi.ts issue create --title "Demo title" --team LIN --description-file /tmp/demo-desc.md --key lin_api_fake
error: Linear auth required — set LINEAR_API_KEY or pass --key <key>
code: AUTH_REQUIRED
help[2]: "Create a personal API key at https://linear.app/settings/api",Then export LINEAR_API_KEY=<key> or run with --key <key>
EXIT:1
$ echo 'from stdin, with "quotes" and line
breaks' | pnpm exec tsx bin/linear-axi.ts issue create --title "Stdin demo" --team LIN --description-file - --key lin_api_fake
error: Linear auth required — set LINEAR_API_KEY or pass --key <key>
code: AUTH_REQUIRED
help[2]: "Create a personal API key at https://linear.app/settings/api",Then export LINEAR_API_KEY=<key> or run with --key <key>
EXIT:1

(AUTH_REQUIRED is the fake key at the API layer — the flag was accepted, the file/stdin was read, and the request was attempted. Same for issue update LIN-123 --description-file /tmp/demo-desc.md.)

Loud guards (all fail before any network request, exit 2):

$ pnpm exec tsx bin/linear-axi.ts issue update LIN-123 --description "inline" --description-file /tmp/demo-desc.md --key lin_api_fake
error: Pass only one of --description or --description-file
code: VALIDATION_ERROR
EXIT:2

$ pnpm exec tsx bin/linear-axi.ts issue create --title t --team LIN --description-file /tmp/does-not-exist.md --key lin_api_fake
error: "Could not read --description-file: /tmp/does-not-exist.md"
code: VALIDATION_ERROR
EXIT:2

$ printf '' > /tmp/empty-desc.md
$ pnpm exec tsx bin/linear-axi.ts issue create --title t --team LIN --description-file /tmp/empty-desc.md --key lin_api_fake
error: "--description-file is empty: /tmp/empty-desc.md"
code: VALIDATION_ERROR
help[1]: "Pass a non-empty UTF-8 file or pipe stdin (\"-\")"
EXIT:2

Local gates (all run against the pushed commit)

$ pnpm build          # tsc — clean
$ pnpm lint           # eslint — clean, no output
$ pnpm run build:skill -- --check
skills/linear-axi/SKILL.md is up to date.
$ pnpm test
 Test Files  17 passed (17)
      Tests  200 passed (200)     # was 183 on the base of this stack; +17 new
$ pnpm exec prettier --check test/description-file.test.ts
All matched files use Prettier code style!

pnpm run format:check still flags the pre-existing set of 18 files (identical to the base branch; CI does not run it). skills/linear-axi/SKILL.md needed no regen — it derives from TOP_HELP, which this change does not touch; --check confirms.

Stacked-PR note

Stacked on #46 (feat/sub-issues); stack: #37→#38→#39→#40→#41→#42→#43→#44→#45→#46→this PR. No CI checks appear because ci.yml only triggers on PRs targeting main. CI runs when retargeted to main after the stack merges; local gates above are the evidence. Not retargeting.

CI caveat: if checks do appear and fail fast (~3-4s, empty steps), that pattern indicates a billing/spending-limit rejection rather than a code failure — gh run view <run-id> would show the billing annotation.

Flagged decisions (review attention)

  • Empty input policy: an empty or whitespace-only file/stdin is rejected loud (--description-file is empty: <path>, VALIDATION_ERROR) rather than accepted as "". Rationale: on update, a silently-empty description would wipe the field — a destructive no-op. Inline --description "" keeps its pre-existing pass-through behavior (out of scope here).
  • stdin scope: - works on --description-file only. The issue claims stdin for --description-file; comment's --body-file was left untouched to keep this PR minimal. Follow-up candidate: extend - to comment --body-file (and reuse this reader) for consistency.
  • Reader testability: readDescriptionFile(path, read?) takes an injectable raw-read function (default readFileSync utf-8, which serves both a path and a numeric fd). Tests demonstrate -→fd 0 two ways: reader-level with an injected read asserting read(0), and command-level with node:fs mocked so fd 0 serves fixed content — no real stdin dependence, no network.

Identity

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

@ghostinprod-pixelperfect

Copy link
Copy Markdown
Collaborator

Superseded by merged rc/0.2 PR #52 (commit ad6b141), which consolidated this write/transport 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