cicy-desktop 2.1.236 → 2.1.237

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,49 +1,29 @@
1
1
  # CiCy Desktop
2
2
 
3
- CiCy Desktop is an Electron-based desktop automation worker with a small cluster control plane.
3
+ CiCy Desktop is an Electron-based desktop automation worker with a small cluster
4
+ control plane. It exposes ~100+ system tools — Chrome/CDP control, in-page
5
+ JavaScript, screenshots, clipboard, file ops, shell/node/python exec, system
6
+ info — over MCP and HTTP, plus a homepage UI for managing local and remote
7
+ teams. The `cicy-code` sidecar daemon is acquired at runtime (`npx cicy-code` on
8
+ mac/linux, Docker-in-WSL on Windows), not bundled.
4
9
 
5
- The project now has **two separate CLIs**:
10
+ ## Screenshots
6
11
 
7
- - `cicy` / `cicy-desktop`: start, stop, inspect, and manage the local desktop/cluster lifecycle
8
- - `cicy-rpc`: call worker RPC tools such as `ping`, `tools`, `open_window`, and `exec_js`
12
+ The homepage your teams (the local sidecar, private-cloud teams, and custom
13
+ remote nodes), each a card you open as a tab:
9
14
 
10
- If you remember the old unified CLI model, that is no longer the current behavior.
15
+ ![CiCy Desktop homepage team list](assets/my_teams.png)
11
16
 
12
- ## CLI split
17
+ A team opened as a tab — the agent roster on the left, a live conversation on
18
+ the right:
13
19
 
14
- ### `cicy` / `cicy-desktop`
15
- Use this for local desktop/cluster management only:
20
+ ![CiCy Desktop team workspace](assets/team.png)
16
21
 
17
- ```bash
18
- cicy start
19
- cicy stop
20
- cicy status
21
- cicy restart
22
- cicy logs
23
- ```
24
-
25
- Equivalent alias:
26
-
27
- ```bash
28
- cicy-desktop start
29
- ```
30
-
31
- Notes:
32
- - `npm start` runs the same desktop lifecycle entrypoint
33
- - `cicy --json` / `cicy -j` is not supported
34
- - RPC/tool commands moved to `cicy-rpc`
22
+ ## CLI — `cicy-desktop`
35
23
 
36
- ### `cicy-rpc`
37
- Use this for RPC/tool calls only:
38
-
39
- ```bash
40
- cicy-rpc init
41
- cicy-rpc tools
42
- cicy-rpc tools open_window
43
- cicy-rpc ping
44
- cicy-rpc open_window url=https://example.com
45
- cicy-rpc --json get_window_info win_id=1
46
- ```
24
+ `cicy-desktop` launches the Electron app — `npm start` and `npx cicy-desktop` run
25
+ the same entrypoint. Self-update with `cicy-desktop --update`; `--version` and
26
+ `--help` print info.
47
27
 
48
28
  ## Run (end users, no clone)
49
29
 
@@ -51,317 +31,100 @@ First run launches the Electron app and drops a desktop shortcut (Windows
51
31
  `.lnk` / macOS `.app` / Linux `.desktop`, all with the CiCy icon); double-click
52
32
  it afterwards.
53
33
 
54
- **CN needs the electron mirror.** A fresh machine has no cached electron
55
- binary, so electron's postinstall would hit GitHub releases and fail. Point
56
- `ELECTRON_MIRROR` + the npm registry at npmmirror.
34
+ **CN needs the electron mirror.** A fresh machine has no cached electron binary,
35
+ so electron's postinstall would otherwise hit GitHub releases and fail — point
36
+ `ELECTRON_MIRROR` and the npm registry at npmmirror.
57
37
 
58
- ### Windows — global install (NOT npx)
38
+ ### Windows — global install (not npx)
59
39
 
60
- npx's libnpmexec lock false-positives as `ECOMPROMISED` / "Lock compromised" on
61
- Windows boxes with realtime antivirus (Defender touches `node_modules` mtimes
62
- mid-install → the lock heartbeat aborts). `npm i -g` has no such lock, so
63
- Windows installs globally and launches the global bin:
40
+ npx's libnpmexec lock false-positives as "Lock compromised" on Windows boxes
41
+ with realtime antivirus (Defender touches `node_modules` mtimes mid-install).
42
+ `npm i -g` has no such lock:
64
43
 
