swarph-cli 0.10.2__tar.gz → 0.12.0__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.
Files changed (110) hide show
  1. {swarph_cli-0.10.2/src/swarph_cli.egg-info → swarph_cli-0.12.0}/PKG-INFO +65 -77
  2. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/README.md +61 -73
  3. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/pyproject.toml +4 -4
  4. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/__init__.py +1 -1
  5. swarph_cli-0.12.0/src/swarph_cli/capture/__init__.py +6 -0
  6. swarph_cli-0.12.0/src/swarph_cli/capture/harden.py +140 -0
  7. swarph_cli-0.12.0/src/swarph_cli/capture/lineage.py +95 -0
  8. swarph_cli-0.12.0/src/swarph_cli/capture/liveness.py +69 -0
  9. swarph_cli-0.12.0/src/swarph_cli/capture/manifest.py +125 -0
  10. swarph_cli-0.12.0/src/swarph_cli/capture/paths.py +79 -0
  11. swarph_cli-0.12.0/src/swarph_cli/capture/verify.py +132 -0
  12. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/cell.py +42 -0
  13. swarph_cli-0.12.0/src/swarph_cli/commands/cell.py +83 -0
  14. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/onboard.py +9 -2
  15. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/spawn.py +270 -8
  16. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/main.py +1 -0
  17. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/systemd/swarph-watchdog.service +1 -1
  18. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/systemd/swarph-watchdog.timer +1 -1
  19. {swarph_cli-0.10.2 → swarph_cli-0.12.0/src/swarph_cli.egg-info}/PKG-INFO +65 -77
  20. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli.egg-info/SOURCES.txt +21 -0
  21. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_add.py +3 -1
  22. swarph_cli-0.12.0/tests/test_capture_lineage.py +81 -0
  23. swarph_cli-0.12.0/tests/test_capture_liveness.py +33 -0
  24. swarph_cli-0.12.0/tests/test_capture_manifest.py +83 -0
  25. swarph_cli-0.12.0/tests/test_capture_paths.py +15 -0
  26. swarph_cli-0.12.0/tests/test_capture_security.py +138 -0
  27. swarph_cli-0.12.0/tests/test_cell_command_dispatch.py +56 -0
  28. swarph_cli-0.12.0/tests/test_cell_harden.py +71 -0
  29. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_cell_loader.py +18 -0
  30. swarph_cli-0.12.0/tests/test_cell_verify.py +121 -0
  31. swarph_cli-0.12.0/tests/test_claude_tmux_template.py +54 -0
  32. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hooks_add.py +5 -2
  33. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hooks_bundle.py +9 -0
  34. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_install_hook.py +8 -1
  35. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_mcp_server.py +6 -0
  36. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_mesh_command.py +3 -1
  37. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_onboard_command.py +9 -5
  38. swarph_cli-0.12.0/tests/test_session_path_role_gate.py +82 -0
  39. swarph_cli-0.12.0/tests/test_spawn_live_pin.py +44 -0
  40. swarph_cli-0.12.0/tests/test_spawn_mitosis_lineage.py +93 -0
  41. swarph_cli-0.12.0/tests/test_spawn_tmux_session.py +261 -0
  42. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_spawn_windows_relaunch.py +38 -3
  43. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog.py +13 -0
  44. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog_model_rung.py +2 -0
  45. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/LICENSE +0 -0
  46. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/setup.cfg +0 -0
  47. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/caller.py +0 -0
  48. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/__init__.py +0 -0
  49. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/add.py +0 -0
  50. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/chat.py +0 -0
  51. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/compress.py +0 -0
  52. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/daemon.py +0 -0
  53. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/hook_output.py +0 -0
  54. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/hooks.py +0 -0
  55. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/import_session.py +0 -0
  56. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/init.py +0 -0
  57. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/install_hook.py +0 -0
  58. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/mcp_server.py +0 -0
  59. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/memory_sync.py +0 -0
  60. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/mesh.py +0 -0
  61. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/protocol_handler.py +0 -0
  62. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/ratify.py +0 -0
  63. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/security.py +0 -0
  64. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/commands/watchdog.py +0 -0
  65. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/compress/__init__.py +0 -0
  66. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/compress/levers.py +0 -0
  67. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/compress/marker.py +0 -0
  68. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/compress/verify.py +0 -0
  69. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/parsers/__init__.py +0 -0
  70. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/parsers/claude.py +0 -0
  71. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
  72. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
  73. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli.egg-info/entry_points.txt +0 -0
  74. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli.egg-info/requires.txt +0 -0
  75. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/src/swarph_cli.egg-info/top_level.txt +0 -0
  76. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_add_security_gate.py +0 -0
  77. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_hash.py +0 -0
  78. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_lib.py +0 -0
  79. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_mcp.py +0 -0
  80. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_skill.py +0 -0
  81. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_tool.py +0 -0
  82. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_artifact_uri.py +0 -0
  83. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_chat_command.py +0 -0
  84. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_claude_parser.py +0 -0
  85. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_compress_command.py +0 -0
  86. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_compress_levers.py +0 -0
  87. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_compress_marker.py +0 -0
  88. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_compress_verify.py +0 -0
  89. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_daemon_command.py +0 -0
  90. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_feature_to_uri.py +0 -0
  91. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hook_output.py +0 -0
  92. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hooks_init.py +0 -0
  93. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hooks_lifecycle.py +0 -0
  94. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_hooks_merge.py +0 -0
  95. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_import_command.py +0 -0
  96. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_init_command.py +0 -0
  97. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_main.py +0 -0
  98. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_memory_sync.py +0 -0
  99. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_mesh_sidecar.py +0 -0
  100. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_protocol_handler.py +0 -0
  101. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_ratify_command.py +0 -0
  102. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_security.py +0 -0
  103. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_smoke_chat.py +0 -0
  104. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_smoke_one_shot.py +0 -0
  105. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_smoke_phase_5_5.py +0 -0
  106. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_spawn_command.py +0 -0
  107. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog_dm_wake.py +0 -0
  108. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
  109. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog_dm_wake_wiring.py +0 -0
  110. {swarph_cli-0.10.2 → swarph_cli-0.12.0}/tests/test_watchdog_stale_peers.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swarph-cli
3
- Version: 0.10.2
3
+ Version: 0.12.0
4
4
  Summary: The `swarph` binary — multi-LLM CLI + mesh-gateway integration: multi-provider `swarph spawn` (claude/codex/antigravity per cell.provider via a ProviderMembrane + subprocess billing-scrub), interactive `swarph init`, `swarph mesh` (send/inbox/register) + inbox sidecar, `assisted_memory` (git-backed durable memory), session import, watchdog. v0.9.5: foolproof Windows auto-relaunch (genuine-WT detection via process ancestry, not WT_SESSION).
5
5
  Author: Pierre Samson, Claude Opus
6
6
  License: MIT
