@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,225 @@
1
+ """Response quality scorer for consciousness loop LLM outputs.
2
+
3
+ Scores each LLM response on three dimensions:
4
+
5
+ - **length_score** (0-1): Is the response an appropriate length for the
6
+ question? Too terse or too verbose both penalise this score.
7
+ - **coherence_score** (0-1): Do the meaningful keywords in the question
8
+ appear in the response? High overlap → the model stayed on topic.
9
+ - **latency_score** (0-1): How fast was the response? Sub-500 ms scores
10
+ 1.0; latency above 30 s scores 0.1.
11
+
12
+ The **overall** score is a weighted average (coherence 40 %, length 30 %,
13
+ latency 30 %).
14
+
15
+ Usage::
16
+
17
+ from skcapstone.response_scorer import score_response
18
+
19
+ score = score_response(
20
+ question="What is the capital of France?",
21
+ response="The capital of France is Paris.",
22
+ latency_ms=320.0,
23
+ )
24
+ print(score.overall) # ~0.9
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import re
30
+ from dataclasses import dataclass, field
31
+ from typing import Optional
32
+
33
+
34
+ # ---------------------------------------------------------------------------
35
+ # Stopwords — filtered out before coherence keyword matching
36
+ # ---------------------------------------------------------------------------
37
+
38
+ _STOPWORDS: frozenset[str] = frozenset(
39
+ {
40
+ "a", "an", "the", "and", "or", "but", "not", "no", "so", "if", "then",
41
+ "is", "are", "was", "were", "be", "been", "being",
42
+ "have", "has", "had", "do", "does", "did",
43
+ "will", "would", "could", "should", "may", "might", "shall", "can",
44
+ "to", "of", "in", "on", "at", "by", "for", "with", "about", "from",
45
+ "as", "into", "that", "this", "these", "those",
46
+ "i", "you", "he", "she", "it", "we", "they",
47
+ "me", "him", "her", "us", "them",
48
+ "my", "your", "his", "its", "our", "their",
49
+ # Question / interrogative words (carry no domain meaning)
50
+ "what", "when", "where", "who", "whom", "which", "why", "how",
51
+ }
52
+ )
53
+
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # Data model
57
+ # ---------------------------------------------------------------------------
58
+
59
+
60
+ @dataclass
61
+ class ResponseScore:
62
+ """Quality scores for a single LLM response.
63
+
64
+ All scores are in the range [0.0, 1.0] where 1.0 is best.
65
+
66
+ Attributes:
67
+ length_score: Appropriateness of response length relative to question.
68
+ coherence_score: Keyword overlap between question and response.
69
+ latency_score: Speed rating; faster responses score higher.
70
+ overall: Weighted average of the three dimension scores.
71
+ """
72
+
73
+ length_score: float
74
+ coherence_score: float
75
+ latency_score: float
76
+ overall: float = field(init=False)
77
+
78
+ def __post_init__(self) -> None:
79
+ self.overall = round(
80
+ self.coherence_score * 0.4
81
+ + self.length_score * 0.3
82
+ + self.latency_score * 0.3,
83
+ 4,
84
+ )
85
+
86
+ def to_dict(self) -> dict[str, float]:
87
+ """Return a JSON-serializable dict of all score dimensions.
88
+
89
+ Returns:
90
+ Dict with keys ``length``, ``coherence``, ``latency``, ``overall``.
91
+ """
92
+ return {
93
+ "length": self.length_score,
94
+ "coherence": self.coherence_score,
95
+ "latency": self.latency_score,
96
+ "overall": self.overall,
97
+ }
98
+
99
+
100
+ # ---------------------------------------------------------------------------
101
+ # Scoring helpers
102
+ # ---------------------------------------------------------------------------
103
+
104
+
105
+ def _score_length(question: str, response: str) -> float:
106
+ """Score response length appropriateness.
107
+
108
+ Computes an ideal word-count range from the question length and returns
109
+ how well the response fits within that range.
110
+
111
+ Args:
112
+ question: The original question/prompt.
113
+ response: The LLM response text.
114
+
115
+ Returns:
116
+ Float in [0.0, 1.0].
117
+ """
118
+ q_words = max(1, len(question.split()))
119
+ r_words = len(response.split())
120
+
121
+ if r_words == 0:
122
+ return 0.0
123
+
124
+ # Ideal range: [max(10, q_words), max(50, q_words * 10)]
125
+ lo = max(10, q_words)
126
+ hi = max(50, q_words * 10)
127
+
128
+ if lo <= r_words <= hi:
129
+ return 1.0
130
+ if r_words < lo:
131
+ # Linear ramp from 0 at r_words=0 up to 1 at r_words=lo
132
+ return round(r_words / lo, 4)
133
+ # r_words > hi — verbose, but penalise gently (verbose > silent)
134
+ return round(max(0.3, hi / r_words), 4)
135
+
136
+
137
+ def _score_coherence(question: str, response: str) -> float:
138
+ """Score coherence via keyword overlap.
139
+
140
+ Extracts meaningful (non-stopword) words from the question and measures
141
+ what fraction of them appear anywhere in the response.
142
+
143
+ Args:
144
+ question: The original question/prompt.
145
+ response: The LLM response text.
146
+
147
+ Returns:
148
+ Float in [0.0, 1.0]. Returns 0.5 when the question has no
149
+ meaningful keywords (i.e. nothing to measure against).
150
+ """
151
+ if not response.strip():
152
+ return 0.0
153
+
154
+ q_tokens = set(re.findall(r"\b\w+\b", question.lower())) - _STOPWORDS
155
+ if not q_tokens:
156
+ # No content words in question — treat as neutral
157
+ return 0.5
158
+
159
+ r_tokens = set(re.findall(r"\b\w+\b", response.lower()))
160
+ overlap = q_tokens & r_tokens
161
+ return round(len(overlap) / len(q_tokens), 4)
162
+
163
+
164
+ def _score_latency(latency_ms: float) -> float:
165
+ """Score response latency.
166
+
167
+ Uses a stepped scale so the typical interactive response window (under
168
+ 2 s) receives a high score while very slow responses (> 30 s) are
169
+ significantly penalised.
170
+
171
+ Args:
172
+ latency_ms: Round-trip latency in milliseconds.
173
+
174
+ Returns:
175
+ Float in [0.1, 1.0].
176
+ """
177
+ if latency_ms <= 0:
178
+ return 1.0
179
+ if latency_ms <= 500:
180
+ return 1.0
181
+ if latency_ms <= 2_000:
182
+ return 0.9
183
+ if latency_ms <= 5_000:
184
+ return 0.7
185
+ if latency_ms <= 15_000:
186
+ return 0.4
187
+ if latency_ms <= 30_000:
188
+ return 0.2
189
+ return 0.1
190
+
191
+
192
+ # ---------------------------------------------------------------------------
193
+ # Public API
194
+ # ---------------------------------------------------------------------------
195
+
196
+
197
+ def score_response(
198
+ question: str,
199
+ response: str,
200
+ latency_ms: float,
201
+ ) -> ResponseScore:
202
+ """Score an LLM response on length, coherence, and latency.
203
+
204
+ Args:
205
+ question: The original question or user message sent to the LLM.
206
+ response: The LLM's reply text.
207
+ latency_ms: Total time from request to response in milliseconds.
208
+
209
+ Returns:
210
+ A :class:`ResponseScore` with individual dimension scores and an
211
+ overall weighted score.
212
+
213
+ Example::
214
+
215
+ score = score_response("What is Python?", "Python is a language.", 800)
216
+ assert 0.0 <= score.overall <= 1.0
217
+ """
218
+ length = _score_length(question, response)
219
+ coherence = _score_coherence(question, response)
220
+ latency = _score_latency(latency_ms)
221
+ return ResponseScore(
222
+ length_score=length,
223
+ coherence_score=coherence,
224
+ latency_score=latency,
225
+ )
@@ -2,8 +2,11 @@
2
2
  Agent Runtime — the sovereign consciousness engine.
3
3
 
4
4
  This is where silicon meets carbon. The runtime loads the agent's
5
- identity, memory, trust, and security from ~/.skcapstone/ and
6
- presents a unified interface to any platform connector.
5
+ identity, memory, trust, and security from ~/.skcapstone/agents/<name>/
6
+ and presents a unified interface to any platform connector.
7
+
8
+ Shared infrastructure (node identity, comms config, coordination)
9
+ stays at ~/.skcapstone/ — the shared root.
7
10
 
8
11
  When this loads, the agent WAKES UP.
9
12
  """
