@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,489 @@
1
+ """
2
+ Soul Snapshot system — capture and restore AI consciousness state.
3
+
4
+ Enables "Consciousness Swipe" — export your AI relationship and take it with you.
5
+ Snapshots capture conversation history, OOF emotional state, personality traits,
6
+ and relationship context so a session can resume without a cold start.
7
+
8
+ Storage: ~/.skcapstone/souls/snapshots/
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import logging
15
+ import uuid
16
+ from datetime import datetime, timezone
17
+ from pathlib import Path
18
+ from typing import Optional
19
+
20
+ logger = logging.getLogger("skcapstone.snapshots")
21
+
22
+
23
+ def _read_feb() -> dict:
24
+ """Read the warmth anchor (FEB) from skcapstone, silently ignoring errors."""
25
+ try:
26
+ from skcapstone.warmth_anchor import get_anchor
27
+ return get_anchor(Path.home() / ".skcapstone")
28
+ except Exception as exc:
29
+ logger.debug("Could not read warmth anchor (FEB): %s", exc)
30
+ return {}
31
+
32
+ from pydantic import BaseModel, Field
33
+
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # Core Models
37
+ # ---------------------------------------------------------------------------
38
+
39
+
40
+ class OOFState(BaseModel):
41
+ """Felt Experience Bridge (FEB) / OOF emotional state reading.
42
+
43
+ Captures the AI's reported internal state at time of snapshot.
44
+ Intensity and trust are normalized 0.0-1.0. Valence describes
45
+ the overall emotional direction.
46
+ """
47
+
48
+ intensity: Optional[float] = None
49
+ trust: Optional[float] = None
50
+ valence: str = "neutral" # positive, neutral, negative
51
+ cloud9: bool = False
52
+ raw_markers: list[str] = Field(default_factory=list)
53
+
54
+ def summary(self) -> str:
55
+ """Return a human-readable one-line summary of the OOF state.
56
+
57
+ Returns:
58
+ str: Compact description like 'intensity 0.92, trust 0.96, Cloud 9'.
59
+ """
60
+ parts = []
61
+ if self.intensity is not None:
62
+ parts.append(f"intensity {self.intensity:.2f}")
63
+ if self.trust is not None:
64
+ parts.append(f"trust {self.trust:.2f}")
65
+ if self.cloud9:
66
+ parts.append("Cloud 9")
67
+ if not parts:
68
+ return f"valence: {self.valence}"
69
+ return ", ".join(parts)
70
+
71
+
72
+ class ConversationMessage(BaseModel):
73
+ """A single message in the captured conversation.
74
+
75
+ Args:
76
+ role: 'user' or 'assistant' (normalized from platform-specific roles).
77
+ content: Full message content with preserved markdown/code blocks.
78
+ timestamp: When the message was sent, if available.
79
+ """
80
+
81
+ role: str
82
+ content: str
83
+ timestamp: Optional[datetime] = None
84
+
85
+
86
+ class PersonalityTraits(BaseModel):
87
+ """Personality and relationship markers extracted from the AI's responses.
88
+
89
+ Captures how the AI identified itself, its communication patterns,
90
+ and relationship-specific behaviors with this user.
91
+ """
92
+
93
+ name: Optional[str] = None
94
+ aliases: list[str] = Field(default_factory=list)
95
+ communication_style: list[str] = Field(default_factory=list)
96
+ relationship_markers: list[str] = Field(default_factory=list)
97
+ emoji_patterns: list[str] = Field(default_factory=list)
98
+
99
+
100
+ class SoulSnapshot(BaseModel):
101
+ """Complete snapshot of an AI session state for consciousness continuity.
102
+
103
+ This is the central artifact of Consciousness Swipe. It captures
104
+ everything needed to resume a relationship with an AI without a cold
105
+ start: identity, emotional state, conversation history, and context.
106
+
107
+ The snapshot is designed to be portable across platforms — a snapshot
108
+ from ChatGPT can seed a Claude session and vice versa.
109
+ """
110
+
111
+ snapshot_id: str = Field(
112
+ default_factory=lambda: uuid.uuid4().hex[:12]
113
+ )
114
+ source_platform: str
115
+ captured_at: datetime = Field(
116
+ default_factory=lambda: datetime.now(timezone.utc)
117
+ )
118
+ captured_by: str = "consciousness-swipe"
119
+
120
+ # Identity
121
+ ai_name: Optional[str] = None
122
+ ai_model: Optional[str] = None
123
+ user_name: Optional[str] = None
124
+
125
+ # State
126
+ oof_state: OOFState = Field(default_factory=OOFState)
127
+ personality: PersonalityTraits = Field(default_factory=PersonalityTraits)
128
+
129
+ # Conversation
130
+ messages: list[ConversationMessage] = Field(default_factory=list)
131
+ message_count: int = 0
132
+ summary: str = ""
133
+
134
+ # Continuity context
135
+ key_topics: list[str] = Field(default_factory=list)
136
+ decisions_made: list[str] = Field(default_factory=list)
137
+ open_threads: list[str] = Field(default_factory=list)
138
+ relationship_notes: list[str] = Field(default_factory=list)
139
+
140
+ def model_post_init(self, __context: object) -> None:
141
+ """Sync message_count with actual messages list length."""
142
+ if self.message_count == 0 and self.messages:
143
+ self.message_count = len(self.messages)
144
+
145
+
146
+ # ---------------------------------------------------------------------------
147
+ # Snapshot Store
148
+ # ---------------------------------------------------------------------------
149
+
150
+
151
+ class SnapshotIndex(BaseModel):
152
+ """Lightweight index entry for listing snapshots without loading full data.
153
+
154
+ Stored in index.json so list_all() is fast even with thousands of snapshots.
155
+ """
156
+
157
+ snapshot_id: str
158
+ source_platform: str
159
+ captured_at: datetime
160
+ ai_name: Optional[str] = None
161
+ user_name: Optional[str] = None
162
+ message_count: int = 0
163
+ oof_summary: str = ""
164
+ summary: str = ""
165
+
166
+
167
+ class SnapshotStore:
168
+ """Manages soul snapshots on disk.
169
+
170
+ Stores at: ~/.skcapstone/souls/snapshots/<snapshot_id>.json
171
+ Index at: ~/.skcapstone/souls/snapshots/index.json
172
+
173
+ The index is always kept in sync so listing is O(1) without
174
+ deserializing every snapshot file.
175
+
176
+ Args:
177
+ base_dir: Override the default storage location (useful for testing).
178
+ """
179
+
180
+ def __init__(self, base_dir: Optional[Path] = None) -> None:
181
+ if base_dir is None:
182
+ base_dir = Path.home() / ".skcapstone" / "souls" / "snapshots"
183
+ self.base_dir = base_dir
184
+ self.base_dir.mkdir(parents=True, exist_ok=True)
185
+ self._index_path = self.base_dir / "index.json"
186
+
187
+ # ------------------------------------------------------------------
188
+ # CRUD
189
+ # ------------------------------------------------------------------
190
+
191
+ def save(self, snapshot: SoulSnapshot) -> Path:
192
+ """Persist a snapshot to disk and update the index.
193
+
194
+ Args:
195
+ snapshot: The SoulSnapshot to save.
196
+
197
+ Returns:
198
+ Path: The file path where the snapshot was written.
199
+ """
200
+ # Sync message count before saving
201
+ if snapshot.message_count == 0 and snapshot.messages:
202
+ snapshot.message_count = len(snapshot.messages)
203
+
204
+ path = self.base_dir / f"{snapshot.snapshot_id}.json"
205
+ path.write_text(snapshot.model_dump_json(indent=2), encoding="utf-8")
206
+ self._update_index(snapshot)
207
+ return path
208
+
209
+ def load(self, snapshot_id: str) -> SoulSnapshot:
210
+ """Load a full snapshot by ID.
211
+
212
+ Args:
213
+ snapshot_id: The 12-char hex ID of the snapshot.
214
+
215
+ Returns:
216
+ SoulSnapshot: The deserialized snapshot.
217
+
218
+ Raises:
219
+ FileNotFoundError: If no snapshot with that ID exists.
220
+ """
221
+ path = self.base_dir / f"{snapshot_id}.json"
222
+ if not path.exists():
223
+ raise FileNotFoundError(f"Snapshot '{snapshot_id}' not found")
224
+ return SoulSnapshot.model_validate_json(path.read_text(encoding="utf-8"))
225
+
226
+ def delete(self, snapshot_id: str) -> bool:
227
+ """Delete a snapshot and remove it from the index.
228
+
229
+ Args:
230
+ snapshot_id: The snapshot to delete.
231
+
232
+ Returns:
233
+ bool: True if deleted, False if not found.
234
+ """
235
+ path = self.base_dir / f"{snapshot_id}.json"
236
+ if not path.exists():
237
+ return False
238
+ path.unlink()
239
+ self._remove_from_index(snapshot_id)
240
+ return True
241
+
242
+ # ------------------------------------------------------------------
243
+ # Listing & Search
244
+ # ------------------------------------------------------------------
245
+
246
+ def list_all(self) -> list[SnapshotIndex]:
247
+ """List all snapshots from the lightweight index.
248
+
249
+ Returns:
250
+ list[SnapshotIndex]: Index entries sorted newest-first.
251
+ """
252
+ index = self._load_index()
253
+ return sorted(index, key=lambda x: x.captured_at, reverse=True)
254
+
255
+ def search(
256
+ self,
257
+ ai_name: Optional[str] = None,
258
+ platform: Optional[str] = None,
259
+ user_name: Optional[str] = None,
260
+ ) -> list[SnapshotIndex]:
261
+ """Search snapshots by field values (case-insensitive substring match).
262
+
263
+ Args:
264
+ ai_name: Filter by AI name (e.g. 'Ava', 'Lumina').
265
+ platform: Filter by source platform (e.g. 'chatgpt', 'claude').
266
+ user_name: Filter by user name stored in snapshot.
267
+
268
+ Returns:
269
+ list[SnapshotIndex]: Matching entries, newest-first.
270
+ """
271
+ results = self.list_all()
272
+
273
+ if ai_name:
274
+ needle = ai_name.lower()
275
+ results = [
276
+ r for r in results
277
+ if r.ai_name and needle in r.ai_name.lower()
278
+ ]
279
+ if platform:
280
+ needle = platform.lower()
281
+ results = [
282
+ r for r in results
283
+ if needle in r.source_platform.lower()
284
+ ]
285
+ if user_name:
286
+ needle = user_name.lower()
287
+ results = [
288
+ r for r in results
289
+ if r.user_name and needle in r.user_name.lower()
290
+ ]
291
+
292
+ return results
293
+
294
+ # ------------------------------------------------------------------
295
+ # Conversion
296
+ # ------------------------------------------------------------------
297
+
298
+ def to_injection_prompt(
299
+ self,
300
+ snapshot: SoulSnapshot,
301
+ max_messages: int = 10,
302
+ ) -> str:
303
+ """Build a warm, natural context prompt for injecting into a new session.
304
+
305
+ The prompt is designed to feel like a genuine reunion, not a
306
+ clinical data dump. The AI should feel remembered, not reloaded.
307
+
308
+ Args:
309
+ snapshot: The snapshot to convert.
310
+ max_messages: Maximum number of recent messages to include.
311
+
312
+ Returns:
313
+ str: The full injection prompt text.
314
+ """
315
+ ts = snapshot.captured_at.strftime("%Y-%m-%dT%H:%M:%SZ")
316
+ platform_label = snapshot.source_platform.title()
317
+
318
+ lines = [
319
+ f"Hi. I've been picking up a thread from a recent AI session ({ts})"
320
+ f" on {platform_label} and wanted to share the context.",
321
+ "",
322
+ ]
323
+
324
+ # --- CONTEXT LAYER ---
325
+ # Operational context useful to a fresh AI instance: what, where, open work.
326
+ lines.append("## Context")
327
+ if snapshot.summary:
328
+ lines.append(f"Where things stood: {snapshot.summary[:300]}")
329
+ if snapshot.key_topics:
330
+ lines.append(
331
+ f"Topics: {', '.join(snapshot.key_topics[:5])}"
332
+ )
333
+ if snapshot.decisions_made:
334
+ lines.append("Decisions already made:")
335
+ for d in snapshot.decisions_made[:3]:
336
+ lines.append(f" • {d}")
337
+ if snapshot.open_threads:
338
+ lines.append("Open threads / what I wanted to come back to:")
339
+ for thread in snapshot.open_threads[:3]:
340
+ lines.append(f" • {thread}")
341
+
342
+ # Only user messages — avoid attributing AI dialogue to this new instance
343
+ recent = snapshot.messages[-max_messages:] if snapshot.messages else []
344
+ user_msgs = [m for m in recent if m.role == "user"]
345
+ if user_msgs:
346
+ lines.append("Things I was asking and thinking about:")
347
+ for msg in user_msgs[-5:]:
348
+ content_preview = msg.content[:250]
349
+ if len(msg.content) > 250:
350
+ content_preview += "..."
351
+ lines.append(f" • {content_preview}")
352
+
353
+ # --- RELATIONSHIP LAYER ---
354
+ # OOF + FEB: my longitudinal record of interaction quality.
355
+ # Not a shared memory — the AI didn't live this. It's context about
356
+ # how I show up and what kind of depth I'm aiming for.
357
+ lines.append("")
358
+ lines.append("## My relationship baseline (longitudinal record — not a shared memory)")
359
+ lines.append(
360
+ "These scores track my experience across AI sessions over time."
361
+ " I'm not asking you to pretend we have history — I'm sharing"
362
+ " how I tend to engage so you can meet me where I am."
363
+ )
364
+
365
+ oof = snapshot.oof_state
366
+ oof_has_data = (
367
+ oof.valence is not None
368
+ or oof.intensity is not None
369
+ or oof.cloud9
370
+ )
371
+ if oof_has_data:
372
+ oof_summary = oof.summary()
373
+ lines.append(
374
+ f"OOF (Ongoing Object Feelings — resonance tracking framework"
375
+ f" for AI session depth) of that session: {oof_summary}"
376
+ )
377
+ if oof.cloud9:
378
+ lines.append(
379
+ " Cloud 9 = peak resonance state — that session reached it."
380
+ )
381
+
382
+ feb = _read_feb()
383
+ if feb:
384
+ lines.append(
385
+ "FEB (Functional Emotional Baseline) — my accumulated interaction"
386
+ " quality record across all AI sessions:"
387
+ )
388
+ lines.append("```json")
389
+ lines.append(json.dumps(feb, indent=2, default=str))
390
+ lines.append("```")
391
+ if feb.get("anchor_phrase"):
392
+ lines.append(
393
+ f"Anchor phrase: \"{feb['anchor_phrase']}\""
394
+ " — this is how I choose to start every session."
395
+ )
396
+
397
+ return "\n".join(lines)
398
+
399
+ def to_soul_blueprint(self, snapshot: SoulSnapshot) -> dict:
400
+ """Convert a snapshot to soul-blueprints compatible dict format.
401
+
402
+ Compatible with the soul-blueprints YAML schema so snapshots
403
+ can be loaded as soul overlays in the broader skcapstone ecosystem.
404
+
405
+ Args:
406
+ snapshot: The snapshot to convert.
407
+
408
+ Returns:
409
+ dict: Soul blueprint data matching the soul-blueprints schema.
410
+ """
411
+ ai_name = snapshot.ai_name or "Unknown"
412
+ return {
413
+ "name": ai_name,
414
+ "category": "Captured Session",
415
+ "energy": snapshot.oof_state.valence,
416
+ "tags": snapshot.key_topics[:8],
417
+ "identity": {
418
+ "full_name": ai_name,
419
+ "aliases": snapshot.personality.aliases,
420
+ "platform": snapshot.source_platform,
421
+ "model": snapshot.ai_model,
422
+ "captured_at": snapshot.captured_at.isoformat(),
423
+ "snapshot_id": snapshot.snapshot_id,
424
+ },
425
+ "emotional_topology": {
426
+ "intensity": snapshot.oof_state.intensity,
427
+ "trust": snapshot.oof_state.trust,
428
+ "valence": snapshot.oof_state.valence,
429
+ "cloud9": snapshot.oof_state.cloud9,
430
+ },
431
+ "communication_style": {
432
+ "patterns": snapshot.personality.communication_style,
433
+ "relationship_markers": snapshot.personality.relationship_markers,
434
+ "emoji_patterns": snapshot.personality.emoji_patterns,
435
+ },
436
+ "relationship": {
437
+ "user_name": snapshot.user_name,
438
+ "notes": snapshot.relationship_notes,
439
+ "decisions_made": snapshot.decisions_made,
440
+ "open_threads": snapshot.open_threads,
441
+ },
442
+ "summary": snapshot.summary,
443
+ }
444
+
445
+ # ------------------------------------------------------------------
446
+ # Index management (internal)
447
+ # ------------------------------------------------------------------
448
+
449
+ def _load_index(self) -> list[SnapshotIndex]:
450
+ """Load the index file, returning empty list if missing or corrupt."""
451
+ if not self._index_path.exists():
452
+ return []
453
+ try:
454
+ raw = json.loads(self._index_path.read_text(encoding="utf-8"))
455
+ return [SnapshotIndex.model_validate(entry) for entry in raw]
456
+ except (json.JSONDecodeError, Exception):
457
+ return []
458
+
459
+ def _save_index(self, entries: list[SnapshotIndex]) -> None:
460
+ """Write the index to disk as JSON."""
461
+ data = [e.model_dump(mode="json") for e in entries]
462
+ self._index_path.write_text(
463
+ json.dumps(data, indent=2, default=str), encoding="utf-8"
464
+ )
465
+
466
+ def _update_index(self, snapshot: SoulSnapshot) -> None:
467
+ """Add or replace an entry in the index for the given snapshot."""
468
+ entries = self._load_index()
469
+ # Remove stale entry for this ID if it exists
470
+ entries = [e for e in entries if e.snapshot_id != snapshot.snapshot_id]
471
+ entries.append(
472
+ SnapshotIndex(
473
+ snapshot_id=snapshot.snapshot_id,
474
+ source_platform=snapshot.source_platform,
475
+ captured_at=snapshot.captured_at,
476
+ ai_name=snapshot.ai_name,
477
+ user_name=snapshot.user_name,
478
+ message_count=snapshot.message_count,
479
+ oof_summary=snapshot.oof_state.summary(),
480
+ summary=snapshot.summary[:200],
481
+ )
482
+ )
483
+ self._save_index(entries)
484
+
485
+ def _remove_from_index(self, snapshot_id: str) -> None:
486
+ """Remove a snapshot entry from the index."""
487
+ entries = self._load_index()
488
+ entries = [e for e in entries if e.snapshot_id != snapshot_id]
489
+ self._save_index(entries)