@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,522 @@
1
+ """
2
+ Team Deployment Engine — provider-agnostic orchestration.
3
+
4
+ Takes a BlueprintManifest and deploys it to the target infrastructure.
5
+ The engine doesn't care whether agents land on local processes, Proxmox
6
+ LXCs, Hetzner VMs, AWS, GCP, or Docker containers. Each provider
7
+ implements the same interface; the engine orchestrates the workflow.
8
+
9
+ Architecture follows best practices from:
10
+ - multi-agent-patterns: context isolation, supervisor coordination
11
+ - hosted-agents: pre-built images, warm pools, snapshot/restore
12
+ - memory-systems: filesystem-first, upgrade path to vector/graph
13
+
14
+ Deployment flow:
15
+ 1. Validate blueprint + resolve dependencies
16
+ 2. Provision infrastructure (provider-specific)
17
+ 3. Configure each agent (soul, skills, memory, network)
18
+ 4. Register in vault registry (skref)
19
+ 5. Start health monitoring
20
+ 6. Hand off to coordination layer (queen)
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import json
26
+ import logging
27
+ import time
28
+ from abc import ABC, abstractmethod
29
+ from datetime import datetime, timezone
30
+ from enum import Enum
31
+ from pathlib import Path
32
+ from typing import Any, Dict, List, Optional
33
+
34
+ from pydantic import BaseModel, Field
35
+
36
+ from .blueprints.schema import AgentRole, AgentSpec, BlueprintManifest, ProviderType
37
+ from .team_comms import TeamChannel, bootstrap_team_channel
38
+
39
+ logger = logging.getLogger(__name__)
40
+
41
+
42
+ # ---------------------------------------------------------------------------
43
+ # Deployment state
44
+ # ---------------------------------------------------------------------------
45
+
46
+ class AgentStatus(str, Enum):
47
+ """Runtime status of a deployed agent."""
48
+
49
+ PENDING = "pending"
50
+ PROVISIONING = "provisioning"
51
+ CONFIGURING = "configuring"
52
+ RUNNING = "running"
53
+ DEGRADED = "degraded"
54
+ STOPPED = "stopped"
55
+ FAILED = "failed"
56
+
57
+
58
+ class DeployedAgent(BaseModel):
59
+ """Runtime state of a single deployed agent instance."""
60
+
61
+ name: str
62
+ instance_id: str
63
+ blueprint_slug: str
64
+ agent_spec_key: str
65
+ status: AgentStatus = AgentStatus.PENDING
66
+ provider: ProviderType = ProviderType.LOCAL
67
+ host: Optional[str] = None
68
+ port: Optional[int] = None
69
+ pid: Optional[int] = None
70
+ container_id: Optional[str] = None
71
+ started_at: Optional[str] = None
72
+ last_heartbeat: Optional[str] = None
73
+ error: Optional[str] = None
74
+
75
+
76
+ class TeamDeployment(BaseModel):
77
+ """Full state of a deployed team."""
78
+
79
+ deployment_id: str
80
+ blueprint_slug: str
81
+ team_name: str
82
+ provider: ProviderType
83
+ agents: Dict[str, DeployedAgent] = Field(default_factory=dict)
84
+ created_at: str = Field(
85
+ default_factory=lambda: datetime.now(timezone.utc).isoformat()
86
+ )
87
+ status: str = "deploying"
88
+ comms_channel: Optional[Any] = Field(
89
+ default=None,
90
+ exclude=True,
91
+ description="In-memory TeamChannel; not persisted to disk.",
92
+ )
93
+
94
+
95
+ # ---------------------------------------------------------------------------
96
+ # Provider interface (abstract base)
97
+ # ---------------------------------------------------------------------------
98
+
99
+ class ProviderBackend(ABC):
100
+ """Abstract base for infrastructure providers.
101
+
102
+ Each provider (local, proxmox, hetzner, aws, gcp, docker) implements
103
+ these methods. The engine calls them in sequence during deployment.
104
+ """
105
+
106
+ provider_type: ProviderType = ProviderType.LOCAL
107
+
108
+ @abstractmethod
109
+ def provision(
110
+ self,
111
+ agent_name: str,
112
+ spec: AgentSpec,
113
+ team_name: str,
114
+ ) -> Dict[str, Any]:
115
+ """Provision infrastructure for one agent.
116
+
117
+ Args:
118
+ agent_name: Unique name for this agent instance.
119
+ spec: The agent specification from the blueprint.
120
+ team_name: The team this agent belongs to.
121
+
122
+ Returns:
123
+ Dict with provider-specific details (host, port, pid, container_id, etc.)
124
+ """
125
+
126
+ @abstractmethod
127
+ def configure(
128
+ self,
129
+ agent_name: str,
130
+ spec: AgentSpec,
131
+ provision_result: Dict[str, Any],
132
+ ) -> bool:
133
+ """Configure an agent after provisioning (soul, skills, memory).
134
+
135
+ Args:
136
+ agent_name: The agent instance name.
137
+ spec: The agent specification.
138
+ provision_result: Output from provision().
139
+
140
+ Returns:
141
+ True if configuration succeeded.
142
+ """
143
+
144
+ @abstractmethod
145
+ def start(self, agent_name: str, provision_result: Dict[str, Any]) -> bool:
146
+ """Start the agent process/container.
147
+
148
+ Args:
149
+ agent_name: The agent instance name.
150
+ provision_result: Output from provision().
151
+
152
+ Returns:
153
+ True if the agent started successfully.
154
+ """
155
+
156
+ @abstractmethod
157
+ def stop(self, agent_name: str, provision_result: Dict[str, Any]) -> bool:
158
+ """Stop a running agent.
159
+
160
+ Args:
161
+ agent_name: The agent instance name.
162
+ provision_result: Output from provision().
163
+
164
+ Returns:
165
+ True if the agent stopped successfully.
166
+ """
167
+
168
+ @abstractmethod
169
+ def destroy(self, agent_name: str, provision_result: Dict[str, Any]) -> bool:
170
+ """Destroy agent infrastructure entirely.
171
+
172
+ Args:
173
+ agent_name: The agent instance name.
174
+ provision_result: Output from provision().
175
+
176
+ Returns:
177
+ True if destruction succeeded.
178
+ """
179
+
180
+ @abstractmethod
181
+ def health_check(self, agent_name: str, provision_result: Dict[str, Any]) -> AgentStatus:
182
+ """Check the health of a deployed agent.
183
+
184
+ Args:
185
+ agent_name: The agent instance name.
186
+ provision_result: Output from provision().
187
+
188
+ Returns:
189
+ Current AgentStatus.
190
+ """
191
+
192
+
193
+ # ---------------------------------------------------------------------------
194
+ # Deployment engine
195
+ # ---------------------------------------------------------------------------
196
+
197
+ class TeamEngine:
198
+ """Orchestrates team deployment across any provider.
199
+
200
+ Args:
201
+ home: Agent home directory.
202
+ provider: The backend to deploy to.
203
+ comms_root: Root directory for team comms channels. Defaults to
204
+ ``<home>/comms``. Pass ``None`` to disable comms bootstrapping.
205
+ """
206
+
207
+ def __init__(
208
+ self,
209
+ home: Optional[Path] = None,
210
+ provider: Optional[ProviderBackend] = None,
211
+ comms_root: Optional[Path] = None,
212
+ ) -> None:
213
+ self._home = (home or Path("~/.skcapstone")).expanduser()
214
+ self._provider = provider
215
+ self._deployments_dir = self._home / "deployments"
216
+ self._deployments_dir.mkdir(parents=True, exist_ok=True)
217
+ # Reason: allow callers to disable comms by passing comms_root=None explicitly
218
+ self._comms_root: Optional[Path] = (
219
+ comms_root if comms_root is not None else self._home / "comms"
220
+ )
221
+
222
+ # ------------------------------------------------------------------
223
+ # Dependency resolution
224
+ # ------------------------------------------------------------------
225
+
226
+ @staticmethod
227
+ def resolve_deploy_order(blueprint: BlueprintManifest) -> List[List[str]]:
228
+ """Topological sort of agents by depends_on.
229
+
230
+ Returns a list of "waves" — agents in the same wave can deploy
231
+ in parallel; each wave must complete before the next starts.
232
+
233
+ Args:
234
+ blueprint: The team blueprint.
235
+
236
+ Returns:
237
+ List of waves, each wave is a list of agent keys.
238
+
239
+ Raises:
240
+ ValueError: If circular dependencies are detected.
241
+ """
242
+ agent_keys = set(blueprint.agents.keys())
243
+ remaining = dict(blueprint.agents)
244
+ waves: List[List[str]] = []
245
+ resolved: set = set()
246
+
247
+ max_iterations = len(agent_keys) + 1
248
+ iteration = 0
249
+
250
+ while remaining:
251
+ iteration += 1
252
+ if iteration > max_iterations:
253
+ unresolved = list(remaining.keys())
254
+ raise ValueError(
255
+ f"Circular dependency detected among: {unresolved}"
256
+ )
257
+
258
+ wave = []
259
+ for key, spec in list(remaining.items()):
260
+ deps = set(spec.depends_on) & agent_keys
261
+ if deps <= resolved:
262
+ wave.append(key)
263
+
264
+ if not wave:
265
+ unresolved = list(remaining.keys())
266
+ raise ValueError(
267
+ f"Unresolvable dependencies for: {unresolved}"
268
+ )
269
+
270
+ for key in wave:
271
+ del remaining[key]
272
+ resolved.add(key)
273
+
274
+ waves.append(wave)
275
+
276
+ return waves
277
+
278
+ # ------------------------------------------------------------------
279
+ # Deployment
280
+ # ------------------------------------------------------------------
281
+
282
+ def deploy(
283
+ self,
284
+ blueprint: BlueprintManifest,
285
+ name: Optional[str] = None,
286
+ provider_override: Optional[ProviderType] = None,
287
+ ) -> TeamDeployment:
288
+ """Deploy a team from a blueprint.
289
+
290
+ Args:
291
+ blueprint: The validated blueprint manifest.
292
+ name: Optional custom deployment name.
293
+ provider_override: Override the blueprint's default provider.
294
+
295
+ Returns:
296
+ TeamDeployment with the full state of all agents.
297
+ """
298
+ deployment_id = f"{blueprint.slug}-{int(time.time())}"
299
+ team_name = name or blueprint.name
300
+ provider_type = provider_override or blueprint.default_provider
301
+
302
+ deployment = TeamDeployment(
303
+ deployment_id=deployment_id,
304
+ blueprint_slug=blueprint.slug,
305
+ team_name=team_name,
306
+ provider=provider_type,
307
+ )
308
+
309
+ waves = self.resolve_deploy_order(blueprint)
310
+ logger.info(
311
+ "Deploying %s: %d agents in %d waves",
312
+ team_name, blueprint.agent_count, len(waves),
313
+ )
314
+
315
+ for wave_idx, wave in enumerate(waves):
316
+ logger.info("Wave %d: %s", wave_idx + 1, wave)
317
+
318
+ for agent_key in wave:
319
+ spec = blueprint.agents[agent_key]
320
+ for instance_num in range(spec.count):
321
+ suffix = f"-{instance_num + 1}" if spec.count > 1 else ""
322
+ instance_name = f"{blueprint.slug}-{agent_key}{suffix}"
323
+
324
+ deployed = DeployedAgent(
325
+ name=instance_name,
326
+ instance_id=f"{deployment_id}/{instance_name}",
327
+ blueprint_slug=blueprint.slug,
328
+ agent_spec_key=agent_key,
329
+ provider=provider_type,
330
+ status=AgentStatus.PROVISIONING,
331
+ )
332
+
333
+ if self._provider:
334
+ try:
335
+ result = self._provider.provision(
336
+ instance_name, spec, team_name,
337
+ )
338
+ deployed.host = result.get("host")
339
+ deployed.port = result.get("port")
340
+ deployed.pid = result.get("pid")
341
+ deployed.container_id = result.get("container_id")
342
+
343
+ deployed.status = AgentStatus.CONFIGURING
344
+ self._provider.configure(instance_name, spec, result)
345
+
346
+ deployed.status = AgentStatus.RUNNING
347
+ self._provider.start(instance_name, result)
348
+ deployed.started_at = datetime.now(
349
+ timezone.utc
350
+ ).isoformat()
351
+ deployed.last_heartbeat = deployed.started_at
352
+
353
+ except Exception as exc:
354
+ deployed.status = AgentStatus.FAILED
355
+ deployed.error = str(exc)
356
+ logger.error(
357
+ "Failed to deploy %s: %s", instance_name, exc
358
+ )
359
+ else:
360
+ # Dry-run mode: no provider, just record the plan
361
+ deployed.status = AgentStatus.PENDING
362
+ deployed.host = "localhost"
363
+
364
+ deployment.agents[instance_name] = deployed
365
+
366
+ deployment.status = (
367
+ "running"
368
+ if all(
369
+ a.status == AgentStatus.RUNNING or a.status == AgentStatus.PENDING
370
+ for a in deployment.agents.values()
371
+ )
372
+ else "degraded"
373
+ )
374
+
375
+ self._save_deployment(deployment)
376
+
377
+ if self._comms_root is not None:
378
+ deployment.comms_channel = self._bootstrap_comms(
379
+ deployment, blueprint
380
+ )
381
+
382
+ return deployment
383
+
384
+ # ------------------------------------------------------------------
385
+ # Status / management
386
+ # ------------------------------------------------------------------
387
+
388
+ def list_deployments(self) -> List[TeamDeployment]:
389
+ """List all saved deployments.
390
+
391
+ Returns:
392
+ List of TeamDeployment objects.
393
+ """
394
+ deployments = []
395
+ for f in sorted(self._deployments_dir.glob("*.json")):
396
+ try:
397
+ data = json.loads(f.read_text(encoding="utf-8"))
398
+ deployments.append(TeamDeployment(**data))
399
+ except Exception as exc:
400
+ logger.warning("Skipping %s: %s", f, exc)
401
+ return deployments
402
+
403
+ def get_deployment(self, deployment_id: str) -> Optional[TeamDeployment]:
404
+ """Load a specific deployment by ID.
405
+
406
+ Args:
407
+ deployment_id: The deployment identifier.
408
+
409
+ Returns:
410
+ TeamDeployment or None.
411
+ """
412
+ path = self._deployments_dir / f"{deployment_id}.json"
413
+ if not path.exists():
414
+ return None
415
+ data = json.loads(path.read_text(encoding="utf-8"))
416
+ return TeamDeployment(**data)
417
+
418
+ def destroy_deployment(self, deployment_id: str) -> bool:
419
+ """Destroy all agents in a deployment and remove state.
420
+
421
+ Args:
422
+ deployment_id: The deployment to destroy.
423
+
424
+ Returns:
425
+ True if all agents were destroyed.
426
+ """
427
+ deployment = self.get_deployment(deployment_id)
428
+ if not deployment:
429
+ return False
430
+
431
+ all_ok = True
432
+ if self._provider:
433
+ for agent in deployment.agents.values():
434
+ try:
435
+ self._provider.destroy(
436
+ agent.name,
437
+ {"host": agent.host, "pid": agent.pid,
438
+ "container_id": agent.container_id},
439
+ )
440
+ except Exception as exc:
441
+ logger.error("Failed to destroy %s: %s", agent.name, exc)
442
+ all_ok = False
443
+
444
+ path = self._deployments_dir / f"{deployment_id}.json"
445
+ if path.exists():
446
+ path.unlink()
447
+
448
+ return all_ok
449
+
450
+ # ------------------------------------------------------------------
451
+ # Persistence
452
+ # ------------------------------------------------------------------
453
+
454
+ def _save_deployment(self, deployment: TeamDeployment) -> Path:
455
+ """Save deployment state to disk.
456
+
457
+ Args:
458
+ deployment: The deployment to persist.
459
+
460
+ Returns:
461
+ Path to the saved JSON file.
462
+ """
463
+ path = self._deployments_dir / f"{deployment.deployment_id}.json"
464
+ path.write_text(
465
+ json.dumps(deployment.model_dump(mode="json"), indent=2),
466
+ encoding="utf-8",
467
+ )
468
+ return path
469
+
470
+ def _bootstrap_comms(
471
+ self,
472
+ deployment: TeamDeployment,
473
+ blueprint: BlueprintManifest,
474
+ ) -> TeamChannel:
475
+ """Bootstrap SKComm file channel for all agents in a deployment.
476
+
477
+ Identifies the queen agent from the blueprint's coordination config
478
+ (falling back to any agent with role=manager) and provisions per-agent
479
+ inboxes plus a broadcast directory.
480
+
481
+ Args:
482
+ deployment: The freshly created TeamDeployment.
483
+ blueprint: The blueprint manifest used for this deployment.
484
+
485
+ Returns:
486
+ TeamChannel: The configured comms channel.
487
+ """
488
+ agent_names = list(deployment.agents.keys())
489
+
490
+ # Determine the queen: prefer coordination config, then role=manager
491
+ queen: Optional[str] = None
492
+ configured_queen = blueprint.coordination.queen
493
+ if configured_queen:
494
+ # Find the deployed instance that matches this spec key
495
+ for inst_name in agent_names:
496
+ agent = deployment.agents[inst_name]
497
+ if agent.agent_spec_key == configured_queen:
498
+ queen = inst_name
499
+ break
500
+
501
+ if queen is None:
502
+ for inst_name in agent_names:
503
+ agent = deployment.agents[inst_name]
504
+ spec = blueprint.agents.get(agent.agent_spec_key)
505
+ if spec and spec.role == AgentRole.MANAGER:
506
+ queen = inst_name
507
+ break
508
+
509
+ assert self._comms_root is not None # guarded by caller
510
+ channel = bootstrap_team_channel(
511
+ team_slug=deployment.deployment_id,
512
+ agent_names=agent_names,
513
+ comms_root=self._comms_root,
514
+ queen=queen,
515
+ )
516
+
517
+ logger.info(
518
+ "Comms channel ready for deployment '%s' (queen=%s)",
519
+ deployment.deployment_id,
520
+ queen or "none",
521
+ )
522
+ return channel