shellsage-mcp 0.3.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ShellSage Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,605 @@
1
+ Metadata-Version: 2.4
2
+ Name: shellsage-mcp
3
+ Version: 0.3.0
4
+ Summary: Shell command translation layer for AI agent IDEs — no external services required.
5
+ Author: ShellSage Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/shellsage/shellsage
8
+ Project-URL: Issues, https://github.com/shellsage/shellsage/issues
9
+ Keywords: claude-code,copilot,vscode,kiro,mcp,powershell,tokens
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1.0
24
+ Requires-Dist: rich>=13.0.0
25
+ Provides-Extra: mcp
26
+ Requires-Dist: mcp>=1.9.4; extra == "mcp"
27
+ Requires-Dist: uvicorn>=0.29.0; extra == "mcp"
28
+ Requires-Dist: httpx>=0.27.0; extra == "mcp"
29
+ Provides-Extra: all
30
+ Requires-Dist: shellsage[mcp]; extra == "all"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
34
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
35
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
36
+ Requires-Dist: types-click; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ <div align="center"><pre>
40
+ ██████╗██╗ ██╗███████╗██╗ ██╗ ███████╗ █████╗ ██████╗ ███████╗
41
+ ██╔════╝██║ ██║██╔════╝██║ ██║ ██╔════╝██╔══██╗██╔════╝ ██╔════╝
42
+ ╚█████╗ ███████║█████╗ ██║ ██║ ███████╗███████║██║ ███╗█████╗
43
+ ╚═══██╗██╔══██║██╔══╝ ██║ ██║ ╚════██║██╔══██║██║ ██║██╔══╝
44
+ ██████╔╝██║ ██║███████╗███████╗███████╗███████║██║ ██║╚██████╔╝███████╗
45
+ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝
46
+ The shell translation layer for AI coding agents
47
+ </pre></div>
48
+
49
+ <p align="center">
50
+ <strong>fast rule engine · optional vector memory · MCP server · hooks · local-first · zero token waste</strong>
51
+ </p>
52
+
53
+ <p align="center">
54
+ <a href="https://github.com/shellsage/shellsage/actions/workflows/ci.yml">
55
+ <img src="https://github.com/shellsage/shellsage/actions/workflows/ci.yml/badge.svg" alt="CI">
56
+ </a>
57
+ <a href="https://pypi.org/project/shellsage/">
58
+ <img src="https://img.shields.io/pypi/v/shellsage.svg" alt="PyPI">
59
+ </a>
60
+ <a href="https://pypi.org/project/shellsage/">
61
+ <img src="https://img.shields.io/pypi/pyversions/shellsage.svg" alt="Python">
62
+ </a>
63
+ <a href="LICENSE">
64
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
65
+ </a>
66
+ </p>
67
+
68
+ <p align="center">
69
+ <a href="#what-it-does">What it does</a> ·
70
+ <a href="#quickstart">Quickstart</a> ·
71
+ <a href="#setup-guides">Setup</a> ·
72
+ <a href="#command-translation-reference">Translation Reference</a> ·
73
+ <a href="#configuration">Configuration</a> ·
74
+ <a href="#cli-reference">CLI</a> ·
75
+ <a href="#architecture">Architecture</a>
76
+ </p>
77
+
78
+ ---
79
+
80
+ ShellSage intercepts Bash-style tool calls made by your AI coding agent (Claude Code, Cursor, Windsurf, Kiro, Cline …) and silently rewrites bash syntax into correct PowerShell/CMD before the shell sees it. It works immediately with a local rule engine and a SQLite memory that learns from your sessions — no external services required.
81
+
82
+ **No API key. No cloud. No Docker. Runs entirely on your machine.**
83
+
84
+ ---
85
+
86
+ ## What it does
87
+
88
+ | Without ShellSage | With ShellSage |
89
+ |---|---|
90
+ | Agent writes `ls -la` → PowerShell fails → retry loop → 45k wasted tokens | Agent writes `ls -la` → silently becomes `Get-ChildItem -Force` → works ✓ |
91
+ | 3 bash failures per session = ~135k wasted tokens | 0 failures · 0 wasted tokens |
92
+ | Error traces pollute all future turns | Errors never reach the LLM context |
93
+
94
+ **How it translates:**
95
+
96
+ 1. **Rule-based translation** — 100+ regex patterns covering common bash constructs. Instant, zero DB dependency.
97
+ 2. **SQLite memory** — BM25-style lookup over 400+ curated seed translations plus anything learned from your own sessions. Stored locally in `~/.shellsage/memory.db`.
98
+ 3. **Passthrough** — if no translation is needed (native PowerShell, git, docker), the command passes through unchanged.
99
+
100
+ ---
101
+
102
+ ## Quickstart
103
+
104
+ ```bash
105
+ # 1. Install
106
+ pip install "shellsage[mcp]"
107
+
108
+ # 2. One-command setup (detects your IDE automatically)
109
+ shellsage setup
110
+ ```
111
+
112
+ The setup wizard:
113
+ - detects which IDE/agent you have (Claude Code, Cursor, Windsurf)
114
+ - seeds the local SQLite database with 400+ curated translations
115
+ - starts the background MCP server
116
+ - registers the MCP server with your IDE
117
+ - optionally installs Claude Code hooks for transparent pre-execution translation
118
+
119
+ If you have multiple IDEs installed it will ask which to configure.
120
+
121
+ ---
122
+
123
+ ## Setup Guides
124
+
125
+ `shellsage setup` handles everything automatically. The manual steps below are for reference or scripted environments.
126
+
127
+ ### Claude Code (recommended — hooks + MCP)
128
+
129
+ Claude Code supports **hooks** (silently rewrite before execution) and **MCP** (tools the model can call).
130
+
131
+ #### Option A — automatic (recommended)
132
+
133
+ ```bash
134
+ shellsage setup
135
+ ```
136
+
137
+ #### Option B — manual
138
+
139
+ ```bash
140
+ # 1. Start the background server
141
+ shellsage start
142
+
143
+ # 2. Register the MCP server
144
+ claude mcp add --transport sse shellsage http://127.0.0.1:7842/sse
145
+
146
+ # 3. Install project hooks (run inside your project directory)
147
+ shellsage hooks install
148
+ ```
149
+
150
+ `shellsage hooks install` creates `.claude/hooks/pre_tool_use.py` and `post_tool_use.py` and prints the settings snippet to add to `.claude/settings.json`.
151
+
152
+ **What each hook does:**
153
+ - `pre_tool_use.py` — translates the command before execution; caches original→translated to a temp file
154
+ - `post_tool_use.py` — reads the cache and records the outcome to local SQLite memory
155
+
156
+ ### Cursor
157
+
158
+ ```bash
159
+ shellsage setup # auto-writes ~/.cursor/mcp.json
160
+ ```
161
+
162
+ Or add manually to `~/.cursor/mcp.json`:
163
+
164
+ ```json
165
+ {
166
+ "mcpServers": {
167
+ "shellsage": {
168
+ "url": "http://127.0.0.1:7842/sse"
169
+ }
170
+ }
171
+ }
172
+ ```
173
+
174
+ Start the server first: `shellsage start`
175
+
176
+ ### Windsurf
177
+
178
+ ```bash
179
+ shellsage setup # auto-writes ~/.codeium/windsurf/mcp_config.json
180
+ ```
181
+
182
+ Or add manually to `~/.codeium/windsurf/mcp_config.json`:
183
+
184
+ ```json
185
+ {
186
+ "mcpServers": {
187
+ "shellsage": {
188
+ "serverUrl": "http://127.0.0.1:7842/sse"
189
+ }
190
+ }
191
+ }
192
+ ```
193
+
194
+ Start the server first: `shellsage start`
195
+
196
+ ### Other IDEs (stdio transport)
197
+
198
+ For any MCP-compatible IDE that supports stdio transport:
199
+
200
+ ```json
201
+ {
202
+ "mcpServers": {
203
+ "shellsage": {
204
+ "command": "shellsage",
205
+ "args": ["mcp"]
206
+ }
207
+ }
208
+ }
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Command Translation Reference
214
+
215
+ The rule engine handles these commands immediately. If vector memory is installed, `shellsage init` loads a limited curated seed set by default; use `shellsage init --all` to load the complete corpus.
216
+
217
+ ### File Listing
218
+
219
+ | bash | PowerShell |
220
+ |------|-----------|
221
+ | `ls` | `Get-ChildItem` |
222
+ | `ls -la` | `Get-ChildItem -Force` |
223
+ | `ls -l` | `Get-ChildItem \| Format-List` |
224
+ | `ls -R` | `Get-ChildItem -Recurse` |
225
+ | `ls *.py` | `Get-ChildItem *.py` |
226
+ | `ls -la src/` | `Get-ChildItem -Force 'src/'` |
227
+ | `ls ~` | `Get-ChildItem $HOME` |
228
+
229
+ ### Find / Locate
230
+
231
+ | bash | PowerShell |
232
+ |------|-----------|
233
+ | `find . -name '*.py'` | `Get-ChildItem -Recurse -Filter '*.py'` |
234
+ | `find . -type f` | `Get-ChildItem -Recurse -File` |
235
+ | `find . -type d` | `Get-ChildItem -Recurse -Directory` |
236
+ | `find . -type f -name '*.log'` | `Get-ChildItem -Recurse -File -Filter '*.log'` |
237
+ | `find src/ -name '*.py'` | `Get-ChildItem -Path 'src/' -Recurse -Filter '*.py'` |
238
+ | `find . -mtime -7` | `Get-ChildItem -Recurse \| Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) }` |
239
+ | `find . -size +1M` | `Get-ChildItem -Recurse \| Where-Object { $_.Length -gt 1MB }` |
240
+ | `find . -name '*.tmp' -delete` | `Get-ChildItem -Recurse -Filter '*.tmp' \| Remove-Item -Force` |
241
+ | `find . -name '*.pyc' -delete` | `Get-ChildItem -Recurse -Filter '*.pyc' \| Remove-Item -Force` |
242
+
243
+ ### Grep / Search
244
+
245
+ | bash | PowerShell |
246
+ |------|-----------|
247
+ | `grep 'error' app.log` | `Select-String -Pattern 'error' -Path 'app.log'` |
248
+ | `grep -r 'TODO' .` | `Get-ChildItem -Recurse \| Select-String -Pattern 'TODO'` |
249
+ | `grep -rn 'import' src/` | `Get-ChildItem -Recurse 'src/' \| Select-String -Pattern 'import'` |
250
+ | `grep -i 'error' app.log` | `Select-String -Pattern 'error' -Path 'app.log' -CaseSensitive:$false` |
251
+ | `grep -v 'debug' app.log` | `Get-Content 'app.log' \| Where-Object { $_ -notmatch 'debug' }` |
252
+ | `grep -c 'error' app.log` | `(Select-String -Pattern 'error' -Path 'app.log').Count` |
253
+ | `grep -l 'TODO' *.py` | `Select-String -Pattern 'TODO' -Path '*.py' \| Select-Object -ExpandProperty Path -Unique` |
254
+ | `grep 'error' *.log` | `Select-String -Pattern 'error' -Path '*.log'` |
255
+ | `grep -r 'password' . --include='*.py'` | `Get-ChildItem -Recurse -Filter '*.py' \| Select-String -Pattern 'password'` |
256
+
257
+ ### View Files
258
+
259
+ | bash | PowerShell |
260
+ |------|-----------|
261
+ | `cat README.md` | `Get-Content 'README.md'` |
262
+ | `cat file1.txt file2.txt` | `Get-Content 'file1.txt', 'file2.txt'` |
263
+ | `head -n 20 file.txt` | `Get-Content 'file.txt' -TotalCount 20` |
264
+ | `tail -n 50 app.log` | `Get-Content 'app.log' -Tail 50` |
265
+ | `tail -f server.log` | `Get-Content -Wait 'server.log'` |
266
+
267
+ ### File Management
268
+
269
+ | bash | PowerShell |
270
+ |------|-----------|
271
+ | `mkdir -p src/utils` | `New-Item -ItemType Directory -Force -Path 'src/utils'` |
272
+ | `rm -rf node_modules` | `Remove-Item -Recurse -Force 'node_modules'` |
273
+ | `rm -rf dist/` | `Remove-Item -Recurse -Force 'dist/'` |
274
+ | `rm -f output.log` | `Remove-Item -Force 'output.log'` |
275
+ | `cp -r src/ backup/` | `Copy-Item -Recurse 'src/' 'backup/'` |
276
+ | `cp config.json config.json.bak` | `Copy-Item 'config.json' 'config.json.bak'` |
277
+ | `mv old.txt new.txt` | `Move-Item 'old.txt' 'new.txt'` |
278
+ | `touch .gitkeep` | `New-Item -ItemType File -Force '.gitkeep'` |
279
+ | `ln -s src dest` | `New-Item -ItemType SymbolicLink -Name 'dest' -Target 'src'` |
280
+
281
+ ### Text Processing
282
+
283
+ | bash | PowerShell |
284
+ |------|-----------|
285
+ | `wc -l file.txt` | `(Get-Content 'file.txt').Count` |
286
+ | `sort file.txt` | `Get-Content 'file.txt' \| Sort-Object` |
287
+ | `sort -u file.txt` | `Get-Content 'file.txt' \| Sort-Object -Unique` |
288
+ | `sort -r file.txt` | `Get-Content 'file.txt' \| Sort-Object -Descending` |
289
+ | `sort file.txt \| uniq -c` | `Get-Content 'file.txt' \| Group-Object \| Select-Object Count, Name` |
290
+ | `sed -i 's/foo/bar/g' file.txt` | `(Get-Content 'file.txt') -replace 'foo','bar' \| Set-Content 'file.txt'` |
291
+ | `sed '/^#/d' file.txt` | `Get-Content 'file.txt' \| Where-Object { $_ -notmatch '^#' }` |
292
+ | `awk '{print $1}' file.txt` | `Get-Content 'file.txt' \| ForEach-Object { ($_ -split '\s+')[0] }` |
293
+
294
+ ### Echo / Redirect
295
+
296
+ | bash | PowerShell |
297
+ |------|-----------|
298
+ | `echo 'hello world'` | `Write-Output 'hello world'` |
299
+ | `echo $PATH` | `$env:PATH` |
300
+ | `echo $HOME` | `$env:USERPROFILE` |
301
+ | `echo 'line' > file.txt` | `Set-Content 'file.txt' 'line'` |
302
+ | `echo 'line' >> file.txt` | `Add-Content 'file.txt' 'line'` |
303
+
304
+ ### Environment Variables
305
+
306
+ | bash | PowerShell |
307
+ |------|-----------|
308
+ | `export NODE_ENV=production` | `$env:NODE_ENV = 'production'` |
309
+ | `export PORT=3000` | `$env:PORT = '3000'` |
310
+ | `export DATABASE_URL=postgres://localhost/db` | `$env:DATABASE_URL = 'postgres://localhost/db'` |
311
+ | `unset NODE_ENV` | `Remove-Item Env:\NODE_ENV` |
312
+ | `env` | `Get-ChildItem Env:` |
313
+ | `printenv PATH` | `$env:PATH` |
314
+
315
+ ### Process Management
316
+
317
+ | bash | PowerShell |
318
+ |------|-----------|
319
+ | `ps aux` | `Get-Process` |
320
+ | `ps aux \| grep node` | `Get-Process \| Where-Object { $_.Name -match 'node' }` |
321
+ | `pgrep python` | `Get-Process -Name '*python*'` |
322
+ | `pkill node` | `Stop-Process -Name 'node' -Force` |
323
+ | `kill -9 1234` | `Stop-Process -Id 1234 -Force` |
324
+ | `killall python` | `Stop-Process -Name 'python' -Force` |
325
+ | `sleep 5` | `Start-Sleep 5` |
326
+ | `nohup python app.py &` | `Start-Process -NoNewWindow python -ArgumentList 'app.py' -RedirectStandardOutput 'nohup.out'` |
327
+
328
+ ### Network
329
+
330
+ | bash | PowerShell |
331
+ |------|-----------|
332
+ | `curl https://example.com` | `Invoke-WebRequest -Uri 'https://example.com'` |
333
+ | `curl -s https://api.github.com` | `Invoke-RestMethod 'https://api.github.com'` |
334
+ | `curl -o file.zip https://example.com/a.zip` | `Invoke-WebRequest -Uri 'https://example.com/a.zip' -OutFile 'file.zip'` |
335
+ | `curl -X POST URL -d '{"k":"v"}'` | `Invoke-RestMethod -Method POST -Uri URL -Body '{"k":"v"}' -ContentType 'application/json'` |
336
+ | `curl -H 'Authorization: Bearer TOKEN' URL` | `Invoke-RestMethod -Uri URL -Headers @{ Authorization = 'Bearer TOKEN' }` |
337
+ | `wget https://example.com/file.zip` | `Invoke-WebRequest -Uri 'https://example.com/file.zip' -OutFile 'file.zip'` |
338
+ | `ping google.com` | `Test-Connection -ComputerName 'google.com'` |
339
+ | `ping -c 4 google.com` | `Test-Connection -ComputerName 'google.com' -Count 4` |
340
+ | `netstat -tulpn` | `Get-NetTCPConnection \| Where-Object { $_.State -eq 'Listen' }` |
341
+ | `nslookup google.com` | `Resolve-DnsName 'google.com'` |
342
+
343
+ ### Archive / Compression
344
+
345
+ | bash | PowerShell |
346
+ |------|-----------|
347
+ | `tar -czf archive.tar.gz dist/` | `Compress-Archive -Path 'dist/' -DestinationPath 'archive.zip'` |
348
+ | `tar -xzf archive.tar.gz` | `Expand-Archive -Path 'archive.zip' -DestinationPath '.'` |
349
+ | `tar -xzf archive.tar.gz -C out/` | `Expand-Archive -Path 'archive.zip' -DestinationPath 'out/'` |
350
+ | `zip -r archive.zip src/` | `Compress-Archive -Path 'src/' -DestinationPath 'archive.zip'` |
351
+ | `unzip archive.zip -d output/` | `Expand-Archive -Path 'archive.zip' -DestinationPath 'output/'` |
352
+
353
+ ### Disk / System Info
354
+
355
+ | bash | PowerShell |
356
+ |------|-----------|
357
+ | `df -h` | `Get-PSDrive -PSProvider FileSystem` |
358
+ | `du -sh .` | `(Get-ChildItem -Recurse \| Measure-Object -Property Length -Sum).Sum / 1MB` |
359
+ | `du -sh node_modules/` | `(Get-ChildItem -Recurse 'node_modules/' \| Measure-Object -Property Length -Sum).Sum / 1MB` |
360
+ | `uname -a` | `Get-ComputerInfo \| Select-Object WindowsProductName, WindowsVersion` |
361
+ | `hostname` | `$env:COMPUTERNAME` |
362
+ | `whoami` | `$env:USERNAME` |
363
+ | `date` | `Get-Date` |
364
+ | `date '+%Y-%m-%d'` | `Get-Date -Format 'yyyy-MM-dd'` |
365
+ | `uptime` | `(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime` |
366
+
367
+ ### Permissions
368
+
369
+ | bash | PowerShell |
370
+ |------|-----------|
371
+ | `chmod +x script.sh` | `# Rename to script.ps1 or use Set-ExecutionPolicy` |
372
+ | `chmod 755 dir/` | `# Use icacls for Windows ACL management` |
373
+ | `chown user file` | `# Use icacls: icacls 'file' /setowner 'user'` |
374
+ | `sudo command` | `# Run PowerShell as Administrator, then: command` |
375
+
376
+ ### Python
377
+
378
+ | bash | PowerShell |
379
+ |------|-----------|
380
+ | `python3 script.py` | `python script.py` |
381
+ | `python3 -m pytest` | `python -m pytest` |
382
+ | `python3 -m pytest -v` | `python -m pytest -v` |
383
+ | `python3 -m pip install -r requirements.txt` | `python -m pip install -r requirements.txt` |
384
+ | `python3 -m pip install -e .` | `python -m pip install -e .` |
385
+ | `python3 -m venv .venv` | `python -m venv .venv` |
386
+ | `source .venv/bin/activate` | `.venv\Scripts\Activate.ps1` |
387
+ | `python3 -m pip freeze > requirements.txt` | `python -m pip freeze \| Set-Content 'requirements.txt'` |
388
+ | `which python3` | `(Get-Command python).Source` |
389
+
390
+ ### Node.js / npm
391
+
392
+ | bash | PowerShell |
393
+ |------|-----------|
394
+ | `npm install` | `npm install` |
395
+ | `npm install package` | `npm install package` |
396
+ | `npm run build` | `npm run build` |
397
+ | `npm run dev` | `npm run dev` |
398
+ | `npm test` | `npm test` |
399
+ | `npx tsc` | `npx tsc` |
400
+ | `yarn install` | `yarn install` |
401
+ | `yarn add package` | `yarn add package` |
402
+
403
+ ### Docker
404
+
405
+ | bash | PowerShell |
406
+ |------|-----------|
407
+ | `docker ps -a` | `docker ps -a` |
408
+ | `docker build -t myapp .` | `docker build -t myapp .` |
409
+ | `docker run -d -p 8080:8080 myapp` | `docker run -d -p 8080:8080 myapp` |
410
+ | `docker exec -it mycontainer bash` | `docker exec -it mycontainer bash` |
411
+ | `docker logs -f mycontainer` | `docker logs -f mycontainer` |
412
+ | `docker-compose up -d` | `docker-compose up -d` |
413
+ | `docker-compose down` | `docker-compose down` |
414
+ | `docker system prune -f` | `docker system prune -f` |
415
+
416
+ ### Git
417
+
418
+ Git commands are identical on all platforms — ShellSage passes them through unchanged.
419
+
420
+ | bash / PowerShell |
421
+ |---|
422
+ | `git init` · `git clone URL` · `git status` · `git add .` |
423
+ | `git commit -m 'message'` · `git push origin main` · `git pull` |
424
+ | `git checkout -b feature/name` · `git merge branch` · `git rebase main` |
425
+ | `git log --oneline -10` · `git diff --stat` · `git stash` |
426
+
427
+ ### Directory Navigation
428
+
429
+ | bash | PowerShell |
430
+ |------|-----------|
431
+ | `pwd` | `Get-Location` |
432
+ | `cd src/` | `Set-Location 'src/'` |
433
+ | `cd ..` | `Set-Location ..` |
434
+ | `cd ~` | `Set-Location $HOME` |
435
+ | `pushd src/` | `Push-Location 'src/'` |
436
+ | `popd` | `Pop-Location` |
437
+
438
+ ### Pipes and Redirects
439
+
440
+ | bash | PowerShell |
441
+ |------|-----------|
442
+ | `ls \| grep '.py'` | `Get-ChildItem \| Where-Object { $_.Name -match '\.py' }` |
443
+ | `ls \| wc -l` | `(Get-ChildItem).Count` |
444
+ | `cat file.txt \| sort \| uniq` | `Get-Content 'file.txt' \| Sort-Object -Unique` |
445
+ | `find . -name '*.py' \| xargs grep 'import'` | `Get-ChildItem -Recurse -Filter '*.py' \| Select-String -Pattern 'import'` |
446
+ | `command > /dev/null 2>&1` | `command > $null 2>&1` |
447
+
448
+ ---
449
+
450
+ ## Configuration
451
+
452
+ All settings can be overridden via environment variables:
453
+
454
+ | Variable | Default | Description |
455
+ |---|---|---|
456
+ | `SHELLSAGE_DB_PATH` | `~/.shellsage/memory.db` | SQLite database path |
457
+ | `SHELLSAGE_PORT` | `7842` | Background MCP server port |
458
+ | `SHELLSAGE_HOST` | `127.0.0.1` | Background MCP server host |
459
+ | `SHELLSAGE_SCORE_THRESHOLD` | `0.1` | Minimum score to accept a stored-translation hit |
460
+ | `SHELLSAGE_SEED_LIMIT` | `75` | Number of seed examples loaded by `shellsage init` |
461
+ | `SHELLSAGE_SEED_CONFIDENCE` | `0.95` | Confidence assigned to seed translations |
462
+ | `SHELLSAGE_OUTCOME_CONFIDENCE` | `0.99` | Confidence assigned when a command succeeds in practice |
463
+
464
+ Example — custom port:
465
+
466
+ ```bash
467
+ export SHELLSAGE_PORT=8888
468
+ shellsage setup --port 8888
469
+ ```
470
+
471
+ ---
472
+
473
+ ## MCP Tools
474
+
475
+ The MCP server exposes 4 tools that your AI agent can call directly:
476
+
477
+ | Tool | Description |
478
+ |---|---|
479
+ | `translate_command(command, project_root)` | Translate a bash command for the current shell |
480
+ | `store_command_result(original, translated, shell, os_name, project_type, exit_code, error_snippet)` | Record command outcome when vector memory is installed |
481
+ | `get_shell_context(project_root)` | Return detected OS/shell/project environment |
482
+ | `get_stats()` | Health check — return Qdrant collection counts |
483
+
484
+ ---
485
+
486
+ ## CLI Reference
487
+
488
+ ```
489
+ shellsage setup # Interactive one-command install wizard (auto-detects IDE)
490
+ shellsage setup --port 8888 # Wizard with custom port
491
+
492
+ shellsage init # Seed the local SQLite DB (75 examples by default)
493
+ shellsage init --all # Load the complete 400+ seed corpus
494
+
495
+ shellsage translate "ls -la" # Translate a single command
496
+ shellsage translate "ls -la" --json-out # Machine-readable output
497
+
498
+ shellsage stats # Show local DB counts
499
+ shellsage replay # Show recent failure patterns
500
+
501
+ shellsage start # Start background MCP server (HTTP/SSE)
502
+ shellsage stop # Stop background MCP server
503
+ shellsage status # Show daemon and DB status
504
+
505
+ shellsage mcp # Start MCP server in foreground (stdio)
506
+ shellsage mcp --http # Start MCP server in foreground (HTTP/SSE)
507
+
508
+ shellsage hooks install # Write pre/post hook scripts to .claude/hooks/
509
+
510
+ shellsage --version # Print version
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Architecture
516
+
517
+ ```
518
+ Claude Code / Cursor / Windsurf / Kiro / Cline
519
+ │ bash command
520
+
521
+ ┌───────────────────────────────────────────────┐
522
+ │ PreToolUse Hook (.claude/hooks/pre_*.py) │ ← Claude Code only
523
+ │ ───────────────────────────────────────── │
524
+ │ 1. Rule-based translation (100+ patterns) │
525
+ │ 2. SQLite hybrid search (BM25 + learned) │
526
+ │ 3. Passthrough if no match │
527
+ │ Caches: original → translated (temp file) │
528
+ └───────────────────────────────────────────────┘
529
+ │ corrected PowerShell command
530
+
531
+ [Shell execution]
532
+
533
+
534
+ ┌───────────────────────────────────────────────┐
535
+ │ PostToolUse Hook (.claude/hooks/post_*.py) │ ← Claude Code only
536
+ │ Reads cache, records outcome to SQLite │
537
+ │ Success → upsert translation (conf=0.99) │
538
+ │ Failure → upsert failure pattern │
539
+ └───────────────────────────────────────────────┘
540
+
541
+
542
+ SQLite (~/.shellsage/memory.db) — always local, zero config
543
+ ├─ translations (400+ seeds + session-learned)
544
+ └─ failures (error patterns for replay)
545
+
546
+ ─────────────────────────────────────────────────
547
+ MCP server (http://127.0.0.1:7842/sse)
548
+ ├─ translate_command → rules + SQLite lookup
549
+ ├─ store_command_result → write back to SQLite
550
+ ├─ get_shell_context → OS / shell / project detection
551
+ └─ get_stats → health check
552
+ ```
553
+
554
+ **Module map:**
555
+
556
+ | Module | Role |
557
+ |---|---|
558
+ | `config.py` | Env-var-backed settings (single source of truth) |
559
+ | `models.py` | `ShellContext`, `Translation`, `CommandOutcome` — zero deps |
560
+ | `rules.py` | 100+ regex patterns (instant, no DB needed) |
561
+ | `seed.py` | 400+ curated bash→PS pairs; `init` loads a bounded set by default |
562
+ | `store.py` | SQLite: translations + failures, BM25-style lookup |
563
+ | `translator.py` | 2-tier resolution: rules → SQLite lookup → passthrough |
564
+ | `server.py` | FastMCP server (4 tools, stdio or HTTP/SSE) |
565
+ | `daemon.py` | Background process management (start / stop / status) |
566
+ | `setup_wizard.py` | Interactive installer with IDE auto-detection |
567
+ | `cli.py` | Click CLI (10 commands) |
568
+
569
+ ---
570
+
571
+ ## Development
572
+
573
+ ```bash
574
+ git clone https://github.com/shellsage/shellsage.git
575
+ cd shellsage
576
+ pip install -e ".[mcp,dev]"
577
+
578
+ # Run tests
579
+ pytest
580
+
581
+ # Lint
582
+ ruff check shellsage/ tests/
583
+ ruff format shellsage/ tests/
584
+
585
+ # Type check
586
+ mypy shellsage/
587
+
588
+ # Validate seed data
589
+ python -c "from shellsage.seed import SEED_TRANSLATIONS; print(len(SEED_TRANSLATIONS))"
590
+
591
+ # Test a translation (no Qdrant needed)
592
+ shellsage translate "find . -name '*.py'"
593
+ ```
594
+
595
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full contribution guidelines.
596
+
597
+ ---
598
+
599
+ ## License
600
+
601
+ MIT — see [LICENSE](LICENSE).
602
+
603
+ ## Security
604
+
605
+ Please report vulnerabilities to **security@shellsage.dev** — see [SECURITY.md](SECURITY.md).