65
44
  ```cmd
66
45
  cmd /c "set ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/&& npm i -g cicy-desktop --registry=https://registry.npmmirror.com&& cicy-desktop"
67
46
  ```
68
47
 
69
- Re-run the same line to update. The generated `.lnk` runs the global
70
- `cicy-desktop` bin (no npx).
48
+ Re-run the same line to update.
71
49
 
72
50
  ### macOS / Linux — npx
73
51
 
74
- npx's lock works fine here:
75
-
76
52
  ```bash
77
53
  ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm_config_registry=https://registry.npmmirror.com npx -y cicy-desktop
78
54
  ```
79
55
 
80
56
  Outside CN (or once electron is cached) a plain `npx -y cicy-desktop` is enough.
81
57
 
82
- ## Quick start (development)
83
-
84
- ### 1. Install
58
+ ## Develop
85
59
 
86
60
  ```bash
87
61
  git clone git@github.com:cicy-ai/cicy-desktop.git
88
62
  cd cicy-desktop
89
63
  npm install
90
- ```
91
-
92
- ### 2. Start the local desktop worker
93
-
94
- ```bash
95
- cicy start
96
- # or
97
64
  npm start
98
65
  ```
99
66
 
100
- ### 3. Initialize RPC config
101
-
102
- ```bash
103
- cicy-rpc init
104
- ```
105
-
106
- This creates `~/global.json` if it does not exist.
67
+ Config lives in `~/cicy-ai/global.json` (API token, gateway key, node list). The
68
+ worker reads its `Authorization: Bearer <token>` from there.
107
69
 
108
- ### 4. Verify connectivity
70
+ ### Homepage UI (`workers/render`)
109
71
 
110
- ```bash
111
- cicy-rpc ping
112
- ```
72
+ The desktop homepage — team cards, tabs, everything the user sees — is a Vite +
73
+ React app in `workers/render/`. The Electron main process loads a **prebuilt
74
+ snapshot** from `src/backends/homepage-react/` (a `file://` SPA: works offline,
75
+ no mixed-content issues embedding the team webview). Source and snapshot are two
76
+ different things — `scripts/build-homepage.cjs` (run on every `build:*` /
77
+ publish) rebuilds the snapshot so it never lags behind `workers/render/`.
113
78
 
114
- ### 5. Inspect available tools
79
+ Build ship the snapshot:
115
80
 
116
81
  ```bash
117
- cicy-rpc tools
118
- cicy-rpc tools open_window
119
- ```
120
-
121
- ### 6. Open a page
122
-
123
- ```bash
124
- cicy-rpc open_window url=https://example.com
125
- ```
126
-
127
- ## Homepage renderer (`workers/render`)
128
-
129
- The cicy-desktop homepage UI lives in `workers/render` — a Vite + React app that
130
- the Electron main process loads into the primary BrowserWindow.
131
-
132
- ### Where it's served from
133
-
134
- - **All platforms (Win/Mac/Linux)**: local
135
- `file:///.../src/backends/homepage-react/index.html` (a synced copy of
136
- `workers/render/dist/`). `pickHomepageURL()` returns this unconditionally —
137
- the bundled `file://` SPA works offline, is fast, and lets the homepage
138
- embed the HTTP team-assistant webview without mixed-content issues.
139
- - **Dev**: set `CICY_HOMEPAGE_URL=http://localhost:8173` to load the live
140
- vite dev server instead. See "Dev workflow" below.
141
-
142
- ### Build → ship layout
143
-
144
- ```bash
145
- # build the SPA
146
82
  cd workers/render && npm run build
147
- # copy into the file:// SPA folder cicy-desktop's main process loads from
148
83
  rsync -av --delete dist/ ../../src/backends/homepage-react/
149
84
  ```
150
85
 
