@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,260 @@
|
|
|
1
|
+
"""Shell completion scripts for ``omega``.
|
|
2
|
+
|
|
3
|
+
Generates bash + zsh + fish completion files from the live argparse tree
|
|
4
|
+
so the file always reflects the current command surface — no hand-edited
|
|
5
|
+
completion list to drift.
|
|
6
|
+
|
|
7
|
+
Files land at:
|
|
8
|
+
|
|
9
|
+
* ``$OMEGA_HOME/Agentik_Tools/completions/omega.bash``
|
|
10
|
+
* ``$OMEGA_HOME/Agentik_Tools/completions/_omega`` (zsh)
|
|
11
|
+
* ``$OMEGA_HOME/Agentik_Tools/completions/omega.fish``
|
|
12
|
+
|
|
13
|
+
The ``omega completions install`` CLI sources / symlinks them into the
|
|
14
|
+
right place per shell. Idempotent.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import os
|
|
20
|
+
import shutil
|
|
21
|
+
from dataclasses import dataclass
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class CommandNode:
|
|
27
|
+
"""One node in the omega command tree."""
|
|
28
|
+
name: str
|
|
29
|
+
help_text: str = ""
|
|
30
|
+
subcommands: list["CommandNode"] = None # type: ignore[assignment]
|
|
31
|
+
|
|
32
|
+
def __post_init__(self) -> None:
|
|
33
|
+
if self.subcommands is None:
|
|
34
|
+
self.subcommands = []
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def extract_tree(parser: argparse.ArgumentParser) -> CommandNode:
|
|
38
|
+
"""Walk an argparse parser and produce a CommandNode tree."""
|
|
39
|
+
root = CommandNode(name="omega", help_text="Omega OS control CLI")
|
|
40
|
+
# The top-level parser has one subparsers action — find it.
|
|
41
|
+
for action in parser._actions: # noqa: SLF001
|
|
42
|
+
if isinstance(action, argparse._SubParsersAction): # noqa: SLF001
|
|
43
|
+
for name, sub_parser in action.choices.items():
|
|
44
|
+
root.subcommands.append(_walk(name, sub_parser))
|
|
45
|
+
break
|
|
46
|
+
return root
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _walk(name: str, parser: argparse.ArgumentParser) -> CommandNode:
|
|
50
|
+
node = CommandNode(name=name, help_text=(parser.description or "").strip())
|
|
51
|
+
for action in parser._actions: # noqa: SLF001
|
|
52
|
+
if isinstance(action, argparse._SubParsersAction): # noqa: SLF001
|
|
53
|
+
for sub_name, sub_parser in action.choices.items():
|
|
54
|
+
node.subcommands.append(_walk(sub_name, sub_parser))
|
|
55
|
+
break
|
|
56
|
+
return node
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# Bash
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def render_bash(root: CommandNode) -> str:
|
|
65
|
+
"""Generate a bash completion script for the command tree."""
|
|
66
|
+
# Build a flat map: "omega" → first-level subs;
|
|
67
|
+
# "omega <sub>" → that sub's children, etc.
|
|
68
|
+
lines: list[str] = [
|
|
69
|
+
"#!/usr/bin/env bash",
|
|
70
|
+
"# omega — bash completion (auto-generated by omega completions)",
|
|
71
|
+
"",
|
|
72
|
+
"_omega_complete() {",
|
|
73
|
+
" local cur prev words cword",
|
|
74
|
+
" _init_completion || return",
|
|
75
|
+
"",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
# We compute completion by walking COMP_WORDS skipping flags.
|
|
79
|
+
lines += [
|
|
80
|
+
' local commands="' + " ".join(s.name for s in root.subcommands) + '"',
|
|
81
|
+
' if [ $cword -eq 1 ]; then',
|
|
82
|
+
' COMPREPLY=( $(compgen -W "$commands" -- "$cur") )',
|
|
83
|
+
' return 0',
|
|
84
|
+
' fi',
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
for sub in root.subcommands:
|
|
88
|
+
if not sub.subcommands:
|
|
89
|
+
continue
|
|
90
|
+
children = " ".join(c.name for c in sub.subcommands)
|
|
91
|
+
lines += [
|
|
92
|
+
f' if [ "${{words[1]}}" = "{sub.name}" ] && [ $cword -eq 2 ]; then',
|
|
93
|
+
f' COMPREPLY=( $(compgen -W "{children}" -- "$cur") )',
|
|
94
|
+
' return 0',
|
|
95
|
+
' fi',
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
lines += [
|
|
99
|
+
' COMPREPLY=( $(compgen -f -- "$cur") )',
|
|
100
|
+
"}",
|
|
101
|
+
"complete -F _omega_complete omega",
|
|
102
|
+
"",
|
|
103
|
+
]
|
|
104
|
+
return "\n".join(lines)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# ---------------------------------------------------------------------------
|
|
108
|
+
# Zsh
|
|
109
|
+
# ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def render_zsh(root: CommandNode) -> str:
|
|
113
|
+
"""Generate a zsh completion script (uses _arguments / _describe)."""
|
|
114
|
+
lines: list[str] = [
|
|
115
|
+
"#compdef omega",
|
|
116
|
+
"# omega — zsh completion (auto-generated by omega completions)",
|
|
117
|
+
"",
|
|
118
|
+
"_omega() {",
|
|
119
|
+
" local context state line",
|
|
120
|
+
" typeset -A opt_args",
|
|
121
|
+
"",
|
|
122
|
+
' _arguments -C \\',
|
|
123
|
+
" '1: :->command' \\",
|
|
124
|
+
" '*::arg:->args'",
|
|
125
|
+
"",
|
|
126
|
+
" case $state in",
|
|
127
|
+
" command)",
|
|
128
|
+
" local -a commands",
|
|
129
|
+
" commands=(",
|
|
130
|
+
]
|
|
131
|
+
for sub in root.subcommands:
|
|
132
|
+
help_one = sub.help_text.split("\n")[0].replace("'", "'\\''")
|
|
133
|
+
lines.append(f" '{sub.name}:{help_one[:60]}'")
|
|
134
|
+
lines += [
|
|
135
|
+
" )",
|
|
136
|
+
" _describe -t commands 'omega command' commands",
|
|
137
|
+
" ;;",
|
|
138
|
+
" args)",
|
|
139
|
+
" case $line[1] in",
|
|
140
|
+
]
|
|
141
|
+
for sub in root.subcommands:
|
|
142
|
+
if not sub.subcommands:
|
|
143
|
+
continue
|
|
144
|
+
lines += [
|
|
145
|
+
f" {sub.name})",
|
|
146
|
+
" local -a subs",
|
|
147
|
+
" subs=(",
|
|
148
|
+
]
|
|
149
|
+
for child in sub.subcommands:
|
|
150
|
+
help_one = child.help_text.split("\n")[0].replace("'", "'\\''")
|
|
151
|
+
lines.append(f" '{child.name}:{help_one[:60]}'")
|
|
152
|
+
lines += [
|
|
153
|
+
" )",
|
|
154
|
+
f" _describe -t subcommands '{sub.name}' subs",
|
|
155
|
+
" ;;",
|
|
156
|
+
]
|
|
157
|
+
lines += [
|
|
158
|
+
" esac",
|
|
159
|
+
" ;;",
|
|
160
|
+
" esac",
|
|
161
|
+
"}",
|
|
162
|
+
"",
|
|
163
|
+
"_omega \"$@\"",
|
|
164
|
+
"",
|
|
165
|
+
]
|
|
166
|
+
return "\n".join(lines)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# ---------------------------------------------------------------------------
|
|
170
|
+
# Fish
|
|
171
|
+
# ---------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def render_fish(root: CommandNode) -> str:
|
|
175
|
+
"""Generate a fish completion script."""
|
|
176
|
+
lines: list[str] = [
|
|
177
|
+
"# omega — fish completion (auto-generated by omega completions)",
|
|
178
|
+
"",
|
|
179
|
+
]
|
|
180
|
+
for sub in root.subcommands:
|
|
181
|
+
desc = sub.help_text.split("\n")[0].replace("'", "\\'")[:60]
|
|
182
|
+
lines.append(
|
|
183
|
+
f"complete -c omega -n '__fish_use_subcommand' -a '{sub.name}' "
|
|
184
|
+
f"-d '{desc}'"
|
|
185
|
+
)
|
|
186
|
+
for sub in root.subcommands:
|
|
187
|
+
if not sub.subcommands:
|
|
188
|
+
continue
|
|
189
|
+
for child in sub.subcommands:
|
|
190
|
+
desc = child.help_text.split("\n")[0].replace("'", "\\'")[:60]
|
|
191
|
+
lines.append(
|
|
192
|
+
f"complete -c omega -n '__fish_seen_subcommand_from "
|
|
193
|
+
f"{sub.name}' -a '{child.name}' -d '{desc}'"
|
|
194
|
+
)
|
|
195
|
+
lines.append("")
|
|
196
|
+
return "\n".join(lines)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
# ---------------------------------------------------------------------------
|
|
200
|
+
# Install
|
|
201
|
+
# ---------------------------------------------------------------------------
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def write_all(omega_home: str | Path, root: CommandNode) -> dict[str, Path]:
|
|
205
|
+
"""Write all three completion files. Returns paths."""
|
|
206
|
+
out = Path(omega_home) / "Agentik_Tools" / "completions"
|
|
207
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
208
|
+
bash = out / "omega.bash"
|
|
209
|
+
zsh = out / "_omega"
|
|
210
|
+
fish = out / "omega.fish"
|
|
211
|
+
bash.write_text(render_bash(root))
|
|
212
|
+
zsh.write_text(render_zsh(root))
|
|
213
|
+
fish.write_text(render_fish(root))
|
|
214
|
+
return {"bash": bash, "zsh": zsh, "fish": fish}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def install_for_shell(
|
|
218
|
+
omega_home: str | Path, shell: str,
|
|
219
|
+
) -> dict[str, str]:
|
|
220
|
+
"""Hook the completion into the operator's shell.
|
|
221
|
+
|
|
222
|
+
For each shell we know the conventional install location:
|
|
223
|
+
|
|
224
|
+
bash → ``~/.bash_completion.d/omega`` (if it exists) or sourced
|
|
225
|
+
from ``~/.bashrc``
|
|
226
|
+
zsh → ``~/.zsh/completion/_omega`` (fpath addition in ``~/.zshrc``)
|
|
227
|
+
fish → ``~/.config/fish/completions/omega.fish``
|
|
228
|
+
|
|
229
|
+
We never overwrite an existing operator file; we symlink. Returns a
|
|
230
|
+
summary dict.
|
|
231
|
+
"""
|
|
232
|
+
home = Path(omega_home)
|
|
233
|
+
completions = home / "Agentik_Tools" / "completions"
|
|
234
|
+
if not completions.is_dir():
|
|
235
|
+
return {"status": "error",
|
|
236
|
+
"detail": f"{completions} does not exist — "
|
|
237
|
+
"run `omega completions write` first"}
|
|
238
|
+
shell = shell.lower()
|
|
239
|
+
if shell == "bash":
|
|
240
|
+
target_dir = Path.home() / ".bash_completion.d"
|
|
241
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
242
|
+
link = target_dir / "omega"
|
|
243
|
+
src = completions / "omega.bash"
|
|
244
|
+
elif shell == "zsh":
|
|
245
|
+
target_dir = Path.home() / ".zsh" / "completion"
|
|
246
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
247
|
+
link = target_dir / "_omega"
|
|
248
|
+
src = completions / "_omega"
|
|
249
|
+
elif shell == "fish":
|
|
250
|
+
target_dir = Path.home() / ".config" / "fish" / "completions"
|
|
251
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
252
|
+
link = target_dir / "omega.fish"
|
|
253
|
+
src = completions / "omega.fish"
|
|
254
|
+
else:
|
|
255
|
+
return {"status": "error", "detail": f"unknown shell: {shell}"}
|
|
256
|
+
|
|
257
|
+
if link.is_symlink() or link.exists():
|
|
258
|
+
link.unlink()
|
|
259
|
+
link.symlink_to(src)
|
|
260
|
+
return {"status": "ok", "link": str(link), "src": str(src), "shell": shell}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Provider cost rate cards — turn token usage into $.
|
|
2
|
+
|
|
3
|
+
The ``BillingAggregator`` already aggregates input/output tokens per
|
|
4
|
+
account from the event log. This module multiplies by a per-provider
|
|
5
|
+
rate card and surfaces $ in the CLI.
|
|
6
|
+
|
|
7
|
+
Rate cards are kept in code (not a YAML the operator edits) because:
|
|
8
|
+
|
|
9
|
+
1. Anthropic / OpenAI / Zhipu publish public list prices.
|
|
10
|
+
2. An out-of-date rate card → wrong projections, but the underlying
|
|
11
|
+
usage numbers are unaffected. The risk is only in the dashboard,
|
|
12
|
+
not in any state we depend on.
|
|
13
|
+
3. We document the rate card date so the operator knows when it was
|
|
14
|
+
last refreshed.
|
|
15
|
+
|
|
16
|
+
Updating the rate card is a one-line edit when a provider changes prices.
|
|
17
|
+
The doctor surfaces "rate card from <date>; check if your provider has
|
|
18
|
+
changed prices since" so it's never silent.
|
|
19
|
+
|
|
20
|
+
NOTE: Rates here are USD per million tokens, current at the date below.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
from dataclasses import dataclass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
RATE_CARD_DATE = "2026-05-23"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class Rates:
|
|
32
|
+
"""USD per MILLION tokens, input and output."""
|
|
33
|
+
input_per_million: float
|
|
34
|
+
output_per_million: float
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Most-common models per provider. The model field on the event payload
|
|
38
|
+
# determines which row we use; fall back to a sensible default per provider.
|
|
39
|
+
_RATES: dict[str, dict[str, Rates]] = {
|
|
40
|
+
"claude": {
|
|
41
|
+
"claude-opus-4-7": Rates(input_per_million=15.00, output_per_million=75.00),
|
|
42
|
+
"claude-sonnet-4-6": Rates(input_per_million= 3.00, output_per_million=15.00),
|
|
43
|
+
"claude-haiku-4-5": Rates(input_per_million= 0.25, output_per_million= 1.25),
|
|
44
|
+
# fallback
|
|
45
|
+
"default": Rates(input_per_million= 3.00, output_per_million=15.00),
|
|
46
|
+
},
|
|
47
|
+
"openai": {
|
|
48
|
+
"gpt-4o": Rates(input_per_million= 2.50, output_per_million=10.00),
|
|
49
|
+
"gpt-4o-mini": Rates(input_per_million= 0.15, output_per_million= 0.60),
|
|
50
|
+
"default": Rates(input_per_million= 2.50, output_per_million=10.00),
|
|
51
|
+
},
|
|
52
|
+
"glm": {
|
|
53
|
+
"glm-4-plus": Rates(input_per_million= 5.00, output_per_million=15.00),
|
|
54
|
+
"glm-4-flash": Rates(input_per_million= 0.00, output_per_million= 0.00),
|
|
55
|
+
"default": Rates(input_per_million= 1.00, output_per_million= 2.00),
|
|
56
|
+
},
|
|
57
|
+
"deepseek": {
|
|
58
|
+
"deepseek-chat": Rates(input_per_million=0.14, output_per_million=0.28),
|
|
59
|
+
"deepseek-reasoner": Rates(input_per_million=0.55, output_per_million=2.19),
|
|
60
|
+
"default": Rates(input_per_million=0.14, output_per_million=0.28),
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def estimate_cost(
|
|
66
|
+
provider: str,
|
|
67
|
+
*,
|
|
68
|
+
input_tokens: int,
|
|
69
|
+
output_tokens: int,
|
|
70
|
+
model: str = "default",
|
|
71
|
+
) -> float:
|
|
72
|
+
"""Return cost in USD for the given usage."""
|
|
73
|
+
table = _RATES.get(provider.lower())
|
|
74
|
+
if not table:
|
|
75
|
+
return 0.0
|
|
76
|
+
rates = table.get(model) or table["default"]
|
|
77
|
+
return (
|
|
78
|
+
(input_tokens / 1_000_000) * rates.input_per_million
|
|
79
|
+
+ (output_tokens / 1_000_000) * rates.output_per_million
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def project_account_cost(
|
|
84
|
+
provider: str, account_totals: dict, model: str = "default",
|
|
85
|
+
) -> float:
|
|
86
|
+
"""Take a BillingAggregator row + a provider hint, return $."""
|
|
87
|
+
return estimate_cost(
|
|
88
|
+
provider,
|
|
89
|
+
input_tokens=int(account_totals.get("input_tokens", 0)),
|
|
90
|
+
output_tokens=int(account_totals.get("output_tokens", 0)),
|
|
91
|
+
model=model,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def rate_card_summary() -> dict:
|
|
96
|
+
"""For the doctor: the date + which providers we cover."""
|
|
97
|
+
return {
|
|
98
|
+
"date": RATE_CARD_DATE,
|
|
99
|
+
"providers": sorted(_RATES.keys()),
|
|
100
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""24/7 service layer for Omega OS.
|
|
2
|
+
|
|
3
|
+
Three long-running daemons backed by systemd user units:
|
|
4
|
+
|
|
5
|
+
* :mod:`omega_engine.daemons.engine` — the event-store keeper + heartbeat
|
|
6
|
+
* :mod:`omega_engine.daemons.telegram` — long-polls Telegram, routes inbound
|
|
7
|
+
messages to either the autonomous supervisor or :func:`run_mission`
|
|
8
|
+
* :mod:`omega_engine.daemons.autonomous` — runs the autonomous-agent
|
|
9
|
+
supervisor
|
|
10
|
+
|
|
11
|
+
Each daemon exposes a ``main()`` entry point invoked by ``omega daemon <name>``.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__all__ = ["engine", "telegram", "autonomous"]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""The autonomous-agent daemon.
|
|
2
|
+
|
|
3
|
+
Loads every charter under
|
|
4
|
+
``$OMEGA_HOME/Agentik_Orchestration/autonomous/``, builds an
|
|
5
|
+
:class:`omega_engine.autonomous.AutonomousSupervisor`, and runs it until
|
|
6
|
+
SIGTERM/SIGINT.
|
|
7
|
+
|
|
8
|
+
This daemon owns the cron + event triggers. Channel triggers are routed in
|
|
9
|
+
from the Telegram daemon; webhook triggers are awakened by whatever HTTP shim
|
|
10
|
+
your operator put in front (the supervisor exposes ``wake_webhook`` for them).
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
from omega_engine.autonomous import build_supervisor_from_home
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("omega.daemon.autonomous")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def main() -> int:
|
|
23
|
+
logging.basicConfig(
|
|
24
|
+
level=os.environ.get("OMEGA_LOG_LEVEL", "INFO"),
|
|
25
|
+
format="%(asctime)s %(name)s %(levelname)s %(message)s",
|
|
26
|
+
)
|
|
27
|
+
# Optional outbound Telegram bridge — used by the supervisor to deliver
|
|
28
|
+
# progress + reports for missions it spawns. Best-effort: missing vault
|
|
29
|
+
# token means "no Telegram", not "abort".
|
|
30
|
+
telegram = None
|
|
31
|
+
try:
|
|
32
|
+
from omega_engine.telegram import TelegramBridge
|
|
33
|
+
telegram = TelegramBridge.from_vault()
|
|
34
|
+
except Exception as exc: # noqa: BLE001
|
|
35
|
+
logger.warning("autonomous daemon: no outbound Telegram (%s)", exc)
|
|
36
|
+
|
|
37
|
+
supervisor = build_supervisor_from_home(telegram=telegram)
|
|
38
|
+
charters = supervisor.charters()
|
|
39
|
+
if not charters:
|
|
40
|
+
logger.warning(
|
|
41
|
+
"autonomous daemon: no charters found — idling. Drop a YAML in "
|
|
42
|
+
"Agentik_Orchestration/autonomous/ and restart."
|
|
43
|
+
)
|
|
44
|
+
else:
|
|
45
|
+
for c in charters:
|
|
46
|
+
logger.info("autonomous: loaded charter %s (%s, trigger=%s)",
|
|
47
|
+
c.id, c.role, c.trigger_type)
|
|
48
|
+
|
|
49
|
+
# blocks until SIGTERM / SIGINT (the supervisor wires both)
|
|
50
|
+
supervisor.run()
|
|
51
|
+
logger.info("autonomous daemon stopped")
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__": # pragma: no cover
|
|
56
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""The engine daemon — keeps the event store alive 24/7.
|
|
2
|
+
|
|
3
|
+
What it actually does:
|
|
4
|
+
|
|
5
|
+
* opens ``$OMEGA_HOME/Agentik_Runtime/eventlog/omega.db`` (WAL-mode SQLite)
|
|
6
|
+
* periodically appends a ``system.heartbeat`` event so the store always has a
|
|
7
|
+
fresh "this engine is alive" anchor
|
|
8
|
+
* exposes a small stdlib HTTP API on ``127.0.0.1:OMEGA_ENGINE_PORT`` so the
|
|
9
|
+
other daemons (telegram, autonomous) can ask the engine to run a mission
|
|
10
|
+
inside *one* process tree (avoids each daemon spinning its own duplicate
|
|
11
|
+
executor stack)
|
|
12
|
+
* exits cleanly on SIGTERM / SIGINT (systemd `Restart=always` handles the rest)
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import logging
|
|
18
|
+
import os
|
|
19
|
+
import signal
|
|
20
|
+
import threading
|
|
21
|
+
import time
|
|
22
|
+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
from omega_engine.bus import EventBus
|
|
26
|
+
from omega_engine.events import Event, EventType
|
|
27
|
+
from omega_engine.store import SQLiteStore
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger("omega.daemon.engine")
|
|
30
|
+
|
|
31
|
+
# the heartbeat event lives outside the task FSM, so we reuse the HEARTBEAT
|
|
32
|
+
# event type but with a system-level task id.
|
|
33
|
+
_SYSTEM_TASK_ID = "system.engine"
|
|
34
|
+
_HEARTBEAT_PERIOD_S = 60.0
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _omega_home() -> Path:
|
|
38
|
+
return Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _store_path(home: Path) -> Path:
|
|
42
|
+
return home / "Agentik_Runtime" / "eventlog" / "omega.db"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
+
# HTTP API — local-only mission dispatch
|
|
47
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
class _EngineHandler(BaseHTTPRequestHandler):
|
|
50
|
+
"""A tiny REST-ish surface. JSON in/out. Loopback only.
|
|
51
|
+
|
|
52
|
+
Endpoints:
|
|
53
|
+
|
|
54
|
+
* ``GET /health`` -- liveness
|
|
55
|
+
* ``POST /mission`` -- body: ``{"intent": "..."}``; runs a mission
|
|
56
|
+
synchronously and returns the result. Used
|
|
57
|
+
by the telegram daemon for project-bound
|
|
58
|
+
topics.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
# silence stock access log → use our logger
|
|
62
|
+
def log_message(self, fmt: str, *args) -> None: # noqa: A003
|
|
63
|
+
logger.debug("http: " + fmt, *args)
|
|
64
|
+
|
|
65
|
+
def _reply(self, status: int, payload: dict) -> None:
|
|
66
|
+
body = json.dumps(payload).encode()
|
|
67
|
+
self.send_response(status)
|
|
68
|
+
self.send_header("Content-Type", "application/json")
|
|
69
|
+
self.send_header("Content-Length", str(len(body)))
|
|
70
|
+
self.end_headers()
|
|
71
|
+
self.wfile.write(body)
|
|
72
|
+
|
|
73
|
+
def do_GET(self) -> None: # noqa: N802 — required by BaseHTTPRequestHandler
|
|
74
|
+
if self.path == "/health":
|
|
75
|
+
self._reply(200, {"ok": True, "ts": time.time()})
|
|
76
|
+
return
|
|
77
|
+
self._reply(404, {"error": "not found"})
|
|
78
|
+
|
|
79
|
+
def do_POST(self) -> None: # noqa: N802
|
|
80
|
+
# /webhook/<id> — inbound HMAC-signed webhooks (GitHub/Linear/generic)
|
|
81
|
+
if self.path.startswith("/webhook/"):
|
|
82
|
+
return self._handle_webhook()
|
|
83
|
+
if self.path != "/mission":
|
|
84
|
+
self._reply(404, {"error": "not found"})
|
|
85
|
+
return
|
|
86
|
+
length = int(self.headers.get("Content-Length", "0"))
|
|
87
|
+
raw = self.rfile.read(length).decode() if length else "{}"
|
|
88
|
+
try:
|
|
89
|
+
body = json.loads(raw) if raw else {}
|
|
90
|
+
except json.JSONDecodeError:
|
|
91
|
+
self._reply(400, {"error": "invalid json"})
|
|
92
|
+
return
|
|
93
|
+
intent = body.get("intent")
|
|
94
|
+
topic_id = body.get("topic_id")
|
|
95
|
+
if not intent:
|
|
96
|
+
self._reply(400, {"error": "missing intent"})
|
|
97
|
+
return
|
|
98
|
+
try:
|
|
99
|
+
from omega_engine.mission import run_mission
|
|
100
|
+
outcome = run_mission(
|
|
101
|
+
intent=intent,
|
|
102
|
+
topic_id=topic_id,
|
|
103
|
+
telegram=None, # the telegram daemon supplies its own bridge
|
|
104
|
+
)
|
|
105
|
+
self._reply(200, {
|
|
106
|
+
"mission_id": outcome.result.mission_id,
|
|
107
|
+
"verified": outcome.result.verified,
|
|
108
|
+
"final_state": outcome.result.final_state.value,
|
|
109
|
+
"progress_pct": outcome.progress_pct,
|
|
110
|
+
"report_pdf": (
|
|
111
|
+
str(outcome.report_pdf) if outcome.report_pdf else None
|
|
112
|
+
),
|
|
113
|
+
})
|
|
114
|
+
except Exception as exc: # noqa: BLE001
|
|
115
|
+
logger.exception("engine HTTP: mission failed")
|
|
116
|
+
self._reply(500, {"error": str(exc)})
|
|
117
|
+
|
|
118
|
+
def _handle_webhook(self) -> None:
|
|
119
|
+
"""Inbound webhook gate: verify signature → wake supervisor charters."""
|
|
120
|
+
from omega_engine.webhooks import handle_webhook
|
|
121
|
+
length = int(self.headers.get("Content-Length", "0"))
|
|
122
|
+
body = self.rfile.read(length) if length else b""
|
|
123
|
+
# Collect headers as a plain dict for the gate.
|
|
124
|
+
headers = {k: v for k, v in self.headers.items()}
|
|
125
|
+
# The engine daemon's supervisor is built in main() and exposed
|
|
126
|
+
# via the handler class attribute (set just before serving).
|
|
127
|
+
supervisor = getattr(self.server, "supervisor", None)
|
|
128
|
+
try:
|
|
129
|
+
result = handle_webhook(
|
|
130
|
+
_omega_home(), path=self.path,
|
|
131
|
+
headers=headers, body=body, supervisor=supervisor,
|
|
132
|
+
)
|
|
133
|
+
except Exception as exc: # noqa: BLE001
|
|
134
|
+
logger.exception("engine HTTP: webhook failed")
|
|
135
|
+
self._reply(500, {"ok": False, "error": str(exc)})
|
|
136
|
+
return
|
|
137
|
+
self._reply(result["status"], {
|
|
138
|
+
"ok": result["ok"],
|
|
139
|
+
"reason": result.get("reason", ""),
|
|
140
|
+
"fired": result.get("fired", []),
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _serve_http(
|
|
145
|
+
port: int, stop: threading.Event, supervisor=None,
|
|
146
|
+
) -> None:
|
|
147
|
+
"""Run the HTTP API until ``stop`` is set.
|
|
148
|
+
|
|
149
|
+
The ``supervisor`` is exposed as a server attribute so the
|
|
150
|
+
``/webhook/<id>`` handler can fire charters on a verified inbound.
|
|
151
|
+
"""
|
|
152
|
+
httpd = ThreadingHTTPServer(("127.0.0.1", port), _EngineHandler)
|
|
153
|
+
httpd.timeout = 1.0
|
|
154
|
+
# Stash on the server so the handler can find it via self.server.
|
|
155
|
+
httpd.supervisor = supervisor # type: ignore[attr-defined]
|
|
156
|
+
logger.info("engine HTTP API on 127.0.0.1:%d (webhooks: %s)",
|
|
157
|
+
port, "wired" if supervisor else "disabled")
|
|
158
|
+
while not stop.is_set():
|
|
159
|
+
httpd.handle_request()
|
|
160
|
+
httpd.server_close()
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
164
|
+
# Main loop
|
|
165
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
166
|
+
|
|
167
|
+
def main() -> int:
|
|
168
|
+
logging.basicConfig(
|
|
169
|
+
level=os.environ.get("OMEGA_LOG_LEVEL", "INFO"),
|
|
170
|
+
format="%(asctime)s %(name)s %(levelname)s %(message)s",
|
|
171
|
+
)
|
|
172
|
+
home = _omega_home()
|
|
173
|
+
db_path = _store_path(home)
|
|
174
|
+
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
175
|
+
|
|
176
|
+
store = SQLiteStore(db_path)
|
|
177
|
+
bus = EventBus(store)
|
|
178
|
+
logger.info("engine daemon online — store=%s", db_path)
|
|
179
|
+
|
|
180
|
+
stop = threading.Event()
|
|
181
|
+
signal.signal(signal.SIGTERM, lambda *_: stop.set())
|
|
182
|
+
signal.signal(signal.SIGINT, lambda *_: stop.set())
|
|
183
|
+
|
|
184
|
+
port = int(os.environ.get("OMEGA_ENGINE_PORT", "8731"))
|
|
185
|
+
# Build the supervisor once at startup so the HTTP server can fire
|
|
186
|
+
# webhook-triggered charters. Best-effort: if no charters are
|
|
187
|
+
# configured, the supervisor is still safe to pass — wake_webhook
|
|
188
|
+
# just returns an empty list.
|
|
189
|
+
supervisor = None
|
|
190
|
+
try:
|
|
191
|
+
from omega_engine.autonomous import build_supervisor_from_home
|
|
192
|
+
supervisor = build_supervisor_from_home(home)
|
|
193
|
+
except Exception: # noqa: BLE001
|
|
194
|
+
logger.warning("engine daemon: supervisor unavailable — webhooks disabled",
|
|
195
|
+
exc_info=True)
|
|
196
|
+
http_thread = threading.Thread(
|
|
197
|
+
target=_serve_http, args=(port, stop, supervisor),
|
|
198
|
+
daemon=True, name="omega-engine-http",
|
|
199
|
+
)
|
|
200
|
+
http_thread.start()
|
|
201
|
+
|
|
202
|
+
# first heartbeat at startup so `omega status` immediately shows the engine
|
|
203
|
+
bus.publish(Event(
|
|
204
|
+
task_id=_SYSTEM_TASK_ID,
|
|
205
|
+
type=EventType.HEARTBEAT,
|
|
206
|
+
payload={"daemon": "engine", "event": "start"},
|
|
207
|
+
))
|
|
208
|
+
|
|
209
|
+
last_beat = time.time()
|
|
210
|
+
try:
|
|
211
|
+
while not stop.is_set():
|
|
212
|
+
now = time.time()
|
|
213
|
+
if now - last_beat >= _HEARTBEAT_PERIOD_S:
|
|
214
|
+
try:
|
|
215
|
+
bus.publish(Event(
|
|
216
|
+
task_id=_SYSTEM_TASK_ID,
|
|
217
|
+
type=EventType.HEARTBEAT,
|
|
218
|
+
payload={"daemon": "engine", "ts": now},
|
|
219
|
+
))
|
|
220
|
+
except Exception: # noqa: BLE001 — never die on a heartbeat
|
|
221
|
+
logger.exception("engine daemon: heartbeat publish failed")
|
|
222
|
+
last_beat = now
|
|
223
|
+
stop.wait(1.0)
|
|
224
|
+
finally:
|
|
225
|
+
bus.publish(Event(
|
|
226
|
+
task_id=_SYSTEM_TASK_ID,
|
|
227
|
+
type=EventType.HEARTBEAT,
|
|
228
|
+
payload={"daemon": "engine", "event": "stop"},
|
|
229
|
+
))
|
|
230
|
+
store.close()
|
|
231
|
+
logger.info("engine daemon stopped")
|
|
232
|
+
return 0
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
if __name__ == "__main__": # pragma: no cover
|
|
236
|
+
raise SystemExit(main())
|