premanmcp 0.16.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,223 +1,38 @@
1
- # PreMan MCP
1
+ # `premanmcp` 1.0
2
2
 
3
- Turn your APIs into MCP tools that coding agents can discover, call, test, and audit.
4
-
5
- PreMan is agent-first API infrastructure. It lets backend teams expose endpoints to AI coding agents through MCP, add an auth layer around those tools, and see exactly which agent called what.
6
-
7
- ## Start
8
-
9
- ```bash
10
- npm exec -y premanmcp@latest -- onboard
11
- ```
12
-
13
- Create the account, verify the email, get the PreMan app installed and opened already
14
- signed in, and hook this repo so `git push` checks the endpoints you touched. A bare
15
- `preman` in a terminal does the same thing.
16
-
17
- ## Connect a coding agent
18
-
19
- ```bash
20
- npm exec -y premanmcp@latest -- connect
21
- ```
22
-
23
- Optional, and separate from starting out. Pick your coding agent from the list — Cursor,
24
- Claude Code, or Codex — and PreMan writes that agent's MCP config for you. No hand-edited
25
- config anywhere.
26
-
27
- Local development form:
28
-
29
- ```bash
30
- node bin/cli.js connect
31
- ```
32
-
33
- First-time users are asked for an email and the code sent to it — no password: the
34
- terminal's credential is the `pm_live_` key. Pass `--password` to also set one for
35
- dashboard sign-in, or set it later from the dashboard. PreMan creates or connects the
36
- account, generates an API key, saves it to `~/.preman/credentials.json`, then writes a
37
- `preman` MCP server into the config your agent actually reads (`~/.cursor/mcp.json`,
38
- Claude Code's MCP config, or `~/.codex/config.toml`):
39
-
40
- ```json
41
- {
42
- "mcpServers": {
43
- "preman": {
44
- "command": "npm",
45
- "args": ["exec", "-y", "premanmcp@latest", "--"],
46
- "env": {
47
- "PREMAN_BACKEND": "https://api.preman.live",
48
- "PREMAN_FRONTEND": "https://app.preman.live"
49
- }
50
- }
51
- }
52
- }
53
- ```
54
-
55
- `connect` reads the config back after writing it, and prints a copy-paste snippet if it
56
- cannot confirm the entry landed. Then it finishes the link itself rather than asking you
57
- to go restart anything, in cheapest-first order:
58
-
59
- 1. **Self-test.** It starts the MCP server exactly as your agent will and calls
60
- `preman_status` over stdio. That both completes the link and proves the whole chain —
61
- launcher, package, key, backend. `--no-self-test` turns it off.
62
- 2. **Agent run**, which also proves your agent can load what was written. For Cursor it
63
- runs `cursor-agent mcp enable` after writing `mcp.json` (new servers stay off the CLI
64
- approved list otherwise) and launches the agent with `--approve-mcps` so the check-in
65
- can actually call `preman_status`. It opens your agent interactively in a new terminal
66
- window — the session you go on to use — and falls back to a headless run (`claude -p`,
67
- `cursor-agent --approve-mcps -p`, `codex exec`) where no window can be opened, such as
68
- CI or SSH. `--no-auto-checkin` turns it off, `PREMAN_NO_TERMINAL=1` keeps it headless.
69
- 3. **Wait**, if neither is possible: restart your agent and it links on its first call.
70
-
71
- A self-test that answers from an unexpected backend is reported with the file that
72
- redirected it — a repo-local `preman-mcp.config.json` with `"PREMAN_CONFIG_OVERRIDE": true`
73
- wins over the MCP config env, and otherwise only fills in what the env leaves unset. When
74
- that file overrides `PREMAN_BACKEND`, the config `connect` wrote is still correct: the
75
- server reads that file only from the directory it starts in, so `connect` names the file
76
- and then retries from your home directory, where the override cannot reach it — self-test
77
- first, then your agent. Agents you start in the overriding directory keep using its
78
- backend, which is the point of the file.
79
-
80
- Once linked, `connect` installs the git pre-push hook — so `git push` checks the endpoints
81
- you touched — prints what is left, and stops. It asks nothing. Everything else it used to
82
- run is its own command, because each one can fail on its own and none of them should hold
83
- up a link that already worked:
84
-
85
- ```bash
86
- preman endpoints discover # map this repo's endpoints
87
- preman tests generate # heuristic suites on saved Collections requests
88
- preman tests review # list flagged suites; --approve <id> enables schedule
89
- preman tests setup # harvest path-param fixture IDs into a .env snippet
90
- preman tests enrich # optional LLM cases on remaining heuristic suites
91
- preman runner start --background # let PreMan apply fixes on this machine
92
- preman github # or connect it in the dashboard
93
- preman status # which of those are done
94
- ```
95
-
96
- `preman onboard` (or `setup`, or a bare `preman` in a terminal) is what someone starting
97
- out runs: create the account and verify the email, install the PreMan app and open it
98
- already signed in, then write the pre-push hook into this repo — one question per step, `b`
99
- to go back, and a summary at the end. GitHub, AWS and Slack are their own commands now.
100
- Onboarding outside a git repository skips the hook rather than failing; run `preman hook
101
- install` in the repo you meant. Connecting a coding agent is no longer part of starting out; run
102
- `preman connect` when you actually want one wired into an IDE. `connect --guide` still runs
103
- the full pass inside connect itself: discovery, a first test, the runner, the desktop app
104
- and the integration prompts.
105
-
106
- The app opens signed in because the CLI leaves the key it just minted in
107
- `~/.preman/desktop-session.json`, which the app reads once and deletes. An app too old to
108
- look for it, or a machine that is not macOS, falls back to signing in on the app's own
109
- login screen with the account you just created.
110
-
111
- Useful flags: `--agent cursor|claude-code|codex` skips the picker, `--project` writes
112
- project-local config, `--print` shows the config without writing it, `--no-hook` leaves
113
- push testing alone, and `--no-guide` connects and nothing else. With `--guide`, `--yes`
114
- takes every step's default without asking and `--no-runner` / `--no-desktop` /
115
- `--no-integrations` skip one each.
116
-
117
- The desktop app is installed rather than offered. It was a question for a while, defaulted
118
- to no on the grounds that nobody should get a 150MB download by pressing Enter, and what
119
- that produced was a setup whose last act was to describe the app and decline to install
120
- it. The build is Developer ID signed and notarized, it is checked against the sha512
121
- published with the release before anything is copied into `/Applications`, and nothing
122
- arrives through a browser so there is no quarantine flag and no Gatekeeper warning on
123
- first launch. `--no-desktop`, or `PREMAN_NO_DESKTOP=1` where no flag can be passed, skips
124
- it; `install-desktop` does it on its own.
125
-
126
- In CI or any non-interactive shell, run `connect --agent <name> --api-key pm_live_…`.
127
- Without `--agent` there is nothing to prompt on, so `connect` prints ready-to-paste
128
- setup blocks for all three agents and exits 2.
129
-
130
- `preman install` still exists and does the Cursor-only half of this.
131
-
132
- ### Cloud dispatch (optional)
133
-
134
- With a coding-agent credential saved — a Cursor API key from
135
- `cursor.com/dashboard → Integrations → API Keys`, or a Claude Code routine token and id
136
- from `claude.ai/code/routines → your routine → Add API trigger` — PreMan can start an
137
- agent run for you when it finds a failing endpoint, instead of handing back a prompt to
138
- paste.
139
-
140
- `connect` asks for it once you are already set up, so skipping costs nothing. Come back
141
- to it any time:
142
-
143
- ```bash
144
- npm exec -y premanmcp@latest -- dispatch
145
- ```
146
-
147
- You can also create or connect your account first:
148
-
149
- ```bash
150
- npm exec -y premanmcp@latest -- login
151
- ```
152
-
153
- You can also pass the key directly:
154
-
155
- ```bash
156
- npm exec -y premanmcp@latest -- connect --api-key pm_live_xxx
157
- ```
158
-
159
- For project-local config:
160
-
161
- ```bash
162
- npm exec -y premanmcp@latest -- connect --project
163
- ```
164
-
165
- ## What It Does
166
-
167
- - Converts API endpoints into agent-callable MCP tools.
168
- - Migrates a Postman collection in one call (`migrate_from_postman`): keeps the assertions your `pm.test` blocks declared, splits the environment into shared variables and encrypted secrets, and schedules a monitored test suite per request.
169
- - Creates/connects a PreMan account from the terminal or IDE agent.
170
- - Lets agents test real backend endpoints from the IDE.
171
- - Syncs endpoint inventory across backend and frontend workflows.
172
- - Adds API-key auth for PreMan MCP access.
173
- - Supports hosted MCPs with consumer tokens for customer-facing agent access.
174
- - Records per-call observability so teams can audit which agent did what.
175
- - Hands failing-endpoint alerts to your agent as fix tasks (`preman_get_fix_task` → repro curl → `preman_complete_fix_task`).
176
- - Connects your production logs from the terminal (`connect_logs`): your agent asks where the logs live, then deploys a read-only CloudFormation role for AWS, or wires a shipper to the ingest endpoint for everything else.
177
-
178
- ## Common Agent Commands
179
-
180
- After installing, ask your coding agent:
181
-
182
- ```text
183
- Use PreMan to convert the endpoints I choose into a hosted MCP server, then give me the Cursor/Claude install snippet.
184
- ```
3
+ `premanmcp` is the compatibility client for agents that can start only a local
4
+ stdio MCP process. It forwards MCP initialization, discovery, notifications,
5
+ and tool calls to PreMan's authoritative hosted server at:
185
6
 
186
7
  ```text
187
- Use PreMan to sign me up, verify my email OTP, create my API key, then scan this project.
8
+ https://api.preman.live/mcp
188
9
  ```
189
10
 
190
- ```text
191
- Use PreMan to test POST /auth/login.
192
- ```
11
+ It defines no tools or schemas locally. The hosted service exposes the stable
12
+ four-tool PreMan conversation protocol:
193
13
 
194
- ```text
195
- Convert these endpoints into an MCP.
196
- ```
14
+ - `preman_chat`
15
+ - `preman_get_turn`
16
+ - `preman_confirm_action`
17
+ - `preman_cancel_turn`
197
18
 
198
- ```text
199
- Show me the audit log for this hosted MCP.
200
- ```
19
+ PreMan can add private agent capabilities without publishing a new npm package.
201
20
 
202
- ```text
203
- Move my Postman collection over to PreMan.
204
- ```
21
+ ## Marketplace users
205
22
 
206
- ```text
207
- Pull my pending PreMan fix tasks and fix the failing endpoint.
208
- ```
23
+ Do not install this package. The PreMan Codex/ChatGPT plugin connects directly
24
+ to the hosted Streamable HTTP MCP server with OAuth.
209
25
 
210
- ```text
211
- Connect my production logs to PreMan.
212
- ```
26
+ ## Local-agent compatibility
213
27
 
214
- ## Cursor
28
+ Create a PreMan API key in the app, then export it or store it locally:
215
29
 
216
30
  ```bash
217
- npm exec -y premanmcp@latest -- connect --agent cursor
31
+ export PREMAN_API_KEY=pm_live_xxx
32
+ # or: ~/.preman/credentials.json -> {"api_key":"pm_live_xxx"}
218
33
  ```
219
34
 
220
- Manual Cursor config, if you would rather write it yourself:
35
+ Then configure an agent that requires stdio:
221
36
 
222
37
  ```json
223
38
  {
@@ -230,179 +45,33 @@ Manual Cursor config, if you would rather write it yourself:
230
45
  }
231
46
  ```
232
47
 
233
- ## Claude Code
234
-
235
- ```bash
236
- npm exec -y premanmcp@latest -- connect --agent claude-code
237
- ```
238
-
239
- Equivalent manual command:
240
-
241
- ```bash
242
- claude mcp add preman -- npm exec -y premanmcp@latest --
243
- ```
244
-
245
- ## Codex
246
-
247
- ```bash
248
- npm exec -y premanmcp@latest -- connect --agent codex
249
- ```
250
-
251
- Writes an `[mcp_servers.preman]` block into `~/.codex/config.toml`.
252
-
253
- ## CLI
254
-
255
- ```bash
256
- npm exec -y premanmcp@latest -- connect # Pick an agent and connect it
257
- npm exec -y premanmcp@latest -- connect --agent codex # Skip the picker
258
- npm exec -y premanmcp@latest -- connect --project # Write project-local config
259
- npm exec -y premanmcp@latest -- connect --print # Print config without writing
260
- npm exec -y premanmcp@latest -- # Start the MCP server
261
- npm exec -y premanmcp@latest -- login # Create/login and generate a PreMan API key
262
- npm exec -y premanmcp@latest -- install # Cursor-only installer (legacy)
263
- ```
264
-
265
- ### Push testing
48
+ The proxy reads `PREMAN_API_KEY` or `~/.preman/credentials.json`. Optional
49
+ transport overrides are `PREMAN_MCP_URL` and `PREMAN_BACKEND`.
266
50
 
267
- ```bash
268
- preman hook install # Write the pre-push hook (onboard and connect do this too)
269
- preman hook status # Installed? And does the command in it still answer?
270
- preman hook repair # Rewrite it if it stopped working (usually automatic)
271
- preman hook uninstall # Remove it, restoring any hook it replaced
272
- ```
273
-
274
- The hook is generated shell that runs `preman verify --pre-push` and can only ever be
275
- advisory: no backend, no credentials, a crash or a timeout all exit 0 with a notice. Before
276
- writing it, `install` runs the command it is about to embed and requires an answer — a hook
277
- holding a `preman` that belongs to another package prints `checks skipped` at every push and
278
- looks installed forever. The embedded command is pinned to the version that wrote it rather
279
- than `@latest`, so upgrading us never changes what your pushes run; re-run `hook install`
280
- to move it. Set `PREMAN_HOOK_INVOCATION` to write a command of your own instead, and
281
- `PREMAN_SKIP_HOOK=1` to silence the hook for a push.
282
-
283
- You should not have to run `repair`. A hook of ours that stops answering is rewritten in the
284
- background by anything that proves PreMan runs here — any command, or your agent starting the
285
- MCP server — because nothing re-runs `connect` after an upgrade to notice, and the broken
286
- state is silent. It is narrow on purpose: a hook that still works keeps the version it pins, a
287
- hook we did not write is never touched, and no hook is installed where you never asked for
288
- one. The answer is remembered for an hour per directory, and `PREMAN_NO_HOOK_REPAIR=1` turns
289
- it off.
290
-
291
- #### The link a push leaves behind
292
-
293
- Once runs are stored, the hook prints a line you can click straight through to that push:
294
-
295
- ```
296
- ◆ PreMan · check #a3f21c passed — view results
297
- https://app.preman.live/observability/endpoints?batch=a3f21c9e-…
298
- ```
299
-
300
- Where the click lands is decided before anything is printed, because a terminal hands the
301
- URL it was given to the OS and there is nothing left of the hook by then:
302
-
303
- | What is true when the hook runs | What the link opens |
304
- | --- | --- |
305
- | A frontend other than `app.preman.live` | That frontend, in the browser |
306
- | PreMan.app installed and new enough to route | The desktop app, via `preman://` |
307
- | Anything else | `app.preman.live`, in the browser |
308
-
309
- The frontend is read from `--frontend`, then `PREMAN_FRONTEND`, then the one saved at login
310
- in `~/.preman/credentials.json`. That last fallback is what makes a local setup work from a
311
- hook at all: `git push` does not carry the shell that exported the variable, and a `dev.env`
312
- file is not an environment.
51
+ ## Security model
313
52
 
314
- The bare URL is always printed underneath, because macOS Terminal.app renders no hyperlink.
315
- Piped output a GUI git client, CI — gets the plain line with no escapes at all, and
316
- `NO_COLOR` drops the colour but keeps the link.
53
+ - OAuth is used by marketplace clients; API keys remain for CLI compatibility.
54
+ - Risky actions are stored server-side as exact, expiring proposals.
55
+ - Chat text never approves an action. Approval uses
56
+ `preman_confirm_action` or the matching control in the PreMan app.
57
+ - The proxy never receives private PreMan tool schemas or raw proposal payloads.
317
58
 
318
- Desktop builds from `MIN_ROUTE_VERSION` in `bin/link.js` onward are expected to read
319
- `preman://open?source=push&route=<url-encoded path>` and navigate to that path. Older builds
320
- raise the window and ignore the query, so the CLI reads `CFBundleShortVersionString` out of
321
- the installed bundle and falls back to https rather than sending them somewhere they cannot
322
- follow.
323
-
324
- ### Runner
325
-
326
- `preman onboard` and `connect --guide` set this up for you; these are for managing it
327
- afterwards.
59
+ ## Development
328
60
 
329
61
  ```bash
330
- preman runner status # Paired? Running?
331
- preman runner start --background # Hold the job stream, log to ~/.preman/runner.log
332
- preman runner stop # Stop it and report offline
333
- preman runner register --agent claude-code # Pair without starting
62
+ npm ci
63
+ npm test
64
+ npm pack --dry-run
334
65
  ```
335
66
 
336
- `start` pairs this machine itself when it is not paired yet, and re-pairs it when the
337
- backend has revoked the token it held, so neither is a command you have to be told to run.
338
- It works out which agent to pair as from the session it is running in, then from the agent
339
- PreMan is already configured in, then from the only one installed — and asks only when
340
- those disagree. Pass `--agent cursor|claude-code|codex` to settle it yourself, which is
341
- also what a machine with no terminal to ask in needs.
342
-
343
- The runner holds one outbound connection to PreMan and runs the work PreMan queues for
344
- this machine — a failing endpoint becomes an agent run in your own repo instead of a
345
- prompt you have to paste. It is bound to the agent and directory it was registered with
346
- and refuses any job that names a different one. The agent may edit files; running commands
347
- needs `--full-access` (or `PREMAN_RUNNER_FULL_ACCESS=1`). Nothing runs until PreMan has
348
- something to fix, and `preman runner stop` ends it.
349
-
350
- Options:
351
-
352
- - `--api-key <key>`: PreMan API key.
353
- - `--backend <url>`: PreMan backend URL. Defaults to `https://api.preman.live`.
354
- - `--frontend <url>`: PreMan frontend URL. Defaults to `https://app.preman.live`.
355
- - `--name <name>`: MCP server name. Defaults to `preman`.
356
- - `--project`: Write `.cursor/mcp.json` in the current project.
357
- - `--skip-login`: Install config without interactive terminal auth.
358
- - `--print`: Print the generated MCP config without writing it.
359
-
360
- ## Run a hosted MCP from the terminal
361
-
362
- Installing the package also gives you a `preman` command. Once a selection is published as a
363
- hosted MCP, you can call its tools straight from a shell — same published selection, same
364
- consumer token, and same audit trail as an agent calling `POST /h/<id>/mcp`. Updating the
365
- selection updates the terminal; there is nothing to re-install.
366
-
367
- ```bash
368
- preman link https://api.preman.live/h/<id>/mcp --env staging --token pm_hmcp_xxx
369
- preman tools --env staging
370
- preman run post_users_id_orders --env staging --arg id=42 --json '{"body":{"sku":"A1"}}'
371
- ```
372
-
373
- `link` takes the URL straight from the deploy install snippet (a bare hosted MCP id works too,
374
- with `--backend`). Profiles are stored in `~/.preman/cli.json` (mode 0600); `--env <name>`
375
- picks one. Tool names are the ones the runtime publishes — run `preman tools` to see them.
376
-
377
- Run options:
378
-
379
- - `--env <name>`: Profile to use. Falls back to `PREMAN_MCP_URL`, then the default profile.
380
- - `--arg key=value`: String argument (repeatable). `--arg key:=json` sends a JSON-typed value.
381
- - `--json '{...}'`: Full arguments object. `--json -` reads it from stdin.
382
- - `--timeout <seconds>`: Client-side timeout. Defaults to 60.
383
- - `--json-out`: Print the raw JSON-RPC result.
384
- - `<tool>` may be dotted — `preman run staging.get_orders` selects the profile inline.
385
-
386
- Exit codes: `0` success, `1` the tool returned an error, `2` usage, `3` authentication,
387
- `4` JSON-RPC error (e.g. unknown tool), `5` network failure.
388
-
389
- ## Environment Variables
390
-
391
- - `PREMAN_API_KEY`: PreMan API key.
392
- - `PREMAN_BACKEND`: PreMan backend URL.
393
- - `PREMAN_FRONTEND`: PreMan frontend URL.
394
- - `PREMAN_MCP_URL`: Hosted MCP endpoint (`…/h/<id>/mcp`) for `preman run`/`preman tools` when
395
- `--env` is omitted — useful in CI, where no profile file exists.
396
- - `PREMAN_MCP_TOKEN`: Consumer token for `PREMAN_MCP_URL`.
397
-
398
- If `PREMAN_API_KEY` is omitted, the MCP server loads credentials from `~/.preman/credentials.json`.
399
-
400
- ## Product
401
-
402
- PreMan helps teams make APIs usable by agents without giving up control. Developers can turn endpoints into MCP servers, hand customers an install snippet or hosted MCP URL, and audit every tool call through PreMan.
67
+ `npm test` builds the TypeScript proxy and checks transparent forwarding against
68
+ a mock Streamable HTTP MCP server.
403
69
 
404
- Dashboard: [https://app.preman.live](https://app.preman.live)
70
+ ## Links
405
71
 
406
- ## License
72
+ - Documentation: https://app.preman.live/docs/preman-plugin
73
+ - Support: https://app.preman.live/support
74
+ - Privacy: https://app.preman.live/privacy
75
+ - Terms: https://app.preman.live/terms
407
76
 
408
- MIT
77
+ License: MIT
package/bin/api_tools.js CHANGED
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * `preman endpoints` and `preman test` — the API-testing surface of the CLI.
3
3
  *
4
- * Both are thin proxies over `POST /mcp/call-tool`, exactly like the MCP
5
- * server's tools, so the CLI and an agent calling the same tool see identical
6
- * behaviour. Requires a pm_live_ key (flag, env, or stored credentials).
4
+ * Both are thin proxies over the `/cli` REST routes, which call the same
5
+ * implementations the MCP tools did, so the CLI and an agent asking for the
6
+ * same thing see identical data. Requires a pm_live_ key (flag, env, or stored
7
+ * credentials).
7
8
  */
8
9
 
9
10
  import { readFileSync } from "node:fs";
@@ -42,6 +43,40 @@ class CliError extends Error {
42
43
  }
43
44
  }
44
45
 
46
+ /**
47
+ * Where each tool's data comes from now.
48
+ *
49
+ * These were one POST to `/mcp/call-tool` until the four-tool chat gateway
50
+ * retired that catalog. `/mcp` is now a conversation, which is the wrong shape
51
+ * for a CLI that wants a list of endpoints and an exit code. The `/cli` routes
52
+ * call the same implementations the tools did, so the two surfaces cannot
53
+ * drift apart. A tool absent from this table is one the CLI cannot reach.
54
+ */
55
+ const TOOL_ROUTES = {
56
+ get_endpoints: { method: "GET", path: "/cli/endpoints" },
57
+ discover_endpoints_from_codebase: { method: "POST", path: "/cli/discovery-brief" },
58
+ register_discovered_endpoints: { method: "POST", path: "/cli/endpoints/register" },
59
+ generate_endpoint_tests: { method: "POST", path: "/cli/tests/generate" },
60
+ run_stress_test: { method: "POST", path: "/cli/stress-test" },
61
+ share_endpoints_with_ui: { method: "POST", path: "/cli/playground-session" },
62
+ };
63
+
64
+ /**
65
+ * A failure a person can act on.
66
+ *
67
+ * FastAPI's `detail` is often an object, and interpolating one straight into a
68
+ * template gives `[object Object]` — which is what a retired route reported for
69
+ * a day, hiding both its status and its remedy.
70
+ */
71
+ function describeFailure(result) {
72
+ const detail = result.detail ?? result.message ?? result.raw;
73
+ if (typeof detail === "string" && detail) return detail;
74
+ if (detail && typeof detail === "object") {
75
+ return detail.message || detail.code || JSON.stringify(detail);
76
+ }
77
+ return "backend error";
78
+ }
79
+
45
80
  export async function callTool(args, tool, toolArguments) {
46
81
  const token = resolveApiKey(args);
47
82
  if (!token) {
@@ -50,13 +85,17 @@ export async function callTool(args, tool, toolArguments) {
50
85
  2,
51
86
  );
52
87
  }
53
- const result = await callBackendJson(args, "POST", "/mcp/call-tool", {
54
- json: { tool, arguments: toolArguments },
88
+ const route = TOOL_ROUTES[tool];
89
+ if (!route) {
90
+ throw new CliError(`${tool} is not reachable from the CLI`);
91
+ }
92
+ const payload = toolArguments || {};
93
+ const result = await callBackendJson(args, route.method, route.path, {
55
94
  token,
95
+ ...(route.method === "GET" ? { query: payload } : { json: payload }),
56
96
  });
57
97
  if (!result.ok) {
58
- const detail = result.detail || result.message || result.raw || "backend error";
59
- throw new CliError(`${tool} failed: ${result.status_code} ${detail}`);
98
+ throw new CliError(`${tool} failed: ${result.status_code} ${describeFailure(result)}`);
60
99
  }
61
100
  return result;
62
101
  }
package/bin/cli.js CHANGED
@@ -91,7 +91,7 @@ function printHelp() {
91
91
  ["runner start|status|stop", "Run PreMan's queued agent work on this machine"],
92
92
  ["doctor", "Diagnose credentials, backend, target, integrations"],
93
93
  ["install-desktop", "Download and install the PreMan desktop app"],
94
- ["onboard", "Sign in, map this repo's endpoints, connect it, test on push"],
94
+ ["onboard", "Create an account, install the app signed in, then integrations"],
95
95
  ["connect [options]", "Pick a coding agent and connect it (optional)"],
96
96
  ["dispatch [options]", "Let PreMan start agent runs for you"],
97
97
  ["aws | github | slack", "Connect one integration on its own"],