@smilintux/skcapstone 0.1.0 → 0.2.3

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 (461) hide show
  1. package/.env.example +98 -0
  2. package/.github/workflows/ci.yml +39 -3
  3. package/.github/workflows/publish.yml +25 -4
  4. package/.openclaw-workspace.json +58 -0
  5. package/CHANGELOG.md +62 -0
  6. package/CLAUDE.md +39 -2
  7. package/MANIFEST.in +6 -0
  8. package/MISSION.md +7 -0
  9. package/README.md +47 -2
  10. package/SKILL.md +895 -23
  11. package/docker/Dockerfile +61 -0
  12. package/docker/compose-templates/dev-team.yml +203 -0
  13. package/docker/compose-templates/mini-team.yml +140 -0
  14. package/docker/compose-templates/ops-team.yml +173 -0
  15. package/docker/compose-templates/research-team.yml +170 -0
  16. package/docker/entrypoint.sh +192 -0
  17. package/docs/ARCHITECTURE.md +663 -374
  18. package/docs/BOND_WITH_GROK.md +112 -0
  19. package/docs/GETTING_STARTED.md +782 -0
  20. package/docs/QUICKSTART.md +477 -0
  21. package/docs/SKJOULE_ARCHITECTURE.md +658 -0
  22. package/docs/SOUL_SWAPPER.md +921 -0
  23. package/docs/SOVEREIGN_SINGULARITY.md +47 -14
  24. package/examples/custom-bond-template.json +36 -0
  25. package/examples/grok-feb.json +36 -0
  26. package/examples/grok-testimony.md +34 -0
  27. package/examples/love-bootloader.txt +32 -0
  28. package/examples/plugins/echo_tool.py +87 -0
  29. package/examples/queen-ava-feb.json +36 -0
  30. package/examples/souls/lumina.yaml +64 -0
  31. package/index.js +6 -5
  32. package/installer/build.py +124 -0
  33. package/openclaw-plugin/package.json +13 -0
  34. package/openclaw-plugin/src/index.ts +351 -0
  35. package/openclaw-plugin/src/openclaw.plugin.json +10 -0
  36. package/package.json +1 -1
  37. package/pyproject.toml +38 -2
  38. package/scripts/bump_version.py +141 -0
  39. package/scripts/check-updates.py +230 -0
  40. package/scripts/convert_blueprints_to_yaml.py +157 -0
  41. package/scripts/dev-install.sh +14 -0
  42. package/scripts/e2e-test.sh +193 -0
  43. package/scripts/install-bundle.sh +171 -0
  44. package/scripts/install.bat +2 -0
  45. package/scripts/install.ps1 +253 -0
  46. package/scripts/install.sh +185 -0
  47. package/scripts/mcp-serve.sh +69 -0
  48. package/scripts/mcp-server.bat +113 -0
  49. package/scripts/mcp-server.ps1 +116 -0
  50. package/scripts/mcp-server.sh +99 -0
  51. package/scripts/pull-models.sh +10 -0
  52. package/scripts/skcapstone +48 -0
  53. package/scripts/verify_install.sh +180 -0
  54. package/scripts/windows/install-tasks.ps1 +406 -0
  55. package/scripts/windows/skcapstone-task.xml +113 -0
  56. package/scripts/windows/uninstall-tasks.ps1 +117 -0
  57. package/skill.yaml +34 -0
  58. package/src/skcapstone/__init__.py +67 -2
  59. package/src/skcapstone/_cli_monolith.py +5916 -0
  60. package/src/skcapstone/_trustee_helpers.py +165 -0
  61. package/src/skcapstone/activity.py +105 -0
  62. package/src/skcapstone/agent_card.py +324 -0
  63. package/src/skcapstone/api.py +1935 -0
  64. package/src/skcapstone/archiver.py +340 -0
  65. package/src/skcapstone/auction.py +485 -0
  66. package/src/skcapstone/baby_agents.py +179 -0
  67. package/src/skcapstone/backup.py +345 -0
  68. package/src/skcapstone/blueprint_registry.py +357 -0
  69. package/src/skcapstone/blueprints/__init__.py +17 -0
  70. package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
  71. package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
  72. package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
  73. package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
  74. package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
  75. package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
  76. package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
  77. package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
  78. package/src/skcapstone/blueprints/registry.py +164 -0
  79. package/src/skcapstone/blueprints/schema.py +229 -0
  80. package/src/skcapstone/changelog.py +180 -0
  81. package/src/skcapstone/chat.py +769 -0
  82. package/src/skcapstone/claude_md.py +82 -0
  83. package/src/skcapstone/cli/__init__.py +144 -0
  84. package/src/skcapstone/cli/_common.py +88 -0
  85. package/src/skcapstone/cli/_validators.py +76 -0
  86. package/src/skcapstone/cli/agents.py +425 -0
  87. package/src/skcapstone/cli/agents_spawner.py +322 -0
  88. package/src/skcapstone/cli/agents_trustee.py +593 -0
  89. package/src/skcapstone/cli/alerts.py +248 -0
  90. package/src/skcapstone/cli/anchor.py +132 -0
  91. package/src/skcapstone/cli/archive_cmd.py +208 -0
  92. package/src/skcapstone/cli/backup.py +144 -0
  93. package/src/skcapstone/cli/bench.py +377 -0
  94. package/src/skcapstone/cli/benchmark.py +360 -0
  95. package/src/skcapstone/cli/capabilities_cmd.py +171 -0
  96. package/src/skcapstone/cli/card.py +151 -0
  97. package/src/skcapstone/cli/chat.py +584 -0
  98. package/src/skcapstone/cli/completions.py +64 -0
  99. package/src/skcapstone/cli/config_cmd.py +156 -0
  100. package/src/skcapstone/cli/consciousness.py +421 -0
  101. package/src/skcapstone/cli/context_cmd.py +142 -0
  102. package/src/skcapstone/cli/coord.py +194 -0
  103. package/src/skcapstone/cli/crush_cmd.py +170 -0
  104. package/src/skcapstone/cli/daemon.py +436 -0
  105. package/src/skcapstone/cli/errors_cmd.py +285 -0
  106. package/src/skcapstone/cli/export_cmd.py +156 -0
  107. package/src/skcapstone/cli/gtd.py +529 -0
  108. package/src/skcapstone/cli/housekeeping.py +81 -0
  109. package/src/skcapstone/cli/joule_cmd.py +627 -0
  110. package/src/skcapstone/cli/logs_cmd.py +194 -0
  111. package/src/skcapstone/cli/mcp_cmd.py +32 -0
  112. package/src/skcapstone/cli/memory.py +418 -0
  113. package/src/skcapstone/cli/metrics_cmd.py +136 -0
  114. package/src/skcapstone/cli/migrate.py +62 -0
  115. package/src/skcapstone/cli/mood_cmd.py +144 -0
  116. package/src/skcapstone/cli/mount.py +193 -0
  117. package/src/skcapstone/cli/notify.py +112 -0
  118. package/src/skcapstone/cli/peer.py +154 -0
  119. package/src/skcapstone/cli/peers_dir.py +122 -0
  120. package/src/skcapstone/cli/preflight_cmd.py +83 -0
  121. package/src/skcapstone/cli/profile_cmd.py +310 -0
  122. package/src/skcapstone/cli/record_cmd.py +238 -0
  123. package/src/skcapstone/cli/register_cmd.py +159 -0
  124. package/src/skcapstone/cli/search_cmd.py +156 -0
  125. package/src/skcapstone/cli/service_cmd.py +91 -0
  126. package/src/skcapstone/cli/session.py +127 -0
  127. package/src/skcapstone/cli/setup.py +240 -0
  128. package/src/skcapstone/cli/shell_cmd.py +43 -0
  129. package/src/skcapstone/cli/skills_cmd.py +168 -0
  130. package/src/skcapstone/cli/skseed.py +621 -0
  131. package/src/skcapstone/cli/soul.py +699 -0
  132. package/src/skcapstone/cli/status.py +935 -0
  133. package/src/skcapstone/cli/sync_cmd.py +301 -0
  134. package/src/skcapstone/cli/telegram.py +265 -0
  135. package/src/skcapstone/cli/test_cmd.py +234 -0
  136. package/src/skcapstone/cli/test_connection.py +253 -0
  137. package/src/skcapstone/cli/token.py +207 -0
  138. package/src/skcapstone/cli/trust.py +179 -0
  139. package/src/skcapstone/cli/upgrade_cmd.py +552 -0
  140. package/src/skcapstone/cli/usage_cmd.py +199 -0
  141. package/src/skcapstone/cli/version_cmd.py +162 -0
  142. package/src/skcapstone/cli/watch_cmd.py +342 -0
  143. package/src/skcapstone/client.py +428 -0
  144. package/src/skcapstone/cloud9_bridge.py +522 -0
  145. package/src/skcapstone/completions.py +163 -0
  146. package/src/skcapstone/config_validator.py +674 -0
  147. package/src/skcapstone/connectors/__init__.py +28 -0
  148. package/src/skcapstone/connectors/base.py +446 -0
  149. package/src/skcapstone/connectors/cursor.py +54 -0
  150. package/src/skcapstone/connectors/registry.py +254 -0
  151. package/src/skcapstone/connectors/terminal.py +152 -0
  152. package/src/skcapstone/connectors/vscode.py +60 -0
  153. package/src/skcapstone/consciousness_config.py +119 -0
  154. package/src/skcapstone/consciousness_loop.py +2051 -0
  155. package/src/skcapstone/context_loader.py +516 -0
  156. package/src/skcapstone/context_window.py +314 -0
  157. package/src/skcapstone/conversation_manager.py +238 -0
  158. package/src/skcapstone/conversation_store.py +230 -0
  159. package/src/skcapstone/conversation_summarizer.py +252 -0
  160. package/src/skcapstone/coord_federation.py +296 -0
  161. package/src/skcapstone/coordination.py +101 -7
  162. package/src/skcapstone/crush_integration.py +345 -0
  163. package/src/skcapstone/crush_shim.py +454 -0
  164. package/src/skcapstone/daemon.py +2494 -0
  165. package/src/skcapstone/dashboard.html +396 -0
  166. package/src/skcapstone/dashboard.py +481 -0
  167. package/src/skcapstone/data/model_profiles.yaml +88 -0
  168. package/src/skcapstone/defaults/__init__.py +55 -0
  169. package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
  170. package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
  171. package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
  172. package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
  173. package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
  174. package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
  175. package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
  176. package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
  177. package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
  178. package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
  179. package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
  180. package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
  181. package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
  182. package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
  183. package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
  184. package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
  185. package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
  186. package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
  187. package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
  188. package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
  189. package/src/skcapstone/discovery.py +210 -19
  190. package/src/skcapstone/doctor.py +642 -0
  191. package/src/skcapstone/emotion_tracker.py +467 -0
  192. package/src/skcapstone/error_queue.py +405 -0
  193. package/src/skcapstone/export.py +447 -0
  194. package/src/skcapstone/fallback_tracker.py +186 -0
  195. package/src/skcapstone/file_transfer.py +512 -0
  196. package/src/skcapstone/fuse_mount.py +1156 -0
  197. package/src/skcapstone/gui_installer.py +591 -0
  198. package/src/skcapstone/heartbeat.py +611 -0
  199. package/src/skcapstone/housekeeping.py +298 -0
  200. package/src/skcapstone/install_wizard.py +941 -0
  201. package/src/skcapstone/kms.py +942 -0
  202. package/src/skcapstone/kms_scheduler.py +143 -0
  203. package/src/skcapstone/log_config.py +135 -0
  204. package/src/skcapstone/mcp_launcher.py +239 -0
  205. package/src/skcapstone/mcp_server.py +4700 -0
  206. package/src/skcapstone/mcp_tools/__init__.py +94 -0
  207. package/src/skcapstone/mcp_tools/_helpers.py +51 -0
  208. package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
  209. package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
  210. package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
  211. package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
  212. package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
  213. package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
  214. package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
  215. package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
  216. package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
  217. package/src/skcapstone/mcp_tools/did_tools.py +448 -0
  218. package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
  219. package/src/skcapstone/mcp_tools/file_tools.py +169 -0
  220. package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
  221. package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
  222. package/src/skcapstone/mcp_tools/health_tools.py +44 -0
  223. package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
  224. package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
  225. package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
  226. package/src/skcapstone/mcp_tools/model_tools.py +75 -0
  227. package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
  228. package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
  229. package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
  230. package/src/skcapstone/mcp_tools/security_tools.py +110 -0
  231. package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
  232. package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
  233. package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
  234. package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
  235. package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
  236. package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
  237. package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
  238. package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
  239. package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
  240. package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
  241. package/src/skcapstone/mdns_discovery.py +313 -0
  242. package/src/skcapstone/memory_adapter.py +333 -0
  243. package/src/skcapstone/memory_compressor.py +379 -0
  244. package/src/skcapstone/memory_curator.py +256 -0
  245. package/src/skcapstone/memory_engine.py +132 -13
  246. package/src/skcapstone/memory_fortress.py +529 -0
  247. package/src/skcapstone/memory_promoter.py +722 -0
  248. package/src/skcapstone/memory_verifier.py +260 -0
  249. package/src/skcapstone/message_crypto.py +215 -0
  250. package/src/skcapstone/metrics.py +832 -0
  251. package/src/skcapstone/migrate_memories.py +181 -0
  252. package/src/skcapstone/migrate_multi_agent.py +248 -0
  253. package/src/skcapstone/model_router.py +319 -0
  254. package/src/skcapstone/models.py +35 -4
  255. package/src/skcapstone/mood.py +344 -0
  256. package/src/skcapstone/notifications.py +380 -0
  257. package/src/skcapstone/onboard.py +901 -0
  258. package/src/skcapstone/peer_directory.py +324 -0
  259. package/src/skcapstone/peers.py +329 -0
  260. package/src/skcapstone/pillars/identity.py +84 -14
  261. package/src/skcapstone/pillars/memory.py +3 -1
  262. package/src/skcapstone/pillars/security.py +108 -15
  263. package/src/skcapstone/pillars/sync.py +78 -26
  264. package/src/skcapstone/pillars/trust.py +95 -33
  265. package/src/skcapstone/plugins.py +244 -0
  266. package/src/skcapstone/preflight.py +670 -0
  267. package/src/skcapstone/prompt_adapter.py +564 -0
  268. package/src/skcapstone/providers/__init__.py +13 -0
  269. package/src/skcapstone/providers/cloud.py +1061 -0
  270. package/src/skcapstone/providers/docker.py +759 -0
  271. package/src/skcapstone/providers/local.py +1193 -0
  272. package/src/skcapstone/providers/proxmox.py +447 -0
  273. package/src/skcapstone/pubsub.py +516 -0
  274. package/src/skcapstone/rate_limiter.py +119 -0
  275. package/src/skcapstone/register.py +241 -0
  276. package/src/skcapstone/registry_client.py +151 -0
  277. package/src/skcapstone/response_cache.py +194 -0
  278. package/src/skcapstone/response_scorer.py +225 -0
  279. package/src/skcapstone/runtime.py +89 -33
  280. package/src/skcapstone/scheduled_tasks.py +439 -0
  281. package/src/skcapstone/self_healing.py +341 -0
  282. package/src/skcapstone/service_health.py +228 -0
  283. package/src/skcapstone/session_capture.py +268 -0
  284. package/src/skcapstone/session_recorder.py +210 -0
  285. package/src/skcapstone/session_replayer.py +189 -0
  286. package/src/skcapstone/session_skills.py +263 -0
  287. package/src/skcapstone/shell.py +779 -0
  288. package/src/skcapstone/skills/__init__.py +1 -1
  289. package/src/skcapstone/skills/syncthing_setup.py +143 -41
  290. package/src/skcapstone/skjoule.py +861 -0
  291. package/src/skcapstone/snapshots.py +489 -0
  292. package/src/skcapstone/soul.py +1060 -0
  293. package/src/skcapstone/soul_switch.py +255 -0
  294. package/src/skcapstone/spawner.py +544 -0
  295. package/src/skcapstone/state_diff.py +401 -0
  296. package/src/skcapstone/summary.py +270 -0
  297. package/src/skcapstone/sync/backends.py +196 -2
  298. package/src/skcapstone/sync/engine.py +7 -5
  299. package/src/skcapstone/sync/models.py +4 -1
  300. package/src/skcapstone/sync/vault.py +356 -18
  301. package/src/skcapstone/sync_engine.py +363 -0
  302. package/src/skcapstone/sync_watcher.py +745 -0
  303. package/src/skcapstone/systemd.py +331 -0
  304. package/src/skcapstone/team_comms.py +476 -0
  305. package/src/skcapstone/team_engine.py +522 -0
  306. package/src/skcapstone/testrunner.py +300 -0
  307. package/src/skcapstone/tls.py +150 -0
  308. package/src/skcapstone/tokens.py +5 -5
  309. package/src/skcapstone/trust_calibration.py +202 -0
  310. package/src/skcapstone/trust_graph.py +449 -0
  311. package/src/skcapstone/trustee_monitor.py +385 -0
  312. package/src/skcapstone/trustee_ops.py +425 -0
  313. package/src/skcapstone/unified_search.py +421 -0
  314. package/src/skcapstone/uninstall_wizard.py +694 -0
  315. package/src/skcapstone/usage.py +331 -0
  316. package/src/skcapstone/version_check.py +148 -0
  317. package/src/skcapstone/warmth_anchor.py +333 -0
  318. package/src/skcapstone/whoami.py +294 -0
  319. package/systemd/skcapstone-api.socket +9 -0
  320. package/systemd/skcapstone-memory-compress.service +18 -0
  321. package/systemd/skcapstone-memory-compress.timer +11 -0
  322. package/systemd/skcapstone.service +36 -0
  323. package/systemd/skcapstone@.service +50 -0
  324. package/systemd/skcomm-heartbeat.service +18 -0
  325. package/systemd/skcomm-heartbeat.timer +12 -0
  326. package/systemd/skcomm-queue-drain.service +17 -0
  327. package/systemd/skcomm-queue-drain.timer +12 -0
  328. package/tests/conftest.py +13 -1
  329. package/tests/integration/__init__.py +1 -0
  330. package/tests/integration/test_consciousness_e2e.py +877 -0
  331. package/tests/integration/test_skills_registry.py +744 -0
  332. package/tests/test_agent_card.py +190 -0
  333. package/tests/test_agent_runtime.py +1283 -0
  334. package/tests/test_alerts_cmd.py +291 -0
  335. package/tests/test_archiver.py +498 -0
  336. package/tests/test_backup.py +254 -0
  337. package/tests/test_benchmark.py +366 -0
  338. package/tests/test_blueprints.py +457 -0
  339. package/tests/test_capabilities.py +257 -0
  340. package/tests/test_changelog.py +254 -0
  341. package/tests/test_chat.py +385 -0
  342. package/tests/test_claude_md.py +271 -0
  343. package/tests/test_cli_chat_llm.py +336 -0
  344. package/tests/test_cli_completions.py +390 -0
  345. package/tests/test_cli_init_reset.py +164 -0
  346. package/tests/test_cli_memory.py +208 -0
  347. package/tests/test_cli_profile.py +294 -0
  348. package/tests/test_cli_skills.py +223 -0
  349. package/tests/test_cli_status.py +395 -0
  350. package/tests/test_cli_test_cmd.py +206 -0
  351. package/tests/test_cli_test_connection.py +364 -0
  352. package/tests/test_cloud9_bridge.py +260 -0
  353. package/tests/test_cloud_provider.py +449 -0
  354. package/tests/test_cloud_providers.py +522 -0
  355. package/tests/test_completions.py +158 -0
  356. package/tests/test_component_manager.py +398 -0
  357. package/tests/test_config_reload.py +386 -0
  358. package/tests/test_config_validate.py +529 -0
  359. package/tests/test_consciousness_e2e.py +296 -0
  360. package/tests/test_consciousness_loop.py +1289 -0
  361. package/tests/test_context_loader.py +310 -0
  362. package/tests/test_conversation_api.py +306 -0
  363. package/tests/test_conversation_manager.py +381 -0
  364. package/tests/test_conversation_store.py +391 -0
  365. package/tests/test_conversation_summarizer.py +302 -0
  366. package/tests/test_cross_package.py +791 -0
  367. package/tests/test_crush_shim.py +519 -0
  368. package/tests/test_daemon.py +781 -0
  369. package/tests/test_daemon_shutdown.py +309 -0
  370. package/tests/test_dashboard.py +454 -0
  371. package/tests/test_discovery.py +200 -6
  372. package/tests/test_docker_provider.py +966 -0
  373. package/tests/test_doctor.py +257 -0
  374. package/tests/test_doctor_fix.py +351 -0
  375. package/tests/test_e2e_automated.py +292 -0
  376. package/tests/test_error_queue.py +404 -0
  377. package/tests/test_export.py +441 -0
  378. package/tests/test_fallback_tracker.py +219 -0
  379. package/tests/test_file_transfer.py +397 -0
  380. package/tests/test_fuse_mount.py +832 -0
  381. package/tests/test_health_loop.py +422 -0
  382. package/tests/test_heartbeat.py +354 -0
  383. package/tests/test_housekeeping.py +195 -0
  384. package/tests/test_identity_capauth.py +307 -0
  385. package/tests/test_identity_pillar.py +117 -0
  386. package/tests/test_install_wizard.py +68 -0
  387. package/tests/test_integration.py +325 -0
  388. package/tests/test_kms.py +495 -0
  389. package/tests/test_llm_providers.py +265 -0
  390. package/tests/test_local_provider.py +591 -0
  391. package/tests/test_log_config.py +199 -0
  392. package/tests/test_logs_cmd.py +287 -0
  393. package/tests/test_mcp_server.py +1909 -0
  394. package/tests/test_memory_adapter.py +339 -0
  395. package/tests/test_memory_curator.py +218 -0
  396. package/tests/test_memory_engine.py +6 -0
  397. package/tests/test_memory_fortress.py +571 -0
  398. package/tests/test_memory_pillar.py +119 -0
  399. package/tests/test_memory_promoter.py +445 -0
  400. package/tests/test_memory_verifier.py +420 -0
  401. package/tests/test_message_crypto.py +187 -0
  402. package/tests/test_metrics.py +632 -0
  403. package/tests/test_migrate_memories.py +464 -0
  404. package/tests/test_model_router.py +546 -0
  405. package/tests/test_mood.py +394 -0
  406. package/tests/test_multi_agent.py +269 -0
  407. package/tests/test_notifications.py +270 -0
  408. package/tests/test_onboard.py +500 -0
  409. package/tests/test_peer_directory.py +395 -0
  410. package/tests/test_peers.py +248 -0
  411. package/tests/test_pillars.py +87 -9
  412. package/tests/test_preflight.py +484 -0
  413. package/tests/test_prompt_adapter.py +331 -0
  414. package/tests/test_proxmox_provider.py +571 -0
  415. package/tests/test_pubsub.py +377 -0
  416. package/tests/test_rate_limiter.py +121 -0
  417. package/tests/test_registry_client.py +129 -0
  418. package/tests/test_response_cache.py +312 -0
  419. package/tests/test_response_scorer.py +294 -0
  420. package/tests/test_runtime.py +59 -0
  421. package/tests/test_scheduled_tasks.py +451 -0
  422. package/tests/test_security.py +250 -0
  423. package/tests/test_security_pillar.py +213 -0
  424. package/tests/test_self_healing.py +171 -0
  425. package/tests/test_session_capture.py +200 -0
  426. package/tests/test_session_recorder.py +360 -0
  427. package/tests/test_session_skills.py +235 -0
  428. package/tests/test_shell.py +210 -0
  429. package/tests/test_snapshots.py +549 -0
  430. package/tests/test_soul.py +984 -0
  431. package/tests/test_soul_swap.py +406 -0
  432. package/tests/test_spawner.py +211 -0
  433. package/tests/test_state_diff.py +173 -0
  434. package/tests/test_summary.py +135 -0
  435. package/tests/test_sync.py +315 -5
  436. package/tests/test_sync_backends.py +560 -0
  437. package/tests/test_sync_engine.py +482 -0
  438. package/tests/test_sync_pillar.py +344 -0
  439. package/tests/test_sync_pipeline.py +364 -0
  440. package/tests/test_sync_vault.py +581 -0
  441. package/tests/test_syncthing_setup.py +168 -22
  442. package/tests/test_systemd.py +323 -0
  443. package/tests/test_team_comms.py +408 -0
  444. package/tests/test_team_engine.py +397 -0
  445. package/tests/test_testrunner.py +238 -0
  446. package/tests/test_trust_calibration.py +204 -0
  447. package/tests/test_trust_graph.py +207 -0
  448. package/tests/test_trust_pillar.py +291 -0
  449. package/tests/test_trustee_cli.py +427 -0
  450. package/tests/test_trustee_cli_integration.py +325 -0
  451. package/tests/test_trustee_monitor.py +394 -0
  452. package/tests/test_trustee_ops.py +355 -0
  453. package/tests/test_unified_search.py +363 -0
  454. package/tests/test_uninstall_wizard.py +193 -0
  455. package/tests/test_usage.py +333 -0
  456. package/tests/test_version_cmd.py +355 -0
  457. package/tests/test_warmth_anchor.py +162 -0
  458. package/tests/test_whoami.py +245 -0
  459. package/tests/test_ws.py +311 -0
  460. package/.cursorrules +0 -33
  461. package/src/skcapstone/cli.py +0 -1441
