@agentikos/omega-os 0.2.0 → 0.19.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -3
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +790 -21
- package/bootstrap/manifest.example.yaml +87 -1
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +4 -2
- package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +28 -31
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +88 -41
- package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +8 -3
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-INTERCONNECTIONS.md +283 -0
- package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-ORCHESTRATION-PLAYBOOK.md +364 -0
- package/omega/Agentik_SSOT/docs/quality-arsenal/AUDIT-VERIFICATION-CONTRACT.md +272 -0
- package/omega/Agentik_SSOT/docs/quality-arsenal/QUALITY-ARSENAL-PREAMBLE.md +462 -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/audit-orchestrator.md +212 -0
- package/omega/Agentik_SSOT/skills/audit-pilot.md +466 -0
- package/omega/Agentik_SSOT/skills/audit-tracker.md +147 -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/newcmd.md +300 -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/quality-arsenal.md +180 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"""Tests that the installer actually wires v0.19.x features that the engine
|
|
2
|
+
already exposes. Without this guard the engine ships modules nobody calls,
|
|
3
|
+
which is exactly the v0.19.2 bug:
|
|
4
|
+
|
|
5
|
+
* `omega_engine.tmux.install_into_home_tmux_conf(profile="pro")` existed
|
|
6
|
+
but `step_engine` only wrote the "minimal" bundled config and never
|
|
7
|
+
touched ~/.tmux.conf.
|
|
8
|
+
* `omega_engine.hermes_bootstrap.write_brief()` existed but no install
|
|
9
|
+
step called it, so Hermès booted blind.
|
|
10
|
+
* `tmux.spawn_aisb_chat()` existed but install never created the always-on
|
|
11
|
+
session, so a user without Telegram had no entry point.
|
|
12
|
+
|
|
13
|
+
This test reads `bootstrap/lib/steps.sh` and `install.sh` directly — the
|
|
14
|
+
shell files are the source of truth, and `unittest` is cheap enough to keep
|
|
15
|
+
in the suite that already runs on every commit.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import re
|
|
21
|
+
import sys
|
|
22
|
+
import tempfile
|
|
23
|
+
import textwrap
|
|
24
|
+
import unittest
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
HERE = Path(__file__).resolve().parent
|
|
29
|
+
sys.path.insert(0, str(HERE.parent))
|
|
30
|
+
|
|
31
|
+
REPO_ROOT = Path(__file__).resolve().parents[3]
|
|
32
|
+
INSTALL_SH = REPO_ROOT / "install.sh"
|
|
33
|
+
STEPS_SH = REPO_ROOT / "bootstrap" / "lib" / "steps.sh"
|
|
34
|
+
COMMON_SH = REPO_ROOT / "bootstrap" / "lib" / "common.sh"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
# Plan-mode wiring (the STEPS array drives the entire UX)
|
|
39
|
+
# ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class TestInstallerStepList(unittest.TestCase):
|
|
43
|
+
"""The STEPS array in install.sh MUST mention each new step name.
|
|
44
|
+
If the engine ships a new step function but install.sh never registers
|
|
45
|
+
it, the plan-mode display + the run loop both miss it."""
|
|
46
|
+
|
|
47
|
+
REQUIRED_ENTRIES = [
|
|
48
|
+
# name (the human label) → step function name
|
|
49
|
+
("36-tmux-config", "step_tmux_config"),
|
|
50
|
+
("37-hermes-brief", "step_hermes_brief"),
|
|
51
|
+
("59-hermes-session", "step_hermes_session"),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
def setUp(self):
|
|
55
|
+
if not INSTALL_SH.is_file():
|
|
56
|
+
self.skipTest("install.sh not in repo")
|
|
57
|
+
if not STEPS_SH.is_file():
|
|
58
|
+
self.skipTest("bootstrap/lib/steps.sh not in repo")
|
|
59
|
+
self.install_text = INSTALL_SH.read_text()
|
|
60
|
+
self.steps_text = STEPS_SH.read_text()
|
|
61
|
+
|
|
62
|
+
def test_install_sh_registers_each_new_step(self):
|
|
63
|
+
for label, fn in self.REQUIRED_ENTRIES:
|
|
64
|
+
entry = f'"{label}:{fn}"'
|
|
65
|
+
self.assertIn(entry, self.install_text,
|
|
66
|
+
f"install.sh STEPS array missing {entry!r} — "
|
|
67
|
+
f"plan-mode will not show it and run loop will skip it")
|
|
68
|
+
|
|
69
|
+
def test_steps_sh_defines_each_step_function(self):
|
|
70
|
+
for _, fn in self.REQUIRED_ENTRIES:
|
|
71
|
+
pattern = re.compile(rf"^{fn}\(\) \{{", re.MULTILINE)
|
|
72
|
+
self.assertRegex(self.steps_text, pattern,
|
|
73
|
+
f"{fn} is referenced by install.sh but not defined in steps.sh")
|
|
74
|
+
|
|
75
|
+
def test_step_engine_no_longer_inlines_tmux_block(self):
|
|
76
|
+
"""We moved tmux config out of step_engine into step_tmux_config so
|
|
77
|
+
plan-mode shows it as its own line. Guard against accidental
|
|
78
|
+
re-inlining."""
|
|
79
|
+
# Find the body of step_engine
|
|
80
|
+
m = re.search(r"^step_engine\(\) \{(.+?)^\}", self.steps_text,
|
|
81
|
+
re.DOTALL | re.MULTILINE)
|
|
82
|
+
self.assertIsNotNone(m, "step_engine function not found")
|
|
83
|
+
body = m.group(1)
|
|
84
|
+
self.assertNotIn("write_default_config", body,
|
|
85
|
+
"step_engine must NOT call write_default_config directly anymore "
|
|
86
|
+
"— that's step_tmux_config's job")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
# Step semantics — exercise the same Python the heredocs run, against a
|
|
91
|
+
# temp HOME, so we don't touch the live ~/Omega or ~/.tmux.conf.
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class TestStepTmuxConfigBehavior(unittest.TestCase):
|
|
96
|
+
"""step_tmux_config writes the pro bundled config AND wires ~/.tmux.conf
|
|
97
|
+
with backup-on-difference. Re-runs with identical content must be silent
|
|
98
|
+
no-ops (no extra backups)."""
|
|
99
|
+
|
|
100
|
+
def test_pro_profile_lands_and_is_idempotent(self):
|
|
101
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
102
|
+
tmp = Path(tmp)
|
|
103
|
+
fake_home = tmp / "fake-home"
|
|
104
|
+
fake_home.mkdir()
|
|
105
|
+
omega_home = tmp / "Omega"
|
|
106
|
+
omega_home.mkdir()
|
|
107
|
+
|
|
108
|
+
os.environ["OMEGA_HOME"] = str(omega_home)
|
|
109
|
+
os.environ["HOME"] = str(fake_home)
|
|
110
|
+
try:
|
|
111
|
+
from omega_engine.tmux import (
|
|
112
|
+
write_default_config,
|
|
113
|
+
install_into_home_tmux_conf,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# First pass — writes both files.
|
|
117
|
+
bundled = write_default_config(profile="pro")
|
|
118
|
+
bundled_content = Path(bundled).read_text()
|
|
119
|
+
self.assertGreater(len(bundled_content), 1000,
|
|
120
|
+
"pro profile should be substantially larger than minimal")
|
|
121
|
+
# Pro-only sentinels (paste fix + kill log).
|
|
122
|
+
self.assertIn("assume-paste-time", bundled_content,
|
|
123
|
+
"pro profile missing Termius paste-fix sentinel")
|
|
124
|
+
self.assertIn("buffer-limit", bundled_content,
|
|
125
|
+
"pro profile missing tmux buffer-limit sentinel")
|
|
126
|
+
|
|
127
|
+
res1 = install_into_home_tmux_conf(profile="pro", backup=True)
|
|
128
|
+
self.assertEqual(res1["profile"], "pro")
|
|
129
|
+
home_conf = fake_home / ".tmux.conf"
|
|
130
|
+
self.assertEqual(home_conf.read_text(), bundled_content)
|
|
131
|
+
|
|
132
|
+
# Second pass — content matches, the step's heredoc skips the
|
|
133
|
+
# rewrite. We simulate that gate here (the heredoc compares
|
|
134
|
+
# existing vs bundled_content before calling install_into_*).
|
|
135
|
+
existing = home_conf.read_text()
|
|
136
|
+
self.assertEqual(existing, bundled_content,
|
|
137
|
+
"second-pass content drifted — idempotency broken")
|
|
138
|
+
finally:
|
|
139
|
+
os.environ.pop("OMEGA_HOME", None)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class TestStepHermesBriefBehavior(unittest.TestCase):
|
|
143
|
+
"""step_hermes_brief writes ~/.hermes/skills/omega/SKILL.md so Hermès
|
|
144
|
+
knows about OmegaOS at install time. Atomic + idempotent."""
|
|
145
|
+
|
|
146
|
+
def test_brief_lands_and_is_atomic(self):
|
|
147
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
148
|
+
tmp = Path(tmp)
|
|
149
|
+
fake_home = tmp / "fake-home"
|
|
150
|
+
fake_home.mkdir()
|
|
151
|
+
omega_home = tmp / "Omega"
|
|
152
|
+
omega_home.mkdir()
|
|
153
|
+
os.environ["OMEGA_HOME"] = str(omega_home)
|
|
154
|
+
os.environ["HOME"] = str(fake_home)
|
|
155
|
+
try:
|
|
156
|
+
from omega_engine import hermes_bootstrap as HB
|
|
157
|
+
res = HB.write_brief()
|
|
158
|
+
self.assertTrue(res.written)
|
|
159
|
+
brief = Path(res.path)
|
|
160
|
+
self.assertTrue(brief.is_file())
|
|
161
|
+
content = brief.read_text()
|
|
162
|
+
# The brief must teach Hermès the L1-L5 architecture + the
|
|
163
|
+
# no-API-key principle — those are the two non-negotiable
|
|
164
|
+
# seed facts.
|
|
165
|
+
self.assertIn("OmegaOS", content)
|
|
166
|
+
self.assertIn("Hermès", content)
|
|
167
|
+
memlog = HB.memory_log_path()
|
|
168
|
+
# Memory log path is computed (file may not exist yet —
|
|
169
|
+
# observe_outcome creates it lazily).
|
|
170
|
+
self.assertTrue(str(memlog).endswith(
|
|
171
|
+
".hermes/memory/omega_observations.jsonl"))
|
|
172
|
+
finally:
|
|
173
|
+
os.environ.pop("OMEGA_HOME", None)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# ---------------------------------------------------------------------------
|
|
177
|
+
# UX wiring — the post-install card must announce the always-on session.
|
|
178
|
+
# ---------------------------------------------------------------------------
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
# ---------------------------------------------------------------------------
|
|
182
|
+
# State drift — installer must NOT skip new steps after an upgrade.
|
|
183
|
+
# This was the v0.19.x Mac regression: a stale state file from v0.2.0
|
|
184
|
+
# silently skipped every step on a v0.19.x re-run, so the user got "se
|
|
185
|
+
# passe rien" and no new card.
|
|
186
|
+
# ---------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class TestInstallerStateDrift(unittest.TestCase):
|
|
190
|
+
"""state_version_drift / record_state_version must:
|
|
191
|
+
1. Detect a missing version marker as drift (legacy state files).
|
|
192
|
+
2. Detect a recorded version different from $OMEGA_BUNDLED_VERSION.
|
|
193
|
+
3. Treat a matching marker as "no drift" (idempotent re-run is silent)."""
|
|
194
|
+
|
|
195
|
+
def _run(self, *, recorded: str | None, current: str,
|
|
196
|
+
have_state: bool = True) -> int:
|
|
197
|
+
"""Source common.sh, set env, call state_version_drift,
|
|
198
|
+
return its exit code (0 = drift, 1 = no drift).
|
|
199
|
+
|
|
200
|
+
common.sh derives STATE_DIR from OMEGA_HOME at source time, so we
|
|
201
|
+
export OMEGA_HOME (not STATE_DIR) and let common.sh build the
|
|
202
|
+
right path. Sourcing later override of STATE_DIR is then safe.
|
|
203
|
+
"""
|
|
204
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
205
|
+
tmp = Path(tmp)
|
|
206
|
+
omega_home = tmp / "Omega"
|
|
207
|
+
state_dir = omega_home / "Agentik_Extra" / "var"
|
|
208
|
+
state_dir.mkdir(parents=True)
|
|
209
|
+
if have_state:
|
|
210
|
+
(state_dir / ".install-state").write_text("00-preflight\n")
|
|
211
|
+
if recorded is not None:
|
|
212
|
+
(state_dir / ".install-version").write_text(recorded + "\n")
|
|
213
|
+
script = (
|
|
214
|
+
f"set -e\n"
|
|
215
|
+
f"export OMEGA_HOME={omega_home!s}\n"
|
|
216
|
+
f"export OMEGA_BUNDLED_VERSION={current!r}\n"
|
|
217
|
+
f". {COMMON_SH!s}\n"
|
|
218
|
+
f"if state_version_drift; then exit 0; else exit 1; fi\n"
|
|
219
|
+
)
|
|
220
|
+
import subprocess
|
|
221
|
+
rc = subprocess.run(["bash", "-c", script],
|
|
222
|
+
capture_output=True).returncode
|
|
223
|
+
return rc
|
|
224
|
+
|
|
225
|
+
def test_missing_marker_is_drift(self):
|
|
226
|
+
rc = self._run(recorded=None, current="0.19.4")
|
|
227
|
+
self.assertEqual(rc, 0,
|
|
228
|
+
"stale state with no version marker MUST be treated as drift")
|
|
229
|
+
|
|
230
|
+
def test_version_mismatch_is_drift(self):
|
|
231
|
+
rc = self._run(recorded="0.2.0", current="0.19.4")
|
|
232
|
+
self.assertEqual(rc, 0,
|
|
233
|
+
"0.2.0 state under 0.19.4 installer MUST be treated as drift")
|
|
234
|
+
|
|
235
|
+
def test_matching_version_is_no_drift(self):
|
|
236
|
+
rc = self._run(recorded="0.19.4", current="0.19.4")
|
|
237
|
+
self.assertEqual(rc, 1,
|
|
238
|
+
"matching versions MUST be treated as a clean idempotent re-run")
|
|
239
|
+
|
|
240
|
+
def test_record_state_version_writes_marker(self):
|
|
241
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
242
|
+
tmp = Path(tmp)
|
|
243
|
+
omega_home = tmp / "Omega"
|
|
244
|
+
state_dir = omega_home / "Agentik_Extra" / "var"
|
|
245
|
+
script = (
|
|
246
|
+
f"set -e\n"
|
|
247
|
+
f"export OMEGA_HOME={omega_home!s}\n"
|
|
248
|
+
f"export OMEGA_BUNDLED_VERSION='0.19.4'\n"
|
|
249
|
+
f". {COMMON_SH!s}\n"
|
|
250
|
+
f"record_state_version\n"
|
|
251
|
+
)
|
|
252
|
+
import subprocess
|
|
253
|
+
subprocess.run(["bash", "-c", script], check=True,
|
|
254
|
+
capture_output=True)
|
|
255
|
+
marker = state_dir / ".install-version"
|
|
256
|
+
self.assertTrue(marker.exists(),
|
|
257
|
+
".install-version marker must be created")
|
|
258
|
+
self.assertEqual(marker.read_text().strip(), "0.19.4")
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class TestInstallShWiresDriftCheck(unittest.TestCase):
|
|
262
|
+
"""The install.sh entry point MUST source OMEGA_BUNDLED_VERSION and call
|
|
263
|
+
state_version_drift / record_state_version. Without those, the engine-side
|
|
264
|
+
drift detection is dead code."""
|
|
265
|
+
|
|
266
|
+
def test_install_sh_exports_bundled_version(self):
|
|
267
|
+
text = INSTALL_SH.read_text()
|
|
268
|
+
self.assertIn("OMEGA_BUNDLED_VERSION", text,
|
|
269
|
+
"install.sh must read the bundled version for drift detection")
|
|
270
|
+
self.assertIn("state_version_drift", text,
|
|
271
|
+
"install.sh must call state_version_drift before run_step loop")
|
|
272
|
+
self.assertIn("record_state_version", text,
|
|
273
|
+
"install.sh must call record_state_version after path setup")
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
# ---------------------------------------------------------------------------
|
|
277
|
+
# whiptail / newt — the bare `omega` command MUST work on macOS too.
|
|
278
|
+
# ---------------------------------------------------------------------------
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
class TestSystemDepsCoversMenuDep(unittest.TestCase):
|
|
282
|
+
"""`omega` (no args) shows the menu. On Linux apt/dnf, on macOS brew —
|
|
283
|
+
all three branches MUST install the package that provides `whiptail`."""
|
|
284
|
+
|
|
285
|
+
def test_apt_branch_installs_whiptail(self):
|
|
286
|
+
text = STEPS_SH.read_text()
|
|
287
|
+
# apt installs the 'whiptail' package
|
|
288
|
+
self.assertRegex(text, r"apt\)[^;]*whiptail",
|
|
289
|
+
"apt branch must install whiptail")
|
|
290
|
+
|
|
291
|
+
def test_dnf_branch_installs_newt(self):
|
|
292
|
+
text = STEPS_SH.read_text()
|
|
293
|
+
# dnf installs 'newt' which provides /usr/bin/whiptail
|
|
294
|
+
self.assertRegex(text, r"dnf\)[^;]*newt",
|
|
295
|
+
"dnf branch must install newt (provides whiptail)")
|
|
296
|
+
|
|
297
|
+
def test_brew_branch_installs_newt(self):
|
|
298
|
+
text = STEPS_SH.read_text()
|
|
299
|
+
# macOS brew package is 'newt'
|
|
300
|
+
self.assertRegex(text, r"brew\)[^;]*newt",
|
|
301
|
+
"brew branch must install newt (provides whiptail on macOS)")
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# ---------------------------------------------------------------------------
|
|
305
|
+
# Text-mode menu — `omega` must NEVER silently exit when whiptail is missing.
|
|
306
|
+
# ---------------------------------------------------------------------------
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class TestTextMenuFallback(unittest.TestCase):
|
|
310
|
+
"""When whiptail is unavailable, `omega` must print a visible numbered
|
|
311
|
+
list and accept stdin input. Silent exit was the v0.19.x Mac symptom
|
|
312
|
+
("se passe rien")."""
|
|
313
|
+
|
|
314
|
+
def test_text_menu_prints_items_and_quits_cleanly(self):
|
|
315
|
+
import io, contextlib
|
|
316
|
+
from omega_engine import menu as M
|
|
317
|
+
# Force the no-whiptail path by monkeypatching _have.
|
|
318
|
+
orig = M._have
|
|
319
|
+
M._have = lambda b: False if b == "whiptail" else orig(b)
|
|
320
|
+
try:
|
|
321
|
+
# Feed "0\n" so it quits on the first prompt.
|
|
322
|
+
stdin_buf = io.StringIO("0\n")
|
|
323
|
+
stdout_buf = io.StringIO()
|
|
324
|
+
with contextlib.redirect_stdout(stdout_buf):
|
|
325
|
+
from unittest.mock import patch
|
|
326
|
+
with patch("builtins.input", side_effect=["0"]):
|
|
327
|
+
rc = M.run_menu()
|
|
328
|
+
finally:
|
|
329
|
+
M._have = orig
|
|
330
|
+
self.assertEqual(rc, 0)
|
|
331
|
+
out = stdout_buf.getvalue()
|
|
332
|
+
self.assertIn("Omega OS v", out, "header must include version")
|
|
333
|
+
# Each main item label must appear at least once.
|
|
334
|
+
for tag, label in M._MAIN_ITEMS:
|
|
335
|
+
if tag == "quit":
|
|
336
|
+
continue
|
|
337
|
+
self.assertIn(label, out,
|
|
338
|
+
f"text menu missing item: {label!r}")
|
|
339
|
+
|
|
340
|
+
def test_text_menu_unknown_input_does_not_exit(self):
|
|
341
|
+
"""Garbage input loops back, doesn't crash the menu."""
|
|
342
|
+
import io, contextlib
|
|
343
|
+
from omega_engine import menu as M
|
|
344
|
+
orig = M._have
|
|
345
|
+
M._have = lambda b: False if b == "whiptail" else orig(b)
|
|
346
|
+
try:
|
|
347
|
+
from unittest.mock import patch
|
|
348
|
+
with patch("builtins.input", side_effect=["abc", "99", "0"]):
|
|
349
|
+
with contextlib.redirect_stdout(io.StringIO()):
|
|
350
|
+
rc = M.run_menu()
|
|
351
|
+
finally:
|
|
352
|
+
M._have = orig
|
|
353
|
+
self.assertEqual(rc, 0)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# ---------------------------------------------------------------------------
|
|
357
|
+
# Helper functions defined in common.sh — used by install.sh in plan-mode.
|
|
358
|
+
# `prompt_yes_no` was missing in v0.19.1..0.19.4 and aborted the first install
|
|
359
|
+
# on macOS ("command not found"). This guards the regression.
|
|
360
|
+
# ---------------------------------------------------------------------------
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
class TestPromptYesNoDefined(unittest.TestCase):
|
|
364
|
+
"""install.sh's plan-mode gate calls `prompt_yes_no` to confirm the run.
|
|
365
|
+
The helper MUST be defined in common.sh, or the install aborts before
|
|
366
|
+
a single step executes."""
|
|
367
|
+
|
|
368
|
+
def test_prompt_yes_no_is_a_shell_function(self):
|
|
369
|
+
import subprocess
|
|
370
|
+
rc = subprocess.run(
|
|
371
|
+
["bash", "-c", f". {COMMON_SH!s} && type prompt_yes_no"],
|
|
372
|
+
capture_output=True, text=True,
|
|
373
|
+
)
|
|
374
|
+
self.assertEqual(rc.returncode, 0,
|
|
375
|
+
"prompt_yes_no must be defined in common.sh — without it the "
|
|
376
|
+
"plan-mode prompt aborts every interactive install")
|
|
377
|
+
self.assertIn("function", rc.stdout,
|
|
378
|
+
"prompt_yes_no must be a bash function, not an alias")
|
|
379
|
+
|
|
380
|
+
def test_prompt_yes_no_default_yes_accepts_empty_stdin(self):
|
|
381
|
+
"""Just hitting Enter must accept the default."""
|
|
382
|
+
import subprocess
|
|
383
|
+
script = (
|
|
384
|
+
f". {COMMON_SH!s}\n"
|
|
385
|
+
f"prompt_yes_no 'install?' yes && echo YES || echo NO\n"
|
|
386
|
+
)
|
|
387
|
+
rc = subprocess.run(
|
|
388
|
+
["bash", "-c", script],
|
|
389
|
+
input="\n", capture_output=True, text=True,
|
|
390
|
+
)
|
|
391
|
+
self.assertIn("YES", rc.stdout)
|
|
392
|
+
|
|
393
|
+
def test_prompt_yes_no_n_rejects(self):
|
|
394
|
+
"""Typing 'n' returns non-zero so install aborts cleanly."""
|
|
395
|
+
import subprocess
|
|
396
|
+
script = (
|
|
397
|
+
f". {COMMON_SH!s}\n"
|
|
398
|
+
f"prompt_yes_no 'install?' yes && echo YES || echo NO\n"
|
|
399
|
+
)
|
|
400
|
+
rc = subprocess.run(
|
|
401
|
+
["bash", "-c", script],
|
|
402
|
+
input="n\n", capture_output=True, text=True,
|
|
403
|
+
)
|
|
404
|
+
self.assertIn("NO", rc.stdout)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
# ---------------------------------------------------------------------------
|
|
408
|
+
# Banner — the OMEGA ascii art must read OMEGA, not OMEBA.
|
|
409
|
+
# Position 4 (the G) was rendering as a B in some terminals because row 3
|
|
410
|
+
# closed the upper-right with `█▀` (looked like the top loop of B) and the
|
|
411
|
+
# bottom used a flat `████████▀` instead of the canonical arc.
|
|
412
|
+
# ---------------------------------------------------------------------------
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
class TestBannerReadsOmega(unittest.TestCase):
|
|
416
|
+
"""The hand-tuned colossal-font OMEGA banner has specific row signatures
|
|
417
|
+
that distinguish G from B. We assert both signatures directly."""
|
|
418
|
+
|
|
419
|
+
def test_g_row3_does_not_close_upper_right(self):
|
|
420
|
+
text = COMMON_SH.read_text()
|
|
421
|
+
# The fixed G row 3 has just `███` for left side then spaces.
|
|
422
|
+
# The old broken-G row 3 had `███ █▀` closing the upper right.
|
|
423
|
+
# We check the actual line in the banner:
|
|
424
|
+
# 'row 3' in the printf list is the third printf after install_banner.
|
|
425
|
+
# Easiest: assert the broken-G row sentinel does NOT appear in the
|
|
426
|
+
# banner block.
|
|
427
|
+
broken_row3 = '███ █▀ ███ ███'
|
|
428
|
+
# That's the OLD row3 with E+G+A — find the install_banner block.
|
|
429
|
+
import re
|
|
430
|
+
m = re.search(r"install_banner\(\) \{.*?^\}", text, re.S | re.M)
|
|
431
|
+
self.assertIsNotNone(m, "install_banner not found in common.sh")
|
|
432
|
+
block = m.group(0)
|
|
433
|
+
# OLD signature (E and G both close upper-right): three repetitions
|
|
434
|
+
# of `█▀` separated by spaces on the SAME row.
|
|
435
|
+
old_sig = "███ █▀ ███ █▀ ███ ███"
|
|
436
|
+
self.assertNotIn(old_sig, block,
|
|
437
|
+
"banner row 3 still has the old G-as-B signature "
|
|
438
|
+
"(closes upper-right with █▀)")
|
|
439
|
+
|
|
440
|
+
def test_g_has_clean_arc_bottom(self):
|
|
441
|
+
text = COMMON_SH.read_text()
|
|
442
|
+
# Fixed bottom row has ` ▀██████▀ ` for G (arc), not `████████▀`.
|
|
443
|
+
# Search for the BOTTOM row in install_banner.
|
|
444
|
+
import re
|
|
445
|
+
m = re.search(r"install_banner\(\) \{.*?^\}", text, re.S | re.M)
|
|
446
|
+
block = m.group(0)
|
|
447
|
+
# OLD signature on bottom row: `██████████ ████████▀`
|
|
448
|
+
old_bottom = "██████████ ████████▀"
|
|
449
|
+
self.assertNotIn(old_bottom, block,
|
|
450
|
+
"banner bottom row still uses the flat G base — should be arc")
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
# ---------------------------------------------------------------------------
|
|
454
|
+
# Brand colour — Claude-Code orange. The truecolor escape must be exported.
|
|
455
|
+
# ---------------------------------------------------------------------------
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
class TestBrandColourIsOrange(unittest.TestCase):
|
|
459
|
+
def test_c_orange_is_truecolor_d97757(self):
|
|
460
|
+
text = COMMON_SH.read_text()
|
|
461
|
+
self.assertIn("38;2;217;119;87", text,
|
|
462
|
+
"C_ORANGE must be the Claude-Code brand truecolor "
|
|
463
|
+
"(\\033[38;2;217;119;87m)")
|
|
464
|
+
self.assertIn("C_ORANGE=", text)
|
|
465
|
+
|
|
466
|
+
def test_banner_uses_c_orange(self):
|
|
467
|
+
text = COMMON_SH.read_text()
|
|
468
|
+
# Count how many times the banner printf uses C_ORANGE.
|
|
469
|
+
# Banner has 8 rows — each row must use C_ORANGE.
|
|
470
|
+
import re
|
|
471
|
+
m = re.search(r"install_banner\(\) \{.*?^\}", text, re.S | re.M)
|
|
472
|
+
block = m.group(0)
|
|
473
|
+
n = block.count("$C_ORANGE")
|
|
474
|
+
self.assertGreaterEqual(n, 8,
|
|
475
|
+
f"banner should use C_ORANGE on each of 8 rows (got {n})")
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
class TestPostInstallCardMentionsAISBChat(unittest.TestCase):
|
|
479
|
+
"""The 'AISB-chat' tmux session is the conversational entry point when
|
|
480
|
+
Telegram isn't wired. The post-install card MUST tell the operator how
|
|
481
|
+
to attach to it; otherwise they finish the install with no UI."""
|
|
482
|
+
|
|
483
|
+
def test_card_shows_attach_command(self):
|
|
484
|
+
if not COMMON_SH.is_file():
|
|
485
|
+
self.skipTest("common.sh not in repo")
|
|
486
|
+
text = COMMON_SH.read_text()
|
|
487
|
+
self.assertIn("tmux attach -t AISB-chat", text,
|
|
488
|
+
"post_install_card must include the AISB-chat attach line — "
|
|
489
|
+
"otherwise the operator has no way to discover their always-on "
|
|
490
|
+
"Hermès session")
|
|
491
|
+
# Also surface the "every session in tmux" expectation.
|
|
492
|
+
self.assertIn("tmux", text)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
if __name__ == "__main__":
|
|
496
|
+
unittest.main()
|