myshell-tools 1.0.0 → 2.0.0-alpha.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/CHANGELOG.md +44 -69
- package/LICENSE +21 -21
- package/README.md +178 -318
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +106 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cost.d.ts +36 -0
- package/dist/commands/cost.js +103 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/doctor.d.ts +36 -0
- package/dist/commands/doctor.js +115 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/core/assess.d.ts +25 -0
- package/dist/core/assess.js +142 -0
- package/dist/core/assess.js.map +1 -0
- package/dist/core/classify.d.ts +19 -0
- package/dist/core/classify.js +80 -0
- package/dist/core/classify.js.map +1 -0
- package/dist/core/escalate.d.ts +32 -0
- package/dist/core/escalate.js +57 -0
- package/dist/core/escalate.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/orchestrate.d.ts +42 -0
- package/dist/core/orchestrate.js +439 -0
- package/dist/core/orchestrate.js.map +1 -0
- package/dist/core/policy.d.ts +9 -0
- package/dist/core/policy.js +27 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/prompt.d.ts +26 -0
- package/dist/core/prompt.js +125 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/review.d.ts +46 -0
- package/dist/core/review.js +148 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/route.d.ts +28 -0
- package/dist/core/route.js +52 -0
- package/dist/core/route.js.map +1 -0
- package/dist/core/types.d.ts +141 -0
- package/dist/core/types.js +14 -0
- package/dist/core/types.js.map +1 -0
- package/dist/infra/atomic.d.ts +53 -0
- package/dist/infra/atomic.js +171 -0
- package/dist/infra/atomic.js.map +1 -0
- package/dist/infra/clock.d.ts +9 -0
- package/dist/infra/clock.js +15 -0
- package/dist/infra/clock.js.map +1 -0
- package/dist/infra/index.d.ts +9 -0
- package/dist/infra/index.js +7 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/ledger.d.ts +49 -0
- package/dist/infra/ledger.js +90 -0
- package/dist/infra/ledger.js.map +1 -0
- package/dist/infra/paths.d.ts +28 -0
- package/dist/infra/paths.js +38 -0
- package/dist/infra/paths.js.map +1 -0
- package/dist/infra/pricing.d.ts +47 -0
- package/dist/infra/pricing.js +151 -0
- package/dist/infra/pricing.js.map +1 -0
- package/dist/infra/session.d.ts +28 -0
- package/dist/infra/session.js +61 -0
- package/dist/infra/session.js.map +1 -0
- package/dist/interface/render.d.ts +27 -0
- package/dist/interface/render.js +134 -0
- package/dist/interface/render.js.map +1 -0
- package/dist/interface/repl.d.ts +23 -0
- package/dist/interface/repl.js +90 -0
- package/dist/interface/repl.js.map +1 -0
- package/dist/interface/run.d.ts +20 -0
- package/dist/interface/run.js +31 -0
- package/dist/interface/run.js.map +1 -0
- package/dist/providers/claude-parse.d.ts +24 -0
- package/dist/providers/claude-parse.js +113 -0
- package/dist/providers/claude-parse.js.map +1 -0
- package/dist/providers/claude.d.ts +45 -0
- package/dist/providers/claude.js +122 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex-parse.d.ts +32 -0
- package/dist/providers/codex-parse.js +145 -0
- package/dist/providers/codex-parse.js.map +1 -0
- package/dist/providers/codex.d.ts +44 -0
- package/dist/providers/codex.js +124 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/detect.d.ts +49 -0
- package/dist/providers/detect.js +125 -0
- package/dist/providers/detect.js.map +1 -0
- package/dist/providers/errors.d.ts +49 -0
- package/dist/providers/errors.js +189 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +7 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/port.d.ts +74 -0
- package/dist/providers/port.js +16 -0
- package/dist/providers/port.js.map +1 -0
- package/dist/providers/registry.d.ts +21 -0
- package/dist/providers/registry.js +34 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/ui/banner.d.ts +19 -0
- package/dist/ui/banner.js +32 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/spinner.d.ts +27 -0
- package/dist/ui/spinner.js +67 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/theme.d.ts +32 -0
- package/dist/ui/theme.js +56 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +55 -49
- package/data/orchestrator.json +0 -113
- package/src/auth/recovery.mjs +0 -328
- package/src/auth/refresh.mjs +0 -373
- package/src/chef.mjs +0 -348
- package/src/cli/doctor.mjs +0 -568
- package/src/cli/reset.mjs +0 -447
- package/src/cli/status.mjs +0 -379
- package/src/cli.mjs +0 -429
- package/src/commands/doctor.mjs +0 -375
- package/src/commands/help.mjs +0 -324
- package/src/commands/status.mjs +0 -331
- package/src/monitor/health.mjs +0 -486
- package/src/monitor/performance.mjs +0 -442
- package/src/monitor/report.mjs +0 -535
- package/src/orchestrator/classify.mjs +0 -391
- package/src/orchestrator/confidence.mjs +0 -151
- package/src/orchestrator/handoffs.mjs +0 -231
- package/src/orchestrator/review.mjs +0 -222
- package/src/providers/balance.mjs +0 -201
- package/src/providers/claude.mjs +0 -236
- package/src/providers/codex.mjs +0 -255
- package/src/providers/detect.mjs +0 -185
- package/src/providers/errors.mjs +0 -373
- package/src/providers/select.mjs +0 -162
- package/src/repl-enhanced.mjs +0 -417
- package/src/repl.mjs +0 -321
- package/src/state/archive.mjs +0 -366
- package/src/state/atomic.mjs +0 -116
- package/src/state/cleanup.mjs +0 -440
- package/src/state/recovery.mjs +0 -461
- package/src/state/session.mjs +0 -147
- package/src/ui/errors.mjs +0 -456
- package/src/ui/formatter.mjs +0 -327
- package/src/ui/icons.mjs +0 -318
- package/src/ui/progress.mjs +0 -468
- package/templates/prompts/confidence-format.txt +0 -14
- package/templates/prompts/ic-with-feedback.txt +0 -41
- package/templates/prompts/ic.txt +0 -13
- package/templates/prompts/manager-review.txt +0 -40
- package/templates/prompts/manager.txt +0 -14
- package/templates/prompts/worker.txt +0 -12
package/README.md
CHANGED
|
@@ -1,318 +1,178 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
###
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
##
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
- `/clear` - Clear conversation history
|
|
180
|
-
- `/reset` - Reset session state
|
|
181
|
-
- `/quit` - Exit Cortex
|
|
182
|
-
|
|
183
|
-
## Configuration
|
|
184
|
-
|
|
185
|
-
Cortex works zero-config, but you can customize behavior:
|
|
186
|
-
|
|
187
|
-
### Custom Model Preferences
|
|
188
|
-
```bash
|
|
189
|
-
# Prefer Claude for coding tasks
|
|
190
|
-
export CORTEX_PREFER_CLAUDE=true
|
|
191
|
-
|
|
192
|
-
# Prefer OpenAI for creative tasks
|
|
193
|
-
export CORTEX_PREFER_OPENAI=true
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Confidence Thresholds
|
|
197
|
-
```bash
|
|
198
|
-
# Higher escalation threshold (more conservative)
|
|
199
|
-
export CORTEX_ESCALATION_THRESHOLD=0.7
|
|
200
|
-
|
|
201
|
-
# Lower escalation threshold (more aggressive delegation)
|
|
202
|
-
export CORTEX_ESCALATION_THRESHOLD=0.3
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## Troubleshooting
|
|
206
|
-
|
|
207
|
-
### "No AI providers detected"
|
|
208
|
-
```bash
|
|
209
|
-
# Check authentication status
|
|
210
|
-
claude auth status
|
|
211
|
-
openai auth status
|
|
212
|
-
|
|
213
|
-
# Re-authenticate if needed
|
|
214
|
-
claude auth login
|
|
215
|
-
openai auth login
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### "Permission denied" errors
|
|
219
|
-
```bash
|
|
220
|
-
# Ensure Node.js permissions
|
|
221
|
-
chmod +x ~/.local/bin/cortex
|
|
222
|
-
|
|
223
|
-
# Check directory permissions
|
|
224
|
-
ls -la .cortex/
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Provider-specific issues
|
|
228
|
-
```bash
|
|
229
|
-
# Test Claude connection
|
|
230
|
-
claude chat "Hello, can you respond?"
|
|
231
|
-
|
|
232
|
-
# Test OpenAI connection
|
|
233
|
-
openai chat "Hello, can you respond?"
|
|
234
|
-
|
|
235
|
-
# Run full system check
|
|
236
|
-
npx cortex-ai --doctor
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Performance Issues
|
|
240
|
-
```bash
|
|
241
|
-
# Clear session cache
|
|
242
|
-
rm -rf .cortex/sessions/
|
|
243
|
-
|
|
244
|
-
# Reset to defaults
|
|
245
|
-
npx cortex-ai --reset
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Why Hierarchical AI?
|
|
249
|
-
|
|
250
|
-
### Traditional Approach Problems
|
|
251
|
-
- ❌ Every task burns expensive premium model tokens
|
|
252
|
-
- ❌ Simple tasks get over-engineered solutions
|
|
253
|
-
- ❌ No transparency into decision-making process
|
|
254
|
-
- ❌ High costs for routine work
|
|
255
|
-
|
|
256
|
-
### Cortex Approach Benefits
|
|
257
|
-
- ✅ **Cost Efficient**: 80% of tasks complete at IC tier or below
|
|
258
|
-
- ✅ **Better Quality**: Managers review complex/security-critical work
|
|
259
|
-
- ✅ **Transparent**: See exactly which model handled what and why
|
|
260
|
-
- ✅ **Adaptive**: Automatically escalates when confidence is low
|
|
261
|
-
- ✅ **Local Privacy**: Uses your existing subscriptions, no data sharing
|
|
262
|
-
|
|
263
|
-
## Contributing
|
|
264
|
-
|
|
265
|
-
We welcome contributions! This is a community-driven project.
|
|
266
|
-
|
|
267
|
-
### Development Setup
|
|
268
|
-
```bash
|
|
269
|
-
git clone https://github.com/heyvera/cortex-ai.git
|
|
270
|
-
cd cortex-ai
|
|
271
|
-
npm install
|
|
272
|
-
npm start
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Architecture Overview
|
|
276
|
-
- **`src/cli.mjs`**: Main entry point and argument parsing
|
|
277
|
-
- **`src/orchestrator/`**: Hierarchical routing and escalation logic
|
|
278
|
-
- **`src/providers/`**: Claude and OpenAI CLI integration
|
|
279
|
-
- **`src/repl.mjs`**: Interactive shell implementation
|
|
280
|
-
- **`templates/`**: Prompt templates for each tier
|
|
281
|
-
|
|
282
|
-
### Contributing Guidelines
|
|
283
|
-
1. **Issues**: Report bugs or suggest features via GitHub Issues
|
|
284
|
-
2. **Pull Requests**: Fork, create feature branch, submit PR
|
|
285
|
-
3. **Code Style**: Follow existing patterns, use ESLint
|
|
286
|
-
4. **Testing**: Test with both Claude and OpenAI setups
|
|
287
|
-
5. **Documentation**: Update README for new features
|
|
288
|
-
|
|
289
|
-
## Roadmap
|
|
290
|
-
|
|
291
|
-
### v1.1 (Next Release)
|
|
292
|
-
- [ ] Plugin system for custom AI providers
|
|
293
|
-
- [ ] Team collaboration features
|
|
294
|
-
- [ ] Advanced analytics and usage tracking
|
|
295
|
-
- [ ] Custom prompt template management
|
|
296
|
-
|
|
297
|
-
### v1.2 (Future)
|
|
298
|
-
- [ ] Web dashboard for session management
|
|
299
|
-
- [ ] Integration with VS Code extension
|
|
300
|
-
- [ ] Multi-project workspace support
|
|
301
|
-
- [ ] Advanced caching and performance optimization
|
|
302
|
-
|
|
303
|
-
## License
|
|
304
|
-
|
|
305
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
|
306
|
-
|
|
307
|
-
## Support
|
|
308
|
-
|
|
309
|
-
- **Documentation**: [GitHub Wiki](https://github.com/heyvera/cortex-ai/wiki)
|
|
310
|
-
- **Issues**: [GitHub Issues](https://github.com/heyvera/cortex-ai/issues)
|
|
311
|
-
- **Discussions**: [GitHub Discussions](https://github.com/heyvera/cortex-ai/discussions)
|
|
312
|
-
- **Email**: hello@heyvera.org
|
|
313
|
-
|
|
314
|
-
---
|
|
315
|
-
|
|
316
|
-
**Made with ❤️ by the HeyVera team**
|
|
317
|
-
|
|
318
|
-
*Cortex AI: Where artificial intelligence meets organizational intelligence.*
|
|
1
|
+
# myshell-tools
|
|
2
|
+
|
|
3
|
+
**Hierarchical, multi-provider AI orchestration for your shell — over the CLIs you already use.**
|
|
4
|
+
|
|
5
|
+
`myshell-tools` routes each task to the *cheapest* model likely to succeed, runs it on your real codebase, optionally has a **different vendor** review the result, and shows you exactly what it did and what it truly cost — with **no fabricated data, ever**.
|
|
6
|
+
|
|
7
|
+
> **Status: `2.0.0-alpha.0` — early, honest, and real.** The Claude path is validated end‑to‑end on real models; the Codex path auto‑activates the moment `codex` is installed and authenticated. Not yet published to npm — install from source (below).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why it exists
|
|
12
|
+
|
|
13
|
+
Using one frontier model for everything is wasteful (renaming a variable doesn't need Opus) and single‑model output has blind spots. `myshell-tools` addresses both, honestly:
|
|
14
|
+
|
|
15
|
+
- **Cost‑aware routing** — trivial work goes to the cheap tier (Haiku / GPT‑5 mini), real implementation to the mid tier, hard calls to the flagship. You see the savings as a real number.
|
|
16
|
+
- **Cross‑vendor adversarial review** — for high‑risk work, a *different vendor* checks the first model's output (Codex reviewing Claude, or vice‑versa). Different families, different blind spots.
|
|
17
|
+
- **Subscription, not metering** — it drives the **Claude Code** and **Codex** CLIs you already pay for. No API keys, no per‑token bill.
|
|
18
|
+
- **Honest by construction** — every number on screen traces to a real measurement. A suite of *architecture tests* makes fabricated/mock output literally unmergeable.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- **Node.js ≥ 20** (the CLI itself; tests require Node ≥ 22).
|
|
25
|
+
- At least one provider CLI, installed and authenticated:
|
|
26
|
+
- **Claude Code** — `npm install -g @anthropic-ai/claude-code` then `claude` (sign in).
|
|
27
|
+
- **Codex** — `npm install -g @openai/codex` then `codex login`.
|
|
28
|
+
|
|
29
|
+
You need **one** to start; install **both** to unlock cross‑vendor review.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Install (from source, during alpha)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone <this-repo>
|
|
37
|
+
cd myshell-tools
|
|
38
|
+
npm install
|
|
39
|
+
npm run build
|
|
40
|
+
node dist/cli.js --help
|
|
41
|
+
# optional: make `myshell-tools` available globally
|
|
42
|
+
npm link
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
myshell-tools [command] [options]
|
|
51
|
+
|
|
52
|
+
Commands:
|
|
53
|
+
run <task...> Run a one-shot task and exit
|
|
54
|
+
repl Interactive session (default when no command is given)
|
|
55
|
+
doctor Check providers, auth, environment
|
|
56
|
+
cost Show real spend + the cost-routing counterfactual
|
|
57
|
+
|
|
58
|
+
Options:
|
|
59
|
+
-h, --help Show help
|
|
60
|
+
-v, --version Print version
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### A real run
|
|
64
|
+
|
|
65
|
+
These are **actual, unedited** outputs (your costs/timings will differ):
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
$ myshell-tools run "what is 2 plus 2"
|
|
69
|
+
Classified: worker tier, low risk — tier: worker keyword 'what is'; risk: defaulting to low
|
|
70
|
+
▶ WORKER (claude/claude-haiku-4-5) attempt 1
|
|
71
|
+
2 plus 2 equals 4.
|
|
72
|
+
✓ tier done — confidence: 100%, cost: $0.0124, duration: 5648ms
|
|
73
|
+
Success — tier: worker, cost: $0.0124, attempts: 1, session: 0dbfe2e3-…
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The confidence (`100%`) is **parsed from the model's own structured reply**, not invented. The cost is the **CLI's own reported figure**, not an estimate.
|
|
77
|
+
|
|
78
|
+
### Health check
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
$ myshell-tools doctor
|
|
82
|
+
Providers
|
|
83
|
+
✓ claude — installed, version: 2.1.157 (Claude Code)
|
|
84
|
+
auth: assumed; verified on first run
|
|
85
|
+
✓ codex — installed, version: codex-cli 0.135.0
|
|
86
|
+
Ready — at least one provider is available.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Cost & the routing counterfactual
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
$ myshell-tools cost
|
|
93
|
+
Billed total: $0.0125 (as billed, incl. caching/discounts)
|
|
94
|
+
Total calls: 1
|
|
95
|
+
Per-model breakdown
|
|
96
|
+
claude-haiku-4-5: 1 call, $0.0125
|
|
97
|
+
Counterfactual — list price, token-for-token
|
|
98
|
+
Routed (models used): $0.0010
|
|
99
|
+
Always-flagship: $0.0063
|
|
100
|
+
Routing saved you money: always-flagship would cost 6.3x more …
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The counterfactual is **apples‑to‑apples** (both routed and flagship priced the same way), and the *billed* total is shown separately and labeled — no mixing of cache‑adjusted and list prices.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## How it works
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
classify ─▶ route(cheapest tier) ─▶ run ─▶ assess
|
|
111
|
+
│
|
|
112
|
+
high-risk IC work ────────────┘──▶ cross-vendor review (other vendor)
|
|
113
|
+
approve → accept
|
|
114
|
+
revise → retry with feedback
|
|
115
|
+
escalate→ manager tier
|
|
116
|
+
low confidence / failure ─────────▶ escalate to a higher tier
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- **Tiers** map to stable model *aliases* (`haiku`/`sonnet`/`opus`, or the Codex tiers), so when a vendor ships a newer model the alias resolves to it automatically — no myshell-tools update needed.
|
|
120
|
+
- **Cost** prefers the provider CLI's own reported figure (Claude does this); otherwise it estimates from real token counts and a dated, staleness‑warned price seed.
|
|
121
|
+
- Every run is recorded to an append‑only **session log** and **cost ledger** under `.myshell-tools/`.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## The honesty contract
|
|
126
|
+
|
|
127
|
+
This is a ground‑up rebuild whose first principle is: **the tool never shows fabricated, mocked, or randomized data as if it were real.** It's enforced, not promised:
|
|
128
|
+
|
|
129
|
+
- **Architecture guard tests** fail the build if the UI/command layers contain hardcoded "AI responses", fake metrics, or a digit‑then‑`%` literal; if the orchestration core touches the filesystem, clock, or RNG directly; or if any module other than the entry point can terminate the process.
|
|
130
|
+
- **513 unit/architecture tests + 42 contract tests** (parsers pinned to *recorded real transcripts*), with `tsc --strict`, ESLint, and a clean `npm pack` checked in CI across Windows / macOS / Linux.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Architecture
|
|
135
|
+
|
|
136
|
+
Hexagonal / ports‑and‑adapters:
|
|
137
|
+
|
|
138
|
+
- `src/core/` — **pure** orchestration (classify, route, assess, review, escalate). No I/O; everything injected. 100% testable with fakes.
|
|
139
|
+
- `src/providers/` — the `Provider` port + Claude/Codex adapters (via `execa`, prompt over **stdin**, cancelable, streaming).
|
|
140
|
+
- `src/infra/` — atomic session/ledger persistence, clock, pricing seed.
|
|
141
|
+
- `src/interface/` + `src/ui/` — REPL, one‑shot runner, streaming renderer, theme.
|
|
142
|
+
- `src/commands/` — `doctor`, `cost`.
|
|
143
|
+
|
|
144
|
+
**One runtime dependency** (`execa`, for correct cross‑platform process handling — including Windows process‑tree cancellation). Everything else is the Node standard library.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npm run typecheck # tsc --strict, 0 errors
|
|
152
|
+
npm run lint # ESLint (typescript-eslint strict)
|
|
153
|
+
npm test # unit + architecture tests
|
|
154
|
+
npm run test:contract # parser contract tests vs recorded transcripts
|
|
155
|
+
npm run build # → dist/
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Status & roadmap
|
|
161
|
+
|
|
162
|
+
Honest snapshot of `2.0.0-alpha.0`:
|
|
163
|
+
|
|
164
|
+
| Area | State |
|
|
165
|
+
| --- | --- |
|
|
166
|
+
| Core routing + escalation + cross‑vendor review loop | ✅ implemented & unit‑proven |
|
|
167
|
+
| Claude adapter | ✅ live, validated end‑to‑end on real models |
|
|
168
|
+
| Codex adapter | ✅ built; auto‑activates once `codex` is installed + authed |
|
|
169
|
+
| `doctor` / `cost` / REPL / streaming UI | ✅ |
|
|
170
|
+
| Live cross‑vendor demonstration | ⏳ pending Codex auth |
|
|
171
|
+
| Cross‑OS CI run | ⏳ pending a public remote |
|
|
172
|
+
| npm publish | ⏳ alpha |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT — see [LICENSE](LICENSE).
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* src/cli.ts — single entry point for the myshell-tools CLI.
|
|
4
|
+
*
|
|
5
|
+
* This is the ONLY file in the project that may call process.exit().
|
|
6
|
+
* All other modules return values and let this file decide the exit code.
|
|
7
|
+
*/
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { systemClock } from './infra/clock.js';
|
|
10
|
+
import { createSessionWriter } from './infra/session.js';
|
|
11
|
+
import { createLedger } from './infra/ledger.js';
|
|
12
|
+
import { DEFAULT_POLICY } from './core/policy.js';
|
|
13
|
+
import { runTask } from './interface/run.js';
|
|
14
|
+
import { startRepl } from './interface/repl.js';
|
|
15
|
+
import { buildProviders } from './providers/registry.js';
|
|
16
|
+
import { runDoctor } from './commands/doctor.js';
|
|
17
|
+
import { runCost } from './commands/cost.js';
|
|
18
|
+
const require = createRequire(import.meta.url);
|
|
19
|
+
const pkg = require('../package.json');
|
|
20
|
+
const version = pkg.version;
|
|
21
|
+
const HELP = `\
|
|
22
|
+
myshell-tools v${version}
|
|
23
|
+
|
|
24
|
+
Usage: myshell-tools [command] [options]
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
-h, --help Show this help message
|
|
28
|
+
-v, --version Print version number
|
|
29
|
+
|
|
30
|
+
Commands:
|
|
31
|
+
run <task...> Run a one-shot task and exit
|
|
32
|
+
repl Start an interactive REPL session (default when no command given)
|
|
33
|
+
doctor Check provider installation, auth, and environment health
|
|
34
|
+
cost Show real spend from the ledger with a per-model breakdown
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
myshell-tools run "refactor the auth module"
|
|
38
|
+
myshell-tools repl
|
|
39
|
+
myshell-tools doctor
|
|
40
|
+
myshell-tools cost
|
|
41
|
+
myshell-tools
|
|
42
|
+
|
|
43
|
+
Repository: https://github.com/hey-vera/myshell-tools
|
|
44
|
+
`;
|
|
45
|
+
async function main() {
|
|
46
|
+
const args = process.argv.slice(2);
|
|
47
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
48
|
+
process.stdout.write(HELP);
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
52
|
+
process.stdout.write(`${version}\n`);
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Build shared infrastructure
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
const cwd = process.cwd();
|
|
59
|
+
const out = {
|
|
60
|
+
write: (s) => { process.stdout.write(s); },
|
|
61
|
+
color: process.stdout.isTTY === true && !process.env['NO_COLOR'],
|
|
62
|
+
isTty: process.stdout.isTTY === true,
|
|
63
|
+
};
|
|
64
|
+
const deps = {
|
|
65
|
+
clock: systemClock,
|
|
66
|
+
session: createSessionWriter({ cwd, id: systemClock.uuid() }),
|
|
67
|
+
ledger: createLedger({ cwd }),
|
|
68
|
+
policy: DEFAULT_POLICY,
|
|
69
|
+
providers: await buildProviders(cwd),
|
|
70
|
+
cwd,
|
|
71
|
+
sandbox: 'workspace-write',
|
|
72
|
+
timeoutMs: 120000,
|
|
73
|
+
};
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Dispatch
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
if (args[0] === 'doctor') {
|
|
78
|
+
process.exit(await runDoctor(out));
|
|
79
|
+
}
|
|
80
|
+
if (args[0] === 'cost') {
|
|
81
|
+
process.exit(await runCost(cwd, out));
|
|
82
|
+
}
|
|
83
|
+
if (args[0] === 'run') {
|
|
84
|
+
const taskParts = args.slice(1);
|
|
85
|
+
if (taskParts.length === 0) {
|
|
86
|
+
process.stderr.write('myshell-tools run: expected a task description\n');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const task = taskParts.join(' ');
|
|
90
|
+
const ac = new AbortController();
|
|
91
|
+
const code = await runTask(task, deps, out, ac.signal);
|
|
92
|
+
process.exit(code);
|
|
93
|
+
}
|
|
94
|
+
if (args.length === 0 || args[0] === 'repl') {
|
|
95
|
+
await startRepl(deps, out);
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
// Unknown command
|
|
99
|
+
process.stderr.write(`myshell-tools: unknown command "${args[0] ?? ''}"\nRun myshell-tools --help for usage.\n`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
main().catch((err) => {
|
|
103
|
+
process.stderr.write(String(err) + '\n');
|
|
104
|
+
process.exit(1);
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/commands/cost.ts — `myshell-tools cost` spend-summary command.
|
|
3
|
+
*
|
|
4
|
+
* Reads the on-disk ledger, computes real totals, and prints an honest
|
|
5
|
+
* per-model breakdown together with a counterfactual "what if you had used
|
|
6
|
+
* the manager-tier flagship for every call?" comparison.
|
|
7
|
+
*
|
|
8
|
+
* Counterfactual (apples-to-apples)
|
|
9
|
+
* ---------------------------------
|
|
10
|
+
* The "Billed total" is the real amount from the ledger (includes caching and
|
|
11
|
+
* discounts). The counterfactual compares ONLY like-for-like list prices:
|
|
12
|
+
* routed = sum over entries of listPrice(entry.model) × entry tokens
|
|
13
|
+
* flagship = sum over entries of listPrice(manager flagship) × entry tokens
|
|
14
|
+
* multiplier = flagship / routed
|
|
15
|
+
* We never compare the cache-adjusted billed total against a list-price flagship
|
|
16
|
+
* estimate — that would understate flagship and mislead.
|
|
17
|
+
*
|
|
18
|
+
* Honesty contract: every figure comes from the real ledger; no values are
|
|
19
|
+
* fabricated. If the ledger is empty the command says so and returns 0.
|
|
20
|
+
*/
|
|
21
|
+
import type { LedgerEntry } from '../core/types.js';
|
|
22
|
+
import type { OutputSink } from '../interface/render.js';
|
|
23
|
+
/**
|
|
24
|
+
* Build the cost-report lines from a (possibly empty) ledger entry array.
|
|
25
|
+
*
|
|
26
|
+
* Pure function: no I/O, no process.exit, no Date/Math.random.
|
|
27
|
+
* Called by runCost after reading the real ledger, and by unit tests.
|
|
28
|
+
*/
|
|
29
|
+
export declare function formatCostReport(entries: LedgerEntry[], color?: boolean): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Read the ledger for `cwd`, build the cost report, and write it to `out`.
|
|
32
|
+
*
|
|
33
|
+
* Returns 0 always (cost reporting is informational, not an error condition).
|
|
34
|
+
* Never calls process.exit — that is handled exclusively by src/cli.ts.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runCost(cwd: string, out: OutputSink): Promise<number>;
|