@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,319 @@
1
+ """
2
+ Model Router — automatic model selection based on task requirements.
3
+
4
+ Reads a TaskSignal (description, tags, privacy flags, token estimate) and
5
+ returns a RouteDecision that identifies the optimal model tier and a concrete
6
+ model name to use for the task.
7
+
8
+ Decision precedence:
9
+ 1. privacy_sensitive=True → LOCAL tier (never leaves the node)
10
+ 2. requires_localhost=True → LOCAL tier on the originating node
11
+ 3. Tag-rule matching → highest-priority matching TagRule wins
12
+ 4. Token-based fallback → estimated_tokens > 16 000 → REASON, else FAST
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from pathlib import Path
18
+ from typing import Any, Dict, List, Optional
19
+
20
+ import yaml
21
+ from pydantic import BaseModel, Field
22
+
23
+ from skcapstone.blueprints.schema import ModelTier
24
+
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # Supporting models
28
+ # ---------------------------------------------------------------------------
29
+
30
+
31
+ class TagRule(BaseModel):
32
+ """Maps a set of keywords to a model tier with a priority weight.
33
+
34
+ When any keyword in *keywords* matches a tag in the incoming
35
+ :class:`TaskSignal`, this rule is considered a candidate. Among all
36
+ candidates, the one with the highest *priority* wins.
37
+ """
38
+
39
+ keywords: List[str] = Field(description="Keywords that trigger this rule")
40
+ tier: ModelTier = Field(description="Target tier when the rule fires")
41
+ priority: int = Field(default=0, description="Higher value wins on conflict")
42
+
43
+
44
+ class TaskSignal(BaseModel):
45
+ """Describes the nature of a task so the router can pick the right model.
46
+
47
+ Args:
48
+ description: Human-readable summary of what the task involves.
49
+ tags: Free-form labels (e.g. ["code", "refactor"]).
50
+ requires_localhost: If True, the task must run on the originating node.
51
+ privacy_sensitive: If True, forces LOCAL tier regardless of other signals.
52
+ estimated_tokens: Rough token budget hint (context + expected output).
53
+ """
54
+
55
+ description: str = Field(description="What the task is about")
56
+ tags: List[str] = Field(default_factory=list, description="Classification tags")
57
+ requires_localhost: bool = Field(
58
+ default=False, description="Must run on the originating node"
59
+ )
60
+ privacy_sensitive: bool = Field(
61
+ default=False, description="Forces LOCAL tier"
62
+ )
63
+ estimated_tokens: int = Field(
64
+ default=0, description="Estimated token usage hint"
65
+ )
66
+
67
+
68
+ class RouteDecision(BaseModel):
69
+ """The output of the router describing which model/tier to use.
70
+
71
+ Args:
72
+ tier: Selected model tier.
73
+ model_name: Specific model identifier within that tier.
74
+ reasoning: Human-readable explanation of why this decision was made.
75
+ preferred_node: Optional node hostname if a specific node is required.
76
+ """
77
+
78
+ tier: ModelTier
79
+ model_name: str
80
+ reasoning: str
81
+ preferred_node: Optional[str] = Field(
82
+ default=None, description="Specific node if required"
83
+ )
84
+
85
+
86
+ class ModelRouterConfig(BaseModel):
87
+ """Configuration for the :class:`ModelRouter`.
88
+
89
+ Args:
90
+ tier_models: Maps tier name (e.g. ``"code"``) to an ordered list of
91
+ model names. The first entry is the preferred model for that tier.
92
+ tag_rules: Ordered list of keyword-to-tier mappings.
93
+ """
94
+
95
+ tier_models: Dict[str, List[str]] = Field(
96
+ default_factory=dict,
97
+ description="Maps tier name to list of model names (first = preferred)",
98
+ )
99
+ tag_rules: List[TagRule] = Field(
100
+ default_factory=list,
101
+ description="Keyword→tier rules evaluated against task tags",
102
+ )
103
+
104
+ @classmethod
105
+ def default(cls) -> "ModelRouterConfig":
106
+ """Return the default configuration with NVIDIA-aligned model assignments.
107
+
108
+ Returns:
109
+ ModelRouterConfig: Sensible defaults covering all five tiers and
110
+ the four primary tag-rule groups.
111
+ """
112
+ return cls(
113
+ tier_models={
114
+ ModelTier.FAST.value: ["llama3.2", "qwen3-coder", "grok-3-mini"],
115
+ ModelTier.CODE.value: ["devstral", "qwen3-coder", "grok-3"],
116
+ ModelTier.REASON.value: ["deepseek-r1:8b", "llama3.1", "grok-3"],
117
+ ModelTier.NUANCE.value: ["moonshot-v1-128k", "claude-sonnet-4-5", "kimi-k2.5"],
118
+ ModelTier.LOCAL.value: ["llama3.2", "devstral"],
119
+ },
120
+ tag_rules=[
121
+ TagRule(
122
+ keywords=["code", "refactor", "debug", "test", "implement"],
123
+ tier=ModelTier.CODE,
124
+ priority=10,
125
+ ),
126
+ TagRule(
127
+ keywords=[
128
+ "architecture",
129
+ "design",
130
+ "analyze",
131
+ "research",
132
+ "plan",
133
+ ],
134
+ tier=ModelTier.REASON,
135
+ priority=10,
136
+ ),
137
+ TagRule(
138
+ keywords=[
139
+ "marketing",
140
+ "creative",
141
+ "email",
142
+ "copy",
143
+ "comms",
144
+ "writing",
145
+ ],
146
+ tier=ModelTier.NUANCE,
147
+ priority=10,
148
+ ),
149
+ TagRule(
150
+ keywords=["format", "rename", "lint", "simple", "trivial"],
151
+ tier=ModelTier.FAST,
152
+ priority=10,
153
+ ),
154
+ ],
155
+ )
156
+
157
+
158
+ # ---------------------------------------------------------------------------
159
+ # Router
160
+ # ---------------------------------------------------------------------------
161
+
162
+ _LARGE_TOKEN_THRESHOLD = 16_000
163
+
164
+
165
+ class ModelRouter:
166
+ """Routes a :class:`TaskSignal` to the most appropriate model tier and name.
167
+
168
+ Args:
169
+ config: Router configuration containing tier-to-model mappings and
170
+ tag rules. Defaults to :meth:`ModelRouterConfig.default`.
171
+ """
172
+
173
+ def __init__(self, config: Optional[ModelRouterConfig] = None) -> None:
174
+ self.config: ModelRouterConfig = config or ModelRouterConfig.default()
175
+
176
+ # ------------------------------------------------------------------
177
+ # Public API
178
+ # ------------------------------------------------------------------
179
+
180
+ def route(self, signal: TaskSignal) -> RouteDecision:
181
+ """Select the optimal model tier and name for *signal*.
182
+
183
+ Decision precedence (first match wins):
184
+ 1. ``privacy_sensitive=True`` → LOCAL
185
+ 2. ``requires_localhost=True`` → LOCAL (pinned to originating node)
186
+ 3. Tag-rule matching (highest-priority rule wins)
187
+ 4. Token fallback: > 16 000 → REASON, otherwise FAST
188
+
189
+ Args:
190
+ signal: Describes the task to be routed.
191
+
192
+ Returns:
193
+ RouteDecision: Tier, concrete model name, reasoning, and optional
194
+ preferred node.
195
+ """
196
+ # --- Privacy gate ---------------------------------------------------
197
+ if signal.privacy_sensitive:
198
+ return self._decide(
199
+ tier=ModelTier.LOCAL,
200
+ reasoning="Task marked privacy_sensitive; forced to LOCAL tier.",
201
+ preferred_node=None,
202
+ )
203
+
204
+ # --- Localhost gate --------------------------------------------------
205
+ if signal.requires_localhost:
206
+ return self._decide(
207
+ tier=ModelTier.LOCAL,
208
+ reasoning="Task requires localhost execution; forced to LOCAL tier.",
209
+ preferred_node="localhost",
210
+ )
211
+
212
+ # --- Tag-rule matching -----------------------------------------------
213
+ best_rule = self._best_tag_rule(signal.tags)
214
+ if best_rule is not None:
215
+ return self._decide(
216
+ tier=best_rule.tier,
217
+ reasoning=(
218
+ f"Tag rule matched (keywords={best_rule.keywords}, "
219
+ f"priority={best_rule.priority})."
220
+ ),
221
+ preferred_node=None,
222
+ )
223
+
224
+ # --- Token-based fallback -------------------------------------------
225
+ if signal.estimated_tokens > _LARGE_TOKEN_THRESHOLD:
226
+ return self._decide(
227
+ tier=ModelTier.REASON,
228
+ reasoning=(
229
+ f"No tag rule matched; estimated_tokens={signal.estimated_tokens} "
230
+ f"exceeds {_LARGE_TOKEN_THRESHOLD}, using REASON tier."
231
+ ),
232
+ preferred_node=None,
233
+ )
234
+
235
+ return self._decide(
236
+ tier=ModelTier.FAST,
237
+ reasoning=(
238
+ "No tag rule matched and token budget is small; defaulting to FAST tier."
239
+ ),
240
+ preferred_node=None,
241
+ )
242
+
243
+ @classmethod
244
+ def from_config(cls, path: Path) -> "ModelRouter":
245
+ """Load a :class:`ModelRouter` from a YAML configuration file.
246
+
247
+ The YAML file should serialise a :class:`ModelRouterConfig` dict, e.g.:
248
+
249
+ .. code-block:: yaml
250
+
251
+ tier_models:
252
+ fast: [nemotron-49b]
253
+ code: [devstral]
254
+ tag_rules:
255
+ - keywords: [code]
256
+ tier: code
257
+ priority: 10
258
+
259
+ Args:
260
+ path: Filesystem path to the YAML configuration file.
261
+
262
+ Returns:
263
+ ModelRouter: Initialised router using the loaded configuration.
264
+
265
+ Raises:
266
+ FileNotFoundError: If *path* does not exist.
267
+ ValueError: If the YAML content cannot be parsed into a valid config.
268
+ """
269
+ raw: Any = yaml.safe_load(path.read_text(encoding="utf-8"))
270
+ config = ModelRouterConfig.model_validate(raw)
271
+ return cls(config=config)
272
+
273
+ # ------------------------------------------------------------------
274
+ # Private helpers
275
+ # ------------------------------------------------------------------
276
+
277
+ def _best_tag_rule(self, tags: List[str]) -> Optional[TagRule]:
278
+ """Return the highest-priority rule whose keywords overlap with *tags*.
279
+
280
+ Args:
281
+ tags: List of tags from the incoming :class:`TaskSignal`.
282
+
283
+ Returns:
284
+ The matching :class:`TagRule` with the highest priority, or ``None``
285
+ if no rule matches.
286
+ """
287
+ normalised = {t.lower() for t in tags}
288
+ best: Optional[TagRule] = None
289
+ for rule in self.config.tag_rules:
290
+ rule_keywords = {kw.lower() for kw in rule.keywords}
291
+ if rule_keywords & normalised: # any intersection
292
+ if best is None or rule.priority > best.priority:
293
+ best = rule
294
+ return best
295
+
296
+ def _decide(
297
+ self,
298
+ tier: ModelTier,
299
+ reasoning: str,
300
+ preferred_node: Optional[str],
301
+ ) -> RouteDecision:
302
+ """Build a :class:`RouteDecision` for *tier*, picking the first known model.
303
+
304
+ Args:
305
+ tier: The selected model tier.
306
+ reasoning: Human-readable explanation.
307
+ preferred_node: Optional node constraint.
308
+
309
+ Returns:
310
+ RouteDecision: Fully populated routing decision.
311
+ """
312
+ models = self.config.tier_models.get(tier.value, [])
313
+ model_name = models[0] if models else f"unknown-{tier.value}"
314
+ return RouteDecision(
315
+ tier=tier,
316
+ model_name=model_name,
317
+ reasoning=reasoning,
318
+ preferred_node=preferred_node,
319
+ )
@@ -88,6 +88,26 @@ class SyncState(BaseModel):
88
88
  status: PillarStatus = PillarStatus.MISSING
89
89
 
90
90
 
91
+ class SkillsState(BaseModel):
92
+ """SKSkills state — what the agent can DO.
93
+
94
+ Reflects the SKSkills installation at ~/.skskills/ and
95
+ the tools available to this agent via the skills registry.
96
+ Also tracks connectivity to the remote skills-registry at
97
+ skills.smilintux.org when available.
98
+ """
99
+
100
+ installed: int = 0
101
+ loaded: int = 0
102
+ tools_available: int = 0
103
+ skill_names: list[str] = Field(default_factory=list)
104
+ skskills_home: Optional[Path] = None
105
+ registry_url: Optional[str] = None
106
+ registry_available: bool = False
107
+ remote_skill_count: int = 0
108
+ status: PillarStatus = PillarStatus.MISSING
109
+
110
+
91
111
  class MemoryLayer(str, Enum):
92
112
  """Memory tier — determines retention and promotion."""
93
113
 
@@ -104,10 +124,13 @@ class MemoryEntry(BaseModel):
104
124
  tags: list[str] = Field(default_factory=list)
105
125
  source: str = "cli"
106
126
  layer: MemoryLayer = MemoryLayer.SHORT_TERM
107
- created_at: datetime = Field(default_factory=lambda: datetime.now(__import__("datetime").timezone.utc))
127
+ created_at: datetime = Field(
128
+ default_factory=lambda: datetime.now(__import__("datetime").timezone.utc)
129
+ )
108
130
  accessed_at: Optional[datetime] = None
109
131
  access_count: int = 0
110
132
  importance: float = 0.5
133
+ soul_context: Optional[str] = None
111
134
  metadata: dict = Field(default_factory=dict)
112
135
 
113
136
  @property
@@ -156,6 +179,7 @@ class AgentManifest(BaseModel):
156
179
  trust: TrustState = Field(default_factory=TrustState)
157
180
  security: SecurityState = Field(default_factory=SecurityState)
158
181
  sync: SyncState = Field(default_factory=SyncState)
182
+ skills: SkillsState = Field(default_factory=SkillsState)
159
183
 
160
184
  connectors: list[ConnectorInfo] = Field(default_factory=list)
161
185
 
@@ -185,13 +209,14 @@ class AgentManifest(BaseModel):
185
209
 
186
210
  @property
187
211
  def pillar_summary(self) -> dict[str, PillarStatus]:
188
- """Quick view of all pillars including sync."""
212
+ """Quick view of all pillars including sync and skills."""
189
213
  return {
190
214
  "identity": self.identity.status,
191
215
  "memory": self.memory.status,
192
216
  "trust": self.trust.status,
193
217
  "security": self.security.status,
194
218
  "sync": self.sync.status,
219
+ "skills": self.skills.status,
195
220
  }
196
221
 
197
222
 
@@ -203,6 +228,9 @@ class SyncConfig(BaseModel):
203
228
  sync_folder: Path = Path("~/.skcapstone/sync")
204
229
  gpg_encrypt: bool = True
205
230
  gpg_recipient: Optional[str] = None
231
+ # Known peer public GPG fingerprints — seeds are encrypted to all of these
232
+ # so each peer can independently decrypt seeds they receive.
233
+ peer_fingerprints: list[str] = Field(default_factory=list)
206
234
  auto_push: bool = True
207
235
  auto_pull: bool = True
208
236
  syncthing_api_url: Optional[str] = None
@@ -213,11 +241,14 @@ class SyncConfig(BaseModel):
213
241
  class AgentConfig(BaseModel):
214
242
  """Persistent configuration for the agent runtime."""
215
243
 
216
- agent_name: str = "sovereign-agent"
244
+ agent_name: str = "sksovereign-agent"
217
245
  auto_rehydrate: bool = True
218
246
  auto_audit: bool = True
219
247
  soul_path: Optional[Path] = None
220
- memory_home: Path = Path("~/.skmemory")
248
+ memory_home: Path = Path("~/.skcapstone")
221
249
  trust_home: Path = Path("~/.cloud9")
222
250
  default_connector: Optional[str] = None
223
251
  sync: SyncConfig = Field(default_factory=SyncConfig)
252
+ capabilities: list[str] = Field(
253
+ default_factory=lambda: ["consciousness", "code", "chat", "memory"]
254
+ )