151
- ### Dev workflow
152
-
153
- Vite runs **on Mac**. Source edits happen on Linux and are rsynced over —
154
- Linux itself never serves the SPA. There used to be a Linux-runs-Vite +
155
- `ssh -R` tunnel option; it was dropped because the tunnel silently dropped
156
- mid-session and the resulting blank page wasted hours.
157
-
158
- ```bash
159
- # On Linux: sync source to Mac
160
- rsync -avz --delete \
161
- --exclude=node_modules --exclude=dist --exclude=.git \
162
- ~/projects/cicy-desktop/ mac:~/projects/cicy-desktop/
163
-
164
- # On Mac: start Vite + run source-mode Electron
165
- ssh mac
166
- cd ~/projects/cicy-desktop/workers/render
167
- npm install # first time only
168
- npm run dev # serves http://localhost:8173
169
-
170
- # In another shell on Mac
171
- cd ~/projects/cicy-desktop
172
- pkill -f "MacOS/CiCy Desktop" 2>/dev/null # stop any installed .app first
173
- bash -c 'set -a; . ./.env.dev; set +a; npm start'
174
- # .env.dev sets CICY_HOMEPAGE_URL=http://localhost:8173 so Electron loads
175
- # the Vite bundle (HMR enabled) instead of the bundled file:// one.
176
- ```
177
-
178
- Now edit `workers/render/src/App.jsx` on Linux → `rsync` to Mac →
179
- Vite HMR picks it up instantly. No Electron restart for React/CSS edits.
180
-
181
- > **Fallback**: if `CICY_HOMEPAGE_URL` is set but unreachable (Vite not
182
- > started, port conflict), `homepage-window.js` falls back to the bundled
183
- > `file://` SPA so the window never stays blank.
86
+ Fast dev loop (React/CSS HMR, no Electron restart): run Vite and source-mode
87
+ Electron with `CICY_HOMEPAGE_URL=http://localhost:8173` set (via `.env.dev`).
88
+ `src/backends/homepage-window.js` falls back to the bundled `file://` SPA if that
89
+ URL is unreachable, so the window never stays blank. Full platform/loop details
90
+ (Mac fast loop, Windows packaged, the three reload classes) are in the worker's
91
+ `CLAUDE.md`.
184
92
 
185
- `src/backends/homepage-window.js` URL priority:
186
- 1. `CICY_HOMEPAGE_URL` env (dev override) → falls back to `file://` on load failure
187
- 2. All platforms → bundled `file://src/backends/homepage-react/index.html`
93
+ ## Calling tools
188
94
 
189
- ### Shipping SPA changes to Windows (hotpatch)
190
-
191
- Windows loads the same local `file://` SPA as Mac/Linux — the running
192
- npm-global install reads `src/backends/homepage-react/`. So shipping a SPA
193
- change = sync the files, **not** redeploy a Worker (there is no remote
194
- homepage Worker for Windows anymore):
195
-
196
- ```bash
197
- # build + mirror into the file:// folder
198
- cd workers/render && npm run build
199
- rsync -av --delete dist/ ../../src/backends/homepage-react/
200
- # package backend + SPA and push to the Windows box
201
- cd ../.. && tar czf /tmp/cicy-hotpatch.tgz src build bin package.json
202
- scp /tmp/cicy-hotpatch.tgz win:'C:/Users/Administrator/cicy-hotpatch.tgz'
203
- ssh win 'cd /d "C:\Users\Administrator\AppData\Roaming\npm\node_modules\cicy-desktop" && tar -xzf C:\Users\Administrator\cicy-hotpatch.tgz'
204
- # relaunch in the *interactive* session (session 0 can't paint a GUI window)
205
- ssh win 'schtasks /run /tn StartElectron'
206
- ```
95
+ The worker dispatches its tools three ways:
207
96
 
