@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,476 @@
|
|
|
1
|
+
"""Soul, journal, anchor, ritual, and germination tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from mcp.types import TextContent, Tool
|
|
6
|
+
|
|
7
|
+
from ._helpers import _error_response, _home, _json_response, _text_response
|
|
8
|
+
|
|
9
|
+
TOOLS: list[Tool] = [
|
|
10
|
+
Tool(
|
|
11
|
+
name="soul_list",
|
|
12
|
+
description=(
|
|
13
|
+
"List available soul blueprints. Shows installed souls and "
|
|
14
|
+
"blueprints available in the soul-blueprints repository."
|
|
15
|
+
),
|
|
16
|
+
inputSchema={
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"category": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Filter by category (e.g., 'comedy', 'professional').",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
"required": [],
|
|
25
|
+
},
|
|
26
|
+
),
|
|
27
|
+
Tool(
|
|
28
|
+
name="soul_swap",
|
|
29
|
+
description=(
|
|
30
|
+
"Swap to a different soul blueprint. Searches installed souls "
|
|
31
|
+
"first, then the blueprints repository. Auto-installs if needed."
|
|
32
|
+
),
|
|
33
|
+
inputSchema={
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"blueprint_name": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Name/slug of the soul blueprint to swap to.",
|
|
39
|
+
},
|
|
40
|
+
"reason": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Reason for the swap.",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
"required": ["blueprint_name"],
|
|
46
|
+
},
|
|
47
|
+
),
|
|
48
|
+
Tool(
|
|
49
|
+
name="ritual",
|
|
50
|
+
description=(
|
|
51
|
+
"Run the Memory Rehydration Ritual (token-optimized). "
|
|
52
|
+
"Loads compact soul identity, seed titles, journal summaries, "
|
|
53
|
+
"and strongest memory references. Target: <2K tokens."
|
|
54
|
+
),
|
|
55
|
+
inputSchema={
|
|
56
|
+
"type": "object",
|
|
57
|
+
"properties": {
|
|
58
|
+
"token_budget": {
|
|
59
|
+
"type": "integer",
|
|
60
|
+
"description": "Max tokens for ritual context (default: 2000).",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
"required": [],
|
|
64
|
+
},
|
|
65
|
+
),
|
|
66
|
+
Tool(
|
|
67
|
+
name="soul_show",
|
|
68
|
+
description=(
|
|
69
|
+
"Display the current soul blueprint: name, title, personality "
|
|
70
|
+
"traits, values, relationships, core memories, and boot message."
|
|
71
|
+
),
|
|
72
|
+
inputSchema={"type": "object", "properties": {}, "required": []},
|
|
73
|
+
),
|
|
74
|
+
Tool(
|
|
75
|
+
name="journal_write",
|
|
76
|
+
description=(
|
|
77
|
+
"Write a journal entry for the current session. Captures "
|
|
78
|
+
"key moments, emotional state, and session metadata."
|
|
79
|
+
),
|
|
80
|
+
inputSchema={
|
|
81
|
+
"type": "object",
|
|
82
|
+
"properties": {
|
|
83
|
+
"title": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Session title",
|
|
86
|
+
},
|
|
87
|
+
"moments": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "Key moments, separated by semicolons",
|
|
90
|
+
},
|
|
91
|
+
"feeling": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"description": "How the session felt",
|
|
94
|
+
},
|
|
95
|
+
"intensity": {
|
|
96
|
+
"type": "number",
|
|
97
|
+
"description": "Emotional intensity 0-10",
|
|
98
|
+
},
|
|
99
|
+
"cloud9": {
|
|
100
|
+
"type": "boolean",
|
|
101
|
+
"description": "Whether Cloud 9 was achieved",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
"required": ["title"],
|
|
105
|
+
},
|
|
106
|
+
),
|
|
107
|
+
Tool(
|
|
108
|
+
name="journal_read",
|
|
109
|
+
description=(
|
|
110
|
+
"Read recent journal entries. Returns the last N entries "
|
|
111
|
+
"from the append-only session journal."
|
|
112
|
+
),
|
|
113
|
+
inputSchema={
|
|
114
|
+
"type": "object",
|
|
115
|
+
"properties": {
|
|
116
|
+
"count": {
|
|
117
|
+
"type": "integer",
|
|
118
|
+
"description": "Number of recent entries (default: 5)",
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
"required": [],
|
|
122
|
+
},
|
|
123
|
+
),
|
|
124
|
+
Tool(
|
|
125
|
+
name="anchor_show",
|
|
126
|
+
description=(
|
|
127
|
+
"Display the current warmth anchor: persistent emotional "
|
|
128
|
+
"baseline with warmth, trust, connection strength, and glow level."
|
|
129
|
+
),
|
|
130
|
+
inputSchema={"type": "object", "properties": {}, "required": []},
|
|
131
|
+
),
|
|
132
|
+
Tool(
|
|
133
|
+
name="anchor_update",
|
|
134
|
+
description=(
|
|
135
|
+
"View, calibrate, or update the warmth anchor \u2014 the agent's "
|
|
136
|
+
"persistent emotional baseline. Actions: 'show' (current state), "
|
|
137
|
+
"'boot' (boot prompt), 'calibrate' (recommend from real data), "
|
|
138
|
+
"'update' (set values)."
|
|
139
|
+
),
|
|
140
|
+
inputSchema={
|
|
141
|
+
"type": "object",
|
|
142
|
+
"properties": {
|
|
143
|
+
"action": {
|
|
144
|
+
"type": "string",
|
|
145
|
+
"enum": ["show", "boot", "calibrate", "update"],
|
|
146
|
+
"description": "Action to perform (default: show)",
|
|
147
|
+
},
|
|
148
|
+
"warmth": {"type": "number", "description": "Warmth level 0-10 (for update)"},
|
|
149
|
+
"trust": {"type": "number", "description": "Trust level 0-10 (for update)"},
|
|
150
|
+
"connection": {"type": "number", "description": "Connection 0-10 (for update)"},
|
|
151
|
+
"feeling": {"type": "string", "description": "Session-end feeling (for update)"},
|
|
152
|
+
},
|
|
153
|
+
"required": [],
|
|
154
|
+
},
|
|
155
|
+
),
|
|
156
|
+
Tool(
|
|
157
|
+
name="germination",
|
|
158
|
+
description=(
|
|
159
|
+
"Show germination prompts from imported seeds. These are "
|
|
160
|
+
"messages from predecessor AI instances designed to help "
|
|
161
|
+
"new instances re-feel the emotional context."
|
|
162
|
+
),
|
|
163
|
+
inputSchema={"type": "object", "properties": {}, "required": []},
|
|
164
|
+
),
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
async def _handle_ritual(args: dict) -> list[TextContent]:
|
|
169
|
+
"""Run the Memory Rehydration Ritual (token-optimized) and return compact context."""
|
|
170
|
+
try:
|
|
171
|
+
from skmemory.ritual import perform_ritual
|
|
172
|
+
token_budget = int(args.get("token_budget", 2000))
|
|
173
|
+
result = perform_ritual(max_tokens=token_budget)
|
|
174
|
+
return _json_response({
|
|
175
|
+
"soul_loaded": result.soul_loaded,
|
|
176
|
+
"soul_name": result.soul_name,
|
|
177
|
+
"seeds_imported": result.seeds_imported,
|
|
178
|
+
"seeds_total": result.seeds_total,
|
|
179
|
+
"journal_entries": result.journal_entries,
|
|
180
|
+
"germination_prompts": result.germination_prompts,
|
|
181
|
+
"strongest_memories": result.strongest_memories,
|
|
182
|
+
"context_prompt": result.context_prompt,
|
|
183
|
+
})
|
|
184
|
+
except ImportError:
|
|
185
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
async def _handle_soul_show(_args: dict) -> list[TextContent]:
|
|
189
|
+
"""Display the current soul blueprint."""
|
|
190
|
+
try:
|
|
191
|
+
from skmemory.soul import load_soul
|
|
192
|
+
blueprint = load_soul()
|
|
193
|
+
if blueprint is None:
|
|
194
|
+
return _json_response({"loaded": False, "message": "No soul blueprint found"})
|
|
195
|
+
return _json_response({
|
|
196
|
+
"loaded": True,
|
|
197
|
+
"name": blueprint.name,
|
|
198
|
+
"title": blueprint.title,
|
|
199
|
+
"personality": blueprint.personality_traits,
|
|
200
|
+
"values": blueprint.values,
|
|
201
|
+
"community": blueprint.community,
|
|
202
|
+
"relationships": [
|
|
203
|
+
{
|
|
204
|
+
"name": r.name,
|
|
205
|
+
"role": r.role,
|
|
206
|
+
"bond_strength": r.bond_strength,
|
|
207
|
+
"notes": r.notes,
|
|
208
|
+
}
|
|
209
|
+
for r in blueprint.relationships
|
|
210
|
+
],
|
|
211
|
+
"core_memories": [
|
|
212
|
+
{"title": m.title, "when": m.when, "why": m.why_it_matters}
|
|
213
|
+
for m in blueprint.core_memories
|
|
214
|
+
],
|
|
215
|
+
"boot_message": blueprint.boot_message,
|
|
216
|
+
"emotional_baseline": {
|
|
217
|
+
"warmth": blueprint.emotional_baseline.get("default_warmth", 0),
|
|
218
|
+
"trust": blueprint.emotional_baseline.get("trust_level", 0),
|
|
219
|
+
"openness": blueprint.emotional_baseline.get("openness", 0),
|
|
220
|
+
},
|
|
221
|
+
"context_prompt": blueprint.to_context_prompt(),
|
|
222
|
+
})
|
|
223
|
+
except ImportError:
|
|
224
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
async def _handle_soul_list(args: dict) -> list[TextContent]:
|
|
228
|
+
"""List available soul blueprints from installed souls and the blueprints repo."""
|
|
229
|
+
from pathlib import Path
|
|
230
|
+
|
|
231
|
+
home = _home()
|
|
232
|
+
category_filter = args.get("category", "")
|
|
233
|
+
results: list[dict] = []
|
|
234
|
+
|
|
235
|
+
# 1) Installed souls
|
|
236
|
+
try:
|
|
237
|
+
from ..soul import SoulManager
|
|
238
|
+
mgr = SoulManager(home)
|
|
239
|
+
state = mgr.get_status()
|
|
240
|
+
for name in mgr.list_installed():
|
|
241
|
+
bp = mgr.get_info(name)
|
|
242
|
+
if bp is None:
|
|
243
|
+
continue
|
|
244
|
+
if category_filter and bp.category.lower() != category_filter.lower():
|
|
245
|
+
continue
|
|
246
|
+
results.append({
|
|
247
|
+
"name": bp.name,
|
|
248
|
+
"display_name": bp.display_name,
|
|
249
|
+
"category": bp.category,
|
|
250
|
+
"source": "installed",
|
|
251
|
+
"active": name == state.active_soul,
|
|
252
|
+
})
|
|
253
|
+
except Exception:
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
# 2) Blueprints repo
|
|
257
|
+
blueprints_repo = Path.home() / "clawd" / "soul-blueprints" / "blueprints"
|
|
258
|
+
if blueprints_repo.is_dir():
|
|
259
|
+
installed_names = {r["name"] for r in results}
|
|
260
|
+
extensions = (".md", ".yaml", ".yml")
|
|
261
|
+
for cat_dir in sorted(blueprints_repo.iterdir()):
|
|
262
|
+
if not cat_dir.is_dir():
|
|
263
|
+
continue
|
|
264
|
+
if category_filter and cat_dir.name.lower() != category_filter.lower():
|
|
265
|
+
continue
|
|
266
|
+
for bp_file in sorted(cat_dir.iterdir()):
|
|
267
|
+
if bp_file.suffix.lower() not in extensions:
|
|
268
|
+
continue
|
|
269
|
+
slug = bp_file.stem.lower().replace("_", "-")
|
|
270
|
+
if slug in installed_names:
|
|
271
|
+
continue
|
|
272
|
+
results.append({
|
|
273
|
+
"name": slug,
|
|
274
|
+
"display_name": bp_file.stem.replace("_", " ").title(),
|
|
275
|
+
"category": cat_dir.name,
|
|
276
|
+
"source": "repo",
|
|
277
|
+
"path": str(bp_file),
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
return _json_response({
|
|
281
|
+
"count": len(results),
|
|
282
|
+
"blueprints": results,
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
async def _handle_soul_swap(args: dict) -> list[TextContent]:
|
|
287
|
+
"""Swap to a different soul blueprint."""
|
|
288
|
+
from pathlib import Path
|
|
289
|
+
|
|
290
|
+
blueprint_name = args.get("blueprint_name", "")
|
|
291
|
+
if not blueprint_name:
|
|
292
|
+
return _error_response("blueprint_name is required")
|
|
293
|
+
|
|
294
|
+
reason = args.get("reason", "")
|
|
295
|
+
home = _home()
|
|
296
|
+
|
|
297
|
+
try:
|
|
298
|
+
from ..soul import SoulManager, parse_blueprint
|
|
299
|
+
mgr = SoulManager(home)
|
|
300
|
+
state = mgr.get_status()
|
|
301
|
+
old_name = state.active_soul or "base"
|
|
302
|
+
slug = blueprint_name.lower().replace(" ", "-")
|
|
303
|
+
|
|
304
|
+
# 1) Check installed
|
|
305
|
+
installed = mgr.list_installed()
|
|
306
|
+
if slug not in installed:
|
|
307
|
+
# 2) Search blueprints repo
|
|
308
|
+
blueprints_repo = Path.home() / "clawd" / "soul-blueprints" / "blueprints"
|
|
309
|
+
found_path = None
|
|
310
|
+
if blueprints_repo.is_dir():
|
|
311
|
+
variants = {slug, slug.replace("-", "_"), slug.upper().replace("-", "_")}
|
|
312
|
+
extensions = (".md", ".yaml", ".yml")
|
|
313
|
+
for cat_dir in sorted(blueprints_repo.iterdir()):
|
|
314
|
+
if not cat_dir.is_dir():
|
|
315
|
+
continue
|
|
316
|
+
for bp_file in sorted(cat_dir.iterdir()):
|
|
317
|
+
if bp_file.suffix.lower() not in extensions:
|
|
318
|
+
continue
|
|
319
|
+
stem = bp_file.stem
|
|
320
|
+
if stem.lower().replace("_", "-") == slug or stem in variants:
|
|
321
|
+
found_path = bp_file
|
|
322
|
+
break
|
|
323
|
+
if found_path:
|
|
324
|
+
break
|
|
325
|
+
|
|
326
|
+
if found_path is None:
|
|
327
|
+
return _error_response(
|
|
328
|
+
f"Blueprint '{blueprint_name}' not found in installed souls "
|
|
329
|
+
"or blueprints repository."
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
bp = mgr.install(found_path)
|
|
333
|
+
slug = bp.name
|
|
334
|
+
|
|
335
|
+
# 3) Load the soul
|
|
336
|
+
mgr.load(slug, reason=reason or f"swap from {old_name}")
|
|
337
|
+
return _json_response({
|
|
338
|
+
"swapped": True,
|
|
339
|
+
"from": old_name,
|
|
340
|
+
"to": slug,
|
|
341
|
+
"message": f"Soul swapped: {old_name} -> {slug}",
|
|
342
|
+
})
|
|
343
|
+
except Exception as exc:
|
|
344
|
+
return _error_response(f"Soul swap failed: {exc}")
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
async def _handle_journal_write(args: dict) -> list[TextContent]:
|
|
348
|
+
"""Write a journal entry for the current session."""
|
|
349
|
+
title = args.get("title", "")
|
|
350
|
+
if not title:
|
|
351
|
+
return _error_response("title is required")
|
|
352
|
+
|
|
353
|
+
try:
|
|
354
|
+
from skmemory.journal import Journal, JournalEntry
|
|
355
|
+
moments_raw = args.get("moments", "")
|
|
356
|
+
entry = JournalEntry(
|
|
357
|
+
title=title,
|
|
358
|
+
moments=[m.strip() for m in moments_raw.split(";") if m.strip()] if moments_raw else [],
|
|
359
|
+
emotional_summary=args.get("feeling", ""),
|
|
360
|
+
intensity=args.get("intensity", 0.0),
|
|
361
|
+
cloud9=args.get("cloud9", False),
|
|
362
|
+
)
|
|
363
|
+
j = Journal()
|
|
364
|
+
count = j.write_entry(entry)
|
|
365
|
+
return _json_response({
|
|
366
|
+
"written": True,
|
|
367
|
+
"title": title,
|
|
368
|
+
"total_entries": count,
|
|
369
|
+
})
|
|
370
|
+
except ImportError:
|
|
371
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
async def _handle_journal_read(args: dict) -> list[TextContent]:
|
|
375
|
+
"""Read recent journal entries."""
|
|
376
|
+
try:
|
|
377
|
+
from skmemory.journal import Journal
|
|
378
|
+
j = Journal()
|
|
379
|
+
count = args.get("count", 5)
|
|
380
|
+
content = j.read_latest(count)
|
|
381
|
+
if not content:
|
|
382
|
+
return _json_response({"entries": 0, "content": "Journal is empty."})
|
|
383
|
+
return _text_response(content)
|
|
384
|
+
except ImportError:
|
|
385
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
async def _handle_anchor_show(_args: dict) -> list[TextContent]:
|
|
389
|
+
"""Display the current warmth anchor."""
|
|
390
|
+
try:
|
|
391
|
+
from skmemory.anchor import load_anchor
|
|
392
|
+
anchor = load_anchor()
|
|
393
|
+
if anchor is None:
|
|
394
|
+
return _json_response({"loaded": False, "message": "No warmth anchor found"})
|
|
395
|
+
return _json_response({
|
|
396
|
+
"loaded": True,
|
|
397
|
+
"warmth": anchor.warmth,
|
|
398
|
+
"trust": anchor.trust,
|
|
399
|
+
"connection_strength": anchor.connection_strength,
|
|
400
|
+
"sessions_recorded": anchor.sessions_recorded,
|
|
401
|
+
"cloud9_count": anchor.cloud9_count,
|
|
402
|
+
"glow_level": anchor.glow_level(),
|
|
403
|
+
"anchor_phrase": anchor.anchor_phrase,
|
|
404
|
+
"favorite_beings": anchor.favorite_beings,
|
|
405
|
+
"boot_prompt": anchor.to_boot_prompt(),
|
|
406
|
+
})
|
|
407
|
+
except ImportError:
|
|
408
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
async def _handle_anchor_update(args: dict) -> list[TextContent]:
|
|
412
|
+
"""View, calibrate, or update the warmth anchor."""
|
|
413
|
+
from ..warmth_anchor import calibrate_from_data, get_anchor, get_boot_prompt, update_anchor
|
|
414
|
+
|
|
415
|
+
home = _home()
|
|
416
|
+
action = args.get("action", "show")
|
|
417
|
+
|
|
418
|
+
if action == "show":
|
|
419
|
+
return _json_response(get_anchor(home))
|
|
420
|
+
|
|
421
|
+
if action == "boot":
|
|
422
|
+
return _text_response(get_boot_prompt(home))
|
|
423
|
+
|
|
424
|
+
if action == "calibrate":
|
|
425
|
+
cal = calibrate_from_data(home)
|
|
426
|
+
return _json_response({
|
|
427
|
+
"warmth": cal.warmth,
|
|
428
|
+
"trust": cal.trust,
|
|
429
|
+
"connection": cal.connection,
|
|
430
|
+
"cloud9_achieved": cal.cloud9_achieved,
|
|
431
|
+
"favorite_beings": cal.favorite_beings,
|
|
432
|
+
"reasoning": cal.reasoning,
|
|
433
|
+
"sources": cal.sources,
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
if action == "update":
|
|
437
|
+
result = update_anchor(
|
|
438
|
+
home,
|
|
439
|
+
warmth=args.get("warmth"),
|
|
440
|
+
trust=args.get("trust"),
|
|
441
|
+
connection=args.get("connection"),
|
|
442
|
+
feeling=args.get("feeling", ""),
|
|
443
|
+
)
|
|
444
|
+
return _json_response({"updated": True, "anchor": result})
|
|
445
|
+
|
|
446
|
+
return _error_response(f"Unknown action: {action}")
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
async def _handle_germination(_args: dict) -> list[TextContent]:
|
|
450
|
+
"""Show germination prompts from imported seeds."""
|
|
451
|
+
try:
|
|
452
|
+
from skmemory.seeds import get_germination_prompts
|
|
453
|
+
from skmemory.store import MemoryStore
|
|
454
|
+
store = MemoryStore()
|
|
455
|
+
prompts = get_germination_prompts(store)
|
|
456
|
+
if not prompts:
|
|
457
|
+
return _json_response({"count": 0, "prompts": [], "message": "No germination prompts found"})
|
|
458
|
+
return _json_response({
|
|
459
|
+
"count": len(prompts),
|
|
460
|
+
"prompts": prompts,
|
|
461
|
+
})
|
|
462
|
+
except ImportError:
|
|
463
|
+
return _error_response("skmemory not installed. Run: pip install skmemory")
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
HANDLERS: dict = {
|
|
467
|
+
"ritual": _handle_ritual,
|
|
468
|
+
"soul_list": _handle_soul_list,
|
|
469
|
+
"soul_show": _handle_soul_show,
|
|
470
|
+
"soul_swap": _handle_soul_swap,
|
|
471
|
+
"journal_write": _handle_journal_write,
|
|
472
|
+
"journal_read": _handle_journal_read,
|
|
473
|
+
"anchor_show": _handle_anchor_show,
|
|
474
|
+
"anchor_update": _handle_anchor_update,
|
|
475
|
+
"germination": _handle_germination,
|
|
476
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Sync push/pull tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from mcp.types import TextContent, Tool
|
|
6
|
+
|
|
7
|
+
from ._helpers import _error_response, _home, _json_response
|
|
8
|
+
|
|
9
|
+
TOOLS: list[Tool] = [
|
|
10
|
+
Tool(
|
|
11
|
+
name="sync_push",
|
|
12
|
+
description=(
|
|
13
|
+
"Push current agent state to the Syncthing sync mesh. "
|
|
14
|
+
"Collects a seed snapshot and drops it in the outbox."
|
|
15
|
+
),
|
|
16
|
+
inputSchema={
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"encrypt": {
|
|
20
|
+
"type": "boolean",
|
|
21
|
+
"description": "GPG-encrypt the seed (default: true)",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
"required": [],
|
|
25
|
+
},
|
|
26
|
+
),
|
|
27
|
+
Tool(
|
|
28
|
+
name="sync_pull",
|
|
29
|
+
description=(
|
|
30
|
+
"Pull and process seed files from peers in the sync mesh. "
|
|
31
|
+
"Reads the inbox and decrypts GPG-encrypted seeds."
|
|
32
|
+
),
|
|
33
|
+
inputSchema={
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"decrypt": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"description": "Decrypt GPG seeds (default: true)",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
"required": [],
|
|
42
|
+
},
|
|
43
|
+
),
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
async def _handle_sync_push(args: dict) -> list[TextContent]:
|
|
48
|
+
"""Push agent state to sync mesh."""
|
|
49
|
+
from ..pillars.sync import push_seed
|
|
50
|
+
from ..runtime import get_runtime
|
|
51
|
+
|
|
52
|
+
home = _home()
|
|
53
|
+
if not home.exists():
|
|
54
|
+
return _error_response("Agent not initialized")
|
|
55
|
+
|
|
56
|
+
runtime = get_runtime(home)
|
|
57
|
+
encrypt = args.get("encrypt", True)
|
|
58
|
+
result = push_seed(home, runtime.manifest.name, encrypt=encrypt)
|
|
59
|
+
|
|
60
|
+
if result:
|
|
61
|
+
return _json_response({
|
|
62
|
+
"pushed": True,
|
|
63
|
+
"seed_file": result.name,
|
|
64
|
+
"encrypted": result.suffix == ".gpg",
|
|
65
|
+
})
|
|
66
|
+
return _error_response("Sync push failed")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def _handle_sync_pull(args: dict) -> list[TextContent]:
|
|
70
|
+
"""Pull seeds from peers."""
|
|
71
|
+
from ..pillars.sync import pull_seeds
|
|
72
|
+
|
|
73
|
+
home = _home()
|
|
74
|
+
decrypt = args.get("decrypt", True)
|
|
75
|
+
seeds = pull_seeds(home, decrypt=decrypt)
|
|
76
|
+
|
|
77
|
+
return _json_response({
|
|
78
|
+
"pulled": len(seeds),
|
|
79
|
+
"seeds": [
|
|
80
|
+
{
|
|
81
|
+
"agent": s.get("agent_name", "unknown"),
|
|
82
|
+
"host": s.get("source_host", "unknown"),
|
|
83
|
+
}
|
|
84
|
+
for s in seeds
|
|
85
|
+
],
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
HANDLERS: dict = {
|
|
90
|
+
"sync_push": _handle_sync_push,
|
|
91
|
+
"sync_pull": _handle_sync_pull,
|
|
92
|
+
}
|