frely-cli 0.23.8 → 0.23.10

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 (116) hide show
  1. package/README.md +50 -20
  2. package/README.zh-CN.md +47 -19
  3. package/dist/agent/local/approvals.d.ts +24 -0
  4. package/dist/agent/local/approvals.js +79 -0
  5. package/dist/agent/local/approvals.js.map +1 -0
  6. package/dist/agent/local/command.d.ts +10 -0
  7. package/dist/agent/local/command.js +292 -0
  8. package/dist/agent/local/command.js.map +1 -0
  9. package/dist/agent/local/confine.d.ts +20 -0
  10. package/dist/agent/local/confine.js +52 -0
  11. package/dist/agent/local/confine.js.map +1 -0
  12. package/dist/agent/local/manifest.d.ts +17 -0
  13. package/dist/agent/local/manifest.js +55 -0
  14. package/dist/agent/local/manifest.js.map +1 -0
  15. package/dist/agent/local/model-proxy.d.ts +18 -0
  16. package/dist/agent/local/model-proxy.js +111 -0
  17. package/dist/agent/local/model-proxy.js.map +1 -0
  18. package/dist/agent/local/source.d.ts +28 -0
  19. package/dist/agent/local/source.js +64 -0
  20. package/dist/agent/local/source.js.map +1 -0
  21. package/dist/agent/local/store.d.ts +45 -0
  22. package/dist/agent/local/store.js +78 -0
  23. package/dist/agent/local/store.js.map +1 -0
  24. package/dist/agent/local/supervisor.d.ts +9 -0
  25. package/dist/agent/local/supervisor.js +62 -0
  26. package/dist/agent/local/supervisor.js.map +1 -0
  27. package/dist/agent-help.d.ts +294 -18
  28. package/dist/agent-help.js +56 -7
  29. package/dist/agent-help.js.map +1 -1
  30. package/dist/auth.d.ts +5 -0
  31. package/dist/auth.js +36 -0
  32. package/dist/auth.js.map +1 -1
  33. package/dist/cloud.d.ts +2 -0
  34. package/dist/cloud.js +38 -0
  35. package/dist/cloud.js.map +1 -1
  36. package/dist/controller/args.d.ts +25 -0
  37. package/dist/controller/args.js +61 -0
  38. package/dist/controller/args.js.map +1 -0
  39. package/dist/controller/client.d.ts +52 -0
  40. package/dist/controller/client.js +124 -0
  41. package/dist/controller/client.js.map +1 -0
  42. package/dist/controller/commands.d.ts +16 -0
  43. package/dist/controller/commands.js +411 -0
  44. package/dist/controller/commands.js.map +1 -0
  45. package/dist/controller/dpop.d.ts +24 -0
  46. package/dist/controller/dpop.js +26 -0
  47. package/dist/controller/dpop.js.map +1 -0
  48. package/dist/controller/session.d.ts +53 -0
  49. package/dist/controller/session.js +211 -0
  50. package/dist/controller/session.js.map +1 -0
  51. package/dist/device/protocol.d.ts +1 -1
  52. package/dist/device/protocol.js +1 -1
  53. package/dist/device/protocol.js.map +1 -1
  54. package/dist/device/relay-client.d.ts +14 -0
  55. package/dist/device/relay-client.js +34 -14
  56. package/dist/device/relay-client.js.map +1 -1
  57. package/dist/index.js +79 -8
  58. package/dist/index.js.map +1 -1
  59. package/dist/provider/control.d.ts +10 -0
  60. package/dist/provider/control.js +19 -0
  61. package/dist/provider/control.js.map +1 -1
  62. package/dist/provider/share.js +4 -1
  63. package/dist/provider/share.js.map +1 -1
  64. package/dist/runtime/sandbox.d.ts +20 -0
  65. package/dist/runtime/sandbox.js +39 -1
  66. package/dist/runtime/sandbox.js.map +1 -1
  67. package/dist/share/allowance.d.ts +8 -0
  68. package/dist/share/allowance.js +22 -0
  69. package/dist/share/allowance.js.map +1 -0
  70. package/dist/share/control.d.ts +18 -0
  71. package/dist/share/control.js +53 -0
  72. package/dist/share/control.js.map +1 -0
  73. package/dist/share/frpc-config.d.ts +24 -0
  74. package/dist/share/frpc-config.js +63 -0
  75. package/dist/share/frpc-config.js.map +1 -0
  76. package/dist/share/frpc.d.ts +30 -0
  77. package/dist/share/frpc.js +108 -0
  78. package/dist/share/frpc.js.map +1 -0
  79. package/dist/share/gateway.d.ts +26 -0
  80. package/dist/share/gateway.js +100 -0
  81. package/dist/share/gateway.js.map +1 -0
  82. package/dist/share/run.d.ts +43 -0
  83. package/dist/share/run.js +163 -0
  84. package/dist/share/run.js.map +1 -0
  85. package/dist/share/service-config.d.ts +39 -0
  86. package/dist/share/service-config.js +85 -0
  87. package/dist/share/service-config.js.map +1 -0
  88. package/dist/share/service-control.d.ts +15 -0
  89. package/dist/share/service-control.js +31 -0
  90. package/dist/share/service-control.js.map +1 -0
  91. package/dist/share/service-run.d.ts +55 -0
  92. package/dist/share/service-run.js +285 -0
  93. package/dist/share/service-run.js.map +1 -0
  94. package/dist/share/service-state.d.ts +16 -0
  95. package/dist/share/service-state.js +66 -0
  96. package/dist/share/service-state.js.map +1 -0
  97. package/dist/skill/access.d.ts +2 -2
  98. package/dist/skill/access.js +4 -2
  99. package/dist/skill/access.js.map +1 -1
  100. package/dist/skill/cloud-item.d.ts +2 -2
  101. package/dist/skill/cloud-item.js.map +1 -1
  102. package/dist/skill/entry.d.ts +1 -1
  103. package/dist/skill/entry.js +1 -1
  104. package/dist/skill/remote-mcp.d.ts +3 -0
  105. package/dist/skill/remote-mcp.js +7 -1
  106. package/dist/skill/remote-mcp.js.map +1 -1
  107. package/dist/skill/router.d.ts +6 -2
  108. package/dist/skill/router.js +4 -4
  109. package/dist/skill/router.js.map +1 -1
  110. package/dist/skill/sealed-run.js +5 -3
  111. package/dist/skill/sealed-run.js.map +1 -1
  112. package/dist/uninstall.d.ts +4 -0
  113. package/dist/uninstall.js +14 -0
  114. package/dist/uninstall.js.map +1 -1
  115. package/package.json +3 -2
  116. package/skills/frely-cli/SKILL.md +8 -0
