@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,296 @@
|
|
|
1
|
+
"""E2E tests for the consciousness pipeline — no real LLM needed."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from unittest.mock import MagicMock, patch
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from skcapstone.consciousness_loop import (
|
|
12
|
+
ConsciousnessConfig,
|
|
13
|
+
ConsciousnessLoop,
|
|
14
|
+
LLMBridge,
|
|
15
|
+
SystemPromptBuilder,
|
|
16
|
+
InboxHandler,
|
|
17
|
+
_SimpleEnvelope,
|
|
18
|
+
_classify_message,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Helpers
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _make_loop(tmp_path: Path, config: ConsciousnessConfig | None = None) -> ConsciousnessLoop:
|
|
28
|
+
"""Create a ConsciousnessLoop with tmp dirs and no real backend probing."""
|
|
29
|
+
home = tmp_path / "home"
|
|
30
|
+
home.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
shared_root = tmp_path / "shared"
|
|
32
|
+
shared_root.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
|
|
34
|
+
if config is None:
|
|
35
|
+
config = ConsciousnessConfig(
|
|
36
|
+
auto_memory=False, # avoid skcapstone.memory_engine I/O
|
|
37
|
+
auto_ack=False, # no SKComm needed
|
|
38
|
+
use_inotify=False, # no filesystem watcher needed
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
with patch.object(LLMBridge, "_probe_ollama", return_value=False):
|
|
42
|
+
loop = ConsciousnessLoop(config, home=home, shared_root=shared_root)
|
|
43
|
+
|
|
44
|
+
return loop
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _text_envelope(content: str, sender: str = "test-peer") -> _SimpleEnvelope:
|
|
48
|
+
"""Build a minimal text envelope."""
|
|
49
|
+
return _SimpleEnvelope({
|
|
50
|
+
"sender": sender,
|
|
51
|
+
"payload": {"content": content, "content_type": "text"},
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _ack_envelope() -> _SimpleEnvelope:
|
|
56
|
+
"""Build a minimal ACK envelope."""
|
|
57
|
+
return _SimpleEnvelope({
|
|
58
|
+
"sender": "test-peer",
|
|
59
|
+
"payload": {"content": "ACK", "content_type": "ack"},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
# Tests
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class TestFullPipelineMockLLM:
|
|
69
|
+
"""test_full_pipeline_mock_llm — ConsciousnessLoop with a mock LLMBridge."""
|
|
70
|
+
|
|
71
|
+
def test_returns_response(self, tmp_path):
|
|
72
|
+
"""process_envelope() returns the LLM response."""
|
|
73
|
+
loop = _make_loop(tmp_path)
|
|
74
|
+
|
|
75
|
+
mock_bridge = MagicMock()
|
|
76
|
+
mock_bridge.generate.return_value = "hello back"
|
|
77
|
+
mock_bridge.available_backends = {"passthrough": True}
|
|
78
|
+
loop._bridge = mock_bridge
|
|
79
|
+
|
|
80
|
+
envelope = _text_envelope("hello world")
|
|
81
|
+
result = loop.process_envelope(envelope)
|
|
82
|
+
|
|
83
|
+
assert result == "hello back"
|
|
84
|
+
|
|
85
|
+
def test_messages_processed_increments(self, tmp_path):
|
|
86
|
+
"""stats['messages_processed'] is 1 after processing one message."""
|
|
87
|
+
loop = _make_loop(tmp_path)
|
|
88
|
+
|
|
89
|
+
mock_bridge = MagicMock()
|
|
90
|
+
mock_bridge.generate.return_value = "response"
|
|
91
|
+
mock_bridge.available_backends = {"passthrough": True}
|
|
92
|
+
loop._bridge = mock_bridge
|
|
93
|
+
|
|
94
|
+
assert loop.stats["messages_processed"] == 0
|
|
95
|
+
loop.process_envelope(_text_envelope("ping"))
|
|
96
|
+
assert loop.stats["messages_processed"] == 1
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class TestPipelineSkipsAckMessages:
|
|
100
|
+
"""test_pipeline_skips_ack_messages — ACK envelopes are ignored."""
|
|
101
|
+
|
|
102
|
+
def test_ack_returns_none(self, tmp_path):
|
|
103
|
+
"""process_envelope() returns None for an ACK message."""
|
|
104
|
+
loop = _make_loop(tmp_path)
|
|
105
|
+
result = loop.process_envelope(_ack_envelope())
|
|
106
|
+
assert result is None
|
|
107
|
+
|
|
108
|
+
def test_ack_does_not_increment_counter(self, tmp_path):
|
|
109
|
+
"""ACK messages do NOT increment messages_processed."""
|
|
110
|
+
loop = _make_loop(tmp_path)
|
|
111
|
+
loop.process_envelope(_ack_envelope())
|
|
112
|
+
# ACK is skipped before the counter increment
|
|
113
|
+
assert loop.stats["messages_processed"] == 0
|
|
114
|
+
|
|
115
|
+
@pytest.mark.parametrize("skip_type", ["heartbeat", "file", "file_chunk", "file_manifest"])
|
|
116
|
+
def test_other_skip_types_return_none(self, tmp_path, skip_type):
|
|
117
|
+
"""process_envelope() returns None for all non-text content types."""
|
|
118
|
+
loop = _make_loop(tmp_path)
|
|
119
|
+
envelope = _SimpleEnvelope({
|
|
120
|
+
"sender": "peer",
|
|
121
|
+
"payload": {"content": "data", "content_type": skip_type},
|
|
122
|
+
})
|
|
123
|
+
assert loop.process_envelope(envelope) is None
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class TestPipelineStoresConversationHistory:
|
|
127
|
+
"""test_pipeline_stores_conversation_history — history is updated."""
|
|
128
|
+
|
|
129
|
+
def test_user_message_in_history(self, tmp_path):
|
|
130
|
+
"""After processing, the sender's message appears in conversation history."""
|
|
131
|
+
loop = _make_loop(tmp_path)
|
|
132
|
+
|
|
133
|
+
mock_bridge = MagicMock()
|
|
134
|
+
mock_bridge.generate.return_value = "got it"
|
|
135
|
+
mock_bridge.available_backends = {"passthrough": True}
|
|
136
|
+
loop._bridge = mock_bridge
|
|
137
|
+
|
|
138
|
+
loop.process_envelope(_text_envelope("what is the answer?", sender="alice"))
|
|
139
|
+
|
|
140
|
+
history = loop._prompt_builder._conversation_history
|
|
141
|
+
assert "alice" in history
|
|
142
|
+
user_msgs = [m for m in history["alice"] if m.get("role") == "user"]
|
|
143
|
+
assert any("what is the answer?" in m.get("content", "") for m in user_msgs)
|
|
144
|
+
|
|
145
|
+
def test_assistant_reply_in_history(self, tmp_path):
|
|
146
|
+
"""After processing, the assistant reply is stored in history."""
|
|
147
|
+
loop = _make_loop(tmp_path)
|
|
148
|
+
|
|
149
|
+
mock_bridge = MagicMock()
|
|
150
|
+
mock_bridge.generate.return_value = "forty-two"
|
|
151
|
+
mock_bridge.available_backends = {"passthrough": True}
|
|
152
|
+
loop._bridge = mock_bridge
|
|
153
|
+
|
|
154
|
+
loop.process_envelope(_text_envelope("what is the answer?", sender="bob"))
|
|
155
|
+
|
|
156
|
+
history = loop._prompt_builder._conversation_history
|
|
157
|
+
assistant_msgs = [m for m in history.get("bob", []) if m.get("role") == "assistant"]
|
|
158
|
+
assert any("forty-two" in m.get("content", "") for m in assistant_msgs)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class TestPipelineHandlesLLMFailure:
|
|
162
|
+
"""test_pipeline_handles_llm_failure — errors are counted and None returned."""
|
|
163
|
+
|
|
164
|
+
def test_returns_none_on_generate_exception(self, tmp_path):
|
|
165
|
+
"""process_envelope() returns None when LLMBridge.generate() raises."""
|
|
166
|
+
loop = _make_loop(tmp_path)
|
|
167
|
+
|
|
168
|
+
mock_bridge = MagicMock()
|
|
169
|
+
mock_bridge.generate.side_effect = RuntimeError("backend unavailable")
|
|
170
|
+
mock_bridge.available_backends = {}
|
|
171
|
+
loop._bridge = mock_bridge
|
|
172
|
+
|
|
173
|
+
result = loop.process_envelope(_text_envelope("hello"))
|
|
174
|
+
assert result is None
|
|
175
|
+
|
|
176
|
+
def test_errors_count_increments(self, tmp_path):
|
|
177
|
+
"""errors counter increments when LLMBridge.generate() raises."""
|
|
178
|
+
loop = _make_loop(tmp_path)
|
|
179
|
+
|
|
180
|
+
mock_bridge = MagicMock()
|
|
181
|
+
mock_bridge.generate.side_effect = RuntimeError("boom")
|
|
182
|
+
mock_bridge.available_backends = {}
|
|
183
|
+
loop._bridge = mock_bridge
|
|
184
|
+
|
|
185
|
+
assert loop.stats["errors"] == 0
|
|
186
|
+
loop.process_envelope(_text_envelope("hello"))
|
|
187
|
+
assert loop.stats["errors"] == 1
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class _FakeEvent:
|
|
191
|
+
"""Minimal watchdog-style file creation event."""
|
|
192
|
+
|
|
193
|
+
def __init__(self, src_path: str, is_directory: bool = False) -> None:
|
|
194
|
+
self.src_path = src_path
|
|
195
|
+
self.is_directory = is_directory
|
|
196
|
+
self.event_type = "created"
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class TestInotifyHandlerDebounce:
|
|
200
|
+
"""test_inotify_handler_debounce — rapid duplicate events are collapsed."""
|
|
201
|
+
|
|
202
|
+
def test_single_call_on_rapid_duplicates(self):
|
|
203
|
+
"""Callback is invoked only once when the same path fires twice within debounce window."""
|
|
204
|
+
calls: list[Path] = []
|
|
205
|
+
handler = InboxHandler(callback=calls.append, debounce_ms=5000)
|
|
206
|
+
|
|
207
|
+
event = _FakeEvent("/inbox/msg.skc.json")
|
|
208
|
+
handler.on_created(event)
|
|
209
|
+
handler.on_created(event) # rapid second fire — within 5 s
|
|
210
|
+
|
|
211
|
+
assert len(calls) == 1
|
|
212
|
+
|
|
213
|
+
def test_two_calls_after_debounce_expires(self):
|
|
214
|
+
"""Callback is invoked twice when events are separated by > debounce window."""
|
|
215
|
+
calls: list[Path] = []
|
|
216
|
+
handler = InboxHandler(callback=calls.append, debounce_ms=50) # 50 ms
|
|
217
|
+
|
|
218
|
+
event = _FakeEvent("/inbox/msg2.skc.json")
|
|
219
|
+
handler.on_created(event)
|
|
220
|
+
time.sleep(0.06) # 60 ms — past the 50 ms window
|
|
221
|
+
handler.on_created(event)
|
|
222
|
+
|
|
223
|
+
assert len(calls) == 2
|
|
224
|
+
|
|
225
|
+
def test_ignores_non_skc_json_files(self):
|
|
226
|
+
"""Callback is NOT called for non-.skc.json files."""
|
|
227
|
+
calls: list[Path] = []
|
|
228
|
+
handler = InboxHandler(callback=calls.append)
|
|
229
|
+
|
|
230
|
+
handler.on_created(_FakeEvent("/inbox/somefile.txt"))
|
|
231
|
+
handler.on_created(_FakeEvent("/inbox/data.json"))
|
|
232
|
+
|
|
233
|
+
assert len(calls) == 0
|
|
234
|
+
|
|
235
|
+
def test_ignores_directory_events(self):
|
|
236
|
+
"""Callback is NOT called for directory creation events."""
|
|
237
|
+
calls: list[Path] = []
|
|
238
|
+
handler = InboxHandler(callback=calls.append)
|
|
239
|
+
|
|
240
|
+
handler.on_created(_FakeEvent("/inbox/subdir", is_directory=True))
|
|
241
|
+
|
|
242
|
+
assert len(calls) == 0
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class TestClassifyMessageTags:
|
|
246
|
+
"""test_classify_message_tags — keyword-to-tag mapping."""
|
|
247
|
+
|
|
248
|
+
@pytest.mark.parametrize("msg,expected_tag", [
|
|
249
|
+
("please debug this function", "code"),
|
|
250
|
+
("can you fix this error?", "code"),
|
|
251
|
+
("implement the class now", "code"),
|
|
252
|
+
("can you analyze the architecture", "analyze"),
|
|
253
|
+
("explain why this fails", "analyze"),
|
|
254
|
+
("write a story about a penguin", "creative"),
|
|
255
|
+
("compose a marketing email", "creative"),
|
|
256
|
+
("hi", "simple"),
|
|
257
|
+
("hello there", "simple"),
|
|
258
|
+
("ok", "simple"),
|
|
259
|
+
("the clouds look nice today", "general"),
|
|
260
|
+
])
|
|
261
|
+
def test_tag_assigned(self, msg: str, expected_tag: str):
|
|
262
|
+
"""Correct tag is assigned based on keyword presence."""
|
|
263
|
+
signal = _classify_message(msg)
|
|
264
|
+
assert expected_tag in signal.tags, (
|
|
265
|
+
f"Expected tag {expected_tag!r} for message {msg!r}, got {signal.tags}"
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
def test_general_tag_when_no_keywords(self):
|
|
269
|
+
"""Messages with no matching keywords get exactly ['general']."""
|
|
270
|
+
signal = _classify_message("the sky is beautiful today")
|
|
271
|
+
assert signal.tags == ["general"]
|
|
272
|
+
|
|
273
|
+
def test_multiple_tags_on_overlap(self):
|
|
274
|
+
"""Messages matching multiple keyword sets receive multiple tags."""
|
|
275
|
+
signal = _classify_message("debug and analyze this code architecture")
|
|
276
|
+
assert "code" in signal.tags
|
|
277
|
+
assert "analyze" in signal.tags
|
|
278
|
+
|
|
279
|
+
def test_simple_tag_requires_short_message(self):
|
|
280
|
+
"""'simple' tag is only assigned if the message is < 50 chars."""
|
|
281
|
+
short_msg = "hello"
|
|
282
|
+
long_msg = "hello " + "x" * 50 # > 50 chars
|
|
283
|
+
assert "simple" in _classify_message(short_msg).tags
|
|
284
|
+
assert "simple" not in _classify_message(long_msg).tags
|
|
285
|
+
|
|
286
|
+
def test_token_estimate(self):
|
|
287
|
+
"""Estimated tokens is approximately content_length / 4."""
|
|
288
|
+
msg = "a" * 400
|
|
289
|
+
signal = _classify_message(msg)
|
|
290
|
+
assert signal.estimated_tokens == 100
|
|
291
|
+
|
|
292
|
+
def test_description_capped_at_100_chars(self):
|
|
293
|
+
"""TaskSignal description is capped at 100 characters."""
|
|
294
|
+
msg = "x" * 200
|
|
295
|
+
signal = _classify_message(msg)
|
|
296
|
+
assert len(signal.description) == 100
|