@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,464 @@
1
+ """Tests for Memory Migration — JSON memories to unified backend."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+ from unittest.mock import MagicMock, patch
8
+
9
+ import pytest
10
+
11
+ from skcapstone.migrate_memories import _scan_json_memories, _verify_migration, migrate
12
+ from skcapstone.models import MemoryEntry, MemoryLayer
13
+
14
+
15
+ # ---------------------------------------------------------------------------
16
+ # Helpers
17
+ # ---------------------------------------------------------------------------
18
+
19
+
20
+ def _make_memory_json(
21
+ memory_id: str = "test-001",
22
+ content: str = "Test memory content",
23
+ tags: list[str] | None = None,
24
+ source: str = "test",
25
+ layer: str = "short-term",
26
+ importance: float = 0.5,
27
+ ) -> str:
28
+ """Return a valid MemoryEntry JSON string."""
29
+ return json.dumps(
30
+ {
31
+ "memory_id": memory_id,
32
+ "content": content,
33
+ "tags": tags or ["test"],
34
+ "source": source,
35
+ "layer": layer,
36
+ "importance": importance,
37
+ }
38
+ )
39
+
40
+
41
+ def _populate_layer(home: Path, layer: str, entries: dict[str, str]) -> None:
42
+ """Write JSON files into home/memory/<layer>/."""
43
+ layer_dir = home / "memory" / layer
44
+ layer_dir.mkdir(parents=True, exist_ok=True)
45
+ for filename, content in entries.items():
46
+ (layer_dir / filename).write_text(content, encoding="utf-8")
47
+
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # TestScanJsonMemories
51
+ # ---------------------------------------------------------------------------
52
+
53
+
54
+ class TestScanJsonMemories:
55
+ """Tests for _scan_json_memories."""
56
+
57
+ def test_empty_home_returns_empty_list(self, tmp_path: Path) -> None:
58
+ """An empty home directory yields no memories."""
59
+ result = _scan_json_memories(tmp_path)
60
+ assert result == []
61
+
62
+ def test_memories_in_different_layers_are_found(self, tmp_path: Path) -> None:
63
+ """Memories across short-term, mid-term, and long-term are all collected."""
64
+ _populate_layer(
65
+ tmp_path,
66
+ "short-term",
67
+ {"a.json": _make_memory_json(memory_id="st-1", content="short")},
68
+ )
69
+ _populate_layer(
70
+ tmp_path,
71
+ "mid-term",
72
+ {"b.json": _make_memory_json(memory_id="mt-1", content="mid")},
73
+ )
74
+ _populate_layer(
75
+ tmp_path,
76
+ "long-term",
77
+ {"c.json": _make_memory_json(memory_id="lt-1", content="long")},
78
+ )
79
+
80
+ result = _scan_json_memories(tmp_path)
81
+ ids = {e.memory_id for e in result}
82
+ assert ids == {"st-1", "mt-1", "lt-1"}
83
+ assert len(result) == 3
84
+
85
+ def test_invalid_json_files_are_skipped(self, tmp_path: Path) -> None:
86
+ """Files containing invalid JSON are skipped without raising."""
87
+ _populate_layer(
88
+ tmp_path,
89
+ "short-term",
90
+ {
91
+ "good.json": _make_memory_json(memory_id="good-1"),
92
+ "bad.json": "NOT VALID JSON {{{",
93
+ },
94
+ )
95
+
96
+ result = _scan_json_memories(tmp_path)
97
+ assert len(result) == 1
98
+ assert result[0].memory_id == "good-1"
99
+
100
+ def test_index_json_is_skipped(self, tmp_path: Path) -> None:
101
+ """index.json files are always skipped."""
102
+ _populate_layer(
103
+ tmp_path,
104
+ "short-term",
105
+ {
106
+ "index.json": json.dumps({"some": "index data"}),
107
+ "real.json": _make_memory_json(memory_id="real-1"),
108
+ },
109
+ )
110
+
111
+ result = _scan_json_memories(tmp_path)
112
+ assert len(result) == 1
113
+ assert result[0].memory_id == "real-1"
114
+
115
+ def test_missing_layer_dirs_are_handled(self, tmp_path: Path) -> None:
116
+ """If only some layer directories exist, others are silently skipped."""
117
+ # Create only short-term
118
+ _populate_layer(
119
+ tmp_path,
120
+ "short-term",
121
+ {"m.json": _make_memory_json(memory_id="only-1")},
122
+ )
123
+ # mid-term and long-term do not exist
124
+
125
+ result = _scan_json_memories(tmp_path)
126
+ assert len(result) == 1
127
+ assert result[0].memory_id == "only-1"
128
+
129
+ def test_entries_have_correct_fields(self, tmp_path: Path) -> None:
130
+ """Parsed MemoryEntry objects carry the expected field values."""
131
+ _populate_layer(
132
+ tmp_path,
133
+ "long-term",
134
+ {
135
+ "entry.json": _make_memory_json(
136
+ memory_id="lt-99",
137
+ content="important stuff",
138
+ tags=["alpha", "beta"],
139
+ source="migration",
140
+ layer="long-term",
141
+ importance=0.9,
142
+ )
143
+ },
144
+ )
145
+
146
+ result = _scan_json_memories(tmp_path)
147
+ assert len(result) == 1
148
+ entry = result[0]
149
+ assert entry.memory_id == "lt-99"
150
+ assert entry.content == "important stuff"
151
+ assert entry.tags == ["alpha", "beta"]
152
+ assert entry.source == "migration"
153
+ assert entry.layer == MemoryLayer.LONG_TERM
154
+ assert entry.importance == 0.9
155
+
156
+ def test_invalid_model_data_is_skipped(self, tmp_path: Path) -> None:
157
+ """JSON that is valid but fails MemoryEntry validation is skipped."""
158
+ # content is required, omitting it should cause a validation error
159
+ bad_model_json = json.dumps({"memory_id": "bad-model"})
160
+ _populate_layer(
161
+ tmp_path,
162
+ "short-term",
163
+ {
164
+ "bad_model.json": bad_model_json,
165
+ "ok.json": _make_memory_json(memory_id="ok-1"),
166
+ },
167
+ )
168
+
169
+ result = _scan_json_memories(tmp_path)
170
+ assert len(result) == 1
171
+ assert result[0].memory_id == "ok-1"
172
+
173
+
174
+ # ---------------------------------------------------------------------------
175
+ # TestMigrate
176
+ # ---------------------------------------------------------------------------
177
+
178
+
179
+ class TestMigrate:
180
+ """Tests for the migrate function."""
181
+
182
+ @patch("skcapstone.memory_adapter.get_unified", return_value=None)
183
+ def test_returns_error_when_skmemory_not_available(
184
+ self, mock_get: MagicMock, tmp_path: Path
185
+ ) -> None:
186
+ """Returns an error dict when get_unified returns None."""
187
+ result = migrate(tmp_path)
188
+ assert result["ok"] is False
189
+ assert "skmemory not available" in result["error"]
190
+
191
+ @patch("skcapstone.memory_adapter.get_unified")
192
+ def test_dry_run_returns_counts_without_writing(
193
+ self, mock_get: MagicMock, tmp_path: Path
194
+ ) -> None:
195
+ """Dry run scans memories and reports counts but does not call store."""
196
+ mock_store = MagicMock()
197
+ mock_get.return_value = mock_store
198
+
199
+ _populate_layer(
200
+ tmp_path,
201
+ "short-term",
202
+ {
203
+ "a.json": _make_memory_json(memory_id="dr-1"),
204
+ "b.json": _make_memory_json(memory_id="dr-2"),
205
+ },
206
+ )
207
+
208
+ result = migrate(tmp_path, dry_run=True)
209
+ assert result["ok"] is True
210
+ assert result["dry_run"] is True
211
+ assert result["total_json"] == 2
212
+ assert result["migrated"] == 0
213
+ # No writes should have happened
214
+ mock_store.primary.save.assert_not_called()
215
+
216
+ @patch("skcapstone.memory_adapter.entry_to_memory")
217
+ @patch("skcapstone.memory_adapter.get_unified")
218
+ def test_skips_existing_memories(
219
+ self,
220
+ mock_get: MagicMock,
221
+ mock_entry_to_memory: MagicMock,
222
+ tmp_path: Path,
223
+ ) -> None:
224
+ """Memories already present in the store are skipped (deduplication)."""
225
+ mock_store = MagicMock()
226
+ # Simulate existing memory with id "dup-1"
227
+ existing_mem = MagicMock()
228
+ existing_mem.id = "dup-1"
229
+ mock_store.list_memories.return_value = [existing_mem]
230
+ mock_store.vector = None
231
+ mock_store.graph = None
232
+ mock_get.return_value = mock_store
233
+
234
+ _populate_layer(
235
+ tmp_path,
236
+ "short-term",
237
+ {"dup.json": _make_memory_json(memory_id="dup-1")},
238
+ )
239
+
240
+ result = migrate(tmp_path)
241
+ assert result["ok"] is True
242
+ assert result["skipped_existing"] == 1
243
+ assert result["migrated"] == 0
244
+ mock_entry_to_memory.assert_not_called()
245
+
246
+ @patch("skcapstone.memory_adapter.entry_to_memory")
247
+ @patch("skcapstone.memory_adapter.get_unified")
248
+ def test_migrates_new_memories(
249
+ self,
250
+ mock_get: MagicMock,
251
+ mock_entry_to_memory: MagicMock,
252
+ tmp_path: Path,
253
+ ) -> None:
254
+ """New memories are converted and saved to the store."""
255
+ mock_store = MagicMock()
256
+ mock_store.list_memories.return_value = [] # nothing existing
257
+ mock_store.vector = None
258
+ mock_store.graph = None
259
+ mock_get.return_value = mock_store
260
+
261
+ mock_memory = MagicMock()
262
+ mock_entry_to_memory.return_value = mock_memory
263
+
264
+ _populate_layer(
265
+ tmp_path,
266
+ "short-term",
267
+ {
268
+ "m1.json": _make_memory_json(memory_id="new-1"),
269
+ "m2.json": _make_memory_json(memory_id="new-2"),
270
+ },
271
+ )
272
+
273
+ result = migrate(tmp_path)
274
+ assert result["ok"] is True
275
+ assert result["migrated"] == 2
276
+ assert result["skipped_existing"] == 0
277
+ assert mock_store.primary.save.call_count == 2
278
+ assert mock_memory.seal.call_count == 2
279
+
280
+ @patch("skcapstone.memory_adapter.entry_to_memory")
281
+ @patch("skcapstone.memory_adapter.get_unified")
282
+ def test_records_errors_for_failed_entries(
283
+ self,
284
+ mock_get: MagicMock,
285
+ mock_entry_to_memory: MagicMock,
286
+ tmp_path: Path,
287
+ ) -> None:
288
+ """Entries that fail during migration are recorded in errors list."""
289
+ mock_store = MagicMock()
290
+ mock_store.list_memories.return_value = []
291
+ mock_store.vector = None
292
+ mock_store.graph = None
293
+ mock_get.return_value = mock_store
294
+
295
+ mock_entry_to_memory.side_effect = RuntimeError("conversion failed")
296
+
297
+ _populate_layer(
298
+ tmp_path,
299
+ "short-term",
300
+ {"fail.json": _make_memory_json(memory_id="fail-1")},
301
+ )
302
+
303
+ result = migrate(tmp_path)
304
+ assert result["ok"] is True # ok tracks overall process, not individual errors
305
+ assert result["migrated"] == 0
306
+ assert len(result["errors"]) == 1
307
+ assert "fail-1" in result["errors"][0]
308
+ assert "conversion failed" in result["errors"][0]
309
+
310
+ @patch("skcapstone.memory_adapter.entry_to_memory")
311
+ @patch("skcapstone.memory_adapter.get_unified")
312
+ def test_vector_and_graph_failures_do_not_block_primary(
313
+ self,
314
+ mock_get: MagicMock,
315
+ mock_entry_to_memory: MagicMock,
316
+ tmp_path: Path,
317
+ ) -> None:
318
+ """Failures in vector/graph backends do not prevent primary save."""
319
+ mock_store = MagicMock()
320
+ mock_store.list_memories.return_value = []
321
+ mock_store.vector = MagicMock()
322
+ mock_store.graph = MagicMock()
323
+ mock_store.vector.save.side_effect = RuntimeError("skvector down")
324
+ mock_store.graph.index_memory.side_effect = RuntimeError("skgraph down")
325
+ mock_get.return_value = mock_store
326
+
327
+ mock_memory = MagicMock()
328
+ mock_entry_to_memory.return_value = mock_memory
329
+
330
+ _populate_layer(
331
+ tmp_path,
332
+ "short-term",
333
+ {"v.json": _make_memory_json(memory_id="vec-1")},
334
+ )
335
+
336
+ result = migrate(tmp_path)
337
+ assert result["migrated"] == 1
338
+ assert len(result["errors"]) == 0 # vector/graph errors are debug-logged, not recorded
339
+
340
+ @patch("skcapstone.memory_adapter.get_unified")
341
+ def test_verify_delegates_to_verify_migration(
342
+ self, mock_get: MagicMock, tmp_path: Path
343
+ ) -> None:
344
+ """When verify=True, migrate delegates to _verify_migration."""
345
+ mock_store = MagicMock()
346
+ mock_store.recall.return_value = MagicMock() # present
347
+ mock_get.return_value = mock_store
348
+
349
+ _populate_layer(
350
+ tmp_path,
351
+ "short-term",
352
+ {"v.json": _make_memory_json(memory_id="ver-1")},
353
+ )
354
+
355
+ result = migrate(tmp_path, verify=True)
356
+ assert result["verify"] is True
357
+ assert result["ok"] is True
358
+ assert result["verified"] == 1
359
+ assert result["missing"] == []
360
+
361
+
362
+ # ---------------------------------------------------------------------------
363
+ # TestVerifyMigration
364
+ # ---------------------------------------------------------------------------
365
+
366
+
367
+ class TestVerifyMigration:
368
+ """Tests for _verify_migration."""
369
+
370
+ def _make_entries(self, ids: list[str]) -> list[MemoryEntry]:
371
+ """Create minimal MemoryEntry list from a set of ids."""
372
+ return [
373
+ MemoryEntry(memory_id=mid, content=f"Content for {mid}") for mid in ids
374
+ ]
375
+
376
+ def test_all_present_returns_ok_true(self) -> None:
377
+ """When all entries are found in the store, ok is True."""
378
+ entries = self._make_entries(["a", "b", "c"])
379
+ mock_store = MagicMock()
380
+ mock_store.recall.return_value = MagicMock() # always returns something
381
+
382
+ result = {
383
+ "ok": True,
384
+ "total_json": 3,
385
+ "migrated": 0,
386
+ "skipped_existing": 0,
387
+ "errors": [],
388
+ }
389
+ out = _verify_migration(entries, mock_store, result)
390
+ assert out["ok"] is True
391
+ assert out["verified"] == 3
392
+ assert out["missing"] == []
393
+
394
+ def test_missing_memories_reported(self) -> None:
395
+ """When store.recall returns None, the memory id appears in missing."""
396
+ entries = self._make_entries(["found-1", "gone-1", "gone-2"])
397
+ mock_store = MagicMock()
398
+
399
+ def recall_side(mid: str):
400
+ if mid == "found-1":
401
+ return MagicMock()
402
+ return None
403
+
404
+ mock_store.recall.side_effect = recall_side
405
+
406
+ result = {
407
+ "ok": True,
408
+ "total_json": 3,
409
+ "migrated": 0,
410
+ "skipped_existing": 0,
411
+ "errors": [],
412
+ }
413
+ out = _verify_migration(entries, mock_store, result)
414
+ assert out["ok"] is False
415
+ assert out["verified"] == 1
416
+ assert set(out["missing"]) == {"gone-1", "gone-2"}
417
+
418
+ def test_store_recall_exception_handled(self) -> None:
419
+ """When store.recall raises, the memory is treated as missing."""
420
+ entries = self._make_entries(["err-1"])
421
+ mock_store = MagicMock()
422
+ mock_store.recall.side_effect = RuntimeError("db failure")
423
+
424
+ result = {
425
+ "ok": True,
426
+ "total_json": 1,
427
+ "migrated": 0,
428
+ "skipped_existing": 0,
429
+ "errors": [],
430
+ }
431
+ out = _verify_migration(entries, mock_store, result)
432
+ assert out["ok"] is False
433
+ assert "err-1" in out["missing"]
434
+
435
+ def test_empty_entries_returns_ok(self) -> None:
436
+ """Verifying an empty entry list returns ok with zero counts."""
437
+ mock_store = MagicMock()
438
+ result = {
439
+ "ok": True,
440
+ "total_json": 0,
441
+ "migrated": 0,
442
+ "skipped_existing": 0,
443
+ "errors": [],
444
+ }
445
+ out = _verify_migration([], mock_store, result)
446
+ assert out["ok"] is True
447
+ assert out["verified"] == 0
448
+ assert out["missing"] == []
449
+
450
+ def test_verify_flag_is_set(self) -> None:
451
+ """The result dict gets verify=True added by _verify_migration."""
452
+ entries = self._make_entries(["x"])
453
+ mock_store = MagicMock()
454
+ mock_store.recall.return_value = MagicMock()
455
+
456
+ result = {
457
+ "ok": True,
458
+ "total_json": 1,
459
+ "migrated": 0,
460
+ "skipped_existing": 0,
461
+ "errors": [],
462
+ }
463
+ out = _verify_migration(entries, mock_store, result)
464
+ assert out["verify"] is True