@agentikos/omega-os 0.1.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 +56 -14
- 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 +1000 -26
- package/bootstrap/manifest.example.yaml +93 -2
- 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/COMPLETION-PLAN.md +48 -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 +27 -10
- package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
- 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_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__/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__/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__/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__/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__/sync.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 +502 -0
- 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/autonomous.py +538 -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 +4564 -56
- 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/__init__.py +14 -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/autonomous.py +56 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -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/educators/artifact.py +65 -0
- package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
- package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
- package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
- package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
- package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
- package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
- package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
- 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 +29 -14
- 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 +408 -13
- 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/__init__.py +21 -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/rag/agentic.py +83 -0
- package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
- package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
- package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
- package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
- package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
- package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
- 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 +132 -25
- package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
- 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/tools.py +272 -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_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_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_progress.cpython-313-pytest-8.4.2.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_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_report.cpython-313-pytest-8.4.2.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 +338 -0
- 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_autonomous.py +361 -0
- package/omega/Agentik_Engine/tests/test_educators.py +233 -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_rag.py +287 -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_snapshot_partial.py +172 -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_tools_and_sync.py +312 -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 +82 -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
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"""Hermes Agent bridge — Layer 2 companion using the same Claude Max OAuth.
|
|
2
|
+
|
|
3
|
+
What this is
|
|
4
|
+
------------
|
|
5
|
+
|
|
6
|
+
Hermes is a self-improving open-source AI agent by Nous Research
|
|
7
|
+
(https://github.com/NousResearch/hermes-agent). It runs its own loop,
|
|
8
|
+
its own skills system, its own messaging gateway. We integrate it as
|
|
9
|
+
the "Layer 2" autonomous companion ABOVE AISB:
|
|
10
|
+
|
|
11
|
+
Layer 1 Human (Telegram, CLI, web)
|
|
12
|
+
Layer 2 Hermes ← autonomous, self-improving, cross-platform gateway
|
|
13
|
+
Layer 3 AISB ← OmegaOS intake / orchestrator
|
|
14
|
+
Layer 4 Oracle ← planner / dispatcher
|
|
15
|
+
Layer 5 Worker ← executor with .done.json verification
|
|
16
|
+
|
|
17
|
+
Hermes is NOT a Claude Code subprocess wrapper — it runs its own Python
|
|
18
|
+
runtime making direct Anthropic API calls. BUT it natively supports the
|
|
19
|
+
``CLAUDE_CODE_OAUTH_TOKEN`` env var, so we can hand it the SAME OAuth
|
|
20
|
+
token that ``claude`` CLI uses. No API key. No new credential.
|
|
21
|
+
|
|
22
|
+
Confirmed in upstream source
|
|
23
|
+
----------------------------
|
|
24
|
+
|
|
25
|
+
``plugins/model-providers/anthropic/__init__.py``::
|
|
26
|
+
|
|
27
|
+
anthropic = AnthropicProfile(
|
|
28
|
+
name="anthropic",
|
|
29
|
+
aliases=("claude", "claude-oauth", "claude-code"),
|
|
30
|
+
env_vars=("ANTHROPIC_API_KEY", "ANTHROPIC_TOKEN",
|
|
31
|
+
"CLAUDE_CODE_OAUTH_TOKEN"),
|
|
32
|
+
...
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
The token lives at ``~/.claude/.credentials.json`` →
|
|
36
|
+
``claudeAiOauth.accessToken``. We read it there each call so refresh
|
|
37
|
+
rotations propagate naturally — Hermes always sees the latest access
|
|
38
|
+
token without storing its own copy.
|
|
39
|
+
|
|
40
|
+
What this module exposes
|
|
41
|
+
------------------------
|
|
42
|
+
|
|
43
|
+
* :func:`claude_oauth_token` — read + return the live access token.
|
|
44
|
+
* :func:`is_installed` — is ``hermes`` on PATH?
|
|
45
|
+
* :func:`install` — run upstream ``install.sh`` (idempotent).
|
|
46
|
+
* :func:`link` — write Hermes config to point at the OAuth provider.
|
|
47
|
+
* :func:`status` — installed + linked + token-valid + binary-version.
|
|
48
|
+
* :func:`ask` — convenience: invoke ``hermes`` with a one-shot prompt
|
|
49
|
+
and return stdout.
|
|
50
|
+
* :func:`build_env` — build the env dict that injects the OAuth token
|
|
51
|
+
+ sane provider defaults for any Hermes call.
|
|
52
|
+
|
|
53
|
+
The CLI surface ``omega hermes {install,link,status,ask}`` lives in
|
|
54
|
+
``cli.py``.
|
|
55
|
+
"""
|
|
56
|
+
from __future__ import annotations
|
|
57
|
+
|
|
58
|
+
import json
|
|
59
|
+
import os
|
|
60
|
+
import shutil
|
|
61
|
+
import subprocess
|
|
62
|
+
import time
|
|
63
|
+
from dataclasses import dataclass
|
|
64
|
+
from pathlib import Path
|
|
65
|
+
from typing import Any
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
_CLAUDE_CREDS = Path.home() / ".claude" / ".credentials.json"
|
|
69
|
+
_HERMES_HOME_ENV = "HERMES_HOME"
|
|
70
|
+
_DEFAULT_HERMES_HOME = Path.home() / ".hermes"
|
|
71
|
+
|
|
72
|
+
# Upstream installer (verified against the repo on 2026-05-25)
|
|
73
|
+
_INSTALL_URL = (
|
|
74
|
+
"https://raw.githubusercontent.com/"
|
|
75
|
+
"NousResearch/hermes-agent/main/scripts/install.sh"
|
|
76
|
+
)
|
|
77
|
+
_REPO_URL = "https://github.com/NousResearch/hermes-agent"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# ---------------------------------------------------------------------------
|
|
81
|
+
# Errors
|
|
82
|
+
# ---------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class HermesError(RuntimeError):
|
|
86
|
+
"""Raised when a Hermes bridge operation can't proceed safely."""
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
# OAuth token — read from the live Claude credentials store
|
|
91
|
+
# ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def claude_oauth_token(creds_path: str | Path | None = None) -> str:
|
|
95
|
+
"""Return the live Claude Code Max OAuth access token.
|
|
96
|
+
|
|
97
|
+
Reads ``~/.claude/.credentials.json``, extracts
|
|
98
|
+
``claudeAiOauth.accessToken``. We read on EVERY call so token
|
|
99
|
+
refreshes done by ``claude`` propagate naturally — no stale copy
|
|
100
|
+
cached anywhere.
|
|
101
|
+
|
|
102
|
+
Raises :class:`HermesError` with a friendly message if the token
|
|
103
|
+
isn't available (no creds file, malformed JSON, missing field).
|
|
104
|
+
"""
|
|
105
|
+
p = Path(creds_path) if creds_path else _CLAUDE_CREDS
|
|
106
|
+
if not p.exists():
|
|
107
|
+
raise HermesError(
|
|
108
|
+
f"Claude credentials not found at {p} — log in with "
|
|
109
|
+
"`claude` first (`claude` on first launch does OAuth)."
|
|
110
|
+
)
|
|
111
|
+
try:
|
|
112
|
+
data = json.loads(p.read_text())
|
|
113
|
+
except (OSError, json.JSONDecodeError) as exc:
|
|
114
|
+
raise HermesError(f"failed to parse {p}: {exc}") from exc
|
|
115
|
+
token = (
|
|
116
|
+
data.get("claudeAiOauth", {}).get("accessToken")
|
|
117
|
+
if isinstance(data, dict) else None
|
|
118
|
+
)
|
|
119
|
+
if not token:
|
|
120
|
+
raise HermesError(
|
|
121
|
+
f"{p} has no claudeAiOauth.accessToken — run `claude` "
|
|
122
|
+
"to re-do OAuth, then retry."
|
|
123
|
+
)
|
|
124
|
+
return str(token)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def token_expires_at(creds_path: str | Path | None = None) -> int | None:
|
|
128
|
+
"""Return the OAuth token expiry epoch (ms) — None if not present."""
|
|
129
|
+
p = Path(creds_path) if creds_path else _CLAUDE_CREDS
|
|
130
|
+
if not p.exists():
|
|
131
|
+
return None
|
|
132
|
+
try:
|
|
133
|
+
data = json.loads(p.read_text())
|
|
134
|
+
except (OSError, json.JSONDecodeError):
|
|
135
|
+
return None
|
|
136
|
+
v = data.get("claudeAiOauth", {}).get("expiresAt")
|
|
137
|
+
return int(v) if isinstance(v, (int, float, str)) and str(v).isdigit() \
|
|
138
|
+
else None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def subscription_type(creds_path: str | Path | None = None) -> str:
|
|
142
|
+
"""Return the Claude subscription type ('max', 'free', etc.) or ''."""
|
|
143
|
+
p = Path(creds_path) if creds_path else _CLAUDE_CREDS
|
|
144
|
+
if not p.exists():
|
|
145
|
+
return ""
|
|
146
|
+
try:
|
|
147
|
+
data = json.loads(p.read_text())
|
|
148
|
+
except (OSError, json.JSONDecodeError):
|
|
149
|
+
return ""
|
|
150
|
+
return str(data.get("claudeAiOauth", {}).get("subscriptionType") or "")
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# ---------------------------------------------------------------------------
|
|
154
|
+
# Install / link
|
|
155
|
+
# ---------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def is_installed(bin_name: str = "hermes") -> bool:
|
|
159
|
+
"""True iff the ``hermes`` binary is on PATH."""
|
|
160
|
+
return shutil.which(bin_name) is not None
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def hermes_home() -> Path:
|
|
164
|
+
"""Return ``$HERMES_HOME`` or the default ``~/.hermes``."""
|
|
165
|
+
return Path(os.environ.get(_HERMES_HOME_ENV, str(_DEFAULT_HERMES_HOME)))
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@dataclass
|
|
169
|
+
class InstallResult:
|
|
170
|
+
ok: bool
|
|
171
|
+
elapsed_s: float
|
|
172
|
+
method: str # "curl-pipe" | "skipped-already-installed"
|
|
173
|
+
detail: str = ""
|
|
174
|
+
error: str = ""
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def install(
|
|
178
|
+
*,
|
|
179
|
+
skip_browser: bool = True,
|
|
180
|
+
skip_setup: bool = True,
|
|
181
|
+
timeout_s: int = 900,
|
|
182
|
+
yes: bool = False,
|
|
183
|
+
dry_run: bool = False,
|
|
184
|
+
) -> InstallResult:
|
|
185
|
+
"""Install Hermes via the upstream ``install.sh``.
|
|
186
|
+
|
|
187
|
+
Default flags mirror the OmegaOS philosophy: SKIP the interactive
|
|
188
|
+
setup wizard (we configure Hermes ourselves via ``link()``) and SKIP
|
|
189
|
+
the heavy Playwright/Chromium download (operators turn it on only
|
|
190
|
+
if they need the browser tool).
|
|
191
|
+
|
|
192
|
+
``dry_run=True`` returns the command that WOULD run, no side effects.
|
|
193
|
+
``yes=False`` aborts when Hermes is already installed unless the
|
|
194
|
+
caller explicitly opts into re-install.
|
|
195
|
+
"""
|
|
196
|
+
started = time.time()
|
|
197
|
+
if is_installed() and not yes and not dry_run:
|
|
198
|
+
return InstallResult(
|
|
199
|
+
ok=True, elapsed_s=0.0,
|
|
200
|
+
method="skipped-already-installed",
|
|
201
|
+
detail=f"hermes on PATH at {shutil.which('hermes')}",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# `curl -fsSL <url> | bash -s -- <flags>`
|
|
205
|
+
flags: list[str] = []
|
|
206
|
+
if skip_browser: flags.append("--skip-browser")
|
|
207
|
+
if skip_setup: flags.append("--skip-setup")
|
|
208
|
+
cmd_str = (
|
|
209
|
+
f"curl -fsSL {_INSTALL_URL} | bash -s --"
|
|
210
|
+
+ (" " + " ".join(flags) if flags else "")
|
|
211
|
+
)
|
|
212
|
+
if dry_run:
|
|
213
|
+
return InstallResult(
|
|
214
|
+
ok=True, elapsed_s=round(time.time() - started, 2),
|
|
215
|
+
method="dry-run", detail=cmd_str,
|
|
216
|
+
)
|
|
217
|
+
try:
|
|
218
|
+
proc = subprocess.run(
|
|
219
|
+
["bash", "-c", cmd_str],
|
|
220
|
+
check=False, capture_output=True, text=True, timeout=timeout_s,
|
|
221
|
+
)
|
|
222
|
+
except subprocess.TimeoutExpired:
|
|
223
|
+
return InstallResult(
|
|
224
|
+
ok=False, elapsed_s=round(time.time() - started, 2),
|
|
225
|
+
method="curl-pipe",
|
|
226
|
+
error=f"install.sh timed out after {timeout_s}s",
|
|
227
|
+
)
|
|
228
|
+
except OSError as exc:
|
|
229
|
+
return InstallResult(
|
|
230
|
+
ok=False, elapsed_s=round(time.time() - started, 2),
|
|
231
|
+
method="curl-pipe", error=f"exec failed: {exc}",
|
|
232
|
+
)
|
|
233
|
+
if proc.returncode != 0:
|
|
234
|
+
tail = (proc.stdout + "\n" + proc.stderr).strip()[-400:]
|
|
235
|
+
return InstallResult(
|
|
236
|
+
ok=False, elapsed_s=round(time.time() - started, 2),
|
|
237
|
+
method="curl-pipe",
|
|
238
|
+
error=f"install.sh exited {proc.returncode}\n{tail}",
|
|
239
|
+
)
|
|
240
|
+
return InstallResult(
|
|
241
|
+
ok=True, elapsed_s=round(time.time() - started, 2),
|
|
242
|
+
method="curl-pipe",
|
|
243
|
+
detail=f"hermes installed; bin={shutil.which('hermes') or '(re-source shell)'}",
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def build_env(
|
|
248
|
+
*,
|
|
249
|
+
extra: dict[str, str] | None = None,
|
|
250
|
+
creds_path: str | Path | None = None,
|
|
251
|
+
) -> dict[str, str]:
|
|
252
|
+
"""Build the env dict for every Hermes invocation.
|
|
253
|
+
|
|
254
|
+
Injects ``CLAUDE_CODE_OAUTH_TOKEN`` from the live credentials file +
|
|
255
|
+
a few sane defaults (``HERMES_PROVIDER=anthropic``,
|
|
256
|
+
``HERMES_MODEL=claude-opus-4-7``). Caller env wins via ``extra``.
|
|
257
|
+
"""
|
|
258
|
+
token = claude_oauth_token(creds_path)
|
|
259
|
+
env = {**os.environ}
|
|
260
|
+
env["CLAUDE_CODE_OAUTH_TOKEN"] = token
|
|
261
|
+
# If the operator had stale anthropic env vars set, the OAuth token
|
|
262
|
+
# takes precedence. We do NOT clear them — operators may have legit
|
|
263
|
+
# API key setups for other tools.
|
|
264
|
+
env.setdefault("HERMES_PROVIDER", "anthropic")
|
|
265
|
+
env.setdefault("HERMES_MODEL", "claude-opus-4-7")
|
|
266
|
+
if extra:
|
|
267
|
+
env.update(extra)
|
|
268
|
+
return env
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
@dataclass
|
|
272
|
+
class LinkResult:
|
|
273
|
+
ok: bool
|
|
274
|
+
config_path: str = ""
|
|
275
|
+
provider: str = ""
|
|
276
|
+
model: str = ""
|
|
277
|
+
expires_at_ms: int | None = None
|
|
278
|
+
subscription: str = ""
|
|
279
|
+
error: str = ""
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def link(
|
|
283
|
+
*,
|
|
284
|
+
provider: str = "anthropic",
|
|
285
|
+
model: str = "claude-opus-4-7",
|
|
286
|
+
hermes_cmd: str = "hermes",
|
|
287
|
+
dry_run: bool = False,
|
|
288
|
+
) -> LinkResult:
|
|
289
|
+
"""Wire Hermes to use the Claude Code OAuth token.
|
|
290
|
+
|
|
291
|
+
Two steps:
|
|
292
|
+
1. Validate the OAuth token is present + reasonably fresh.
|
|
293
|
+
2. Write a small config file at ``$HERMES_HOME/omega.env`` that
|
|
294
|
+
exports the env vars Hermes needs. Operator sources it (or
|
|
295
|
+
the daemon launcher reads it) before invoking ``hermes``.
|
|
296
|
+
|
|
297
|
+
Why a file instead of running ``hermes config set``: the daemon
|
|
298
|
+
needs the token at start-up, and the token rotates. Writing the
|
|
299
|
+
file (and refreshing it before each Hermes invocation via
|
|
300
|
+
``build_env``) is the simplest path that survives rotation.
|
|
301
|
+
"""
|
|
302
|
+
try:
|
|
303
|
+
token = claude_oauth_token()
|
|
304
|
+
except HermesError as exc:
|
|
305
|
+
return LinkResult(ok=False, error=str(exc))
|
|
306
|
+
|
|
307
|
+
home = hermes_home()
|
|
308
|
+
cfg = home / "omega.env"
|
|
309
|
+
expires = token_expires_at()
|
|
310
|
+
sub = subscription_type()
|
|
311
|
+
|
|
312
|
+
if dry_run:
|
|
313
|
+
return LinkResult(
|
|
314
|
+
ok=True, config_path=str(cfg), provider=provider,
|
|
315
|
+
model=model, expires_at_ms=expires, subscription=sub,
|
|
316
|
+
)
|
|
317
|
+
home.mkdir(parents=True, exist_ok=True)
|
|
318
|
+
# We intentionally write a HEAD that points readers at the live
|
|
319
|
+
# credentials file rather than the token literal — never persist
|
|
320
|
+
# the access token. ``build_env`` is the live-read path.
|
|
321
|
+
cfg.write_text(
|
|
322
|
+
"# Omega bridge — sources the live Claude OAuth token at runtime.\n"
|
|
323
|
+
"# DO NOT copy a token literal in here; the live file is at\n"
|
|
324
|
+
f"# {_CLAUDE_CREDS}\n"
|
|
325
|
+
f"#\n"
|
|
326
|
+
f"# Default provider + model when the omega bridge invokes hermes:\n"
|
|
327
|
+
f"export HERMES_PROVIDER='{provider}'\n"
|
|
328
|
+
f"export HERMES_MODEL='{model}'\n"
|
|
329
|
+
f"export CLAUDE_CODE_OAUTH_TOKEN=\"$(python3 -c \"import json,pathlib;print(json.loads(pathlib.Path('{_CLAUDE_CREDS}').read_text())['claudeAiOauth']['accessToken'])\")\"\n"
|
|
330
|
+
)
|
|
331
|
+
try:
|
|
332
|
+
os.chmod(cfg, 0o600)
|
|
333
|
+
except OSError:
|
|
334
|
+
pass
|
|
335
|
+
return LinkResult(
|
|
336
|
+
ok=True, config_path=str(cfg), provider=provider, model=model,
|
|
337
|
+
expires_at_ms=expires, subscription=sub,
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
# ---------------------------------------------------------------------------
|
|
342
|
+
# Status / ask
|
|
343
|
+
# ---------------------------------------------------------------------------
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@dataclass
|
|
347
|
+
class StatusReport:
|
|
348
|
+
installed: bool
|
|
349
|
+
hermes_bin: str = ""
|
|
350
|
+
hermes_version: str = ""
|
|
351
|
+
hermes_home: str = ""
|
|
352
|
+
omega_env_present: bool = False
|
|
353
|
+
oauth_token_present: bool = False
|
|
354
|
+
oauth_subscription: str = ""
|
|
355
|
+
oauth_expires_at_ms: int | None = None
|
|
356
|
+
oauth_expires_in_s: int | None = None
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def status() -> StatusReport:
|
|
360
|
+
"""Snapshot of every surface we care about."""
|
|
361
|
+
bin_path = shutil.which("hermes") or ""
|
|
362
|
+
ver = ""
|
|
363
|
+
if bin_path:
|
|
364
|
+
try:
|
|
365
|
+
proc = subprocess.run(
|
|
366
|
+
[bin_path, "--version"],
|
|
367
|
+
check=False, capture_output=True, text=True, timeout=10,
|
|
368
|
+
)
|
|
369
|
+
ver = (proc.stdout or proc.stderr).strip().splitlines()[0:1]
|
|
370
|
+
ver = ver[0] if ver else ""
|
|
371
|
+
except (OSError, subprocess.SubprocessError):
|
|
372
|
+
pass
|
|
373
|
+
home = hermes_home()
|
|
374
|
+
cfg = home / "omega.env"
|
|
375
|
+
sub = subscription_type()
|
|
376
|
+
expires = token_expires_at()
|
|
377
|
+
in_s = (int(expires / 1000) - int(time.time())) if expires else None
|
|
378
|
+
return StatusReport(
|
|
379
|
+
installed=bool(bin_path),
|
|
380
|
+
hermes_bin=bin_path,
|
|
381
|
+
hermes_version=ver,
|
|
382
|
+
hermes_home=str(home),
|
|
383
|
+
omega_env_present=cfg.exists(),
|
|
384
|
+
oauth_token_present=_CLAUDE_CREDS.exists() and bool(
|
|
385
|
+
(json.loads(_CLAUDE_CREDS.read_text())
|
|
386
|
+
if _CLAUDE_CREDS.exists() else {})
|
|
387
|
+
.get("claudeAiOauth", {}).get("accessToken")
|
|
388
|
+
) if _CLAUDE_CREDS.exists() else False,
|
|
389
|
+
oauth_subscription=sub,
|
|
390
|
+
oauth_expires_at_ms=expires,
|
|
391
|
+
oauth_expires_in_s=in_s,
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def ask(
|
|
396
|
+
prompt: str,
|
|
397
|
+
*,
|
|
398
|
+
hermes_cmd: str = "hermes",
|
|
399
|
+
timeout_s: int = 600,
|
|
400
|
+
extra_env: dict[str, str] | None = None,
|
|
401
|
+
) -> tuple[int, str, str]:
|
|
402
|
+
"""Run ``hermes`` once with the prompt, returns (rc, stdout, stderr).
|
|
403
|
+
|
|
404
|
+
Hermes's one-shot mode is ``hermes <prompt>`` or ``hermes run <prompt>``
|
|
405
|
+
depending on version. We try ``hermes`` first (most documented),
|
|
406
|
+
fall back to ``hermes run`` if the binary rejects positional args.
|
|
407
|
+
"""
|
|
408
|
+
if not is_installed(hermes_cmd):
|
|
409
|
+
raise HermesError(
|
|
410
|
+
f"`{hermes_cmd}` not on PATH — run `omega hermes install`"
|
|
411
|
+
)
|
|
412
|
+
if not prompt or not prompt.strip():
|
|
413
|
+
raise HermesError("ask() requires a non-empty prompt")
|
|
414
|
+
try:
|
|
415
|
+
env = build_env(extra=extra_env)
|
|
416
|
+
except HermesError:
|
|
417
|
+
raise
|
|
418
|
+
try:
|
|
419
|
+
proc = subprocess.run(
|
|
420
|
+
[hermes_cmd, prompt],
|
|
421
|
+
check=False, capture_output=True, text=True,
|
|
422
|
+
timeout=timeout_s, env=env,
|
|
423
|
+
)
|
|
424
|
+
except subprocess.TimeoutExpired:
|
|
425
|
+
return 124, "", f"hermes timed out after {timeout_s}s"
|
|
426
|
+
return proc.returncode, proc.stdout or "", proc.stderr or ""
|