@agentikos/omega-os 0.1.0 → 0.19.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/README.md +56 -14
  2. package/bootstrap/lib/__pycache__/claude-code-settings.cpython-313.pyc +0 -0
  3. package/bootstrap/lib/__pycache__/llm-clis.cpython-313.pyc +0 -0
  4. package/bootstrap/lib/__pycache__/manifest-helpers.cpython-313.pyc +0 -0
  5. package/bootstrap/lib/claude-code-settings.py +176 -0
  6. package/bootstrap/lib/common.sh +457 -1
  7. package/bootstrap/lib/llm-clis.py +341 -0
  8. package/bootstrap/lib/manifest-helpers.py +384 -0
  9. package/bootstrap/lib/steps.sh +1000 -26
  10. package/bootstrap/manifest.example.yaml +93 -2
  11. package/bootstrap/templates/aisb/CLAUDE.md +305 -0
  12. package/bootstrap/templates/aisb/architect.md +204 -0
  13. package/bootstrap/templates/aisb/checkers/CLAUDE.md +9 -0
  14. package/bootstrap/templates/aisb/checkers/checker-architect.md +151 -0
  15. package/bootstrap/templates/aisb/checkers/checker-common.md +171 -0
  16. package/bootstrap/templates/aisb/checkers/checker-construct.md +129 -0
  17. package/bootstrap/templates/aisb/checkers/checker-keymaker.md +204 -0
  18. package/bootstrap/templates/aisb/checkers/checker-link.md +205 -0
  19. package/bootstrap/templates/aisb/checkers/checker-merovingian.md +219 -0
  20. package/bootstrap/templates/aisb/checkers/checker-morpheus.md +211 -0
  21. package/bootstrap/templates/aisb/checkers/checker-neo.md +177 -0
  22. package/bootstrap/templates/aisb/checkers/checker-niobe.md +156 -0
  23. package/bootstrap/templates/aisb/checkers/checker-oracle.md +164 -0
  24. package/bootstrap/templates/aisb/checkers/checker-seraph.md +187 -0
  25. package/bootstrap/templates/aisb/checkers/checker-smith.md +195 -0
  26. package/bootstrap/templates/aisb/checkers/checker-zion.md +113 -0
  27. package/bootstrap/templates/aisb/construct.md +135 -0
  28. package/bootstrap/templates/aisb/keymaker.md +227 -0
  29. package/bootstrap/templates/aisb/link.md +170 -0
  30. package/bootstrap/templates/aisb/lmc-protocol.md +57 -0
  31. package/bootstrap/templates/aisb/merovingian.md +159 -0
  32. package/bootstrap/templates/aisb/morpheus.md +243 -0
  33. package/bootstrap/templates/aisb/neo.md +147 -0
  34. package/bootstrap/templates/aisb/niobe.md +197 -0
  35. package/bootstrap/templates/aisb/oracle.md +244 -0
  36. package/bootstrap/templates/aisb/protocols/handoff-templates.md +204 -0
  37. package/bootstrap/templates/aisb/protocols/shared-protocol.md +248 -0
  38. package/bootstrap/templates/aisb/pythia.md +153 -0
  39. package/bootstrap/templates/aisb/seraph.md +315 -0
  40. package/bootstrap/templates/aisb/smith.md +202 -0
  41. package/bootstrap/templates/aisb/zion.md +172 -0
  42. package/bootstrap/templates/autonomous/audit-patrol.yaml +41 -0
  43. package/bootstrap/templates/autonomous/smith-reflect.yaml +43 -0
  44. package/bootstrap/templates/autonomous/ssh-key-rotate.yaml +46 -0
  45. package/bootstrap/templates/autonomous/support-agent.yaml +38 -0
  46. package/docs/AUDITS.md +85 -0
  47. package/docs/COMPLETION-PLAN.md +48 -0
  48. package/docs/GAP-ANALYSIS.md +214 -0
  49. package/docs/INSTALL.md +47 -9
  50. package/docs/MCP-AND-PLUGINS.md +31 -4
  51. package/docs/SIMULATION.md +171 -0
  52. package/docs/simulate.sh +211 -0
  53. package/install.sh +164 -17
  54. package/omega/Agentik_Engine/README.md +27 -10
  55. package/omega/Agentik_Engine/omega_engine/__init__.py +212 -2
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/account.py +502 -0
  105. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  106. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  107. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  108. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  109. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  110. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  114. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  115. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  116. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  117. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  121. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  122. package/omega/Agentik_Engine/omega_engine/autonomous.py +538 -0
  123. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  124. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  125. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  126. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  127. package/omega/Agentik_Engine/omega_engine/cli.py +4564 -56
  128. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  129. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  130. package/omega/Agentik_Engine/omega_engine/daemons/__init__.py +14 -0
  131. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  132. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  133. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  134. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  135. package/omega/Agentik_Engine/omega_engine/daemons/autonomous.py +56 -0
  136. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +236 -0
  137. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +315 -0
  138. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  139. package/omega/Agentik_Engine/omega_engine/educators/__init__.py +51 -0
  140. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  143. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  144. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/artifact.py +65 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/automation.py +76 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/base.py +327 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/claudecode.py +71 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/connection.py +75 -0
  155. package/omega/Agentik_Engine/omega_engine/educators/coworker.py +68 -0
  156. package/omega/Agentik_Engine/omega_engine/educators/loop.py +82 -0
  157. package/omega/Agentik_Engine/omega_engine/educators/prompt.py +68 -0
  158. package/omega/Agentik_Engine/omega_engine/educators/skill.py +69 -0
  159. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  160. package/omega/Agentik_Engine/omega_engine/executor.py +195 -16
  161. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  167. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  168. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  169. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  170. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  171. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  172. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  173. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  174. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  175. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  176. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  177. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  178. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  179. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  180. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  181. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  182. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  183. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  184. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  185. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  186. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  187. package/omega/Agentik_Engine/omega_engine/mission.py +29 -14
  188. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  189. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  190. package/omega/Agentik_Engine/omega_engine/provider.py +408 -13
  191. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  192. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__init__.py +21 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  198. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  199. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/rag/agentic.py +83 -0
  203. package/omega/Agentik_Engine/omega_engine/rag/base.py +42 -0
  204. package/omega/Agentik_Engine/omega_engine/rag/corrective.py +119 -0
  205. package/omega/Agentik_Engine/omega_engine/rag/graph.py +169 -0
  206. package/omega/Agentik_Engine/omega_engine/rag/hybrid.py +205 -0
  207. package/omega/Agentik_Engine/omega_engine/rag/multimodal.py +136 -0
  208. package/omega/Agentik_Engine/omega_engine/rag/router.py +110 -0
  209. package/omega/Agentik_Engine/omega_engine/reducer.py +21 -3
  210. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  211. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  212. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  214. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  215. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  216. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  217. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  218. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  219. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  220. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  221. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  222. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  223. package/omega/Agentik_Engine/omega_engine/store.py +132 -25
  224. package/omega/Agentik_Engine/omega_engine/sync.py +445 -0
  225. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  226. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  227. package/omega/Agentik_Engine/omega_engine/tools.py +272 -0
  228. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  229. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  230. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  231. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  232. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  233. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  234. package/omega/Agentik_Engine/pyproject.toml +1 -1
  235. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  304. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  305. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  306. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  307. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  308. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  309. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  310. package/omega/Agentik_Engine/tests/test_account.py +338 -0
  311. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  312. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  313. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  314. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  315. package/omega/Agentik_Engine/tests/test_autonomous.py +361 -0
  316. package/omega/Agentik_Engine/tests/test_educators.py +233 -0
  317. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  318. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  319. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  320. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  321. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  322. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  323. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  324. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  325. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  326. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  327. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  328. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  329. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  330. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  331. package/omega/Agentik_Engine/tests/test_rag.py +287 -0
  332. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  333. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  334. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  335. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  336. package/omega/Agentik_Engine/tests/test_snapshot_partial.py +172 -0
  337. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  338. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  339. package/omega/Agentik_Engine/tests/test_tools_and_sync.py +312 -0
  340. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  341. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  342. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  343. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  344. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  345. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  346. package/omega/Agentik_Runtime/audits.db +0 -0
  347. package/omega/Agentik_SSOT/VERSION +1 -1
  348. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  349. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  350. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  351. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  352. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  353. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  354. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  355. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  356. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  357. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  358. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  359. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  360. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  361. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  362. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  363. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  364. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  365. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  366. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  367. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  368. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  369. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  370. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  371. package/omega/Agentik_SSOT/skills/rag-route.md +82 -0
  372. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  373. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  374. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  375. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  376. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  377. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  378. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  379. 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