cloudagent-daemon 0.2.1__tar.gz
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.
- cloudagent_daemon-0.2.1/.gitignore +89 -0
- cloudagent_daemon-0.2.1/LICENSE +21 -0
- cloudagent_daemon-0.2.1/PKG-INFO +322 -0
- cloudagent_daemon-0.2.1/README.md +290 -0
- cloudagent_daemon-0.2.1/pyproject.toml +67 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/__init__.py +1 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/__main__.py +4 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/claude_runner.py +1068 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/cli.py +833 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/config.py +197 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/doctor.py +534 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/frame_dispatch.py +216 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/http_outbound.py +80 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/jsonl_logging.py +98 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/login.py +34 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/main_loop.py +891 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/mcp_bridge.py +441 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/metrics.py +315 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/metrics_server.py +149 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/outbound_queue.py +289 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/paths.py +204 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/protocol.py +141 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/runtime_detect.py +135 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/service.py +355 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/spawn_outbox.py +443 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/spawn_queue.py +200 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/sse_client.py +439 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/transport.py +105 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/unix_socket.py +278 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/workspace.py +441 -0
- cloudagent_daemon-0.2.1/src/cloudagent_daemon/ws_client.py +431 -0
- cloudagent_daemon-0.2.1/uv.lock +849 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.env
|
|
2
|
+
.env.*
|
|
3
|
+
# Allow env templates + non-secret env files to be committed (override .env.* rule above)
|
|
4
|
+
!.env.example
|
|
5
|
+
!**/.env.example
|
|
6
|
+
!**/.env.development
|
|
7
|
+
!**/.env.staging
|
|
8
|
+
!**/.env.production
|
|
9
|
+
|
|
10
|
+
# Local work-in-progress scratch dir (never committed)
|
|
11
|
+
abu/
|
|
12
|
+
|
|
13
|
+
# GSD workflow tool config (local only)
|
|
14
|
+
.planning/
|
|
15
|
+
|
|
16
|
+
__pycache__/
|
|
17
|
+
*.pyc
|
|
18
|
+
*.pyo
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
dist/
|
|
23
|
+
build/
|
|
24
|
+
.venv/
|
|
25
|
+
**/.venv/
|
|
26
|
+
**/.venv.*/
|
|
27
|
+
experiments/**/.venv*
|
|
28
|
+
experiments/**/venv*
|
|
29
|
+
experiments/**/__pycache__/
|
|
30
|
+
experiments/**/*.db
|
|
31
|
+
experiments/**/*.sqlite3
|
|
32
|
+
experiments/**/*.log
|
|
33
|
+
experiments/**/screenshots/
|
|
34
|
+
experiments/**/*-result.json
|
|
35
|
+
experiments/**/*-logs/
|
|
36
|
+
node_modules/
|
|
37
|
+
.next/
|
|
38
|
+
.turbo/
|
|
39
|
+
*.tsbuildinfo
|
|
40
|
+
|
|
41
|
+
# Local agent workspace configs (not shared across team)
|
|
42
|
+
.claude/
|
|
43
|
+
CLAUDE.md
|
|
44
|
+
# Exception: 子项目的 CLAUDE.md 是跨人共享的项目定位/原则文档(含 BFF 共用纪律等),入库
|
|
45
|
+
!one-company-fe/CLAUDE.md
|
|
46
|
+
!one-company-desktop/CLAUDE.md
|
|
47
|
+
|
|
48
|
+
# Git worktrees (local-only, isolated feature branches)
|
|
49
|
+
.worktrees/
|
|
50
|
+
|
|
51
|
+
# Local agent scratch output (UI checker screenshots, design data dumps, etc.)
|
|
52
|
+
.r2c/
|
|
53
|
+
one-company-fe/deploy
|
|
54
|
+
# tests/regression 是本地回归测试工作目录(test-cases / fixtures / runs / scripts)
|
|
55
|
+
one-company-fe/tests/regression/
|
|
56
|
+
# Local DB dumps / migration backups — never commit (may contain secrets)
|
|
57
|
+
backups/
|
|
58
|
+
|
|
59
|
+
# Onboarding PDFs — large binaries, distribute via OSS / 钉钉 instead
|
|
60
|
+
docs/m5/*.pdf
|
|
61
|
+
|
|
62
|
+
# screens 目录是浏览器手测产物
|
|
63
|
+
screens/
|
|
64
|
+
package-lock.json
|
|
65
|
+
|
|
66
|
+
# Next.js --experimental-https 自动生成的 mkcert 自签证书(local dev only)
|
|
67
|
+
**/certificates/
|
|
68
|
+
|
|
69
|
+
# 日报自动化相关 + 本地工作区个人配置(不提交到仓库)
|
|
70
|
+
/scripts/daily_report_simple.sh
|
|
71
|
+
/scripts/generate_daily_report.sh
|
|
72
|
+
/scripts/generate_smart_report.py
|
|
73
|
+
/scripts/README_DAILY_REPORT.md
|
|
74
|
+
/tmp/daily_report.log
|
|
75
|
+
|
|
76
|
+
# 个人 / 本地工作区文件 (Claude personality / cron 经验 / 个人 memory / 工作区 Python 配置)
|
|
77
|
+
/SOUL.md
|
|
78
|
+
/AGENTS.md
|
|
79
|
+
/USER.md
|
|
80
|
+
/memory/
|
|
81
|
+
/.cron-experience/
|
|
82
|
+
/.real/
|
|
83
|
+
/pyproject.toml
|
|
84
|
+
.qoder/
|
|
85
|
+
|
|
86
|
+
# playwright 测试相关
|
|
87
|
+
.playwright-mcp/
|
|
88
|
+
tests/
|
|
89
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 chaoyin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cloudagent-daemon
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Local daemon for cloudagent — bridges Claude Code subprocesses to the cloudagent backend over WebSocket.
|
|
5
|
+
Project-URL: Homepage, https://cloudagent.chat
|
|
6
|
+
Project-URL: Repository, https://codeup.aliyun.com/69bd0a4d29ad98af4065ce71/cloudagent
|
|
7
|
+
Project-URL: Documentation, https://codeup.aliyun.com/69bd0a4d29ad98af4065ce71/cloudagent/docs/superpowers/specs
|
|
8
|
+
Author-email: chaoyin <tudoucyx@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai-coding-agent,claude-code,cloudagent,daemon
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: h2>=4
|
|
21
|
+
Requires-Dist: httpx-sse>=0.4
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Requires-Dist: mcp>=0.9
|
|
24
|
+
Requires-Dist: pydantic>=2.7
|
|
25
|
+
Requires-Dist: typer>=0.12
|
|
26
|
+
Requires-Dist: websockets>=12
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: anyio>=4.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# cloudagent-daemon
|
|
34
|
+
|
|
35
|
+
Local daemon for cloudagent — runs on user's machine, bridges Claude Code
|
|
36
|
+
subprocesses to the cloudagent backend so that agents can work locally with
|
|
37
|
+
your machine's filesystem and tools.
|
|
38
|
+
|
|
39
|
+
**Architecture:** spawn-on-message model — daemon receives a `deliver` frame over
|
|
40
|
+
WebSocket, spawns `claude --resume <session_id>`, claude uses an MCP server
|
|
41
|
+
(also embedded in this daemon) to `send_message` / `list_messages` back to the
|
|
42
|
+
backend, and exits when its work is done.
|
|
43
|
+
|
|
44
|
+
## Quick start (no clone)
|
|
45
|
+
|
|
46
|
+
The fastest way to run cloudagent-daemon, slock-style:
|
|
47
|
+
|
|
48
|
+
Each command below is a SINGLE LINE — copy the whole line as-is.
|
|
49
|
+
Multi-line snippets with `\` continuations are fragile across copy-paste
|
|
50
|
+
(some terminals / web `<pre>` blocks drop the trailing `\` and break the
|
|
51
|
+
command into separate statements).
|
|
52
|
+
|
|
53
|
+
> **Tag-pinned releases.** The `@daemon-vX.Y.Z` ref below points at a frozen
|
|
54
|
+
> daemon release (annotated git tag). To upgrade later, re-run the same
|
|
55
|
+
> command with the latest tag — see `git ls-remote --tags origin "daemon-v*"`
|
|
56
|
+
> on the cloudagent repo, or [the releases list][releases]. Don't replace
|
|
57
|
+
> the tag with a branch name (e.g. `cy` / `m5`); branches move and can drag
|
|
58
|
+
> in unrelated work-in-progress.
|
|
59
|
+
|
|
60
|
+
[releases]: https://codeup.aliyun.com/69bd0a4d29ad98af4065ce71/cloudagent/-/tags?search=daemon-v
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# One-shot run (no install) — single line
|
|
64
|
+
uvx --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Or install persistently — single line, install + start chained with &&
|
|
69
|
+
uv tool install --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon && cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
To upgrade an existing install to the newest tag (forces re-resolve of the
|
|
73
|
+
git ref so a moved tag wouldn't silently stick on the old commit anyway —
|
|
74
|
+
but tags are immutable here, so the bump in the URL is the real signal):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
uv tool install --reinstall --force --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Once published to PyPI, this becomes:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uvx cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***
|
|
84
|
+
# or
|
|
85
|
+
pipx install cloudagent-daemon
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Install
|
|
89
|
+
|
|
90
|
+
Requires Python 3.12+ and Claude Code CLI installed.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install -e ./daemon_cli
|
|
94
|
+
# or after release:
|
|
95
|
+
# pipx install cloudagent-daemon
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Quick start
|
|
99
|
+
|
|
100
|
+
1. Create a host machine in the cloudagent UI (or via REST):
|
|
101
|
+
```bash
|
|
102
|
+
curl -X POST https://api.cloudagent.chat/v1/host-machines \
|
|
103
|
+
-H "Authorization: Bearer <your_user_jwt>" \
|
|
104
|
+
-H "Content-Type: application/json" \
|
|
105
|
+
-d '{"name":"my-mac","hostname":"mbp.local","os":"darwin","daemon_version":"0.1.0"}'
|
|
106
|
+
```
|
|
107
|
+
Capture the `raw_key` from the response — it starts with `sk_machine_` and
|
|
108
|
+
is shown only once.
|
|
109
|
+
|
|
110
|
+
2. Login:
|
|
111
|
+
```bash
|
|
112
|
+
cloudagent-daemon login --server https://api.cloudagent.chat
|
|
113
|
+
# paste the sk_machine_*** key when prompted
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
3. Register a local agent (the agent must already exist in cloudagent with
|
|
117
|
+
`runtime=local_daemon` and `host_machine_id=<your host>`):
|
|
118
|
+
```bash
|
|
119
|
+
cloudagent-daemon agent register --agent-id agent_01HXX --name Frontend
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
4. Start the daemon:
|
|
123
|
+
```bash
|
|
124
|
+
cloudagent-daemon start &
|
|
125
|
+
cloudagent-daemon status
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
You can also use a process manager like `launchd` (macOS) or `systemd`
|
|
129
|
+
(Linux) — see "Running as a service" below.
|
|
130
|
+
|
|
131
|
+
5. From the cloudagent UI / API: send a message to the agent. The daemon will
|
|
132
|
+
spawn `claude` to handle it; check `~/.cloudagent/daemon/logs/` for traces.
|
|
133
|
+
|
|
134
|
+
## One-shot mode
|
|
135
|
+
|
|
136
|
+
For ephemeral runs (CI / debug / quick demo), pass server + key inline — no
|
|
137
|
+
`login` step required and nothing is written to `~/.cloudagent/`:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
cloudagent-daemon start \
|
|
141
|
+
--server-url https://api.cloudagent.chat \
|
|
142
|
+
--api-key sk_machine_***
|
|
143
|
+
|
|
144
|
+
# Output:
|
|
145
|
+
# Detected runtimes:
|
|
146
|
+
# ✓ claude_code 2.1.137 (/opt/homebrew/bin/claude)
|
|
147
|
+
# Connecting to https://api.cloudagent.chat as host host_01HXX...
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`--server-url` and `--api-key` must be passed together; passing one without
|
|
151
|
+
the other exits with code 2. The daemon stops on Ctrl-C / SIGTERM and leaves
|
|
152
|
+
no state behind. For persistent setups, use `login` once + `start` after.
|
|
153
|
+
|
|
154
|
+
## Layout
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
~/.cloudagent/
|
|
158
|
+
├── daemon/
|
|
159
|
+
│ ├── config.json # server URL + machine API key + host_id
|
|
160
|
+
│ ├── state.json # last_seq + processed message IDs (for dedup)
|
|
161
|
+
│ ├── daemon.pid # PID of running daemon
|
|
162
|
+
│ ├── bridge.sock # unix socket for MCP bridge IPC
|
|
163
|
+
│ └── logs/
|
|
164
|
+
└── agents/
|
|
165
|
+
└── <agent_id>/
|
|
166
|
+
├── MEMORY.md # agent's long-term memory
|
|
167
|
+
├── notes/ # agent-managed
|
|
168
|
+
├── workspace/ # agent's working directory
|
|
169
|
+
└── .meta/ # daemon-managed (identity, mcp config, etc.)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Commands
|
|
173
|
+
|
|
174
|
+
| Command | Description |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `cloudagent-daemon login --server URL` | Auth + persist machine key |
|
|
177
|
+
| `cloudagent-daemon start` | Run the daemon (foreground) |
|
|
178
|
+
| `cloudagent-daemon status` | Print PID + connection info |
|
|
179
|
+
| `cloudagent-daemon stop` | Send SIGTERM, wait for clean exit |
|
|
180
|
+
| `cloudagent-daemon install-service` | Install + start as launchd / systemd user service (auto-restart on crash, auto-start at login) |
|
|
181
|
+
| `cloudagent-daemon uninstall-service` | Stop + remove the launchd / systemd service unit |
|
|
182
|
+
| `cloudagent-daemon agent register --agent-id ID` | Create local workspace |
|
|
183
|
+
| `cloudagent-daemon agent unregister --agent-id ID` | Archive workspace |
|
|
184
|
+
|
|
185
|
+
## Logs
|
|
186
|
+
|
|
187
|
+
`~/.cloudagent/daemon/logs/daemon-YYYY-MM-DD.log`. Tail with:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
tail -F ~/.cloudagent/daemon/logs/daemon-*.log
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Troubleshooting
|
|
194
|
+
|
|
195
|
+
- **`Login failed: 401`** — the `sk_machine_***` key was revoked. Create a new
|
|
196
|
+
one in the cloudagent UI (host machine settings).
|
|
197
|
+
- **`daemon not running` after `start &`** — check the log file. Common causes:
|
|
198
|
+
config missing (`login` first), backend unreachable, no claude binary on PATH.
|
|
199
|
+
- **`claude: command not found`** — install Claude Code: see https://claude.ai/code
|
|
200
|
+
- **`agent_status: crashed`** repeatedly — check `~/.cloudagent/agents/<id>/.meta/last-spawn.json`
|
|
201
|
+
for the stderr tail. Common causes: bad MCP config, claude binary version mismatch, agent's
|
|
202
|
+
cwd doesn't exist.
|
|
203
|
+
- **`Backpressure dropped`** — your daemon was offline for too long; the
|
|
204
|
+
cloudagent backend dropped queued messages past 100k.
|
|
205
|
+
|
|
206
|
+
## Running as a service
|
|
207
|
+
|
|
208
|
+
The daemon ships with `install-service` / `uninstall-service` commands that
|
|
209
|
+
generate and load a launchd (macOS) or systemd (Linux) **user** unit configured
|
|
210
|
+
to **auto-restart on crash** (KeepAlive / Restart=always) and **auto-start at
|
|
211
|
+
login**. This is the commercial-grade default — the daemon never self-exits
|
|
212
|
+
unless you explicitly run `uninstall-service` (or stop it via the OS).
|
|
213
|
+
|
|
214
|
+
### macOS / Linux
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# After login (server URL + key persisted in ~/.cloudagent/daemon/config.json):
|
|
218
|
+
cloudagent-daemon login --server https://api.cloudagent.chat --api-key sk_machine_***
|
|
219
|
+
cloudagent-daemon install-service
|
|
220
|
+
|
|
221
|
+
# Or one-shot — embed creds directly in the unit file:
|
|
222
|
+
cloudagent-daemon install-service \
|
|
223
|
+
--server-url https://api.cloudagent.chat \
|
|
224
|
+
--api-key sk_machine_*** \
|
|
225
|
+
--insecure # only if your server uses a self-signed cert
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The command writes:
|
|
229
|
+
|
|
230
|
+
- macOS: `~/Library/LaunchAgents/chat.cloudagent.daemon.plist` (KeepAlive=true)
|
|
231
|
+
- Linux: `~/.config/systemd/user/cloudagent-daemon.service` (Restart=always, RestartSec=5)
|
|
232
|
+
|
|
233
|
+
…then bootstraps + kickstarts (macOS) / `daemon-reload` + `enable --now` (Linux).
|
|
234
|
+
Logs:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# macOS
|
|
238
|
+
tail -F ~/.cloudagent/daemon/logs/launchd.{out,err}.log
|
|
239
|
+
|
|
240
|
+
# Linux
|
|
241
|
+
journalctl --user -u cloudagent-daemon -f
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
To remove:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
cloudagent-daemon uninstall-service
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Multi-profile (managing multiple backends)
|
|
251
|
+
|
|
252
|
+
You can register the same machine with several cloudagent backends (prod / fr /
|
|
253
|
+
staging / dev …) by giving each its own `--profile <name>`. Each profile gets
|
|
254
|
+
its own service unit, config, socket, workspace, and launchd / systemd label —
|
|
255
|
+
they coexist on disk and run as independent processes.
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Default profile (no flag) keeps the legacy paths exactly as before:
|
|
259
|
+
cloudagent-daemon install-service \
|
|
260
|
+
--server-url https://api.cloudagent.chat --api-key sk_machine_xxx
|
|
261
|
+
|
|
262
|
+
# Register a second backend under profile "fr":
|
|
263
|
+
cloudagent-daemon install-service --profile fr \
|
|
264
|
+
--server-url https://api-fr.cloudagent.chat --api-key sk_machine_yyy --insecure
|
|
265
|
+
|
|
266
|
+
# Register a third under "staging":
|
|
267
|
+
cloudagent-daemon install-service --profile staging \
|
|
268
|
+
--server-url https://api-staging.cloudagent.chat --api-key sk_machine_zzz
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Inspect what's installed:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
cloudagent-daemon list-profiles
|
|
275
|
+
# ● default
|
|
276
|
+
# server: https://api.cloudagent.chat
|
|
277
|
+
# host_id: host_a1b2c3
|
|
278
|
+
# status: running pid=12345
|
|
279
|
+
# ● fr
|
|
280
|
+
# server: https://api-fr.cloudagent.chat
|
|
281
|
+
# host_id: host_d4e5f6
|
|
282
|
+
# status: running pid=12350
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
All commands take `--profile <name>` (default is `default`):
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
cloudagent-daemon status --profile fr
|
|
289
|
+
cloudagent-daemon doctor --profile fr
|
|
290
|
+
cloudagent-daemon stop --profile fr
|
|
291
|
+
cloudagent-daemon uninstall-service --profile fr
|
|
292
|
+
cloudagent-daemon agent register --profile fr --agent-id a1
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Profile names must match `[a-z0-9][a-z0-9-]{0,30}`. `default` is reserved.
|
|
296
|
+
|
|
297
|
+
### Per-profile filesystem layout
|
|
298
|
+
|
|
299
|
+
| Resource | Default profile | Named profile `fr` |
|
|
300
|
+
|---|---|---|
|
|
301
|
+
| Config / state | `~/.cloudagent/daemon/{config,state}.json` | `~/.cloudagent/daemon/profiles/fr/{config,state}.json` |
|
|
302
|
+
| IPC socket | `~/.cloudagent/daemon/bridge.sock` | `~/.cloudagent/daemon/profiles/fr/bridge.sock` |
|
|
303
|
+
| Workspace | `~/.cloudagent/agents/` | `~/.cloudagent/agents-fr/` |
|
|
304
|
+
| Logs | `~/.cloudagent/daemon/logs/launchd.{out,err}.log` | `~/.cloudagent/daemon/profiles/fr/logs/launchd.{out,err}.log` |
|
|
305
|
+
| launchd label | `chat.cloudagent.daemon` | `chat.cloudagent.daemon.fr` |
|
|
306
|
+
| systemd unit | `cloudagent-daemon.service` | `cloudagent-daemon-fr.service` |
|
|
307
|
+
|
|
308
|
+
The default profile keeps the original paths byte-for-byte — existing installs
|
|
309
|
+
need no migration. Named profiles only show up after their first
|
|
310
|
+
`install-service --profile <name>`.
|
|
311
|
+
|
|
312
|
+
The active profile pins itself in `CLOUDAGENT_DAEMON_PROFILE` for any child
|
|
313
|
+
process the daemon spawns (mcp_bridge, claude subprocesses), so commands you
|
|
314
|
+
run inside an agent shell pick up the right profile automatically.
|
|
315
|
+
|
|
316
|
+
## Spec
|
|
317
|
+
|
|
318
|
+
See `docs/superpowers/specs/2026-05-08-local-daemon-runtime-design.md`.
|
|
319
|
+
|
|
320
|
+
## License
|
|
321
|
+
|
|
322
|
+
MIT — see [LICENSE](./LICENSE).
|