@@ -1,9 +1,9 @@
1
1
  export declare const COMMANDS: readonly [{
2
2
  readonly id: "login";
3
- readonly usage: "frely login [--relay <url>] [--no-browser] | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>";
3
+ readonly usage: "frely login [--relay <url>] [--no-browser] | frely login --wait | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>";
4
4
  readonly auth: "browser-or-email";
5
5
  readonly effect: "authorization";
6
- readonly purpose: "Authorize the CLI for the user's Frely account. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code.";
6
+ readonly purpose: "Authorize the CLI for the user's Frely account. The browser form blocks until the user approves, then returns, so continue the task when it exits; if the command is stopped first, run `frely login --wait` to resume on the same link. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code.";
7
7
  }, {
8
8
  readonly id: "logout";
9
9
  readonly usage: "frely logout";
@@ -144,19 +144,19 @@ export declare const COMMANDS: readonly [{
144
144
  readonly purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission.";
145
145
  }, {
146
146
  readonly id: "remote.tools";
147
- readonly usage: "frely remote tools <username/name> [--json]";
147
+ readonly usage: "frely remote tools <username/name> [--json] [--replace]";
148
148
  readonly auth: "cloud-oauth";
149
149
  readonly effect: "remote-read";
150
- readonly purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP.";
150
+ readonly purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP. If the name now belongs to a different MCP than the one connected before, it stops; --replace switches to the new one.";
151
151
  }, {
152
152
  readonly id: "remote.call";
153
- readonly usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>]";
153
+ readonly usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>] [--replace]";
154
154
  readonly auth: "cloud-oauth";
155
155
  readonly effect: "remote-call";
156
156
  readonly purpose: "Call one tool of a remote MCP product and print the result as JSON (exit code 1 when the tool reports an error). Each call is billed or needs a pass exactly as in an MCP client; ask the user before a call that writes data they did not ask for.";
157
157
  }, {
158
158
  readonly id: "remote.config";
159
- readonly usage: "frely remote config <username/name> [--write <file>]";
159
+ readonly usage: "frely remote config <username/name> [--write <file>] [--replace]";
160
160
  readonly auth: "cloud-oauth";
161
161
  readonly effect: "remote-write";
162
162
  readonly purpose: "Get a new key for one remote MCP product (it replaces the previous one) and print the mcpServers JSON that MCP clients take for it; with --write the entry is merged into that JSON file (created 0600) instead of printed. The key works only for this MCP.";
@@ -184,18 +184,78 @@ export declare const COMMANDS: readonly [{
184
184
  readonly auth: "none";
185
185
  readonly effect: "local-write";
186
186
  readonly purpose: "Remove an installed Agent Skill and its saved API key.";
187
+ }, {
188
+ readonly id: "agent.local.add";
189
+ readonly usage: "frely agent local add <username/name | https://github.com/owner/repo> [--name <folder-name>]";
190
+ readonly auth: "optional-account";
191
+ readonly effect: "local-write";
192
+ readonly purpose: "Download an Agent's repository into its own folder under ~/frely-agents and run its setup inside the sandbox. The sandbox can write only that folder, cannot read credential folders and can reach only Frely's API plus the sites the repository lists in frely.yaml, each of which the owner approves once through a link (exit code 3 with the link when nobody can wait; approve, then run the same command again). Needs a frely.yaml with a local.run command.";
193
+ }, {
194
+ readonly id: "agent.local.start";
195
+ readonly usage: "frely agent local start <name> [--foreground]";
196
+ readonly auth: "account-and-api-key";
197
+ readonly effect: "local-process";
198
+ readonly purpose: "Run a local Agent in the background inside the sandbox. Its model calls go through a local proxy that adds the Frely API key (saved with `frely agent local key`), so the repository's code never sees it. Billed to the key like any other API call.";
199
+ }, {
200
+ readonly id: "agent.local.stop";
201
+ readonly usage: "frely agent local stop <name>";
202
+ readonly auth: "none";
203
+ readonly effect: "local-process";
204
+ readonly purpose: "Stop a running local Agent. Run start again afterwards to apply newly approved sites.";
205
+ }, {
206
+ readonly id: "agent.local.logs";
207
+ readonly usage: "frely agent local logs <name> [--lines <n>] [--follow]";
208
+ readonly auth: "none";
209
+ readonly effect: "read";
210
+ readonly purpose: "Show what a local Agent printed, including what the sandbox blocked.";
211
+ }, {
212
+ readonly id: "agent.local.list";
213
+ readonly usage: "frely agent local list [--json]";
214
+ readonly auth: "none";
215
+ readonly effect: "read";
216
+ readonly purpose: "List the Agents on this computer, whether each is running, and the sites each has been approved for.";
217
+ }, {
218
+ readonly id: "agent.local.remove";
219
+ readonly usage: "frely agent local remove <name>";
220
+ readonly auth: "none";
221
+ readonly effect: "local-write";
222
+ readonly purpose: "Stop a local Agent and delete its folder and records. Only the Agent's own folder is removed.";
223
+ }, {
224
+ readonly id: "agent.local.key";
225
+ readonly usage: "frely agent local key --api-key-stdin | --clear";
226
+ readonly auth: "account";
227
+ readonly effect: "local-write";
228
+ readonly purpose: "Save the Frely API key that local Agents use for model calls; it goes only through stdin to secure storage. FRELY_API_KEY overrides it.";
187
229
  }, {
188
230
  readonly id: "provider.share";
189
231
  readonly usage: "frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]";
190
232
  readonly auth: "account";
191
233
  readonly effect: "remote-write";
192
- readonly purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead.";
234
+ readonly purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance.";
193
235
  }, {
194
236
  readonly id: "provider.list";
195
237
  readonly usage: "frely provider list [--json]";
196
238
  readonly auth: "account";
197
239
  readonly effect: "read";
198
240
  readonly purpose: "List configured local Providers.";
241
+ }, {
242
+ readonly id: "share";
243
+ readonly usage: "frely share <port> [--ttl <hours>] [--rewrite-host] [--yes] [--json]";
244
+ readonly auth: "account";
245
+ readonly effect: "remote-write";
246
+ readonly purpose: "Make a web service on this computer (http://127.0.0.1:<port>) reachable from the Internet by a private link through Frely's relay, until Ctrl+C or expiry (at most 24 hours). Asks first. The relay allowance is a plan limit per UTC week; --rewrite-host sends Host: localhost to dev servers that refuse other names. Not the same as `frely provider share` (local models) or `frely tunnel` (command sandbox).";
247
+ }, {
248
+ readonly id: "service.share";
249
+ readonly usage: "frely service share --type mcp|a2a --port <n> [--label <text>] [--background] [--json]";
250
+ readonly auth: "account";
251
+ readonly effect: "remote-write";
252
+ readonly purpose: "Connect an MCP server or A2A Agent that runs on this computer (127.0.0.1:<port>) to Frely so you can sell it, without a public address: only Frely's own cloud can reach it, the port never leaves this computer, and Frely never supplies a target. Runs until Ctrl+C, or with --background the device background service keeps it connected. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance.";
253
+ }, {
254
+ readonly id: "service.manage";
255
+ readonly usage: "frely service list [--json] | stop <id|label> | remove <id|label>";
256
+ readonly auth: "account";
257
+ readonly effect: "remote-write";
258
+ readonly purpose: "List registered services, stop one on this computer (it stays registered), or remove it from Frely (products that pointed at it become unreachable).";
199
259
  }, {
200
260
  readonly id: "tunnel";
201
261
  readonly usage: "frely tunnel <host>:<port> [--local-port N]";
@@ -208,12 +268,90 @@ export declare const COMMANDS: readonly [{
208
268
  readonly auth: "none";
209
269
  readonly effect: "local-write";
210
270
  readonly purpose: "Show, save or remove the HTTP(S) proxy that the command sandbox forwards its network traffic to (your own proxy, for example Clash). Without one saved it uses the HTTPS_PROXY / HTTP_PROXY / ALL_PROXY of the CLI process and, on macOS, the system proxy. Your proxy settings are never changed. Takes effect when the MCP service restarts.";
271
+ }, {
272
+ readonly id: "devices";
273
+ readonly usage: "frely devices [--add] [--json]";
274
+ readonly auth: "controller";
275
+ readonly effect: "read";
276
+ readonly purpose: "List your Frely devices with online state and workspaces (list_devices). --add prints a one-time install command for a new computer.";
277
+ }, {
278
+ readonly id: "run";
279
+ readonly usage: "frely run <device> [--cwd <dir>] [--timeout <s>] [--background] -- <command> [--json] [--out <file>]";
280
+ readonly auth: "controller";
281
+ readonly effect: "remote-execution";
282
+ readonly purpose: "Run a shell command on a device inside its sandbox and print its output; --background returns a process id. The command's own failure is exit code 2.";
283
+ }, {
284
+ readonly id: "ps";
285
+ readonly usage: "frely ps <device>";
286
+ readonly auth: "controller";
287
+ readonly effect: "read";
288
+ readonly purpose: "List background commands on a device.";
289
+ }, {
290
+ readonly id: "logs";
291
+ readonly usage: "frely logs <device> <id> [--follow]";
292
+ readonly auth: "controller";
293
+ readonly effect: "read";
294
+ readonly purpose: "Output of a background command; --follow shows it live until it ends.";
295
+ }, {
296
+ readonly id: "kill";
297
+ readonly usage: "frely kill <device> <id>";
298
+ readonly auth: "controller";
299
+ readonly effect: "remote-execution";
300
+ readonly purpose: "Stop a background command on a device.";
301
+ }, {
302
+ readonly id: "read";
303
+ readonly usage: "frely read <device>:<path> [--lines a:b] [--json] [--out <file>]";
304
+ readonly auth: "controller";
305
+ readonly effect: "read";
306
+ readonly purpose: "Print a file on a device (UTF-8, up to 1 MiB). A Windows drive path such as C:\\x is this computer, not a device.";
307
+ }, {
308
+ readonly id: "ls";
309
+ readonly usage: "frely ls [<device>[:<path>]] [--json]";
310
+ readonly auth: "controller";
311
+ readonly effect: "read";
312
+ readonly purpose: "List a folder on a device; with only a device, its workspace roots.";
313
+ }, {
314
+ readonly id: "grep";
315
+ readonly usage: "frely grep <device>:<path> <text> [--regex] [--case] [--max <n>]";
316
+ readonly auth: "controller";
317
+ readonly effect: "read";
318
+ readonly purpose: "Search file contents on a device.";
319
+ }, {
320
+ readonly id: "edit";
321
+ readonly usage: "frely edit <device>:<path> (--from <local file> | --patch <json file>) [--overwrite]";
322
+ readonly auth: "controller";
323
+ readonly effect: "remote-write";
324
+ readonly purpose: "Write a device file from a local file, or apply line-range edits from a JSON file.";
325
+ }, {
326
+ readonly id: "permission";
327
+ readonly usage: "frely permission request <device> --resource <name> --reason <text> --command <text> | confirm <code> [A|B|C] | wait <short code> [--then '<command>']";
328
+ readonly auth: "controller";
329
+ readonly effect: "authorization";
330
+ readonly purpose: "Ask the owner to open what the device sandbox blocks. Exit code 3 prints the approval link and the wait command: show the link to the user, then run `frely permission wait <short code> --then '<original command>'` in the background so the original command runs once they approve.";
331
+ }, {
332
+ readonly id: "tools";
333
+ readonly usage: "frely tools [--json]";
334
+ readonly auth: "controller";
335
+ readonly effect: "read";
336
+ readonly purpose: "Print FrelyMCP's own instructions and every tool it offers.";
337
+ }, {
338
+ readonly id: "call";
339
+ readonly usage: "frely call <tool> [--json '<object>' | --input <file>] [--out <file>]";
340
+ readonly auth: "controller";
341
+ readonly effect: "subcommand-dependent";
342
+ readonly purpose: "Call any FrelyMCP tool by name (browser, models, web_fetch, local_mcp_call, store, ...).";
343
+ }, {
344
+ readonly id: "controller";
345
+ readonly usage: "frely controller login|logout|status";
346
+ readonly auth: "browser";
347
+ readonly effect: "authorization-if-needed";
348
+ readonly purpose: "Authorize this computer to control your devices: shows a short code, you open the link, type the code and confirm with a passkey or authenticator code. The first controller command does this by itself in a terminal.";
211
349
  }, {
212
350
  readonly id: "api";
213
351
  readonly usage: "frely api list|describe|call [--wait] [--help]";
214
- readonly auth: "cloud-oauth";
352
+ readonly auth: "controller";
215
353
  readonly effect: "subcommand-dependent";
216
- readonly purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). The first call requests browser authorization. `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it.";
354
+ readonly purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). Runs on this computer's controller authorization; the first call requests browser approval (frely controller login). `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it.";
217
355
  }, {
218
356
  readonly id: "app.install";
219
357
  readonly usage: "frely app install [--force] [--json]";
@@ -289,10 +427,10 @@ export declare function agentHelp(): {
289
427
  instructions: string[];
290
428
  commands: readonly [{
291
429
  readonly id: "login";
292
- readonly usage: "frely login [--relay <url>] [--no-browser] | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>";
430
+ readonly usage: "frely login [--relay <url>] [--no-browser] | frely login --wait | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>";
293
431
  readonly auth: "browser-or-email";
294
432
  readonly effect: "authorization";
295
- readonly purpose: "Authorize the CLI for the user's Frely account. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code.";
433
+ readonly purpose: "Authorize the CLI for the user's Frely account. The browser form blocks until the user approves, then returns, so continue the task when it exits; if the command is stopped first, run `frely login --wait` to resume on the same link. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code.";
296
434
  }, {
297
435
  readonly id: "logout";
298
436
  readonly usage: "frely logout";
@@ -433,19 +571,19 @@ export declare function agentHelp(): {
433
571
  readonly purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission.";
434
572
  }, {
435
573
  readonly id: "remote.tools";
436
- readonly usage: "frely remote tools <username/name> [--json]";
574
+ readonly usage: "frely remote tools <username/name> [--json] [--replace]";
437
575
  readonly auth: "cloud-oauth";
438
576
  readonly effect: "remote-read";
439
- readonly purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP.";
577
+ readonly purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP. If the name now belongs to a different MCP than the one connected before, it stops; --replace switches to the new one.";
440
578
  }, {
441
579
  readonly id: "remote.call";
442
- readonly usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>]";
580
+ readonly usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>] [--replace]";
443
581
  readonly auth: "cloud-oauth";
444
582
  readonly effect: "remote-call";
445
583
  readonly purpose: "Call one tool of a remote MCP product and print the result as JSON (exit code 1 when the tool reports an error). Each call is billed or needs a pass exactly as in an MCP client; ask the user before a call that writes data they did not ask for.";
446
584
  }, {
447
585
  readonly id: "remote.config";
448
- readonly usage: "frely remote config <username/name> [--write <file>]";
586
+ readonly usage: "frely remote config <username/name> [--write <file>] [--replace]";
449
587
  readonly auth: "cloud-oauth";
450
588
  readonly effect: "remote-write";
451
589
  readonly purpose: "Get a new key for one remote MCP product (it replaces the previous one) and print the mcpServers JSON that MCP clients take for it; with --write the entry is merged into that JSON file (created 0600) instead of printed. The key works only for this MCP.";
@@ -473,18 +611,78 @@ export declare function agentHelp(): {
473
611
  readonly auth: "none";
474
612
  readonly effect: "local-write";
475
613
  readonly purpose: "Remove an installed Agent Skill and its saved API key.";
614
+ }, {
615
+ readonly id: "agent.local.add";
616
+ readonly usage: "frely agent local add <username/name | https://github.com/owner/repo> [--name <folder-name>]";
617
+ readonly auth: "optional-account";
618
+ readonly effect: "local-write";
619
+ readonly purpose: "Download an Agent's repository into its own folder under ~/frely-agents and run its setup inside the sandbox. The sandbox can write only that folder, cannot read credential folders and can reach only Frely's API plus the sites the repository lists in frely.yaml, each of which the owner approves once through a link (exit code 3 with the link when nobody can wait; approve, then run the same command again). Needs a frely.yaml with a local.run command.";
620
+ }, {
621
+ readonly id: "agent.local.start";
622
+ readonly usage: "frely agent local start <name> [--foreground]";
623
+ readonly auth: "account-and-api-key";
624
+ readonly effect: "local-process";
625
+ readonly purpose: "Run a local Agent in the background inside the sandbox. Its model calls go through a local proxy that adds the Frely API key (saved with `frely agent local key`), so the repository's code never sees it. Billed to the key like any other API call.";
626
+ }, {
627
+ readonly id: "agent.local.stop";
628
+ readonly usage: "frely agent local stop <name>";
629
+ readonly auth: "none";
630
+ readonly effect: "local-process";
631
+ readonly purpose: "Stop a running local Agent. Run start again afterwards to apply newly approved sites.";
632
+ }, {
633
+ readonly id: "agent.local.logs";
634
+ readonly usage: "frely agent local logs <name> [--lines <n>] [--follow]";
635
+ readonly auth: "none";
636
+ readonly effect: "read";
637
+ readonly purpose: "Show what a local Agent printed, including what the sandbox blocked.";
638
+ }, {
639
+ readonly id: "agent.local.list";
640
+ readonly usage: "frely agent local list [--json]";
641
+ readonly auth: "none";
642
+ readonly effect: "read";
643
+ readonly purpose: "List the Agents on this computer, whether each is running, and the sites each has been approved for.";
644
+ }, {
645
+ readonly id: "agent.local.remove";
646
+ readonly usage: "frely agent local remove <name>";
647
+ readonly auth: "none";
648
+ readonly effect: "local-write";
649
+ readonly purpose: "Stop a local Agent and delete its folder and records. Only the Agent's own folder is removed.";
650
+ }, {
651
+ readonly id: "agent.local.key";
652
+ readonly usage: "frely agent local key --api-key-stdin | --clear";
653
+ readonly auth: "account";
654
+ readonly effect: "local-write";
655
+ readonly purpose: "Save the Frely API key that local Agents use for model calls; it goes only through stdin to secure storage. FRELY_API_KEY overrides it.";
476
656
  }, {
477
657
  readonly id: "provider.share";
478
658
  readonly usage: "frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]";
479
659
  readonly auth: "account";
480
660
  readonly effect: "remote-write";
481
- readonly purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead.";
661
+ readonly purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance.";
482
662
  }, {
483
663
  readonly id: "provider.list";
484
664
  readonly usage: "frely provider list [--json]";
485
665
  readonly auth: "account";
486
666
  readonly effect: "read";
487
667
  readonly purpose: "List configured local Providers.";
668
+ }, {
669
+ readonly id: "share";
670
+ readonly usage: "frely share <port> [--ttl <hours>] [--rewrite-host] [--yes] [--json]";
671
+ readonly auth: "account";
672
+ readonly effect: "remote-write";
673
+ readonly purpose: "Make a web service on this computer (http://127.0.0.1:<port>) reachable from the Internet by a private link through Frely's relay, until Ctrl+C or expiry (at most 24 hours). Asks first. The relay allowance is a plan limit per UTC week; --rewrite-host sends Host: localhost to dev servers that refuse other names. Not the same as `frely provider share` (local models) or `frely tunnel` (command sandbox).";
674
+ }, {
675
+ readonly id: "service.share";
676
+ readonly usage: "frely service share --type mcp|a2a --port <n> [--label <text>] [--background] [--json]";
677
+ readonly auth: "account";
678
+ readonly effect: "remote-write";
679
+ readonly purpose: "Connect an MCP server or A2A Agent that runs on this computer (127.0.0.1:<port>) to Frely so you can sell it, without a public address: only Frely's own cloud can reach it, the port never leaves this computer, and Frely never supplies a target. Runs until Ctrl+C, or with --background the device background service keeps it connected. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance.";
680
+ }, {
681
+ readonly id: "service.manage";
682
+ readonly usage: "frely service list [--json] | stop <id|label> | remove <id|label>";
683
+ readonly auth: "account";
684
+ readonly effect: "remote-write";
685
+ readonly purpose: "List registered services, stop one on this computer (it stays registered), or remove it from Frely (products that pointed at it become unreachable).";
488
686
  }, {
489
687
  readonly id: "tunnel";
490
688
  readonly usage: "frely tunnel <host>:<port> [--local-port N]";
@@ -497,12 +695,90 @@ export declare function agentHelp(): {
497
695
  readonly auth: "none";
498
696
  readonly effect: "local-write";
499
697
  readonly purpose: "Show, save or remove the HTTP(S) proxy that the command sandbox forwards its network traffic to (your own proxy, for example Clash). Without one saved it uses the HTTPS_PROXY / HTTP_PROXY / ALL_PROXY of the CLI process and, on macOS, the system proxy. Your proxy settings are never changed. Takes effect when the MCP service restarts.";
698
+ }, {
699
+ readonly id: "devices";
700
+ readonly usage: "frely devices [--add] [--json]";
701
+ readonly auth: "controller";
702
+ readonly effect: "read";
703
+ readonly purpose: "List your Frely devices with online state and workspaces (list_devices). --add prints a one-time install command for a new computer.";
704
+ }, {
705
+ readonly id: "run";
706
+ readonly usage: "frely run <device> [--cwd <dir>] [--timeout <s>] [--background] -- <command> [--json] [--out <file>]";
707
+ readonly auth: "controller";
708
+ readonly effect: "remote-execution";
709
+ readonly purpose: "Run a shell command on a device inside its sandbox and print its output; --background returns a process id. The command's own failure is exit code 2.";
710
+ }, {
711
+ readonly id: "ps";
712
+ readonly usage: "frely ps <device>";
713
+ readonly auth: "controller";
714
+ readonly effect: "read";
715
+ readonly purpose: "List background commands on a device.";
716
+ }, {
717
+ readonly id: "logs";
718
+ readonly usage: "frely logs <device> <id> [--follow]";
719
+ readonly auth: "controller";
720
+ readonly effect: "read";
721
+ readonly purpose: "Output of a background command; --follow shows it live until it ends.";
722
+ }, {
723
+ readonly id: "kill";
724
+ readonly usage: "frely kill <device> <id>";
725
+ readonly auth: "controller";
726
+ readonly effect: "remote-execution";
727
+ readonly purpose: "Stop a background command on a device.";
728
+ }, {
729
+ readonly id: "read";
730
+ readonly usage: "frely read <device>:<path> [--lines a:b] [--json] [--out <file>]";
731
+ readonly auth: "controller";
732
+ readonly effect: "read";
733
+ readonly purpose: "Print a file on a device (UTF-8, up to 1 MiB). A Windows drive path such as C:\\x is this computer, not a device.";
734
+ }, {
735
+ readonly id: "ls";
736
+ readonly usage: "frely ls [<device>[:<path>]] [--json]";
737
+ readonly auth: "controller";
738
+ readonly effect: "read";
739
+ readonly purpose: "List a folder on a device; with only a device, its workspace roots.";
740
+ }, {
741
+ readonly id: "grep";
742
+ readonly usage: "frely grep <device>:<path> <text> [--regex] [--case] [--max <n>]";
743
+ readonly auth: "controller";
744
+ readonly effect: "read";
745
+ readonly purpose: "Search file contents on a device.";
746
+ }, {
747
+ readonly id: "edit";
748
+ readonly usage: "frely edit <device>:<path> (--from <local file> | --patch <json file>) [--overwrite]";
749
+ readonly auth: "controller";
750
+ readonly effect: "remote-write";
751
+ readonly purpose: "Write a device file from a local file, or apply line-range edits from a JSON file.";
752
+ }, {
753
+ readonly id: "permission";
754
+ readonly usage: "frely permission request <device> --resource <name> --reason <text> --command <text> | confirm <code> [A|B|C] | wait <short code> [--then '<command>']";
755
+ readonly auth: "controller";
756
+ readonly effect: "authorization";
757
+ readonly purpose: "Ask the owner to open what the device sandbox blocks. Exit code 3 prints the approval link and the wait command: show the link to the user, then run `frely permission wait <short code> --then '<original command>'` in the background so the original command runs once they approve.";
758
+ }, {
759
+ readonly id: "tools";
760
+ readonly usage: "frely tools [--json]";
761
+ readonly auth: "controller";
762
+ readonly effect: "read";
763
+ readonly purpose: "Print FrelyMCP's own instructions and every tool it offers.";
764
+ }, {
765
+ readonly id: "call";
766
+ readonly usage: "frely call <tool> [--json '<object>' | --input <file>] [--out <file>]";
767
+ readonly auth: "controller";
768
+ readonly effect: "subcommand-dependent";
769
+ readonly purpose: "Call any FrelyMCP tool by name (browser, models, web_fetch, local_mcp_call, store, ...).";
770
+ }, {
771
+ readonly id: "controller";
772
+ readonly usage: "frely controller login|logout|status";
773
+ readonly auth: "browser";
774
+ readonly effect: "authorization-if-needed";
775
+ readonly purpose: "Authorize this computer to control your devices: shows a short code, you open the link, type the code and confirm with a passkey or authenticator code. The first controller command does this by itself in a terminal.";
500
776
  }, {
501
777
  readonly id: "api";
502
778
  readonly usage: "frely api list|describe|call [--wait] [--help]";
503
- readonly auth: "cloud-oauth";
779
+ readonly auth: "controller";
504
780
  readonly effect: "subcommand-dependent";
505
- readonly purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). The first call requests browser authorization. `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it.";
781
+ readonly purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). Runs on this computer's controller authorization; the first call requests browser approval (frely controller login). `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it.";
506
782
  }, {
507
783
  readonly id: "app.install";
508
784
  readonly usage: "frely app install [--force] [--json]";
@@ -1,6 +1,6 @@
1
1
  import { VERSION } from "./version.js";
2
2
  export const COMMANDS = [
3
- { id: "login", usage: "frely login [--relay <url>] [--no-browser] | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>", auth: "browser-or-email", effect: "authorization", purpose: "Authorize the CLI for the user's Frely account. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code." },
3
+ { id: "login", usage: "frely login [--relay <url>] [--no-browser] | frely login --wait | frely login --email <address> [--invite <link>] [--mcp] [--workspace <path>] [--days <n>] then frely login --code <6-digit code>", auth: "browser-or-email", effect: "authorization", purpose: "Authorize the CLI for the user's Frely account. The browser form blocks until the user approves, then returns, so continue the task when it exits; if the command is stopped first, run `frely login --wait` to resume on the same link. With --email, Frely emails a code; the user pastes it into `frely login --code` (enter only the 6 digits; the mail also shows a short reference such as K7, which is only for matching the mail). Add --mcp to also enable device MCP for the workspace (default 90 days) once the code is verified; do this when the user is registering for the first time, and tell them before asking for the code." },
4
4
  { id: "logout", usage: "frely logout", auth: "none", effect: "local-write", purpose: "Remove login, revoke Cloud authorization and stop the MCP background service." },
5
5
  { id: "uninstall", usage: "frely uninstall [--yes] [--json]", auth: "optional-account", effect: "remote-write", purpose: "Remove Frely from this computer: revoke this device's Device MCP authorization, Cloud and account login on the Frely side, stop and uninstall the background service, delete saved login, device and MCP data, installed Agent Skills and the frely program itself. It lists everything first and removes nothing until the user types yes; without a terminal it only lists, and --yes confirms. Frely App and server-side Providers/Agents are not removed. Refuses to run inside device MCP. Destructive: run only when the user asks for it." },
6
6
  { id: "doctor", usage: "frely doctor [-v] [--json]", auth: "optional-account", effect: "diagnostic", purpose: "Show the signed-in account, installation, available updates, MCP and connection status; -v verifies the account online and runs detailed diagnostics." },
@@ -24,18 +24,41 @@ export const COMMANDS = [
24
24
  { id: "item.run", usage: "frely item run <script> [args...]", auth: "cloud-oauth", effect: "local-execution", purpose: "Run an encrypted paid script of an installed item inside the Frely command sandbox. The placeholder file at the script's path calls this for you. The access lease is renewed when it is near its end; without a valid pass the script does not run." },
25
25
  { id: "item.update", usage: "frely item update [<folder>] [--json]", auth: "cloud-oauth", effect: "local-write", purpose: "Without a folder, list the installed marketplace items and say which have a newer version; nothing is changed. With a folder, install the newer version into that folder, after you decide to. Frely never updates an item by itself. A folder you edited is refused, and a new version needs a new review (frely item trust) unless Frely's scan passed for it." },
26
26
  { id: "item.install", usage: "frely item install <username/name[@version]> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]", auth: "cloud-oauth", effect: "local-write", purpose: "Install a download-install Prompt or Skill from the marketplace through Frely Cloud. The paid part is installed only with a valid pass; otherwise the command prints how to buy one. Skills go to the host Skill folder, Prompts to --dir (default: current directory). Scripts are saved without execute permission." },
27
- { id: "remote.tools", usage: "frely remote tools <username/name> [--json]", auth: "cloud-oauth", effect: "remote-read", purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP." },
28
- { id: "remote.call", usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>]", auth: "cloud-oauth", effect: "remote-call", purpose: "Call one tool of a remote MCP product and print the result as JSON (exit code 1 when the tool reports an error). Each call is billed or needs a pass exactly as in an MCP client; ask the user before a call that writes data they did not ask for." },
29
- { id: "remote.config", usage: "frely remote config <username/name> [--write <file>]", auth: "cloud-oauth", effect: "remote-write", purpose: "Get a new key for one remote MCP product (it replaces the previous one) and print the mcpServers JSON that MCP clients take for it; with --write the entry is merged into that JSON file (created 0600) instead of printed. The key works only for this MCP." },
27
+ { id: "remote.tools", usage: "frely remote tools <username/name> [--json] [--replace]", auth: "cloud-oauth", effect: "remote-read", purpose: "List the tools of a remote MCP product from the marketplace, with their input schemas, without configuring it in an MCP client. The first use asks Frely for a key that works only for this MCP. If the name now belongs to a different MCP than the one connected before, it stops; --replace switches to the new one." },
28
+ { id: "remote.call", usage: "frely remote call <username/name> <tool> [--json '<object>' | --input <file>] [--replace]", auth: "cloud-oauth", effect: "remote-call", purpose: "Call one tool of a remote MCP product and print the result as JSON (exit code 1 when the tool reports an error). Each call is billed or needs a pass exactly as in an MCP client; ask the user before a call that writes data they did not ask for." },
29
+ { id: "remote.config", usage: "frely remote config <username/name> [--write <file>] [--replace]", auth: "cloud-oauth", effect: "remote-write", purpose: "Get a new key for one remote MCP product (it replaces the previous one) and print the mcpServers JSON that MCP clients take for it; with --write the entry is merged into that JSON file (created 0600) instead of printed. The key works only for this MCP." },
30
30
  { id: "agent.install", usage: "frely agent install <username/name[@version]> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <project>] [--api-key-stdin] [--json]", auth: "optional-api-key", effect: "local-write", purpose: "Install the public Agent's trigger Skill; an API key goes only through stdin to secure storage." },
31
31
  { id: "agent.run", usage: "frely agent run <username/name> (--input <text>|--input-stdin) [--json]", auth: "installed-api-key-or-account", effect: "remote-call", purpose: "Send the complete relevant user request to the installed Agent through model-scoped MCP. Usage may be billed." },
32
32
  { id: "agent.status", usage: "frely agent status (<username/name>|--api-key-stdin [--relay <url>]) [--json]", auth: "none-or-api-key", effect: "read", purpose: "Inspect an installed Agent Skill and, for API-key installs, its Key budget. With --api-key-stdin, read that Key's budget without installing or logging in." },
33
33
  { id: "agent.remove", usage: "frely agent remove <username/name> [--json]", auth: "none", effect: "local-write", purpose: "Remove an installed Agent Skill and its saved API key." },
34
- { id: "provider.share", usage: "frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]", auth: "account", effect: "remote-write", purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead." },
34
+ { id: "agent.local.add", usage: "frely agent local add <username/name | https://github.com/owner/repo> [--name <folder-name>]", auth: "optional-account", effect: "local-write", purpose: "Download an Agent's repository into its own folder under ~/frely-agents and run its setup inside the sandbox. The sandbox can write only that folder, cannot read credential folders and can reach only Frely's API plus the sites the repository lists in frely.yaml, each of which the owner approves once through a link (exit code 3 with the link when nobody can wait; approve, then run the same command again). Needs a frely.yaml with a local.run command." },
35
+ { id: "agent.local.start", usage: "frely agent local start <name> [--foreground]", auth: "account-and-api-key", effect: "local-process", purpose: "Run a local Agent in the background inside the sandbox. Its model calls go through a local proxy that adds the Frely API key (saved with `frely agent local key`), so the repository's code never sees it. Billed to the key like any other API call." },
36
+ { id: "agent.local.stop", usage: "frely agent local stop <name>", auth: "none", effect: "local-process", purpose: "Stop a running local Agent. Run start again afterwards to apply newly approved sites." },
37
+ { id: "agent.local.logs", usage: "frely agent local logs <name> [--lines <n>] [--follow]", auth: "none", effect: "read", purpose: "Show what a local Agent printed, including what the sandbox blocked." },
38
+ { id: "agent.local.list", usage: "frely agent local list [--json]", auth: "none", effect: "read", purpose: "List the Agents on this computer, whether each is running, and the sites each has been approved for." },
39
+ { id: "agent.local.remove", usage: "frely agent local remove <name>", auth: "none", effect: "local-write", purpose: "Stop a local Agent and delete its folder and records. Only the Agent's own folder is removed." },
40
+ { id: "agent.local.key", usage: "frely agent local key --api-key-stdin | --clear", auth: "account", effect: "local-write", purpose: "Save the Frely API key that local Agents use for model calls; it goes only through stdin to secure storage. FRELY_API_KEY overrides it." },
41
+ { id: "provider.share", usage: "frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]", auth: "account", effect: "remote-write", purpose: "Publish a local model Provider. If a prepared Provider on this device is not finished, resume it instead. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance." },
35
42
  { id: "provider.list", usage: "frely provider list [--json]", auth: "account", effect: "read", purpose: "List configured local Providers." },
43
+ { id: "share", usage: "frely share <port> [--ttl <hours>] [--rewrite-host] [--yes] [--json]", auth: "account", effect: "remote-write", purpose: "Make a web service on this computer (http://127.0.0.1:<port>) reachable from the Internet by a private link through Frely's relay, until Ctrl+C or expiry (at most 24 hours). Asks first. The relay allowance is a plan limit per UTC week; --rewrite-host sends Host: localhost to dev servers that refuse other names. Not the same as `frely provider share` (local models) or `frely tunnel` (command sandbox)." },
44
+ { id: "service.share", usage: "frely service share --type mcp|a2a --port <n> [--label <text>] [--background] [--json]", auth: "account", effect: "remote-write", purpose: "Connect an MCP server or A2A Agent that runs on this computer (127.0.0.1:<port>) to Frely so you can sell it, without a public address: only Frely's own cloud can reach it, the port never leaves this computer, and Frely never supplies a target. Runs until Ctrl+C, or with --background the device background service keeps it connected. Prints this week's remaining relay allowance; relayed traffic counts against the weekly relay allowance." },
45
+ { id: "service.manage", usage: "frely service list [--json] | stop <id|label> | remove <id|label>", auth: "account", effect: "remote-write", purpose: "List registered services, stop one on this computer (it stays registered), or remove it from Frely (products that pointed at it become unreachable)." },
36
46
  { id: "tunnel", usage: "frely tunnel <host>:<port> [--local-port N]", auth: "none", effect: "local-execution", purpose: "Run inside a sandboxed command (run_command): listen on 127.0.0.1:<local-port> (default: the same port) and forward each TCP connection to host:port through the command sandbox's proxy, so database and redis clients connect to 127.0.0.1 without turning the sandbox off. Start it in the same command as the client, for example `frely tunnel db.example.com:5432 & sleep 1; psql -h 127.0.0.1 ...`. Prints the local address and runs until killed." },
37
47
  { id: "sandbox.proxy", usage: "frely sandbox proxy [<http://host:port> [--no-proxy <list>] | --clear]", auth: "none", effect: "local-write", purpose: "Show, save or remove the HTTP(S) proxy that the command sandbox forwards its network traffic to (your own proxy, for example Clash). Without one saved it uses the HTTPS_PROXY / HTTP_PROXY / ALL_PROXY of the CLI process and, on macOS, the system proxy. Your proxy settings are never changed. Takes effect when the MCP service restarts." },
38
- { id: "api", usage: "frely api list|describe|call [--wait] [--help]", auth: "cloud-oauth", effect: "subcommand-dependent", purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). The first call requests browser authorization. `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it." },
48
+ { id: "devices", usage: "frely devices [--add] [--json]", auth: "controller", effect: "read", purpose: "List your Frely devices with online state and workspaces (list_devices). --add prints a one-time install command for a new computer." },
49
+ { id: "run", usage: "frely run <device> [--cwd <dir>] [--timeout <s>] [--background] -- <command> [--json] [--out <file>]", auth: "controller", effect: "remote-execution", purpose: "Run a shell command on a device inside its sandbox and print its output; --background returns a process id. The command's own failure is exit code 2." },
50
+ { id: "ps", usage: "frely ps <device>", auth: "controller", effect: "read", purpose: "List background commands on a device." },
51
+ { id: "logs", usage: "frely logs <device> <id> [--follow]", auth: "controller", effect: "read", purpose: "Output of a background command; --follow shows it live until it ends." },
52
+ { id: "kill", usage: "frely kill <device> <id>", auth: "controller", effect: "remote-execution", purpose: "Stop a background command on a device." },
53
+ { id: "read", usage: "frely read <device>:<path> [--lines a:b] [--json] [--out <file>]", auth: "controller", effect: "read", purpose: "Print a file on a device (UTF-8, up to 1 MiB). A Windows drive path such as C:\\x is this computer, not a device." },
54
+ { id: "ls", usage: "frely ls [<device>[:<path>]] [--json]", auth: "controller", effect: "read", purpose: "List a folder on a device; with only a device, its workspace roots." },
55
+ { id: "grep", usage: "frely grep <device>:<path> <text> [--regex] [--case] [--max <n>]", auth: "controller", effect: "read", purpose: "Search file contents on a device." },
56
+ { id: "edit", usage: "frely edit <device>:<path> (--from <local file> | --patch <json file>) [--overwrite]", auth: "controller", effect: "remote-write", purpose: "Write a device file from a local file, or apply line-range edits from a JSON file." },
57
+ { id: "permission", usage: "frely permission request <device> --resource <name> --reason <text> --command <text> | confirm <code> [A|B|C] | wait <short code> [--then '<command>']", auth: "controller", effect: "authorization", purpose: "Ask the owner to open what the device sandbox blocks. Exit code 3 prints the approval link and the wait command: show the link to the user, then run `frely permission wait <short code> --then '<original command>'` in the background so the original command runs once they approve." },
58
+ { id: "tools", usage: "frely tools [--json]", auth: "controller", effect: "read", purpose: "Print FrelyMCP's own instructions and every tool it offers." },
59
+ { id: "call", usage: "frely call <tool> [--json '<object>' | --input <file>] [--out <file>]", auth: "controller", effect: "subcommand-dependent", purpose: "Call any FrelyMCP tool by name (browser, models, web_fetch, local_mcp_call, store, ...)." },
60
+ { id: "controller", usage: "frely controller login|logout|status", auth: "browser", effect: "authorization-if-needed", purpose: "Authorize this computer to control your devices: shows a short code, you open the link, type the code and confirm with a passkey or authenticator code. The first controller command does this by itself in a terminal." },
61
+ { id: "api", usage: "frely api list|describe|call [--wait] [--help]", auth: "controller", effect: "subcommand-dependent", purpose: "Discover and call your Frely account's business operations (the same tools FrelyMCP offers through frely_list/frely_call). Runs on this computer's controller authorization; the first call requests browser approval (frely controller login). `list` is grouped and compact (add --json for the full tool list); use describe before call; parameters and results are JSON; --input reads a file up to 512 KiB. When a call needs the owner's approval the error links to it; run the call with --wait (in the foreground, tool timeout of at least 10 minutes) to show the user the link first and then block until they approve on their phone or the web, so the call finishes by itself and you need not be told. Never background or kill it." },
39
62
  { id: "app.install", usage: "frely app install [--force] [--json]", auth: "local", effect: "local-write", purpose: "Install the Frely App: Homebrew cask when available, otherwise a verified download (SHA-256) from the FrelyHQ/frely-cli release mirror; quarantine is preserved." },
40
63
  { id: "app.open", usage: "frely app open [--window]", auth: "local", effect: "local-write", purpose: "Launch the Frely App in the background (menu bar) or with its main window via --window." },
41
64
  { id: "app.status", usage: "frely app status [--json]", auth: "local", effect: "read", purpose: "Show whether the Frely App is installed, its version, install path, running state and how it is managed." },
@@ -72,12 +95,14 @@ export function agentHelp() {
72
95
  };
73
96
  }
74
97
  const GROUPS = [
98
+ { title: "Control your devices", ids: ["devices", "run", "ps", "logs", "kill", "read", "ls", "grep", "edit", "permission", "tools", "call", "controller"] },
75
99
  { title: "Account", ids: ["login", "logout", "uninstall", "doctor", "update"] },
76
100
  { title: "Device MCP", ids: ["mcp.start", "mcp.workspace", "mcp.local", "mcp.lifecycle"] },
77
- { title: "Agents", ids: ["agent.install", "agent.run", "agent.status", "agent.remove"] },
101
+ { title: "Agents", ids: ["agent.install", "agent.run", "agent.status", "agent.remove", "agent.local"] },
78
102
  { title: "Skills", ids: ["skill.install"] },
79
103
  { title: "Marketplace items", ids: ["item.install", "item.update", "item.run", "item.trust"] },
80
104
  { title: "Providers", ids: ["provider.share", "provider.list"] },
105
+ { title: "Share", ids: ["share", "service.share", "service.manage"] },
81
106
  { title: "Command sandbox", ids: ["tunnel", "sandbox.proxy"] },
82
107
  { title: "API", ids: ["api", "remote.tools", "remote.call", "remote.config"] },
83
108
  ];
@@ -86,6 +111,19 @@ const GROUPS = [
86
111
  // --json`, which this overview points to for the complete contract. Commands
87
112
  // meant for services and Agents (mcp serve/stdio, network) appear only there.
88
113
  const SHORT_USAGE = {
114
+ devices: "frely devices [--add]",
115
+ run: "frely run <device> [--cwd <dir>] [--background] -- <command>",
116
+ ps: "frely ps <device>",
117
+ logs: "frely logs <device> <id> [--follow]",
118
+ kill: "frely kill <device> <id>",
119
+ read: "frely read <device>:<path> [--lines a:b]",
120
+ ls: "frely ls [<device>[:<path>]]",
121
+ grep: "frely grep <device>:<path> <text>",
122
+ edit: "frely edit <device>:<path> --from <file>",
123
+ permission: "frely permission request|confirm|wait",
124
+ tools: "frely tools",
125
+ call: "frely call <tool> [--json '<object>']",
126
+ controller: "frely controller login|logout|status",
89
127
  login: "frely login [--no-browser]",
90
128
  logout: "frely logout",
91
129
  uninstall: "frely uninstall [--yes]",
@@ -104,8 +142,19 @@ const SHORT_USAGE = {
104
142
  "agent.run": "frely agent run <username/name> (--input <text>|--input-stdin)",
105
143
  "agent.status": "frely agent status <username/name>",
106
144
  "agent.remove": "frely agent remove <username/name>",
145
+ "agent.local": "frely agent local add|start|stop|logs|list|remove|key",
146
+ "agent.local.add": "frely agent local add <username/name | github-url>",
147
+ "agent.local.start": "frely agent local start <name>",
148
+ "agent.local.stop": "frely agent local stop <name>",
149
+ "agent.local.logs": "frely agent local logs <name> [--follow]",
150
+ "agent.local.list": "frely agent local list",
151
+ "agent.local.remove": "frely agent local remove <name>",
152
+ "agent.local.key": "frely agent local key --api-key-stdin",
107
153
  "provider.share": "frely provider share [ollama|openai-compatible] [--models <a,b>]",
108
154
  "provider.list": "frely provider list",
155
+ share: "frely share <port> [--ttl <hours>]",
156
+ "service.share": "frely service share --type mcp|a2a --port <n>",
157
+ "service.manage": "frely service list|stop|remove",
109
158
  tunnel: "frely tunnel <host>:<port> [--local-port N]",
110
159
  "sandbox.proxy": "frely sandbox proxy [<url> [--no-proxy <list>] | --clear]",
111
160
  api: "frely api list|describe|call",