frely-cli 0.9.6 → 0.10.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 +27 -5
- package/README.zh-CN.md +15 -4
- package/dist/agent-help.d.ts +102 -6
- package/dist/agent-help.js +16 -5
- package/dist/agent-help.js.map +1 -1
- package/dist/cloud.d.ts +11 -1
- package/dist/cloud.js +73 -1
- package/dist/cloud.js.map +1 -1
- package/dist/computer/command.d.ts +6 -0
- package/dist/computer/command.js +53 -0
- package/dist/computer/command.js.map +1 -0
- package/dist/computer/guard.d.ts +18 -0
- package/dist/computer/guard.js +82 -0
- package/dist/computer/guard.js.map +1 -0
- package/dist/computer/image.d.ts +22 -0
- package/dist/computer/image.js +183 -0
- package/dist/computer/image.js.map +1 -0
- package/dist/computer/ocu.d.ts +40 -0
- package/dist/computer/ocu.js +59 -0
- package/dist/computer/ocu.js.map +1 -0
- package/dist/computer/runtime.d.ts +22 -0
- package/dist/computer/runtime.js +85 -0
- package/dist/computer/runtime.js.map +1 -0
- package/dist/computer/server.d.ts +11 -0
- package/dist/computer/server.js +31 -0
- package/dist/computer/server.js.map +1 -0
- package/dist/computer/state.d.ts +11 -0
- package/dist/computer/state.js +17 -0
- package/dist/computer/state.js.map +1 -0
- package/dist/computer/toolset.d.ts +22 -0
- package/dist/computer/toolset.js +112 -0
- package/dist/computer/toolset.js.map +1 -0
- package/dist/device/protocol.d.ts +2 -0
- package/dist/device/protocol.js +7 -1
- package/dist/device/protocol.js.map +1 -1
- package/dist/device/relay-client.d.ts +3 -0
- package/dist/device/relay-client.js +7 -1
- package/dist/device/relay-client.js.map +1 -1
- package/dist/index.js +69 -8
- package/dist/index.js.map +1 -1
- package/dist/local-mcp-command.d.ts +10 -0
- package/dist/local-mcp-command.js +105 -0
- package/dist/local-mcp-command.js.map +1 -0
- package/dist/mcp-authorization.js +27 -2
- package/dist/mcp-authorization.js.map +1 -1
- package/dist/mcp-command.js +17 -1
- package/dist/mcp-command.js.map +1 -1
- package/dist/provider/control.d.ts +8 -2
- package/dist/provider/control.js.map +1 -1
- package/dist/runtime/local-mcp.d.ts +114 -0
- package/dist/runtime/local-mcp.js +448 -0
- package/dist/runtime/local-mcp.js.map +1 -0
- package/dist/runtime/mcp.d.ts +20 -0
- package/dist/runtime/mcp.js +29 -0
- package/dist/runtime/mcp.js.map +1 -1
- package/dist/runtime/relay-mcp.d.ts +3 -1
- package/dist/runtime/relay-mcp.js +5 -1
- package/dist/runtime/relay-mcp.js.map +1 -1
- package/dist/runtime/relay-session.d.ts +2 -2
- package/dist/runtime/relay-session.js +1 -1
- package/dist/runtime/relay-session.js.map +1 -1
- package/dist/runtime/sandbox.js +3 -0
- package/dist/runtime/sandbox.js.map +1 -1
- package/dist/skill/cloud-item.d.ts +38 -0
- package/dist/skill/cloud-item.js +151 -0
- package/dist/skill/cloud-item.js.map +1 -0
- package/dist/upgrade/maintenance.js +1 -1
- package/dist/upgrade/maintenance.js.map +1 -1
- package/dist/upgrade/service-refresh.js +1 -1
- package/dist/upgrade/service-refresh.js.map +1 -1
- package/dist/upgrade/update.js +2 -2
- package/dist/upgrade/update.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,6 +79,10 @@ frely mcp url --workspace /path/to/project
|
|
|
79
79
|
|
|
80
80
|
`frely mcp url` is idempotent: once enabled it only prints the same URL, so run it again whenever you need the address. Prompts go to stderr, so stdout remains a single URL or, with `--json`, a JSON object. No URL is printed if approval or service installation fails. To expose more directories, use `frely mcp workspace add <path>`; `frely mcp workspace list` lists them. A command group run without a subcommand (for example `frely mcp workspace` or `frely agent`) prints the subcommands under it.
|
|
81
81
|
|
|
82
|
+
### Local MCP servers on this computer
|
|
83
|
+
|
|
84
|
+
Remote MCP clients can also reach MCP servers that only run on this computer, such as a browser-extension server listening on `127.0.0.1`. Servers listening only on loopback are found automatically (`frely mcp local list`); add others with `frely mcp local add <name> --url http://127.0.0.1:<port>/mcp` or `frely mcp local add <name> [--env KEY=VALUE] -- <command> [args...]` (stdio). Every server stays off for remote clients until you turn it on, one by one, on the Frely connections page. Enabled servers are then reachable through two device tools, `local_mcp_list` and `local_mcp_call`, and run outside the command sandbox with your user account. Only loopback addresses are ever contacted; headers and environment values stay on this computer.
|
|
85
|
+
|
|
82
86
|
Add the exact printed URL to a remote MCP client with OAuth support, choose OAuth and complete authorization. Keep the computer online. Verify the first connection by asking the client to list the top-level names in your selected workspace, without writing files or running shell commands — a returned result that matches the folder confirms connectivity.
|
|
83
87
|
|
|
84
88
|
For Claude Code on the calling computer:
|
|
@@ -124,6 +128,16 @@ printf '%s' 'Your complete task' | \
|
|
|
124
128
|
|
|
125
129
|
`frely agent status <distribution-id>` shows the installed Skill and, for API-key installs, the Key's budget. `frely agent remove <distribution-id>` removes the Skill and its saved key.
|
|
126
130
|
|
|
131
|
+
### Install marketplace Prompts and Skills
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
frely item install <item-id> --host claude-code
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`frely item install` downloads a Prompt or Skill through Frely Cloud (the first call opens a browser for Cloud authorization). A paid part is installed only when your account holds a pass; otherwise the command prints how to buy one. Skills go to the host's Skill folder, Prompts to `--dir` (default: current directory), and scripts are saved without execute permission. Frely never overwrites a folder it did not install or a file you edited.
|
|
138
|
+
|
|
139
|
+
Cloud MCPs you buy are not installed on the device: enable them for a connection on the Frely web console (Agents page) and their tools appear inside FrelyMCP.
|
|
140
|
+
|
|
127
141
|
## Local model sharing
|
|
128
142
|
|
|
129
143
|
Publish a loopback OpenAI-compatible runtime as a Frely personal Provider. Ollama is the default driver:
|
|
@@ -142,10 +156,14 @@ frely provider share openai-compatible \
|
|
|
142
156
|
--name "Local GPU"
|
|
143
157
|
```
|
|
144
158
|
|
|
145
|
-
Requirements: Frely login, one empty active personal Provider slot, loopback HTTP, OpenAI-compatible `/v1` (default Ollama endpoint `http://127.0.0.1:11434/v1`). Model names cannot contain whitespace or `/`.
|
|
159
|
+
Requirements: Frely login, one empty active personal Provider slot (or a Creator plan, see below), loopback HTTP, OpenAI-compatible `/v1` (default Ollama endpoint `http://127.0.0.1:11434/v1`). Model names cannot contain whitespace or `/`.
|
|
146
160
|
|
|
147
161
|
The command creates a server-managed `openai-compatible` personal Provider, stores the local endpoint in owner-only CLI state, starts the Device Relay service, signs a Provider credential with the device Ed25519 key, configures CPA, and enables the declared models. Existing Frely Access Point and API-key flows consume the Provider.
|
|
148
162
|
|
|
163
|
+
### Use a local model as the base of your own Agent (Creator)
|
|
164
|
+
|
|
165
|
+
With no empty personal Provider slot, or with `--creator`, `frely provider share` creates a Creator Provider instead, counted against your Creator plan (Creator 3, Creator Plus 100). Its enabled models appear in Frely when you create an Agent. You do not sell the Provider: buyers call your Agent, which runs on your model. Keep this device online while the Agent is used, and make sure the local runtime returns `usage` in its responses.
|
|
166
|
+
|
|
149
167
|
Provider inspection:
|
|
150
168
|
|
|
151
169
|
```sh
|
|
@@ -159,10 +177,10 @@ If setup stops after the Provider was prepared, run `frely provider share` again
|
|
|
159
177
|
```sh
|
|
160
178
|
frely doctor # signed-in account, installation path, distribution, latest stable, MCP/service state
|
|
161
179
|
frely doctor -v # + config paths, runtime details, authorization expiry, last heartbeat, sanitized errors
|
|
162
|
-
frely
|
|
180
|
+
frely update # updates the running installation in place
|
|
163
181
|
```
|
|
164
182
|
|
|
165
|
-
`frely
|
|
183
|
+
`frely update` never changes to a different installer, edits PATH or downgrades a newer installation. Standalone downloads are checksum-checked and tested before the installed executable is replaced. npm/Bun installations keep their original global directory. A matching, running Device Relay service is paused for maintenance, restarted and checked after installation; credentials, device identity, MCP URL, workspace and authorization expiry are preserved. On Windows, `update` prints a PowerShell command for the detected installation to run in a local terminal.
|
|
166
184
|
|
|
167
185
|
`frely doctor` is the single diagnostic entry point and never restarts the service. `Connected` means the matching account/device process has received a WebSocket heartbeat within 75 seconds and the MCP authorization and workspace match the running relay. Neither mode completes client OAuth authorization or executes a tool call through the client. `frely doctor --mcp` is the recommended way to check the protected credential and server state.
|
|
168
186
|
|
|
@@ -202,16 +220,20 @@ The public MCP URL is the canonical resource returned by Relay, `https://mcp.fre
|
|
|
202
220
|
frely login [--relay <https-url>] [--no-browser]
|
|
203
221
|
frely logout
|
|
204
222
|
frely doctor [-v] [--json]
|
|
205
|
-
frely
|
|
223
|
+
frely update
|
|
206
224
|
frely mcp url [--workspace <path>] [--days 1..365] [--json]
|
|
207
225
|
frely mcp workspace list [--json]
|
|
208
226
|
frely mcp workspace add|remove <path>
|
|
227
|
+
frely mcp local list [--json]
|
|
228
|
+
frely mcp local add <name> (--url <address> | -- <command> [args...])
|
|
229
|
+
frely mcp local remove <name>
|
|
209
230
|
frely mcp stop|start|remove
|
|
210
231
|
frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]
|
|
211
232
|
frely agent run <distribution-id> (--input <text>|--input-stdin) [--json]
|
|
212
233
|
frely agent status (<distribution-id>|--api-key-stdin [--relay <url>]) [--json]
|
|
213
234
|
frely agent remove <distribution-id> [--json]
|
|
214
|
-
frely
|
|
235
|
+
frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]
|
|
236
|
+
frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id> | --creator] [--name <name>]
|
|
215
237
|
frely provider list [--json]
|
|
216
238
|
frely cloud list|describe|call
|
|
217
239
|
```
|
package/README.zh-CN.md
CHANGED
|
@@ -79,6 +79,10 @@ frely mcp url --workspace /path/to/project
|
|
|
79
79
|
|
|
80
80
|
`frely mcp url` 是幂等的:启用后再次运行只打印同一个 URL,需要地址时直接再运行即可。提示走 stderr,stdout 保持单一 URL(或 `--json` 时一个 JSON 对象);批准或安装失败则不打印 URL。要开放更多目录,用 `frely mcp workspace add <path>`;`frely mcp workspace list` 列出所有目录。只输入命令组而不带子命令(如 `frely mcp workspace`、`frely agent`)时,会显示该组下可用的子命令。
|
|
81
81
|
|
|
82
|
+
### 这台电脑上的本机 MCP 服务
|
|
83
|
+
|
|
84
|
+
远程 MCP 客户端也能访问只在这台电脑上运行的 MCP 服务,例如只监听 `127.0.0.1` 的浏览器插件 MCP。只监听本机回环地址的服务会被自动发现(`frely mcp local list`);其他服务用 `frely mcp local add <name> --url http://127.0.0.1:<port>/mcp`,或 `frely mcp local add <name> [--env KEY=VALUE] -- <命令> [参数...]`(stdio)手动添加。每个服务默认对远程客户端关闭,需要在 Frely 连接页面逐个开启。开启后通过两个设备工具 `local_mcp_list` 和 `local_mcp_call` 访问,运行在命令沙箱之外,使用你的用户账号。只会连接回环地址;请求头和环境变量的值只保存在本机。
|
|
85
|
+
|
|
82
86
|
把打印的完整 URL 添加到支持 OAuth 的远程 MCP 客户端,选择 OAuth 并完成授权。保持电脑在线。验证首次连接:让客户端只列出所选工作区的顶层名称,不写文件、不跑 shell 命令——返回与目录一致的结果即连通。
|
|
83
87
|
|
|
84
88
|
调用端的 Claude Code:
|
|
@@ -146,6 +150,10 @@ frely provider share openai-compatible \
|
|
|
146
150
|
|
|
147
151
|
该命令创建服务端管理的 `openai-compatible` 个人 Provider,把本地端点存入仅属主可读的 CLI 状态,启动 Device Relay 服务,用设备 Ed25519 key 签署 Provider 凭证,配置 CPA 并启用声明的模型。现有 Frely Access Point 与 API-key 流程即可消费该 Provider。
|
|
148
152
|
|
|
153
|
+
### 用本地模型作为自己 Agent 的底座(Creator)
|
|
154
|
+
|
|
155
|
+
没有空闲的个人 Provider 名额,或加上 `--creator` 时,`frely provider share` 会创建 Creator Provider,计入 Creator 套餐名额(Creator 3 个,Creator Plus 100 个)。它启用的模型会出现在 Frely 创建 Agent 的模型选择里。Provider 本身不对外售卖:买家调用的是你的 Agent,由你的模型驱动。Agent 被使用期间本机需保持在线,并且本地运行时的响应需包含 `usage`。
|
|
156
|
+
|
|
149
157
|
Provider 检查:
|
|
150
158
|
|
|
151
159
|
```sh
|
|
@@ -159,10 +167,10 @@ frely provider list
|
|
|
159
167
|
```sh
|
|
160
168
|
frely doctor # 当前账号、安装路径、发行形态、最新稳定版、MCP/服务状态
|
|
161
169
|
frely doctor -v # 另加配置路径、运行时细节、授权到期、最近心跳、脱敏错误
|
|
162
|
-
frely
|
|
170
|
+
frely update # 原地升级当前正在运行的安装
|
|
163
171
|
```
|
|
164
172
|
|
|
165
|
-
`frely
|
|
173
|
+
`frely update` 永不换安装器、不改 PATH、不降级更新版本。standalone 下载会先校验 SHA-256 并做启动测试再替换可执行文件;npm/Bun 安装保持原全局目录。匹配的、正在运行的 Device Relay 服务会被暂停维护、重启并在安装后检查;凭证、设备身份、MCP URL、工作区与授权到期均保留。Windows 上 `update` 打印检测到安装方式对应的 PowerShell 命令,请在本地终端执行。
|
|
166
174
|
|
|
167
175
|
`frely doctor` 是唯一诊断入口,永不重启服务。“Connected” 表示匹配的账号/设备进程在 75 秒内收到 WebSocket 心跳,且 MCP 授权与工作区与运行中的 relay 匹配。两种模式都不代替客户端完成 OAuth 授权,也不代替执行工具调用。`frely doctor --mcp` 是检查受保护凭证和服务端授权状态的推荐方式。
|
|
168
176
|
|
|
@@ -202,16 +210,19 @@ MCP 密钥使用 AES-256-GCM 文件,主密钥存 macOS Keychain、Windows 凭
|
|
|
202
210
|
frely login [--relay <https-url>] [--no-browser]
|
|
203
211
|
frely logout
|
|
204
212
|
frely doctor [-v] [--json]
|
|
205
|
-
frely
|
|
213
|
+
frely update
|
|
206
214
|
frely mcp url [--workspace <path>] [--days 1..365] [--json]
|
|
207
215
|
frely mcp workspace list [--json]
|
|
208
216
|
frely mcp workspace add|remove <path>
|
|
217
|
+
frely mcp local list [--json]
|
|
218
|
+
frely mcp local add <name> (--url <address> | -- <command> [args...])
|
|
219
|
+
frely mcp local remove <name>
|
|
209
220
|
frely mcp stop|start|remove
|
|
210
221
|
frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]
|
|
211
222
|
frely agent run <distribution-id> (--input <text>|--input-stdin) [--json]
|
|
212
223
|
frely agent status (<distribution-id>|--api-key-stdin [--relay <url>]) [--json]
|
|
213
224
|
frely agent remove <distribution-id> [--json]
|
|
214
|
-
frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id>] [--name <name>]
|
|
225
|
+
frely provider share [ollama|openai-compatible] [--url <loopback-v1-url>] [--models <a,b>] [--slot <slot-id> | --creator] [--name <name>]
|
|
215
226
|
frely provider list [--json]
|
|
216
227
|
frely cloud list|describe|call
|
|
217
228
|
```
|
package/dist/agent-help.d.ts
CHANGED
|
@@ -17,11 +17,11 @@ export declare const COMMANDS: readonly [{
|
|
|
17
17
|
readonly effect: "diagnostic";
|
|
18
18
|
readonly purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics.";
|
|
19
19
|
}, {
|
|
20
|
-
readonly id: "
|
|
21
|
-
readonly usage: "frely
|
|
20
|
+
readonly id: "update";
|
|
21
|
+
readonly usage: "frely update";
|
|
22
22
|
readonly auth: "none";
|
|
23
23
|
readonly effect: "local-write";
|
|
24
|
-
readonly purpose: "
|
|
24
|
+
readonly purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
|
|
25
25
|
}, {
|
|
26
26
|
readonly id: "help";
|
|
27
27
|
readonly usage: "frely help --agent --json";
|
|
@@ -52,6 +52,24 @@ export declare const COMMANDS: readonly [{
|
|
|
52
52
|
readonly auth: "mcp";
|
|
53
53
|
readonly effect: "local-write";
|
|
54
54
|
readonly purpose: "Remove an additional workspace directory (the primary cannot be removed).";
|
|
55
|
+
}, {
|
|
56
|
+
readonly id: "mcp.local.list";
|
|
57
|
+
readonly usage: "frely mcp local list [--json]";
|
|
58
|
+
readonly auth: "none";
|
|
59
|
+
readonly effect: "read";
|
|
60
|
+
readonly purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console.";
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: "mcp.local.add";
|
|
63
|
+
readonly usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]";
|
|
64
|
+
readonly auth: "none";
|
|
65
|
+
readonly effect: "local-write";
|
|
66
|
+
readonly purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console.";
|
|
67
|
+
}, {
|
|
68
|
+
readonly id: "mcp.local.remove";
|
|
69
|
+
readonly usage: "frely mcp local remove <name>";
|
|
70
|
+
readonly auth: "none";
|
|
71
|
+
readonly effect: "local-write";
|
|
72
|
+
readonly purpose: "Remove a manually added local MCP server.";
|
|
55
73
|
}, {
|
|
56
74
|
readonly id: "mcp.stop";
|
|
57
75
|
readonly usage: "frely mcp stop";
|
|
@@ -82,6 +100,12 @@ export declare const COMMANDS: readonly [{
|
|
|
82
100
|
readonly auth: "account-and-mcp";
|
|
83
101
|
readonly effect: "local-execution";
|
|
84
102
|
readonly purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use.";
|
|
103
|
+
}, {
|
|
104
|
+
readonly id: "item.install";
|
|
105
|
+
readonly usage: "frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]";
|
|
106
|
+
readonly auth: "cloud-oauth";
|
|
107
|
+
readonly effect: "local-write";
|
|
108
|
+
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.";
|
|
85
109
|
}, {
|
|
86
110
|
readonly id: "agent.install";
|
|
87
111
|
readonly usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]";
|
|
@@ -196,6 +220,30 @@ export declare const COMMANDS: readonly [{
|
|
|
196
220
|
readonly auth: "local";
|
|
197
221
|
readonly effect: "local-write";
|
|
198
222
|
readonly purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli.";
|
|
223
|
+
}, {
|
|
224
|
+
readonly id: "computer.enable";
|
|
225
|
+
readonly usage: "frely computer enable";
|
|
226
|
+
readonly auth: "local";
|
|
227
|
+
readonly effect: "local-write";
|
|
228
|
+
readonly purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it.";
|
|
229
|
+
}, {
|
|
230
|
+
readonly id: "computer.disable";
|
|
231
|
+
readonly usage: "frely computer disable";
|
|
232
|
+
readonly auth: "local";
|
|
233
|
+
readonly effect: "local-write";
|
|
234
|
+
readonly purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says.";
|
|
235
|
+
}, {
|
|
236
|
+
readonly id: "computer.status";
|
|
237
|
+
readonly usage: "frely computer status [--json]";
|
|
238
|
+
readonly auth: "local";
|
|
239
|
+
readonly effect: "read";
|
|
240
|
+
readonly purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed.";
|
|
241
|
+
}, {
|
|
242
|
+
readonly id: "computer.mcp";
|
|
243
|
+
readonly usage: "frely computer mcp";
|
|
244
|
+
readonly auth: "local";
|
|
245
|
+
readonly effect: "local-execution";
|
|
246
|
+
readonly purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use.";
|
|
199
247
|
}, {
|
|
200
248
|
readonly id: "network";
|
|
201
249
|
readonly usage: "frely network setup|status|find|use|logout [--json]";
|
|
@@ -228,11 +276,11 @@ export declare function agentHelp(): {
|
|
|
228
276
|
readonly effect: "diagnostic";
|
|
229
277
|
readonly purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics.";
|
|
230
278
|
}, {
|
|
231
|
-
readonly id: "
|
|
232
|
-
readonly usage: "frely
|
|
279
|
+
readonly id: "update";
|
|
280
|
+
readonly usage: "frely update";
|
|
233
281
|
readonly auth: "none";
|
|
234
282
|
readonly effect: "local-write";
|
|
235
|
-
readonly purpose: "
|
|
283
|
+
readonly purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions.";
|
|
236
284
|
}, {
|
|
237
285
|
readonly id: "help";
|
|
238
286
|
readonly usage: "frely help --agent --json";
|
|
@@ -263,6 +311,24 @@ export declare function agentHelp(): {
|
|
|
263
311
|
readonly auth: "mcp";
|
|
264
312
|
readonly effect: "local-write";
|
|
265
313
|
readonly purpose: "Remove an additional workspace directory (the primary cannot be removed).";
|
|
314
|
+
}, {
|
|
315
|
+
readonly id: "mcp.local.list";
|
|
316
|
+
readonly usage: "frely mcp local list [--json]";
|
|
317
|
+
readonly auth: "none";
|
|
318
|
+
readonly effect: "read";
|
|
319
|
+
readonly purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console.";
|
|
320
|
+
}, {
|
|
321
|
+
readonly id: "mcp.local.add";
|
|
322
|
+
readonly usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]";
|
|
323
|
+
readonly auth: "none";
|
|
324
|
+
readonly effect: "local-write";
|
|
325
|
+
readonly purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console.";
|
|
326
|
+
}, {
|
|
327
|
+
readonly id: "mcp.local.remove";
|
|
328
|
+
readonly usage: "frely mcp local remove <name>";
|
|
329
|
+
readonly auth: "none";
|
|
330
|
+
readonly effect: "local-write";
|
|
331
|
+
readonly purpose: "Remove a manually added local MCP server.";
|
|
266
332
|
}, {
|
|
267
333
|
readonly id: "mcp.stop";
|
|
268
334
|
readonly usage: "frely mcp stop";
|
|
@@ -293,6 +359,12 @@ export declare function agentHelp(): {
|
|
|
293
359
|
readonly auth: "account-and-mcp";
|
|
294
360
|
readonly effect: "local-execution";
|
|
295
361
|
readonly purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use.";
|
|
362
|
+
}, {
|
|
363
|
+
readonly id: "item.install";
|
|
364
|
+
readonly usage: "frely item install <item-id> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--dir <path>] [--json]";
|
|
365
|
+
readonly auth: "cloud-oauth";
|
|
366
|
+
readonly effect: "local-write";
|
|
367
|
+
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.";
|
|
296
368
|
}, {
|
|
297
369
|
readonly id: "agent.install";
|
|
298
370
|
readonly usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|project] [--api-key-stdin] [--json]";
|
|
@@ -407,6 +479,30 @@ export declare function agentHelp(): {
|
|
|
407
479
|
readonly auth: "local";
|
|
408
480
|
readonly effect: "local-write";
|
|
409
481
|
readonly purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli.";
|
|
482
|
+
}, {
|
|
483
|
+
readonly id: "computer.enable";
|
|
484
|
+
readonly usage: "frely computer enable";
|
|
485
|
+
readonly auth: "local";
|
|
486
|
+
readonly effect: "local-write";
|
|
487
|
+
readonly purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it.";
|
|
488
|
+
}, {
|
|
489
|
+
readonly id: "computer.disable";
|
|
490
|
+
readonly usage: "frely computer disable";
|
|
491
|
+
readonly auth: "local";
|
|
492
|
+
readonly effect: "local-write";
|
|
493
|
+
readonly purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says.";
|
|
494
|
+
}, {
|
|
495
|
+
readonly id: "computer.status";
|
|
496
|
+
readonly usage: "frely computer status [--json]";
|
|
497
|
+
readonly auth: "local";
|
|
498
|
+
readonly effect: "read";
|
|
499
|
+
readonly purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed.";
|
|
500
|
+
}, {
|
|
501
|
+
readonly id: "computer.mcp";
|
|
502
|
+
readonly usage: "frely computer mcp";
|
|
503
|
+
readonly auth: "local";
|
|
504
|
+
readonly effect: "local-execution";
|
|
505
|
+
readonly purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use.";
|
|
410
506
|
}, {
|
|
411
507
|
readonly id: "network";
|
|
412
508
|
readonly usage: "frely network setup|status|find|use|logout [--json]";
|
package/dist/agent-help.js
CHANGED
|
@@ -3,17 +3,21 @@ export const COMMANDS = [
|
|
|
3
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`. 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: "doctor", usage: "frely doctor [-v] [--json]", auth: "optional-account", effect: "diagnostic", purpose: "Show the signed-in account, installation, available upgrades, MCP and connection status; -v verifies the account online and runs detailed diagnostics." },
|
|
6
|
-
{ id: "
|
|
6
|
+
{ id: "update", usage: "frely update", auth: "none", effect: "local-write", purpose: "Update the current installation to the latest stable release. Windows prints a manual command; doctor checks versions." },
|
|
7
7
|
{ id: "help", usage: "frely help --agent --json", auth: "none", effect: "read", purpose: "Read this installed CLI's current Agent instructions." },
|
|
8
8
|
{ id: "mcp.url", usage: "frely mcp url [--workspace <path>] [--days 1..365] [--json]", auth: "account-and-browser-if-needed", effect: "authorization-if-needed", purpose: "Enable, renew or read device MCP. Unconfigured: request browser approval for --workspace (default: current directory) and install the background service. Expired or --days given: renew with browser approval; the MCP URL stays the same. Otherwise print the MCP URL unchanged. Prompts go to stderr; stdout holds only the URL, or JSON with HTTP transport and OAuth details." },
|
|
9
9
|
{ id: "mcp.workspace.list", usage: "frely mcp workspace list [--json]", auth: "mcp", effect: "read", purpose: "List workspace directories for this device; the primary is marked." },
|
|
10
10
|
{ id: "mcp.workspace.add", usage: "frely mcp workspace add <path>", auth: "mcp", effect: "local-write", purpose: "Add an additional workspace directory for this device." },
|
|
11
11
|
{ id: "mcp.workspace.remove", usage: "frely mcp workspace remove <path>", auth: "mcp", effect: "local-write", purpose: "Remove an additional workspace directory (the primary cannot be removed)." },
|
|
12
|
+
{ id: "mcp.local.list", usage: "frely mcp local list [--json]", auth: "none", effect: "read", purpose: "List MCP servers on this device that remote clients could use: loopback HTTP servers found automatically plus ones added by hand. Every server is off for remote clients until the owner turns it on in the web console." },
|
|
13
|
+
{ id: "mcp.local.add", usage: "frely mcp local add <name> --url <http://127.0.0.1:port/path> [--header K=V] | frely mcp local add <name> [--env K=V] -- <command> [args...]", auth: "none", effect: "local-write", purpose: "Add a local MCP server by loopback URL or by the command that starts it (stdio). It is connected once to check it works; it stays off for remote clients until the owner turns it on in the web console." },
|
|
14
|
+
{ id: "mcp.local.remove", usage: "frely mcp local remove <name>", auth: "none", effect: "local-write", purpose: "Remove a manually added local MCP server." },
|
|
12
15
|
{ id: "mcp.stop", usage: "frely mcp stop", auth: "none", effect: "local-service", purpose: "Pause the local MCP background service. Supported upgrades restore running services without this command." },
|
|
13
16
|
{ id: "mcp.start", usage: "frely mcp start", auth: "none", effect: "local-service", purpose: "Resume the local MCP background service." },
|
|
14
17
|
{ id: "mcp.remove", usage: "frely mcp remove", auth: "account", effect: "remote-write", purpose: "Revoke device MCP for every connected client and uninstall the background service (kept running provider-only when local Providers exist)." },
|
|
15
18
|
{ id: "mcp.stdio", usage: "frely mcp stdio [--workspace <path>]", auth: "mcp", effect: "local-execution", purpose: "Serve authorized local tools over stdio for a local MCP client." },
|
|
16
19
|
{ id: "mcp.serve", usage: "frely mcp serve [--workspace <path>]", auth: "account-and-mcp", effect: "local-execution", purpose: "Foreground Device Relay client; the background service runs this. Not needed for normal use." },
|
|
20
|
+
{ id: "item.install", usage: "frely item install <item-id> [--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." },
|
|
17
21
|
{ id: "agent.install", usage: "frely agent install <distribution-id|manifest-url> [--host chatgpt|codex|claude-code|pi|generic] [--scope global|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." },
|
|
18
22
|
{ id: "agent.run", usage: "frely agent run <distribution-id> (--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." },
|
|
19
23
|
{ id: "agent.status", usage: "frely agent status (<distribution-id>|--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,6 +37,10 @@ export const COMMANDS = [
|
|
|
33
37
|
{ 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." },
|
|
34
38
|
{ id: "app.update", usage: "frely app update [--json]", auth: "local", effect: "local-write", purpose: "Update the Frely App through Homebrew or by re-downloading the latest release." },
|
|
35
39
|
{ id: "app.uninstall", usage: "frely app uninstall", auth: "local", effect: "local-write", purpose: "Uninstall the Frely App. Tasks, credentials and worktrees stay with frely-cli." },
|
|
40
|
+
{ id: "computer.enable", usage: "frely computer enable", auth: "local", effect: "local-write", purpose: "Register computer use (desktop control by a remote MCP client) as the local MCP \"computer\" on this device. Run it only on a device you are sitting at. It still has to be turned on for remote clients on the Frely connections page; registering alone never exposes it." },
|
|
41
|
+
{ id: "computer.disable", usage: "frely computer disable", auth: "local", effect: "local-write", purpose: "Remove the local MCP \"computer\" so computer use stops working on this device at once, whatever the web page says." },
|
|
42
|
+
{ id: "computer.status", usage: "frely computer status [--json]", auth: "local", effect: "read", purpose: "Show whether computer use is registered locally, the runtime version it needs and whether it is installed." },
|
|
43
|
+
{ id: "computer.mcp", usage: "frely computer mcp", auth: "local", effect: "local-execution", purpose: "Stdio MCP server for computer use; local MCP forwarding starts it. Not needed for normal use." },
|
|
36
44
|
{ id: "network", usage: "frely network setup|status|find|use|logout [--json]", auth: "network", effect: "subcommand-dependent", purpose: "Access Frely Network (preview) using its separate setup and credentials." },
|
|
37
45
|
];
|
|
38
46
|
export function agentHelp() {
|
|
@@ -59,9 +67,10 @@ export function agentHelp() {
|
|
|
59
67
|
};
|
|
60
68
|
}
|
|
61
69
|
const GROUPS = [
|
|
62
|
-
{ title: "Account", ids: ["login", "logout", "doctor", "
|
|
63
|
-
{ title: "Device MCP", ids: ["mcp.url", "mcp.workspace", "mcp.lifecycle"] },
|
|
70
|
+
{ title: "Account", ids: ["login", "logout", "doctor", "update"] },
|
|
71
|
+
{ title: "Device MCP", ids: ["mcp.url", "mcp.workspace", "mcp.local", "mcp.lifecycle"] },
|
|
64
72
|
{ title: "Agents", ids: ["agent.install", "agent.run", "agent.status", "agent.remove"] },
|
|
73
|
+
{ title: "Marketplace items", ids: ["item.install"] },
|
|
65
74
|
{ title: "Providers", ids: ["provider.share", "provider.list"] },
|
|
66
75
|
{ title: "Cloud", ids: ["cloud"] },
|
|
67
76
|
];
|
|
@@ -73,10 +82,12 @@ const SHORT_USAGE = {
|
|
|
73
82
|
login: "frely login [--no-browser]",
|
|
74
83
|
logout: "frely logout",
|
|
75
84
|
doctor: "frely doctor [-v] [--json]",
|
|
76
|
-
|
|
85
|
+
update: "frely update",
|
|
77
86
|
"mcp.url": "frely mcp url [--workspace <path>] [--days 1..365] [--json]",
|
|
78
87
|
"mcp.workspace": "frely mcp workspace list|add <path>|remove <path>",
|
|
88
|
+
"mcp.local": "frely mcp local list|add <name> (--url <address>|-- <command>)|remove <name>",
|
|
79
89
|
"mcp.lifecycle": "frely mcp stop|start|remove",
|
|
90
|
+
"item.install": "frely item install <item-id> [--host <host>]",
|
|
80
91
|
"agent.install": "frely agent install <distribution-id> [--host <host>] [--api-key-stdin]",
|
|
81
92
|
"agent.run": "frely agent run <distribution-id> (--input <text>|--input-stdin)",
|
|
82
93
|
"agent.status": "frely agent status <distribution-id>",
|
|
@@ -107,7 +118,7 @@ export function subcommandUsage(group) {
|
|
|
107
118
|
}
|
|
108
119
|
export function mcpUsage() {
|
|
109
120
|
return "Device MCP — use this computer from a remote MCP client.\n\nUsage:\n"
|
|
110
|
-
+ ["mcp.url", "mcp.workspace", "mcp.lifecycle"].map((id) => " " + SHORT_USAGE[id] + "\n").join("")
|
|
121
|
+
+ ["mcp.url", "mcp.workspace", "mcp.local", "mcp.lifecycle"].map((id) => " " + SHORT_USAGE[id] + "\n").join("")
|
|
111
122
|
+ "\nStatus and diagnostics: frely doctor [-v] [--json]\n\n"
|
|
112
123
|
+ "Run frely mcp url on the computer to control. It asks for browser approval the first time (current directory, or --workspace) and when authorization has expired, installs the background service, and prints the MCP URL. Add that URL to ChatGPT, Claude Code on another computer, or another HTTP MCP client, then authorize with OAuth.\n"
|
|
113
124
|
+ "Prompts go to stderr; stdout contains only the URL or JSON. --days 1..365 renews now; the URL stays the same.\n"
|
package/dist/agent-help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-help.js","sourceRoot":"","sources":["../src/agent-help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,+KAA+K,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,wUAAwU,EAAE;IAC7kB,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,+EAA+E,EAAE;IACtK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,4BAA4B,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,wJAAwJ,EAAE;IACxQ,EAAE,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-help.js","sourceRoot":"","sources":["../src/agent-help.ts"],"names":[],"mappings":"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"}
|
package/dist/cloud.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/** Names this installation on the web console ("Frely CLI Cloud (host)"); the "Frely CLI" prefix selects per-device permissions on the server. */
|
|
2
|
+
export declare function cloudClientName(host?: string): string;
|
|
3
|
+
/** The server's `permission_required` or `confirmation_required` tool failure as a one-line hint, or null for any other result. */
|
|
4
|
+
export declare function permissionHint(result: object): string | null;
|
|
5
|
+
export declare const CLOUD_USAGE = "Frely Cloud \u2014 call your Frely application.\n frely cloud list [--group <name>]\n frely cloud describe <tool>\n frely cloud call <tool> [--json '<object>' | --input <file>]\n\nResults are JSON. The first command opens a browser for Cloud authorization;\nfrely logout also revokes it. Cloud authorization is separate from device MCP.\nCalls may create resources or incur usage. Failed writes are never replayed automatically.\nA new device may only read non-sensitive data; for anything else the error links to the web\nconsole page where you grant it (passkey or authenticator code required).\n";
|
|
2
6
|
export declare function logoutCloud(): Promise<void>;
|
|
3
7
|
export declare function runCloud(args: readonly string[]): Promise<{
|
|
4
8
|
value?: unknown;
|
|
5
9
|
text?: string;
|
|
6
10
|
failed?: boolean;
|
|
7
11
|
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Call one Cloud tool for another command (for example skill install). The
|
|
14
|
+
* result is the tool's JSON; a failed call throws CloudToolError with the
|
|
15
|
+
* server's error code. Writes are never retried.
|
|
16
|
+
*/
|
|
17
|
+
export declare function callCloudTool(name: string, input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
package/dist/cloud.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { hostname } from "node:os";
|
|
2
3
|
import { createServer } from "node:http";
|
|
3
4
|
import { readFile, stat } from "node:fs/promises";
|
|
4
5
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -7,7 +8,41 @@ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
|
7
8
|
import { credentialStore } from "./credential-store.js";
|
|
8
9
|
import { inspectAuth, normalizeRelayUrl, openVerificationUrl } from "./auth.js";
|
|
9
10
|
import { VERSION } from "./version.js";
|
|
11
|
+
import { CloudToolError } from "./skill/cloud-item.js";
|
|
10
12
|
const SERVICE = "frely-cli-cloud-v1";
|
|
13
|
+
/** Names this installation on the web console ("Frely CLI Cloud (host)"); the "Frely CLI" prefix selects per-device permissions on the server. */
|
|
14
|
+
export function cloudClientName(host = hostname()) {
|
|
15
|
+
const safe = host.replace(/[^A-Za-z0-9._ -]/g, "").trim().slice(0, 40);
|
|
16
|
+
return safe ? `Frely CLI Cloud (${safe})` : "Frely CLI Cloud";
|
|
17
|
+
}
|
|
18
|
+
/** The server's `permission_required` or `confirmation_required` tool failure as a one-line hint, or null for any other result. */
|
|
19
|
+
export function permissionHint(result) {
|
|
20
|
+
const { isError, content } = result;
|
|
21
|
+
if (isError !== true || !Array.isArray(content))
|
|
22
|
+
return null;
|
|
23
|
+
for (const part of content) {
|
|
24
|
+
const text = part.type === "text" ? part.text : undefined;
|
|
25
|
+
if (typeof text !== "string")
|
|
26
|
+
continue;
|
|
27
|
+
try {
|
|
28
|
+
const error = JSON.parse(text).error;
|
|
29
|
+
if (typeof error?.url !== "string" || (error.code !== "permission_required" && error.code !== "confirmation_required"))
|
|
30
|
+
continue;
|
|
31
|
+
const need = error.need === "write" ? "write access" : error.need === "sensitive" ? "sensitive read access" : "read access";
|
|
32
|
+
const url = new URL(error.url);
|
|
33
|
+
if (url.protocol !== "https:" && url.hostname !== "127.0.0.1" && url.hostname !== "localhost")
|
|
34
|
+
continue;
|
|
35
|
+
if (error.code === "confirmation_required") {
|
|
36
|
+
if (typeof error.confirmationId !== "string" || !/^[A-Za-z0-9_-]{1,80}$/.test(error.confirmationId))
|
|
37
|
+
continue;
|
|
38
|
+
return `${typeof error.summary === "string" ? error.summary + "\n" : ""}Approve this in your browser (passkey or authenticator code required): ${url.toString()}\nThen run the same call again with "confirmationId":"${error.confirmationId}" added to the input.`;
|
|
39
|
+
}
|
|
40
|
+
return `This device needs ${need}${typeof error.group === "string" ? " to " + error.group : ""}. Grant it in your browser (passkey or authenticator code required): ${url.toString()}`;
|
|
41
|
+
}
|
|
42
|
+
catch { /* Not a permission failure. */ }
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
11
46
|
const SCOPE = "openid profile offline_access cloud:read cloud:write cloud:execute cloud:publish";
|
|
12
47
|
export const CLOUD_USAGE = `Frely Cloud — call your Frely application.
|
|
13
48
|
frely cloud list [--group <name>]
|
|
@@ -17,6 +52,8 @@ export const CLOUD_USAGE = `Frely Cloud — call your Frely application.
|
|
|
17
52
|
Results are JSON. The first command opens a browser for Cloud authorization;
|
|
18
53
|
frely logout also revokes it. Cloud authorization is separate from device MCP.
|
|
19
54
|
Calls may create resources or incur usage. Failed writes are never replayed automatically.
|
|
55
|
+
A new device may only read non-sensitive data; for anything else the error links to the web
|
|
56
|
+
console page where you grant it (passkey or authenticator code required).
|
|
20
57
|
`;
|
|
21
58
|
async function cloudIdentity() {
|
|
22
59
|
const account = await inspectAuth();
|
|
@@ -103,7 +140,7 @@ async function connectCloud() {
|
|
|
103
140
|
const save = () => credentialStore.setPassword(SERVICE, identity.key, JSON.stringify(stored));
|
|
104
141
|
const provider = {
|
|
105
142
|
redirectUrl: stored.redirectUrl,
|
|
106
|
-
clientMetadata: { client_name:
|
|
143
|
+
clientMetadata: { client_name: cloudClientName(), redirect_uris: [stored.redirectUrl],
|
|
107
144
|
grant_types: ["authorization_code", "refresh_token"], response_types: ["code"], token_endpoint_auth_method: "none", scope: SCOPE },
|
|
108
145
|
state: () => state,
|
|
109
146
|
clientInformation: () => stored.client,
|
|
@@ -247,10 +284,45 @@ export async function runCloud(args) {
|
|
|
247
284
|
if (action === "describe")
|
|
248
285
|
return { value: tool };
|
|
249
286
|
const result = await session.client.callTool({ name: name, arguments: input }, undefined, { timeout: 180000 });
|
|
287
|
+
const hint = permissionHint(result);
|
|
288
|
+
if (hint)
|
|
289
|
+
process.stderr.write(hint + "\n");
|
|
250
290
|
return { value: result, failed: result.isError === true };
|
|
251
291
|
}
|
|
252
292
|
finally {
|
|
253
293
|
await session.close();
|
|
254
294
|
}
|
|
255
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Call one Cloud tool for another command (for example skill install). The
|
|
298
|
+
* result is the tool's JSON; a failed call throws CloudToolError with the
|
|
299
|
+
* server's error code. Writes are never retried.
|
|
300
|
+
*/
|
|
301
|
+
export async function callCloudTool(name, input) {
|
|
302
|
+
const session = await connectCloud();
|
|
303
|
+
try {
|
|
304
|
+
const result = await session.client.callTool({ name, arguments: input }, undefined, { timeout: 180000 });
|
|
305
|
+
const hint = permissionHint(result);
|
|
306
|
+
if (hint)
|
|
307
|
+
process.stderr.write(hint + "\n");
|
|
308
|
+
const text = Array.isArray(result.content) ? result.content.find(part => part.type === "text")?.text : undefined;
|
|
309
|
+
if (result.isError === true) {
|
|
310
|
+
let code = "operation_failed";
|
|
311
|
+
try {
|
|
312
|
+
const parsed = JSON.parse(String(text)).error?.code;
|
|
313
|
+
if (typeof parsed === "string")
|
|
314
|
+
code = parsed;
|
|
315
|
+
}
|
|
316
|
+
catch { /* Keep the generic code. */ }
|
|
317
|
+
throw new CloudToolError(code);
|
|
318
|
+
}
|
|
319
|
+
const value = result.structuredContent ?? (typeof text === "string" ? JSON.parse(text) : null);
|
|
320
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
321
|
+
throw new CloudToolError("invalid_operation_output");
|
|
322
|
+
return value;
|
|
323
|
+
}
|
|
324
|
+
finally {
|
|
325
|
+
await session.close();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
256
328
|
//# sourceMappingURL=cloud.js.map
|