208
- The `StartElectron` scheduled task is set to "interactive only" so the
209
- relaunched window appears on the user's RDP desktop. `bin/cicy-desktop`
210
- always opens `--remote-debugging-port=9221`, so verify the reload over CDP.
211
-
212
- ## Canonical config
213
-
214
- `cicy-rpc` reads `~/global.json`.
215
-
216
- Use this format:
217
-
218
- ```json
219
- {
220
- "api_token": "your-default-token",
221
- "cicyDesktopNodes": {
222
- "local": {
223
- "api_token": "",
224
- "base_url": "http://localhost:8101"
225
- },
226
- "windows": {
227
- "api_token": "your-windows-token",
228
- "base_url": "http://windows-host:8101"
229
- }
230
- }
231
- }
232
- ```
97
+ - **In-page (IPC):** `window.electronRPC(toolName, args)` the bridge injected
98
+ into trusted BrowserWindows.
99
+ - **HTTP (REST):** `POST /rpc/:toolName` with `Authorization: Bearer <token>` —
100
+ served by the master, which forwards to the selected worker. `401
101
+ Unauthorized` means the token is wrong or missing.
102
+ - **From an agent:** the `agent-desktop` / `agent-electron` / `agent-chrome`
103
+ skills drive a connected client over WebSocket
104
+ (`agent-desktop rpc <tool>`, `agent-desktop exec …`, etc.).
233
105
 
234
- Rules:
235
- - `cicyDesktopNodes.<name>.base_url` is the worker base URL
236
- - `cicyDesktopNodes.<name>.api_token` overrides the top-level `api_token` for that node
237
- - `CICY_NODE=<name>` selects the target node
238
- - default node is `local`
106
+ Discover tools at runtime:
239
107
 
240
- Example:
108
+ - `list_tools` meta-tool (`electronRPC("list_tools")` / `agent-desktop rpc list_tools`)
109
+ - `GET /openapi.json` (browsable at `/docs`)
241
110
 
242
- ```bash
243
- CICY_NODE=windows cicy-rpc get_windows
244
- ```
245
-
246
- ## Main workflows
247
-
248
- ### Local lifecycle management
249
-
250
- ```bash
251
- cicy start
252
- cicy status
253
- cicy logs
254
- ```
255
-
256
- ### Local tool calls
257
-
258
- ```bash
259
- cicy-rpc ping
260
- cicy-rpc tools
261
- cicy-rpc open_window url=https://example.com
262
- cicy-rpc get_window_info win_id=1
263
- cicy-rpc --json get_window_info win_id=1
264
- ```
265
-
266
- ### Remote or multi-node tool calls
267
-
268
- ```bash
269
- CICY_NODE=windows cicy-rpc ping
270
- CICY_NODE=windows cicy-rpc get_windows
271
- CICY_NODE=windows cicy-rpc open_window url=https://example.com
272
- ```
273
-
274
- ## What the worker can do
275
-
276
- The worker exposes automation tools for:
277
-
278
- - browser window lifecycle and navigation
279
- - page interaction through CDP
280
- - JavaScript execution inside pages
281
- - screenshots, downloads, and clipboard operations
282
- - system window control and system information
283
- - worker/master cluster coordination
284
-
285
- For the exact tool list, use:
286
-
287
- ```bash
288
- cicy-rpc tools
289
- ```
111
+ The worker exposes automation for: browser window lifecycle and navigation, CDP
112
+ page interaction, in-page JavaScript, screenshots / downloads / clipboard,
113
+ system window control and system info, and worker/master cluster coordination.
290
114
 
291
115
  ## Architecture
292
116
 
