Files
sift/docs/plans/p5c/02-extract-cli.md

61 lines
2.4 KiB
Markdown

# P5c task 02: `sift extract <file.pdf>`
**Branch:** `p5c` (`git switch p5c`; `git status --short` must be empty, otherwise stop)
**Commit subject:** `cli: sift extract uploads a local PDF; README and skill`
## Goal
`sift extract thesis.pdf [--pages 41-60] [--grep RE] [--question Q] [--json]` uploads the file
to `/v1/extract` and prints the answer exactly as `sift fetch` does.
## Files
- Copy: `cmd/sift/extract_test.go`
- Create: `cmd/sift/extractcmd.go`
- Modify: `cmd/sift/main.go` (a `case "extract":` and one help line), `README.md`,
`skill/SKILL.md`, `docs/implementer-log.md`
## Interfaces
```go
package main
type extractOpts struct {
File, Pages, Grep, Question, Mode string
JSON bool
}
const extractUsage = "usage: sift extract <file.pdf> [--pages a-b] [--grep RE] [--question Q] [--mode clean|digest] [--json]"
func parseExtractOpts(args []string) (extractOpts, error) // flags before or after the file, as fetch
func extractURL(base string, o extractOpts) string // base + "/v1/extract?" + only the options that are set; mode=digest when Question is set and Mode is empty
```
## Rules
1. The command:
- Resolve the base URL and key exactly as `sift fetch` does (reuse its client-config helpers; do not copy them).
- `stat` the file: over 100 MiB → exit with a message before uploading.
- `POST` the bytes with `Content-Type: application/pdf` and the bearer key.
- Print `content` (or the whole envelope with `--json`), with the same errors and exit codes as fetch (`exitFor`).
- Do not read the whole file into memory twice: stream it with `os.Open` as the request body and set `ContentLength`.
2. **`README.md`:** a `sift extract` subsection next to `sift fetch`.
3. **`skill/SKILL.md`:** "A PDF on disk (an attachment, a download): `sift extract <file>`, with the same `--pages`/`--grep`/`--question`. Never run `pdftotext` yourself."
## Steps
- [ ] **1.** `git switch p5c`; copy the given test. **2. See it fail.**
- [ ] **3.** `extractcmd.go`, `main.go`, README, skill.
- [ ] **4.** `gofmt -w`; `go test -race -count=3 ./cmd/sift/` → `ok`. **5.** `make gate`.
- [ ] **6.** `make build && bin/sift extract 2>&1 | head -1` prints the usage line.
- [ ] **7.** Row `p5c/02-extract-cli`; commit.
```sh
git add cmd/sift README.md skill/SKILL.md docs/implementer-log.md
git commit -F .state/commit-msg.txt
```
## Done when
- All tests pass; `make gate` ok; given file byte-identical.