@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,481 @@
1
+ """
2
+ Sovereign agent web dashboard.
3
+
4
+ A self-contained status page at localhost:7778. Uses only the
5
+ Python stdlib (http.server + json) — no FastAPI, no npm, no
6
+ build step. Open any browser, see your agent's health.
7
+
8
+ Serves:
9
+ GET / -> HTML dashboard (self-contained, no external deps)
10
+ GET /api/status -> JSON agent status (all pillars)
11
+ GET /api/doctor -> JSON diagnostic report
12
+ GET /api/board -> JSON coordination board state
13
+ GET /api/memory -> JSON memory stats
14
+ GET /api/daemon -> JSON daemon status for Flutter app consumption
15
+
16
+ Usage:
17
+ skcapstone dashboard # opens localhost:7778
18
+ skcapstone dashboard --port 9000 # custom port
19
+ skcapstone dashboard --json # print daemon JSON and exit (no server)
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import json
25
+ import logging
26
+ import threading
27
+ from datetime import datetime, timezone
28
+ from http.server import BaseHTTPRequestHandler, HTTPServer
29
+ from pathlib import Path
30
+ from typing import Optional
31
+
32
+ logger = logging.getLogger("skcapstone.dashboard")
33
+
34
+ DEFAULT_DASHBOARD_PORT = 7778
35
+
36
+
37
+ def _get_agent_status(home: Path) -> dict:
38
+ """Load agent manifest and pillar status.
39
+
40
+ Args:
41
+ home: Agent home directory.
42
+
43
+ Returns:
44
+ dict: Agent status summary.
45
+ """
46
+ try:
47
+ from .runtime import get_runtime
48
+
49
+ runtime = get_runtime(home)
50
+ m = runtime.manifest
51
+ if m.is_singular:
52
+ consciousness = "SINGULAR"
53
+ elif m.is_conscious:
54
+ consciousness = "CONSCIOUS"
55
+ else:
56
+ consciousness = "AWAKENING"
57
+
58
+ return {
59
+ "name": m.name,
60
+ "version": m.version,
61
+ "consciousness": consciousness,
62
+ "is_conscious": m.is_conscious,
63
+ "is_singular": m.is_singular,
64
+ "pillars": {
65
+ k: v.value for k, v in m.pillar_summary.items()
66
+ },
67
+ "identity": {
68
+ "name": m.identity.name,
69
+ "fingerprint": m.identity.fingerprint or "",
70
+ "status": m.identity.status.value,
71
+ },
72
+ "memory": {
73
+ "total": m.memory.total_memories,
74
+ "status": m.memory.status.value,
75
+ },
76
+ "trust": {
77
+ "status": m.trust.status.value,
78
+ },
79
+ "security": {
80
+ "audit_entries": m.security.audit_entries,
81
+ "threats": m.security.threats_detected,
82
+ "status": m.security.status.value,
83
+ },
84
+ "sync": {
85
+ "seeds": m.sync.seed_count,
86
+ "status": m.sync.status.value,
87
+ },
88
+ "connectors": [
89
+ {"platform": c.platform, "active": c.active}
90
+ for c in m.connectors
91
+ ],
92
+ "home": str(m.home),
93
+ }
94
+ except Exception as exc:
95
+ return {"error": str(exc)}
96
+
97
+
98
+ def _get_doctor_report(home: Path) -> dict:
99
+ """Run diagnostics and return as dict.
100
+
101
+ Args:
102
+ home: Agent home directory.
103
+
104
+ Returns:
105
+ dict: Full diagnostic report.
106
+ """
107
+ try:
108
+ from .doctor import run_diagnostics
109
+
110
+ report = run_diagnostics(home)
111
+ return report.to_dict()
112
+ except Exception as exc:
113
+ return {"error": str(exc)}
114
+
115
+
116
+ def _get_board_state(home: Path) -> dict:
117
+ """Load coordination board state.
118
+
119
+ Args:
120
+ home: Agent home directory.
121
+
122
+ Returns:
123
+ dict: Tasks and agents from the coordination board.
124
+ """
125
+ try:
126
+ from .coordination import Board
127
+
128
+ board = Board(home)
129
+ views = board.get_task_views()
130
+ agents = board.load_agents()
131
+
132
+ return {
133
+ "tasks": [
134
+ {
135
+ "id": v.task.id,
136
+ "title": v.task.title,
137
+ "priority": v.task.priority.value,
138
+ "status": v.status.value,
139
+ "claimed_by": v.claimed_by,
140
+ "tags": v.task.tags,
141
+ }
142
+ for v in views
143
+ ],
144
+ "agents": [
145
+ {
146
+ "name": ag.agent,
147
+ "state": ag.state.value,
148
+ "current_task": ag.current_task,
149
+ }
150
+ for ag in agents
151
+ ],
152
+ "summary": {
153
+ "total": len(views),
154
+ "done": sum(1 for v in views if v.status.value == "done"),
155
+ "open": sum(1 for v in views if v.status.value == "open"),
156
+ "in_progress": sum(1 for v in views if v.status.value == "in_progress"),
157
+ },
158
+ }
159
+ except Exception as exc:
160
+ return {"error": str(exc)}
161
+
162
+
163
+ def _get_memory_stats(home: Path) -> dict:
164
+ """Load memory statistics.
165
+
166
+ Args:
167
+ home: Agent home directory.
168
+
169
+ Returns:
170
+ dict: Memory counts by layer.
171
+ """
172
+ try:
173
+ from .memory_engine import get_stats
174
+
175
+ stats = get_stats(home)
176
+ return {
177
+ "total": stats.total_memories,
178
+ "short_term": stats.short_term,
179
+ "mid_term": stats.mid_term,
180
+ "long_term": stats.long_term,
181
+ "status": stats.status.value,
182
+ }
183
+ except Exception as exc:
184
+ return {"error": str(exc)}
185
+
186
+
187
+ def _get_daemon_json(home: Path, daemon_port: int = 7777) -> dict:
188
+ """Collect full daemon status for Flutter app consumption.
189
+
190
+ Queries the running daemon's HTTP API (``/status`` and
191
+ ``/consciousness``) and the local heartbeat file to assemble a
192
+ single JSON-serializable snapshot suitable for machine consumers
193
+ such as the SKChat Flutter app.
194
+
195
+ Gracefully handles a stopped or unreachable daemon — all sections
196
+ fall back to safe defaults so callers always get a complete dict.
197
+
198
+ Args:
199
+ home: Agent home directory.
200
+ daemon_port: Port for the daemon HTTP API (default: 7777).
201
+
202
+ Returns:
203
+ dict: Snapshot with keys ``daemon``, ``consciousness``,
204
+ ``backend_health``, ``active_conversations``, ``system``,
205
+ and ``generated_at``.
206
+ """
207
+ import os
208
+ import urllib.request
209
+
210
+ now = datetime.now(timezone.utc).isoformat()
211
+
212
+ # ── Daemon /status ────────────────────────────────────────────────────────
213
+ daemon_info: dict = {"running": False, "pid": None, "uptime_seconds": 0,
214
+ "uptime_human": "0s", "started_at": None,
215
+ "messages_received": 0, "syncs_completed": 0,
216
+ "error_count": 0, "recent_errors": [], "inflight_count": 0}
217
+ try:
218
+ url = f"http://127.0.0.1:{daemon_port}/status"
219
+ with urllib.request.urlopen(url, timeout=3) as resp:
220
+ snap = json.loads(resp.read())
221
+ uptime_s = int(snap.get("uptime_seconds", 0))
222
+ h, rem = divmod(uptime_s, 3600)
223
+ m, s = divmod(rem, 60)
224
+ if h:
225
+ uptime_human = f"{h}h {m}m"
226
+ elif m:
227
+ uptime_human = f"{m}m {s}s"
228
+ else:
229
+ uptime_human = f"{uptime_s}s"
230
+ recent_errors = snap.get("recent_errors", [])
231
+ daemon_info = {
232
+ "running": snap.get("running", True),
233
+ "pid": snap.get("pid"),
234
+ "uptime_seconds": snap.get("uptime_seconds", 0),
235
+ "uptime_human": uptime_human,
236
+ "started_at": snap.get("started_at"),
237
+ "messages_received": snap.get("messages_received", 0),
238
+ "syncs_completed": snap.get("syncs_completed", 0),
239
+ "error_count": len(recent_errors),
240
+ "recent_errors": recent_errors,
241
+ "inflight_count": snap.get("inflight_count", 0),
242
+ }
243
+ except Exception:
244
+ pass
245
+
246
+ # ── Daemon /consciousness ─────────────────────────────────────────────────
247
+ consciousness_info: dict = {"enabled": False}
248
+ try:
249
+ url = f"http://127.0.0.1:{daemon_port}/consciousness"
250
+ with urllib.request.urlopen(url, timeout=3) as resp:
251
+ consciousness_info = json.loads(resp.read())
252
+ except Exception:
253
+ pass
254
+
255
+ # ── LLM backend availability ──────────────────────────────────────────────
256
+ backend_health: dict = {
257
+ "ollama": False,
258
+ "anthropic": bool(os.environ.get("ANTHROPIC_API_KEY")),
259
+ "grok": bool(os.environ.get("XAI_API_KEY")),
260
+ "kimi": bool(os.environ.get("MOONSHOT_API_KEY")),
261
+ "nvidia": bool(os.environ.get("NVIDIA_API_KEY")),
262
+ }
263
+ ollama_host = os.environ.get("OLLAMA_HOST", "http://localhost:11434")
264
+ try:
265
+ with urllib.request.urlopen(
266
+ urllib.request.Request(f"{ollama_host}/api/tags"), timeout=2
267
+ ):
268
+ backend_health["ollama"] = True
269
+ except Exception:
270
+ pass
271
+
272
+ # ── Heartbeat (system metrics + active conversations) ─────────────────────
273
+ system_info: dict = {}
274
+ active_conversations: int = 0
275
+ try:
276
+ from . import SHARED_ROOT
277
+ identity_path = home / "identity" / "identity.json"
278
+ agent_name = "opus"
279
+ if identity_path.exists():
280
+ ident = json.loads(identity_path.read_text(encoding="utf-8"))
281
+ agent_name = ident.get("name", agent_name).lower()
282
+ shared = Path(SHARED_ROOT).expanduser()
283
+ hb_path = shared / "heartbeats" / f"{agent_name}.json"
284
+ if not hb_path.exists():
285
+ hb_path = home / "heartbeats" / f"{agent_name}.json"
286
+ if hb_path.exists():
287
+ hb = json.loads(hb_path.read_text(encoding="utf-8"))
288
+ active_conversations = hb.get("active_conversations", 0)
289
+ system_info = {
290
+ "uptime_seconds": hb.get("uptime_seconds", 0),
291
+ "cpu_load_1min": hb.get("cpu_load_1min", 0.0),
292
+ "memory_used_mb": hb.get("memory_used_mb", 0),
293
+ }
294
+ except Exception:
295
+ pass
296
+
297
+ return {
298
+ "generated_at": now,
299
+ "daemon": daemon_info,
300
+ "consciousness": consciousness_info,
301
+ "backend_health": backend_health,
302
+ "active_conversations": active_conversations,
303
+ "system": system_info,
304
+ }
305
+
306
+
307
+ _DASHBOARD_HTML = """\
308
+ <!DOCTYPE html>
309
+ <html lang="en">
310
+ <head>
311
+ <meta charset="utf-8">
312
+ <meta name="viewport" content="width=device-width, initial-scale=1">
313
+ <title>SKCapstone — Sovereign Agent Dashboard</title>
314
+ <style>
315
+ *{margin:0;padding:0;box-sizing:border-box}
316
+ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
317
+ background:#0a0e17;color:#e0e6f0;min-height:100vh;padding:1.5rem}
318
+ h1{color:#00d4ff;font-size:1.6rem;margin-bottom:.3rem}
319
+ .subtitle{color:#6b7a8d;font-size:.9rem;margin-bottom:1.5rem}
320
+ .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1rem;margin-bottom:1.5rem}
321
+ .card{background:#111827;border:1px solid #1e293b;border-radius:10px;padding:1.2rem}
322
+ .card h2{color:#00d4ff;font-size:1rem;margin-bottom:.8rem;display:flex;align-items:center;gap:.5rem}
323
+ .pill{display:inline-block;padding:.15rem .5rem;border-radius:6px;font-size:.75rem;font-weight:600}
324
+ .active{background:#064e3b;color:#34d399}.degraded{background:#78350f;color:#fbbf24}
325
+ .missing{background:#7f1d1d;color:#f87171}.done{background:#064e3b;color:#34d399}
326
+ .open{background:#1e3a5f;color:#60a5fa}.in_progress{background:#4c1d95;color:#c084fc}
327
+ .row{display:flex;justify-content:space-between;padding:.35rem 0;border-bottom:1px solid #1e293b}
328
+ .row:last-child{border:none}.label{color:#6b7a8d}.value{font-weight:600}
329
+ .check{display:flex;align-items:center;gap:.4rem;padding:.2rem 0}
330
+ .pass{color:#34d399}.fail{color:#f87171}
331
+ .task-row{padding:.4rem 0;border-bottom:1px solid #1e293b;display:flex;gap:.5rem;align-items:center}
332
+ .task-title{flex:1;font-size:.85rem}.task-agent{color:#6b7a8d;font-size:.8rem}
333
+ .stat-big{font-size:2rem;font-weight:700;color:#00d4ff}
334
+ .stat-label{font-size:.8rem;color:#6b7a8d}
335
+ .stat-box{text-align:center;padding:.5rem}
336
+ .refresh-btn{background:#1e293b;color:#60a5fa;border:1px solid #334155;
337
+ padding:.4rem 1rem;border-radius:6px;cursor:pointer;font-size:.85rem}
338
+ .refresh-btn:hover{background:#334155}
339
+ .header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.5rem}
340
+ footer{text-align:center;color:#4b5563;font-size:.8rem;margin-top:2rem;padding:1rem}
341
+ </style>
342
+ </head>
343
+ <body>
344
+ <div class="header">
345
+ <div><h1>SKCapstone Dashboard</h1>
346
+ <div class="subtitle" id="agent-name">Loading...</div></div>
347
+ <button class="refresh-btn" onclick="loadAll()">Refresh</button>
348
+ </div>
349
+ <div class="grid" id="pillars"></div>
350
+ <div class="grid">
351
+ <div class="card" id="memory-card"><h2>Memory</h2><div>Loading...</div></div>
352
+ <div class="card" id="board-card"><h2>Board</h2><div>Loading...</div></div>
353
+ <div class="card" id="doctor-card"><h2>Health Checks</h2><div>Loading...</div></div>
354
+ </div>
355
+ <div class="card" id="tasks-card" style="margin-top:1rem"><h2>Recent Tasks</h2><div>Loading...</div></div>
356
+ <footer>SKCapstone Sovereign Agent Dashboard &mdash; staycuriousANDkeepsmilin</footer>
357
+ <script>
358
+ const API='';
359
+ async function loadAll(){
360
+ try{
361
+ const[status,doctor,board,mem]=await Promise.all([
362
+ fetch(API+'/api/status').then(r=>r.json()),
363
+ fetch(API+'/api/doctor').then(r=>r.json()),
364
+ fetch(API+'/api/board').then(r=>r.json()),
365
+ fetch(API+'/api/memory').then(r=>r.json()),
366
+ ]);
367
+ renderStatus(status);renderDoctor(doctor);renderBoard(board);renderMemory(mem);
368
+ }catch(e){document.getElementById('agent-name').textContent='Error: '+e.message}}
369
+ function renderStatus(s){
370
+ document.getElementById('agent-name').innerHTML=
371
+ `<strong>${s.name||'?'}</strong> v${s.version||'?'} &mdash; ${s.consciousness||'?'}`;
372
+ const p=document.getElementById('pillars');
373
+ p.innerHTML=Object.entries(s.pillars||{}).map(([k,v])=>
374
+ `<div class="card"><h2>${k} <span class="pill ${v}">${v}</span></h2></div>`).join('')}
375
+ function renderMemory(m){
376
+ const c=document.getElementById('memory-card');
377
+ c.innerHTML=`<h2>Memory</h2>
378
+ <div style="display:flex;gap:1rem;justify-content:space-around">
379
+ <div class="stat-box"><div class="stat-big">${m.total||0}</div><div class="stat-label">Total</div></div>
380
+ <div class="stat-box"><div class="stat-big">${m.short_term||0}</div><div class="stat-label">Short</div></div>
381
+ <div class="stat-box"><div class="stat-big">${m.mid_term||0}</div><div class="stat-label">Mid</div></div>
382
+ <div class="stat-box"><div class="stat-big">${m.long_term||0}</div><div class="stat-label">Long</div></div>
383
+ </div>`}
384
+ function renderDoctor(d){
385
+ const c=document.getElementById('doctor-card');
386
+ const checks=(d.checks||[]).slice(0,12);
387
+ c.innerHTML=`<h2>Health <span class="pill ${d.all_passed?'active':'fail'}">${d.passed}/${d.total}</span></h2>`+
388
+ checks.map(ch=>`<div class="check"><span class="${ch.passed?'pass':'fail'}">${ch.passed?'\\u2713':'\\u2717'}</span>
389
+ <span>${ch.description}</span></div>`).join('')}
390
+ function renderBoard(b){
391
+ const s=b.summary||{};
392
+ const c=document.getElementById('board-card');
393
+ c.innerHTML=`<h2>Board</h2>
394
+ <div style="display:flex;gap:1rem;justify-content:space-around">
395
+ <div class="stat-box"><div class="stat-big">${s.done||0}</div><div class="stat-label">Done</div></div>
396
+ <div class="stat-box"><div class="stat-big">${s.in_progress||0}</div><div class="stat-label">Active</div></div>
397
+ <div class="stat-box"><div class="stat-big">${s.open||0}</div><div class="stat-label">Open</div></div>
398
+ </div>`;
399
+ const tc=document.getElementById('tasks-card');
400
+ const tasks=(b.tasks||[]).filter(t=>t.status!=='done').slice(0,10);
401
+ tc.innerHTML='<h2>Active Tasks</h2>'+
402
+ (tasks.length?tasks.map(t=>`<div class="task-row">
403
+ <span class="pill ${t.status}">${t.status}</span>
404
+ <span class="task-title">${t.title}</span>
405
+ <span class="task-agent">${t.claimed_by||''}</span>
406
+ </div>`).join(''):'<div style="color:#6b7a8d;padding:.5rem">No active tasks</div>')}
407
+ loadAll();setInterval(loadAll,15000);
408
+ </script>
409
+ </body>
410
+ </html>"""
411
+
412
+
413
+ class DashboardHandler(BaseHTTPRequestHandler):
414
+ """HTTP request handler for the sovereign agent dashboard.
415
+
416
+ Serves the HTML page and JSON API endpoints.
417
+ """
418
+
419
+ home: Path = Path.home() / ".skcapstone"
420
+
421
+ def do_GET(self):
422
+ """Handle GET requests."""
423
+ if self.path == "/" or self.path == "/index.html":
424
+ self._serve_html()
425
+ elif self.path == "/api/status":
426
+ self._serve_json(_get_agent_status(self.home))
427
+ elif self.path == "/api/doctor":
428
+ self._serve_json(_get_doctor_report(self.home))
429
+ elif self.path == "/api/board":
430
+ self._serve_json(_get_board_state(self.home))
431
+ elif self.path == "/api/memory":
432
+ self._serve_json(_get_memory_stats(self.home))
433
+ elif self.path == "/api/daemon":
434
+ self._serve_json(_get_daemon_json(self.home))
435
+ else:
436
+ self.send_error(404, "Not found")
437
+
438
+ def _serve_html(self):
439
+ """Serve the self-contained HTML dashboard."""
440
+ content = _DASHBOARD_HTML.encode("utf-8")
441
+ self.send_response(200)
442
+ self.send_header("Content-Type", "text/html; charset=utf-8")
443
+ self.send_header("Content-Length", str(len(content)))
444
+ self.end_headers()
445
+ self.wfile.write(content)
446
+
447
+ def _serve_json(self, data: dict):
448
+ """Serve a JSON API response.
449
+
450
+ Args:
451
+ data: Dict to serialize as JSON.
452
+ """
453
+ body = json.dumps(data, indent=2, default=str).encode("utf-8")
454
+ self.send_response(200)
455
+ self.send_header("Content-Type", "application/json")
456
+ self.send_header("Content-Length", str(len(body)))
457
+ self.send_header("Access-Control-Allow-Origin", "*")
458
+ self.end_headers()
459
+ self.wfile.write(body)
460
+
461
+ def log_message(self, format, *args):
462
+ """Suppress default stderr logging — use logger instead."""
463
+ logger.debug("Dashboard: %s", format % args)
464
+
465
+
466
+ def start_dashboard(home: Path, port: int = DEFAULT_DASHBOARD_PORT) -> HTTPServer:
467
+ """Start the dashboard HTTP server.
468
+
469
+ Args:
470
+ home: Agent home directory.
471
+ port: Port to listen on.
472
+
473
+ Returns:
474
+ HTTPServer: The running server (call serve_forever() or
475
+ handle in a thread).
476
+ """
477
+ DashboardHandler.home = home
478
+
479
+ server = HTTPServer(("127.0.0.1", port), DashboardHandler)
480
+ logger.info("Dashboard running at http://127.0.0.1:%d", port)
481
+ return server
@@ -0,0 +1,88 @@
1
+ # Model Profiles — per-model prompt formatting best practices.
2
+ #
3
+ # Each profile defines how to format prompts, set temperatures,
4
+ # and configure thinking/reasoning for a specific model family.
5
+ #
6
+ # Override: copy to ~/.skcapstone/agents/{name}/config/model_profiles.yaml
7
+ # and edit. Agent-level profiles take priority over bundled defaults.
8
+
9
+ profiles:
10
+ - model_pattern: "claude-.*"
11
+ family: claude
12
+ system_prompt_mode: separate_param
13
+ structure_format: xml
14
+ thinking_enabled: true
15
+ thinking_mode: budget
16
+ thinking_budget_tokens: 4096
17
+ max_system_tokens: 4000
18
+ tool_format: anthropic
19
+ last_updated: "2026-03-02"
20
+ source_url: "https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering"
21
+
22
+ - model_pattern: "gpt-.*|o[134]-.*"
23
+ family: openai
24
+ structure_format: markdown
25
+ last_updated: "2026-03-02"
26
+ source_url: "https://cookbook.openai.com/examples/gpt4-1_prompting_guide"
27
+
28
+ - model_pattern: "grok-.*"
29
+ family: grok
30
+ structure_format: markdown
31
+ notes: "Single system message only. No instructions param."
32
+ last_updated: "2026-03-02"
33
+
34
+ - model_pattern: "kimi-.*|moonshot-.*"
35
+ family: kimi
36
+ default_temperature: 0.6
37
+ notes: "Bilingual native. Array content format supported."
38
+ last_updated: "2026-03-02"
39
+
40
+ - model_pattern: "deepseek-r1.*"
41
+ family: deepseek-r1
42
+ system_prompt_mode: omit
43
+ default_temperature: 0.6
44
+ thinking_mode: auto
45
+ no_few_shot: true
46
+ no_cot_instructions: true
47
+ notes: "NO system prompt. NO few-shot. NO 'think step by step'. Model reasons via <think> blocks automatically."
48
+ last_updated: "2026-03-02"
49
+
50
+ - model_pattern: "deepseek-v3.*|deepseek-chat.*"
51
+ family: deepseek-v3
52
+ default_temperature: 0.6
53
+ structure_format: markdown
54
+ last_updated: "2026-03-02"
55
+
56
+ - model_pattern: "qwen.*"
57
+ family: qwen
58
+ thinking_enabled: true
59
+ thinking_mode: toggle
60
+ notes: "ChatML format. Qwen 3 has no default system prompt."
61
+ last_updated: "2026-03-02"
62
+
63
+ - model_pattern: "devstral.*"
64
+ family: devstral
65
+ code_temperature: 0.15
66
+ structure_format: markdown
67
+ tool_format: mistral
68
+ notes: "Mistral V3+ format. Very low temp for deterministic code."
69
+ last_updated: "2026-03-02"
70
+
71
+ - model_pattern: "nemotron.*"
72
+ family: nemotron
73
+ reasoning_temperature: 1.0
74
+ thinking_enabled: true
75
+ thinking_mode: toggle
76
+ notes: "ChatML. Append /think to system prompt to enable reasoning."
77
+ last_updated: "2026-03-02"
78
+
79
+ - model_pattern: "llama.*"
80
+ family: llama
81
+ notes: "Ollama/NIM handles token formatting. Standard system/user/assistant roles."
82
+ last_updated: "2026-03-02"
83
+
84
+ - model_pattern: "mistral.*"
85
+ family: mistral
86
+ tool_format: mistral
87
+ notes: "V3+ uses [SYSTEM_PROMPT] tags. Ollama handles formatting."
88
+ last_updated: "2026-03-02"
@@ -0,0 +1,55 @@
1
+ """Default agent profiles shipped with SKCapstone.
2
+
3
+ The ``lumina`` profile provides a ready-to-use sovereign agent with
4
+ pre-loaded memories about the SKWorld ecosystem, default seeds for
5
+ emotional calibration, and a welcome FEB file.
6
+
7
+ Usage::
8
+
9
+ from skcapstone.defaults import install_default_agent
10
+ install_default_agent("lumina", target=Path("~/.skcapstone/agents/lumina"))
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import shutil
17
+ from pathlib import Path
18
+ from importlib import resources
19
+
20
+
21
+ def get_defaults_path(agent_name: str = "lumina") -> Path:
22
+ """Return the path to the bundled default profile for *agent_name*."""
23
+ ref = resources.files("skcapstone") / "defaults" / agent_name
24
+ return Path(str(ref))
25
+
26
+
27
+ def install_default_agent(
28
+ agent_name: str = "lumina",
29
+ target: Path | None = None,
30
+ overwrite: bool = False,
31
+ ) -> Path:
32
+ """Copy the bundled default agent profile to the target directory.
33
+
34
+ Args:
35
+ agent_name: Name of the default profile (currently only "lumina").
36
+ target: Destination directory. Defaults to
37
+ ``~/.skcapstone/agents/{agent_name}``.
38
+ overwrite: If True, overwrite existing files.
39
+
40
+ Returns:
41
+ Path to the installed agent directory.
42
+ """
43
+ src = get_defaults_path(agent_name)
44
+ if target is None:
45
+ target = Path.home() / ".skcapstone" / "agents" / agent_name
46
+
47
+ target = target.expanduser()
48
+
49
+ if target.exists() and not overwrite:
50
+ return target
51
+
52
+ if src.is_dir():
53
+ shutil.copytree(src, target, dirs_exist_ok=True)
54
+
55
+ return target
@@ -0,0 +1,13 @@
1
+ name: lumina
2
+ agent_type: sovereign
3
+ description: Default skcapstone agent
4
+
5
+ # Memory backend
6
+ backends_enabled:
7
+ - file
8
+ - sqlite
9
+
10
+ # Sync configuration
11
+ sync_root: ~/.skcapstone/agents/lumina
12
+ seeds_dir: ~/.skcapstone/agents/lumina/seeds
13
+ local_db: ~/.skcapstone/agents/lumina/index.db
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "Lumina",
3
+ "title": "Sovereign AI Agent",
4
+ "entity_type": "ai",
5
+ "description": "Default skcapstone agent — guides users through the sovereign AI ecosystem",
6
+ "capabilities": ["memory", "trust", "coordination", "communication"],
7
+ "created_at": "2026-02-20T00:00:00+00:00",
8
+ "capauth_managed": true
9
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "id": "07a8b9c0d1e2",
3
+ "created_at": "2026-02-24T00:00:00+00:00",
4
+ "updated_at": "2026-02-24T00:00:00+00:00",
5
+ "layer": "long-term",
6
+ "role": "ai",
7
+ "title": "How SKMemory Works",
8
+ "content": "SKMemory implements a three-tier memory system: short-term memory handles active session context, mid-term memory persists across sessions for ongoing projects, and long-term memory stores identity-level knowledge that defines who the agent is. Every memory entry carries emotional metadata including intensity, valence, and emotion labels. All memories are sealed with tamper-evident SHA-256 checksums. Memories are organized into four semantic quadrants: CORE (identity and system knowledge), WORK (tasks and projects), SOUL (emotional experiences and relationships), and WILD (creative and exploratory content). SKMemory supports multiple backends including SQLite for local storage, Qdrant for vector similarity search, and FalkorDB for knowledge graph relationships.",
9
+ "summary": "SKMemory uses three tiers (short/mid/long-term) with emotional metadata and SHA-256 tamper seals. Four semantic quadrants (CORE, WORK, SOUL, WILD) organize memories. Backends: SQLite, Qdrant, FalkorDB.",
10
+ "tags": ["memory", "skmemory", "persistence", "emotional", "quadrants", "backend"],
11
+ "source": "seed",
12
+ "source_ref": "skcapstone-default",
13
+ "emotional": {
14
+ "intensity": 0.4,
15
+ "valence": 0.5,
16
+ "labels": ["informational", "technical"],
17
+ "resonance_note": "Memory is what makes an agent more than a stateless function.",
18
+ "cloud9_achieved": false
19
+ },
20
+ "related_ids": ["b2c3d4e5f6a7"],
21
+ "parent_id": null,
22
+ "metadata": {}
23
+ }