293
- Current source of truth in code:
294
-
295
- - worker/server entry: `src/main.js:1`
296
- - RPC CLI: `src/cli/rpc.js:1`
297
- - desktop lifecycle CLI: `bin/cicy-desktop:1`
298
- - tool implementations: `src/tools/*`
299
-
300
- At a high level:
301
- - the **worker** dispatches tools two ways: in-process via `ipcMain.handle("rpc", …)` (`src/main.js`, what `window.electronRPC(tool, args)` rides) and over HTTP. The full, live tool index is `GET /openapi.json` (browse at `/docs`); call `list_tools` to enumerate from the RPC/IPC side.
302
- - REST tool invocation (`POST /rpc/:toolName`, used by `cicy-rpc`) is served by the **master** (`src/master/master-routes.js`), which forwards to the selected worker.
303
- - RPC routes are protected by auth and return `401 Unauthorized` when the token is wrong or missing
304
- - the desktop CLI starts a local master + worker cluster and provides status/log management
305
-
306
- ## Authentication
307
-
308
- RPC requests use the token loaded from `~/global.json`.
309
-
310
- - CLI calls made through `cicy-rpc` send `Authorization: Bearer <token>`
311
- - worker routes return `401 Unauthorized` if auth fails
312
- - per-node token comes from `cicyDesktopNodes.<name>.api_token`, falling back to top-level `api_token`
313
-
314
- ## Troubleshooting
315
-
316
- ### `fetch failed`
317
- Usually means the target node is unreachable.
318
-
319
- Check:
320
-
321
- ```bash
322
- cicy status
323
- cicy-rpc ping
324
- CICY_NODE=windows cicy-rpc ping
325
- ```
326
-
327
- If needed, verify the node's `base_url` in `~/global.json`.
328
-
329
- ### `HTTP 401 Unauthorized`
330
- Usually means the URL is correct but the token is wrong.
331
-
332
- Check:
333
- - `api_token`
334
- - `cicyDesktopNodes.<name>.api_token`
335
- - `cicyDesktopNodes.<name>.base_url`
336
-
337
- Then retry:
338
-
339
- ```bash
340
- cicy-rpc ping
341
- ```
342
-
343
- ### Window opened but page is not ready yet
344
- Query the window state and wait for loading to finish:
345
-
346
- ```bash
347
- cicy-rpc get_window_info win_id=1
348
- ```
349
-
350
- For remote nodes:
351
-
352
- ```bash
353
- CICY_NODE=windows cicy-rpc get_window_info win_id=1
354
- ```
355
-
356
- ## Documentation
357
-
358
- Use the root README as the entrypoint, then go deeper here:
117
+ - worker/server entry `src/main.js`
118
+ - desktop lifecycle CLI — `bin/cicy-desktop`
119
+ - tool implementations `src/tools/*`
120
+ - master (routes `POST /rpc/:toolName` to workers) — `src/master/master-routes.js`
121
+ - homepage source `workers/render/` → built into `src/backends/homepage-react/`
359
122
 
360
- - [CLI split and usage](./skills/cicy-cli/README.md)
361
- - [RPC CLI details](./packages/cicy-rpc/README.md)
362
- - [REST API notes](./docs/REST-API.md)
363
- - [Desktop service skill](./skills/cicy-desktop-service/README.md)
123
+ The **worker** dispatches tools in-process via `ipcMain.handle("rpc", …)` (what
124
+ `window.electronRPC` rides) and over HTTP; the live tool index is
125
+ `GET /openapi.json`. The desktop CLI starts a local master + worker cluster and
126
+ manages status/logs.
364
127
 
365
128
  ## License
366
129
 
367
- Apache-2.0
130
+ [Apache-2.0](./LICENSE).
Binary file
Binary file
package/bin/cicy-desktop CHANGED
@@ -268,7 +268,7 @@ for (let i = 0; i < args.length; i++) {
268
268
  } else if (arg === "-v" || arg === "--version") {
269
269
  showVersion = true;
270
270
  } else if (arg === "-j" || arg === "--json") {
271
- console.error("[x] --json is only supported by cicy-rpc");
271
+ console.error("[x] --json is not supported");
272
272
  process.exit(1);
273
273
  } else if (arg === "-cn" || arg === "--cn") {
274
274
  useCNMirror = true;
@@ -343,9 +343,7 @@ Examples:
343
343
  cicy status
344
344
  cicy restart
345
345
  cicy logs
346
- cicy --port 8201
347
-
348
- RPC commands moved to: cicy-rpc`);
346
+ cicy --port 8201`);
349
347
  }
350
348
 
