wraptc 0.0.1

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,520 @@
1
+ # wraptc
2
+
3
+ A unified CLI wrapper for multiple coding AI agents (Gemini CLI, OpenCode, Qwen Code, Codex CLI) with intelligent routing, credit tracking, and automatic fallback.
4
+
5
+ ## Features
6
+
7
+ - **Multi-Provider Support**: Works with Gemini CLI, OpenCode, Qwen Code CLI, Codex CLI, and custom providers
8
+ - **Intelligent Routing**: Automatic provider selection based on priority, availability, and credit limits
9
+ - **Credit Tracking**: Per-provider usage tracking and automatic fallback when limits are reached
10
+ - **Error Threshold Blacklisting**: Automatic provider blacklisting after consecutive failures (configurable per provider)
11
+ - **Tokens Saved Tracking**: Estimates Claude tokens saved by delegating tasks to free-tier providers
12
+ - **Streaming Support**: Real-time streaming of responses in JSON or text format
13
+ - **Unified API**: Single, consistent JSON-first interface across all providers
14
+ - **MCP Server**: Exposes functionality as an MCP server for Claude Desktop and other MCP clients
15
+
16
+ ## Installation
17
+
18
+ **Requires: [Bun](https://bun.sh/) runtime**
19
+
20
+ ```bash
21
+ # Install via npm (requires Bun to be installed)
22
+ npm install -g wraptc
23
+
24
+ # Or install via bun
25
+ bun install -g wraptc
26
+
27
+ # Or clone and build from source
28
+ git clone https://github.com/briansunter/wraptc.git
29
+ cd wraptc
30
+ bun install
31
+ bun run build
32
+ bun link
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ### Basic Usage
38
+
39
+ ```bash
40
+ # Simple request using best available provider
41
+ wraptc ask -p "Write a TypeScript function that reverses a string"
42
+
43
+ # Specify a provider
44
+ wraptc ask -p "Explain this code" --provider gemini
45
+
46
+ # Include file context
47
+ wraptc ask -p "Refactor this module" -f src/utils.ts -f src/main.ts
48
+
49
+ # Stream response
50
+ wraptc ask -p "Create unit tests" --stream --output jsonl
51
+ ```
52
+
53
+ ### Output Formats
54
+
55
+ **JSON (default)**:
56
+
57
+ ```json
58
+ {
59
+ "provider": "qwen-code",
60
+ "text": "function reverseString(str: string): string {\n return str.split('').reverse().join('');\n}",
61
+ "usage": {
62
+ "inputTokens": 45,
63
+ "outputTokens": 23
64
+ },
65
+ "meta": {
66
+ "elapsedMs": 1250
67
+ }
68
+ }
69
+ ```
70
+
71
+ **Text**:
72
+
73
+ ```bash
74
+ wraptc ask -p "Write a function" --output text
75
+ ```
76
+
77
+ ## Configuration
78
+
79
+ wraptc uses a layered configuration system:
80
+
81
+ 1. Built-in defaults
82
+ 2. System config: `/etc/wraptc/config.json`
83
+ 3. User config: `~/.config/wraptc/config.json`
84
+ 4. Project config: `./.config/wraptc/config.json`
85
+ 5. Environment variables: `WTC_*`
86
+ 6. CLI flags
87
+
88
+ ### Example Configuration
89
+
90
+ Create `~/.config/wraptc/config.json`:
91
+
92
+ ```json
93
+ {
94
+ "routing": {
95
+ "defaultOrder": ["gemini", "opencode", "qwen-code", "codex"],
96
+ "perModeOverride": {
97
+ "test": ["codex", "gemini"],
98
+ "explain": ["gemini", "qwen-code"]
99
+ }
100
+ },
101
+ "providers": {
102
+ "gemini": {
103
+ "binary": "gemini",
104
+ "args": [],
105
+ "jsonMode": "flag",
106
+ "jsonFlag": "--output-format",
107
+ "streamingMode": "jsonl",
108
+ "capabilities": ["generate", "edit", "explain", "test"]
109
+ },
110
+ "opencode": {
111
+ "binary": "opencode",
112
+ "args": [],
113
+ "jsonMode": "flag",
114
+ "jsonFlag": "-f",
115
+ "streamingMode": "none",
116
+ "capabilities": ["generate", "edit", "explain", "test", "refactor"]
117
+ },
118
+ "qwen-code": {
119
+ "binary": "qwen",
120
+ "args": [],
121
+ "jsonMode": "flag",
122
+ "jsonFlag": "--json",
123
+ "streamingMode": "jsonl",
124
+ "capabilities": ["generate", "edit", "explain", "test"]
125
+ },
126
+ "codex": {
127
+ "binary": "cdx",
128
+ "args": [],
129
+ "jsonMode": "none",
130
+ "streamingMode": "line",
131
+ "capabilities": ["generate", "edit", "test"]
132
+ }
133
+ },
134
+ "credits": {
135
+ "providers": {
136
+ "gemini": {
137
+ "dailyRequestLimit": 1000,
138
+ "resetHourUtc": 0
139
+ },
140
+ "opencode": {
141
+ "dailyRequestLimit": 1000,
142
+ "resetHourUtc": 0
143
+ },
144
+ "qwen-code": {
145
+ "dailyRequestLimit": 2000,
146
+ "resetHourUtc": 0
147
+ },
148
+ "codex": {
149
+ "plan": "chatgpt_plus"
150
+ }
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ ### Adding Custom Providers
157
+
158
+ You can add new providers via configuration:
159
+
160
+ ```json
161
+ {
162
+ "providers": {
163
+ "my-custom-llm": {
164
+ "binary": "my-llm-cli",
165
+ "argsTemplate": ["--model", "gpt-4", "--prompt", "{{prompt}}"],
166
+ "streamingMode": "line",
167
+ "capabilities": ["generate", "explain"]
168
+ }
169
+ },
170
+ "routing": {
171
+ "defaultOrder": ["my-custom-llm", "qwen-code", "gemini"]
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Environment Variables
177
+
178
+ Override config with environment variables:
179
+
180
+ ```bash
181
+ WRAPTC_ROUTING__DEFAULT_ORDER='["gemini","codex"]' wraptc ask -p "Hello"
182
+ WRAPTC_REQUEST__PROVIDER="gemini" wraptc ask -p "Hello"
183
+ ```
184
+
185
+ ## CLI Commands
186
+
187
+ ### `wraptc ask`
188
+
189
+ Send a coding request to the best available provider.
190
+
191
+ ```bash
192
+ wraptc ask -p "Your prompt" [options]
193
+
194
+ Options:
195
+ -p, --prompt <prompt> The prompt to send
196
+ --provider <provider> Override provider selection
197
+ --mode <mode> Request mode: generate, edit, explain, test
198
+ --language <language> Language hint
199
+ -f, --file <files...> Include file context
200
+ --temperature <temp> Temperature (0-2)
201
+ --stream Enable streaming
202
+ --output <format> Output format: json, jsonl, text
203
+ --dry-run Show which provider would be used
204
+ --config <path> Config file path
205
+ ```
206
+
207
+ ### `wraptc providers`
208
+
209
+ List all available providers and their status.
210
+
211
+ ```bash
212
+ wraptc providers
213
+ ```
214
+
215
+ ### `wraptc reset`
216
+
217
+ Reset provider state (counters, error tracking).
218
+
219
+ ```bash
220
+ wraptc reset --provider qwen-code # Reset specific provider
221
+ wraptc reset --all # Reset all providers
222
+ ```
223
+
224
+ ### `ultrathink`
225
+
226
+ Alias for enhanced reasoning mode.
227
+
228
+ ```bash
229
+ ultrathink -p "Explain this complex algorithm in detail"
230
+ ```
231
+
232
+ ## MCP Server
233
+
234
+ The MCP server exposes wraptc functionality to MCP clients.
235
+
236
+ ### Running the MCP Server
237
+
238
+ ```bash
239
+ # Directly
240
+ bun run packages/mcp-server/src/server.ts
241
+
242
+ # With config
243
+ WTC_CONFIG=/path/to/config.json bun run packages/mcp-server/src/server.ts
244
+ ```
245
+
246
+ ### MCP Tools
247
+
248
+ #### `run_coding_task`
249
+
250
+ Execute a coding task using the best available provider.
251
+
252
+ **Parameters:**
253
+
254
+ - `prompt` (string, required): The coding task prompt
255
+ - `mode` (string, optional): generate, edit, explain, or test
256
+ - `language` (string, optional): Language hint
257
+ - `files` (array of strings, optional): File paths for context
258
+ - `provider` (string, optional): Specific provider to use
259
+
260
+ **Response:**
261
+
262
+ ```json
263
+ {
264
+ "provider": "qwen-code",
265
+ "text": "Generated code...",
266
+ "usage": { "inputTokens": 100, "outputTokens": 50 }
267
+ }
268
+ ```
269
+
270
+ #### `get_providers`
271
+
272
+ List all available providers and their current status.
273
+
274
+ **Response:**
275
+
276
+ ```json
277
+ [
278
+ {
279
+ "id": "qwen-code",
280
+ "displayName": "Qwen Code CLI",
281
+ "requestsToday": 42,
282
+ "outOfCreditsUntil": null
283
+ }
284
+ ]
285
+ ```
286
+
287
+ #### `dry_run`
288
+
289
+ Show which provider would be used for a request without executing it.
290
+
291
+ **Parameters:**
292
+
293
+ - `prompt` (string, required)
294
+ - `mode` (string, optional)
295
+ - `provider` (string, optional)
296
+
297
+ ## Architecture
298
+
299
+ ### Core Components
300
+
301
+ 1. **Provider Abstraction** (`packages/core/src/providers/`)
302
+ - `Provider` interface for unified provider API
303
+ - Adapters for Gemini, Qwen Code, Codex, and custom providers
304
+ - Streaming and non-streaming support
305
+
306
+ 2. **Router** (`packages/core/src/router.ts`)
307
+ - Provider selection based on priority and availability
308
+ - Automatic fallback on errors or credit exhaustion
309
+ - Per-mode routing overrides
310
+
311
+ 3. **State Manager** (`packages/core/src/state.ts`)
312
+ - Per-provider usage tracking
313
+ - Credit limit enforcement
314
+ - Error history and cooldown management
315
+
316
+ 4. **Config Loader** (`packages/core/src/config.ts`)
317
+ - Multi-source configuration merging
318
+ - Environment variable support
319
+ - Validation with Zod
320
+
321
+ 5. **CLI** (`packages/cli/src/index.ts`)
322
+ - Commander-based CLI with multiple commands
323
+ - Support for streaming and multiple output formats
324
+
325
+ 6. **MCP Server** (`packages/mcp-server/src/server.ts`)
326
+ - MCP protocol implementation
327
+ - Tool-based interface for MCP clients
328
+
329
+ ## Error Handling
330
+
331
+ The wrapper classifies errors into categories:
332
+
333
+ - `OUT_OF_CREDITS`: Provider has exhausted quota
334
+ - `RATE_LIMIT`: Provider is rate limited
335
+ - `TRANSIENT`: Temporary error, retryable
336
+ - `BAD_REQUEST`: Invalid request, don't retry
337
+ - `INTERNAL`: Provider internal error
338
+
339
+ When a provider fails, the router automatically tries the next available provider in the priority list.
340
+
341
+ ## State File
342
+
343
+ State is persisted to `~/.config/wraptc/state.json`:
344
+
345
+ ```json
346
+ {
347
+ "version": "1.0.0",
348
+ "providers": {
349
+ "qwen-code": {
350
+ "lastUsedAt": "2025-01-20T10:30:00Z",
351
+ "requestsToday": 42,
352
+ "lastReset": "2025-01-20T00:00:00Z",
353
+ "outOfCreditsUntil": null,
354
+ "lastErrors": []
355
+ }
356
+ }
357
+ }
358
+ ```
359
+
360
+ ## Development
361
+
362
+ ```bash
363
+ # Install dependencies
364
+ bun install
365
+
366
+ # Build all packages
367
+ bun run build
368
+
369
+ # Development mode with watch
370
+ bun run dev
371
+
372
+ # Run tests
373
+ bun test
374
+
375
+ # Lint
376
+ bun run lint
377
+
378
+ # Type check
379
+ bun run typecheck
380
+ ```
381
+
382
+ ## Examples
383
+
384
+ ### Generate Code
385
+
386
+ ```bash
387
+ wraptc ask -p "Write a Python function to parse CSV data" --language python
388
+ ```
389
+
390
+ ### Explain Code
391
+
392
+ ```bash
393
+ wraptc ask -p "Explain this function" -f src/complex.ts --mode explain
394
+ ```
395
+
396
+ ### Edit with Context
397
+
398
+ ```bash
399
+ wraptc ask -p "Refactor to use async/await" -f src/api.ts --mode edit
400
+ ```
401
+
402
+ ### Test Generation
403
+
404
+ ```bash
405
+ wraptc ask -p "Create unit tests" -f src/utils.ts --mode test
406
+ ```
407
+
408
+ ### Stream Response
409
+
410
+ ```bash
411
+ wraptc ask -p "Write a long document" --stream --output jsonl
412
+ ```
413
+
414
+ ### Check Provider Status
415
+
416
+ ```bash
417
+ wraptc providers
418
+ ```
419
+
420
+ ## Troubleshooting
421
+
422
+ ### Provider Not Found
423
+
424
+ Ensure the CLI tool is installed and in your PATH:
425
+
426
+ ```bash
427
+ which gemini # Should show path
428
+ gemini --help # Should work
429
+ ```
430
+
431
+ ### Credit Limit Issues
432
+
433
+ Check provider status:
434
+
435
+ ```bash
436
+ wraptc providers
437
+ ```
438
+
439
+ Reset if needed:
440
+
441
+ ```bash
442
+ wraptc reset --provider qwen-code
443
+ ```
444
+
445
+ ### Configuration Issues
446
+
447
+ Validate your config:
448
+
449
+ ```bash
450
+ # The tool validates on startup and will show errors
451
+ wraptc ask -p "test" --dry-run
452
+ ```
453
+
454
+ ### Debug Mode
455
+
456
+ Enable debug logging:
457
+
458
+ ```bash
459
+ DEBUG=1 wraptc ask -p "Hello"
460
+ ```
461
+
462
+ ## MCP Server
463
+
464
+ wraptc includes an MCP (Model Context Protocol) server for integration with Claude Desktop and other MCP-compatible tools.
465
+
466
+ ### Starting the MCP Server
467
+
468
+ ```bash
469
+ # Using the --mcp flag
470
+ wraptc --mcp
471
+
472
+ # Or using the mcp command
473
+ wraptc mcp
474
+ ```
475
+
476
+ ### MCP Tools
477
+
478
+ The MCP server exposes the following tools:
479
+
480
+ - **run_coding_task**: Execute a coding task using the best available provider
481
+ - **get_providers**: List all available providers and their current status
482
+ - **dry_run**: Show which provider would be used for a request without executing it
483
+
484
+ ### Claude Desktop Integration
485
+
486
+ Add to your Claude Desktop configuration (`claude_desktop_config.json`):
487
+
488
+ ```json
489
+ {
490
+ "mcpServers": {
491
+ "wraptc": {
492
+ "command": "wraptc",
493
+ "args": ["--mcp"]
494
+ }
495
+ }
496
+ }
497
+ ```
498
+
499
+ ## Publishing
500
+
501
+ This project uses **Bitwarden Secrets Manager (BWS)** for secure npm token management in CI/CD. See [docs/PUBLISHING_CHECKLIST.md](docs/PUBLISHING_CHECKLIST.md) for setup instructions and [docs/PUBLISHING.md](docs/PUBLISHING.md) for detailed documentation.
502
+
503
+ **Why BWS?**
504
+ - No npm tokens stored in GitHub Secrets
505
+ - On-demand secret retrieval with audit logs
506
+ - Centralized secret management
507
+ - Works with Bun (unlike OIDC)
508
+ - Single location for token rotation
509
+
510
+ **Quick setup:**
511
+ 1. Create BWS project: `bws project create "npm-publishing"`
512
+ 2. Store npm token in BWS: `bws secret create NPM_TOKEN "<token>" <project-id>`
513
+ 3. Add `BWS_ACCESS_TOKEN` and `BWS_NPM_TOKEN_ID` to GitHub Secrets
514
+ 4. Push to `master` branch with conventional commits
515
+ 5. GitHub Actions fetches token from BWS and publishes!
516
+
517
+ ## License
518
+
519
+ MIT
520
+ # Test
package/bin/wraptc ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import('../dist/index.js');