@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,285 @@
1
+ """Error queue commands: list, retry, clear."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ import click
10
+ from rich.table import Table
11
+ from rich.text import Text
12
+
13
+ from ._common import console
14
+
15
+
16
+ def register_errors_commands(main: click.Group) -> None:
17
+ """Register the ``errors`` command group."""
18
+
19
+ @main.group("errors")
20
+ def errors_grp():
21
+ """Error recovery queue — inspect and replay failed operations.
22
+
23
+ Failed LLM calls, message sends, and sync operations land here
24
+ and are retried automatically with exponential backoff (max 3 times).
25
+ """
26
+
27
+ # ------------------------------------------------------------------
28
+ # errors list
29
+ # ------------------------------------------------------------------
30
+
31
+ @errors_grp.command("list")
32
+ @click.option(
33
+ "--path",
34
+ default=None,
35
+ type=click.Path(),
36
+ help="Override error queue JSON path.",
37
+ )
38
+ @click.option(
39
+ "--all", "show_all",
40
+ is_flag=True,
41
+ help="Include resolved entries.",
42
+ )
43
+ @click.option(
44
+ "--status",
45
+ type=click.Choice(["pending", "retrying", "exhausted", "resolved"]),
46
+ default=None,
47
+ help="Filter by status.",
48
+ )
49
+ def errors_list(path, show_all, status):
50
+ """List queued error entries."""
51
+ from ..error_queue import ErrorQueue
52
+
53
+ q = ErrorQueue(path=Path(path) if path else None)
54
+ entries = q.list_entries(status=status, include_resolved=show_all)
55
+
56
+ stats = q.stats()
57
+ console.print(
58
+ f"\n Error queue — "
59
+ f"[yellow]{stats.get('pending', 0)}[/] pending "
60
+ f"[red]{stats.get('exhausted', 0)}[/] exhausted "
61
+ f"[green]{stats.get('resolved', 0)}[/] resolved "
62
+ f"([dim]{stats.get('total', 0)} total[/])\n"
63
+ )
64
+
65
+ if not entries:
66
+ console.print(" [dim]Queue is empty.[/]\n")
67
+ return
68
+
69
+ table = Table(show_header=True, header_style="bold", box=None, padding=(0, 2))
70
+ table.add_column("ID", style="cyan", max_width=12)
71
+ table.add_column("Type")
72
+ table.add_column("Error", max_width=40)
73
+ table.add_column("Retries", justify="right")
74
+ table.add_column("Status")
75
+ table.add_column("Next retry", style="dim")
76
+
77
+ status_styles = {
78
+ "pending": "yellow",
79
+ "retrying": "blue",
80
+ "exhausted": "red",
81
+ "resolved": "green",
82
+ }
83
+
84
+ for entry in entries:
85
+ color = status_styles.get(entry.status, "dim")
86
+ table.add_row(
87
+ entry.entry_id[:10],
88
+ entry.operation_type,
89
+ entry.error_message[:60] + ("…" if len(entry.error_message) > 60 else ""),
90
+ str(entry.retry_count),
91
+ Text(entry.status, style=color),
92
+ entry.next_retry_at[:19].replace("T", " ") if entry.next_retry_at else "—",
93
+ )
94
+
95
+ console.print(table)
96
+ console.print()
97
+
98
+ # ------------------------------------------------------------------
99
+ # errors retry
100
+ # ------------------------------------------------------------------
101
+
102
+ @errors_grp.command("retry")
103
+ @click.argument("entry_id", required=False, default=None)
104
+ @click.option(
105
+ "--all", "retry_all",
106
+ is_flag=True,
107
+ help="Retry all due entries.",
108
+ )
109
+ @click.option(
110
+ "--path",
111
+ default=None,
112
+ type=click.Path(),
113
+ help="Override error queue JSON path.",
114
+ )
115
+ def errors_retry(entry_id, retry_all, path):
116
+ """Retry a specific entry or all due entries.
117
+
118
+ ENTRY_ID Hex entry ID (or prefix) to retry.
119
+
120
+ Without --all, ENTRY_ID is required.
121
+ """
122
+ from ..error_queue import ErrorQueue
123
+
124
+ if not retry_all and not entry_id:
125
+ console.print("[red]Provide ENTRY_ID or use --all.[/]")
126
+ sys.exit(1)
127
+
128
+ q = ErrorQueue(path=Path(path) if path else None)
129
+
130
+ if retry_all:
131
+ results = q.retry_all_due()
132
+ if not results:
133
+ console.print("\n [dim]No entries currently due for retry.[/]\n")
134
+ return
135
+ ok = sum(1 for v in results.values() if v)
136
+ fail = len(results) - ok
137
+ console.print(
138
+ f"\n Retried [bold]{len(results)}[/] entries — "
139
+ f"[green]{ok} resolved[/] [yellow]{fail} still pending[/]\n"
140
+ )
141
+ return
142
+
143
+ # Single entry: allow prefix matching
144
+ entries = q.list_entries(include_resolved=True)
145
+ matched = [e for e in entries if e.entry_id.startswith(entry_id)]
146
+ if not matched:
147
+ console.print(f"[red]No entry found matching '[/]{entry_id}[red]'.[/]")
148
+ sys.exit(1)
149
+ if len(matched) > 1:
150
+ console.print(
151
+ f"[yellow]Ambiguous prefix '[/]{entry_id}[yellow]' — "
152
+ f"matches {len(matched)} entries. Use more characters.[/]"
153
+ )
154
+ sys.exit(1)
155
+
156
+ success = q.retry(matched[0].entry_id)
157
+ if success:
158
+ console.print(f"\n [green]Resolved:[/] {matched[0].entry_id[:10]}\n")
159
+ else:
160
+ console.print(
161
+ f"\n [yellow]Retry recorded for:[/] {matched[0].entry_id[:10]} "
162
+ f"(retries={matched[0].retry_count})\n"
163
+ )
164
+
165
+ # ------------------------------------------------------------------
166
+ # errors clear
167
+ # ------------------------------------------------------------------
168
+
169
+ @errors_grp.command("clear")
170
+ @click.argument("entry_id", required=False, default=None)
171
+ @click.option(
172
+ "--all", "clear_all",
173
+ is_flag=True,
174
+ help="Clear all entries.",
175
+ )
176
+ @click.option(
177
+ "--exhausted",
178
+ is_flag=True,
179
+ help="Clear only exhausted entries.",
180
+ )
181
+ @click.option(
182
+ "--resolved",
183
+ is_flag=True,
184
+ help="Clear only resolved entries.",
185
+ )
186
+ @click.option(
187
+ "--path",
188
+ default=None,
189
+ type=click.Path(),
190
+ help="Override error queue JSON path.",
191
+ )
192
+ @click.option("--force", is_flag=True, help="Skip confirmation prompt.")
193
+ def errors_clear(entry_id, clear_all, exhausted, resolved, path, force):
194
+ """Remove entries from the queue.
195
+
196
+ ENTRY_ID Hex entry ID (or prefix) to remove.
197
+
198
+ Use --all, --exhausted, or --resolved for bulk removal.
199
+ """
200
+ from ..error_queue import ErrorQueue, ErrorStatus
201
+
202
+ if not any([entry_id, clear_all, exhausted, resolved]):
203
+ console.print(
204
+ "[red]Provide ENTRY_ID, --all, --exhausted, or --resolved.[/]"
205
+ )
206
+ sys.exit(1)
207
+
208
+ q = ErrorQueue(path=Path(path) if path else None)
209
+
210
+ if exhausted:
211
+ if not force and not click.confirm("Clear all exhausted entries?"):
212
+ console.print("[yellow]Aborted.[/]")
213
+ return
214
+ removed = q.clear_all(status=ErrorStatus.EXHAUSTED)
215
+ console.print(f"\n [red]Cleared[/] {removed} exhausted entr{'y' if removed == 1 else 'ies'}.\n")
216
+ return
217
+
218
+ if resolved:
219
+ if not force and not click.confirm("Clear all resolved entries?"):
220
+ console.print("[yellow]Aborted.[/]")
221
+ return
222
+ removed = q.clear_all(status=ErrorStatus.RESOLVED)
223
+ console.print(f"\n [green]Cleared[/] {removed} resolved entr{'y' if removed == 1 else 'ies'}.\n")
224
+ return
225
+
226
+ if clear_all:
227
+ stats = q.stats()
228
+ total = stats.get("total", 0)
229
+ if not force and not click.confirm(f"Clear all {total} entries?"):
230
+ console.print("[yellow]Aborted.[/]")
231
+ return
232
+ removed = q.clear_all()
233
+ console.print(f"\n Cleared [bold]{removed}[/] entr{'y' if removed == 1 else 'ies'}.\n")
234
+ return
235
+
236
+ # Single entry
237
+ entries = q.list_entries(include_resolved=True)
238
+ matched = [e for e in entries if e.entry_id.startswith(entry_id)]
239
+ if not matched:
240
+ console.print(f"[red]No entry found matching '[/]{entry_id}[red]'.[/]")
241
+ sys.exit(1)
242
+ if len(matched) > 1:
243
+ console.print(
244
+ f"[yellow]Ambiguous prefix '[/]{entry_id}[yellow]' — "
245
+ f"matches {len(matched)} entries.[/]"
246
+ )
247
+ sys.exit(1)
248
+
249
+ if not force and not click.confirm(f"Remove entry {matched[0].entry_id[:10]}?"):
250
+ console.print("[yellow]Aborted.[/]")
251
+ return
252
+
253
+ q.remove(matched[0].entry_id)
254
+ console.print(f"\n [red]Removed:[/] {matched[0].entry_id[:10]}\n")
255
+
256
+ # ------------------------------------------------------------------
257
+ # errors stats
258
+ # ------------------------------------------------------------------
259
+
260
+ @errors_grp.command("stats")
261
+ @click.option(
262
+ "--path",
263
+ default=None,
264
+ type=click.Path(),
265
+ help="Override error queue JSON path.",
266
+ )
267
+ def errors_stats(path):
268
+ """Show error queue statistics."""
269
+ from ..error_queue import ErrorQueue
270
+ from rich.panel import Panel
271
+
272
+ q = ErrorQueue(path=Path(path) if path else None)
273
+ s = q.stats()
274
+
275
+ console.print()
276
+ console.print(Panel(
277
+ f"[bold]Total:[/] {s.get('total', 0)}\n"
278
+ f"[yellow]Pending:[/] {s.get('pending', 0)}\n"
279
+ f"[blue]Retrying:[/] {s.get('retrying', 0)}\n"
280
+ f"[red]Exhausted:[/] {s.get('exhausted', 0)}\n"
281
+ f"[green]Resolved:[/] {s.get('resolved', 0)}",
282
+ title="Error Queue",
283
+ border_style="bright_blue",
284
+ ))
285
+ console.print()
@@ -0,0 +1,156 @@
1
+ """Export and import commands for portable agent state bundles."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ import click
10
+
11
+ from ._common import AGENT_HOME, console
12
+
13
+ from rich.panel import Panel
14
+
15
+
16
+ def register_export_commands(main: click.Group) -> None:
17
+ """Register the export and import commands."""
18
+
19
+ @main.command("export")
20
+ @click.option("--home", default=AGENT_HOME, type=click.Path(), help="Agent home directory.")
21
+ @click.option(
22
+ "--output", "-o", default=None, type=click.Path(),
23
+ help="Output file path. Defaults to stdout.",
24
+ )
25
+ @click.option(
26
+ "--pretty/--compact", default=True,
27
+ help="Pretty-print JSON (default) or compact output.",
28
+ )
29
+ def export_cmd(home: str, output: str | None, pretty: bool):
30
+ """Export the full agent state as a portable JSON bundle.
31
+
32
+ Collects identity, soul overlays, memories, conversations, and
33
+ config into a single JSON document. Use ``--output`` to write to
34
+ a file, or pipe stdout for use in scripts.
35
+
36
+ Examples:
37
+
38
+ skcapstone export
39
+
40
+ skcapstone export --output agent-snapshot.json
41
+
42
+ skcapstone export --compact | gzip > snapshot.json.gz
43
+ """
44
+ from ..export import export_bundle
45
+
46
+ home_path = Path(home).expanduser()
47
+ if not home_path.exists():
48
+ console.print(f"[red]Agent home not found: {home_path}[/]")
49
+ raise SystemExit(1)
50
+
51
+ try:
52
+ bundle = export_bundle(home_path)
53
+ except Exception as exc:
54
+ console.print(f"[red]Export failed: {exc}[/]")
55
+ raise SystemExit(1)
56
+
57
+ indent = 2 if pretty else None
58
+ serialized = json.dumps(bundle, indent=indent, ensure_ascii=False)
59
+
60
+ if output:
61
+ out_path = Path(output).expanduser()
62
+ out_path.parent.mkdir(parents=True, exist_ok=True)
63
+ out_path.write_text(serialized, encoding="utf-8")
64
+ size_kb = out_path.stat().st_size / 1024
65
+ console.print(Panel(
66
+ f"[bold green]Export complete[/]\n"
67
+ f"Agent: {bundle['agent_name']}\n"
68
+ f"Memories: {len(bundle['memories'])}\n"
69
+ f"Conversations: {len(bundle['conversations'])}\n"
70
+ f"Soul overlays: {len((bundle.get('soul') or {}).get('installed') or {})}\n"
71
+ f"Size: {size_kb:.1f} KB\n"
72
+ f"File: [cyan]{out_path}[/]",
73
+ title="Agent Bundle Exported",
74
+ border_style="green",
75
+ ))
76
+ else:
77
+ sys.stdout.write(serialized)
78
+ sys.stdout.write("\n")
79
+ sys.stdout.flush()
80
+
81
+ @main.command("import")
82
+ @click.argument("bundle_file", metavar="BUNDLE")
83
+ @click.option("--home", default=AGENT_HOME, type=click.Path(), help="Target agent home directory.")
84
+ @click.option("--overwrite-identity", is_flag=True, help="Overwrite existing identity file.")
85
+ @click.option("--overwrite-config", is_flag=True, help="Overwrite existing config file.")
86
+ @click.option("--overwrite-soul", is_flag=True, help="Overwrite existing soul files.")
87
+ def import_cmd(
88
+ bundle_file: str,
89
+ home: str,
90
+ overwrite_identity: bool,
91
+ overwrite_config: bool,
92
+ overwrite_soul: bool,
93
+ ):
94
+ """Import an agent state bundle into a home directory.
95
+
96
+ Memories are always merged (existing memories with the same ID are
97
+ kept). Conversations are merged per peer. Identity, config, and soul
98
+ are only written when their target file is absent — unless the
99
+ corresponding ``--overwrite-*`` flag is passed.
100
+
101
+ Examples:
102
+
103
+ skcapstone import agent-snapshot.json
104
+
105
+ skcapstone import snapshot.json --home ~/.skcapstone-new
106
+
107
+ skcapstone import snapshot.json --overwrite-identity --overwrite-config
108
+ """
109
+ from ..export import import_bundle
110
+
111
+ bundle_path = Path(bundle_file).expanduser()
112
+ if not bundle_path.exists():
113
+ console.print(f"[red]Bundle file not found: {bundle_path}[/]")
114
+ raise SystemExit(1)
115
+
116
+ try:
117
+ bundle = json.loads(bundle_path.read_text(encoding="utf-8"))
118
+ except (json.JSONDecodeError, OSError) as exc:
119
+ console.print(f"[red]Cannot read bundle: {exc}[/]")
120
+ raise SystemExit(1)
121
+
122
+ home_path = Path(home).expanduser()
123
+
124
+ try:
125
+ result = import_bundle(
126
+ home=home_path,
127
+ bundle=bundle,
128
+ overwrite_identity=overwrite_identity,
129
+ overwrite_config=overwrite_config,
130
+ overwrite_soul=overwrite_soul,
131
+ )
132
+ except ValueError as exc:
133
+ console.print(f"[red]Invalid bundle: {exc}[/]")
134
+ raise SystemExit(1)
135
+ except Exception as exc:
136
+ console.print(f"[red]Import failed: {exc}[/]")
137
+ raise SystemExit(1)
138
+
139
+ identity_status = "[green]written[/]" if result["identity_written"] else "[dim]skipped[/]"
140
+ config_status = "[green]written[/]" if result["config_written"] else "[dim]skipped[/]"
141
+
142
+ console.print(Panel(
143
+ f"[bold green]Import complete[/]\n"
144
+ f"Memories imported: {result['memories_imported']}\n"
145
+ f"Conversations imported: {result['conversations_imported']}\n"
146
+ f"Soul files written: {result['soul_files_written']}\n"
147
+ f"Identity: {identity_status}\n"
148
+ f"Config: {config_status}",
149
+ title="Agent Bundle Imported",
150
+ border_style="green",
151
+ ))
152
+
153
+ if result["errors"]:
154
+ console.print("[yellow]Warnings:[/]")
155
+ for err in result["errors"]:
156
+ console.print(f" [dim]{err}[/]")