@agentikos/omega-os 0.2.0 → 0.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -3
- package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
- package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
- package/bootstrap/lib/claude-code-settings.py +176 -0
- package/bootstrap/lib/common.sh +457 -1
- package/bootstrap/lib/llm-clis.py +341 -0
- package/bootstrap/lib/manifest-helpers.py +384 -0
- package/bootstrap/lib/steps.sh +790 -21
- package/bootstrap/manifest.example.yaml +87 -1
- package/bootstrap/templates/aisb/CLAUDE.md +305 -0
- package/bootstrap/templates/aisb/architect.md +204 -0
- package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
- package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
- package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
- package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
- package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
- package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
- package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
- package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
- package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
- package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
- package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
- package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
- package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
- package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
- package/bootstrap/templates/aisb/construct.md +135 -0
- package/bootstrap/templates/aisb/keymaker.md +227 -0
- package/bootstrap/templates/aisb/link.md +170 -0
- package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
- package/bootstrap/templates/aisb/merovingian.md +159 -0
- package/bootstrap/templates/aisb/morpheus.md +243 -0
- package/bootstrap/templates/aisb/neo.md +147 -0
- package/bootstrap/templates/aisb/niobe.md +197 -0
- package/bootstrap/templates/aisb/oracle.md +244 -0
- package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
- package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
- package/bootstrap/templates/aisb/pythia.md +153 -0
- package/bootstrap/templates/aisb/seraph.md +315 -0
- package/bootstrap/templates/aisb/smith.md +202 -0
- package/bootstrap/templates/aisb/zion.md +172 -0
- package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
- package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
- package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
- package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
- package/docs/AUDITS.md +85 -0
- package/docs/GAP-ANALYSIS.md +214 -0
- package/docs/INSTALL.md +47 -9
- package/docs/MCP-AND-PLUGINS.md +31 -4
- package/docs/SIMULATION.md +171 -0
- package/docs/simulate.sh +211 -0
- package/install.sh +164 -17
- package/omega/Agentik_Engine/README.md +4 -2
- package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
- package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/account.py +28 -31
- package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
- package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
- package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
- package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
- package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
- package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
- package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
- package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
- package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
- package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
- package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
- package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
- package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
- package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
- package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
- package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
- package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
- package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
- package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
- package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
- package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
- package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
- package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
- package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
- package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
- package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
- package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
- package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
- package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
- package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
- package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
- package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
- package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
- package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
- package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
- package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
- package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/router.py +28 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
- package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
- package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
- package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
- package/omega/Agentik_Engine/omega_engine/store.py +88 -41
- package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
- package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
- package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
- package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
- package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
- package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
- package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
- package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
- package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
- package/omega/Agentik_Engine/pyproject.toml +1 -1
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
- package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
- package/omega/Agentik_Engine/tests/test_account.py +8 -3
- package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
- package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
- package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
- package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
- package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
- package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
- package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
- package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
- package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
- package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
- package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
- package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
- package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
- package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
- package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
- package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
- package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
- package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
- package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
- package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
- package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
- package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
- package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
- package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
- package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
- package/omega/Agentik_Engine/tests/test_vault.py +173 -0
- package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
- package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
- package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
- package/omega/Agentik_Runtime/audits.db +0 -0
- package/omega/Agentik_SSOT/VERSION +1 -1
- package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
- package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
- package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
- package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
- package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
- package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
- package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
- package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
- package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
- package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
- package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
- package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
- package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
- package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
- package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
- package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
- package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
- package/package.json +2 -2
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"""Stack picker — the first phase of Genesis.
|
|
2
|
+
|
|
3
|
+
The picker is a deterministic decision tree that turns a project type
|
|
4
|
+
(``web`` / ``mobile`` / ``desktop`` / …) into a concrete :class:`StackConfig`.
|
|
5
|
+
For ambiguous cases (mixed web+mobile, custom backend, exotic UI kit) the
|
|
6
|
+
picker emits a list of :class:`StackQuestion` items that the orchestrator
|
|
7
|
+
forwards to the operator via:
|
|
8
|
+
|
|
9
|
+
* the CLI (interactive prompt, `omega genesis new ...` without --brief)
|
|
10
|
+
* the Claude Code skill (`AskUserQuestion`)
|
|
11
|
+
* the Telegram bot (inline keyboard)
|
|
12
|
+
|
|
13
|
+
Defaults
|
|
14
|
+
--------
|
|
15
|
+
|
|
16
|
+
The OmegaOS canonical stack is::
|
|
17
|
+
|
|
18
|
+
type=web frontend=nextjs backend=convex deploy=vercel
|
|
19
|
+
payments=stripe ui_kit=shadcn auth=clerk
|
|
20
|
+
|
|
21
|
+
It's what we know works end-to-end with the rest of the OS (audits,
|
|
22
|
+
worker briefs, deploy pipeline). Any deviation should be a CONSCIOUS
|
|
23
|
+
choice — the picker surfaces the alternatives explicitly.
|
|
24
|
+
"""
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from dataclasses import dataclass, field
|
|
28
|
+
from typing import Literal
|
|
29
|
+
|
|
30
|
+
from omega_engine.genesis.state import StackConfig
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# Question abstraction
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class StackQuestion:
|
|
40
|
+
"""One operator decision the picker needs to advance.
|
|
41
|
+
|
|
42
|
+
``key`` is the field on StackConfig to set; ``header`` is the short
|
|
43
|
+
label shown in UI (CLI / Telegram); ``options`` are the *allowed*
|
|
44
|
+
answers — the picker rejects anything else.
|
|
45
|
+
|
|
46
|
+
The ``recommended`` value is the default the orchestrator picks when
|
|
47
|
+
the operator skips the question (``--accept-defaults`` flag, or no
|
|
48
|
+
Telegram reply within the patience window).
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
key: str # StackConfig field
|
|
52
|
+
header: str # short label
|
|
53
|
+
question: str # full question text
|
|
54
|
+
options: list[str] # allowed answers
|
|
55
|
+
recommended: str # default if skipped
|
|
56
|
+
why: str = "" # 1-line rationale for the operator
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
# Stack pre-sets (named bundles)
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class Stack:
|
|
66
|
+
"""A named bundle of StackConfig fields + a one-line rationale.
|
|
67
|
+
|
|
68
|
+
The orchestrator stores stacks under this name in ``PROJECT.yaml``
|
|
69
|
+
so future operators can read the deliberate choice ("we picked
|
|
70
|
+
omegaos-canonical because we wanted shadcn + convex + stripe out of
|
|
71
|
+
the box").
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
id: str
|
|
75
|
+
title: str
|
|
76
|
+
config: StackConfig
|
|
77
|
+
why: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def default_stack() -> Stack:
|
|
81
|
+
"""The OmegaOS canonical stack — Next.js + Convex + Vercel + Stripe + shadcn."""
|
|
82
|
+
return Stack(
|
|
83
|
+
id="omegaos-canonical",
|
|
84
|
+
title="OmegaOS canonical (Next.js + Convex + Vercel + Stripe + shadcn + Clerk)",
|
|
85
|
+
config=StackConfig(
|
|
86
|
+
type="web",
|
|
87
|
+
frontend="nextjs",
|
|
88
|
+
backend="convex",
|
|
89
|
+
deploy="vercel",
|
|
90
|
+
payments="stripe",
|
|
91
|
+
ui_kit="shadcn",
|
|
92
|
+
auth="clerk",
|
|
93
|
+
extras=["framer-motion"],
|
|
94
|
+
),
|
|
95
|
+
why="The stack the engine knows end-to-end. Audits, deploy, "
|
|
96
|
+
"/prod pipeline, and the design-discipline skills all assume "
|
|
97
|
+
"this shape.",
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _mobile_native_stack() -> Stack:
|
|
102
|
+
return Stack(
|
|
103
|
+
id="omegaos-mobile-native",
|
|
104
|
+
title="iOS native (SwiftUI + Convex + Stripe Connect)",
|
|
105
|
+
config=StackConfig(
|
|
106
|
+
type="iphone",
|
|
107
|
+
frontend="swiftui",
|
|
108
|
+
backend="convex",
|
|
109
|
+
deploy="none",
|
|
110
|
+
payments="stripe",
|
|
111
|
+
ui_kit="custom",
|
|
112
|
+
auth="clerk",
|
|
113
|
+
mobile="swiftui",
|
|
114
|
+
extras=[],
|
|
115
|
+
),
|
|
116
|
+
why="When the brief says 'iPhone app, native feel, app store'. "
|
|
117
|
+
"Convex still works as the backend; UI is pure SwiftUI.",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _mobile_cross_stack() -> Stack:
|
|
122
|
+
return Stack(
|
|
123
|
+
id="omegaos-mobile-expo",
|
|
124
|
+
title="Cross-platform mobile (Expo + Convex + Stripe + NativeWind)",
|
|
125
|
+
config=StackConfig(
|
|
126
|
+
type="mobile",
|
|
127
|
+
frontend="expo",
|
|
128
|
+
backend="convex",
|
|
129
|
+
deploy="eas",
|
|
130
|
+
payments="stripe",
|
|
131
|
+
ui_kit="shadcn", # via react-native-reusables
|
|
132
|
+
auth="clerk",
|
|
133
|
+
mobile="expo",
|
|
134
|
+
extras=["nativewind", "react-native-reanimated"],
|
|
135
|
+
),
|
|
136
|
+
why="iOS + Android in one codebase. Convex SDK has first-class "
|
|
137
|
+
"Expo support; clerk-expo handles auth.",
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _desktop_tauri_stack() -> Stack:
|
|
142
|
+
return Stack(
|
|
143
|
+
id="omegaos-desktop-tauri",
|
|
144
|
+
title="Desktop (Tauri + Next.js renderer + Convex)",
|
|
145
|
+
config=StackConfig(
|
|
146
|
+
type="desktop",
|
|
147
|
+
frontend="nextjs",
|
|
148
|
+
backend="convex",
|
|
149
|
+
deploy="self-hosted",
|
|
150
|
+
payments="stripe",
|
|
151
|
+
ui_kit="shadcn",
|
|
152
|
+
auth="clerk",
|
|
153
|
+
desktop="tauri",
|
|
154
|
+
extras=["framer-motion"],
|
|
155
|
+
),
|
|
156
|
+
why="Native binary, web tech inside. Smaller than Electron, "
|
|
157
|
+
"ships to mac/win/linux from one codebase.",
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _backend_supabase_stack() -> Stack:
|
|
162
|
+
return Stack(
|
|
163
|
+
id="omegaos-supabase",
|
|
164
|
+
title="Supabase variant (Next.js + Supabase + Vercel + Stripe + shadcn)",
|
|
165
|
+
config=StackConfig(
|
|
166
|
+
type="web",
|
|
167
|
+
frontend="nextjs",
|
|
168
|
+
backend="supabase",
|
|
169
|
+
deploy="vercel",
|
|
170
|
+
payments="stripe",
|
|
171
|
+
ui_kit="shadcn",
|
|
172
|
+
auth="supabase-auth",
|
|
173
|
+
),
|
|
174
|
+
why="When the operator explicitly wants Supabase (existing data, "
|
|
175
|
+
"PostgreSQL needs, RLS). Pay attention: Supabase auth, not Clerk.",
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
CANONICAL_STACKS: dict[str, Stack] = {
|
|
180
|
+
s.id: s for s in (
|
|
181
|
+
default_stack(),
|
|
182
|
+
_mobile_native_stack(),
|
|
183
|
+
_mobile_cross_stack(),
|
|
184
|
+
_desktop_tauri_stack(),
|
|
185
|
+
_backend_supabase_stack(),
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# ---------------------------------------------------------------------------
|
|
191
|
+
# Question generator
|
|
192
|
+
# ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def stack_questions(intent: str = "") -> list[StackQuestion]:
|
|
196
|
+
"""The minimal question list the picker needs to settle the stack.
|
|
197
|
+
|
|
198
|
+
Five questions, each with a recommended default — operator can hit
|
|
199
|
+
Enter on each to accept the OmegaOS canonical stack.
|
|
200
|
+
"""
|
|
201
|
+
return [
|
|
202
|
+
StackQuestion(
|
|
203
|
+
key="type",
|
|
204
|
+
header="Target",
|
|
205
|
+
question="What's the project's target surface?",
|
|
206
|
+
options=["web", "mobile", "desktop", "iphone", "mac", "cli", "library", "mixed"],
|
|
207
|
+
recommended="web",
|
|
208
|
+
why="Web is the default; switch only when the brief calls for native.",
|
|
209
|
+
),
|
|
210
|
+
StackQuestion(
|
|
211
|
+
key="backend",
|
|
212
|
+
header="Backend",
|
|
213
|
+
question="Which backend?",
|
|
214
|
+
options=["convex", "supabase", "postgres+drizzle", "trpc+prisma", "firebase", "none"],
|
|
215
|
+
recommended="convex",
|
|
216
|
+
why="Convex is the OmegaOS canonical — real-time, typed, hosted, fits the agent loop.",
|
|
217
|
+
),
|
|
218
|
+
StackQuestion(
|
|
219
|
+
key="frontend",
|
|
220
|
+
header="Frontend",
|
|
221
|
+
question="Which frontend framework?",
|
|
222
|
+
options=["nextjs", "astro", "remix", "vite-react", "expo", "tauri", "electron", "swiftui"],
|
|
223
|
+
recommended="nextjs",
|
|
224
|
+
why="Next.js + App Router is the stack the engine deploys cleanly via /prod.",
|
|
225
|
+
),
|
|
226
|
+
StackQuestion(
|
|
227
|
+
key="auth",
|
|
228
|
+
header="Auth",
|
|
229
|
+
question="Auth provider?",
|
|
230
|
+
options=["clerk", "better-auth", "next-auth", "supabase-auth", "custom"],
|
|
231
|
+
recommended="clerk",
|
|
232
|
+
why="Clerk: organisations, MFA, OAuth, magic links — out of the box.",
|
|
233
|
+
),
|
|
234
|
+
StackQuestion(
|
|
235
|
+
key="payments",
|
|
236
|
+
header="Payments",
|
|
237
|
+
question="Payments provider?",
|
|
238
|
+
options=["stripe", "lemonsqueezy", "paddle", "none"],
|
|
239
|
+
recommended="stripe",
|
|
240
|
+
why="Stripe Connect is the engine's tested integration.",
|
|
241
|
+
),
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
# ---------------------------------------------------------------------------
|
|
246
|
+
# The picker
|
|
247
|
+
# ---------------------------------------------------------------------------
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def pick_stack(
|
|
251
|
+
*,
|
|
252
|
+
answers: dict[str, str] | None = None,
|
|
253
|
+
intent: str = "",
|
|
254
|
+
accept_defaults: bool = False,
|
|
255
|
+
) -> StackConfig:
|
|
256
|
+
"""Apply ``answers`` (key → value) on top of the canonical stack.
|
|
257
|
+
|
|
258
|
+
Rules:
|
|
259
|
+
* Every key in ``answers`` MUST appear in the question list and the
|
|
260
|
+
value MUST be in that question's ``options``. Otherwise we raise.
|
|
261
|
+
* Missing keys fall back to the recommended default.
|
|
262
|
+
* When ``accept_defaults=True``, ``answers`` is ignored entirely
|
|
263
|
+
and the canonical stack is returned.
|
|
264
|
+
|
|
265
|
+
Coupled inference (after the operator's answers are applied):
|
|
266
|
+
* type=iphone → mobile=swiftui, deploy=none, ui_kit=custom
|
|
267
|
+
* type=mobile + frontend=expo → mobile=expo, deploy=eas, ui_kit=shadcn
|
|
268
|
+
* type=desktop + frontend in (electron|tauri) → desktop=<that>
|
|
269
|
+
* backend=supabase → auth=supabase-auth (unless overridden)
|
|
270
|
+
"""
|
|
271
|
+
if accept_defaults:
|
|
272
|
+
return default_stack().config
|
|
273
|
+
|
|
274
|
+
answers = answers or {}
|
|
275
|
+
qs = {q.key: q for q in stack_questions(intent)}
|
|
276
|
+
cfg = default_stack().config
|
|
277
|
+
|
|
278
|
+
for key, val in answers.items():
|
|
279
|
+
if key not in qs:
|
|
280
|
+
raise ValueError(
|
|
281
|
+
f"unknown stack question key: {key!r} "
|
|
282
|
+
f"(allowed: {sorted(qs.keys())})"
|
|
283
|
+
)
|
|
284
|
+
if val not in qs[key].options:
|
|
285
|
+
raise ValueError(
|
|
286
|
+
f"invalid value {val!r} for key {key!r} "
|
|
287
|
+
f"(allowed: {qs[key].options})"
|
|
288
|
+
)
|
|
289
|
+
setattr(cfg, key, val)
|
|
290
|
+
|
|
291
|
+
# Coupled inferences — keep config internally consistent.
|
|
292
|
+
if cfg.type == "iphone":
|
|
293
|
+
cfg.mobile = "swiftui"
|
|
294
|
+
cfg.deploy = "none"
|
|
295
|
+
if "ui_kit" not in answers:
|
|
296
|
+
cfg.ui_kit = "custom"
|
|
297
|
+
elif cfg.type == "mac":
|
|
298
|
+
cfg.desktop = "swiftui"
|
|
299
|
+
cfg.deploy = "none"
|
|
300
|
+
if "ui_kit" not in answers:
|
|
301
|
+
cfg.ui_kit = "custom"
|
|
302
|
+
elif cfg.type == "mobile":
|
|
303
|
+
if cfg.frontend in ("expo", "react-native"):
|
|
304
|
+
cfg.mobile = cfg.frontend
|
|
305
|
+
cfg.deploy = "eas"
|
|
306
|
+
elif cfg.type == "desktop":
|
|
307
|
+
if cfg.frontend in ("electron", "tauri"):
|
|
308
|
+
cfg.desktop = cfg.frontend
|
|
309
|
+
|
|
310
|
+
# Auth coupling: supabase backend ⇒ default auth=supabase-auth unless
|
|
311
|
+
# the operator explicitly picked something else.
|
|
312
|
+
if cfg.backend == "supabase" and "auth" not in answers:
|
|
313
|
+
cfg.auth = "supabase-auth"
|
|
314
|
+
|
|
315
|
+
# Strip impossible combinations.
|
|
316
|
+
if cfg.type == "library" or cfg.type == "cli":
|
|
317
|
+
cfg.deploy = "none"
|
|
318
|
+
cfg.payments = "none"
|
|
319
|
+
cfg.auth = "custom"
|
|
320
|
+
cfg.ui_kit = "tailwind-only"
|
|
321
|
+
cfg.mobile = None
|
|
322
|
+
cfg.desktop = None
|
|
323
|
+
|
|
324
|
+
return cfg
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""Genesis state machine + project root resolver.
|
|
2
|
+
|
|
3
|
+
PROJECT.yaml schema (one file per project, source of truth)
|
|
4
|
+
-----------------------------------------------------------
|
|
5
|
+
|
|
6
|
+
::
|
|
7
|
+
|
|
8
|
+
slug: my-saas
|
|
9
|
+
name: My SaaS
|
|
10
|
+
created_at: 2026-05-25T14:00:00Z
|
|
11
|
+
updated_at: 2026-05-25T14:30:00Z
|
|
12
|
+
intent: "AI-powered email warmup for B2B teams"
|
|
13
|
+
phase: market # one of PHASES
|
|
14
|
+
completed_phases:
|
|
15
|
+
- stack
|
|
16
|
+
- vision
|
|
17
|
+
stack:
|
|
18
|
+
type: web # web | mobile | desktop | cli | library | mac | iphone
|
|
19
|
+
frontend: nextjs
|
|
20
|
+
backend: convex
|
|
21
|
+
deploy: vercel
|
|
22
|
+
payments: stripe
|
|
23
|
+
ui_kit: shadcn
|
|
24
|
+
auth: clerk
|
|
25
|
+
mobile: null
|
|
26
|
+
desktop: null
|
|
27
|
+
extras: [framer-motion, react-flow]
|
|
28
|
+
repo:
|
|
29
|
+
provider: github
|
|
30
|
+
visibility: private
|
|
31
|
+
url: null # set after `omega genesis repo`
|
|
32
|
+
notes: |
|
|
33
|
+
Any operator notes that the orchestrator should remember.
|
|
34
|
+
|
|
35
|
+
The orchestrator reads this file BEFORE every phase and writes it
|
|
36
|
+
ATOMICALLY after. Resume = re-read + skip completed_phases.
|
|
37
|
+
"""
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
import json
|
|
41
|
+
import os
|
|
42
|
+
import shutil
|
|
43
|
+
import threading
|
|
44
|
+
import time
|
|
45
|
+
from dataclasses import asdict, dataclass, field
|
|
46
|
+
from datetime import datetime, timezone
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
from typing import Any
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Ordered phase list — used by the orchestrator to walk forward and by the
|
|
52
|
+
# state machine to validate transitions. Adding a new phase here is the
|
|
53
|
+
# only place that needs to know about it.
|
|
54
|
+
PHASES: tuple[str, ...] = (
|
|
55
|
+
"stack", # pick the technical + programmatic stack
|
|
56
|
+
"vision", # one-page product identity
|
|
57
|
+
"market", # 5 research files
|
|
58
|
+
"branding", # 3 brand files
|
|
59
|
+
"prd", # 9 PRD files
|
|
60
|
+
"features", # N feature files with depends_on
|
|
61
|
+
"plan", # hand off to omega plan build
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
# Dataclasses
|
|
67
|
+
# ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class StackConfig:
|
|
72
|
+
"""The technical + deployment stack the project is built on.
|
|
73
|
+
|
|
74
|
+
All fields default to the OmegaOS preferred stack (Next.js + Convex +
|
|
75
|
+
Vercel + Stripe + shadcn + Clerk). Operators can pivot any field via
|
|
76
|
+
the stack picker; `extras` is the escape hatch for libraries that
|
|
77
|
+
fall outside the canonical 5-tuple (framer-motion, react-flow,
|
|
78
|
+
three.js, gsap, …).
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
type: str = "web" # web | mobile | desktop | cli | library | mac | iphone | mixed
|
|
82
|
+
frontend: str = "nextjs" # nextjs | astro | remix | vite-react | expo | tauri | electron | swiftui | …
|
|
83
|
+
backend: str = "convex" # convex | supabase | postgres+drizzle | trpc+prisma | firebase | none
|
|
84
|
+
deploy: str = "vercel" # vercel | cloudflare | fly | render | self-hosted | aws-amplify | none
|
|
85
|
+
payments: str = "stripe" # stripe | lemonsqueezy | paddle | none
|
|
86
|
+
ui_kit: str = "shadcn" # shadcn | radix | mantine | mui | tailwind-only | custom
|
|
87
|
+
auth: str = "clerk" # clerk | better-auth | next-auth | supabase-auth | custom
|
|
88
|
+
mobile: str | None = None # null | expo | react-native | swiftui | flutter
|
|
89
|
+
desktop: str | None = None # null | tauri | electron | wails
|
|
90
|
+
extras: list[str] = field(default_factory=list)
|
|
91
|
+
|
|
92
|
+
def to_dict(self) -> dict[str, Any]:
|
|
93
|
+
return asdict(self)
|
|
94
|
+
|
|
95
|
+
@staticmethod
|
|
96
|
+
def from_dict(d: dict[str, Any]) -> "StackConfig":
|
|
97
|
+
# tolerant — fill missing fields with defaults
|
|
98
|
+
kept = {k: v for k, v in d.items() if k in StackConfig().__dict__}
|
|
99
|
+
return StackConfig(**kept)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class RepoConfig:
|
|
104
|
+
provider: str = "github" # github | gitlab | none
|
|
105
|
+
visibility: str = "private" # private | public
|
|
106
|
+
url: str | None = None # set after `omega genesis repo`
|
|
107
|
+
|
|
108
|
+
def to_dict(self) -> dict[str, Any]:
|
|
109
|
+
return asdict(self)
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def from_dict(d: dict[str, Any]) -> "RepoConfig":
|
|
113
|
+
kept = {k: v for k, v in d.items() if k in RepoConfig().__dict__}
|
|
114
|
+
return RepoConfig(**kept)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@dataclass
|
|
118
|
+
class GenesisState:
|
|
119
|
+
"""The source of truth for a project's genesis pipeline."""
|
|
120
|
+
|
|
121
|
+
slug: str
|
|
122
|
+
name: str
|
|
123
|
+
intent: str
|
|
124
|
+
created_at: str
|
|
125
|
+
updated_at: str
|
|
126
|
+
phase: str = "stack" # current phase
|
|
127
|
+
completed_phases: list[str] = field(default_factory=list)
|
|
128
|
+
stack: StackConfig = field(default_factory=StackConfig)
|
|
129
|
+
repo: RepoConfig = field(default_factory=RepoConfig)
|
|
130
|
+
notes: str = ""
|
|
131
|
+
|
|
132
|
+
def is_phase_done(self, phase: str) -> bool:
|
|
133
|
+
return phase in self.completed_phases
|
|
134
|
+
|
|
135
|
+
def next_phase(self) -> str | None:
|
|
136
|
+
"""The next phase to run, or None when the pipeline is finished."""
|
|
137
|
+
for ph in PHASES:
|
|
138
|
+
if not self.is_phase_done(ph):
|
|
139
|
+
return ph
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
def mark_phase_done(self, phase: str) -> None:
|
|
143
|
+
if phase not in PHASES:
|
|
144
|
+
raise ValueError(f"unknown phase: {phase!r}")
|
|
145
|
+
if phase not in self.completed_phases:
|
|
146
|
+
self.completed_phases.append(phase)
|
|
147
|
+
# phase pointer advances to the next undone phase, or stays at
|
|
148
|
+
# the last one if everything is done
|
|
149
|
+
nxt = self.next_phase()
|
|
150
|
+
self.phase = nxt or PHASES[-1]
|
|
151
|
+
self.updated_at = _now_iso()
|
|
152
|
+
|
|
153
|
+
# ---- YAML / JSON serialisation -----------------------------------
|
|
154
|
+
|
|
155
|
+
def to_yaml(self) -> str:
|
|
156
|
+
try:
|
|
157
|
+
import yaml
|
|
158
|
+
except ImportError:
|
|
159
|
+
# Fallback to JSON when PyYAML isn't installed. The file will
|
|
160
|
+
# still be readable by load_state via the same fallback.
|
|
161
|
+
return json.dumps(self.to_dict(), indent=2)
|
|
162
|
+
return yaml.safe_dump(self.to_dict(), sort_keys=False, allow_unicode=True)
|
|
163
|
+
|
|
164
|
+
def to_dict(self) -> dict[str, Any]:
|
|
165
|
+
d = asdict(self)
|
|
166
|
+
d["stack"] = self.stack.to_dict()
|
|
167
|
+
d["repo"] = self.repo.to_dict()
|
|
168
|
+
return d
|
|
169
|
+
|
|
170
|
+
@staticmethod
|
|
171
|
+
def from_dict(d: dict[str, Any]) -> "GenesisState":
|
|
172
|
+
stack = StackConfig.from_dict(d.get("stack") or {})
|
|
173
|
+
repo = RepoConfig.from_dict(d.get("repo") or {})
|
|
174
|
+
return GenesisState(
|
|
175
|
+
slug=str(d["slug"]),
|
|
176
|
+
name=str(d.get("name", d["slug"])),
|
|
177
|
+
intent=str(d.get("intent", "")),
|
|
178
|
+
created_at=str(d.get("created_at", _now_iso())),
|
|
179
|
+
updated_at=str(d.get("updated_at", _now_iso())),
|
|
180
|
+
phase=str(d.get("phase", "stack")),
|
|
181
|
+
completed_phases=list(d.get("completed_phases") or []),
|
|
182
|
+
stack=stack,
|
|
183
|
+
repo=repo,
|
|
184
|
+
notes=str(d.get("notes", "")),
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _now_iso() -> str:
|
|
189
|
+
return datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# ---------------------------------------------------------------------------
|
|
193
|
+
# Path resolver — STRICT per-project isolation
|
|
194
|
+
# ---------------------------------------------------------------------------
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _omega_home(explicit: str | Path | None) -> Path:
|
|
198
|
+
if explicit is not None:
|
|
199
|
+
return Path(explicit)
|
|
200
|
+
return Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def project_root(slug: str, omega_home: str | Path | None = None) -> Path:
|
|
204
|
+
"""The single, canonical root for a project's genesis tree.
|
|
205
|
+
|
|
206
|
+
Every helper in this package MUST go through this function — no
|
|
207
|
+
ambient CWD heuristics, no "find the closest .git". One slug → one
|
|
208
|
+
path, always.
|
|
209
|
+
"""
|
|
210
|
+
if not slug or not slug.replace("-", "").replace("_", "").isalnum():
|
|
211
|
+
raise ValueError(
|
|
212
|
+
f"invalid project slug {slug!r} — must match [A-Za-z0-9_-]+"
|
|
213
|
+
)
|
|
214
|
+
return _omega_home(omega_home) / "Agentik_Coding" / "projects" / slug
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def state_path(slug: str, omega_home: str | Path | None = None) -> Path:
|
|
218
|
+
return project_root(slug, omega_home) / "PROJECT.yaml"
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
# Atomic read / write
|
|
223
|
+
# ---------------------------------------------------------------------------
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _atomic_write(path: Path, content: str) -> None:
|
|
227
|
+
"""Same temp+fsync+rename pattern as done_signal — never partial writes."""
|
|
228
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
229
|
+
tmp = path.with_suffix(
|
|
230
|
+
path.suffix + f".tmp.{os.getpid()}.{threading.get_ident()}"
|
|
231
|
+
)
|
|
232
|
+
fd = os.open(str(tmp), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)
|
|
233
|
+
with os.fdopen(fd, "w") as fh:
|
|
234
|
+
fh.write(content)
|
|
235
|
+
fh.flush()
|
|
236
|
+
try:
|
|
237
|
+
os.fsync(fh.fileno())
|
|
238
|
+
except OSError:
|
|
239
|
+
pass
|
|
240
|
+
os.replace(tmp, path)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def save_state(state: GenesisState, omega_home: str | Path | None = None) -> Path:
|
|
244
|
+
"""Atomically persist PROJECT.yaml. Returns the absolute path."""
|
|
245
|
+
p = state_path(state.slug, omega_home)
|
|
246
|
+
_atomic_write(p, state.to_yaml())
|
|
247
|
+
return p
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def load_state(
|
|
251
|
+
slug: str, omega_home: str | Path | None = None,
|
|
252
|
+
) -> GenesisState:
|
|
253
|
+
"""Read PROJECT.yaml. Raises FileNotFoundError if it doesn't exist.
|
|
254
|
+
|
|
255
|
+
Supports both YAML and JSON payloads — write_state always emits the
|
|
256
|
+
most expressive format available (YAML if PyYAML, JSON otherwise).
|
|
257
|
+
"""
|
|
258
|
+
p = state_path(slug, omega_home)
|
|
259
|
+
if not p.exists():
|
|
260
|
+
raise FileNotFoundError(
|
|
261
|
+
f"no genesis state at {p} — run `omega genesis new {slug}` first"
|
|
262
|
+
)
|
|
263
|
+
raw = p.read_text()
|
|
264
|
+
try:
|
|
265
|
+
import yaml
|
|
266
|
+
data = yaml.safe_load(raw) or {}
|
|
267
|
+
except ImportError:
|
|
268
|
+
data = json.loads(raw)
|
|
269
|
+
return GenesisState.from_dict(data)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
# ---------------------------------------------------------------------------
|
|
273
|
+
# Init
|
|
274
|
+
# ---------------------------------------------------------------------------
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def init_project(
|
|
278
|
+
slug: str,
|
|
279
|
+
*,
|
|
280
|
+
name: str | None = None,
|
|
281
|
+
intent: str = "",
|
|
282
|
+
stack: StackConfig | None = None,
|
|
283
|
+
omega_home: str | Path | None = None,
|
|
284
|
+
force: bool = False,
|
|
285
|
+
) -> GenesisState:
|
|
286
|
+
"""Create the project skeleton on disk + write the initial PROJECT.yaml.
|
|
287
|
+
|
|
288
|
+
Folder shape created on disk:
|
|
289
|
+
<root>/
|
|
290
|
+
PROJECT.yaml
|
|
291
|
+
docs/
|
|
292
|
+
10-market/
|
|
293
|
+
20-brand/
|
|
294
|
+
30-prd/
|
|
295
|
+
40-features/
|
|
296
|
+
plan/
|
|
297
|
+
|
|
298
|
+
Idempotent: a re-call WITHOUT ``force`` raises if PROJECT.yaml already
|
|
299
|
+
exists. With ``force=True``, the existing state is OVERWRITTEN (the
|
|
300
|
+
docs/ tree is left intact — destructive deletes are never automatic).
|
|
301
|
+
"""
|
|
302
|
+
root = project_root(slug, omega_home)
|
|
303
|
+
if state_path(slug, omega_home).exists() and not force:
|
|
304
|
+
raise FileExistsError(
|
|
305
|
+
f"PROJECT.yaml already exists at {root} — "
|
|
306
|
+
f"use `omega genesis resume {slug}` to continue, "
|
|
307
|
+
f"or pass --force to re-init"
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
# Create the canonical sub-tree. ``mkdir parents=True exist_ok=True`` is
|
|
311
|
+
# idempotent so re-running on an existing tree is safe.
|
|
312
|
+
for sub in (
|
|
313
|
+
"docs/10-market",
|
|
314
|
+
"docs/20-brand",
|
|
315
|
+
"docs/30-prd",
|
|
316
|
+
"docs/40-features",
|
|
317
|
+
"plan",
|
|
318
|
+
):
|
|
319
|
+
(root / sub).mkdir(parents=True, exist_ok=True)
|
|
320
|
+
|
|
321
|
+
now = _now_iso()
|
|
322
|
+
state = GenesisState(
|
|
323
|
+
slug=slug,
|
|
324
|
+
name=name or slug,
|
|
325
|
+
intent=intent,
|
|
326
|
+
created_at=now,
|
|
327
|
+
updated_at=now,
|
|
328
|
+
phase="stack",
|
|
329
|
+
completed_phases=[],
|
|
330
|
+
stack=stack or StackConfig(),
|
|
331
|
+
repo=RepoConfig(),
|
|
332
|
+
)
|
|
333
|
+
save_state(state, omega_home=omega_home)
|
|
334
|
+
return state
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def delete_project(slug: str, omega_home: str | Path | None = None) -> bool:
|
|
338
|
+
"""Best-effort destroy a project tree. Returns True if anything was
|
|
339
|
+
deleted. Refuses if the path escapes the canonical
|
|
340
|
+
Agentik_Coding/projects/ root."""
|
|
341
|
+
root = project_root(slug, omega_home)
|
|
342
|
+
if not root.exists():
|
|
343
|
+
return False
|
|
344
|
+
# Defence in depth — make sure we don't shutil.rmtree something
|
|
345
|
+
# unexpected (a symlink, an ambient relative path, …).
|
|
346
|
+
home = _omega_home(omega_home)
|
|
347
|
+
canon = (home / "Agentik_Coding" / "projects").resolve()
|
|
348
|
+
if not str(root.resolve()).startswith(str(canon)):
|
|
349
|
+
raise RuntimeError(
|
|
350
|
+
f"refusing to delete {root} — outside canonical projects/ root"
|
|
351
|
+
)
|
|
352
|
+
shutil.rmtree(root, ignore_errors=True)
|
|
353
|
+
return True
|