@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,446 @@
1
+ """
2
+ ConnectorBackend — abstract interface for platform connectors.
3
+
4
+ A connector is a viewport into the sovereign agent from an external tool
5
+ (terminal, VS Code, Cursor, Windsurf, etc.). The agent is the truth;
6
+ the platform is just a window.
7
+
8
+ Every connector must implement five lifecycle methods:
9
+ connect() — establish the channel
10
+ disconnect() — clean teardown
11
+ send() — push a message to the platform
12
+ receive() — pull the next incoming message (non-blocking)
13
+ health_check() — return current ConnectorStatus
14
+
15
+ Wire format (Unix domain socket connectors)
16
+ -------------------------------------------
17
+ All Unix socket connectors use the same framed JSON-RPC 2.0 protocol:
18
+
19
+ ┌─────────────────────────────────────────┐
20
+ │ 4-byte big-endian uint32 length (N) │
21
+ │ N bytes of UTF-8 JSON-RPC 2.0 payload │
22
+ └─────────────────────────────────────────┘
23
+
24
+ JSON-RPC 2.0 request example::
25
+
26
+ {"jsonrpc": "2.0", "id": 1, "method": "agent/notify",
27
+ "params": {"type": "status", "payload": {"state": "ready"}}}
28
+
29
+ JSON-RPC 2.0 notification (no "id")::
30
+
31
+ {"jsonrpc": "2.0", "method": "agent/event",
32
+ "params": {"type": "memory_stored", "payload": {...}}}
33
+
34
+ The agent acts as the server: it creates, binds, and listens on the socket.
35
+ The IDE extension connects as a client. Only one client at a time is
36
+ supported; a new connection replaces the previous one.
37
+
38
+ Constants exported for use by subclasses:
39
+ FRAME_FORMAT — struct format string (">I")
40
+ FRAME_HEADER_SIZE — byte size of the length prefix (4)
41
+ """
42
+
43
+ from __future__ import annotations
44
+
45
+ import logging
46
+ import queue
47
+ import socket
48
+ import struct
49
+ import threading
50
+ from abc import ABC, abstractmethod
51
+ from enum import Enum
52
+ from pathlib import Path
53
+ from typing import Any, Dict, Optional
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # Wire-format constants
57
+ # ---------------------------------------------------------------------------
58
+
59
+ FRAME_FORMAT = ">I"
60
+ FRAME_HEADER_SIZE: int = struct.calcsize(FRAME_FORMAT)
61
+ _MAX_FRAME_BYTES = 10 * 1024 * 1024 # 10 MB guard
62
+
63
+ _log = logging.getLogger(__name__)
64
+
65
+
66
+ class ConnectorType(str, Enum):
67
+ """Identifies the platform this connector talks to."""
68
+
69
+ TERMINAL = "terminal"
70
+ VSCODE = "vscode"
71
+ CURSOR = "cursor"
72
+ WINDSURF = "windsurf"
73
+ UNKNOWN = "unknown"
74
+
75
+
76
+ class ConnectorStatus(str, Enum):
77
+ """Operational state of a connector."""
78
+
79
+ CONNECTED = "connected"
80
+ DISCONNECTED = "disconnected"
81
+ ERROR = "error"
82
+ UNAVAILABLE = "unavailable"
83
+
84
+
85
+ class ConnectorInfo:
86
+ """Snapshot of a connector's current state.
87
+
88
+ Args:
89
+ name: Human-readable connector name.
90
+ connector_type: Which platform this connector targets.
91
+ status: Current operational status.
92
+ metadata: Optional extra platform-specific data.
93
+ """
94
+
95
+ __slots__ = ("name", "connector_type", "status", "metadata")
96
+
97
+ def __init__(
98
+ self,
99
+ name: str,
100
+ connector_type: ConnectorType,
101
+ status: ConnectorStatus,
102
+ metadata: Optional[Dict[str, Any]] = None,
103
+ ) -> None:
104
+ self.name = name
105
+ self.connector_type = connector_type
106
+ self.status = status
107
+ self.metadata: Dict[str, Any] = metadata or {}
108
+
109
+ def __repr__(self) -> str: # pragma: no cover
110
+ return (
111
+ f"ConnectorInfo(name={self.name!r}, type={self.connector_type.value}, "
112
+ f"status={self.status.value})"
113
+ )
114
+
115
+
116
+ class ConnectorBackend(ABC):
117
+ """Abstract base for sovereign agent platform connectors.
118
+
119
+ Subclasses implement this interface for each target platform
120
+ (terminal, VS Code, Cursor, …). The agent runtime uses connectors
121
+ to send/receive messages without caring about the underlying channel.
122
+
123
+ Class attributes:
124
+ connector_type: Set by each subclass to identify its platform.
125
+ """
126
+
127
+ connector_type: ConnectorType = ConnectorType.UNKNOWN
128
+
129
+ # ------------------------------------------------------------------
130
+ # Lifecycle
131
+ # ------------------------------------------------------------------
132
+
133
+ @abstractmethod
134
+ def connect(self) -> bool:
135
+ """Establish the platform channel.
136
+
137
+ Returns:
138
+ True if the connection was established successfully.
139
+ """
140
+
141
+ @abstractmethod
142
+ def disconnect(self) -> bool:
143
+ """Tear down the platform channel cleanly.
144
+
145
+ Returns:
146
+ True if disconnection succeeded (or was already disconnected).
147
+ """
148
+
149
+ # ------------------------------------------------------------------
150
+ # Messaging
151
+ # ------------------------------------------------------------------
152
+
153
+ @abstractmethod
154
+ def send(self, message: str) -> bool:
155
+ """Push a message to the connected platform.
156
+
157
+ Args:
158
+ message: UTF-8 text payload to send.
159
+
160
+ Returns:
161
+ True if the message was delivered (or queued) successfully.
162
+ """
163
+
164
+ @abstractmethod
165
+ def receive(self) -> Optional[str]:
166
+ """Pull the next pending message from the platform (non-blocking).
167
+
168
+ Returns:
169
+ Message string if one is available, None otherwise.
170
+ """
171
+
172
+ # ------------------------------------------------------------------
173
+ # Health
174
+ # ------------------------------------------------------------------
175
+
176
+ @abstractmethod
177
+ def health_check(self) -> ConnectorStatus:
178
+ """Return the current operational status of this connector.
179
+
180
+ Returns:
181
+ ConnectorStatus reflecting the channel health.
182
+ """
183
+
184
+ # ------------------------------------------------------------------
185
+ # Convenience
186
+ # ------------------------------------------------------------------
187
+
188
+ def info(self) -> ConnectorInfo:
189
+ """Return a ConnectorInfo snapshot for this connector.
190
+
191
+ Returns:
192
+ ConnectorInfo with current status and metadata.
193
+ """
194
+ return ConnectorInfo(
195
+ name=self.__class__.__name__,
196
+ connector_type=self.connector_type,
197
+ status=self.health_check(),
198
+ )
199
+
200
+
201
+ # ---------------------------------------------------------------------------
202
+ # Shared Unix domain socket server connector
203
+ # ---------------------------------------------------------------------------
204
+
205
+
206
+ class UnixSocketConnector(ConnectorBackend):
207
+ """Server-side Unix domain socket connector with framed JSON-RPC transport.
208
+
209
+ The agent is the **server**: it creates and binds the socket file so the
210
+ IDE extension can connect as a client. The socket directory is created on
211
+ ``connect()``; the socket file is removed on ``disconnect()``.
212
+
213
+ Thread model:
214
+ - An accept-loop daemon thread blocks on ``socket.accept()``.
215
+ - Each accepted client gets a reader daemon thread that enqueues frames.
216
+ - ``send()`` acquires ``_client_lock`` before writing to the live client.
217
+
218
+ Subclasses must set ``connector_type`` and pass the desired ``socket_path``
219
+ to ``super().__init__()``.
220
+
221
+ Args:
222
+ socket_path: Absolute (or ``~``-prefixed) path for the socket file.
223
+ """
224
+
225
+ connector_type: ConnectorType = ConnectorType.UNKNOWN
226
+
227
+ def __init__(self, socket_path: Path) -> None:
228
+ self._socket_path: Path = socket_path.expanduser()
229
+ self._server_sock: Optional[socket.socket] = None
230
+ self._client_conn: Optional[socket.socket] = None
231
+ self._client_lock = threading.Lock()
232
+ self._queue: queue.Queue[str] = queue.Queue()
233
+ self._accept_thread: Optional[threading.Thread] = None
234
+ self._connected = False
235
+ self._error: Optional[str] = None
236
+
237
+ # ------------------------------------------------------------------
238
+ # Lifecycle
239
+ # ------------------------------------------------------------------
240
+
241
+ def connect(self) -> bool:
242
+ """Create the socket directory, bind, listen, and start accept loop.
243
+
244
+ Returns:
245
+ True if the server socket was created successfully.
246
+ """
247
+ if self._connected:
248
+ return True
249
+
250
+ try:
251
+ self._socket_path.parent.mkdir(parents=True, exist_ok=True)
252
+ if self._socket_path.exists():
253
+ self._socket_path.unlink()
254
+
255
+ self._server_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
256
+ self._server_sock.bind(str(self._socket_path))
257
+ self._server_sock.listen(1)
258
+ # Use a timeout so the accept loop can exit cleanly on disconnect.
259
+ self._server_sock.settimeout(1.0)
260
+
261
+ self._connected = True
262
+ self._error = None
263
+
264
+ self._accept_thread = threading.Thread(
265
+ target=self._accept_loop,
266
+ name=f"{self.__class__.__name__}-accept",
267
+ daemon=True,
268
+ )
269
+ self._accept_thread.start()
270
+ _log.info("%s: listening on %s", self.__class__.__name__, self._socket_path)
271
+ return True
272
+
273
+ except OSError as exc:
274
+ self._error = str(exc)
275
+ _log.error("%s: connect() failed: %s", self.__class__.__name__, exc)
276
+ return False
277
+
278
+ def disconnect(self) -> bool:
279
+ """Close the server socket, drop the client connection, and remove the socket file.
280
+
281
+ Returns:
282
+ True always (errors during teardown are logged and swallowed).
283
+ """
284
+ self._connected = False
285
+
286
+ with self._client_lock:
287
+ if self._client_conn is not None:
288
+ try:
289
+ self._client_conn.close()
290
+ except OSError:
291
+ pass
292
+ self._client_conn = None
293
+
294
+ if self._server_sock is not None:
295
+ try:
296
+ self._server_sock.close()
297
+ except OSError:
298
+ pass
299
+ self._server_sock = None
300
+
301
+ try:
302
+ if self._socket_path.exists():
303
+ self._socket_path.unlink()
304
+ except OSError:
305
+ pass
306
+
307
+ return True
308
+
309
+ # ------------------------------------------------------------------
310
+ # Messaging
311
+ # ------------------------------------------------------------------
312
+
313
+ def send(self, message: str) -> bool:
314
+ """Write a framed JSON-RPC message to the connected client.
315
+
316
+ Frame layout: 4-byte big-endian uint32 length + UTF-8 payload.
317
+
318
+ Args:
319
+ message: UTF-8 JSON string to send.
320
+
321
+ Returns:
322
+ True if delivered; False if no client is connected or I/O failed.
323
+ """
324
+ with self._client_lock:
325
+ if self._client_conn is None:
326
+ return False
327
+ try:
328
+ payload = message.encode("utf-8")
329
+ header = struct.pack(FRAME_FORMAT, len(payload))
330
+ self._client_conn.sendall(header + payload)
331
+ return True
332
+ except OSError as exc:
333
+ _log.warning("%s: send failed: %s", self.__class__.__name__, exc)
334
+ self._error = str(exc)
335
+ self._client_conn = None
336
+ return False
337
+
338
+ def receive(self) -> Optional[str]:
339
+ """Return the next queued message from the client (non-blocking).
340
+
341
+ Returns:
342
+ JSON string if one is available, None if the queue is empty.
343
+ """
344
+ try:
345
+ return self._queue.get_nowait()
346
+ except queue.Empty:
347
+ return None
348
+
349
+ # ------------------------------------------------------------------
350
+ # Health
351
+ # ------------------------------------------------------------------
352
+
353
+ def health_check(self) -> ConnectorStatus:
354
+ """Return the current connector status.
355
+
356
+ Returns:
357
+ CONNECTED when a client is live, DISCONNECTED when the server is
358
+ bound but idle, ERROR on any socket failure, or UNAVAILABLE if
359
+ ``connect()`` was never called.
360
+ """
361
+ if self._error:
362
+ return ConnectorStatus.ERROR
363
+ if not self._connected:
364
+ return ConnectorStatus.DISCONNECTED
365
+ with self._client_lock:
366
+ if self._client_conn is not None:
367
+ return ConnectorStatus.CONNECTED
368
+ return ConnectorStatus.DISCONNECTED
369
+
370
+ # ------------------------------------------------------------------
371
+ # Internal threads
372
+ # ------------------------------------------------------------------
373
+
374
+ def _accept_loop(self) -> None:
375
+ """Daemon thread: accept incoming client connections."""
376
+ while self._connected and self._server_sock is not None:
377
+ try:
378
+ conn, _ = self._server_sock.accept()
379
+ _log.info("%s: client connected", self.__class__.__name__)
380
+ with self._client_lock:
381
+ if self._client_conn is not None:
382
+ try:
383
+ self._client_conn.close()
384
+ except OSError:
385
+ pass
386
+ self._client_conn = conn
387
+ threading.Thread(
388
+ target=self._read_loop,
389
+ args=(conn,),
390
+ name=f"{self.__class__.__name__}-reader",
391
+ daemon=True,
392
+ ).start()
393
+ except socket.timeout:
394
+ continue
395
+ except OSError as exc:
396
+ if self._connected:
397
+ self._error = str(exc)
398
+ _log.error("%s: accept error: %s", self.__class__.__name__, exc)
399
+ break
400
+
401
+ def _read_loop(self, conn: socket.socket) -> None:
402
+ """Daemon thread: read framed messages from a client connection."""
403
+ try:
404
+ while self._connected:
405
+ header_data = _recv_exactly(conn, FRAME_HEADER_SIZE)
406
+ if header_data is None:
407
+ break
408
+ (length,) = struct.unpack(FRAME_FORMAT, header_data)
409
+ if length == 0 or length > _MAX_FRAME_BYTES:
410
+ _log.warning(
411
+ "%s: invalid frame length %d — dropping connection",
412
+ self.__class__.__name__,
413
+ length,
414
+ )
415
+ break
416
+ payload_data = _recv_exactly(conn, length)
417
+ if payload_data is None:
418
+ break
419
+ self._queue.put(payload_data.decode("utf-8"))
420
+ except OSError as exc:
421
+ _log.debug("%s: read loop ended: %s", self.__class__.__name__, exc)
422
+ finally:
423
+ with self._client_lock:
424
+ if self._client_conn is conn:
425
+ self._client_conn = None
426
+ try:
427
+ conn.close()
428
+ except OSError:
429
+ pass
430
+ _log.info("%s: client disconnected", self.__class__.__name__)
431
+
432
+
433
+ # ---------------------------------------------------------------------------
434
+ # Module-private helpers
435
+ # ---------------------------------------------------------------------------
436
+
437
+
438
+ def _recv_exactly(conn: socket.socket, n: int) -> Optional[bytes]:
439
+ """Read exactly *n* bytes from *conn*, returning None on EOF."""
440
+ buf = bytearray()
441
+ while len(buf) < n:
442
+ chunk = conn.recv(n - len(buf))
443
+ if not chunk:
444
+ return None
445
+ buf.extend(chunk)
446
+ return bytes(buf)
@@ -0,0 +1,54 @@
1
+ """
2
+ CursorConnector — sovereign agent viewport into the Cursor editor.
3
+
4
+ Cursor is an Electron-based VS Code fork. The connector follows the same
5
+ Unix domain socket protocol as :class:`VSCodeConnector`: the agent binds
6
+ ``~/.skcapstone/connectors/cursor.sock`` and the Cursor extension connects.
7
+
8
+ Protocol
9
+ --------
10
+ Wire format: 4-byte big-endian uint32 length prefix + UTF-8 JSON-RPC 2.0 body.
11
+ See :class:`~skcapstone.connectors.base.UnixSocketConnector` for details.
12
+
13
+ Extension contract:
14
+ - Extension connects to ``~/.skcapstone/connectors/cursor.sock``.
15
+ - Both sides exchange length-framed JSON-RPC 2.0 messages.
16
+ - Notifications (no ``"id"`` field) are fire-and-forget.
17
+ - Requests carry an ``"id"`` and expect a matching ``"result"`` response.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from pathlib import Path
23
+ from typing import Optional
24
+
25
+ from .base import ConnectorStatus, ConnectorType, UnixSocketConnector
26
+
27
+ _DEFAULT_SOCKET_PATH = Path("~/.skcapstone/connectors/cursor.sock")
28
+
29
+
30
+ class CursorConnector(UnixSocketConnector):
31
+ """Connect the sovereign agent to the Cursor editor.
32
+
33
+ Binds a Unix domain socket at ``~/.skcapstone/connectors/cursor.sock``
34
+ and waits for the SKCapstone Cursor extension to connect.
35
+
36
+ Args:
37
+ socket_path: Override the default socket file location.
38
+ """
39
+
40
+ connector_type = ConnectorType.CURSOR
41
+
42
+ def __init__(self, socket_path: Optional[Path] = None) -> None:
43
+ super().__init__(socket_path or _DEFAULT_SOCKET_PATH)
44
+
45
+ def health_check(self) -> ConnectorStatus:
46
+ """Return the current connector status.
47
+
48
+ Returns UNAVAILABLE when neither connected nor the socket dir exists,
49
+ so callers can tell whether the extension has ever been set up.
50
+ """
51
+ status = super().health_check()
52
+ if status == ConnectorStatus.DISCONNECTED and not self._socket_path.parent.exists():
53
+ return ConnectorStatus.UNAVAILABLE
54
+ return status