dotdotdot-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,707 @@
1
+ <h1 align="center">
2
+ <br>
3
+ <code>...</code>
4
+ <br>
5
+ </h1>
6
+
7
+ <p align="center">
8
+ <code>npm install -g dotdotdot</code>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/dotdotdot"><img src="https://img.shields.io/npm/v/dotdotdot?color=blue&label=npm" alt="npm version" /></a>
13
+ <img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="zero dependencies" />
14
+ <img src="https://img.shields.io/badge/node-%3E%3D18-green" alt="node version" />
15
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="license" />
16
+ <img src="https://img.shields.io/badge/windows%20%7C%20macos%20%7C%20linux-supported-lightgrey" alt="platforms" />
17
+ </p>
18
+
19
+ <br>
20
+
21
+ <p align="center">
22
+ You know what you want. You just don't know the command.
23
+ <br>
24
+ <code>...</code> takes plain English and gives you the exact terminal command for your OS, your shell, your setup. Execute it, copy it, or just look at it. Nothing runs without your say-so.
25
+ </p>
26
+
27
+ <br>
28
+
29
+ **Quick mode** &mdash; say it, get it
30
+
31
+ ```bash
32
+ ... show my public IP
33
+ ... find all files over 100MB
34
+ ... undo my last git commit
35
+ ... what's eating my RAM
36
+ ```
37
+
38
+ <p align="center">
39
+ <img src="demo/quick.gif" alt="dotdotdot quick mode demo" width="700" />
40
+ </p>
41
+
42
+ **Task mode** &mdash; chain steps together
43
+
44
+ ```bash
45
+ ... find all .tmp files then delete them
46
+ ... check node version, scaffold a new app
47
+ ... build the project then deploy to staging
48
+ ... ping popular DNS and show the fastest
49
+ ```
50
+
51
+ <p align="center">
52
+ <img src="demo/task.gif" alt="dotdotdot task mode demo" width="700" />
53
+ </p>
54
+
55
+ <br>
56
+
57
+ ---
58
+
59
+ ## Setup
60
+
61
+ ```bash
62
+ npm install -g dotdotdot
63
+ ... -c # add your API key (you need at least one)
64
+ ... show my disk usage
65
+ ```
66
+
67
+ <details>
68
+ <summary><strong>Or use environment variables</strong></summary>
69
+
70
+ ```bash
71
+ export DOT_OPENROUTER_KEY=sk-or-...
72
+ export DOT_ANTHROPIC_KEY=sk-ant-...
73
+ export DOT_OPENAI_KEY=sk-...
74
+ export DOT_GOOGLE_KEY=AIza...
75
+ export DOT_CUSTOM_KEY=sk-...
76
+ ```
77
+ </details>
78
+
79
+ ---
80
+
81
+ ## Contents
82
+
83
+ - [How It Works](#how-it-works)
84
+ - [Quick Mode](#quick-mode)
85
+ - [Task Mode](#task-mode)
86
+ - [Examples](#examples)
87
+ - [Context Awareness](#context-awareness)
88
+ - [Session Memory](#session-memory)
89
+ - [Safety](#safety)
90
+ - [Providers](#providers)
91
+ - [Token Tracking & Cost](#token-tracking--cost)
92
+ - [Flags](#flags)
93
+ - [Config](#config)
94
+ - [Shell Aliases](#shell-aliases)
95
+ - [Why `...`](#why-)
96
+ - [Project Structure](#project-structure)
97
+
98
+ ---
99
+
100
+ ## How It Works
101
+
102
+ ```
103
+ you type something in plain english
104
+
105
+ ... gathers context ─── OS, shell, cwd, git, tools, project info
106
+
107
+ sends it to your chosen LLM
108
+
109
+ you get back a command (or a multi-step plan)
110
+
111
+ you decide: execute ─ copy ─ skip
112
+ ```
113
+
114
+ You always choose. `...` never runs anything behind your back.
115
+
116
+ ---
117
+
118
+ ## Quick Mode
119
+
120
+ One request. One command. The right one.
121
+
122
+ ```bash
123
+ ... compress this folder into a zip
124
+ ... show running docker containers
125
+ ... make a new react project called my-app
126
+ ... list all open ports
127
+ ... what version of python do I have
128
+ ```
129
+
130
+ You pick what happens:
131
+
132
+ | Key | Action |
133
+ |:---:|--------|
134
+ | **e** | Execute the command |
135
+ | **c** | Copy to clipboard |
136
+ | **i** | Insert (print to stdout) |
137
+ | **q** | Cancel |
138
+
139
+ ---
140
+
141
+ ## Task Mode
142
+
143
+ Chain actions with `-t`, or just use natural words like *"then"*, *"and"*, or commas.
144
+ `...` breaks it into steps, shows you the full plan, and runs them one at a time.
145
+
146
+ ```bash
147
+ ... find all .tmp files then delete them
148
+ ... read my desktop files and propose a new organization
149
+ ... locate project my-site, install deps, then start dev server
150
+ ```
151
+
152
+ Before anything executes, you see everything. You can:
153
+ - **Run all** at once
154
+ - Go **step by step**
155
+ - **Skip** or **abort** any step
156
+ - **Retry** if something fails
157
+
158
+ Dangerous steps always pause and ask first.
159
+
160
+ ---
161
+
162
+ ## Examples
163
+
164
+ Real terminal sessions. Debug mode (`-d`) shows timing, provider, and token cost.
165
+
166
+ ### Quick Mode
167
+
168
+ <table><tr><td><strong>List files in the current directory</strong></td></tr></table>
169
+
170
+ <details>
171
+ <summary>Session</summary>
172
+
173
+ ```
174
+ $ ... -d list files
175
+ ✔ ctx 688ms | openrouter/google/gemma-4-31b-it | mode: quick
176
+ ✔ done
177
+
178
+ ❯ Get-ChildItem -Path .
179
+ Lists all files and directories in the current working directory.
180
+ ✔ Execute
181
+
182
+ Directory: C:\Users\you\Projects\my-app
183
+
184
+ Mode LastWriteTime Length Name
185
+ ---- ------------- ------ ----
186
+ d----- 4/4/2026 4:22 PM src
187
+ d----- 4/4/2026 4:22 PM node_modules
188
+ -a---- 4/4/2026 3:17 PM 1157 package.json
189
+ -a---- 4/4/2026 5:38 PM 14098 README.md
190
+
191
+ tokens: 711 in 43 out (754 total) ~$0.000117
192
+ ✔ exit 0
193
+ ```
194
+ </details>
195
+
196
+ ---
197
+
198
+ <table><tr><td><strong>What's my public IP address?</strong></td></tr></table>
199
+
200
+ <details>
201
+ <summary>Session</summary>
202
+
203
+ ```
204
+ $ ... -d what is my public ip address
205
+ ✔ ctx 209ms | openrouter/google/gemma-4-31b-it | mode: quick
206
+ ✔ done
207
+
208
+ ❯ (Invoke-RestMethod -Uri 'https://api.ipify.org').Trim()
209
+ Uses Invoke-RestMethod to query the ipify API and retrieve the public IP address.
210
+ ✔ Execute
211
+
212
+ 203.0.113.42
213
+
214
+ tokens: 715 in 57 out (772 total) ~$0.000123
215
+ ✔ exit 0
216
+ ```
217
+ </details>
218
+
219
+ ---
220
+
221
+ <table><tr><td><strong>Show disk usage</strong></td></tr></table>
222
+
223
+ <details>
224
+ <summary>Session</summary>
225
+
226
+ ```
227
+ $ ... -d show me the disk usage
228
+ ✔ ctx 211ms | openrouter/google/gemma-4-31b-it | mode: quick
229
+ ✔ done
230
+
231
+ ❯ Get-PSDrive C | Select-Object Name, @{Name='Used(GB)';Expression={...}}, ...
232
+ Retrieves disk usage statistics for the C drive, converting bytes to
233
+ gigabytes and rounding to two decimal places.
234
+ ✔ Execute
235
+
236
+ Name Used(GB) Free(GB) Total(GB)
237
+ ---- -------- -------- ---------
238
+ C 256.36 218.36 474.72
239
+
240
+ tokens: 714 in 135 out (849 total) ~$0.000154
241
+ ✔ exit 0
242
+ ```
243
+ </details>
244
+
245
+ ---
246
+
247
+ ### Task Mode
248
+
249
+ <table><tr><td><strong>Find the fastest DNS provider</strong></td></tr></table>
250
+
251
+ <details>
252
+ <summary>Session</summary>
253
+
254
+ ```
255
+ $ ... -d -t find the best dns provider by pinging popular ones and show me the fastest
256
+ ✔ ctx 213ms | openrouter/google/gemma-4-31b-it | mode: task
257
+ ✔ 1 steps planned | tokens: 837 in 256 out (1.1k total) ~$0.000220
258
+ Pings Google, Cloudflare, OpenDNS, and Quad9 to determine the fastest DNS provider.
259
+
260
+ ─ 1. Ping DNS providers and sort by response time
261
+ $ $dns = @{ 'Google'='8.8.8.8'; 'Cloudflare'='1.1.1.1'; 'OpenDNS'=...
262
+
263
+ ✔ Run
264
+
265
+ ▶ 1/1 Ping DNS providers and sort by response time
266
+ $ $dns = @{ 'Google'='8.8.8.8'; 'Cloudflare'='1.1.1.1'; 'OpenDNS'='208.67.222.222'; ...
267
+
268
+ Provider IP AvgResponse
269
+ -------- -- -----------
270
+ Cloudflare 1.1.1.1 20
271
+ Quad9 9.9.9.9 35.5
272
+ OpenDNS 208.67.222.222 47.5
273
+ Google 8.8.8.8 80.5
274
+
275
+ ✔ exit 0
276
+ ✔ 1/1 done
277
+ ```
278
+ </details>
279
+
280
+ ---
281
+
282
+ <table><tr><td><strong>Check Node version, then scaffold a new project</strong></td></tr></table>
283
+
284
+ <details>
285
+ <summary>Session</summary>
286
+
287
+ ```
288
+ $ ... -d check my node version, then create a new folder called test-app and initialize a new npm project in it
289
+ ✔ ctx 214ms | openrouter/google/gemma-4-31b-it | mode: task
290
+ ✔ 2 steps planned | tokens: 844 in 173 out (1.0k total) ~$0.000187
291
+ Checks the Node.js version and initializes a new npm project in 'test-app'.
292
+
293
+ ─ 1. Check Node.js version
294
+ $ node -v
295
+ ─ 2. Create folder and initialize npm project
296
+ $ New-Item -ItemType Directory -Name 'test-app'; Set-Location -Path 'test-app'; npm init -y
297
+
298
+ ✔ Run
299
+
300
+ ▶ 1/2 Check Node.js version
301
+ $ node -v
302
+ v22.0.0
303
+ ✔ exit 0
304
+
305
+ ▶ 2/2 Create folder and initialize npm project
306
+ $ New-Item -ItemType Directory -Name 'test-app'; Set-Location -Path 'test-app'; npm init -y
307
+
308
+ Wrote to C:\Users\you\Projects\test-app\package.json:
309
+ {
310
+ "name": "test-app",
311
+ "version": "1.0.0",
312
+ ...
313
+ }
314
+
315
+ ✔ exit 0
316
+ ✔ 2/2 done
317
+ ```
318
+ </details>
319
+
320
+ ---
321
+
322
+ <table><tr><td><strong>System diagnostics with Claude &mdash; top CPU and memory hogs</strong></td></tr></table>
323
+
324
+ <details>
325
+ <summary>Session</summary>
326
+
327
+ ```
328
+ $ ... -d -p claude show me the top 5 processes using the most CPU, then show the top 5 using the most memory
329
+ ✔ ctx 209ms | anthropic/claude-haiku-4-5 | mode: task
330
+ ✔ 2 steps planned | tokens: 869 in 287 out (1.2k total) ~$0.002304
331
+ Display top 5 CPU-consuming and top 5 memory-consuming processes.
332
+
333
+ ─ 1. Get top 5 processes by CPU usage
334
+ $ Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 5 ...
335
+ ─ 2. Get top 5 processes by memory usage
336
+ $ Get-Process | Sort-Object -Property WorkingSet -Descending | Select-Object -First 5 ...
337
+
338
+ ✔ Run
339
+
340
+ ▶ 1/2 Get top 5 processes by CPU usage
341
+ $ Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 5 ...
342
+
343
+ Name CPU MemoryMB
344
+ ---- --- --------
345
+ Code 2519.78125 1118.19
346
+ Code 1688.984375 191.6
347
+ RemotePCViewerUI 1034.375 54.03
348
+ Code 582.546875 333.34
349
+ Cursor 559.28125 435.31
350
+
351
+ ✔ exit 0
352
+
353
+ ▶ 2/2 Get top 5 processes by memory usage
354
+ $ Get-Process | Sort-Object -Property WorkingSet -Descending | Select-Object -First 5 ...
355
+
356
+ Name MemoryMB CPU
357
+ ---- -------- ---
358
+ Memory Compression 1654.66
359
+ Code 1117.14 2520.31
360
+ kilo 697.46 241.05
361
+ chrome 629.8 339.38
362
+ Cursor 435.32 559.28
363
+
364
+ ✔ exit 0
365
+ ✔ 2/2 done
366
+ ```
367
+ </details>
368
+
369
+ ---
370
+
371
+ <table><tr><td><strong>Git branch cleanup &mdash; find merged branches and delete stale ones</strong></td></tr></table>
372
+
373
+ <details>
374
+ <summary>Session</summary>
375
+
376
+ ```
377
+ $ ... -d -p claude find all merged git branches, show them, then delete the stale ones
378
+ ✔ ctx 48ms | anthropic/claude-haiku-4-5 | mode: task
379
+ ✔ 3 steps planned | tokens: 853 in 397 out (1.3k total) ~$0.002838
380
+ Identify merged branches, list them with last commit info, then clean up.
381
+
382
+ ─ 1. List all branches merged into main with last commit date
383
+ $ git for-each-ref --merged=main --format='%(refname:short) %(committerdate:short) ...
384
+ ─ 2. Count how many stale branches will be removed
385
+ $ git branch --merged main | Select-String -NotMatch -Pattern '^\s*[*+]|^\s*(main|master)$' ...
386
+ ! 3. Delete all merged branches except main/master
387
+ $ git branch --merged main | Select-String -NotMatch -Pattern '^\s*[*+]|^\s*(main|master)$' ...
388
+
389
+ ✔ Run
390
+
391
+ ▶ 1/3 List all branches merged into main with last commit date
392
+ $ git for-each-ref --merged=main --format='%(refname:short) %(committerdate:short) %(subject)' refs/heads/
393
+
394
+ feature/dark-mode 2024-08-12 feat: add dark mode toggle
395
+ fix/login-redirect 2024-11-03 fix: redirect loop on expired session
396
+ chore/deps-update 2025-01-19 chore: bump dependencies
397
+ feature/user-export 2025-03-28 feat: csv export for user data
398
+
399
+ ▶ 2/3 Count how many stale branches will be removed
400
+ $ git branch --merged main | Select-String -NotMatch ... | Measure-Object
401
+
402
+ 4
403
+
404
+ ▶ 3/3 Delete all merged branches except main/master
405
+ $ git branch --merged main | Select-String -NotMatch ... | ForEach-Object { git branch -d $_.Trim() }
406
+
407
+ Deleted branch feature/dark-mode (was a3f291c).
408
+ Deleted branch fix/login-redirect (was 88d0e4f).
409
+ Deleted branch chore/deps-update (was c41b7a2).
410
+ Deleted branch feature/user-export (was 1f9d3bb).
411
+
412
+ ✔ 3/3 done
413
+ ```
414
+ </details>
415
+
416
+ ---
417
+
418
+ <table><tr><td><strong>Check system uptime, then show free memory</strong></td></tr></table>
419
+
420
+ <details>
421
+ <summary>Session</summary>
422
+
423
+ ```
424
+ $ ... -d show system uptime, then show free memory in GB
425
+ ✔ ctx 208ms | openrouter/google/gemma-4-31b-it | mode: task
426
+ ✔ 2 steps planned | tokens: 836 in 173 out (1.0k total) ~$0.000186
427
+ Retrieves system uptime and free physical memory in GB.
428
+
429
+ ─ 1. Get system uptime
430
+ $ (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
431
+ ─ 2. Get free memory in GB
432
+ $ (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1MB
433
+
434
+ ✔ Run
435
+
436
+ ▶ 1/2 Get system uptime
437
+ $ (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
438
+
439
+ Days : 0
440
+ Hours : 15
441
+ Minutes : 36
442
+ Seconds : 23
443
+
444
+ ✔ exit 0
445
+
446
+ ▶ 2/2 Get free memory in GB
447
+ $ (Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1MB
448
+
449
+ 3.65
450
+ ✔ exit 0
451
+ ✔ 2/2 done
452
+ ```
453
+ </details>
454
+
455
+ ---
456
+
457
+ ## Context Awareness
458
+
459
+ `...` isn't guessing. It knows where it's running.
460
+
461
+ | | What it detects |
462
+ |:---|:---|
463
+ | **OS** | Windows, macOS, Linux &mdash; auto-detected |
464
+ | **Shell** | PowerShell, CMD, Bash, Zsh, Fish |
465
+ | **Tools** | node, npm, python, git, docker, etc. |
466
+ | **Project** | package.json, Cargo.toml, pyproject.toml |
467
+ | **Git** | Branch, dirty status, remote |
468
+ | **Environment** | WSL, Docker, SSH, virtualenv |
469
+ | **History** | What you just ran (session memory) |
470
+
471
+ It won't suggest `brew` on Windows or `apt` on macOS. It adapts to you.
472
+
473
+ ---
474
+
475
+ ## Session Memory
476
+
477
+ Follow-ups just work.
478
+
479
+ ```
480
+ $ ... find all log files
481
+ ❯ Get-ChildItem -Recurse -Filter *.log
482
+
483
+ $ ... now delete them
484
+ ❯ Get-ChildItem -Recurse -Filter *.log | Remove-Item
485
+
486
+ $ ... actually undo that
487
+ ❯ well...
488
+ ```
489
+
490
+ ---
491
+
492
+ ## Safety
493
+
494
+ Every command is checked for risk **before** it touches anything.
495
+
496
+ | | Risk | What happens |
497
+ |:---:|:---|:---|
498
+ | **low** | Read-only, harmless | Runs freely (auto-exec if enabled) |
499
+ | **medium** | Creates or modifies files | Runs with your OK |
500
+ | **high** | Destructive (`rm -rf`, `sudo`, `dd`, etc.) | Blocked in auto-mode. Always asks. |
501
+
502
+ ---
503
+
504
+ ## Providers
505
+
506
+ Pick your LLM. Five providers out of the box. Switch on the fly with `-p`.
507
+
508
+ ```bash
509
+ ... -p claude explain this error
510
+ ... -p gpt list my largest files
511
+ ... -p gemini what does this cron do
512
+ ```
513
+
514
+ | Provider | Default Model | Flag |
515
+ |:---------|:--------------|:-----|
516
+ | **OpenRouter** | `gemma-4-26b-a4b-it` | `-p router` |
517
+ | **Anthropic** | `claude-haiku-4-5` | `-p claude` |
518
+ | **OpenAI** | `gpt-4o-mini` | `-p gpt` |
519
+ | **Google Gemini** | `gemini-2.0-flash` | `-p gemini` |
520
+ | **Custom** | *(you set it)* | `-p custom` |
521
+
522
+ **Custom** works with any OpenAI-compatible API &mdash; LM Studio, Ollama, vLLM, Together, etc.
523
+
524
+ Change models anytime: `... -c`
525
+
526
+ ---
527
+
528
+ ## Token Tracking & Cost
529
+
530
+ Every request shows token count and cost inline:
531
+
532
+ ```
533
+ tokens: 1.3k in 93 out (1.4k total) ~$0.000203
534
+ ```
535
+
536
+ Check cumulative usage with `... -u`:
537
+
538
+ ```
539
+ ● ● ● dotdotdot
540
+
541
+ Totals
542
+ ────────────────────────────────────────────
543
+ Requests 9
544
+ Input 12.3k tokens
545
+ Output 763 tokens
546
+ Combined 13.1k tokens
547
+ Cost $0.001696
548
+
549
+ Per Request
550
+ ────────────────────────────────────────────
551
+ Input 1.4k
552
+ Output 85
553
+ Combined 1.5k
554
+ Cost $0.000188
555
+
556
+ Recent
557
+ ────────────────────────────────────────────
558
+ 04/04 18:32 1.1k tokens $0.000220 gemma-4-31b-it
559
+ 04/04 18:35 1.0k tokens $0.000187 gemma-4-31b-it
560
+ 04/04 18:41 1.2k tokens $0.002304 claude-haiku-4-5
561
+
562
+ tracking since 4/1/2026
563
+
564
+ ❯ Exit q
565
+ Reset usage r
566
+ ```
567
+
568
+ Reset from the menu, or directly: `... --reset-usage`
569
+
570
+ <details>
571
+ <summary><strong>Custom pricing</strong></summary>
572
+
573
+ `...` ships with pricing for all default models. For custom models, set pricing during `... -c`:
574
+
575
+ ```
576
+ ❯ Price $/1M input enter to skip (current: 0.10):
577
+ ❯ Price $/1M output enter to skip (current: 0.10):
578
+ ```
579
+
580
+ Custom pricing overrides built-in defaults.
581
+ </details>
582
+
583
+ ---
584
+
585
+ ## Flags
586
+
587
+ | Flag | What it does |
588
+ |:-----|:-------------|
589
+ | `-t` `--task` | Force task mode |
590
+ | `-p` `--provider` `<name>` | Switch provider for this request |
591
+ | `-u` `--usage` | Token usage and cost stats |
592
+ | `-c` `--config` | View and edit config |
593
+ | `-d` `--debug` | Timing, provider info, debug log path |
594
+ | `-v` `--version` | Print version |
595
+ | `-h` `--help` | Help |
596
+ | `--clear` | Clear session history (fresh start, keeps OS/shell context) |
597
+ | `--reset-usage` | Clear all token tracking data |
598
+
599
+ ---
600
+
601
+ ## Config
602
+
603
+ Everything lives in `~/.dotdotdot/config.json`:
604
+
605
+ ```bash
606
+ ... -c # view config, then exit or edit
607
+ ```
608
+
609
+ ```json
610
+ {
611
+ "provider": "openrouter",
612
+ "autoExec": false,
613
+ "providers": {
614
+ "openrouter": { "apiKey": "sk-or-...", "model": "google/gemma-4-26b-a4b-it" },
615
+ "anthropic": { "apiKey": "sk-ant-...", "model": "claude-haiku-4-5-20251001" },
616
+ "custom": { "apiKey": "sk-...", "model": "my-model", "apiUrl": "https://..." }
617
+ },
618
+ "pricing": {
619
+ "my-model": { "input": 1.00, "output": 3.00 }
620
+ }
621
+ }
622
+ ```
623
+
624
+ ---
625
+
626
+ ## Shell Aliases
627
+
628
+ `...` works as a command in most shells. If yours doesn't like it, use `dotdotdot` instead:
629
+
630
+ <details>
631
+ <summary><strong>PowerShell</strong></summary>
632
+
633
+ ```powershell
634
+ # Add to $PROFILE
635
+ function ... { dotdotdot @args }
636
+ ```
637
+ </details>
638
+
639
+ <details>
640
+ <summary><strong>Bash / Zsh</strong></summary>
641
+
642
+ ```bash
643
+ # Add to ~/.bashrc or ~/.zshrc
644
+ alias ...='dotdotdot'
645
+ ```
646
+ </details>
647
+
648
+ <details>
649
+ <summary><strong>Fish</strong></summary>
650
+
651
+ ```fish
652
+ # Add to ~/.config/fish/config.fish
653
+ alias ... 'dotdotdot'
654
+ ```
655
+ </details>
656
+
657
+ ---
658
+
659
+ ## Why `...`
660
+
661
+ Nobody should have to memorize:
662
+
663
+ - `tar -xvzf` vs `tar -xvf` &mdash; seriously, which one
664
+ - every `docker` flag combo
665
+ - `ffmpeg` syntax &mdash; literally impossible
666
+ - PowerShell's `Select-String` vs `grep` vs `findstr`
667
+ - 47 ways to check disk usage across 3 operating systems
668
+ - `find` syntax differences between macOS and Linux
669
+
670
+ **You know what you want. `...` knows how to say it.**
671
+
672
+ ---
673
+
674
+ ## Project Structure
675
+
676
+ ```
677
+ bin/
678
+ dotdotdot.js CLI entry point & arg parser
679
+ lib/
680
+ colors.js Zero-dep ANSI color system
681
+ config.js Multi-provider config management
682
+ context.js OS, shell, git, tools detection
683
+ executor.js Command runner & error recovery
684
+ index.js Public API exports
685
+ llm.js 5 LLM providers, 2 prompt modes
686
+ menu.js Keyboard-driven selection menus
687
+ planner.js Multi-step task orchestrator
688
+ postinstall.js Post-install welcome message
689
+ renderer.js Spinners, boxes, step indicators
690
+ safety.js Command risk analysis engine
691
+ session.js Session history & follow-ups
692
+ tokens.js Token usage tracking & cost estimates
693
+ ui.js Help screen, config view, setup wizard
694
+ ```
695
+
696
+ ---
697
+
698
+ <p align="center">
699
+ <strong>Zero dependencies.</strong> Nothing to break, nothing to conflict.<br>
700
+ <strong>Cross-platform.</strong> Windows, macOS, Linux &mdash; detects your shell and adapts.<br>
701
+ <strong>Transparent.</strong> You always see the command before it runs.<br>
702
+ <strong>Safe.</strong> Dangerous commands are flagged and blocked in auto-mode.
703
+ </p>
704
+
705
+ <p align="center">
706
+ MIT &mdash; do whatever you want with it.
707
+ </p>