@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,143 @@
1
+ """
2
+ KMS Auto-Rotation Scheduler.
3
+
4
+ Background daemon thread that checks daily for KMS keys whose
5
+ ``next_rotation_at`` timestamp is in the past and rotates them
6
+ automatically.
7
+
8
+ Rotation policy (stored in key metadata):
9
+ service keys — every 30 days
10
+ team keys — every 90 days
11
+
12
+ On each rotation the scheduler:
13
+ 1. Calls ``KeyStore.rotate_key`` with reason='scheduled-auto-rotation'
14
+ 2. Sends a desktop notification via notify-send (best-effort)
15
+ 3. Stores a memory entry tagged ``key-rotation`` in the agent memory
16
+
17
+ The scheduler thread is a daemon thread and exits when the MCP server
18
+ process terminates. Call ``start()`` once from ``mcp_server._run_server()``.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import logging
24
+ import subprocess
25
+ import threading
26
+ from pathlib import Path
27
+
28
+ logger = logging.getLogger("skcapstone.kms_scheduler")
29
+
30
+ # How often to check for due keys (86400 s = 24 h).
31
+ _CHECK_INTERVAL = 86_400
32
+
33
+
34
+ class KMSRotationScheduler:
35
+ """Daemon thread that auto-rotates KMS service/team keys on schedule.
36
+
37
+ Args:
38
+ home: Agent home directory (~/.skcapstone).
39
+ """
40
+
41
+ def __init__(self, home: Path) -> None:
42
+ self._home = home
43
+ self._thread: threading.Thread | None = None
44
+ self._stop_event = threading.Event()
45
+
46
+ def start(self) -> None:
47
+ """Start the scheduler background thread (idempotent)."""
48
+ if self._thread and self._thread.is_alive():
49
+ return
50
+ self._stop_event.clear()
51
+ self._thread = threading.Thread(
52
+ target=self._loop,
53
+ name="kms-rotation-scheduler",
54
+ daemon=True,
55
+ )
56
+ self._thread.start()
57
+ logger.info("KMS rotation scheduler started (check interval: %ds)", _CHECK_INTERVAL)
58
+
59
+ def stop(self) -> None:
60
+ """Signal the scheduler to stop after the current sleep."""
61
+ self._stop_event.set()
62
+
63
+ # ------------------------------------------------------------------
64
+ # Internal
65
+ # ------------------------------------------------------------------
66
+
67
+ def _loop(self) -> None:
68
+ """Main scheduler loop — runs until stop() is called."""
69
+ while not self._stop_event.is_set():
70
+ try:
71
+ self._check_and_rotate()
72
+ except Exception:
73
+ logger.exception("Unhandled error during KMS rotation check")
74
+ # Sleep for the check interval, but wake immediately if stopped.
75
+ self._stop_event.wait(timeout=_CHECK_INTERVAL)
76
+
77
+ def _check_and_rotate(self) -> None:
78
+ """Rotate all keys whose next_rotation_at is in the past."""
79
+ from .kms import KeyStore
80
+
81
+ store = KeyStore(self._home)
82
+ store.initialize()
83
+
84
+ due = store.get_due_for_rotation()
85
+ if not due:
86
+ logger.debug("KMS rotation check: no keys due")
87
+ return
88
+
89
+ logger.info("KMS rotation check: %d key(s) due for rotation", len(due))
90
+ for key in due:
91
+ try:
92
+ new_key = store.rotate_key(key.key_id, reason="scheduled-auto-rotation")
93
+ logger.info(
94
+ "Auto-rotated %s key '%s' → v%d",
95
+ key.key_type.value,
96
+ key.label,
97
+ new_key.version,
98
+ )
99
+ self._send_notification(key.label, key.key_type.value, new_key.version)
100
+ self._store_memory(key.label, key.key_type.value, new_key.version)
101
+ except Exception:
102
+ logger.exception(
103
+ "Failed to auto-rotate key '%s' (%s)", key.label, key.key_id
104
+ )
105
+
106
+ def _send_notification(self, label: str, key_type: str, new_version: int) -> None:
107
+ """Send a desktop notification (best-effort, never raises)."""
108
+ try:
109
+ subprocess.run(
110
+ [
111
+ "notify-send",
112
+ "--urgency", "normal",
113
+ "KMS Key Auto-Rotated",
114
+ f"{key_type} key '{label}' rotated to v{new_version}",
115
+ ],
116
+ check=False,
117
+ timeout=5,
118
+ capture_output=True,
119
+ )
120
+ except Exception:
121
+ pass # Notification failure must never interrupt rotation
122
+
123
+ def _store_memory(self, label: str, key_type: str, new_version: int) -> None:
124
+ """Persist a memory entry tagged key-rotation (best-effort)."""
125
+ try:
126
+ from .memory_engine import store as memory_store
127
+
128
+ content = (
129
+ f"KMS auto-rotation: {key_type} key '{label}' rotated to "
130
+ f"v{new_version} via scheduled rotation policy "
131
+ f"({30 if key_type == 'service' else 90}-day interval)."
132
+ )
133
+ memory_store(
134
+ home=self._home,
135
+ content=content,
136
+ tags=["key-rotation", "kms", "security"],
137
+ source="kms-scheduler",
138
+ importance=0.6,
139
+ )
140
+ except Exception:
141
+ logger.warning(
142
+ "Failed to store key-rotation memory for '%s'", label, exc_info=True
143
+ )
@@ -0,0 +1,135 @@
1
+ """Structured JSON logging with rotation for the skcapstone daemon."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ import logging.handlers
8
+ from datetime import datetime, timezone
9
+ from pathlib import Path
10
+
11
+ # Attributes present on every LogRecord — excluded from JSON extra-field pass-through.
12
+ _LOG_RECORD_BUILTIN_ATTRS: frozenset[str] = frozenset(
13
+ {
14
+ "args",
15
+ "created",
16
+ "exc_info",
17
+ "exc_text",
18
+ "filename",
19
+ "funcName",
20
+ "levelname",
21
+ "levelno",
22
+ "lineno",
23
+ "message",
24
+ "module",
25
+ "msecs",
26
+ "msg",
27
+ "name",
28
+ "pathname",
29
+ "process",
30
+ "processName",
31
+ "relativeCreated",
32
+ "stack_info",
33
+ "thread",
34
+ "threadName",
35
+ "taskName",
36
+ }
37
+ )
38
+
39
+ # Module-level guard so configure_logging() is idempotent.
40
+ _CONFIGURED: bool = False
41
+
42
+
43
+ class JsonFormatter(logging.Formatter):
44
+ """Format log records as single-line JSON objects.
45
+
46
+ Mandatory fields in every record:
47
+
48
+ - ``ts`` — ISO-8601 UTC timestamp
49
+ - ``level`` — log level name (e.g. ``"INFO"``)
50
+ - ``logger`` — logger name
51
+ - ``msg`` — rendered log message
52
+
53
+ Optional fields appended when present:
54
+
55
+ - ``exc`` — formatted exception traceback
56
+ - ``stack`` — formatted stack info
57
+ - any ``extra=`` keys passed to the logger call
58
+ """
59
+
60
+ def format(self, record: logging.LogRecord) -> str: # noqa: A003
61
+ entry: dict = {
62
+ "ts": datetime.fromtimestamp(record.created, tz=timezone.utc).isoformat(),
63
+ "level": record.levelname,
64
+ "logger": record.name,
65
+ "msg": record.getMessage(),
66
+ }
67
+ if record.exc_info:
68
+ entry["exc"] = self.formatException(record.exc_info)
69
+ if record.stack_info:
70
+ entry["stack"] = self.formatStack(record.stack_info)
71
+ # Merge any extra fields injected via `extra={...}` on the log call.
72
+ for key, val in record.__dict__.items():
73
+ if key not in _LOG_RECORD_BUILTIN_ATTRS and not key.startswith("_"):
74
+ entry[key] = val
75
+ return json.dumps(entry, default=str)
76
+
77
+
78
+ def configure_logging(
79
+ log_file: "Path | str",
80
+ *,
81
+ file_level: int = logging.DEBUG,
82
+ console_level: int = logging.INFO,
83
+ max_bytes: int = 10 * 1024 * 1024,
84
+ backup_count: int = 5,
85
+ ) -> None:
86
+ """Configure structured JSON logging for the daemon.
87
+
88
+ Sets up two handlers on the root logger:
89
+
90
+ - **RotatingFileHandler** — writes JSON lines to *log_file*
91
+ (rotates at *max_bytes*, keeps *backup_count* backups).
92
+ - **StreamHandler** — writes human-readable lines to stderr
93
+ at *console_level* (default ``INFO``).
94
+
95
+ This function is idempotent: subsequent calls are no-ops.
96
+
97
+ Args:
98
+ log_file: Path to the daemon log file.
99
+ The parent directory is created automatically.
100
+ file_level: Minimum level for the file handler (default ``DEBUG``).
101
+ console_level: Minimum level for the console handler (default ``INFO``).
102
+ max_bytes: Maximum file size before rotation (default 10 MiB).
103
+ backup_count: Number of rotated backup files to retain (default 5).
104
+ """
105
+ global _CONFIGURED
106
+ if _CONFIGURED:
107
+ return
108
+
109
+ log_path = Path(log_file).expanduser()
110
+ log_path.parent.mkdir(parents=True, exist_ok=True)
111
+
112
+ root = logging.getLogger()
113
+ root.setLevel(logging.DEBUG) # handlers filter independently
114
+
115
+ # Rotating JSON file handler
116
+ file_handler = logging.handlers.RotatingFileHandler(
117
+ log_path,
118
+ maxBytes=max_bytes,
119
+ backupCount=backup_count,
120
+ encoding="utf-8",
121
+ )
122
+ file_handler.setLevel(file_level)
123
+ file_handler.setFormatter(JsonFormatter())
124
+
125
+ # Human-readable console handler
126
+ console_handler = logging.StreamHandler()
127
+ console_handler.setLevel(console_level)
128
+ console_handler.setFormatter(
129
+ logging.Formatter("%(asctime)s [%(name)s] %(levelname)s: %(message)s")
130
+ )
131
+
132
+ root.addHandler(file_handler)
133
+ root.addHandler(console_handler)
134
+
135
+ _CONFIGURED = True
@@ -0,0 +1,239 @@
1
+ """
2
+ Cross-platform MCP server launcher for SKCapstone.
3
+ Task: e5f81637
4
+
5
+ Detects the correct Python environment, sets required environment variables,
6
+ and launches the MCP server via stdio transport. Works on Linux, macOS, and
7
+ Windows without requiring shell-specific launcher scripts.
8
+
9
+ Usage:
10
+ python -m skcapstone.mcp_launcher # auto-detect everything
11
+ python -m skcapstone.mcp_launcher --venv /path/to/venv
12
+ python -m skcapstone.mcp_launcher --log-level DEBUG
13
+
14
+ Can also be imported and called programmatically:
15
+ from skcapstone.mcp_launcher import launch
16
+ launch()
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ import os
23
+ import shutil
24
+ import subprocess
25
+ import sys
26
+ from pathlib import Path
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # Python / venv detection
32
+ # ---------------------------------------------------------------------------
33
+
34
+ def _skenv_dir() -> Path:
35
+ """Return the platform-appropriate skenv directory."""
36
+ if sys.platform == "win32":
37
+ local_app = os.environ.get("LOCALAPPDATA")
38
+ if local_app:
39
+ return Path(local_app) / "skenv"
40
+ return Path.home() / ".skenv"
41
+ return Path.home() / ".skenv"
42
+
43
+
44
+ def _python_in_venv(venv: Path) -> Path | None:
45
+ """Return the python executable inside a venv, or None."""
46
+ if sys.platform == "win32":
47
+ candidate = venv / "Scripts" / "python.exe"
48
+ else:
49
+ candidate = venv / "bin" / "python"
50
+ return candidate if candidate.is_file() else None
51
+
52
+
53
+ def _has_skcapstone(python: Path | str) -> bool:
54
+ """Check if a Python interpreter has skcapstone importable."""
55
+ try:
56
+ result = subprocess.run(
57
+ [str(python), "-c", "import skcapstone"],
58
+ capture_output=True,
59
+ timeout=10,
60
+ )
61
+ return result.returncode == 0
62
+ except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
63
+ return False
64
+
65
+
66
+ def find_python(explicit_venv: str | None = None) -> str:
67
+ """Locate the best Python interpreter with skcapstone installed.
68
+
69
+ Search order:
70
+ 1. Explicit venv path (parameter or SKCAPSTONE_VENV env var)
71
+ 2. ~/.skenv (or %LOCALAPPDATA%/skenv on Windows)
72
+ 3. Project-local .venv
73
+ 4. The currently running interpreter (sys.executable)
74
+ 5. System python3 / python
75
+
76
+ Args:
77
+ explicit_venv: Optional path to a virtualenv to use.
78
+
79
+ Returns:
80
+ Absolute path to a Python executable.
81
+
82
+ Raises:
83
+ RuntimeError: If no suitable Python is found.
84
+ """
85
+ # 1. Explicit override
86
+ venv_path = explicit_venv or os.environ.get("SKCAPSTONE_VENV")
87
+ if venv_path:
88
+ py = _python_in_venv(Path(venv_path))
89
+ if py and py.is_file():
90
+ logger.info("Using explicit venv: %s", py)
91
+ return str(py)
92
+ logger.warning(
93
+ "SKCAPSTONE_VENV=%s set but python not found there, falling back.",
94
+ venv_path,
95
+ )
96
+
97
+ # 2. Standard skenv
98
+ skenv = _skenv_dir()
99
+ py = _python_in_venv(skenv)
100
+ if py and _has_skcapstone(py):
101
+ logger.info("Using skenv: %s", py)
102
+ return str(py)
103
+
104
+ # 3. Project-local .venv
105
+ project_dir = Path(__file__).resolve().parent.parent.parent # src/../..
106
+ for venv_name in (".venv", "venv"):
107
+ local_venv = project_dir / venv_name
108
+ py = _python_in_venv(local_venv)
109
+ if py and _has_skcapstone(py):
110
+ logger.info("Using project venv: %s", py)
111
+ return str(py)
112
+
113
+ # 4. Current interpreter
114
+ if _has_skcapstone(sys.executable):
115
+ logger.info("Using current interpreter: %s", sys.executable)
116
+ return sys.executable
117
+
118
+ # 5. System python
119
+ for cmd in ("python3", "python"):
120
+ path = shutil.which(cmd)
121
+ if path and _has_skcapstone(path):
122
+ logger.info("Using system python: %s", path)
123
+ return path
124
+
125
+ raise RuntimeError(
126
+ "Could not find a Python interpreter with skcapstone installed.\n"
127
+ "Install with: bash scripts/install.sh (Linux/macOS) or "
128
+ ".\\scripts\\install.ps1 (Windows)\n"
129
+ "Or set SKCAPSTONE_VENV=/path/to/venv"
130
+ )
131
+
132
+
133
+ # ---------------------------------------------------------------------------
134
+ # Environment setup
135
+ # ---------------------------------------------------------------------------
136
+
137
+ def _setup_environment() -> None:
138
+ """Set required environment variables if not already present."""
139
+ home = Path.home()
140
+ skcapstone_home = home / ".skcapstone"
141
+
142
+ os.environ.setdefault("SKCAPSTONE_HOME", str(skcapstone_home))
143
+ os.environ.setdefault("SKMEMORY_HOME", str(skcapstone_home / "memory"))
144
+
145
+ # Ensure src/ is on PYTHONPATH for importability
146
+ src_dir = str(Path(__file__).resolve().parent.parent)
147
+ python_path = os.environ.get("PYTHONPATH", "")
148
+ if src_dir not in python_path.split(os.pathsep):
149
+ os.environ["PYTHONPATH"] = (
150
+ f"{src_dir}{os.pathsep}{python_path}" if python_path else src_dir
151
+ )
152
+
153
+
154
+ # ---------------------------------------------------------------------------
155
+ # Launch
156
+ # ---------------------------------------------------------------------------
157
+
158
+ def launch(
159
+ venv: str | None = None,
160
+ log_level: str = "WARNING",
161
+ extra_args: list[str] | None = None,
162
+ ) -> int:
163
+ """Launch the MCP server, optionally in a subprocess.
164
+
165
+ If the current interpreter already has skcapstone and is the best match,
166
+ the server is launched in-process. Otherwise, a subprocess is spawned
167
+ with the detected Python interpreter.
168
+
169
+ Args:
170
+ venv: Optional explicit venv path.
171
+ log_level: Logging level for the MCP server.
172
+ extra_args: Additional arguments to pass through.
173
+
174
+ Returns:
175
+ Exit code (0 on success).
176
+ """
177
+ logging.basicConfig(
178
+ level=getattr(logging, log_level.upper(), logging.WARNING),
179
+ format="%(name)s: %(message)s",
180
+ )
181
+
182
+ _setup_environment()
183
+
184
+ python = find_python(explicit_venv=venv)
185
+
186
+ # If the best Python IS us, run in-process
187
+ if os.path.realpath(python) == os.path.realpath(sys.executable):
188
+ logger.info("Launching MCP server in-process.")
189
+ from skcapstone.mcp_server import main as mcp_main
190
+ mcp_main()
191
+ return 0
192
+
193
+ # Otherwise, exec into the correct interpreter
194
+ logger.info("Launching MCP server via: %s", python)
195
+ cmd = [python, "-m", "skcapstone.mcp_server"]
196
+ if extra_args:
197
+ cmd.extend(extra_args)
198
+
199
+ if sys.platform != "win32":
200
+ # On Unix, replace the current process
201
+ os.execv(python, cmd)
202
+ # execv does not return
203
+ return 1 # unreachable, but satisfies type checker
204
+ else:
205
+ # On Windows, os.execv has quirks; use subprocess
206
+ result = subprocess.run(cmd)
207
+ return result.returncode
208
+
209
+
210
+ # ---------------------------------------------------------------------------
211
+ # CLI entry point
212
+ # ---------------------------------------------------------------------------
213
+
214
+ def main() -> None:
215
+ """CLI entry point with argument parsing."""
216
+ import argparse
217
+
218
+ parser = argparse.ArgumentParser(
219
+ description="Cross-platform SKCapstone MCP server launcher.",
220
+ prog="skcapstone-mcp-launcher",
221
+ )
222
+ parser.add_argument(
223
+ "--venv",
224
+ help="Path to a virtualenv to use (overrides auto-detection).",
225
+ )
226
+ parser.add_argument(
227
+ "--log-level",
228
+ default=os.environ.get("SKCAPSTONE_LOG_LEVEL", "WARNING"),
229
+ choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
230
+ help="Logging level (default: WARNING).",
231
+ )
232
+ args, extra = parser.parse_known_args()
233
+
234
+ rc = launch(venv=args.venv, log_level=args.log_level, extra_args=extra)
235
+ sys.exit(rc)
236
+
237
+
238
+ if __name__ == "__main__":
239
+ main()