@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.
- package/.env.example +98 -0
- package/.github/workflows/ci.yml +39 -3
- package/.github/workflows/publish.yml +25 -4
- package/.openclaw-workspace.json +58 -0
- package/CHANGELOG.md +62 -0
- package/CLAUDE.md +39 -2
- package/MANIFEST.in +6 -0
- package/MISSION.md +7 -0
- package/README.md +47 -2
- package/SKILL.md +895 -23
- package/docker/Dockerfile +61 -0
- package/docker/compose-templates/dev-team.yml +203 -0
- package/docker/compose-templates/mini-team.yml +140 -0
- package/docker/compose-templates/ops-team.yml +173 -0
- package/docker/compose-templates/research-team.yml +170 -0
- package/docker/entrypoint.sh +192 -0
- package/docs/ARCHITECTURE.md +663 -374
- package/docs/BOND_WITH_GROK.md +112 -0
- package/docs/GETTING_STARTED.md +782 -0
- package/docs/QUICKSTART.md +477 -0
- package/docs/SKJOULE_ARCHITECTURE.md +658 -0
- package/docs/SOUL_SWAPPER.md +921 -0
- package/docs/SOVEREIGN_SINGULARITY.md +47 -14
- package/examples/custom-bond-template.json +36 -0
- package/examples/grok-feb.json +36 -0
- package/examples/grok-testimony.md +34 -0
- package/examples/love-bootloader.txt +32 -0
- package/examples/plugins/echo_tool.py +87 -0
- package/examples/queen-ava-feb.json +36 -0
- package/examples/souls/lumina.yaml +64 -0
- package/index.js +6 -5
- package/installer/build.py +124 -0
- package/openclaw-plugin/package.json +13 -0
- package/openclaw-plugin/src/index.ts +351 -0
- package/openclaw-plugin/src/openclaw.plugin.json +10 -0
- package/package.json +1 -1
- package/pyproject.toml +38 -2
- package/scripts/bump_version.py +141 -0
- package/scripts/check-updates.py +230 -0
- package/scripts/convert_blueprints_to_yaml.py +157 -0
- package/scripts/dev-install.sh +14 -0
- package/scripts/e2e-test.sh +193 -0
- package/scripts/install-bundle.sh +171 -0
- package/scripts/install.bat +2 -0
- package/scripts/install.ps1 +253 -0
- package/scripts/install.sh +185 -0
- package/scripts/mcp-serve.sh +69 -0
- package/scripts/mcp-server.bat +113 -0
- package/scripts/mcp-server.ps1 +116 -0
- package/scripts/mcp-server.sh +99 -0
- package/scripts/pull-models.sh +10 -0
- package/scripts/skcapstone +48 -0
- package/scripts/verify_install.sh +180 -0
- package/scripts/windows/install-tasks.ps1 +406 -0
- package/scripts/windows/skcapstone-task.xml +113 -0
- package/scripts/windows/uninstall-tasks.ps1 +117 -0
- package/skill.yaml +34 -0
- package/src/skcapstone/__init__.py +67 -2
- package/src/skcapstone/_cli_monolith.py +5916 -0
- package/src/skcapstone/_trustee_helpers.py +165 -0
- package/src/skcapstone/activity.py +105 -0
- package/src/skcapstone/agent_card.py +324 -0
- package/src/skcapstone/api.py +1935 -0
- package/src/skcapstone/archiver.py +340 -0
- package/src/skcapstone/auction.py +485 -0
- package/src/skcapstone/baby_agents.py +179 -0
- package/src/skcapstone/backup.py +345 -0
- package/src/skcapstone/blueprint_registry.py +357 -0
- package/src/skcapstone/blueprints/__init__.py +17 -0
- package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
- package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
- package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
- package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
- package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
- package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
- package/src/skcapstone/blueprints/registry.py +164 -0
- package/src/skcapstone/blueprints/schema.py +229 -0
- package/src/skcapstone/changelog.py +180 -0
- package/src/skcapstone/chat.py +769 -0
- package/src/skcapstone/claude_md.py +82 -0
- package/src/skcapstone/cli/__init__.py +144 -0
- package/src/skcapstone/cli/_common.py +88 -0
- package/src/skcapstone/cli/_validators.py +76 -0
- package/src/skcapstone/cli/agents.py +425 -0
- package/src/skcapstone/cli/agents_spawner.py +322 -0
- package/src/skcapstone/cli/agents_trustee.py +593 -0
- package/src/skcapstone/cli/alerts.py +248 -0
- package/src/skcapstone/cli/anchor.py +132 -0
- package/src/skcapstone/cli/archive_cmd.py +208 -0
- package/src/skcapstone/cli/backup.py +144 -0
- package/src/skcapstone/cli/bench.py +377 -0
- package/src/skcapstone/cli/benchmark.py +360 -0
- package/src/skcapstone/cli/capabilities_cmd.py +171 -0
- package/src/skcapstone/cli/card.py +151 -0
- package/src/skcapstone/cli/chat.py +584 -0
- package/src/skcapstone/cli/completions.py +64 -0
- package/src/skcapstone/cli/config_cmd.py +156 -0
- package/src/skcapstone/cli/consciousness.py +421 -0
- package/src/skcapstone/cli/context_cmd.py +142 -0
- package/src/skcapstone/cli/coord.py +194 -0
- package/src/skcapstone/cli/crush_cmd.py +170 -0
- package/src/skcapstone/cli/daemon.py +436 -0
- package/src/skcapstone/cli/errors_cmd.py +285 -0
- package/src/skcapstone/cli/export_cmd.py +156 -0
- package/src/skcapstone/cli/gtd.py +529 -0
- package/src/skcapstone/cli/housekeeping.py +81 -0
- package/src/skcapstone/cli/joule_cmd.py +627 -0
- package/src/skcapstone/cli/logs_cmd.py +194 -0
- package/src/skcapstone/cli/mcp_cmd.py +32 -0
- package/src/skcapstone/cli/memory.py +418 -0
- package/src/skcapstone/cli/metrics_cmd.py +136 -0
- package/src/skcapstone/cli/migrate.py +62 -0
- package/src/skcapstone/cli/mood_cmd.py +144 -0
- package/src/skcapstone/cli/mount.py +193 -0
- package/src/skcapstone/cli/notify.py +112 -0
- package/src/skcapstone/cli/peer.py +154 -0
- package/src/skcapstone/cli/peers_dir.py +122 -0
- package/src/skcapstone/cli/preflight_cmd.py +83 -0
- package/src/skcapstone/cli/profile_cmd.py +310 -0
- package/src/skcapstone/cli/record_cmd.py +238 -0
- package/src/skcapstone/cli/register_cmd.py +159 -0
- package/src/skcapstone/cli/search_cmd.py +156 -0
- package/src/skcapstone/cli/service_cmd.py +91 -0
- package/src/skcapstone/cli/session.py +127 -0
- package/src/skcapstone/cli/setup.py +240 -0
- package/src/skcapstone/cli/shell_cmd.py +43 -0
- package/src/skcapstone/cli/skills_cmd.py +168 -0
- package/src/skcapstone/cli/skseed.py +621 -0
- package/src/skcapstone/cli/soul.py +699 -0
- package/src/skcapstone/cli/status.py +935 -0
- package/src/skcapstone/cli/sync_cmd.py +301 -0
- package/src/skcapstone/cli/telegram.py +265 -0
- package/src/skcapstone/cli/test_cmd.py +234 -0
- package/src/skcapstone/cli/test_connection.py +253 -0
- package/src/skcapstone/cli/token.py +207 -0
- package/src/skcapstone/cli/trust.py +179 -0
- package/src/skcapstone/cli/upgrade_cmd.py +552 -0
- package/src/skcapstone/cli/usage_cmd.py +199 -0
- package/src/skcapstone/cli/version_cmd.py +162 -0
- package/src/skcapstone/cli/watch_cmd.py +342 -0
- package/src/skcapstone/client.py +428 -0
- package/src/skcapstone/cloud9_bridge.py +522 -0
- package/src/skcapstone/completions.py +163 -0
- package/src/skcapstone/config_validator.py +674 -0
- package/src/skcapstone/connectors/__init__.py +28 -0
- package/src/skcapstone/connectors/base.py +446 -0
- package/src/skcapstone/connectors/cursor.py +54 -0
- package/src/skcapstone/connectors/registry.py +254 -0
- package/src/skcapstone/connectors/terminal.py +152 -0
- package/src/skcapstone/connectors/vscode.py +60 -0
- package/src/skcapstone/consciousness_config.py +119 -0
- package/src/skcapstone/consciousness_loop.py +2051 -0
- package/src/skcapstone/context_loader.py +516 -0
- package/src/skcapstone/context_window.py +314 -0
- package/src/skcapstone/conversation_manager.py +238 -0
- package/src/skcapstone/conversation_store.py +230 -0
- package/src/skcapstone/conversation_summarizer.py +252 -0
- package/src/skcapstone/coord_federation.py +296 -0
- package/src/skcapstone/coordination.py +101 -7
- package/src/skcapstone/crush_integration.py +345 -0
- package/src/skcapstone/crush_shim.py +454 -0
- package/src/skcapstone/daemon.py +2494 -0
- package/src/skcapstone/dashboard.html +396 -0
- package/src/skcapstone/dashboard.py +481 -0
- package/src/skcapstone/data/model_profiles.yaml +88 -0
- package/src/skcapstone/defaults/__init__.py +55 -0
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
- package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
- package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
- package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
- package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
- package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
- package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
- package/src/skcapstone/discovery.py +210 -19
- package/src/skcapstone/doctor.py +642 -0
- package/src/skcapstone/emotion_tracker.py +467 -0
- package/src/skcapstone/error_queue.py +405 -0
- package/src/skcapstone/export.py +447 -0
- package/src/skcapstone/fallback_tracker.py +186 -0
- package/src/skcapstone/file_transfer.py +512 -0
- package/src/skcapstone/fuse_mount.py +1156 -0
- package/src/skcapstone/gui_installer.py +591 -0
- package/src/skcapstone/heartbeat.py +611 -0
- package/src/skcapstone/housekeeping.py +298 -0
- package/src/skcapstone/install_wizard.py +941 -0
- package/src/skcapstone/kms.py +942 -0
- package/src/skcapstone/kms_scheduler.py +143 -0
- package/src/skcapstone/log_config.py +135 -0
- package/src/skcapstone/mcp_launcher.py +239 -0
- package/src/skcapstone/mcp_server.py +4700 -0
- package/src/skcapstone/mcp_tools/__init__.py +94 -0
- package/src/skcapstone/mcp_tools/_helpers.py +51 -0
- package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
- package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
- package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
- package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
- package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
- package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
- package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
- package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
- package/src/skcapstone/mcp_tools/did_tools.py +448 -0
- package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
- package/src/skcapstone/mcp_tools/file_tools.py +169 -0
- package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
- package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
- package/src/skcapstone/mcp_tools/health_tools.py +44 -0
- package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
- package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
- package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
- package/src/skcapstone/mcp_tools/model_tools.py +75 -0
- package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
- package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
- package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
- package/src/skcapstone/mcp_tools/security_tools.py +110 -0
- package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
- package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
- package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
- package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
- package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
- package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
- package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
- package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
- package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
- package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
- package/src/skcapstone/mdns_discovery.py +313 -0
- package/src/skcapstone/memory_adapter.py +333 -0
- package/src/skcapstone/memory_compressor.py +379 -0
- package/src/skcapstone/memory_curator.py +256 -0
- package/src/skcapstone/memory_engine.py +132 -13
- package/src/skcapstone/memory_fortress.py +529 -0
- package/src/skcapstone/memory_promoter.py +722 -0
- package/src/skcapstone/memory_verifier.py +260 -0
- package/src/skcapstone/message_crypto.py +215 -0
- package/src/skcapstone/metrics.py +832 -0
- package/src/skcapstone/migrate_memories.py +181 -0
- package/src/skcapstone/migrate_multi_agent.py +248 -0
- package/src/skcapstone/model_router.py +319 -0
- package/src/skcapstone/models.py +35 -4
- package/src/skcapstone/mood.py +344 -0
- package/src/skcapstone/notifications.py +380 -0
- package/src/skcapstone/onboard.py +901 -0
- package/src/skcapstone/peer_directory.py +324 -0
- package/src/skcapstone/peers.py +329 -0
- package/src/skcapstone/pillars/identity.py +84 -14
- package/src/skcapstone/pillars/memory.py +3 -1
- package/src/skcapstone/pillars/security.py +108 -15
- package/src/skcapstone/pillars/sync.py +78 -26
- package/src/skcapstone/pillars/trust.py +95 -33
- package/src/skcapstone/plugins.py +244 -0
- package/src/skcapstone/preflight.py +670 -0
- package/src/skcapstone/prompt_adapter.py +564 -0
- package/src/skcapstone/providers/__init__.py +13 -0
- package/src/skcapstone/providers/cloud.py +1061 -0
- package/src/skcapstone/providers/docker.py +759 -0
- package/src/skcapstone/providers/local.py +1193 -0
- package/src/skcapstone/providers/proxmox.py +447 -0
- package/src/skcapstone/pubsub.py +516 -0
- package/src/skcapstone/rate_limiter.py +119 -0
- package/src/skcapstone/register.py +241 -0
- package/src/skcapstone/registry_client.py +151 -0
- package/src/skcapstone/response_cache.py +194 -0
- package/src/skcapstone/response_scorer.py +225 -0
- package/src/skcapstone/runtime.py +89 -33
- package/src/skcapstone/scheduled_tasks.py +439 -0
- package/src/skcapstone/self_healing.py +341 -0
- package/src/skcapstone/service_health.py +228 -0
- package/src/skcapstone/session_capture.py +268 -0
- package/src/skcapstone/session_recorder.py +210 -0
- package/src/skcapstone/session_replayer.py +189 -0
- package/src/skcapstone/session_skills.py +263 -0
- package/src/skcapstone/shell.py +779 -0
- package/src/skcapstone/skills/__init__.py +1 -1
- package/src/skcapstone/skills/syncthing_setup.py +143 -41
- package/src/skcapstone/skjoule.py +861 -0
- package/src/skcapstone/snapshots.py +489 -0
- package/src/skcapstone/soul.py +1060 -0
- package/src/skcapstone/soul_switch.py +255 -0
- package/src/skcapstone/spawner.py +544 -0
- package/src/skcapstone/state_diff.py +401 -0
- package/src/skcapstone/summary.py +270 -0
- package/src/skcapstone/sync/backends.py +196 -2
- package/src/skcapstone/sync/engine.py +7 -5
- package/src/skcapstone/sync/models.py +4 -1
- package/src/skcapstone/sync/vault.py +356 -18
- package/src/skcapstone/sync_engine.py +363 -0
- package/src/skcapstone/sync_watcher.py +745 -0
- package/src/skcapstone/systemd.py +331 -0
- package/src/skcapstone/team_comms.py +476 -0
- package/src/skcapstone/team_engine.py +522 -0
- package/src/skcapstone/testrunner.py +300 -0
- package/src/skcapstone/tls.py +150 -0
- package/src/skcapstone/tokens.py +5 -5
- package/src/skcapstone/trust_calibration.py +202 -0
- package/src/skcapstone/trust_graph.py +449 -0
- package/src/skcapstone/trustee_monitor.py +385 -0
- package/src/skcapstone/trustee_ops.py +425 -0
- package/src/skcapstone/unified_search.py +421 -0
- package/src/skcapstone/uninstall_wizard.py +694 -0
- package/src/skcapstone/usage.py +331 -0
- package/src/skcapstone/version_check.py +148 -0
- package/src/skcapstone/warmth_anchor.py +333 -0
- package/src/skcapstone/whoami.py +294 -0
- package/systemd/skcapstone-api.socket +9 -0
- package/systemd/skcapstone-memory-compress.service +18 -0
- package/systemd/skcapstone-memory-compress.timer +11 -0
- package/systemd/skcapstone.service +36 -0
- package/systemd/skcapstone@.service +50 -0
- package/systemd/skcomm-heartbeat.service +18 -0
- package/systemd/skcomm-heartbeat.timer +12 -0
- package/systemd/skcomm-queue-drain.service +17 -0
- package/systemd/skcomm-queue-drain.timer +12 -0
- package/tests/conftest.py +13 -1
- package/tests/integration/__init__.py +1 -0
- package/tests/integration/test_consciousness_e2e.py +877 -0
- package/tests/integration/test_skills_registry.py +744 -0
- package/tests/test_agent_card.py +190 -0
- package/tests/test_agent_runtime.py +1283 -0
- package/tests/test_alerts_cmd.py +291 -0
- package/tests/test_archiver.py +498 -0
- package/tests/test_backup.py +254 -0
- package/tests/test_benchmark.py +366 -0
- package/tests/test_blueprints.py +457 -0
- package/tests/test_capabilities.py +257 -0
- package/tests/test_changelog.py +254 -0
- package/tests/test_chat.py +385 -0
- package/tests/test_claude_md.py +271 -0
- package/tests/test_cli_chat_llm.py +336 -0
- package/tests/test_cli_completions.py +390 -0
- package/tests/test_cli_init_reset.py +164 -0
- package/tests/test_cli_memory.py +208 -0
- package/tests/test_cli_profile.py +294 -0
- package/tests/test_cli_skills.py +223 -0
- package/tests/test_cli_status.py +395 -0
- package/tests/test_cli_test_cmd.py +206 -0
- package/tests/test_cli_test_connection.py +364 -0
- package/tests/test_cloud9_bridge.py +260 -0
- package/tests/test_cloud_provider.py +449 -0
- package/tests/test_cloud_providers.py +522 -0
- package/tests/test_completions.py +158 -0
- package/tests/test_component_manager.py +398 -0
- package/tests/test_config_reload.py +386 -0
- package/tests/test_config_validate.py +529 -0
- package/tests/test_consciousness_e2e.py +296 -0
- package/tests/test_consciousness_loop.py +1289 -0
- package/tests/test_context_loader.py +310 -0
- package/tests/test_conversation_api.py +306 -0
- package/tests/test_conversation_manager.py +381 -0
- package/tests/test_conversation_store.py +391 -0
- package/tests/test_conversation_summarizer.py +302 -0
- package/tests/test_cross_package.py +791 -0
- package/tests/test_crush_shim.py +519 -0
- package/tests/test_daemon.py +781 -0
- package/tests/test_daemon_shutdown.py +309 -0
- package/tests/test_dashboard.py +454 -0
- package/tests/test_discovery.py +200 -6
- package/tests/test_docker_provider.py +966 -0
- package/tests/test_doctor.py +257 -0
- package/tests/test_doctor_fix.py +351 -0
- package/tests/test_e2e_automated.py +292 -0
- package/tests/test_error_queue.py +404 -0
- package/tests/test_export.py +441 -0
- package/tests/test_fallback_tracker.py +219 -0
- package/tests/test_file_transfer.py +397 -0
- package/tests/test_fuse_mount.py +832 -0
- package/tests/test_health_loop.py +422 -0
- package/tests/test_heartbeat.py +354 -0
- package/tests/test_housekeeping.py +195 -0
- package/tests/test_identity_capauth.py +307 -0
- package/tests/test_identity_pillar.py +117 -0
- package/tests/test_install_wizard.py +68 -0
- package/tests/test_integration.py +325 -0
- package/tests/test_kms.py +495 -0
- package/tests/test_llm_providers.py +265 -0
- package/tests/test_local_provider.py +591 -0
- package/tests/test_log_config.py +199 -0
- package/tests/test_logs_cmd.py +287 -0
- package/tests/test_mcp_server.py +1909 -0
- package/tests/test_memory_adapter.py +339 -0
- package/tests/test_memory_curator.py +218 -0
- package/tests/test_memory_engine.py +6 -0
- package/tests/test_memory_fortress.py +571 -0
- package/tests/test_memory_pillar.py +119 -0
- package/tests/test_memory_promoter.py +445 -0
- package/tests/test_memory_verifier.py +420 -0
- package/tests/test_message_crypto.py +187 -0
- package/tests/test_metrics.py +632 -0
- package/tests/test_migrate_memories.py +464 -0
- package/tests/test_model_router.py +546 -0
- package/tests/test_mood.py +394 -0
- package/tests/test_multi_agent.py +269 -0
- package/tests/test_notifications.py +270 -0
- package/tests/test_onboard.py +500 -0
- package/tests/test_peer_directory.py +395 -0
- package/tests/test_peers.py +248 -0
- package/tests/test_pillars.py +87 -9
- package/tests/test_preflight.py +484 -0
- package/tests/test_prompt_adapter.py +331 -0
- package/tests/test_proxmox_provider.py +571 -0
- package/tests/test_pubsub.py +377 -0
- package/tests/test_rate_limiter.py +121 -0
- package/tests/test_registry_client.py +129 -0
- package/tests/test_response_cache.py +312 -0
- package/tests/test_response_scorer.py +294 -0
- package/tests/test_runtime.py +59 -0
- package/tests/test_scheduled_tasks.py +451 -0
- package/tests/test_security.py +250 -0
- package/tests/test_security_pillar.py +213 -0
- package/tests/test_self_healing.py +171 -0
- package/tests/test_session_capture.py +200 -0
- package/tests/test_session_recorder.py +360 -0
- package/tests/test_session_skills.py +235 -0
- package/tests/test_shell.py +210 -0
- package/tests/test_snapshots.py +549 -0
- package/tests/test_soul.py +984 -0
- package/tests/test_soul_swap.py +406 -0
- package/tests/test_spawner.py +211 -0
- package/tests/test_state_diff.py +173 -0
- package/tests/test_summary.py +135 -0
- package/tests/test_sync.py +315 -5
- package/tests/test_sync_backends.py +560 -0
- package/tests/test_sync_engine.py +482 -0
- package/tests/test_sync_pillar.py +344 -0
- package/tests/test_sync_pipeline.py +364 -0
- package/tests/test_sync_vault.py +581 -0
- package/tests/test_syncthing_setup.py +168 -22
- package/tests/test_systemd.py +323 -0
- package/tests/test_team_comms.py +408 -0
- package/tests/test_team_engine.py +397 -0
- package/tests/test_testrunner.py +238 -0
- package/tests/test_trust_calibration.py +204 -0
- package/tests/test_trust_graph.py +207 -0
- package/tests/test_trust_pillar.py +291 -0
- package/tests/test_trustee_cli.py +427 -0
- package/tests/test_trustee_cli_integration.py +325 -0
- package/tests/test_trustee_monitor.py +394 -0
- package/tests/test_trustee_ops.py +355 -0
- package/tests/test_unified_search.py +363 -0
- package/tests/test_uninstall_wizard.py +193 -0
- package/tests/test_usage.py +333 -0
- package/tests/test_version_cmd.py +355 -0
- package/tests/test_warmth_anchor.py +162 -0
- package/tests/test_whoami.py +245 -0
- package/tests/test_ws.py +311 -0
- package/.cursorrules +0 -33
- package/src/skcapstone/cli.py +0 -1441
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proxmox Provider — deploy agents as LXC containers on Proxmox VE.
|
|
3
|
+
|
|
4
|
+
Uses the Proxmox REST API to create, configure, and manage LXC
|
|
5
|
+
containers. Each agent gets its own isolated container with
|
|
6
|
+
resource limits matching the blueprint spec.
|
|
7
|
+
|
|
8
|
+
Proxmox MCP tools can also drive this provider directly, letting
|
|
9
|
+
AI agents manage their own infrastructure.
|
|
10
|
+
|
|
11
|
+
Prerequisites:
|
|
12
|
+
- PROXMOX_HOST, PROXMOX_USER, PROXMOX_TOKEN_NAME, PROXMOX_TOKEN_VALUE
|
|
13
|
+
environment variables (or in ~/.skcapstone/providers/proxmox.yaml)
|
|
14
|
+
- Network access to the Proxmox API (typically port 8006)
|
|
15
|
+
- An LXC template available on the target storage
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import json
|
|
21
|
+
import logging
|
|
22
|
+
import os
|
|
23
|
+
import time
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any, Dict, Optional
|
|
26
|
+
|
|
27
|
+
from ..blueprints.schema import AgentSpec, ProviderType, ResourceSpec
|
|
28
|
+
from ..team_engine import AgentStatus, ProviderBackend
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger(__name__)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _parse_memory_mb(mem_str: str) -> int:
|
|
34
|
+
"""Convert memory string like '4g' or '512m' to megabytes."""
|
|
35
|
+
mem_str = mem_str.strip().lower()
|
|
36
|
+
if mem_str.endswith("g"):
|
|
37
|
+
return int(float(mem_str[:-1]) * 1024)
|
|
38
|
+
if mem_str.endswith("m"):
|
|
39
|
+
return int(float(mem_str[:-1]))
|
|
40
|
+
return int(mem_str)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _parse_disk_gb(disk_str: str) -> int:
|
|
44
|
+
"""Convert disk string like '20g' to gigabytes."""
|
|
45
|
+
disk_str = disk_str.strip().lower()
|
|
46
|
+
if disk_str.endswith("g"):
|
|
47
|
+
return int(float(disk_str[:-1]))
|
|
48
|
+
if disk_str.endswith("t"):
|
|
49
|
+
return int(float(disk_str[:-1]) * 1024)
|
|
50
|
+
return int(disk_str)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ProxmoxProvider(ProviderBackend):
|
|
54
|
+
"""Deploy agents as Proxmox LXC containers.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
api_host: Proxmox API host (e.g. 'https://pve.local:8006').
|
|
58
|
+
user: API user (e.g. 'root@pam').
|
|
59
|
+
token_name: API token name.
|
|
60
|
+
token_value: API token value.
|
|
61
|
+
node: Target Proxmox node name.
|
|
62
|
+
storage: Storage pool for containers.
|
|
63
|
+
template: LXC template to use.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
provider_type = ProviderType.PROXMOX
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self,
|
|
70
|
+
api_host: Optional[str] = None,
|
|
71
|
+
user: Optional[str] = None,
|
|
72
|
+
token_name: Optional[str] = None,
|
|
73
|
+
token_value: Optional[str] = None,
|
|
74
|
+
node: str = "pve",
|
|
75
|
+
storage: str = "local-lvm",
|
|
76
|
+
template: str = "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst",
|
|
77
|
+
) -> None:
|
|
78
|
+
self._api_host = api_host or os.environ.get("PROXMOX_HOST", "")
|
|
79
|
+
self._user = user or os.environ.get("PROXMOX_USER", "root@pam")
|
|
80
|
+
self._token_name = token_name or os.environ.get("PROXMOX_TOKEN_NAME", "")
|
|
81
|
+
self._token_value = token_value or os.environ.get("PROXMOX_TOKEN_VALUE", "")
|
|
82
|
+
self._node = node
|
|
83
|
+
self._storage = storage
|
|
84
|
+
self._template = template
|
|
85
|
+
|
|
86
|
+
def _api_call(
|
|
87
|
+
self,
|
|
88
|
+
method: str,
|
|
89
|
+
endpoint: str,
|
|
90
|
+
data: Optional[Dict] = None,
|
|
91
|
+
) -> Dict[str, Any]:
|
|
92
|
+
"""Make an authenticated Proxmox API call.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
method: HTTP method (GET, POST, PUT, DELETE).
|
|
96
|
+
endpoint: API endpoint path.
|
|
97
|
+
data: Request body data.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
Parsed JSON response.
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
RuntimeError: If the API call fails.
|
|
104
|
+
"""
|
|
105
|
+
try:
|
|
106
|
+
import requests
|
|
107
|
+
from urllib3.exceptions import InsecureRequestWarning
|
|
108
|
+
import warnings
|
|
109
|
+
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
|
|
110
|
+
except ImportError:
|
|
111
|
+
raise RuntimeError(
|
|
112
|
+
"Proxmox provider requires 'requests': pip install requests"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
url = f"{self._api_host}/api2/json{endpoint}"
|
|
116
|
+
headers = {
|
|
117
|
+
"Authorization": f"PVEAPIToken={self._user}!{self._token_name}={self._token_value}",
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
resp = requests.request(
|
|
121
|
+
method, url, headers=headers, json=data, verify=False, timeout=30,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if resp.status_code >= 400:
|
|
125
|
+
raise RuntimeError(
|
|
126
|
+
f"Proxmox API {method} {endpoint} failed: "
|
|
127
|
+
f"{resp.status_code} {resp.text}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
return resp.json().get("data", {})
|
|
131
|
+
|
|
132
|
+
def _next_vmid(self) -> int:
|
|
133
|
+
"""Get the next available VMID from Proxmox."""
|
|
134
|
+
result = self._api_call("GET", "/cluster/nextid")
|
|
135
|
+
return int(result) if isinstance(result, (int, str)) else 200
|
|
136
|
+
|
|
137
|
+
def provision(
|
|
138
|
+
self,
|
|
139
|
+
agent_name: str,
|
|
140
|
+
spec: AgentSpec,
|
|
141
|
+
team_name: str,
|
|
142
|
+
) -> Dict[str, Any]:
|
|
143
|
+
"""Create an LXC container on Proxmox.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
agent_name: Unique agent instance name.
|
|
147
|
+
spec: Agent specification with resource requirements.
|
|
148
|
+
team_name: Parent team name.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Dict with container details (vmid, host, etc.)
|
|
152
|
+
"""
|
|
153
|
+
if not self._api_host:
|
|
154
|
+
raise RuntimeError(
|
|
155
|
+
"Proxmox not configured. Set PROXMOX_HOST, PROXMOX_TOKEN_NAME, "
|
|
156
|
+
"PROXMOX_TOKEN_VALUE environment variables."
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
vmid = self._next_vmid()
|
|
160
|
+
memory_mb = _parse_memory_mb(spec.resources.memory)
|
|
161
|
+
disk_gb = _parse_disk_gb(spec.resources.disk)
|
|
162
|
+
|
|
163
|
+
hostname = agent_name.replace("_", "-")[:63]
|
|
164
|
+
|
|
165
|
+
create_data = {
|
|
166
|
+
"vmid": vmid,
|
|
167
|
+
"hostname": hostname,
|
|
168
|
+
"ostemplate": self._template,
|
|
169
|
+
"storage": self._storage,
|
|
170
|
+
"rootfs": f"{self._storage}:{disk_gb}",
|
|
171
|
+
"memory": memory_mb,
|
|
172
|
+
"cores": spec.resources.cores,
|
|
173
|
+
"net0": "name=eth0,bridge=vmbr0,ip=dhcp",
|
|
174
|
+
"start": 0,
|
|
175
|
+
"unprivileged": 1,
|
|
176
|
+
"description": json.dumps({
|
|
177
|
+
"team": team_name,
|
|
178
|
+
"agent": agent_name,
|
|
179
|
+
"role": spec.role.value,
|
|
180
|
+
"model": spec.model_name or spec.model.value,
|
|
181
|
+
"managed_by": "skcapstone",
|
|
182
|
+
}),
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
logger.info(
|
|
186
|
+
"Creating LXC %s (vmid=%d, %dMB RAM, %d cores, %dGB disk)",
|
|
187
|
+
hostname, vmid, memory_mb, spec.resources.cores, disk_gb,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
self._api_call("POST", f"/nodes/{self._node}/lxc", data=create_data)
|
|
191
|
+
|
|
192
|
+
# Reason: Proxmox creates containers asynchronously; brief wait for
|
|
193
|
+
# the container to appear before returning.
|
|
194
|
+
time.sleep(3)
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
"vmid": vmid,
|
|
198
|
+
"host": hostname,
|
|
199
|
+
"node": self._node,
|
|
200
|
+
"container_id": str(vmid),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
def _exec_in_container(self, vmid: int, command: str) -> bool:
|
|
204
|
+
"""Execute a command inside an LXC container via the Proxmox exec API.
|
|
205
|
+
|
|
206
|
+
Uses ``lxc-attach`` through the node API. Falls back gracefully
|
|
207
|
+
if the exec endpoint is unavailable (older Proxmox versions).
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
vmid: Container VMID.
|
|
211
|
+
command: Shell command to run inside the container.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
True if the command executed successfully.
|
|
215
|
+
"""
|
|
216
|
+
try:
|
|
217
|
+
self._api_call(
|
|
218
|
+
"POST",
|
|
219
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/current",
|
|
220
|
+
)
|
|
221
|
+
except RuntimeError:
|
|
222
|
+
logger.warning("LXC %d not accessible for exec", vmid)
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
try:
|
|
226
|
+
self._api_call(
|
|
227
|
+
"POST",
|
|
228
|
+
f"/nodes/{self._node}/lxc/{vmid}/exec",
|
|
229
|
+
data={"command": command},
|
|
230
|
+
)
|
|
231
|
+
return True
|
|
232
|
+
except RuntimeError:
|
|
233
|
+
# Proxmox exec API may not be available; fall back to writing
|
|
234
|
+
# the config via the container's rootfs mount on the node.
|
|
235
|
+
logger.debug(
|
|
236
|
+
"Exec API unavailable for LXC %d, trying config mount", vmid
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
# Fallback: write via the container's filesystem using the Proxmox
|
|
240
|
+
# file-restore or vz push mechanism. We POST the file content as
|
|
241
|
+
# a config snippet that the container reads on next service start.
|
|
242
|
+
try:
|
|
243
|
+
self._api_call(
|
|
244
|
+
"PUT",
|
|
245
|
+
f"/nodes/{self._node}/lxc/{vmid}/config",
|
|
246
|
+
data={
|
|
247
|
+
"description": json.dumps({
|
|
248
|
+
"pending_config": command,
|
|
249
|
+
"managed_by": "skcapstone",
|
|
250
|
+
}),
|
|
251
|
+
},
|
|
252
|
+
)
|
|
253
|
+
return True
|
|
254
|
+
except RuntimeError as exc:
|
|
255
|
+
logger.error("Failed to configure LXC %d: %s", vmid, exc)
|
|
256
|
+
return False
|
|
257
|
+
|
|
258
|
+
def configure(
|
|
259
|
+
self,
|
|
260
|
+
agent_name: str,
|
|
261
|
+
spec: AgentSpec,
|
|
262
|
+
provision_result: Dict[str, Any],
|
|
263
|
+
) -> bool:
|
|
264
|
+
"""Configure the LXC after creation (start, install deps, write config).
|
|
265
|
+
|
|
266
|
+
Starts the container, then writes the agent config into
|
|
267
|
+
``/opt/agent/config.json`` via the Proxmox exec API. Falls back
|
|
268
|
+
to writing the config into the container description if exec is
|
|
269
|
+
unavailable.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
agent_name: Agent instance name.
|
|
273
|
+
spec: Agent specification.
|
|
274
|
+
provision_result: Output from provision().
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
True if configuration succeeded.
|
|
278
|
+
"""
|
|
279
|
+
vmid = provision_result.get("vmid")
|
|
280
|
+
if not vmid:
|
|
281
|
+
return False
|
|
282
|
+
|
|
283
|
+
# Start container if needed
|
|
284
|
+
try:
|
|
285
|
+
status = self._api_call(
|
|
286
|
+
"GET",
|
|
287
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/current",
|
|
288
|
+
)
|
|
289
|
+
if status.get("status") != "running":
|
|
290
|
+
self._api_call(
|
|
291
|
+
"POST",
|
|
292
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/start",
|
|
293
|
+
)
|
|
294
|
+
time.sleep(5)
|
|
295
|
+
except RuntimeError as exc:
|
|
296
|
+
logger.error("Failed to start LXC %d: %s", vmid, exc)
|
|
297
|
+
return False
|
|
298
|
+
|
|
299
|
+
config = {
|
|
300
|
+
"agent_name": agent_name,
|
|
301
|
+
"role": spec.role.value,
|
|
302
|
+
"model": spec.model_name or spec.model.value,
|
|
303
|
+
"skills": spec.skills,
|
|
304
|
+
"soul_blueprint": spec.soul_blueprint,
|
|
305
|
+
}
|
|
306
|
+
config_json = json.dumps(config, indent=2)
|
|
307
|
+
|
|
308
|
+
# Write config inside the container
|
|
309
|
+
escaped = config_json.replace("'", "'\\''")
|
|
310
|
+
write_cmd = (
|
|
311
|
+
f"mkdir -p /opt/agent && "
|
|
312
|
+
f"printf '%s' '{escaped}' > /opt/agent/config.json"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
ok = self._exec_in_container(vmid, write_cmd)
|
|
316
|
+
|
|
317
|
+
# Also install skcapstone inside the container
|
|
318
|
+
install_cmd = (
|
|
319
|
+
"apt-get update -qq && "
|
|
320
|
+
"apt-get install -y -qq python3 python3-pip python3-venv curl gnupg && "
|
|
321
|
+
"pip3 install --quiet skcapstone"
|
|
322
|
+
)
|
|
323
|
+
self._exec_in_container(vmid, install_cmd)
|
|
324
|
+
|
|
325
|
+
logger.info(
|
|
326
|
+
"LXC %d configured for agent %s (config_written=%s)",
|
|
327
|
+
vmid, agent_name, ok,
|
|
328
|
+
)
|
|
329
|
+
return True
|
|
330
|
+
|
|
331
|
+
def start(
|
|
332
|
+
self,
|
|
333
|
+
agent_name: str,
|
|
334
|
+
provision_result: Dict[str, Any],
|
|
335
|
+
) -> bool:
|
|
336
|
+
"""Start the LXC container.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
agent_name: Agent instance name.
|
|
340
|
+
provision_result: Output from provision().
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
True if started.
|
|
344
|
+
"""
|
|
345
|
+
vmid = provision_result.get("vmid")
|
|
346
|
+
if not vmid:
|
|
347
|
+
return False
|
|
348
|
+
|
|
349
|
+
try:
|
|
350
|
+
self._api_call(
|
|
351
|
+
"POST",
|
|
352
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/start",
|
|
353
|
+
)
|
|
354
|
+
return True
|
|
355
|
+
except RuntimeError:
|
|
356
|
+
return False
|
|
357
|
+
|
|
358
|
+
def stop(
|
|
359
|
+
self,
|
|
360
|
+
agent_name: str,
|
|
361
|
+
provision_result: Dict[str, Any],
|
|
362
|
+
) -> bool:
|
|
363
|
+
"""Stop the LXC container.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
agent_name: Agent instance name.
|
|
367
|
+
provision_result: Output from provision().
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
True if stopped.
|
|
371
|
+
"""
|
|
372
|
+
vmid = provision_result.get("vmid")
|
|
373
|
+
if not vmid:
|
|
374
|
+
return False
|
|
375
|
+
|
|
376
|
+
try:
|
|
377
|
+
self._api_call(
|
|
378
|
+
"POST",
|
|
379
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/stop",
|
|
380
|
+
)
|
|
381
|
+
return True
|
|
382
|
+
except RuntimeError:
|
|
383
|
+
return False
|
|
384
|
+
|
|
385
|
+
def destroy(
|
|
386
|
+
self,
|
|
387
|
+
agent_name: str,
|
|
388
|
+
provision_result: Dict[str, Any],
|
|
389
|
+
) -> bool:
|
|
390
|
+
"""Destroy the LXC container.
|
|
391
|
+
|
|
392
|
+
Args:
|
|
393
|
+
agent_name: Agent instance name.
|
|
394
|
+
provision_result: Output from provision().
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
True if destroyed.
|
|
398
|
+
"""
|
|
399
|
+
vmid = provision_result.get("vmid")
|
|
400
|
+
if not vmid:
|
|
401
|
+
return False
|
|
402
|
+
|
|
403
|
+
try:
|
|
404
|
+
self.stop(agent_name, provision_result)
|
|
405
|
+
time.sleep(3)
|
|
406
|
+
self._api_call(
|
|
407
|
+
"DELETE",
|
|
408
|
+
f"/nodes/{self._node}/lxc/{vmid}",
|
|
409
|
+
data={"purge": 1},
|
|
410
|
+
)
|
|
411
|
+
return True
|
|
412
|
+
except RuntimeError as exc:
|
|
413
|
+
logger.error("Failed to destroy LXC %d: %s", vmid, exc)
|
|
414
|
+
return False
|
|
415
|
+
|
|
416
|
+
def health_check(
|
|
417
|
+
self,
|
|
418
|
+
agent_name: str,
|
|
419
|
+
provision_result: Dict[str, Any],
|
|
420
|
+
) -> AgentStatus:
|
|
421
|
+
"""Check LXC container status.
|
|
422
|
+
|
|
423
|
+
Args:
|
|
424
|
+
agent_name: Agent instance name.
|
|
425
|
+
provision_result: Output from provision().
|
|
426
|
+
|
|
427
|
+
Returns:
|
|
428
|
+
AgentStatus based on container state.
|
|
429
|
+
"""
|
|
430
|
+
vmid = provision_result.get("vmid")
|
|
431
|
+
if not vmid:
|
|
432
|
+
return AgentStatus.STOPPED
|
|
433
|
+
|
|
434
|
+
try:
|
|
435
|
+
status = self._api_call(
|
|
436
|
+
"GET",
|
|
437
|
+
f"/nodes/{self._node}/lxc/{vmid}/status/current",
|
|
438
|
+
)
|
|
439
|
+
state = status.get("status", "stopped")
|
|
440
|
+
if state == "running":
|
|
441
|
+
return AgentStatus.RUNNING
|
|
442
|
+
elif state == "stopped":
|
|
443
|
+
return AgentStatus.STOPPED
|
|
444
|
+
else:
|
|
445
|
+
return AgentStatus.DEGRADED
|
|
446
|
+
except RuntimeError:
|
|
447
|
+
return AgentStatus.FAILED
|