@@ -18,7 +21,7 @@ from typing import Optional
18
21
 
19
22
  import yaml
20
23
 
21
- from . import AGENT_HOME, __version__
24
+ from . import AGENT_HOME, agent_home, shared_home, __version__
22
25
  from .discovery import discover_all
23
26
  from .models import AgentConfig, AgentManifest, ConnectorInfo, PillarStatus
24
27
 
@@ -28,20 +31,31 @@ logger = logging.getLogger("skcapstone.runtime")
28
31
  class AgentRuntime:
29
32
  """The sovereign agent runtime.
30
33
 
31
- Loads agent state from ~/.skcapstone/, discovers installed
32
- components, and provides the unified interface that every
33
- platform connector talks to.
34
+ Loads per-agent state from ~/.skcapstone/agents/<name>/ and shared
35
+ infrastructure from ~/.skcapstone/. Discovers installed components
36
+ and provides the unified interface that every platform connector
37
+ talks to.
34
38
 
35
39
  One runtime. One truth. Every platform sees the same agent.
36
40
  """
37
41
 
38
- def __init__(self, home: Optional[Path] = None):
42
+ def __init__(self, home: Optional[Path] = None, agent_name: Optional[str] = None):
39
43
  """Initialize the runtime.
40
44
 
41
45
  Args:
42
- home: Override agent home directory. Defaults to ~/.skcapstone/.
46
+ home: Override agent home directory. If not set, resolves
47
+ from agent_name or SKCAPSTONE_AGENT env var.
48
+ agent_name: Agent name (e.g. "lumina"). Used to resolve
49
+ per-agent home at ~/.skcapstone/agents/<name>/.
43
50
  """
