Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/bin/
/dist/
node_modules/
/man/src/prompt

.idea
.DS_Store
81 changes: 81 additions & 0 deletions man/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
BOOK := ../book/src
SHELL := /bin/bash

# Detect sed variant (macOS uses gsed from Homebrew)
SED := $(shell command -v gsed 2>/dev/null || echo sed)

.PHONY: all man clean

# Default: assemble prompt and call API if key is set
all: src/prompt
@if [ -z "$$ANTHROPIC_API_KEY" ]; then \
echo "ANTHROPIC_API_KEY is not set."; \
echo "Submit src/prompt to Claude manually, save the result as src/super.1.md,"; \
echo "then run: make man"; \
else \
$(MAKE) src/super.1.md && $(MAKE) man; \
fi

# Step 1: assemble the prompt
src/prompt: src/base-prompt \
src/extract-names.py \
$(BOOK)/command/super.md \
$(BOOK)/command/options.md \
$(BOOK)/command/input.md \
$(BOOK)/command/output.md \
$(BOOK)/command/formats.md \
$(BOOK)/getting-started/tldr.md \
$(BOOK)/command/db.md \
$(BOOK)/command/compile.md \
$(BOOK)/command/dev.md
@echo "Assembling prompt..."
@cp src/base-prompt src/prompt
@echo -e "\nThe \"super -h\" output:\n==============================" >> src/prompt
@super -h | $(SED) 's/\x1b\[[0-9;]*m//g' >> src/prompt
@for file in super.md options.md input.md output.md formats.md; do \
echo -e "\nContents of \"$$file\" from detailed mdbook documentation:" >> src/prompt; \
echo "================================================================" >> src/prompt; \
cat $(BOOK)/command/$$file >> src/prompt; \
done
@echo -e "\nSource material from detailed mdbook documentation for EXAMPLES in manpage:" >> src/prompt
@echo "================================================================" >> src/prompt
@cat $(BOOK)/getting-started/tldr.md >> src/prompt
@for file in db.md compile.md dev.md; do \
echo -e "\nFirst 50 lines of \"$$file\" from detailed mdbook documentation:" >> src/prompt; \
echo "================================================================" >> src/prompt; \
head -50 $(BOOK)/command/$$file >> src/prompt; \
done
@echo -e "\nOperator, aggregate function, and function names that should appear bold in man page text:" >> src/prompt
@echo "================================================================" >> src/prompt
@python3 src/extract-names.py >> src/prompt
@$(SED) -i "s/DATE_PLACEHOLDER/$$(date '+%B %Y')/" src/prompt
@echo "Done. src/prompt is ready."

# Step 2: call Claude API to generate src/super.1.md
src/super.1.md: src/prompt
@echo "Calling Claude API..."
@jq -n --rawfile content src/prompt '{ \
model: "claude-sonnet-4-6", \
max_tokens: 4096, \
temperature: 0, \
messages: [{ role: "user", content: $$content }] \
}' | curl -s https://api.anthropic.com/v1/messages \
--header "x-api-key: $$ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data @- \
| jq -r '.content[0].text' > src/super.1.md
@echo "Done. src/super.1.md is ready."

# Step 3: run pandoc
man: man1/super.1

man1/super.1: src/super.1.md
@echo "Generating super.1..."
@pandoc src/super.1.md -s -t man -o man1/super.1
@echo "Done. man1/super.1 is ready."

clean:
@rm -f src/prompt src/super.1.md man1/super.1
@git checkout src/super.1.md man1/super.1 2>/dev/null || true
@echo "Cleaned."
128 changes: 128 additions & 0 deletions man/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# super man page

This directory contains the `super(1)` man page and AI-assisted tooling used
to generate and maintain it.

## Directory layout

```
man/
Makefile # build and generation pipeline
man1/
super.1 # generated groff man page (installed or shipped in releases)
src/
base-prompt # prompt template for Claude
extract-names.py # extracts operator/function names from the mdbook for use in the prompt
super.1.md # pandoc markdown source for the man page (committed, human-reviewed)
prompt # assembled prompt (generated, not committed — see .gitignore)
```

## How it works

The man page is generated in three steps:

**Step 1 — Assemble the prompt.** `src/base-prompt` is combined with live
output from `super -h` and relevant sections of the mdbook documentation in
`../book/src/` to produce `src/prompt`. This assembled prompt is the complete
input to Claude.

**Step 2 — Generate the markdown.** The prompt is submitted to the Claude API,
which produces `src/super.1.md` — a pandoc-flavored markdown file structured
as a traditional man page. This file is committed to the repo and serves as the
human-reviewable source of truth.

**Step 3 — Render to groff.** `pandoc` converts `src/super.1.md` to
`man1/super.1`, the final groff-format man page suitable for installation or
inclusion in release artifacts.

## Usage

### Full pipeline (requires API key)

```sh
export ANTHROPIC_API_KEY=<your key>
make
```

This assembles the prompt, calls the Claude API to regenerate `src/super.1.md`,
and renders it to `man1/super.1`.

### Manual workflow (no API key)

```sh
make # assembles src/prompt, then stops with guidance
# submit src/prompt to Claude interactively
# save the response as src/super.1.md
make man # renders src/super.1.md to man1/super.1
```

### Prompt only

```sh
make src/prompt
```

Assembles the prompt without calling the API or running `pandoc`.

### Render only

```sh
make man
```

Runs `pandoc` on the existing `src/super.1.md` without regenerating it.
Useful after manually editing `src/super.1.md`.

### Preview locally

```sh
man man1/super.1
```

### Clean

```sh
make clean
```

Removes generated files (`src/prompt`, `src/super.1.md`, `man1/super.1`) and
restores the committed versions via `git checkout`.

## Dependencies

- `pandoc` — converts `src/super.1.md` to groff
- `jq` — builds the JSON request body for the API call
- `curl` — calls the Claude API
- `python3` — runs `src/extract-names.py`
- `gsed` (macOS) or `sed` (Linux) — auto-detected

## Workflow for updating the man page at release time

The man page should be regenerated whenever `super -h` output or the relevant
mdbook source files change. The recommended process is:

1. Run `make` with an API key set.
2. Review the diff of `src/super.1.md` against the previous committed version.
3. Distinguish material changes (new flags, changed defaults, updated
descriptions) from stylistic variations introduced by the model.
4. If the changes look correct, commit both `src/super.1.md` and
`man1/super.1`.
5. Include `man1/super.1` in the release artifact.

## Notes on the generation approach

The man page is generated by Claude from source material rather than
maintained entirely by hand. This keeps it in sync with `super -h` and the
mdbook documentation without requiring manual transcription of every flag and
default value.

Because language models are not fully deterministic, successive runs on
identical input may produce minor wording variations in prose sections. The
committed `src/super.1.md` serves as the stable reference — review the diff
after each regeneration and commit only when the changes are intentional or
clearly reflect source material updates.

The `src/base-prompt` file encodes the formatting conventions and constraints
that have been established for this man page. It should be updated if new
conventions are adopted or if recurring unwanted variations need to be
suppressed.
Loading
Loading