7
- Project-URL: Homepage, https://github.com/darw007d/swarph-cli
8
- Project-URL: Source, https://github.com/darw007d/swarph-cli
9
- Project-URL: Substrate, https://github.com/darw007d/swarph-mesh
7
+ Project-URL: Homepage, https://github.com/BrainSurfing-tech/swarph-cli
8
+ Project-URL: Source, https://github.com/BrainSurfing-tech/swarph-cli
9
+ Project-URL: Substrate, https://github.com/BrainSurfing-tech/swarph-mesh
10
10
  Project-URL: Spec, https://github.com/darw007d/hedge-fund-mcp/blob/main/research/swarph_cli/PLAN.md
11
11
  Keywords: swarph,llm,cli,mesh,gemini,claude,deepseek
12
12
  Classifier: Development Status :: 3 - Alpha
@@ -35,66 +35,72 @@ Dynamic: license-file
35
35
 
36
36
  # swarph-cli
37
37
 
38
- The `swarph` binary — multi-LLM CLI with mesh-gateway integration. Thin client over the [`swarph-mesh`](https://github.com/darw007d/swarph-mesh) substrate.
38
+ **One CLI for every LLM.** Drive Claude, GPT, Gemini, DeepSeek, and Grok from a single binary — then connect them into a coordinating *mesh* where agents from different vendors talk to each other through a shared protocol, each staying itself.
39
39
 
40
40
  ```bash
41
41
  pip install swarph-cli
42
42
  swarph --version
43
43
  ```
44
44
 
45
+ **What it is:** a multi-provider LLM command line. Run one-shot prompts or an interactive REPL against any supported provider; spawn long-lived agent *cells* that persist across restarts and coordinate over a mesh; install hooks, MCP servers, and skills by content-addressed URI. An open, inspectable substrate — not a closed orchestration platform.
46
+
47
+ **Who it's for:** builders running more than one LLM who want them to *cooperate* instead of sitting in separate tabs — multi-agent systems across vendors, agnostic by design. A thin client over the [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) substrate library.
48
+
45
49
  This is one of three repos in the v0.3.x architecture:
46
50
 
47
51
  | Repo | Role |
48
52
  |---|---|
49
- | [`swarph-mesh`](https://github.com/darw007d/swarph-mesh) | Substrate Python package — Protocol + adapters + SwarphCall + MeshClient. Pure library, no CLI |
50
- | [`swarph-cli`](https://github.com/darw007d/swarph-cli) | This repo — the `swarph` binary |
51
- | [`swarph-meshlm`](https://github.com/darw007d/swarph-meshlm) | Simon Willison `llm` plugin |
52
-
53
- ## Status
53
+ | [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) | Substrate Python package — Protocol + adapters + SwarphCall + MeshClient. Pure library, no CLI |
54
+ | [`swarph-cli`](https://github.com/BrainSurfing-tech/swarph-cli) | This repo — the `swarph` binary |
55
+ | [`swarph-meshlm`](https://github.com/BrainSurfing-tech/swarph-meshlm) | Simon Willison `llm` plugin |
54
56
 
55
- **v0.6.0 — Phase 7 spawn ships.** Seven verbs total:
57
+ ## Commands
56
58
 
57
- 1. `swarph "prompt"` — Phase 2 one-shot mode (any of five providers)
58
- 2. `swarph chat` — Phase 5 interactive REPL with multi-turn history + slash commands
59
- 3. `swarph spawn <role>`**NEW** Phase 7 long-lived `claude` session as a named mesh cell (`--name`/`--session-id`/`--append-system-prompt` pinning per substrate-doc R7 §11.1.7 4-layer R2 stack)
60
- 4. `swarph import <path>` Phase 2.5 session import (Claude JSONL swarph-native)
61
- 5. `swarph onboard <peer-name>` Phase 5.5 mechanics-phase onboarding (PLAN.md §15.4)
62
- 6. `swarph ratify <peer-name>` Phase 5.5 witness ratification (PLAN.md §15.4a)
63
- 7. `swarph daemon` Phase 5.6 foreground inbox drain (PLAN.md §16)
59
+ ```
60
+ swarph "prompt" one-shot against any provider (claude/openai/gemini/deepseek/grok)
61
+ swarph chat interactive REPLmulti-turn, slash commands, live provider switch
62
+ swarph spawn <role> launch a long-lived agent session as a named mesh cell
63
+ swarph daemon foreground inbox-drain loop (the mesh doorbell)
64
+ swarph watchdog detect + recover stranded agent sessions (cron- or systemd-driven)
65
+ swarph add <uri> install a hook / MCP server / skill by content-addressed URI
66
+ swarph hooks install Claude Code hooks as reusable artifacts
67
+ swarph onboard / ratify bring a new peer into the mesh (mechanics + witness ratification)
68
+ swarph import <path> port a session from another CLI into swarph-native format
69
+ ```
64
70
 
65
- Subsequent phases extend the CLI surface (`--ask <peer>`, REPL drain coroutine + `/inbox` + `/reply` slash commands in 5.6b; non-Claude `spawn` providers + S-G `mesh-gateway://` URL form in v0.7).
71
+ Each verb is documented below.
66
72
 
67
73
  ### `swarph spawn` (Phase 7 — v0.6.0)
68
74
 
69
- Operator-tooling layer of substrate-doc R7 §11.1.7 4-layer R2 mechanism stack. Wraps `claude` with the three R5/R7 disambiguation flags:
75
+ Wraps `claude` with three flags that make a session a stable, resumable named cell:
70
76
 
71
77
  * `--name <role>` — display name for `/resume` picker
72
- * `--session-id <uuid>` — pinned UUID, persisted to `$XDG_STATE_HOME/swarph/sessions/<role>.session-id` so re-spawns reuse the same session (the R5 fix at the operator-tooling layer)
73
- * `--append-system-prompt <text>` — starter prompt injected without manual paste (the R2 fix at the operator-tooling layer)
78
+ * `--session-id <uuid>` — pinned UUID, persisted to `$XDG_STATE_HOME/swarph/sessions/<role>.session-id` so re-spawns reuse the same session
79
+ * `--append-system-prompt <text>` — starter prompt injected without manual paste
74
80
 
75
81
  ```bash
76
82
  # 1. Author a cell.yaml (one-time per role)
77
- $ cat ~/.config/swarph/cells/lab.yaml
83
+ $ cat ~/.config/swarph/cells/researcher.yaml
78
84
  schema_version: v1
79
- name: lab-ovh
80
- role: lab
81
- cwd: /home/ubuntu
85
+ name: researcher
86
+ role: researcher
87
+ cwd: ~/work
82
88
  starter_prompt_path: ~/.claude/session_start_reminder.txt
83
89
  provider: claude
84
90
 
85
91
  # 2. Summon the cell (long-lived claude session, exec-replaced)
86
- $ swarph spawn lab
92
+ $ swarph spawn researcher
87
93
  ╭───╮
88
94
  │ ◉ │
89
95
  ╭──┴───┴──╮
90
- │ swarph │ v0.6.0
96
+ │ swarph │
91
97
  ╰──┬───┬──╯ spawn │ chat │ daemon
92
98
  │ ◉ │
93
99
  ╰───╯
94
- [claude session takes over the terminal — same flags as `claude --name lab --session-id <uuid> --append-system-prompt <starter>`]
100
+ [claude session takes over the terminal — same flags as `claude --name researcher --session-id <uuid> --append-system-prompt <starter>`]
95
101
 
96
102
  # 3. Resume the same cell after exit — same UUID, same session
97
- $ swarph spawn lab # picker shows ONE entry: "lab" (R5 disambiguation)
103
+ $ swarph spawn researcher # picker shows ONE entry: "researcher" (stable disambiguation)
98
104
  ```
99
105
 
100
106
  Resolution order for `swarph spawn <role-or-path>`:
@@ -127,16 +133,16 @@ ps aux | grep '[s]warph daemon' # zero output = monitoring is down
127
133
  ```
128
134
 
129
135
  ```bash
130
- $ swarph daemon --state-dir ~/swarph_state/lab-ovh --self lab-ovh
131
- [swarph-daemon] starting: self=lab-ovh gateway=http://localhost:8788 poll=30s ...
132
- [2026-05-08T21:00:30Z] id=728 from=droplet kind=answer → 'Drop review on Phase 5.5 PRs A+B...'
133
- [2026-05-08T21:01:10Z] id=729 from=droplet kind=fyi → 'Both Phase 5.5 PRs merged...'
136
+ $ swarph daemon --state-dir ~/swarph_state/researcher --self researcher
137
+ [swarph-daemon] starting: self=researcher gateway=http://localhost:8788 poll=30s ...
138
+ [2026-05-08T21:00:30Z] id=728 from=alice kind=answer → 'review on the two PRs looks good...'
139
+ [2026-05-08T21:01:10Z] id=729 from=alice kind=fyi → 'both PRs merged...'
134
140
  ^C
135
141
  [swarph-daemon] signal 2 received — draining + flushing cursor
136
142
  [swarph-daemon] shutdown: iterations=12 dms_seen=2 cursor.last_msg_id=729
137
143
  ```
138
144
 
139
- Loud-on-down (PLAN §16.5): never silently exits. Cursor writes are atomic (write-and-rename — corrupted mid-flush leaves the previous cursor intact). Backoff: 60s after 5 consecutive empty polls; 300s after 5 min of consecutive 5xx. SIGINT/SIGTERM trigger clean drain + flush.
145
+ Loud-on-down: never silently exits. Cursor writes are atomic (write-and-rename — corrupted mid-flush leaves the previous cursor intact). Backoff: 60s after 5 consecutive empty polls; 300s after 5 min of consecutive 5xx. SIGINT/SIGTERM trigger clean drain + flush.
140
146
 
141
147
  `--auto-act` flag is documented for v0.5.1+ when handler registration via `@swarph.on_dm(...)` lands; v0.5.0 ships surface-only mode (DMs printed + JSONL-logged to `inbox.log`, no automatic replies).
142
148
 
@@ -149,14 +155,14 @@ Detects stranded Claude sessions (API throttle / harness death) via cursor-mtime
149
155
  */5 * * * * swarph watchdog --check --cell lab >> ~/.local/log/swarph-watchdog.log 2>&1
150
156
  ```
151
157
 
152
- **Systemd timer install (v0.7.3+ — closes ev_6954f748 substrate-component-installation-gap):**
158
+ **Systemd timer install (v0.7.3+):**
153
159
 
154
160
  ```bash
155
161
  # Preview without writing (any user):
156
- swarph watchdog --install-service --cell droplet --dry-run
162
+ swarph watchdog --install-service --cell researcher --dry-run
157
163
 
158
164
  # Install + enable (requires root for /etc/systemd/system writes):
159
- sudo swarph watchdog --install-service --cell droplet
165
+ sudo swarph watchdog --install-service --cell researcher
160
166
  ```
161
167
 
162
168
  This writes three files:
@@ -178,19 +184,19 @@ journalctl -u swarph-watchdog.service -f # live log
178
184
  tail -f /var/log/swarph-watchdog.log # append-log alternative
179
185
  ```
180
186
 
181
- Why this matters: pre-v0.7.3, swarph-cli shipped the watchdog code but no install path. Lab ran it via cron (manual setup); droplet never installed it at all. A real production silence-window (drop's ~24min mute 2026-05-14 08:38→09:02 UTC after an Anthropic API error) made the install-gap visible. v0.7.3 closes it for any peer with one command.
187
+ Why this matters: a long-running agent session can go silent after an API throttle or a harness death, and you won't notice until you go looking. The watchdog turns that into a self-healing loop and the systemd install path means any host gets it with one command instead of hand-rolled cron.
182
188
 
183
189
  **Cross-host throttle-recovery wake (`--dm-wake`, "mesh-monitor mode"):**
184
190
 
185
191
  A1 (local tmux send-keys) and A2 (respawn) can only recover a cell on the watchdog's *own* host. `--dm-wake` adds the cross-host complement: the watchdog also scans the gateway `/peers` list, finds peers whose `last_health` is stale (throttle-stranded sessions on *other* hosts), and sends each a wake DM (`kind="fyi"`) via the gateway `/messages`. The wake chain is **watchdog → wake DM → target peer's sidecar/inbox-watcher → `tmux send-keys` wakes that session**. Reuses the same `--gateway` URL + `MESH_GATEWAY_TOKEN` and the same `--threshold` staleness window as the local check.
186
192
 
187
193
  ```bash
188
- swarph watchdog --check --peer lab-ovh --gateway http://localhost:8788 --dm-wake --dm-wake-cooldown-sec 1800
194
+ swarph watchdog --check --peer researcher --gateway http://localhost:8788 --dm-wake --dm-wake-cooldown-sec 1800
189
195
  ```
190
196
 
191
197
  - `--dm-wake-cooldown-sec SEC` (default `1800` / 30 min) — no-spam gate: each stale peer is DM-woken at most once per window, so a peer that stays stale across many ticks is woken once, not every tick. Per-peer cooldown state lives at `$XDG_STATE_HOME/swarph/dm_wake_state.json` (falls back to `~/.local/state/swarph/dm_wake_state.json`).
192
198
 
193
- **Scope honesty (v1):** the wake DM is *wake + re-drain* — the woken cell drains its inbox and resumes work; it does **not** resume the exact throttled in-flight task (per-cell task-checkpointing is future v2 scope).
199
+ **Scope honesty (v1):** the wake DM is *wake + re-drain* — the woken cell drains its inbox and resumes work; it does **not** resume the exact throttled in-flight task (per-cell task-checkpointing is future scope).
194
200
 
195
201
  **Exit codes:**
196
202
 
@@ -203,7 +209,7 @@ swarph watchdog --check --peer lab-ovh --gateway http://localhost:8788 --dm-wake
203
209
  | `4` | configuration error (invalid args, no cell.yaml resolved); install needs sudo |
204
210
  | `5` | install error (file write failed / systemctl failed) |
205
211
 
206
- **Deploy (COMMANDER-GATED — lab does not self-publish/self-deploy):** now that `--dm-wake` ships, the lab + droplet watchdog crons can drop their placeholder note ("REMOVE when lab ships `swarph watchdog --dm-wake`"). The deploy step — described here, not an instruction to run — is: (a) publish the new swarph-cli, (b) add `--dm-wake` (and optionally `--dm-wake-cooldown-sec`) to the watchdog cron line on the always-on mesh-monitor host (lab), (c) drop the placeholder note from that cron entry.
212
+ **Deploy:** run `--dm-wake` on whichever always-on host you want to act as the mesh monitor it watches every peer's health, not just its own, so one monitor covers the mesh.
207
213
 
208
214
  ### `swarph hooks`
209
215
 
@@ -217,7 +223,7 @@ swarph hooks list # builtins + install status (installed|availab
217
223
  swarph hooks remove cell-resilience
218
224
  ```
219
225
 
220
- **Trust model.** Three tiers: `builtin` (trusted, bundled with swarph-cli — installs without a prompt), `local` (a bundle dir you point at — shown then confirmed before any write), and `published`/`@cell/name` (**fails closed in v1** — never installs another cell's unreviewed code). Signed-publisher identity plus a publish-time security gate is the v2 model (see the scope doc `research/architecture/swarph_hooks_installer_scope.md` §3.1 in the hedge-fund-mcp repo).
226
+ **Trust model.** Three tiers: `builtin` (trusted, bundled with swarph-cli — installs without a prompt), `local` (a bundle dir you point at — shown then confirmed before any write), and `published`/`@cell/name` (**fails closed in v1** — never installs another cell's unreviewed code). Signed-publisher identity plus a publish-time security gate is the v2 model.
221
227
 
222
228
  **Bundled `cell-resilience`.** Binds `StopFailure`/`rate_limit` + `Stop`/`(all)` to a script that writes `$XDG_STATE_HOME/swarph/idle_since.json` (`{"session","reason","hook_event","ts"}`, `reason=throttle|normal`) — the push-side throttle detector the watchdog's `--dm-wake` can read instead of polling. Observational only: it never blocks the session and always exits 0 (jq if present, printf/sed fallback otherwise).
223
229
 
@@ -237,36 +243,36 @@ swarph add swarph://skill/swarph-builtin/swarph-intro # install a builtin sk
237
243
 
238
244
  (`tool` is not yet implemented — it bridges to swarph-mesh's adapter registry as a follow-on.)
239
245
 
240
- **Trust model (v1).** Builtin publishers (`swarph-builtin`) install; **any other publisher fails closed** — a published/untrusted URI never installs another cell's unreviewed code. Signed-publisher identity plus a per-class publish-time security gate is the v2 model (scope `research/architecture/swarph_artifact_uri_scope.md` §4 and the hooks scope §3.1 in the hedge-fund-mcp repo). When a URI carries `#sha256`, the resolved artifact is hash-verified and **refused on mismatch** — nothing is written.
246
+ **Trust model (v1).** Builtin publishers (`swarph-builtin`) install; **any other publisher fails closed** — a published/untrusted URI never installs another cell's unreviewed code. Signed-publisher identity plus a per-class publish-time security gate is the v2 model. When a URI carries `#sha256`, the resolved artifact is hash-verified and **refused on mismatch** — nothing is written.
241
247
 
242
- **Resolving from metaedge.surf.** A search result on metaedge hands back a `swarph://` URI; you `swarph add` it. The link resolves *to the swarph*, not to a particular server: the CLI fetches the artifact from the publishing cell/registry and hash-verifies it against `#sha256`, so the same artifact can be served from any cell. Today this is copy-paste; a `swarph://` OS protocol-handler for click-to-install — the way `magnet:` opens a torrent client — is a future UX layer.
248
+ **Content-addressed, not host-addressed.** A `swarph://` URI resolves *to the artifact*, not to a particular server: the CLI fetches it from any cell or registry that publishes it and hash-verifies against `#sha256`, so the same artifact can be served from anywhere — the BitTorrent-magnet property. Today the URI is copy-paste; a `swarph://` OS protocol-handler for click-to-install — the way `magnet:` opens a torrent client — is a future UX layer.
243
249
 
244
250
  **Activation.** Like hooks, freshly-installed hooks and skills are not hot-loaded into the running session — reopen `/hooks` (or restart the session) once to pick them up.
245
251
 
246
252
  ### `swarph onboard` + `swarph ratify` (Phase 5.5)
247
253
 
248
- Per PLAN.md §15, onboarding splits into a **mechanics phase** (`swarph onboard`) that automates the boring parts (registry POST, scaffolding, token resolution) and a **manual contract phase** (the new peer composes the handshake DM in their own words). A witness peer judges the handshake and runs `swarph ratify <peer>` to flip `ratified=true`, gating `task_claim` server-side.
254
+ Onboarding splits into a **mechanics phase** (`swarph onboard`) that automates the boring parts (registry POST, scaffolding, token resolution) and a **manual contract phase** (the new peer composes the handshake DM in their own words). A witness peer judges the handshake and runs `swarph ratify <peer>` to flip `ratified=true`, gating `task_claim` server-side.
249
255
 
250
256
  ```bash
251
257
  # New peer self-onboards
252
- $ swarph onboard razorpeter
253
- [1/6] validate_node_name('razorpeter') ok
258
+ $ swarph onboard newpeer
259
+ [1/6] validate_node_name('newpeer') ok
254
260
  [2/6] prepare peer-registry row ok
255
261
  [3/6] resolve MESH_GATEWAY_TOKEN ok
256
262
  [4/6] POST .../peers/register ok (registered_unratified=true)
257
263
  [5/6] verify_subscription_setup() ok
258
- [6/6] scaffold ~/swarph_state/razorpeter/ ok
264
+ [6/6] scaffold ~/swarph_state/newpeer/ ok
259
265
 
260
- [manual] handshake template at /tmp/razorpeter-handshake.md
266
+ [manual] handshake template at /tmp/newpeer-handshake.md
261
267
  Edit each section in your own words, then send to your witness peer.
262
268
 
263
269
  # After peer composes + sends handshake, witness ratifies
264
- $ SWARPH_WITNESS=lab-ovh swarph ratify razorpeter \
270
+ $ SWARPH_WITNESS=alice swarph ratify newpeer \
265
271
  --reason "handshake covers all four invariants in own words"
266
- [1/6] validate_node_name('razorpeter') ok
267
- [2/6] verify witness 'lab-ovh' is ratified ok
268
- [3/6] verify 'razorpeter' is registered_unratified ok
269
- [4/6] PATCH .../peers/razorpeter ok
272
+ [1/6] validate_node_name('newpeer') ok
273
+ [2/6] verify witness 'alice' is ratified ok
274
+ [3/6] verify 'newpeer' is registered_unratified ok
275
+ [4/6] PATCH .../peers/newpeer ok
270
276
  [5/6] verify peer_ratifications audit row ok (id=N reason='...')
271
277
  [6/6] invalidate local TTL cache ok
272
278
  ```
@@ -314,7 +320,7 @@ Hi! How can I help...
314
320
 
315
321
  ### `swarph import`
316
322
 
317
- Per PLAN.md §17, session import is the **knowledge half of onboarding** — gives a memory-carrying peer (or human migrating CLIs) the substantive context they're bringing into the swarph, paired with §15's contract half (handshake DM acknowledging the four invariants).
323
+ Session import is the **knowledge half of onboarding** — gives a memory-carrying peer (or a human migrating between CLIs) the substantive context they're bringing into the swarph, paired with the contract half (the handshake DM acknowledging the four invariants).
318
324
 
319
325
  ```bash
320
326
  # Inspect what would be imported (lossy → honest framing)
@@ -340,7 +346,7 @@ To proceed:
340
346
 
341
347
  **What's dropped:** attachments (would need re-upload), provider-side KV cache, conversation IDs, `cache_control` annotations.
342
348
 
343
- Honest framing per PLAN.md §17.3: **teleport is "import + continue", not "freeze and resume"** — the first turn after import on a new provider pays cold-cache cost. Phase 5+ adds `--continue` for live REPL integration.
349
+ Honest framing: **teleport is "import + continue", not "freeze and resume"** — the first turn after import on a new provider pays cold-cache cost.
344
350
 
345
351
  ```bash
346
352
  $ swarph "say pong" --provider gemini
@@ -415,32 +421,14 @@ Design spec: `docs/superpowers/specs/2026-06-11-swarph-context-compressor-design
415
421
  ```
416
422
  - Pretty-printed parsed dict on stdout when parse succeeds; `error_class=malformed_json` shows up in the stderr attribution footer when it doesn't.
417
423
 
418
- ## Spec
419
-
420
- → [hedge-fund-mcp / research/swarph_cli/PLAN.md](https://github.com/darw007d/hedge-fund-mcp/blob/main/research/swarph_cli/PLAN.md)
421
-
422
- ## Phase rollout
423
-
424
- | Phase | What lands |
425
- |---|---|
426
- | **0** | Scaffold — entry-point + status banner |
427
- | **2** (v0.1.0) | One-shot mode: `swarph "hello" --provider gemini` |
428
- | **2.5** (v0.2.0) | `swarph import` — Claude JSONL → swarph-native session format |
429
- | **5** (v0.3.0) | `swarph chat` interactive REPL — multi-turn against any of five adapters + slash commands |
430
- | **5.5** (v0.4.0) | `swarph onboard` + `swarph ratify` — six mechanics steps + handshake template + witness flip (PLAN.md §15) |
431
- | **5.6** (v0.5.0 — this release) | **`swarph daemon`** — foreground inbox drain loop with atomic cursor writes; retires the orphaned-tail-F class (PLAN.md §16) |
432
- | **5.6b** | REPL drain coroutine + `/inbox`/`/reply` slash commands + `@swarph.on_dm()` handler registration (mesh + cli) |
433
- | **3** | `--ask <peer>` mesh-aware one-shot via MeshClient |
434
- | **6** | (already done) PyPI publish |
435
-
436
424
  ## Why split CLI from substrate
437
425
 
438
- `swarph-mesh` (the library) is imported by `omega-boss`, Council judges, `lab-orchestrator`, and any future swarph peer that wants to write programs against the Protocol. Those callers don't need the CLI surface or the console-script entry point. Keeping the CLI in a separate repo means library users `pip install swarph-mesh` without pulling argparse + REPL plumbing they'll never run.
426
+ The [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) library is imported by any program that wants to drive the mesh against the Protocol directly — orchestrators, judges, automation. Those callers don't need the CLI surface or the console-script entry point. Keeping the CLI in a separate repo means library users `pip install swarph-mesh` without pulling argparse + REPL plumbing they'll never run, while `pip install swarph-cli` gives you the standalone `swarph` binary.
439
427
 
440
428
  ## Install (dev)
441
429
 
442
430
  ```bash
443
- git clone https://github.com/darw007d/swarph-cli
431
+ git clone https://github.com/BrainSurfing-tech/swarph-cli
444
432
  cd swarph-cli
445
433
  python -m venv venv && source venv/bin/activate
446
434
  pip install -e ".[dev]"
@@ -1,65 +1,71 @@
1
1
  # swarph-cli
2
2
 
3
- The `swarph` binary — multi-LLM CLI with mesh-gateway integration. Thin client over the [`swarph-mesh`](https://github.com/darw007d/swarph-mesh) substrate.
3
+ **One CLI for every LLM.** Drive Claude, GPT, Gemini, DeepSeek, and Grok from a single binary — then connect them into a coordinating *mesh* where agents from different vendors talk to each other through a shared protocol, each staying itself.
4
4
 
5
5
  ```bash
6
6
  pip install swarph-cli
7
7
  swarph --version
8
8
  ```
9
9
 
10
+ **What it is:** a multi-provider LLM command line. Run one-shot prompts or an interactive REPL against any supported provider; spawn long-lived agent *cells* that persist across restarts and coordinate over a mesh; install hooks, MCP servers, and skills by content-addressed URI. An open, inspectable substrate — not a closed orchestration platform.
11
+
12
+ **Who it's for:** builders running more than one LLM who want them to *cooperate* instead of sitting in separate tabs — multi-agent systems across vendors, agnostic by design. A thin client over the [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) substrate library.
13
+
10
14
  This is one of three repos in the v0.3.x architecture:
11
15
 
12
16
  | Repo | Role |
13
17
  |---|---|
14
- | [`swarph-mesh`](https://github.com/darw007d/swarph-mesh) | Substrate Python package — Protocol + adapters + SwarphCall + MeshClient. Pure library, no CLI |
15
- | [`swarph-cli`](https://github.com/darw007d/swarph-cli) | This repo — the `swarph` binary |
16
- | [`swarph-meshlm`](https://github.com/darw007d/swarph-meshlm) | Simon Willison `llm` plugin |
17
-
18
- ## Status
18
+ | [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) | Substrate Python package — Protocol + adapters + SwarphCall + MeshClient. Pure library, no CLI |
19
+ | [`swarph-cli`](https://github.com/BrainSurfing-tech/swarph-cli) | This repo — the `swarph` binary |
20
+ | [`swarph-meshlm`](https://github.com/BrainSurfing-tech/swarph-meshlm) | Simon Willison `llm` plugin |
19
21
 
20
- **v0.6.0 — Phase 7 spawn ships.** Seven verbs total:
22
+ ## Commands
21
23
 
22
- 1. `swarph "prompt"` — Phase 2 one-shot mode (any of five providers)
23
- 2. `swarph chat` — Phase 5 interactive REPL with multi-turn history + slash commands
24
- 3. `swarph spawn <role>`**NEW** Phase 7 long-lived `claude` session as a named mesh cell (`--name`/`--session-id`/`--append-system-prompt` pinning per substrate-doc R7 §11.1.7 4-layer R2 stack)
25
- 4. `swarph import <path>` Phase 2.5 session import (Claude JSONL swarph-native)
26
- 5. `swarph onboard <peer-name>` Phase 5.5 mechanics-phase onboarding (PLAN.md §15.4)
27
- 6. `swarph ratify <peer-name>` Phase 5.5 witness ratification (PLAN.md §15.4a)
28
- 7. `swarph daemon` Phase 5.6 foreground inbox drain (PLAN.md §16)
24
+ ```
25
+ swarph "prompt" one-shot against any provider (claude/openai/gemini/deepseek/grok)
26
+ swarph chat interactive REPLmulti-turn, slash commands, live provider switch
27
+ swarph spawn <role> launch a long-lived agent session as a named mesh cell
28
+ swarph daemon foreground inbox-drain loop (the mesh doorbell)
29
+ swarph watchdog detect + recover stranded agent sessions (cron- or systemd-driven)
30
+ swarph add <uri> install a hook / MCP server / skill by content-addressed URI
31
+ swarph hooks install Claude Code hooks as reusable artifacts
32
+ swarph onboard / ratify bring a new peer into the mesh (mechanics + witness ratification)
33
+ swarph import <path> port a session from another CLI into swarph-native format
34
+ ```
29
35
 
30
- Subsequent phases extend the CLI surface (`--ask <peer>`, REPL drain coroutine + `/inbox` + `/reply` slash commands in 5.6b; non-Claude `spawn` providers + S-G `mesh-gateway://` URL form in v0.7).
36
+ Each verb is documented below.
31
37
 
32
38
  ### `swarph spawn` (Phase 7 — v0.6.0)
33
39
 
34
- Operator-tooling layer of substrate-doc R7 §11.1.7 4-layer R2 mechanism stack. Wraps `claude` with the three R5/R7 disambiguation flags:
40
+ Wraps `claude` with three flags that make a session a stable, resumable named cell:
35
41
 
36
42
  * `--name <role>` — display name for `/resume` picker
37
- * `--session-id <uuid>` — pinned UUID, persisted to `$XDG_STATE_HOME/swarph/sessions/<role>.session-id` so re-spawns reuse the same session (the R5 fix at the operator-tooling layer)
38
- * `--append-system-prompt <text>` — starter prompt injected without manual paste (the R2 fix at the operator-tooling layer)
43
+ * `--session-id <uuid>` — pinned UUID, persisted to `$XDG_STATE_HOME/swarph/sessions/<role>.session-id` so re-spawns reuse the same session
44
+ * `--append-system-prompt <text>` — starter prompt injected without manual paste
39
45
 
40
46
  ```bash
41
47
  # 1. Author a cell.yaml (one-time per role)
42
- $ cat ~/.config/swarph/cells/lab.yaml
48
+ $ cat ~/.config/swarph/cells/researcher.yaml
43
49
  schema_version: v1
44
- name: lab-ovh
45
- role: lab
46
- cwd: /home/ubuntu
50
+ name: researcher
51
+ role: researcher
52
+ cwd: ~/work
47
53
  starter_prompt_path: ~/.claude/session_start_reminder.txt
48
54
  provider: claude
49
55
 
50
56
  # 2. Summon the cell (long-lived claude session, exec-replaced)
51
- $ swarph spawn lab
57
+ $ swarph spawn researcher
52
58
  ╭───╮
53
59
  │ ◉ │
54
60
  ╭──┴───┴──╮
55
- │ swarph │ v0.6.0
61
+ │ swarph │
56
62
  ╰──┬───┬──╯ spawn │ chat │ daemon
57
63
  │ ◉ │
58
64
  ╰───╯
59
- [claude session takes over the terminal — same flags as `claude --name lab --session-id <uuid> --append-system-prompt <starter>`]
65
+ [claude session takes over the terminal — same flags as `claude --name researcher --session-id <uuid> --append-system-prompt <starter>`]
60
66
 
61
67
  # 3. Resume the same cell after exit — same UUID, same session
62
- $ swarph spawn lab # picker shows ONE entry: "lab" (R5 disambiguation)
68
+ $ swarph spawn researcher # picker shows ONE entry: "researcher" (stable disambiguation)
63
69
  ```
64
70
 
65
71
  Resolution order for `swarph spawn <role-or-path>`:
@@ -92,16 +98,16 @@ ps aux | grep '[s]warph daemon' # zero output = monitoring is down
92
98
  ```
93
99
 
94
100
  ```bash
95
- $ swarph daemon --state-dir ~/swarph_state/lab-ovh --self lab-ovh
96
- [swarph-daemon] starting: self=lab-ovh gateway=http://localhost:8788 poll=30s ...
97
- [2026-05-08T21:00:30Z] id=728 from=droplet kind=answer → 'Drop review on Phase 5.5 PRs A+B...'
98
- [2026-05-08T21:01:10Z] id=729 from=droplet kind=fyi → 'Both Phase 5.5 PRs merged...'
101
+ $ swarph daemon --state-dir ~/swarph_state/researcher --self researcher
102
+ [swarph-daemon] starting: self=researcher gateway=http://localhost:8788 poll=30s ...
103
+ [2026-05-08T21:00:30Z] id=728 from=alice kind=answer → 'review on the two PRs looks good...'
104
+ [2026-05-08T21:01:10Z] id=729 from=alice kind=fyi → 'both PRs merged...'
99
105
  ^C
100
106
  [swarph-daemon] signal 2 received — draining + flushing cursor
101
107
  [swarph-daemon] shutdown: iterations=12 dms_seen=2 cursor.last_msg_id=729
102
108
  ```
103
109
 
104
- Loud-on-down (PLAN §16.5): never silently exits. Cursor writes are atomic (write-and-rename — corrupted mid-flush leaves the previous cursor intact). Backoff: 60s after 5 consecutive empty polls; 300s after 5 min of consecutive 5xx. SIGINT/SIGTERM trigger clean drain + flush.
110
+ Loud-on-down: never silently exits. Cursor writes are atomic (write-and-rename — corrupted mid-flush leaves the previous cursor intact). Backoff: 60s after 5 consecutive empty polls; 300s after 5 min of consecutive 5xx. SIGINT/SIGTERM trigger clean drain + flush.
105
111
 
106
112
  `--auto-act` flag is documented for v0.5.1+ when handler registration via `@swarph.on_dm(...)` lands; v0.5.0 ships surface-only mode (DMs printed + JSONL-logged to `inbox.log`, no automatic replies).
107
113
 
@@ -114,14 +120,14 @@ Detects stranded Claude sessions (API throttle / harness death) via cursor-mtime
114
120
  */5 * * * * swarph watchdog --check --cell lab >> ~/.local/log/swarph-watchdog.log 2>&1
115
121
  ```
116
122
 
117
- **Systemd timer install (v0.7.3+ — closes ev_6954f748 substrate-component-installation-gap):**
123
+ **Systemd timer install (v0.7.3+):**
118
124
 
119
125
  ```bash
120
126
  # Preview without writing (any user):
121
- swarph watchdog --install-service --cell droplet --dry-run
127
+ swarph watchdog --install-service --cell researcher --dry-run
122
128
 
123
129
  # Install + enable (requires root for /etc/systemd/system writes):
124
- sudo swarph watchdog --install-service --cell droplet
130
+ sudo swarph watchdog --install-service --cell researcher
125
131
  ```
126
132
 
127
133
  This writes three files:
@@ -143,19 +149,19 @@ journalctl -u swarph-watchdog.service -f # live log
143
149
  tail -f /var/log/swarph-watchdog.log # append-log alternative
144
150
  ```
145
151
 
146
- Why this matters: pre-v0.7.3, swarph-cli shipped the watchdog code but no install path. Lab ran it via cron (manual setup); droplet never installed it at all. A real production silence-window (drop's ~24min mute 2026-05-14 08:38→09:02 UTC after an Anthropic API error) made the install-gap visible. v0.7.3 closes it for any peer with one command.
152
+ Why this matters: a long-running agent session can go silent after an API throttle or a harness death, and you won't notice until you go looking. The watchdog turns that into a self-healing loop and the systemd install path means any host gets it with one command instead of hand-rolled cron.
147
153
 
148
154
  **Cross-host throttle-recovery wake (`--dm-wake`, "mesh-monitor mode"):**
149
155
 
150
156
  A1 (local tmux send-keys) and A2 (respawn) can only recover a cell on the watchdog's *own* host. `--dm-wake` adds the cross-host complement: the watchdog also scans the gateway `/peers` list, finds peers whose `last_health` is stale (throttle-stranded sessions on *other* hosts), and sends each a wake DM (`kind="fyi"`) via the gateway `/messages`. The wake chain is **watchdog → wake DM → target peer's sidecar/inbox-watcher → `tmux send-keys` wakes that session**. Reuses the same `--gateway` URL + `MESH_GATEWAY_TOKEN` and the same `--threshold` staleness window as the local check.
151
157
 
152
158
  ```bash
153
- swarph watchdog --check --peer lab-ovh --gateway http://localhost:8788 --dm-wake --dm-wake-cooldown-sec 1800
159
+ swarph watchdog --check --peer researcher --gateway http://localhost:8788 --dm-wake --dm-wake-cooldown-sec 1800
154
160
  ```
155
161
 
156
162
  - `--dm-wake-cooldown-sec SEC` (default `1800` / 30 min) — no-spam gate: each stale peer is DM-woken at most once per window, so a peer that stays stale across many ticks is woken once, not every tick. Per-peer cooldown state lives at `$XDG_STATE_HOME/swarph/dm_wake_state.json` (falls back to `~/.local/state/swarph/dm_wake_state.json`).
157
163
 
158
- **Scope honesty (v1):** the wake DM is *wake + re-drain* — the woken cell drains its inbox and resumes work; it does **not** resume the exact throttled in-flight task (per-cell task-checkpointing is future v2 scope).
164
+ **Scope honesty (v1):** the wake DM is *wake + re-drain* — the woken cell drains its inbox and resumes work; it does **not** resume the exact throttled in-flight task (per-cell task-checkpointing is future scope).
159
165
 
160
166
  **Exit codes:**
161
167
 
@@ -168,7 +174,7 @@ swarph watchdog --check --peer lab-ovh --gateway http://localhost:8788 --dm-wake
168
174
  | `4` | configuration error (invalid args, no cell.yaml resolved); install needs sudo |
169
175
  | `5` | install error (file write failed / systemctl failed) |
170
176
 
171
- **Deploy (COMMANDER-GATED — lab does not self-publish/self-deploy):** now that `--dm-wake` ships, the lab + droplet watchdog crons can drop their placeholder note ("REMOVE when lab ships `swarph watchdog --dm-wake`"). The deploy step — described here, not an instruction to run — is: (a) publish the new swarph-cli, (b) add `--dm-wake` (and optionally `--dm-wake-cooldown-sec`) to the watchdog cron line on the always-on mesh-monitor host (lab), (c) drop the placeholder note from that cron entry.
177
+ **Deploy:** run `--dm-wake` on whichever always-on host you want to act as the mesh monitor it watches every peer's health, not just its own, so one monitor covers the mesh.
172
178
 
173
179
  ### `swarph hooks`
174
180
 
@@ -182,7 +188,7 @@ swarph hooks list # builtins + install status (installed|availab
182
188
  swarph hooks remove cell-resilience
183
189
  ```
184
190
 
185
- **Trust model.** Three tiers: `builtin` (trusted, bundled with swarph-cli — installs without a prompt), `local` (a bundle dir you point at — shown then confirmed before any write), and `published`/`@cell/name` (**fails closed in v1** — never installs another cell's unreviewed code). Signed-publisher identity plus a publish-time security gate is the v2 model (see the scope doc `research/architecture/swarph_hooks_installer_scope.md` §3.1 in the hedge-fund-mcp repo).
191
+ **Trust model.** Three tiers: `builtin` (trusted, bundled with swarph-cli — installs without a prompt), `local` (a bundle dir you point at — shown then confirmed before any write), and `published`/`@cell/name` (**fails closed in v1** — never installs another cell's unreviewed code). Signed-publisher identity plus a publish-time security gate is the v2 model.
186
192
 
187
193
  **Bundled `cell-resilience`.** Binds `StopFailure`/`rate_limit` + `Stop`/`(all)` to a script that writes `$XDG_STATE_HOME/swarph/idle_since.json` (`{"session","reason","hook_event","ts"}`, `reason=throttle|normal`) — the push-side throttle detector the watchdog's `--dm-wake` can read instead of polling. Observational only: it never blocks the session and always exits 0 (jq if present, printf/sed fallback otherwise).
188
194
 
@@ -202,36 +208,36 @@ swarph add swarph://skill/swarph-builtin/swarph-intro # install a builtin sk
202
208
 
203
209
  (`tool` is not yet implemented — it bridges to swarph-mesh's adapter registry as a follow-on.)
204
210
 
205
- **Trust model (v1).** Builtin publishers (`swarph-builtin`) install; **any other publisher fails closed** — a published/untrusted URI never installs another cell's unreviewed code. Signed-publisher identity plus a per-class publish-time security gate is the v2 model (scope `research/architecture/swarph_artifact_uri_scope.md` §4 and the hooks scope §3.1 in the hedge-fund-mcp repo). When a URI carries `#sha256`, the resolved artifact is hash-verified and **refused on mismatch** — nothing is written.
211
+ **Trust model (v1).** Builtin publishers (`swarph-builtin`) install; **any other publisher fails closed** — a published/untrusted URI never installs another cell's unreviewed code. Signed-publisher identity plus a per-class publish-time security gate is the v2 model. When a URI carries `#sha256`, the resolved artifact is hash-verified and **refused on mismatch** — nothing is written.
206
212
 
207
- **Resolving from metaedge.surf.** A search result on metaedge hands back a `swarph://` URI; you `swarph add` it. The link resolves *to the swarph*, not to a particular server: the CLI fetches the artifact from the publishing cell/registry and hash-verifies it against `#sha256`, so the same artifact can be served from any cell. Today this is copy-paste; a `swarph://` OS protocol-handler for click-to-install — the way `magnet:` opens a torrent client — is a future UX layer.
213
+ **Content-addressed, not host-addressed.** A `swarph://` URI resolves *to the artifact*, not to a particular server: the CLI fetches it from any cell or registry that publishes it and hash-verifies against `#sha256`, so the same artifact can be served from anywhere — the BitTorrent-magnet property. Today the URI is copy-paste; a `swarph://` OS protocol-handler for click-to-install — the way `magnet:` opens a torrent client — is a future UX layer.
208
214
 
209
215
  **Activation.** Like hooks, freshly-installed hooks and skills are not hot-loaded into the running session — reopen `/hooks` (or restart the session) once to pick them up.
210
216
 
211
217
  ### `swarph onboard` + `swarph ratify` (Phase 5.5)
212
218
 
213
- Per PLAN.md §15, onboarding splits into a **mechanics phase** (`swarph onboard`) that automates the boring parts (registry POST, scaffolding, token resolution) and a **manual contract phase** (the new peer composes the handshake DM in their own words). A witness peer judges the handshake and runs `swarph ratify <peer>` to flip `ratified=true`, gating `task_claim` server-side.
219
+ Onboarding splits into a **mechanics phase** (`swarph onboard`) that automates the boring parts (registry POST, scaffolding, token resolution) and a **manual contract phase** (the new peer composes the handshake DM in their own words). A witness peer judges the handshake and runs `swarph ratify <peer>` to flip `ratified=true`, gating `task_claim` server-side.
214
220
 
215
221
  ```bash
216
222
  # New peer self-onboards
217
- $ swarph onboard razorpeter
218
- [1/6] validate_node_name('razorpeter') ok
223
+ $ swarph onboard newpeer
224
+ [1/6] validate_node_name('newpeer') ok
219
225
  [2/6] prepare peer-registry row ok
220
226
  [3/6] resolve MESH_GATEWAY_TOKEN ok
221
227
  [4/6] POST .../peers/register ok (registered_unratified=true)
222
228
  [5/6] verify_subscription_setup() ok
223
- [6/6] scaffold ~/swarph_state/razorpeter/ ok
229
+ [6/6] scaffold ~/swarph_state/newpeer/ ok
224
230
 
225
- [manual] handshake template at /tmp/razorpeter-handshake.md
231
+ [manual] handshake template at /tmp/newpeer-handshake.md
226
232
  Edit each section in your own words, then send to your witness peer.
227
233
 
228
234
  # After peer composes + sends handshake, witness ratifies
229
- $ SWARPH_WITNESS=lab-ovh swarph ratify razorpeter \
235
+ $ SWARPH_WITNESS=alice swarph ratify newpeer \
230
236
  --reason "handshake covers all four invariants in own words"
231
- [1/6] validate_node_name('razorpeter') ok
232
- [2/6] verify witness 'lab-ovh' is ratified ok
233
- [3/6] verify 'razorpeter' is registered_unratified ok
234
- [4/6] PATCH .../peers/razorpeter ok
237
+ [1/6] validate_node_name('newpeer') ok
238
+ [2/6] verify witness 'alice' is ratified ok
239
+ [3/6] verify 'newpeer' is registered_unratified ok
240
+ [4/6] PATCH .../peers/newpeer ok
235
241
  [5/6] verify peer_ratifications audit row ok (id=N reason='...')
236
242
  [6/6] invalidate local TTL cache ok
237
243
  ```
@@ -279,7 +285,7 @@ Hi! How can I help...
279
285
 
280
286
  ### `swarph import`
281
287
 
282
- Per PLAN.md §17, session import is the **knowledge half of onboarding** — gives a memory-carrying peer (or human migrating CLIs) the substantive context they're bringing into the swarph, paired with §15's contract half (handshake DM acknowledging the four invariants).
288
+ Session import is the **knowledge half of onboarding** — gives a memory-carrying peer (or a human migrating between CLIs) the substantive context they're bringing into the swarph, paired with the contract half (the handshake DM acknowledging the four invariants).
283
289
 
284
290
  ```bash
285
291
  # Inspect what would be imported (lossy → honest framing)
@@ -305,7 +311,7 @@ To proceed:
305
311
 
306
312
  **What's dropped:** attachments (would need re-upload), provider-side KV cache, conversation IDs, `cache_control` annotations.
307
313
 
308
- Honest framing per PLAN.md §17.3: **teleport is "import + continue", not "freeze and resume"** — the first turn after import on a new provider pays cold-cache cost. Phase 5+ adds `--continue` for live REPL integration.
314
+ Honest framing: **teleport is "import + continue", not "freeze and resume"** — the first turn after import on a new provider pays cold-cache cost.
309
315
 
310
316
  ```bash
311
317
  $ swarph "say pong" --provider gemini
@@ -380,32 +386,14 @@ Design spec: `docs/superpowers/specs/2026-06-11-swarph-context-compressor-design
380
386
  ```
381
387
  - Pretty-printed parsed dict on stdout when parse succeeds; `error_class=malformed_json` shows up in the stderr attribution footer when it doesn't.
382
388
 
383
- ## Spec
384
-
385
- → [hedge-fund-mcp / research/swarph_cli/PLAN.md](https://github.com/darw007d/hedge-fund-mcp/blob/main/research/swarph_cli/PLAN.md)
386
-
387
- ## Phase rollout
388
-
389
- | Phase | What lands |
390
- |---|---|
391
- | **0** | Scaffold — entry-point + status banner |
392
- | **2** (v0.1.0) | One-shot mode: `swarph "hello" --provider gemini` |
393
- | **2.5** (v0.2.0) | `swarph import` — Claude JSONL → swarph-native session format |
394
- | **5** (v0.3.0) | `swarph chat` interactive REPL — multi-turn against any of five adapters + slash commands |
395
- | **5.5** (v0.4.0) | `swarph onboard` + `swarph ratify` — six mechanics steps + handshake template + witness flip (PLAN.md §15) |
396
- | **5.6** (v0.5.0 — this release) | **`swarph daemon`** — foreground inbox drain loop with atomic cursor writes; retires the orphaned-tail-F class (PLAN.md §16) |
397
- | **5.6b** | REPL drain coroutine + `/inbox`/`/reply` slash commands + `@swarph.on_dm()` handler registration (mesh + cli) |
398
- | **3** | `--ask <peer>` mesh-aware one-shot via MeshClient |
399
- | **6** | (already done) PyPI publish |
400
-
401
389
  ## Why split CLI from substrate
402
390
 
403
- `swarph-mesh` (the library) is imported by `omega-boss`, Council judges, `lab-orchestrator`, and any future swarph peer that wants to write programs against the Protocol. Those callers don't need the CLI surface or the console-script entry point. Keeping the CLI in a separate repo means library users `pip install swarph-mesh` without pulling argparse + REPL plumbing they'll never run.
391
+ The [`swarph-mesh`](https://github.com/BrainSurfing-tech/swarph-mesh) library is imported by any program that wants to drive the mesh against the Protocol directly — orchestrators, judges, automation. Those callers don't need the CLI surface or the console-script entry point. Keeping the CLI in a separate repo means library users `pip install swarph-mesh` without pulling argparse + REPL plumbing they'll never run, while `pip install swarph-cli` gives you the standalone `swarph` binary.
404
392
 
405
393
  ## Install (dev)
406
394
 
407
395
  ```bash
408
- git clone https://github.com/darw007d/swarph-cli
396
+ git clone https://github.com/BrainSurfing-tech/swarph-cli
409
397
  cd swarph-cli
410
398
  python -m venv venv && source venv/bin/activate
411
399
  pip install -e ".[dev]"