Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

table-skill

A Claude Code skill that makes tables in agent replies actually readable.

The problem

Ask an agent for a table and you get markdown table syntax. The terminal — not the agent — decides the layout, and it knows nothing about the intended columns. One long cell refolds a row, the alignment collapses, and you get this:

| Library | Auto-fit | Wraps cells | Notes |
|---|---|---|---|
| rich.table | yes | yes | Computes column widths against a Console(width=N) budget and folds long cells itself. |
| tabulate | no | with maxcolwidths | Caller must compute per-column widths; tablefmt picks the box style. |

...which is exactly when a table is least useful, since the whole point was to let your eye run down a column.

What it does

scripts/table.py lays the table out itself, against the real width of your terminal, and emits finished plain text that the agent pastes into a fenced code block. Code blocks aren't refolded, so what you see is what was computed:

┏━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Library     ┃ Auto-fit ┃ Wraps cells       ┃ Notes                                       ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ rich.table  │ yes      │ yes               │ Computes column widths against a            │
│             │          │                   │ Console(width=N) budget and folds long      │
│             │          │                   │ cells itself.                               │
├─────────────┼──────────┼───────────────────┼─────────────────────────────────────────────┤
│ tabulate    │ no       │ with maxcolwidths │ Caller must compute per-column widths.      │
└─────────────┴──────────┴───────────────────┴─────────────────────────────────────────────┘

Beyond that:

  • Auto-detects input — JSON (object or array of records), an existing markdown table, TSV, or CSV. Piping a broken table back in reflows it.
  • Right-aligns numeric columns automatically.
  • Degrades honestly. A table only works if every column can hold its longest word unbroken. Past that it transposes (few rows) or falls back to one labelled block per row, rather than shredding columns into three-character stumps.
  • Links in cells. Write [label](url) and the terminal shows label while the HTML page hyperlinks it. Only http/https/file/mailto become link targets; anything else stays literal text.
  • Escapes to a browser on its own. Past 10 rows or 5 columns — where no terminal does a table justice — it also writes a self-contained sortable page and prints a file:// link on stderr. --html forces one for a smaller table, --no-html suppresses it.

Install

git clone git@github.com:dgutson/table-skill.git ~/src/table-skill
ln -s ~/src/table-skill ~/.claude/skills/table

New Claude Code sessions pick it up automatically; run /reload-plugins in an existing one. Requires uv — dependencies are declared inline (PEP 723) and fetched per-script, so nothing is installed into your system Python.

The interesting part: finding the terminal width

An agent's shell has no controlling terminal, so tput cols and $COLUMNS report a fallback (usually 80) rather than your actual window. Trusting it silently squeezes every table — on the author's 141-column terminal, to 57% of the screen.

The terminal is still reachable, just not from the shell: an ancestor process (the CLI itself) holds it open. So the script walks up /proc/<pid>/status, finds the first pty among an ancestor's stdio descriptors, and asks it directly with a TIOCGWINSZ ioctl.

A margin is then held back, because the reply area is narrower than the terminal. That margin is measured, not guessed — --ruler prints test lines to paste into a reply, and the widest one that doesn't fold gives the true width. Recalibrate it on your own terminal; the shipped default was measured on the author's.

Notes

Rendering is pure script — no model call, so a table costs the conversation only the data itself, and there is no inference to tune.

HTML pages are written to ~/claude-tables/ rather than /tmp on purpose: a snap-packaged browser gets a private /tmp, so a page written to the host /tmp exists on disk while the browser insists it doesn't. Set CLAUDE_TABLE_DIR to move it, but not to /tmp or a dot-directory.

references/options.md documents every flag; dev/ holds the bakeoff scripts that chose rich over tabulate, prettytable and textual.

About

A Claude Code skill that renders agent tables as width-fitted plain text, so columns stay aligned instead of collapsing when the terminal refolds a long row.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages