@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,397 @@
1
+ """Tests for encrypted file transfer."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+
10
+ from skcapstone.file_transfer import (
11
+ FileTransfer,
12
+ TransferManifest,
13
+ ChunkInfo,
14
+ TransferStatus,
15
+ CHUNK_SIZE,
16
+ )
17
+
18
+
19
+ @pytest.fixture
20
+ def home(tmp_path: Path) -> Path:
21
+ """Create a minimal agent home for file transfer tests."""
22
+ identity_dir = tmp_path / "identity"
23
+ identity_dir.mkdir()
24
+ (identity_dir / "identity.json").write_text(json.dumps({
25
+ "name": "test-agent",
26
+ "fingerprint": "ABCD1234567890ABCDEF1234567890ABCDEF1234",
27
+ }), encoding="utf-8")
28
+
29
+ security_dir = tmp_path / "security"
30
+ security_dir.mkdir()
31
+
32
+ return tmp_path
33
+
34
+
35
+ @pytest.fixture
36
+ def ft(home: Path) -> FileTransfer:
37
+ """Create an initialized FileTransfer instance."""
38
+ t = FileTransfer(home, agent_name="opus", chunk_size=1024)
39
+ t.initialize()
40
+ return t
41
+
42
+
43
+ @pytest.fixture
44
+ def sample_file(tmp_path: Path) -> Path:
45
+ """Create a sample file for transfer."""
46
+ f = tmp_path / "test-document.txt"
47
+ f.write_text("Hello, sovereign world! " * 100, encoding="utf-8")
48
+ return f
49
+
50
+
51
+ @pytest.fixture
52
+ def large_file(tmp_path: Path) -> Path:
53
+ """Create a file larger than one chunk."""
54
+ f = tmp_path / "large-file.bin"
55
+ f.write_bytes(b"X" * 3000) # 3 chunks at 1024 bytes
56
+ return f
57
+
58
+
59
+ # ---------------------------------------------------------------------------
60
+ # Initialization
61
+ # ---------------------------------------------------------------------------
62
+
63
+
64
+ class TestInitialization:
65
+ """Tests for file transfer setup."""
66
+
67
+ def test_initialize_creates_dirs(self, home: Path) -> None:
68
+ """Initialize creates directory structure."""
69
+ ft = FileTransfer(home)
70
+ ft.initialize()
71
+ assert (home / "file-transfer" / "outbox").is_dir()
72
+ assert (home / "file-transfer" / "inbox").is_dir()
73
+ assert (home / "file-transfer" / "completed").is_dir()
74
+
75
+ def test_initialize_idempotent(self, ft: FileTransfer, home: Path) -> None:
76
+ """Multiple initializations don't break anything."""
77
+ ft.initialize()
78
+ ft.initialize()
79
+ assert (home / "file-transfer" / "outbox").is_dir()
80
+
81
+
82
+ # ---------------------------------------------------------------------------
83
+ # Sending
84
+ # ---------------------------------------------------------------------------
85
+
86
+
87
+ class TestSend:
88
+ """Tests for file sending."""
89
+
90
+ def test_send_creates_manifest(
91
+ self, ft: FileTransfer, sample_file: Path, home: Path,
92
+ ) -> None:
93
+ """Send creates a manifest file."""
94
+ manifest = ft.send(sample_file, recipient="lumina")
95
+ manifest_path = home / "file-transfer" / "outbox" / manifest.transfer_id / "manifest.json"
96
+ assert manifest_path.exists()
97
+
98
+ def test_send_creates_chunks(
99
+ self, ft: FileTransfer, sample_file: Path, home: Path,
100
+ ) -> None:
101
+ """Send creates encrypted chunk files."""
102
+ manifest = ft.send(sample_file, recipient="lumina")
103
+ transfer_dir = home / "file-transfer" / "outbox" / manifest.transfer_id
104
+ chunks = list(transfer_dir.glob("chunk-*.enc"))
105
+ assert len(chunks) == manifest.total_chunks
106
+ assert len(chunks) > 0
107
+
108
+ def test_send_manifest_metadata(
109
+ self, ft: FileTransfer, sample_file: Path,
110
+ ) -> None:
111
+ """Manifest contains correct file metadata."""
112
+ manifest = ft.send(sample_file, recipient="lumina")
113
+ assert manifest.filename == "test-document.txt"
114
+ assert manifest.file_size == sample_file.stat().st_size
115
+ assert manifest.sender == "opus"
116
+ assert manifest.recipient == "lumina"
117
+ assert manifest.file_sha256
118
+ assert manifest.total_chunks > 0
119
+
120
+ def test_send_marks_chunks_sent(
121
+ self, ft: FileTransfer, sample_file: Path,
122
+ ) -> None:
123
+ """All chunks are marked as sent."""
124
+ manifest = ft.send(sample_file, recipient="grok")
125
+ assert all(c.sent for c in manifest.chunks)
126
+
127
+ def test_send_multiple_chunks(
128
+ self, ft: FileTransfer, large_file: Path,
129
+ ) -> None:
130
+ """Large files produce multiple chunks."""
131
+ manifest = ft.send(large_file, recipient="lumina")
132
+ assert manifest.total_chunks == 3
133
+
134
+ def test_send_nonexistent_file_raises(self, ft: FileTransfer) -> None:
135
+ """Sending a nonexistent file raises FileNotFoundError."""
136
+ with pytest.raises(FileNotFoundError):
137
+ ft.send(Path("/nonexistent/file.txt"), recipient="lumina")
138
+
139
+ def test_send_empty_file_raises(self, ft: FileTransfer, tmp_path: Path) -> None:
140
+ """Sending an empty file raises ValueError."""
141
+ empty = tmp_path / "empty.txt"
142
+ empty.write_bytes(b"")
143
+ with pytest.raises(ValueError, match="empty"):
144
+ ft.send(empty, recipient="lumina")
145
+
146
+ def test_send_without_encryption(
147
+ self, ft: FileTransfer, sample_file: Path,
148
+ ) -> None:
149
+ """Files can be sent without encryption."""
150
+ manifest = ft.send(sample_file, recipient="lumina", encrypt=False)
151
+ assert all(not c.encrypted for c in manifest.chunks)
152
+
153
+
154
+ # ---------------------------------------------------------------------------
155
+ # Receiving
156
+ # ---------------------------------------------------------------------------
157
+
158
+
159
+ class TestReceive:
160
+ """Tests for file receiving."""
161
+
162
+ def test_receive_reassembles_file(
163
+ self, ft: FileTransfer, sample_file: Path, home: Path,
164
+ ) -> None:
165
+ """Receive reassembles the original file."""
166
+ manifest = ft.send(sample_file, recipient="lumina")
167
+ output = ft.receive(manifest.transfer_id)
168
+ assert output.exists()
169
+ assert output.read_bytes() == sample_file.read_bytes()
170
+
171
+ def test_receive_large_file(
172
+ self, ft: FileTransfer, large_file: Path,
173
+ ) -> None:
174
+ """Receive handles multi-chunk files."""
175
+ manifest = ft.send(large_file, recipient="lumina")
176
+ output = ft.receive(manifest.transfer_id)
177
+ assert output.read_bytes() == large_file.read_bytes()
178
+
179
+ def test_receive_records_completion(
180
+ self, ft: FileTransfer, sample_file: Path, home: Path,
181
+ ) -> None:
182
+ """Receive writes a completion receipt."""
183
+ manifest = ft.send(sample_file, recipient="lumina")
184
+ ft.receive(manifest.transfer_id)
185
+ receipt = home / "file-transfer" / "completed" / f"{manifest.transfer_id}.json"
186
+ assert receipt.exists()
187
+
188
+ def test_receive_custom_output_dir(
189
+ self, ft: FileTransfer, sample_file: Path, tmp_path: Path,
190
+ ) -> None:
191
+ """Receive writes to custom output directory."""
192
+ manifest = ft.send(sample_file, recipient="lumina")
193
+ output_dir = tmp_path / "downloads"
194
+ output = ft.receive(manifest.transfer_id, output_dir=output_dir)
195
+ assert output.parent == output_dir
196
+ assert output.read_bytes() == sample_file.read_bytes()
197
+
198
+ def test_receive_nonexistent_transfer_raises(self, ft: FileTransfer) -> None:
199
+ """Receiving a nonexistent transfer raises FileNotFoundError."""
200
+ with pytest.raises(FileNotFoundError):
201
+ ft.receive("nonexistent-id")
202
+
203
+ def test_receive_detects_tampering(
204
+ self, ft: FileTransfer, sample_file: Path, home: Path,
205
+ ) -> None:
206
+ """Receive detects tampered chunks."""
207
+ manifest = ft.send(sample_file, recipient="lumina", encrypt=False)
208
+ # Tamper with a chunk
209
+ transfer_dir = home / "file-transfer" / "outbox" / manifest.transfer_id
210
+ chunk_file = list(transfer_dir.glob("chunk-*.enc"))[0]
211
+ chunk_file.write_bytes(b"TAMPERED DATA")
212
+
213
+ with pytest.raises(ValueError, match="integrity"):
214
+ ft.receive(manifest.transfer_id)
215
+
216
+ def test_receive_without_encryption(
217
+ self, ft: FileTransfer, sample_file: Path,
218
+ ) -> None:
219
+ """Unencrypted transfers reassemble correctly."""
220
+ manifest = ft.send(sample_file, recipient="lumina", encrypt=False)
221
+ output = ft.receive(manifest.transfer_id)
222
+ assert output.read_bytes() == sample_file.read_bytes()
223
+
224
+
225
+ # ---------------------------------------------------------------------------
226
+ # Resume
227
+ # ---------------------------------------------------------------------------
228
+
229
+
230
+ class TestResume:
231
+ """Tests for transfer resume functionality."""
232
+
233
+ def test_resume_send_complete(
234
+ self, ft: FileTransfer, sample_file: Path,
235
+ ) -> None:
236
+ """Complete transfer has no unsent chunks."""
237
+ manifest = ft.send(sample_file, recipient="lumina")
238
+ unsent = ft.resume_send(manifest.transfer_id)
239
+ assert unsent == []
240
+
241
+ def test_resume_receive_all_present(
242
+ self, ft: FileTransfer, sample_file: Path,
243
+ ) -> None:
244
+ """Transfer with all chunks has no missing."""
245
+ manifest = ft.send(sample_file, recipient="lumina")
246
+ missing = ft.resume_receive(manifest.transfer_id)
247
+ assert missing == []
248
+
249
+ def test_resume_receive_missing_chunks(
250
+ self, ft: FileTransfer, large_file: Path, home: Path,
251
+ ) -> None:
252
+ """Detect missing chunks for resume."""
253
+ manifest = ft.send(large_file, recipient="lumina")
254
+ # Delete a chunk to simulate interrupted transfer
255
+ transfer_dir = home / "file-transfer" / "outbox" / manifest.transfer_id
256
+ (transfer_dir / "chunk-0001.enc").unlink()
257
+
258
+ missing = ft.resume_receive(manifest.transfer_id)
259
+ assert 1 in missing
260
+
261
+ def test_resume_nonexistent_transfer(self, ft: FileTransfer) -> None:
262
+ """Resume on nonexistent transfer returns empty."""
263
+ assert ft.resume_send("ghost") == []
264
+ assert ft.resume_receive("ghost") == []
265
+
266
+
267
+ # ---------------------------------------------------------------------------
268
+ # Listing
269
+ # ---------------------------------------------------------------------------
270
+
271
+
272
+ class TestListTransfers:
273
+ """Tests for transfer listing."""
274
+
275
+ def test_list_empty(self, ft: FileTransfer) -> None:
276
+ """Empty transfer system returns no items."""
277
+ assert ft.list_transfers() == []
278
+
279
+ def test_list_after_send(
280
+ self, ft: FileTransfer, sample_file: Path,
281
+ ) -> None:
282
+ """Sent transfers appear in listing."""
283
+ ft.send(sample_file, recipient="lumina")
284
+ transfers = ft.list_transfers()
285
+ assert len(transfers) == 1
286
+ assert transfers[0].direction == "send"
287
+ assert transfers[0].filename == "test-document.txt"
288
+
289
+ def test_list_filter_direction(
290
+ self, ft: FileTransfer, sample_file: Path,
291
+ ) -> None:
292
+ """Can filter by send/receive direction."""
293
+ ft.send(sample_file, recipient="lumina")
294
+ assert len(ft.list_transfers(direction="send")) == 1
295
+ assert len(ft.list_transfers(direction="receive")) == 0
296
+
297
+ def test_list_progress(
298
+ self, ft: FileTransfer, sample_file: Path,
299
+ ) -> None:
300
+ """Transfer status shows progress."""
301
+ ft.send(sample_file, recipient="lumina")
302
+ status = ft.list_transfers()[0]
303
+ assert status.progress == 1.0
304
+ assert status.chunks_done == status.total_chunks
305
+
306
+
307
+ # ---------------------------------------------------------------------------
308
+ # Manifest and status
309
+ # ---------------------------------------------------------------------------
310
+
311
+
312
+ class TestManifestAndStatus:
313
+ """Tests for manifest retrieval and status."""
314
+
315
+ def test_get_manifest(
316
+ self, ft: FileTransfer, sample_file: Path,
317
+ ) -> None:
318
+ """Get manifest by transfer ID."""
319
+ manifest = ft.send(sample_file, recipient="lumina")
320
+ retrieved = ft.get_manifest(manifest.transfer_id)
321
+ assert retrieved is not None
322
+ assert retrieved.filename == manifest.filename
323
+
324
+ def test_get_manifest_nonexistent(self, ft: FileTransfer) -> None:
325
+ """Getting nonexistent manifest returns None."""
326
+ assert ft.get_manifest("ghost") is None
327
+
328
+ def test_status_summary(self, ft: FileTransfer, sample_file: Path) -> None:
329
+ """Status returns structured summary."""
330
+ ft.send(sample_file, recipient="lumina")
331
+ status = ft.status()
332
+ assert status["outbox_transfers"] == 1
333
+ assert status["inbox_transfers"] == 0
334
+
335
+
336
+ # ---------------------------------------------------------------------------
337
+ # Cleanup
338
+ # ---------------------------------------------------------------------------
339
+
340
+
341
+ class TestCleanup:
342
+ """Tests for transfer cleanup."""
343
+
344
+ def test_cleanup_removes_files(
345
+ self, ft: FileTransfer, sample_file: Path, home: Path,
346
+ ) -> None:
347
+ """Cleanup removes transfer directory."""
348
+ manifest = ft.send(sample_file, recipient="lumina")
349
+ assert ft.cleanup(manifest.transfer_id) is True
350
+ transfer_dir = home / "file-transfer" / "outbox" / manifest.transfer_id
351
+ assert not transfer_dir.exists()
352
+
353
+ def test_cleanup_nonexistent(self, ft: FileTransfer) -> None:
354
+ """Cleaning up nonexistent transfer returns False."""
355
+ assert ft.cleanup("ghost") is False
356
+
357
+
358
+ # ---------------------------------------------------------------------------
359
+ # Model tests
360
+ # ---------------------------------------------------------------------------
361
+
362
+
363
+ class TestModels:
364
+ """Tests for transfer models."""
365
+
366
+ def test_manifest_progress_empty(self) -> None:
367
+ """Empty manifest has zero progress."""
368
+ m = TransferManifest(
369
+ filename="test", file_size=100,
370
+ file_sha256="abc", total_chunks=0,
371
+ )
372
+ assert m.progress == 0.0
373
+
374
+ def test_manifest_is_complete(self) -> None:
375
+ """Complete manifest detected correctly."""
376
+ m = TransferManifest(
377
+ filename="test", file_size=100,
378
+ file_sha256="abc", total_chunks=1,
379
+ chunks=[ChunkInfo(index=0, size=100, sha256="def", sent=True, received=True)],
380
+ )
381
+ assert m.is_complete is True
382
+
383
+ def test_manifest_not_complete(self) -> None:
384
+ """Incomplete manifest detected correctly."""
385
+ m = TransferManifest(
386
+ filename="test", file_size=100,
387
+ file_sha256="abc", total_chunks=1,
388
+ chunks=[ChunkInfo(index=0, size=100, sha256="def", sent=True, received=False)],
389
+ )
390
+ assert m.is_complete is False
391
+
392
+ def test_chunk_info_defaults(self) -> None:
393
+ """ChunkInfo has sensible defaults."""
394
+ c = ChunkInfo(index=0, size=1024, sha256="abc")
395
+ assert c.encrypted is True
396
+ assert c.sent is False
397
+ assert c.received is False