@agentikos/omega-os 0.2.0 → 0.19.5
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/README.md +33 -3
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +790 -21
- package/bootstrap/manifest.example.yaml +87 -1
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +4 -2
- package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +28 -31
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +88 -41
- package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +8 -3
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
- package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
- package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
- package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
- package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
- package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
- package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -63,42 +63,85 @@ CREATE INDEX IF NOT EXISTS idx_snapshots_task ON snapshots(task_id, ts DESC);
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
class SQLiteStore(EventStore):
|
|
66
|
-
"""Append-only event log on SQLite (WAL). The default store for a VPS.
|
|
66
|
+
"""Append-only event log on SQLite (WAL). The default store for a VPS.
|
|
67
|
+
|
|
68
|
+
Thread-safety
|
|
69
|
+
-------------
|
|
70
|
+
The connection is opened with ``check_same_thread=False`` AND every
|
|
71
|
+
write is serialized through ``self._lock``. Background services
|
|
72
|
+
(AutonomousSupervisor, Telegram bot, webhook daemon) all share one
|
|
73
|
+
store from different threads — without this, the first cross-thread
|
|
74
|
+
call raises ``sqlite3.ProgrammingError`` and the supervisor dies.
|
|
75
|
+
|
|
76
|
+
Bug history: pre-v0.13 the lock was missing and a 5-thread fuzz
|
|
77
|
+
raised 5/5 ProgrammingErrors. Test: tests/test_store_concurrency.py.
|
|
78
|
+
"""
|
|
67
79
|
|
|
68
80
|
def __init__(self, db_path: str | Path):
|
|
81
|
+
import threading
|
|
69
82
|
self.db_path = str(db_path)
|
|
70
83
|
Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
|
|
71
|
-
|
|
84
|
+
# check_same_thread=False: we serialise via self._lock so the
|
|
85
|
+
# connection can be safely shared across threads.
|
|
86
|
+
self._conn = sqlite3.connect(
|
|
87
|
+
self.db_path, isolation_level=None, check_same_thread=False,
|
|
88
|
+
)
|
|
72
89
|
self._conn.row_factory = sqlite3.Row
|
|
73
90
|
self._conn.execute("PRAGMA journal_mode=WAL;")
|
|
74
91
|
self._conn.execute("PRAGMA synchronous=NORMAL;")
|
|
75
92
|
self._conn.executescript(_SCHEMA)
|
|
93
|
+
self._lock = threading.Lock()
|
|
94
|
+
|
|
95
|
+
def close(self) -> None:
|
|
96
|
+
"""Explicitly close the SQLite connection (best-effort)."""
|
|
97
|
+
try:
|
|
98
|
+
with self._lock:
|
|
99
|
+
self._conn.close()
|
|
100
|
+
except (sqlite3.Error, AttributeError):
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
def __del__(self) -> None:
|
|
104
|
+
# Best-effort cleanup — Python may have already torn things down.
|
|
105
|
+
try:
|
|
106
|
+
self.close()
|
|
107
|
+
except Exception: # noqa: BLE001
|
|
108
|
+
pass
|
|
76
109
|
|
|
77
110
|
def append(self, event: Event) -> None:
|
|
78
|
-
self.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
111
|
+
with self._lock:
|
|
112
|
+
self._conn.execute(
|
|
113
|
+
"INSERT INTO events (id, task_id, type, ts, payload) "
|
|
114
|
+
"VALUES (:id, :task_id, :type, :ts, :payload)",
|
|
115
|
+
event.to_row(),
|
|
116
|
+
)
|
|
83
117
|
|
|
84
118
|
def events_for(self, task_id: str) -> list[Event]:
|
|
85
119
|
# ORDER BY rowid = insertion order — the only correct order for a reducer.
|
|
86
120
|
# Ordering by `ts` is unsafe: rapid emits can share a timestamp.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
with self._lock:
|
|
122
|
+
cur = self._conn.execute(
|
|
123
|
+
"SELECT * FROM events WHERE task_id = ? ORDER BY rowid",
|
|
124
|
+
(task_id,),
|
|
125
|
+
)
|
|
126
|
+
rows = cur.fetchall()
|
|
127
|
+
return [Event.from_row(dict(r)) for r in rows]
|
|
91
128
|
|
|
92
129
|
def all_events(self, since_ts: float = 0.0) -> Iterator[Event]:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
130
|
+
# Read all rows under the lock, then yield outside it — long-running
|
|
131
|
+
# consumers must not hold the write lock.
|
|
132
|
+
with self._lock:
|
|
133
|
+
cur = self._conn.execute(
|
|
134
|
+
"SELECT * FROM events WHERE ts >= ? ORDER BY rowid",
|
|
135
|
+
(since_ts,),
|
|
136
|
+
)
|
|
137
|
+
rows = cur.fetchall()
|
|
138
|
+
for r in rows:
|
|
97
139
|
yield Event.from_row(dict(r))
|
|
98
140
|
|
|
99
141
|
def task_ids(self) -> list[str]:
|
|
100
|
-
|
|
101
|
-
|
|
142
|
+
with self._lock:
|
|
143
|
+
cur = self._conn.execute("SELECT DISTINCT task_id FROM events")
|
|
144
|
+
return [r["task_id"] for r in cur.fetchall()]
|
|
102
145
|
|
|
103
146
|
# --- snapshots --------------------------------------------------------
|
|
104
147
|
# Snapshots are an optional optimisation. Correctness depends only on
|
|
@@ -107,11 +150,13 @@ class SQLiteStore(EventStore):
|
|
|
107
150
|
def snapshot(self, task_id: str) -> dict | None:
|
|
108
151
|
"""Capture the current reduced state of a task at the latest event.
|
|
109
152
|
Returns the snapshot row, or None if the task has no events."""
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
153
|
+
with self._lock:
|
|
154
|
+
cur = self._conn.execute(
|
|
155
|
+
"SELECT rowid FROM events WHERE task_id = ? "
|
|
156
|
+
"ORDER BY rowid DESC LIMIT 1",
|
|
157
|
+
(task_id,),
|
|
158
|
+
)
|
|
159
|
+
row = cur.fetchone()
|
|
115
160
|
if not row:
|
|
116
161
|
return None
|
|
117
162
|
last_rowid = row[0]
|
|
@@ -120,22 +165,24 @@ class SQLiteStore(EventStore):
|
|
|
120
165
|
events = self.events_for(task_id)
|
|
121
166
|
state = reduce_task(events)
|
|
122
167
|
ts = events[-1].ts
|
|
123
|
-
self.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
168
|
+
with self._lock:
|
|
169
|
+
self._conn.execute(
|
|
170
|
+
"INSERT OR REPLACE INTO snapshots (task_id, state, ts, "
|
|
171
|
+
"last_event_rowid) VALUES (?, ?, ?, ?)",
|
|
172
|
+
(task_id, state.value, ts, last_rowid),
|
|
173
|
+
)
|
|
128
174
|
return {"task_id": task_id, "state": state, "ts": ts,
|
|
129
175
|
"last_event_rowid": last_rowid}
|
|
130
176
|
|
|
131
177
|
def latest_snapshot(self, task_id: str) -> dict | None:
|
|
132
178
|
"""Latest snapshot for a task, or None."""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
179
|
+
with self._lock:
|
|
180
|
+
cur = self._conn.execute(
|
|
181
|
+
"SELECT state, ts, last_event_rowid FROM snapshots "
|
|
182
|
+
"WHERE task_id = ? ORDER BY ts DESC LIMIT 1",
|
|
183
|
+
(task_id,),
|
|
184
|
+
)
|
|
185
|
+
row = cur.fetchone()
|
|
139
186
|
if not row:
|
|
140
187
|
return None
|
|
141
188
|
from omega_engine.task import TaskState
|
|
@@ -147,11 +194,11 @@ class SQLiteStore(EventStore):
|
|
|
147
194
|
snap = self.latest_snapshot(task_id)
|
|
148
195
|
if not snap:
|
|
149
196
|
return self.events_for(task_id)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
197
|
+
with self._lock:
|
|
198
|
+
cur = self._conn.execute(
|
|
199
|
+
"SELECT * FROM events WHERE task_id = ? AND rowid > ? "
|
|
200
|
+
"ORDER BY rowid",
|
|
201
|
+
(task_id, snap["last_event_rowid"]),
|
|
202
|
+
)
|
|
203
|
+
rows = cur.fetchall()
|
|
204
|
+
return [Event.from_row(dict(r)) for r in rows]
|
|
@@ -97,11 +97,26 @@ class ClaudeCodeAdapter:
|
|
|
97
97
|
out_root: Path,
|
|
98
98
|
layout: str, # "skill" | "command" | "agent"
|
|
99
99
|
) -> list[str]:
|
|
100
|
-
"""Copy `src/*.md` to the native layout.
|
|
100
|
+
"""Copy `src/*.md` AND `src/<name>/SKILL.md` to the native layout.
|
|
101
|
+
|
|
102
|
+
Both shapes are supported in the SSOT:
|
|
103
|
+
1. Flat: ``Agentik_SSOT/skills/pursue.md``
|
|
104
|
+
2. Directory: ``Agentik_SSOT/skills/pursue/SKILL.md`` (+ optional
|
|
105
|
+
supporting files like ``scripts/`` or ``examples/``).
|
|
106
|
+
|
|
107
|
+
Directory-based skills are the Claude Code idiom — supporting files
|
|
108
|
+
sit next to ``SKILL.md`` and the agent can reference them via
|
|
109
|
+
``${CLAUDE_SKILL_DIR}``. We copy the whole directory verbatim so
|
|
110
|
+
those references resolve at the destination.
|
|
111
|
+
|
|
112
|
+
Returns the list of written paths (relative to ``out_root.parent``).
|
|
113
|
+
"""
|
|
101
114
|
if not src.is_dir():
|
|
102
115
|
return []
|
|
103
116
|
out_root = self._ensure(out_root)
|
|
104
117
|
written: list[str] = []
|
|
118
|
+
|
|
119
|
+
# 1. flat: src/<name>.md
|
|
105
120
|
for md in sorted(src.glob("*.md")):
|
|
106
121
|
stem = self._stem(md)
|
|
107
122
|
if layout == "skill":
|
|
@@ -111,6 +126,29 @@ class ClaudeCodeAdapter:
|
|
|
111
126
|
dest = out_root / f"{stem}.md"
|
|
112
127
|
dest.write_text(md.read_text())
|
|
113
128
|
written.append(str(dest.relative_to(out_root.parent)))
|
|
129
|
+
|
|
130
|
+
# 2. directory: src/<name>/SKILL.md (+ supporting files)
|
|
131
|
+
if layout == "skill":
|
|
132
|
+
import shutil as _sh
|
|
133
|
+
for child in sorted(src.iterdir()):
|
|
134
|
+
if not child.is_dir():
|
|
135
|
+
continue
|
|
136
|
+
skill_md = child / "SKILL.md"
|
|
137
|
+
if not skill_md.exists():
|
|
138
|
+
continue
|
|
139
|
+
dest_dir = self._ensure(out_root / child.name)
|
|
140
|
+
# Copy SKILL.md plus any supporting files (scripts/, etc.)
|
|
141
|
+
for item in child.iterdir():
|
|
142
|
+
target = dest_dir / item.name
|
|
143
|
+
if item.is_dir():
|
|
144
|
+
if target.exists():
|
|
145
|
+
_sh.rmtree(target)
|
|
146
|
+
_sh.copytree(item, target)
|
|
147
|
+
else:
|
|
148
|
+
target.write_text(item.read_text())
|
|
149
|
+
written.append(
|
|
150
|
+
str((dest_dir / "SKILL.md").relative_to(out_root.parent))
|
|
151
|
+
)
|
|
114
152
|
return written
|
|
115
153
|
|
|
116
154
|
# ----- MCP config (.mcp.json) ---------------------------------------
|
|
@@ -230,6 +268,97 @@ class ClaudeCodeAdapter:
|
|
|
230
268
|
settings_file.write_text(json.dumps(settings, indent=2) + "\n")
|
|
231
269
|
return hooks_block
|
|
232
270
|
|
|
271
|
+
# ----- bridge to ~/.claude/ (the dir Claude Code actually reads) -----
|
|
272
|
+
#
|
|
273
|
+
# Why this exists
|
|
274
|
+
# ---------------
|
|
275
|
+
# ``project()`` writes the SSOT-derived layout into
|
|
276
|
+
# ``$OMEGA_HOME/Agentik_AI/providers/claude-code/.claude/`` — that tree
|
|
277
|
+
# stays under OmegaOS for portability (vault backup, audit trail, you
|
|
278
|
+
# name it). But the ``claude`` CLI on a real workstation reads skills /
|
|
279
|
+
# commands / agents / .mcp.json from ``~/.claude/`` (user-global) and
|
|
280
|
+
# ``.claude/`` (project-local).
|
|
281
|
+
#
|
|
282
|
+
# Without a bridge, the 24 SSOT skills NEVER become invokable slash
|
|
283
|
+
# commands. ``link_to_user_claude(home)`` is that bridge: for every
|
|
284
|
+
# skill we projected, we create a SYMLINK at
|
|
285
|
+
# ``~/.claude/skills/<id> → $OMEGA_HOME/.../skills/<id>``. This means:
|
|
286
|
+
# - editing the SSOT + re-running ``omega sync`` updates the
|
|
287
|
+
# skill in place (no duplicate copies),
|
|
288
|
+
# - removing the SSOT skill nukes the symlink on the next sync,
|
|
289
|
+
# - the operator's existing ``~/.claude/skills/<other>/`` are
|
|
290
|
+
# untouched (we only manage entries whose targets are inside
|
|
291
|
+
# ``$OMEGA_HOME``).
|
|
292
|
+
|
|
293
|
+
def link_to_user_claude(
|
|
294
|
+
self, omega_home: Path,
|
|
295
|
+
*,
|
|
296
|
+
user_claude: Path | None = None,
|
|
297
|
+
) -> dict[str, Any]:
|
|
298
|
+
"""Bridge the projected tree into ``~/.claude/`` via symlinks.
|
|
299
|
+
|
|
300
|
+
Returns ``{linked_skills, linked_commands, linked_agents,
|
|
301
|
+
removed: [stale_paths]}``. Idempotent.
|
|
302
|
+
"""
|
|
303
|
+
import os as _os
|
|
304
|
+
user = Path(user_claude) if user_claude else Path.home() / ".claude"
|
|
305
|
+
target = self.target_dir(omega_home)
|
|
306
|
+
out: dict[str, Any] = {
|
|
307
|
+
"user_claude": str(user),
|
|
308
|
+
"linked_skills": 0,
|
|
309
|
+
"linked_commands": 0,
|
|
310
|
+
"linked_agents": 0,
|
|
311
|
+
"removed": [],
|
|
312
|
+
}
|
|
313
|
+
# The provider-tree target must exist first (project() was called).
|
|
314
|
+
if not target.is_dir():
|
|
315
|
+
return out
|
|
316
|
+
|
|
317
|
+
for layout in ("skills", "commands", "agents"):
|
|
318
|
+
src_root = target / layout
|
|
319
|
+
if not src_root.is_dir():
|
|
320
|
+
continue
|
|
321
|
+
dest_root = self._ensure(user / layout)
|
|
322
|
+
|
|
323
|
+
# Remove stale symlinks we used to manage. A "managed" symlink
|
|
324
|
+
# points anywhere inside `target`. Real dirs and symlinks owned
|
|
325
|
+
# by the user are NEVER touched.
|
|
326
|
+
for child in list(dest_root.iterdir()):
|
|
327
|
+
if not child.is_symlink():
|
|
328
|
+
continue
|
|
329
|
+
try:
|
|
330
|
+
realpath = child.resolve()
|
|
331
|
+
except OSError:
|
|
332
|
+
continue
|
|
333
|
+
# Only nuke our own — points inside the OmegaOS tree.
|
|
334
|
+
if str(realpath).startswith(str(target)) and not (src_root / child.name).exists():
|
|
335
|
+
try:
|
|
336
|
+
child.unlink()
|
|
337
|
+
out["removed"].append(str(child))
|
|
338
|
+
except OSError:
|
|
339
|
+
pass
|
|
340
|
+
|
|
341
|
+
for src in sorted(src_root.iterdir()):
|
|
342
|
+
if not src.is_dir() and not src.suffix == ".md":
|
|
343
|
+
continue
|
|
344
|
+
dest = dest_root / src.name
|
|
345
|
+
if dest.is_symlink():
|
|
346
|
+
try:
|
|
347
|
+
dest.unlink()
|
|
348
|
+
except OSError:
|
|
349
|
+
pass
|
|
350
|
+
elif dest.exists():
|
|
351
|
+
# Don't clobber the user's hand-written content.
|
|
352
|
+
continue
|
|
353
|
+
try:
|
|
354
|
+
_os.symlink(src, dest)
|
|
355
|
+
out[f"linked_{layout}"] += 1
|
|
356
|
+
except OSError:
|
|
357
|
+
# Some filesystems (Windows WSL crossings) refuse symlinks;
|
|
358
|
+
# in that case the user can re-run with --copy.
|
|
359
|
+
pass
|
|
360
|
+
return out
|
|
361
|
+
|
|
233
362
|
# ----- entry point ---------------------------------------------------
|
|
234
363
|
|
|
235
364
|
def project(self, omega_home: Path) -> dict[str, Any]:
|
|
@@ -243,6 +372,17 @@ class ClaudeCodeAdapter:
|
|
|
243
372
|
mcp = self._project_mcp(omega_home, target)
|
|
244
373
|
hooks = self._project_hooks(omega_home, target)
|
|
245
374
|
|
|
375
|
+
# Bridge to ~/.claude/ so the projected skills actually become
|
|
376
|
+
# invokable slash-commands. Toggleable via env var (off → only the
|
|
377
|
+
# provider tree is written; user opts in later with `omega skill link`).
|
|
378
|
+
link_info: dict[str, Any] = {}
|
|
379
|
+
import os as _os
|
|
380
|
+
if _os.environ.get("OMEGA_SYNC_NO_LINK") != "1":
|
|
381
|
+
try:
|
|
382
|
+
link_info = self.link_to_user_claude(omega_home)
|
|
383
|
+
except OSError:
|
|
384
|
+
link_info = {}
|
|
385
|
+
|
|
246
386
|
return {
|
|
247
387
|
"provider": self.id,
|
|
248
388
|
"projected": True,
|
|
@@ -252,6 +392,7 @@ class ClaudeCodeAdapter:
|
|
|
252
392
|
"agents_written": len(agents),
|
|
253
393
|
"mcp_servers": len(mcp.get("mcpServers", {})) if isinstance(mcp, dict) else 0,
|
|
254
394
|
"hooks": list(hooks.keys()),
|
|
395
|
+
"linked_to_user_claude": link_info,
|
|
255
396
|
}
|
|
256
397
|
|
|
257
398
|
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""Per-topic conversation history — fixes the "bot has no memory" bug.
|
|
2
|
+
|
|
3
|
+
When the user types in a Telegram topic, the Telegram daemon used to call
|
|
4
|
+
``run_mission(intent=text)`` with ONLY the new message. The Oracle saw a
|
|
5
|
+
brand-new mission every turn — no idea what the user was actually talking
|
|
6
|
+
about. The user's reply to a follow-up question landed without context.
|
|
7
|
+
|
|
8
|
+
This module is the fix. It persists every inbound + outbound message per
|
|
9
|
+
topic to a SQLite table; the daemon prepends the last N exchanges to the
|
|
10
|
+
envelope's user message so the agent always has the conversation.
|
|
11
|
+
|
|
12
|
+
Layout
|
|
13
|
+
------
|
|
14
|
+
``$OMEGA_HOME/Agentik_Runtime/telegram-history.db``
|
|
15
|
+
|
|
16
|
+
::
|
|
17
|
+
|
|
18
|
+
CREATE TABLE messages (
|
|
19
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
20
|
+
topic_id INTEGER NOT NULL, -- forum topic id (or 0 for DM root)
|
|
21
|
+
role TEXT NOT NULL, -- 'user' | 'bot'
|
|
22
|
+
text TEXT NOT NULL,
|
|
23
|
+
message_id INTEGER, -- Telegram's own message_id
|
|
24
|
+
timestamp INTEGER NOT NULL
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
Two indexes: one for per-topic recency, one for full-text-ish search.
|
|
28
|
+
|
|
29
|
+
Public API
|
|
30
|
+
----------
|
|
31
|
+
``record_inbound(home, topic_id, text, message_id=None)``
|
|
32
|
+
``record_outbound(home, topic_id, text, message_id=None)``
|
|
33
|
+
``recent_messages(home, topic_id, limit=20) -> list[Message]``
|
|
34
|
+
``build_context_prompt(home, topic_id, new_intent, limit=10) -> str``
|
|
35
|
+
"""
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
import os
|
|
39
|
+
import sqlite3
|
|
40
|
+
import time
|
|
41
|
+
from dataclasses import dataclass, field
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
from typing import Iterable
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class Message:
|
|
48
|
+
id: int
|
|
49
|
+
topic_id: int
|
|
50
|
+
role: str # "user" | "bot"
|
|
51
|
+
text: str
|
|
52
|
+
message_id: int | None
|
|
53
|
+
timestamp: int
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _db_path(omega_home: str | Path) -> Path:
|
|
57
|
+
home = Path(omega_home)
|
|
58
|
+
runtime = home / "Agentik_Runtime"
|
|
59
|
+
runtime.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
return runtime / "telegram-history.db"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _connect(omega_home: str | Path) -> sqlite3.Connection:
|
|
64
|
+
conn = sqlite3.connect(str(_db_path(omega_home)))
|
|
65
|
+
conn.row_factory = sqlite3.Row
|
|
66
|
+
conn.execute("PRAGMA journal_mode=WAL")
|
|
67
|
+
conn.execute("""
|
|
68
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
69
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
70
|
+
topic_id INTEGER NOT NULL,
|
|
71
|
+
role TEXT NOT NULL CHECK(role IN ('user', 'bot')),
|
|
72
|
+
text TEXT NOT NULL,
|
|
73
|
+
message_id INTEGER,
|
|
74
|
+
timestamp INTEGER NOT NULL
|
|
75
|
+
)
|
|
76
|
+
""")
|
|
77
|
+
conn.execute("""
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_messages_topic_time
|
|
79
|
+
ON messages(topic_id, timestamp DESC)
|
|
80
|
+
""")
|
|
81
|
+
return conn
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _record(
|
|
85
|
+
omega_home: str | Path,
|
|
86
|
+
*,
|
|
87
|
+
topic_id: int,
|
|
88
|
+
role: str,
|
|
89
|
+
text: str,
|
|
90
|
+
message_id: int | None,
|
|
91
|
+
) -> int:
|
|
92
|
+
"""Persist one message. Returns the rowid."""
|
|
93
|
+
if role not in ("user", "bot"):
|
|
94
|
+
raise ValueError(f"role must be 'user' or 'bot', got {role!r}")
|
|
95
|
+
conn = _connect(omega_home)
|
|
96
|
+
try:
|
|
97
|
+
cur = conn.execute(
|
|
98
|
+
"INSERT INTO messages (topic_id, role, text, message_id, timestamp) "
|
|
99
|
+
"VALUES (?, ?, ?, ?, ?)",
|
|
100
|
+
(int(topic_id), role, text, message_id, int(time.time())),
|
|
101
|
+
)
|
|
102
|
+
conn.commit()
|
|
103
|
+
return int(cur.lastrowid)
|
|
104
|
+
finally:
|
|
105
|
+
conn.close()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def record_inbound(
|
|
109
|
+
omega_home: str | Path,
|
|
110
|
+
topic_id: int,
|
|
111
|
+
text: str,
|
|
112
|
+
*,
|
|
113
|
+
message_id: int | None = None,
|
|
114
|
+
) -> int:
|
|
115
|
+
"""The user just sent this in the topic. Persist it."""
|
|
116
|
+
return _record(omega_home, topic_id=topic_id, role="user",
|
|
117
|
+
text=text, message_id=message_id)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def record_outbound(
|
|
121
|
+
omega_home: str | Path,
|
|
122
|
+
topic_id: int,
|
|
123
|
+
text: str,
|
|
124
|
+
*,
|
|
125
|
+
message_id: int | None = None,
|
|
126
|
+
) -> int:
|
|
127
|
+
"""The bot just posted this. Persist it so the next turn has context."""
|
|
128
|
+
return _record(omega_home, topic_id=topic_id, role="bot",
|
|
129
|
+
text=text, message_id=message_id)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def recent_messages(
|
|
133
|
+
omega_home: str | Path,
|
|
134
|
+
topic_id: int,
|
|
135
|
+
*,
|
|
136
|
+
limit: int = 20,
|
|
137
|
+
) -> list[Message]:
|
|
138
|
+
"""Return the last ``limit`` messages for this topic, oldest first.
|
|
139
|
+
|
|
140
|
+
The query selects by timestamp DESC then reverses — gives us
|
|
141
|
+
chronological order with a hard cap.
|
|
142
|
+
"""
|
|
143
|
+
conn = _connect(omega_home)
|
|
144
|
+
try:
|
|
145
|
+
rows = conn.execute(
|
|
146
|
+
"SELECT * FROM messages WHERE topic_id = ? "
|
|
147
|
+
"ORDER BY timestamp DESC, id DESC LIMIT ?",
|
|
148
|
+
(int(topic_id), int(limit)),
|
|
149
|
+
).fetchall()
|
|
150
|
+
finally:
|
|
151
|
+
conn.close()
|
|
152
|
+
return [
|
|
153
|
+
Message(
|
|
154
|
+
id=int(r["id"]),
|
|
155
|
+
topic_id=int(r["topic_id"]),
|
|
156
|
+
role=str(r["role"]),
|
|
157
|
+
text=str(r["text"]),
|
|
158
|
+
message_id=(int(r["message_id"])
|
|
159
|
+
if r["message_id"] is not None else None),
|
|
160
|
+
timestamp=int(r["timestamp"]),
|
|
161
|
+
)
|
|
162
|
+
for r in reversed(rows)
|
|
163
|
+
]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def build_context_prompt(
|
|
167
|
+
omega_home: str | Path,
|
|
168
|
+
topic_id: int,
|
|
169
|
+
new_intent: str,
|
|
170
|
+
*,
|
|
171
|
+
limit: int = 10,
|
|
172
|
+
) -> str:
|
|
173
|
+
"""Compose a context-aware intent for ``run_mission``.
|
|
174
|
+
|
|
175
|
+
Format::
|
|
176
|
+
|
|
177
|
+
[Conversation history in topic <id>]
|
|
178
|
+
user (10 min ago): previous message
|
|
179
|
+
bot (8 min ago): previous reply
|
|
180
|
+
user (just now): ${new_intent}
|
|
181
|
+
|
|
182
|
+
Respond to the user's latest message — the messages above are
|
|
183
|
+
the conversation so far in this topic; keep your answer
|
|
184
|
+
consistent with them.
|
|
185
|
+
|
|
186
|
+
If there's no prior history, returns ``new_intent`` unchanged so a
|
|
187
|
+
cold conversation behaves as before.
|
|
188
|
+
"""
|
|
189
|
+
history = recent_messages(omega_home, topic_id, limit=limit)
|
|
190
|
+
if not history:
|
|
191
|
+
return new_intent
|
|
192
|
+
|
|
193
|
+
now = int(time.time())
|
|
194
|
+
lines: list[str] = [
|
|
195
|
+
f"[Conversation history in topic {topic_id}]"
|
|
196
|
+
]
|
|
197
|
+
for msg in history:
|
|
198
|
+
delta = now - msg.timestamp
|
|
199
|
+
when = _humanise_age(delta)
|
|
200
|
+
lines.append(f" {msg.role} ({when}): {msg.text}")
|
|
201
|
+
|
|
202
|
+
lines.append("")
|
|
203
|
+
lines.append(f"user (just now): {new_intent}")
|
|
204
|
+
lines.append("")
|
|
205
|
+
lines.append(
|
|
206
|
+
"Respond to the user's latest message — the messages above are "
|
|
207
|
+
"the conversation so far in this topic; keep your answer "
|
|
208
|
+
"consistent with them."
|
|
209
|
+
)
|
|
210
|
+
return "\n".join(lines)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _humanise_age(seconds: int) -> str:
|
|
214
|
+
"""Format an age in seconds as a short human string."""
|
|
215
|
+
if seconds < 60:
|
|
216
|
+
return f"{seconds}s ago"
|
|
217
|
+
if seconds < 3600:
|
|
218
|
+
return f"{seconds // 60}m ago"
|
|
219
|
+
if seconds < 86400:
|
|
220
|
+
return f"{seconds // 3600}h ago"
|
|
221
|
+
return f"{seconds // 86400}d ago"
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def prune(
|
|
225
|
+
omega_home: str | Path,
|
|
226
|
+
*,
|
|
227
|
+
older_than_days: int = 90,
|
|
228
|
+
) -> int:
|
|
229
|
+
"""Drop messages older than ``older_than_days``. Returns rows removed."""
|
|
230
|
+
cutoff = int(time.time()) - older_than_days * 86400
|
|
231
|
+
conn = _connect(omega_home)
|
|
232
|
+
try:
|
|
233
|
+
cur = conn.execute(
|
|
234
|
+
"DELETE FROM messages WHERE timestamp < ?", (cutoff,)
|
|
235
|
+
)
|
|
236
|
+
conn.commit()
|
|
237
|
+
return int(cur.rowcount)
|
|
238
|
+
finally:
|
|
239
|
+
conn.close()
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def topic_stats(omega_home: str | Path) -> list[dict]:
|
|
243
|
+
"""For the doctor: a one-row-per-topic summary."""
|
|
244
|
+
conn = _connect(omega_home)
|
|
245
|
+
try:
|
|
246
|
+
rows = conn.execute(
|
|
247
|
+
"SELECT topic_id, COUNT(*) AS n_msgs, "
|
|
248
|
+
" MAX(timestamp) AS last_seen "
|
|
249
|
+
"FROM messages GROUP BY topic_id ORDER BY last_seen DESC"
|
|
250
|
+
).fetchall()
|
|
251
|
+
finally:
|
|
252
|
+
conn.close()
|
|
253
|
+
return [
|
|
254
|
+
{
|
|
255
|
+
"topic_id": int(r["topic_id"]),
|
|
256
|
+
"messages": int(r["n_msgs"]),
|
|
257
|
+
"last_seen": int(r["last_seen"]),
|
|
258
|
+
}
|
|
259
|
+
for r in rows
|
|
260
|
+
]
|