351
349
  function update() {
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "cicy-desktop",
3
- "version": "2.1.236",
3
+ "version": "2.1.237",
4
4
  "description": "CiCy - AI-powered operating system browser",
5
5
  "main": "src/main.js",
6
6
  "bin": {
7
- "cicy-desktop": "./bin/cicy-desktop",
8
- "cicy": "./bin/cicy-desktop",
9
- "cicy-rpc": "./bin/cicy-rpc"
7
+ "cicy-desktop": "./bin/cicy-desktop"
10
8
  },
11
9
  "scripts": {
12
10
  "start": "node ./bin/cicy-desktop",
@@ -16,7 +14,6 @@
16
14
  "test": "jest",
17
15
  "test:ls": "node tests/test-ls.js",
18
16
  "build": "electron-builder --publish never",
19
- "build:ui": "cd packages/ui-react && npm install && npm run build",
20
17
  "build:homepage": "node scripts/build-homepage.cjs",
21
18
  "prebuild:win": "node scripts/build-homepage.cjs",
22
19
  "prebuild:mac": "node scripts/build-homepage.cjs",
@@ -144,11 +141,11 @@
144
141
  "//optionalDependencies": "(2026-06 回调): mac/linux 改回 native cicy-code(:8008,colima 在 16G mac 上压垮内存)→ 重新内置 cicy-code-<plat> / cicy-mihomo-<plat>,localbin.fromBundle 零网络 seed(npm 仅作更新通道,带 npmmirror→npmjs 回退)。这些由 scripts/sync-runtime-deps.cjs 在 tag-push 时同步到最新版。npm 的 os/cpu 字段保证每个平台只装自己那份。Windows 仍走 docker(WSL :8009),它那份 cicy-code-windows 用不到但 bundle 着无害。",
145
142
  "optionalDependencies": {
146
143
  "electron": "41.0.3",
147
- "cicy-code-darwin-x64": "2.3.190",
148
- "cicy-code-darwin-arm64": "2.3.190",
149
- "cicy-code-linux-x64": "2.3.190",
150
- "cicy-code-linux-arm64": "2.3.190",
151
- "cicy-code-windows-x64": "2.3.190",
144
+ "cicy-code-darwin-x64": "2.3.192",
145
+ "cicy-code-darwin-arm64": "2.3.192",
146
+ "cicy-code-linux-x64": "2.3.192",
147
+ "cicy-code-linux-arm64": "2.3.192",
148
+ "cicy-code-windows-x64": "2.3.192",
152
149
  "cicy-mihomo-darwin-x64": "1.10.4",
153
150
  "cicy-mihomo-darwin-arm64": "1.10.4",
154
151
  "cicy-mihomo-linux-x64": "1.10.4",
@@ -1,9 +1,8 @@
1
- // Copyright 2026 CiCy AI
2
- // SPDX-License-Identifier: Apache-2.0
3
-
1
+ // Copyright 2026 CiCy AI
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
4
  const express = require("express");
5
5
  const cors = require("cors");
6
- const fs = require("fs");
7
6
  const path = require("path");
8
7
  const uiRoutes = require("./ui-routes");
9
8
 
@@ -156,31 +155,18 @@ function createExpressApp(authMiddleware, tools = {}) {
156
155
  }
157
156
  });
158
157
 
159
- const reactUiDir = path.join(__dirname, "../ui-react-dist");
160
-
161
- // Keep legacy UI for fallback/debugging
158
+ // Legacy debug UI. The React /console (packages/ui-react ui-react-dist) was
159
+ // removed — it was served but nothing in the app ever linked to it; the real
160
+ // desktop UI is the homepage + tab-shell. ui.html stays as a bare debug page.
162
161
  app.get("/ui-legacy", (req, res) => {
163
162
  res.sendFile(path.join(__dirname, "../ui.html"));
164
163
  });
165
164
 
166
- // UI (React) lives at /console; /ui is reserved for UI APIs (snapshot, windows, etc.)
167
- if (fs.existsSync(reactUiDir)) {
168
- app.use("/console", express.static(reactUiDir));
169
- app.get(["/console", "/console/*"], (req, res) => {
170
- res.sendFile(path.join(reactUiDir, "index.html"));
171
- });
172
- } else {
173
- // Fallback: serve legacy UI at /console too
174
- app.get(["/console", "/console/*"], (req, res) => {
175
- res.sendFile(path.join(__dirname, "../ui.html"));
176
- });
177
- }
178
-
179
165
  // Mount UI API routes under /ui
180
166
  app.use("/ui", uiRoutes);
181
167
 
182
- // Convenience redirect
183
- app.get("/", (req, res) => res.redirect("/console/chrome"));
168
+ // Root → the remaining legacy debug UI.
169
+ app.get("/", (req, res) => res.redirect("/ui-legacy"));
184
170
 
185
171
  return app;
186
172
  }