Files
pad/internal/cli
David Barkhausen b9381bf5f1 feat(cli): markdown output on the remaining list surfaces; broaden ANSI stripping (#1080)
Completes #898 and fixes #1076.

Markdown on the seven surfaces left out of #1070, so `--format markdown` is now
honestly global and the flag help collapses to "table, json, markdown":

- `item comments`, `item deps`, `project activity`, `attachment list`,
  `library list`, `role list`, `workspace members`.

Two of those are not tabular, and markdown follows the terminal shape rather
than forcing a table onto them:

- `item comments` keeps the attribution-line-then-body form, and the body is
  emitted VERBATIM. A comment body is authored as markdown; escaping it would
  turn its lists and code fences into literal text. Only the attribution line,
  which we construct, is sanitized.
- `item deps` keeps its two sections as `## Blocks` / `## Blocked by` lists.
  Colour carried the direction in the terminal (yellow out, red in); headings
  carry it here.

New shared spine: `cli.RenderMarkdownTable(w, headers, rows)`. Every cell is
escaped, and ragged rows are padded or truncated to the header width so a short
or long row can't shift the column count and break the table. Wiring a surface
is now naming columns and mapping rows.

#1076 — ANSI stripping covered only SGR (`ESC[…m`), so non-SGR CSI sequences,
OSC-8 hyperlinks, and stray C0 controls survived, both in the table width maths
and in markdown output whose doc comment promised escape-free text. Replaced
`sgrPattern` with `ansiPattern` + `stripANSI` covering OSC, CSI, two-character
Fe escapes, and stray C0/DEL, with TAB/LF/CR deliberately preserved for callers
that normalize them. `displayWidth` now uses it too: a control sequence is
zero-width, so counting it was a column-alignment bug of the same family.

Tests: 12 stripping cases, 4 table-helper cases (including ragged rows), 4
renderer cases for the two non-tabular surfaces, and the routing test extended
to 8 subtests — one per surface, driven through cobra against an httptest
server. Also covers the two gaps named in #1076: `item starred` and the scoped
`item list <collection>` path. Each new guard was proven by mutating the source
and watching it fail, not just by passing.

Gates: go build ./... PASS; go vet PASS; gofmt clean; golangci-lint 0 issues.
Both touched packages show the same 6+2 pre-existing Windows failures as clean
main under an identical sandboxed run.
2026-08-14 22:35:23 -04:00
..
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00