cloudagent-daemon 0.2.3__tar.gz → 0.2.5__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.3 → cloudagent_daemon-0.2.5}/PKG-INFO +1 -1
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/pyproject.toml +1 -1
- cloudagent_daemon-0.2.5/src/cloudagent_daemon/__init__.py +1 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/service.py +72 -9
- cloudagent_daemon-0.2.3/src/cloudagent_daemon/__init__.py +0 -1
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/.gitignore +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/LICENSE +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/README.md +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/__main__.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/claude_runner.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/cli.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/config.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/doctor.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/frame_dispatch.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/http_outbound.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/jsonl_logging.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/login.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/main_loop.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/mcp_bridge.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/metrics.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/metrics_server.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/outbound_queue.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/paths.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/protocol.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/runtime_detect.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/spawn_outbox.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/spawn_queue.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/sse_client.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/transport.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/unix_socket.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/workspace.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/src/cloudagent_daemon/ws_client.py +0 -0
- {cloudagent_daemon-0.2.3 → cloudagent_daemon-0.2.5}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudagent-daemon
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: Local daemon for cloudagent — bridges Claude Code subprocesses to the cloudagent backend over WebSocket.
|
|
5
5
|
Project-URL: Homepage, https://cloudagent.chat
|
|
6
6
|
Project-URL: Repository, https://codeup.aliyun.com/69bd0a4d29ad98af4065ce71/cloudagent
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cloudagent-daemon"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.5"
|
|
8
8
|
description = "Local daemon for cloudagent — bridges Claude Code subprocesses to the cloudagent backend over WebSocket."
|
|
9
9
|
authors = [{name = "chaoyin", email = "tudoucyx@gmail.com"}]
|
|
10
10
|
readme = "README.md"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.5"
|
|
@@ -17,6 +17,7 @@ import os
|
|
|
17
17
|
import platform
|
|
18
18
|
import shutil
|
|
19
19
|
import subprocess
|
|
20
|
+
import time
|
|
20
21
|
from pathlib import Path
|
|
21
22
|
|
|
22
23
|
from .paths import (
|
|
@@ -200,18 +201,69 @@ def install_macos(
|
|
|
200
201
|
plist_path.chmod(0o600)
|
|
201
202
|
|
|
202
203
|
uid = os.getuid()
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
204
|
+
domain = f"gui/{uid}"
|
|
205
|
+
service_target = f"{domain}/{label}"
|
|
206
|
+
_launchd_reinstall(domain, service_target, plist_path)
|
|
207
|
+
return plist_path
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _launchd_reinstall(
|
|
211
|
+
domain: str, service_target: str, plist_path: Path
|
|
212
|
+
) -> None:
|
|
213
|
+
"""Reinstall a launchd job: bootout → wait → bootstrap → kickstart.
|
|
214
|
+
|
|
215
|
+
Reinstall-safe + race-safe. Two problems this handles:
|
|
216
|
+
|
|
217
|
+
1. A plain ``bootstrap`` is a no-op when the service is already
|
|
218
|
+
loaded — launchd keeps the OLD in-memory plist and never re-reads
|
|
219
|
+
the file. So we ``bootout`` first to unload any loaded instance.
|
|
220
|
+
|
|
221
|
+
2. ``bootout`` is *asynchronous*: launchctl returns before launchd
|
|
222
|
+
has finished tearing the job down. A ``bootstrap`` fired
|
|
223
|
+
immediately races the still-unloading job and fails with
|
|
224
|
+
``Input/output error`` (5). So after bootout we POLL
|
|
225
|
+
``launchctl print`` until the job is genuinely gone, then
|
|
226
|
+
bootstrap — with a few retries for slow teardown.
|
|
227
|
+
|
|
228
|
+
Raises RuntimeError if bootstrap never succeeds (cli surfaces it as
|
|
229
|
+
a clean error instead of the old silent "✓ Installed" lie).
|
|
230
|
+
"""
|
|
231
|
+
subprocess.run(["launchctl", "bootout", service_target], check=False)
|
|
232
|
+
|
|
233
|
+
# Poll until the job is no longer registered (``print`` exits
|
|
234
|
+
# non-zero). ~5s budget — teardown is normally well under 1s.
|
|
235
|
+
for _ in range(50):
|
|
236
|
+
probe = subprocess.run(
|
|
237
|
+
["launchctl", "print", service_target],
|
|
238
|
+
capture_output=True,
|
|
239
|
+
check=False,
|
|
240
|
+
)
|
|
241
|
+
if probe.returncode != 0:
|
|
242
|
+
break
|
|
243
|
+
time.sleep(0.1)
|
|
244
|
+
|
|
245
|
+
last_err = ""
|
|
246
|
+
for _ in range(5):
|
|
247
|
+
result = subprocess.run(
|
|
248
|
+
["launchctl", "bootstrap", domain, str(plist_path)],
|
|
249
|
+
capture_output=True,
|
|
250
|
+
text=True,
|
|
251
|
+
check=False,
|
|
252
|
+
)
|
|
253
|
+
if result.returncode == 0:
|
|
254
|
+
break
|
|
255
|
+
last_err = (result.stderr or result.stdout or "").strip()
|
|
256
|
+
time.sleep(0.3)
|
|
257
|
+
else:
|
|
258
|
+
raise RuntimeError(
|
|
259
|
+
f"launchctl bootstrap failed after retries: {last_err or 'unknown'}"
|
|
260
|
+
)
|
|
261
|
+
|
|
209
262
|
# Kickstart -k forces an immediate (re)start.
|
|
210
263
|
subprocess.run(
|
|
211
|
-
["launchctl", "kickstart", "-k",
|
|
264
|
+
["launchctl", "kickstart", "-k", service_target],
|
|
212
265
|
check=False,
|
|
213
266
|
)
|
|
214
|
-
return plist_path
|
|
215
267
|
|
|
216
268
|
|
|
217
269
|
def uninstall_macos(profile: str | None = None) -> bool:
|
|
@@ -324,7 +376,18 @@ def install_linux(
|
|
|
324
376
|
)
|
|
325
377
|
subprocess.run(["systemctl", "--user", "daemon-reload"], check=False)
|
|
326
378
|
subprocess.run(
|
|
327
|
-
["systemctl", "--user", "enable",
|
|
379
|
+
["systemctl", "--user", "enable", unit_name],
|
|
380
|
+
check=False,
|
|
381
|
+
)
|
|
382
|
+
# Reinstall-safe (2026-05-19): ``restart`` (not ``enable --now`` /
|
|
383
|
+
# ``start``) so a re-run of ``install-service`` genuinely applies
|
|
384
|
+
# the freshly written unit file — ``start`` is a no-op on an
|
|
385
|
+
# already-running service, leaving the daemon on the stale config.
|
|
386
|
+
# ``daemon-reload`` above re-read the unit; ``restart`` makes the
|
|
387
|
+
# running process pick it up. ``restart`` also starts a stopped
|
|
388
|
+
# service, so this covers first-install too.
|
|
389
|
+
subprocess.run(
|
|
390
|
+
["systemctl", "--user", "restart", unit_name],
|
|
328
391
|
check=False,
|
|
329
392
|
)
|
|
330
393
|
return unit_path
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|