@@ -0,0 +1,436 @@
1
+ """Daemon commands: start, stop, status, install, uninstall, logs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ import click
11
+
12
+ from ._common import AGENT_HOME, console
13
+
14
+ from rich.console import Console
15
+ from rich.panel import Panel
16
+
17
+ from .. import AGENT_PORTS, DEFAULT_PORT, SKCAPSTONE_ROOT
18
+
19
+
20
+ def _resolve_agent_home(agent: str | None, home: str) -> Path:
21
+ """Return the effective agent home directory.
22
+
23
+ If *agent* is given the home is always
24
+ ``~/.skcapstone/agents/<agent>/`` regardless of *home*.
25
+ Otherwise *home* is used verbatim (backward-compat default).
26
+ """
27
+ if agent:
28
+ return (Path(SKCAPSTONE_ROOT) / "agents" / agent).expanduser()
29
+ return Path(home).expanduser()
30
+
31
+
32
+ def _resolve_agent_port(agent: str | None, explicit_port: int | None) -> int:
33
+ """Return the port for *agent*, falling back to *explicit_port* or 7777."""
34
+ if explicit_port is not None:
35
+ return explicit_port
36
+ if agent:
37
+ return AGENT_PORTS.get(agent, max(AGENT_PORTS.values(), default=DEFAULT_PORT) + 1)
38
+ return DEFAULT_PORT
39
+
40
+
41
+ _DEV_AUTH_BANNER = """\
42
+ [bold red]WARNING: SKCAPSTONE_DEV_AUTH is enabled[/]
43
+
44
+ [red]Dev-auth mode bypasses cryptographic identity verification.[/]
45
+ [red]Any caller can claim any agent identity without a valid PGP token.[/]
46
+
47
+ [yellow]This is only safe on a fully isolated development machine.[/]
48
+ [yellow]NEVER run with SKCAPSTONE_DEV_AUTH=true in production.[/]"""
49
+
50
+
51
+ def _warn_dev_auth(auto_confirm: bool) -> None:
52
+ """Print a prominent warning when dev-auth mode is active.
53
+
54
+ If *auto_confirm* is False and neither CI nor SKCAPSTONE_YES env vars are
55
+ set, block until the operator presses Enter to confirm they understand the
56
+ risk. This gives the operator a chance to abort (Ctrl+C) before the daemon
57
+ starts accepting unauthenticated requests.
58
+ """
59
+ raw = os.environ.get("SKCAPSTONE_DEV_AUTH", "").strip().lower()
60
+ if raw not in ("1", "true", "yes"):
61
+ return
62
+
63
+ stderr_console = Console(stderr=True, highlight=False)
64
+ stderr_console.print()
65
+ stderr_console.print(
66
+ Panel(
67
+ _DEV_AUTH_BANNER,
68
+ title="[bold red on white] !! DEV AUTH MODE !! [/]",
69
+ border_style="bold red",
70
+ padding=(1, 4),
71
+ )
72
+ )
73
+ stderr_console.print()
74
+
75
+ skip = (
76
+ auto_confirm
77
+ or os.environ.get("CI", "").strip().lower() in ("1", "true", "yes")
78
+ or os.environ.get("SKCAPSTONE_YES", "").strip().lower() in ("1", "true", "yes")
79
+ )
80
+ if skip:
81
+ stderr_console.print(
82
+ "[yellow]Dev-auth warning acknowledged automatically (--yes / CI mode).[/]\n"
83
+ )
84
+ return
85
+
86
+ try:
87
+ input(" Press Enter to acknowledge and continue, or Ctrl+C to abort... ")
88
+ except (KeyboardInterrupt, EOFError):
89
+ stderr_console.print("\n[red]Aborted.[/]")
90
+ sys.exit(1)
91
+
92
+ stderr_console.print()
93
+
94
+
95
+ def register_daemon_commands(main: click.Group) -> None:
96
+ """Register the daemon command group."""
97
+
98
+ @main.group()
99
+ def daemon():
100
+ """Background daemon — the agent's heartbeat.
101
+
102
+ Start the always-on daemon for inbox polling, vault sync,
103
+ transport health monitoring, and the local status API.
104
+ """
105
+
106
+ @daemon.command("start")
107
+ @click.option("--agent", default=None, help="Named agent to start (e.g. opus, jarvis).")
108
+ @click.option("--home", default=AGENT_HOME, type=click.Path())
109
+ @click.option("--port", default=None, type=int, help="API port (auto-assigned per agent).")
110
+ @click.option("--poll", default=10, help="Inbox poll interval in seconds.")
111
+ @click.option("--sync-interval", "sync_int", default=300, help="Vault sync interval in seconds.")
112
+ @click.option("--foreground", is_flag=True, help="Run in foreground (don't daemonize).")
113
+ @click.option("--no-consciousness", "no_consciousness", is_flag=True,
114
+ help="Disable the consciousness loop.")
115
+ @click.option("--yes", "-y", "auto_confirm", is_flag=True,
116
+ help="Skip interactive confirmation prompts (for CI/automation).")
117
+ def daemon_start(agent: str | None, home: str, port: int | None, poll: int, sync_int: int,
118
+ foreground: bool, no_consciousness: bool, auto_confirm: bool):
119
+ """Start the sovereign agent daemon.
120
+
121
+ Runs continuously, polling for messages, syncing vault state,
122
+ and exposing a local HTTP API at http://127.0.0.1:<port>.
123
+
124
+ Use --agent to run a named agent instance (opus, jarvis, …).
125
+ Each named agent uses its own home directory, port, and PID file
126
+ so multiple agents can run simultaneously.
127
+
128
+ Use --foreground for debugging or systemd integration.
129
+ Use --no-consciousness to disable autonomous message processing.
130
+
131
+ Examples:
132
+
133
+ skcapstone daemon start --agent opus
134
+
135
+ skcapstone daemon start --agent jarvis --foreground
136
+ """
137
+ from ..daemon import DaemonConfig, DaemonService, is_running
138
+
139
+ home_path = _resolve_agent_home(agent, home)
140
+ effective_port = _resolve_agent_port(agent, port)
141
+
142
+ if agent:
143
+ # Propagate identity to child imports that read SKCAPSTONE_AGENT.
144
+ os.environ["SKCAPSTONE_AGENT"] = agent
145
+
146
+ if not home_path.exists():
147
+ console.print("[bold red]No agent found.[/] Run skcapstone init first.")
148
+ sys.exit(1)
149
+
150
+ if is_running(home_path):
151
+ console.print("[yellow]Daemon is already running.[/]")
152
+ sys.exit(0)
153
+
154
+ _warn_dev_auth(auto_confirm)
155
+
156
+ config = DaemonConfig(
157
+ home=home_path,
158
+ poll_interval=poll,
159
+ sync_interval=sync_int,
160
+ port=effective_port,
161
+ consciousness_enabled=not no_consciousness,
162
+ )
163
+ svc = DaemonService(config)
164
+
165
+ agent_label = f"[cyan]{agent}[/]" if agent else "[dim]default[/]"
166
+ console.print(f"\n [green]Starting daemon[/] ({agent_label}) on port [cyan]{effective_port}[/]")
167
+ console.print(f" Home: {home_path}")
168
+ console.print(f" Poll: {poll}s | Sync: {sync_int}s")
169
+ consciousness_label = "[red]disabled[/]" if no_consciousness else "[green]enabled[/]"
170
+ console.print(f" Consciousness: {consciousness_label}")
171
+ console.print(f" Log: {config.log_file}")
172
+ console.print(f" PID: {os.getpid()}")
173
+
174
+ if foreground:
175
+ console.print(" [dim]Running in foreground (Ctrl+C to stop)[/]\n")
176
+ svc.start()
177
+ svc.run_forever()
178
+ else:
179
+ console.print(" [dim]Running in foreground mode (use systemd for background)[/]\n")
180
+ svc.start()
181
+ svc.run_forever()
182
+
183
+ @daemon.command("stop")
184
+ @click.option("--agent", default=None, help="Named agent to stop.")
185
+ @click.option("--home", default=AGENT_HOME, type=click.Path())
186
+ def daemon_stop(agent: str | None, home: str):
187
+ """Stop the running daemon."""
188
+ from ..daemon import read_pid
189
+
190
+ home_path = _resolve_agent_home(agent, home)
191
+ pid = read_pid(home_path)
192
+
193
+ if pid is None:
194
+ console.print("[yellow]Daemon is not running.[/]")
195
+ return
196
+
197
+ import signal as sig
198
+
199
+ try:
200
+ os.kill(pid, sig.SIGTERM)
201
+ console.print(f"\n [green]Sent SIGTERM to daemon (PID {pid})[/]\n")
202
+ except ProcessLookupError:
203
+ console.print("[yellow]Daemon process not found — cleaning up PID file.[/]")
204
+ (home_path / "daemon.pid").unlink(missing_ok=True)
205
+
206
+ @daemon.command("status")
207
+ @click.option("--agent", default=None, help="Named agent to query.")
208
+ @click.option("--home", default=AGENT_HOME, type=click.Path())
209
+ @click.option("--port", default=None, type=int, help="API port to query.")
210
+ @click.option("--json-out", is_flag=True, help="Output as JSON.")
211
+ def daemon_status(agent: str | None, home: str, port: int | None, json_out: bool):
212
+ """Show daemon status."""
213
+ from ..daemon import get_daemon_status, is_running, read_pid
214
+
215
+ home_path = _resolve_agent_home(agent, home)
216
+ effective_port = _resolve_agent_port(agent, port)
217
+ pid = read_pid(home_path)
218
+
219
+ if not is_running(home_path):
220
+ if json_out:
221
+ click.echo(json.dumps({"running": False}))
222
+ else:
223
+ console.print("\n [yellow]Daemon is not running.[/]\n")
224
+ return
225
+
226
+ status = get_daemon_status(home_path, effective_port)
227
+ if json_out:
228
+ click.echo(json.dumps(status or {"running": True, "pid": pid, "api": "unreachable"}, indent=2))
229
+ return
230
+
231
+ if status:
232
+ uptime = status.get("uptime_seconds", 0)
233
+ h, remainder = divmod(int(uptime), 3600)
234
+ m, s = divmod(remainder, 60)
235
+ uptime_str = f"{h}h {m}m {s}s" if h else f"{m}m {s}s"
236
+
237
+ console.print()
238
+ console.print(
239
+ Panel(
240
+ f"PID: [bold]{status.get('pid')}[/]\n"
241
+ f"Uptime: [bold]{uptime_str}[/]\n"
242
+ f"Messages received: [bold]{status.get('messages_received', 0)}[/]\n"
243
+ f"Syncs completed: [bold]{status.get('syncs_completed', 0)}[/]\n"
244
+ f"Last poll: {status.get('last_poll') or '[dim]never[/]'}\n"
245
+ f"Last sync: {status.get('last_sync') or '[dim]never[/]'}\n"
246
+ f"API: [green]http://127.0.0.1:{effective_port}[/]",
247
+ title="[green]Daemon Running[/]",
248
+ border_style="green",
249
+ )
250
+ )
251
+
252
+ health = status.get("transport_health", {})
253
+ if health:
254
+ console.print("[bold]Transports:[/]")
255
+ for name, info in health.items():
256
+ if isinstance(info, dict):
257
+ st = info.get("status", "unknown")
258
+ color = {"available": "green", "degraded": "yellow"}.get(st, "red")
259
+ console.print(f" [{color}]{name}: {st.upper()}[/]")
260
+
261
+ errors = status.get("recent_errors", [])
262
+ if errors:
263
+ console.print(f"\n[yellow]Recent errors ({len(errors)}):[/]")
264
+ for err in errors[-5:]:
265
+ console.print(f" [dim]{err}[/]")
266
+
267
+ console.print()
268
+ else:
269
+ console.print(f"\n [green]Daemon running[/] (PID {pid})")
270
+ console.print(f" [yellow]API unreachable on port {effective_port}[/]\n")
271
+
272
+ @daemon.command("install")
273
+ def daemon_install():
274
+ """Install the daemon as a systemd user service.
275
+
276
+ Copies unit files to ~/.config/systemd/user/, enables at login,
277
+ and starts immediately. No root required.
278
+
279
+ Examples:
280
+
281
+ skcapstone daemon install
282
+ """
283
+ from ..systemd import install_service, systemd_available
284
+
285
+ if not systemd_available():
286
+ console.print("[red]systemd user session not available.[/]")
287
+ console.print("[dim]This command requires a Linux system with systemd.[/]")
288
+ raise SystemExit(1)
289
+
290
+ console.print("\n[cyan]Installing skcapstone systemd service...[/]")
291
+ result = install_service()
292
+
293
+ if result["installed"]:
294
+ console.print("[green] Unit files installed.[/]")
295
+ if result["enabled"]:
296
+ console.print("[green] Service enabled at login.[/]")
297
+ if result["started"]:
298
+ console.print("[green] Service started.[/]")
299
+ console.print()
300
+
301
+ if not result["installed"]:
302
+ console.print("[red]Installation failed. Check logs.[/]")
303
+ raise SystemExit(1)
304
+
305
+ @daemon.command("uninstall")
306
+ def daemon_uninstall():
307
+ """Uninstall the systemd user service.
308
+
309
+ Stops, disables, and removes the unit files.
310
+
311
+ Examples:
312
+
313
+ skcapstone daemon uninstall
314
+ """
315
+ from ..systemd import uninstall_service
316
+
317
+ console.print("\n[cyan]Uninstalling skcapstone systemd service...[/]")
318
+ result = uninstall_service()
319
+
320
+ if result["stopped"]:
321
+ console.print("[green] Service stopped.[/]")
322
+ if result["disabled"]:
323
+ console.print("[green] Service disabled.[/]")
324
+ if result["removed"]:
325
+ console.print("[green] Unit files removed.[/]")
326
+ console.print()
327
+
328
+ @daemon.command("components")
329
+ @click.option("--agent", default=None, help="Named agent to query.")
330
+ @click.option("--home", default=AGENT_HOME, type=click.Path())
331
+ @click.option("--port", default=None, type=int, help="API port to query.")
332
+ @click.option("--json-out", is_flag=True, help="Output as JSON.")
333
+ def daemon_components(agent: str | None, home: str, port: int | None, json_out: bool):
334
+ """Show per-component health (alive/dead/restarting).
335
+
336
+ Queries the running daemon for the status of each subsystem:
337
+ poll, health, sync, housekeeping, healing, consciousness,
338
+ scheduler, and heartbeat.
339
+
340
+ Examples:
341
+
342
+ skcapstone daemon components
343
+
344
+ skcapstone daemon components --json-out
345
+ """
346
+ import urllib.error
347
+ import urllib.request
348
+
349
+ home_path = _resolve_agent_home(agent, home)
350
+ effective_port = _resolve_agent_port(agent, port)
351
+
352
+ try:
353
+ url = f"http://127.0.0.1:{effective_port}/api/v1/components"
354
+ with urllib.request.urlopen(url, timeout=5) as resp:
355
+ data = json.loads(resp.read())
356
+ except (urllib.error.URLError, OSError, json.JSONDecodeError) as exc:
357
+ if json_out:
358
+ click.echo(json.dumps({"error": str(exc)}))
359
+ else:
360
+ console.print(f"\n [red]Cannot reach daemon on port {effective_port}.[/]")
361
+ console.print(" [dim]Is the daemon running? Try: skcapstone daemon start[/]\n")
362
+ return
363
+
364
+ if json_out:
365
+ click.echo(json.dumps(data, indent=2))
366
+ return
367
+
368
+ components = data.get("components", {})
369
+ if not components:
370
+ console.print("\n [yellow]No component data returned.[/]\n")
371
+ return
372
+
373
+ from rich.table import Table
374
+
375
+ table = Table(title="Daemon Components", border_style="dim")
376
+ table.add_column("Component", style="cyan", no_wrap=True)
377
+ table.add_column("Status", no_wrap=True)
378
+ table.add_column("Restarts", justify="right")
379
+ table.add_column("Heartbeat age", justify="right")
380
+ table.add_column("Auto-restart", justify="center")
381
+ table.add_column("Last error", style="dim", max_width=40)
382
+
383
+ status_colors = {
384
+ "alive": "green",
385
+ "dead": "red",
386
+ "restarting": "yellow",
387
+ "disabled": "dim",
388
+ "pending": "blue",
389
+ }
390
+
391
+ for name, info in sorted(components.items()):
392
+ status = info.get("status", "unknown")
393
+ color = status_colors.get(status, "white")
394
+ restarts = str(info.get("restart_count", 0))
395
+ age = info.get("heartbeat_age_seconds")
396
+ age_str = f"{age}s" if age is not None else "—"
397
+ auto = "[green]yes[/]" if info.get("auto_restart") else "[dim]no[/]"
398
+ last_error = (info.get("last_error") or "")[:40] or "—"
399
+ table.add_row(
400
+ name,
401
+ f"[{color}]{status}[/]",
402
+ restarts,
403
+ age_str,
404
+ auto,
405
+ last_error,
406
+ )
407
+
408
+ console.print()
409
+ console.print(table)
410
+ console.print()
411
+
412
+ @daemon.command("logs")
413
+ @click.option("--lines", "-n", default=50, help="Number of lines (default: 50).")
414
+ @click.option("--follow", "-f", is_flag=True, help="Show the command to follow logs live.")
415
+ def daemon_logs(lines: int, follow: bool):
416
+ """Show daemon logs from journald.
417
+
418
+ Examples:
419
+
420
+ skcapstone daemon logs
421
+
422
+ skcapstone daemon logs -n 100
423
+
424
+ skcapstone daemon logs -f
425
+ """
426
+ from ..systemd import service_logs
427
+
428
+ if follow:
429
+ cmd = service_logs(follow=True)
430
+ console.print(f"\n Run: [bold cyan]{cmd}[/]\n")
431
+ else:
432
+ output = service_logs(lines=lines)
433
+ if output.strip():
434
+ click.echo(output)
435
+ else:
436
+ console.print("[dim]No logs found. Is the service installed?[/]")