@mcpbridgeapp/cli 0.0.0-stage → 0.1.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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -3
  3. package/dist/agents/broken.d.ts +24 -0
  4. package/dist/agents/broken.js +31 -0
  5. package/dist/agents/broken.js.map +1 -0
  6. package/dist/agents/cli.d.ts +47 -0
  7. package/dist/agents/cli.js +270 -0
  8. package/dist/agents/cli.js.map +1 -0
  9. package/dist/agents/health.d.ts +38 -0
  10. package/dist/agents/health.js +53 -0
  11. package/dist/agents/health.js.map +1 -0
  12. package/dist/agents/ollama.d.ts +27 -0
  13. package/dist/agents/ollama.js +118 -0
  14. package/dist/agents/ollama.js.map +1 -0
  15. package/dist/agents/openai.d.ts +35 -0
  16. package/dist/agents/openai.js +168 -0
  17. package/dist/agents/openai.js.map +1 -0
  18. package/dist/agents/outcome.d.ts +34 -0
  19. package/dist/agents/outcome.js +96 -0
  20. package/dist/agents/outcome.js.map +1 -0
  21. package/dist/agents/permissions.d.ts +44 -0
  22. package/dist/agents/permissions.js +68 -0
  23. package/dist/agents/permissions.js.map +1 -0
  24. package/dist/agents/registry.d.ts +56 -0
  25. package/dist/agents/registry.js +167 -0
  26. package/dist/agents/registry.js.map +1 -0
  27. package/dist/agents/shim.d.ts +35 -0
  28. package/dist/agents/shim.js +53 -0
  29. package/dist/agents/shim.js.map +1 -0
  30. package/dist/agents/types.d.ts +69 -0
  31. package/dist/agents/types.js +28 -0
  32. package/dist/agents/types.js.map +1 -0
  33. package/dist/config.d.ts +99 -0
  34. package/dist/config.js +78 -0
  35. package/dist/config.js.map +1 -0
  36. package/dist/connect.d.ts +35 -0
  37. package/dist/connect.js +124 -0
  38. package/dist/connect.js.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.js +269 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/limit.d.ts +14 -0
  43. package/dist/limit.js +33 -0
  44. package/dist/limit.js.map +1 -0
  45. package/dist/protocol.d.ts +175 -0
  46. package/dist/protocol.js +86 -0
  47. package/dist/protocol.js.map +1 -0
  48. package/dist/secrets.d.ts +27 -0
  49. package/dist/secrets.js +53 -0
  50. package/dist/secrets.js.map +1 -0
  51. package/dist/server.d.ts +5 -0
  52. package/dist/server.js +97 -0
  53. package/dist/server.js.map +1 -0
  54. package/dist/tasks.d.ts +48 -0
  55. package/dist/tasks.js +103 -0
  56. package/dist/tasks.js.map +1 -0
  57. package/dist/tools.d.ts +25 -0
  58. package/dist/tools.js +71 -0
  59. package/dist/tools.js.map +1 -0
  60. package/dist/ui/page.d.ts +7 -0
  61. package/dist/ui/page.js +428 -0
  62. package/dist/ui/page.js.map +1 -0
  63. package/dist/ui/presets.d.ts +22 -0
  64. package/dist/ui/presets.js +57 -0
  65. package/dist/ui/presets.js.map +1 -0
  66. package/dist/ui/server.d.ts +38 -0
  67. package/dist/ui/server.js +567 -0
  68. package/dist/ui/server.js.map +1 -0
  69. package/package.json +95 -6
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Syed Zeeshan Ali
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.
package/README.md CHANGED
@@ -1,3 +1,346 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ <div align="center">
2
+
3
+ # mcpbridgeapp
4
+
5
+ **Let any AI app hand work to the AI tools on your own computer.**
6
+
7
+ [![npm](https://img.shields.io/npm/v/@mcpbridgeapp/cli?color=4f6bed)](https://www.npmjs.com/package/@mcpbridgeapp/cli)
8
+ [![CI](https://github.com/szeeshan896/mcpbridgeapp/actions/workflows/ci.yml/badge.svg)](https://github.com/szeeshan896/mcpbridgeapp/actions/workflows/ci.yml)
9
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
10
+
11
+ [Quick start](#quick-start) · [How it works](#how-it-works) · [Control panel](#the-control-panel) · [Agents](#agents-you-can-use) · [Safety](#safety) · [Reference](#reference)
12
+
13
+ </div>
14
+
15
+ <img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/how-it-works.png" alt="AI apps such as claude.ai, ChatGPT and Claude Code send a task to the mcpbridge.app relay, which forwards it to your computer, where mcpbridgeapp runs Claude Code, Codex, Grok, Antigravity, DeepSeek, NVIDIA or Ollama and sends the answer back" width="100%">
16
+
17
+ You are chatting with Claude on your phone. Your laptop at home has Codex, Claude Code and
18
+ Grok signed in, each on a plan you already pay for. With mcpbridgeapp you can say:
19
+
20
+ > Ask codex through mcpbridgeapp to review `payment.ts` in my shop project.
21
+
22
+ Claude passes the task to your laptop. Codex runs there, reads the real files, and its
23
+ review comes back into the same chat. **One message, work done.**
24
+
25
+ - **Use the plans you already pay for.** mcpbridgeapp runs the AI command-line tools that are
26
+ signed in on your computer. No new subscription and no API key needed for them.
27
+ - **No keys on any server.** Logins and API keys stay on your computer. The relay only
28
+ passes messages along, so a breach there leaks no AI credentials.
29
+ - **Works from anywhere.** claude.ai on the web, the desktop app and your phone, ChatGPT,
30
+ Claude Code, Cursor, or any app that speaks [MCP](https://modelcontextprotocol.io).
31
+ - **A second opinion on tap.** Have one AI check another's work, or pick the model best at
32
+ the task: a free NVIDIA coding model, DeepSeek, a local Ollama model that never touches
33
+ the internet.
34
+ - **No terminal needed.** A control panel in your browser adds agents, keys and the
35
+ connection, and tests each agent with one click.
36
+
37
+ ## Quick start
38
+
39
+ You need **[Node.js 22 or newer](https://nodejs.org)** on the computer where your AI
40
+ tools are installed. Check with `node --version`.
41
+
42
+ ### A. From claude.ai, your phone, ChatGPT and other apps
43
+
44
+ 1. **Create an account** at **[mcpbridge.app](https://mcpbridge.app)**. On the dashboard,
45
+ generate an **agent token**.
46
+ 2. **Start the control panel** on your computer:
47
+
48
+ ```bash
49
+ npx -y @mcpbridgeapp/cli ui
50
+ ```
51
+
52
+ It opens in your browser. Paste the agent token under **Relay connection**, then press
53
+ **Save & connect**. The panel turns **Online**. Keep that window open (you can minimise
54
+ it); while it runs, your agents are reachable.
55
+ 3. **Add the connector in claude.ai.** Open **Customize → Connectors → Add custom
56
+ connector**, name it `mcpbridgeapp`, and use `https://mcpbridge.app/mcp` as the URL. Press
57
+ **Connect**, sign in, and press **Allow**. Nothing to paste. The same connector then
58
+ works in the Claude desktop app and on your phone.
59
+ 4. **Ask.** In any chat, switch the mcpbridgeapp connector on (**+ → Connectors**) and say
60
+ *"list my mcpbridgeapp agents"*, then *"ask codex to …"*.
61
+
62
+ The dashboard shows the exact setup lines for Claude Code, Claude Desktop and Cursor, with
63
+ your own address filled in.
64
+
65
+ ### B. Only Claude Code, on the same computer
66
+
67
+ You don't need an account or the relay. Claude Code starts mcpbridgeapp itself:
68
+
69
+ ```bash
70
+ # macOS / Linux
71
+ claude mcp add -s user mcpbridgeapp -- npx -y @mcpbridgeapp/cli
72
+
73
+ # Windows (PowerShell or cmd)
74
+ claude mcp add -s user mcpbridgeapp -- cmd /c npx -y @mcpbridgeapp/cli
75
+ ```
76
+
77
+ Then, in Claude Code: *"ask gemini through mcpbridgeapp to review the caching layer in this
78
+ module"*. `-s user` makes it available in every folder, not just the current one.
79
+
80
+ ### Install it for good (optional)
81
+
82
+ `npx` fetches the latest version each time. To install once instead:
83
+
84
+ ```bash
85
+ npm install -g @mcpbridgeapp/cli
86
+ mcpbridgeapp ui # the control panel
87
+ mcpbridgeapp --agents # which agents are ready on this computer
88
+ ```
89
+
90
+ ## How it works
91
+
92
+ <img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/flow.png" alt="Sequence: claude.ai calls ask_agent on the relay; the relay forwards it to mcpbridgeapp on your computer; mcpbridgeapp runs codex in your folder; the answer is checked and returned the same way" width="100%">
93
+
94
+ 1. Your AI app calls mcpbridgeapp's `ask_agent` tool. It names an agent (say `codex`), writes a
95
+ self-contained task, and can pass a folder on your computer.
96
+ 2. The relay at mcpbridge.app forwards the call over a WebSocket that **your computer**
97
+ opened. Nothing on your computer listens for connections, so no ports to open and no
98
+ firewall rules.
99
+ 3. mcpbridgeapp looks the agent up in **your** configuration and runs it, e.g.
100
+ `codex exec "<task>"` in that folder. The task is passed as a single argument with no
101
+ shell involved, so text in a prompt can never become a command.
102
+ 4. The agent works the way it always does, signed in as you.
103
+ 5. mcpbridgeapp **checks the answer** before calling it a success. An agent that exits normally
104
+ but only says *"I couldn't read the files"*, or stops after *"I'll start by reading
105
+ payment.ts"*, comes back as a failure that says why. A usage limit or an expired
106
+ sign-in is remembered, so the next call is told straight away instead of waiting.
107
+ 6. The answer travels back the same way into your chat.
108
+
109
+ Close the laptop and the dashboard shows **offline**. That is the point, not a
110
+ limitation: the work happens where your logins are, which is why the server needs none.
111
+
112
+ ## The control panel
113
+
114
+ ```bash
115
+ npx -y @mcpbridgeapp/cli ui # or: mcpbridgeapp ui
116
+ ```
117
+
118
+ <img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/control-panel.png" alt="The mcpbridgeapp control panel: relay connection Online as my-laptop, and a list of agents (antigravity, claude, codex, deepseek, gemini, grok, an NVIDIA model, ollama), each ready, with Test, Edit and Customise buttons" width="100%">
119
+
120
+ A page on your own computer (`http://127.0.0.1:8809`) that does everything this README does
121
+ with commands:
122
+
123
+ - **Connect to the relay.** Paste the agent token once. The page keeps the computer online
124
+ while it is open, reconnects by itself the next time you open it, and sends a newly added
125
+ agent to the relay straight away.
126
+ - **Add an agent from a preset.** NVIDIA (free tier), DeepSeek, Grok, OpenRouter, Groq,
127
+ Mistral, Ollama, or any OpenAI-compatible service or command-line tool. Paste the key,
128
+ press **List models**, pick one and save. To keep several models from one provider, tick
129
+ them under **Add several models at once**. Each becomes its own agent, named after its
130
+ model (`nvidia-qwen3-coder-480b`).
131
+ - **Test** any agent with a one-word prompt and see the answer or the exact error.
132
+ - **Allow edits or commands** per agent (see [Safety](#safety)).
133
+
134
+ **On Windows**, if you cloned the repository, double-click `start-ui.cmd`. Put a shortcut to
135
+ it on your desktop to start mcpbridgeapp with one click.
136
+
137
+ Keys and the agent token are saved in `~/.config/mcpbridge/secrets.json` on your computer.
138
+ They are never written to `config.json` and never sent to the relay. The page answers only on
139
+ 127.0.0.1, and only to the browser that opened the link it printed.
140
+
141
+ ## The dashboard
142
+
143
+ <img src="https://raw.githubusercontent.com/szeeshan896/mcpbridgeapp/main/docs/images/dashboard.png" alt="The mcpbridge.app dashboard: your machine is Online as my-laptop, with each agent listed as available and what it may do" width="100%">
144
+
145
+ [mcpbridge.app](https://mcpbridge.app) shows whether your computer is online and which agents
146
+ it offers. It is also where you manage tokens, turn on 2-step verification, and see and
147
+ disconnect the apps you have allowed.
148
+
149
+ ## Agents you can use
150
+
151
+ | Agent | What it is | Needs |
152
+ |---|---|---|
153
+ | `claude` | Claude Code | `claude` installed and signed in |
154
+ | `codex` | OpenAI Codex CLI | `codex` installed and signed in |
155
+ | `grok` | Grok Build CLI | `grok` installed and signed in |
156
+ | `antigravity` | Google's Antigravity CLI (`agy`), Gemini models | `agy` installed and signed in |
157
+ | `gemini` | Gemini CLI | `gemini` installed and signed in |
158
+ | `ollama` | a model running locally in [Ollama](https://ollama.com) | Ollama and one pulled model. No account, works offline |
159
+ | anything else | DeepSeek, NVIDIA, xAI API, OpenRouter, Groq, Mistral, LM Studio, … | an API key, added in the control panel |
160
+
161
+ The first six are built in: install the tool, sign in once in a terminal, and it shows up.
162
+ Anything not installed is listed as unavailable, never silently broken. Check from a
163
+ terminal:
164
+
165
+ ```bash
166
+ npx -y @mcpbridgeapp/cli --agents
167
+ ```
168
+
169
+ ```
170
+ ✓ claude claude found on PATH
171
+ ✓ codex codex found on PATH
172
+ ✗ gemini gemini is not on PATH — install it or fix the command
173
+ ✓ ollama Ollama at http://127.0.0.1:11434, using qwen3:latest
174
+ ```
175
+
176
+ Using these tools removes the key, not the quota: each one still spends its own plan's
177
+ limits.
178
+
179
+ ## Tools your AI app gets
180
+
181
+ | Tool | What it does |
182
+ |---|---|
183
+ | `list_agents` | which agents exist, whether each is ready, what each may do, and whether your computer is online |
184
+ | `ask_agent` | give one agent a task, wait, get the answer |
185
+ | `start_task` | the same, but returns an id at once, for work longer than the app will wait |
186
+ | `get_task` | check on a started task: queued, running (with the output so far), or finished |
187
+
188
+ The agent you delegate to starts fresh. It cannot see your chat, so the calling AI writes a
189
+ complete task and passes `workingDirectory` when it is about code.
190
+
191
+ Every answer says honestly how it went:
192
+
193
+ - **`succeeded`** is true only if the agent actually did the work, not just because its
194
+ program exited normally.
195
+ - **`status`** in `list_agents` is `ready`, `unavailable`, `quota-exhausted`,
196
+ `sign-in-failed` or `directory-not-trusted`, with the last error and, when the agent
197
+ named one, when to retry. A limit is remembered for an hour, a failed sign-in for six,
198
+ and any success clears it.
199
+ - **`writesFiles`** and **`runsCommands`** say what the agent is allowed to do, so the
200
+ calling AI hands file-changing work only to an agent that can do it.
201
+ - **`diagnostics`** is short and to the point. `notes` carries what you should know about a
202
+ success, such as tokens spent or an answer cut short.
203
+ - On a **timeout**, whatever the agent had written so far comes back, marked incomplete.
204
+ - **Tasks queue.** Two delegations run at once by default. The rest wait their turn, and
205
+ `get_task` says where they are in the queue.
206
+
207
+ ## Safety
208
+
209
+ mcpbridgeapp runs programs on your computer for apps on the internet, so it is careful by
210
+ default.
211
+
212
+ **Agents are read-only until you allow more.** Every agent starts unable to change files
213
+ or run commands. In the control panel, press **Edit** (or **Customise** for a built-in)
214
+ and tick what it may do. mcpbridgeapp turns that into the tool's own flags:
215
+
216
+ | CLI | Change files | Run commands |
217
+ |---|---|---|
218
+ | claude | `--permission-mode acceptEdits` | `--allowedTools Bash` |
219
+ | codex | `--sandbox workspace-write` (one switch for both; still no network) | same |
220
+ | grok | `--always-approve` (all or nothing) | same |
221
+ | gemini | `--approval-mode auto_edit` | `--approval-mode yolo` |
222
+ | agy (Antigravity) | `--mode accept-edits` | `--dangerously-skip-permissions` (allows edits too) |
223
+
224
+ Allow only what you are happy for every app connected to your account to do on your
225
+ computer. Some tools can't even read files without approval when no one is there to give
226
+ it: Grok Build, for one, reads with shell commands. Such an agent needs **Change files**
227
+ ticked before it can review code.
228
+
229
+ **Commands come only from your configuration.** A tool call can name an agent, never a
230
+ command. The prompt reaches the program as one argument with no shell, so `;`, `&&` and
231
+ backticks in a prompt arrive as plain text. A test checks exactly that.
232
+
233
+ **The relay holds no AI credentials.** It stores accounts, password hashes and token
234
+ hashes, never an API key or a CLI login. Tokens are shown once. claude.ai and Claude Code
235
+ sign in through OAuth with PKCE, and every app you allow is listed on the dashboard, where
236
+ you can disconnect it. 2-step verification with an authenticator app is available.
237
+
238
+ **Local servers stay local.** The control panel and the optional HTTP mode listen on
239
+ 127.0.0.1 only, and refuse requests from other websites.
240
+
241
+ ## Reference
242
+
243
+ ### Commands
244
+
245
+ ```
246
+ mcpbridgeapp MCP server over stdio (what Claude Code starts)
247
+ mcpbridgeapp ui [--port N] the control panel in your browser
248
+ mcpbridgeapp connect stay connected to the relay (uses the saved token,
249
+ [--relay URL --token T] or pass them here)
250
+ mcpbridgeapp --agents which agents are ready here
251
+ mcpbridgeapp --ask <agent> "…" delegate once from the terminal, to test an agent
252
+ mcpbridgeapp --http [port] one shared HTTP server on 127.0.0.1 (default 8808)
253
+ mcpbridgeapp --example-config print a starter config
254
+ ```
255
+
256
+ ### Configuration
257
+
258
+ Everything the control panel does is saved in `~/.config/mcpbridge/config.json` (set
259
+ `MCPBRIDGE_CONFIG` to use another file). You can also write it by hand. An entry replaces the
260
+ built-in agent of the same name.
261
+
262
+ ```json
263
+ {
264
+ "maxConcurrent": 2,
265
+ "agents": {
266
+ "codex": {
267
+ "command": ["codex", "exec", "--skip-git-repo-check", "{prompt}"],
268
+ "allow": { "edits": true, "commands": true },
269
+ "timeoutMs": 600000
270
+ },
271
+ "deepseek": {
272
+ "type": "openai",
273
+ "baseUrl": "https://api.deepseek.com/v1",
274
+ "model": "<a model id: List models in the control panel shows them>",
275
+ "apiKeyEnv": "DEEPSEEK_API_KEY"
276
+ },
277
+ "local": { "type": "ollama", "model": "qwen3:latest" }
278
+ }
279
+ }
280
+ ```
281
+
282
+ | Field | Meaning |
283
+ |---|---|
284
+ | `command` | the program and its arguments. `{prompt}` is replaced by the task, as one argument |
285
+ | `promptVia` | `"argv"` (default) or `"stdin"`. Use stdin for long prompts: Windows limits an argument to about 32 KB |
286
+ | `allow` | `{ "edits": true, "commands": true, "trustDirectory": true }`, the same switches as the control panel |
287
+ | `capabilities` | for a CLI mcpbridgeapp doesn't know: declare `{ "writesFiles": true, "runsCommands": true }` yourself |
288
+ | `env` | extra environment variables for that agent |
289
+ | `timeoutMs` | how long one call may run (default 5 minutes) |
290
+ | `type: "openai"` | any service with `POST /v1/chat/completions`: `baseUrl`, `model`, `apiKeyEnv` |
291
+ | `type: "ollama"` | a local Ollama model: `model`, optional `baseUrl` |
292
+ | `maxConcurrent` | how many delegations run at once (default 2) |
293
+
294
+ `apiKeyEnv` is the **name** of an environment variable, not the key, so a config file can be
295
+ shared without leaking anything. Keys saved in the control panel go to `secrets.json` and are
296
+ loaded into that variable. A variable you export yourself still wins.
297
+
298
+ ### Troubleshooting
299
+
300
+ | You see | What to do |
301
+ |---|---|
302
+ | Panel or dashboard says **offline** | Start `mcpbridgeapp ui` (or `mcpbridgeapp connect`) and keep its window open |
303
+ | `sign-in-failed`, *"session expired"* | Run that tool once in a terminal and sign in again |
304
+ | `quota-exhausted` | The tool's plan hit its limit. Wait for `retryAt`, or use another agent |
305
+ | Agent times out, or says it *needs permission* | It stopped at an approval prompt. Allow edits or commands for it, or ask only for a reading |
306
+ | Gemini CLI: `IneligibleTierError` | Google withdrew Gemini CLI for personal accounts. Use the built-in `antigravity` agent, same models, same login |
307
+ | `directory-not-trusted` | Tick *Trust the working directory* for that agent, if you trust the folders your apps send it |
308
+ | Codex: *not a git repository* | Point it at a git repository, or add `--skip-git-repo-check` to its command |
309
+ | Claude Code doesn't see the tools | Add it with `-s user`, then restart Claude Code. Check with `claude mcp list` |
310
+
311
+ **Windows:** npm-installed CLIs are `.cmd` files, which Node can't run without a shell, and a
312
+ prompt must never go through a shell. mcpbridgeapp reads the `.cmd` file and runs the real
313
+ program it points to, so `claude`, `codex` and the rest work as they are.
314
+
315
+ ### Run your own relay
316
+
317
+ mcpbridge.app is one instance of the relay in [`relay/`](relay/README.md). You can host your
318
+ own: it is one Docker image with a SQLite database, and deploys to Railway, Fly.io or any
319
+ VPS. Accounts use email or phone, a password or Google, with optional 2-step verification.
320
+
321
+ ## Development
322
+
323
+ ```bash
324
+ git clone https://github.com/szeeshan896/mcpbridgeapp.git
325
+ cd mcpbridgeapp
326
+ npm install # also builds dist/
327
+ npm test # typecheck and tests
328
+ npm start # the stdio server, from source
329
+ cd relay && npm install && npm test
330
+ ```
331
+
332
+ ```
333
+ src/agents/ running each kind of agent: cli.ts, openai.ts, ollama.ts; judging an
334
+ answer (outcome.ts); remembered failures (health.ts); permission flags
335
+ (permissions.ts); Windows .cmd shims (shim.ts)
336
+ src/ui/ the control panel
337
+ src/connect.ts the outbound connection to a relay; src/protocol.ts its messages
338
+ src/tools.ts the four tools, shared by the local server and the relay path
339
+ src/tasks.ts background tasks and their queue
340
+ relay/ the hosted relay: accounts, OAuth, tokens, 2FA, dashboard, forwarding
341
+ test/fixtures/ a stand-in agent CLI, so the suite runs on Windows, macOS and Linux
342
+ ```
343
+
344
+ ## License
345
+
346
+ [MIT](LICENSE) © Syed Zeeshan Ali
@@ -0,0 +1,24 @@
1
+ import { type Agent, type AgentResult } from './types.js';
2
+ /**
3
+ * Stands in for an agent whose configuration could not be used.
4
+ *
5
+ * <p>Without this, one bad entry in the config file threw during startup and took the
6
+ * whole bridge with it — every other agent included — and over stdio the client saw only
7
+ * a process that died, with the reason going nowhere a person would look.
8
+ */
9
+ export declare class BrokenAgent implements Agent {
10
+ readonly name: string;
11
+ readonly reason: string;
12
+ readonly readsFiles = false;
13
+ readonly writesFiles = false;
14
+ readonly runsCommands = false;
15
+ readonly timeoutMs = 0;
16
+ readonly requires = "a valid configuration";
17
+ constructor(name: string, reason: string);
18
+ get description(): string;
19
+ probe(): Promise<{
20
+ available: boolean;
21
+ detail: string;
22
+ }>;
23
+ run(): Promise<AgentResult>;
24
+ }
@@ -0,0 +1,31 @@
1
+ import { failed } from './types.js';
2
+ /**
3
+ * Stands in for an agent whose configuration could not be used.
4
+ *
5
+ * <p>Without this, one bad entry in the config file threw during startup and took the
6
+ * whole bridge with it — every other agent included — and over stdio the client saw only
7
+ * a process that died, with the reason going nowhere a person would look.
8
+ */
9
+ export class BrokenAgent {
10
+ name;
11
+ reason;
12
+ readsFiles = false;
13
+ writesFiles = false;
14
+ runsCommands = false;
15
+ timeoutMs = 0;
16
+ requires = 'a valid configuration';
17
+ constructor(name, reason) {
18
+ this.name = name;
19
+ this.reason = reason;
20
+ }
21
+ get description() {
22
+ return `misconfigured: ${this.reason}`;
23
+ }
24
+ async probe() {
25
+ return { available: false, detail: `misconfigured: ${this.reason}` };
26
+ }
27
+ async run() {
28
+ return failed(this.name, `agent "${this.name}" is misconfigured: ${this.reason}`);
29
+ }
30
+ }
31
+ //# sourceMappingURL=broken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broken.js","sourceRoot":"","sources":["../../src/agents/broken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IAQX;IACA;IARF,UAAU,GAAG,KAAK,CAAC;IACnB,WAAW,GAAG,KAAK,CAAC;IACpB,YAAY,GAAG,KAAK,CAAC;IACrB,SAAS,GAAG,CAAC,CAAC;IACd,QAAQ,GAAG,uBAAuB,CAAC;IAE5C,YACW,IAAY,EACZ,MAAc;QADd,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAQ;IACtB,CAAC;IAEJ,IAAI,WAAW;QACb,OAAO,kBAAkB,IAAI,CAAC,MAAM,EAAE,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,GAAG;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,IAAI,CAAC,IAAI,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ import type { CliAgentConfig } from '../config.js';
2
+ import { type Permissions } from './permissions.js';
3
+ import { type Agent, type AgentResult, type RunOptions } from './types.js';
4
+ export declare const PROMPT_PLACEHOLDER = "{prompt}";
5
+ /**
6
+ * An agent that is a command-line tool. The command comes from configuration and the
7
+ * prompt only ever fills {prompt} or goes down stdin — never through a shell, so nothing
8
+ * in a prompt can be read as a shell metacharacter.
9
+ */
10
+ export declare class CliAgent implements Agent {
11
+ readonly name: string;
12
+ private readonly config;
13
+ private readonly maxOutputChars;
14
+ readonly requires: string;
15
+ readonly readsFiles = true;
16
+ readonly permissions: Permissions;
17
+ constructor(name: string, config: CliAgentConfig, maxOutputChars: number);
18
+ get writesFiles(): boolean;
19
+ get runsCommands(): boolean;
20
+ get timeoutMs(): number;
21
+ private get promptVia();
22
+ get description(): string;
23
+ probe(): Promise<{
24
+ available: boolean;
25
+ detail: string;
26
+ }>;
27
+ run(prompt: string, options: RunOptions): Promise<AgentResult>;
28
+ private spawnAgent;
29
+ private startupAdvice;
30
+ }
31
+ /**
32
+ * Turns a spawn failure into something the caller can act on. The size limit varies by
33
+ * platform — roughly 128KB per argument on Linux, about 1MB on macOS, and as little as
34
+ * 32KB on Windows — so the advice names the setting that removes it rather than a number.
35
+ */
36
+ export declare function startupAdvice(agent: string, command: string, error: Error & {
37
+ code?: string;
38
+ }, prompt: string): string;
39
+ /**
40
+ * A .cmd or .bat can only be run through a shell, and running the prompt through a shell
41
+ * is exactly what this program must never do: quoting rules for batch files are their own
42
+ * minefield (see CVE-2024-27980). So such an agent is refused with the fix, rather than
43
+ * made to work unsafely or left to fail as a bare ENOENT.
44
+ */
45
+ export declare function needsAShell(resolvedPath: string): boolean;
46
+ export declare function resolveOnPath(executable: string): Promise<string | null>;
47
+ export declare function onPath(executable: string): Promise<boolean>;