Skip to content

Commit 08b47f9

Browse files
srousseyclaude
andcommitted
refactor(cli-v2): remove old flat command files
All 14 old command files replaced by nested group structure in src/cli/groups/. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 72c3725 commit 08b47f9

19 files changed

Lines changed: 3367 additions & 411 deletions

SPEC.md

Lines changed: 959 additions & 0 deletions
Large diffs are not rendered by default.

bun.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
# @workglow/sec CLI v2 Design
2+
3+
A redesign of the SEC EDGAR CLI focused on ergonomics: guided workflows, logical command grouping, full query support, and rich interactive output.
4+
5+
## Design Goals
6+
7+
- **Three-command happy path:** `init` -> `bootstrap` -> `sync` covers 90% of use cases
8+
- **Progressive disclosure:** simple pipelines for most users, granular commands for power users
9+
- **Exploration-first queries:** search entities, filings, offerings, people directly from the CLI
10+
- **Rich feedback:** progress bars, spinners, colored tables when interactive; structured output when piped
11+
- **Scriptable:** `--json` flag, proper exit codes, stderr for errors
12+
13+
---
14+
15+
## 1. Command Hierarchy
16+
17+
```
18+
sec [--json] [--verbose] [--dry-run] [--no-color] [--concurrency <n>] <command>
19+
```
20+
21+
### 1.1 First-Run
22+
23+
```
24+
sec init
25+
```
26+
27+
Interactive wizard:
28+
1. Choose database type (SQLite or PostgreSQL)
29+
2. Configure database location/connection
30+
3. Configure raw data folder
31+
4. Write `.env.local`
32+
5. Create directories
33+
6. Run `db setup`
34+
35+
Detects existing `.env.local` and offers to reconfigure or skip. PostgreSQL path prompts for connection string or individual parameters. Validates database connectivity before writing config.
36+
37+
When `--json` is passed: outputs config as JSON, no interactivity (for scripting). Non-zero exit if any step fails.
38+
39+
### 1.2 Pipeline Commands
40+
41+
#### `sec bootstrap`
42+
43+
Runs the full initial load pipeline:
44+
45+
| Phase | Description |
46+
|-------|-------------|
47+
| 1. Download | `submissions.zip`, `companyfacts.zip`, `cik-lookup-data.txt` |
48+
| 2. Ingest | CIK names, submissions, company facts |
49+
| 3. Process forms | Form D, Form C, Form 1-A |
50+
51+
Flags:
52+
- `--skip-download` — skip phase 1 (use pre-downloaded files)
53+
- `--skip-ingest` — skip phase 2
54+
- `--skip-forms` — skip phase 3
55+
56+
Resumes automatically — skips already-processed CIKs. Graceful Ctrl+C saves progress.
57+
58+
#### `sec sync`
59+
60+
Smart incremental update — the daily command:
61+
62+
1. Fetches daily index
63+
2. Updates stale submissions
64+
3. Updates stale company facts
65+
4. Processes new form filings
66+
67+
Flags:
68+
- `--forms D,C,1-A` — limit form processing to specific types
69+
70+
If bootstrap hasn't been run, prints: `Database is empty. Run 'sec bootstrap' first.`
71+
72+
Idempotent — safe to run multiple times per day.
73+
74+
### 1.3 Bootstrap (Granular)
75+
76+
```
77+
sec bootstrap download <type> # submissions | facts | ciks | all
78+
sec bootstrap ingest [domain] # submissions | facts | cik-names | all (default)
79+
```
80+
81+
### 1.4 Update (Granular)
82+
83+
```
84+
sec update submissions [--concurrency <n>]
85+
sec update facts [--concurrency <n>]
86+
sec update forms <types> [--concurrency <n>] # comma-separated: D,C,1-A
87+
```
88+
89+
### 1.5 Fetch (Single Entity)
90+
91+
Ad-hoc commands for pulling data for one specific entity:
92+
93+
```
94+
sec fetch submissions <cik>
95+
sec fetch facts <cik>
96+
sec fetch form <cik> <form> [accession]
97+
sec fetch doc <accession> [filename]
98+
```
99+
100+
Works whether or not bootstrap has been run. Respects SEC rate limits (10 req/s with exponential backoff).
101+
102+
### 1.6 Query
103+
104+
All query commands support `--format table|csv|json` (default: `table`), `--limit <n>` (default: 25), `--offset <n>`, and `--sort <field>`.
105+
106+
#### `sec query entities [search]`
107+
108+
Search and list SEC-registered entities.
109+
110+
| Option | Description |
111+
|--------|-------------|
112+
| `--cik <cik>` | Exact CIK lookup (shows full detail view) |
113+
| `--sic <code>` | Filter by SIC code |
114+
| `--state <state>` | Filter by state of incorporation |
115+
116+
Free-text `[search]` matches against entity name. Filters are combinable.
117+
118+
Single-entity detail view when `--cik` returns one result: shows full entity metadata, tickers, addresses, phones, filing count, and fact count.
119+
120+
#### `sec query filings [search]`
121+
122+
Search filing records.
123+
124+
| Option | Description |
125+
|--------|-------------|
126+
| `--cik <cik>` | Filter by entity |
127+
| `--form <type>` | Filter by form type |
128+
| `--after <date>` | Filed on or after date |
129+
| `--before <date>` | Filed on or before date |
130+
131+
Free-text `[search]` matches against primary doc description.
132+
133+
#### `sec query offerings [search]`
134+
135+
Search Form D investment offerings.
136+
137+
| Option | Description |
138+
|--------|-------------|
139+
| `--cik <cik>` | Filter by issuer |
140+
| `--industry <group>` | Filter by industry group |
141+
| `--exemption <type>` | Filter by federal exemption |
142+
| `--after <date>` | First sale on or after date |
143+
| `--before <date>` | First sale on or before date |
144+
145+
#### `sec query crowdfunding [search]`
146+
147+
Search Form C crowdfunding offerings.
148+
149+
| Option | Description |
150+
|--------|-------------|
151+
| `--cik <cik>` | Filter by issuer |
152+
| `--portal <name>` | Filter by funding portal |
153+
| `--after <date>` | Filed on or after date |
154+
| `--before <date>` | Filed on or before date |
155+
156+
#### `sec query facts <cik>`
157+
158+
XBRL financial facts for a specific company.
159+
160+
| Option | Description |
161+
|--------|-------------|
162+
| `--name <fact-name>` | Filter by fact name |
163+
| `--taxonomy <group>` | Filter by taxonomy (us-gaap, dei, etc.) |
164+
| `--year <fy>` | Filter by fiscal year |
165+
166+
#### `sec query persons [search]`
167+
168+
Search people extracted from form filings.
169+
170+
| Option | Description |
171+
|--------|-------------|
172+
| `--cik <cik>` | Filter by related entity |
173+
| `--role <role>` | Filter by role (director, officer, promoter) |
174+
175+
### 1.7 Database Management
176+
177+
```
178+
sec db status # summary: db size, data freshness, staleness counts, last sync
179+
sec db stats # per-table row counts and sizes
180+
sec db setup # create/migrate tables (called automatically by init)
181+
sec db reset # drop and recreate (requires --confirm or interactive prompt)
182+
```
183+
184+
---
185+
186+
## 2. Output Behavior
187+
188+
### 2.1 TTY Detection
189+
190+
When stdout is a TTY:
191+
- Progress bars, spinners, colored tables with box drawing
192+
- Interactive prompts (init, db reset)
193+
194+
When piped or not a TTY:
195+
- No spinners or progress bars
196+
- Plain text tables
197+
- Prompts become errors: `Error: --confirm required when not interactive`
198+
199+
### 2.2 Global Flag Interactions
200+
201+
| Flags | stdout | stderr |
202+
|-------|--------|--------|
203+
| (none) | Rich output | Errors only |
204+
| `--json` | Structured JSON | Nothing |
205+
| `--verbose` | Rich output with detail | Nothing |
206+
| `--json --verbose` | Structured JSON | Verbose logs |
207+
208+
### 2.3 Query Output Formats
209+
210+
**Table** (default): Auto-sizes to terminal width, truncates long fields with `...`.
211+
212+
**JSON**: Array of objects.
213+
214+
**CSV**: Header row + data rows, proper quoting.
215+
216+
### 2.4 Pagination
217+
218+
All list queries show total count in footer:
219+
```
220+
Showing 1-25 of 1,247 results (use --offset 25 for next page)
221+
```
222+
223+
---
224+
225+
## 3. Error Handling
226+
227+
### 3.1 Exit Codes
228+
229+
| Code | Meaning |
230+
|------|---------|
231+
| 0 | Success |
232+
| 1 | Error (bad input, network failure, database error) |
233+
| 2 | Partial failure (some items in batch failed, others succeeded) |
234+
235+
### 3.2 Error Output
236+
237+
Errors always go to stderr.
238+
239+
Normal mode:
240+
```
241+
x Failed to fetch submissions for CIK 1318605: HTTP 429 Too Many Requests
242+
3 of 328 CIKs failed. Passing results were saved.
243+
Re-run 'sec sync' to retry failed items.
244+
```
245+
246+
JSON mode:
247+
```json
248+
{ "error": "Failed to fetch submissions", "cik": 1318605, "cause": "HTTP 429 Too Many Requests" }
249+
```
250+
251+
### 3.3 Ctrl+C Handling
252+
253+
Long-running commands handle SIGINT gracefully:
254+
1. Finish the current item in progress
255+
2. Save all completed work
256+
3. Print summary of progress
257+
4. Exit with code 2
258+
259+
---
260+
261+
## 4. Command Migration from v1
262+
263+
| v1 Command | v2 Equivalent |
264+
|------------|---------------|
265+
| `setup-db` | `sec db setup` (or automatic via `sec init`) |
266+
| `bootstrap-download <type>` | `sec bootstrap download <type>` |
267+
| `bootstrap-all-cik-names` | `sec bootstrap ingest cik-names` |
268+
| `bootstrap-cik-last-update` | Absorbed into `sec bootstrap` and `sec sync` |
269+
| `bootstrap-submissions` | `sec bootstrap ingest submissions` |
270+
| `bootstrap-company-facts` | `sec bootstrap ingest facts` |
271+
| `submissions <cik>` | `sec fetch submissions <cik>` |
272+
| `company-facts <cik>` | `sec fetch facts <cik>` |
273+
| `daily-index [date]` | Absorbed into `sec sync` |
274+
| `form <cik> <form> [docid]` | `sec fetch form <cik> <form> [accession]` |
275+
| `doc <docid> [fileName]` | `sec fetch doc <accession> [filename]` |
276+
| `update-all-submissions` | `sec update submissions` |
277+
| `update-all-company-facts` | `sec update facts` |
278+
| `update-all-forms <form>` | `sec update forms <types>` |
279+
| _(new)_ | `sec init` |
280+
| _(new)_ | `sec bootstrap` (full pipeline) |
281+
| _(new)_ | `sec sync` |
282+
| _(new)_ | `sec query *` |
283+
| _(new)_ | `sec db status`, `sec db stats`, `sec db reset` |

0 commit comments

Comments
 (0)