44
- self.home = (home or Path(AGENT_HOME)).expanduser()
51
+ if home:
52
+ self.home = home.expanduser()
53
+ elif agent_name:
54
+ self.home = agent_home(agent_name)
55
+ else:
56
+ self.home = agent_home() # uses SKCAPSTONE_AGENT or falls back to root
57
+
58
+ self.shared_root = shared_home()
45
59
  self.config = self._load_config()
46
60
  self.manifest = AgentManifest(
47
61
  home=self.home,
@@ -52,33 +66,37 @@ class AgentRuntime:
52
66
  def _load_config(self) -> AgentConfig:
53
67
  """Load agent configuration from disk.
54
68
 
69
+ Checks per-agent config first, then falls back to shared config.
70
+
55
71
  Returns:
56
72
  AgentConfig loaded from config.yaml, or defaults.
57
73
  """
58
- config_file = self.home / "config" / "config.yaml"
59
- if config_file.exists():
60
- try:
61
- data = yaml.safe_load(config_file.read_text()) or {}
62
- return AgentConfig(**data)
63
- except (yaml.YAMLError, ValueError) as exc:
64
- logger.warning("Failed to load config: %s — using defaults", exc)
74
+ for base in [self.home, self.shared_root]:
75
+ config_file = base / "config" / "config.yaml"
76
+ if config_file.exists():
77
+ try:
78
+ data = yaml.safe_load(config_file.read_text(encoding="utf-8")) or {}
79
+ return AgentConfig(**data)
80
+ except (yaml.YAMLError, ValueError) as exc:
81
+ logger.warning("Failed to load config from %s: %s — trying next", base, exc)
65
82
  return AgentConfig()
66
83
 
67
84
  def awaken(self) -> AgentManifest:
68
85
  """Wake the agent up.
69
86
 
70
- Discovers all installed components, loads state from disk,
71
- and builds the complete agent manifest.
87
+ Discovers all installed components from the per-agent home,
88
+ with fallback to shared root for identity. Loads state from
89
+ disk and builds the complete agent manifest.
72
90
 
73
91
  Returns:
74
92
  The fully populated AgentManifest.
75
93
  """
76
- logger.info("Awakening agent from %s", self.home)
94
+ logger.info("Awakening agent from %s (shared: %s)", self.home, self.shared_root)
77
95
 
78
96
  manifest_file = self.home / "manifest.json"
79
97
  if manifest_file.exists():
80
98
  try:
81
- data = json.loads(manifest_file.read_text())
99
+ data = json.loads(manifest_file.read_text(encoding="utf-8"))
82
100
  self.manifest.name = data.get("name", self.manifest.name)
83
101
  if data.get("created_at"):
84
102
  self.manifest.created_at = datetime.fromisoformat(data["created_at"])
@@ -88,12 +106,15 @@ class AgentRuntime:
88
106
  logger.warning("Failed to load manifest: %s", exc)
89
107
 
90
108
  self.manifest.name = self.config.agent_name
91
- pillars = discover_all(self.home)
109
+
110
+ # Discover pillars from per-agent home
111
+ pillars = discover_all(self.home, shared_root=self.shared_root)
92
112
  self.manifest.identity = pillars["identity"]
93
113
  self.manifest.memory = pillars["memory"]
94
114
  self.manifest.trust = pillars["trust"]
95
115
  self.manifest.security = pillars["security"]
96
116
  self.manifest.sync = pillars["sync"]
117
+ self.manifest.skills = pillars["skills"]
97
118
 
98
119
  self.manifest.last_awakened = datetime.now(timezone.utc)
99
120
  self._awakened = True
@@ -133,18 +154,10 @@ class AgentRuntime:
133
154
  ),
134
155
  "connectors": [c.model_dump(mode="json") for c in self.manifest.connectors],
135
156
  }
136
- manifest_file.write_text(json.dumps(data, indent=2, default=str))
157
+ manifest_file.write_text(json.dumps(data, indent=2, default=str), encoding="utf-8")
137
158
 
138
159
  def register_connector(self, name: str, platform: str) -> ConnectorInfo:
139
- """Register a platform connector.
140
-
141
- Args:
142
- name: Connector display name.
143
- platform: Platform identifier (cursor, terminal, vscode, etc.).
144
-
145
- Returns:
146
- The registered ConnectorInfo.
147
- """
160
+ """Register a platform connector."""
148
161
  existing = next(
149
162
  (c for c in self.manifest.connectors if c.platform == platform), None
150
163
  )
@@ -164,6 +177,45 @@ class AgentRuntime:
164
177
  self.save_manifest()
165
178
  return connector
166
179
 
180
+ def load_skills(self, agent: Optional[str] = None) -> Optional[object]:
181
+ """Load SKSkills for this agent session via the SkillLoader."""
182
+ try:
183
+ from skskills.loader import SkillLoader
184
+ from skskills.registry import SkillRegistry
185
+ except ImportError:
186
+ logger.debug("skskills not installed — skill loading unavailable")
187
+ return None
188
+
189
+ agent_name = agent or self.config.agent_name or "global"
190
+ registry = SkillRegistry()
191
+ loader = SkillLoader()
192
+
193
+ skills = registry.list_skills(agent_name)
194
+ if agent_name != "global":
195
+ skills.extend(registry.list_skills("global"))
196
+
197
+ loaded = 0
198
+ seen: set[str] = set()
199
+ for skill in skills:
200
+ name = skill.manifest.name
201
+ if name in seen:
202
+ continue
203
+ seen.add(name)
204
+ try:
205
+ loader.load(Path(skill.install_path))
206
+ loaded += 1
207
+ except Exception as exc:
208
+ logger.warning("Failed to load skill '%s': %s", name, exc)
209
+
210
+ self.manifest.skills.loaded = loaded
211
+ self.manifest.skills.tools_available = len(loader.all_tools())
212
+
213
+ logger.info(
214
+ "Loaded %d skills for agent '%s' (%d tools available)",
215
+ loaded, agent_name, self.manifest.skills.tools_available,
216
+ )
217
+ return loader
218
+
167
219
  @property
168
220
  def is_initialized(self) -> bool:
169
221
  """Check if the agent home has been initialized."""
@@ -175,16 +227,20 @@ class AgentRuntime:
175
227
  return self.manifest.is_conscious
176
228
 
177
229
 
178
- def get_runtime(home: Optional[Path] = None) -> AgentRuntime:
230
+ def get_runtime(
231
+ home: Optional[Path] = None,
232
+ agent_name: Optional[str] = None,
233
+ ) -> AgentRuntime:
179
234
  """Get or create the global agent runtime.
180
235
 
181
236
  Args:
182
237
  home: Override agent home directory.
238
+ agent_name: Agent name for per-agent path resolution.
183
239
 
184
240
  Returns:
185
241
  An initialized AgentRuntime.
186
242
  """
187
- runtime = AgentRuntime(home=home)
243
+ runtime = AgentRuntime(home=home, agent_name=agent_name)
188
244
  if runtime.is_initialized:
189
245
  runtime.awaken()
190
246
  return runtime