@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,445 @@
1
+ """SST → provider projection — the `omega sync` engine.
2
+
3
+ The SSOT is provider-neutral. Each provider adapter compiles
4
+ `Agentik_SSOT/` into that provider's native shape. Re-running `omega sync` is
5
+ idempotent: same SSOT in, same projection out — so the SSOT remains the only
6
+ hand-edited surface.
7
+
8
+ Today only the Claude Code adapter is fully wired. GLM / OpenAI / DeepSeek
9
+ providers consume the SSOT directly via API calls and have no on-disk native
10
+ layout, so their adapters log a no-op message. New providers add one adapter
11
+ file; the SSOT does not change.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import os
17
+ from pathlib import Path
18
+ from typing import Any, Iterable, Protocol, runtime_checkable
19
+
20
+
21
+ def _omega_home(explicit: str | Path | None = None) -> Path:
22
+ return Path(explicit or os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
23
+
24
+
25
+ # --------------------------------------------------------------------------
26
+ # Provider adapter contract
27
+ # --------------------------------------------------------------------------
28
+
29
+
30
+ @runtime_checkable
31
+ class ProviderAdapter(Protocol):
32
+ """Each provider exposes a `project(omega_home)` that writes its native layout."""
33
+
34
+ id: str
35
+
36
+ def project(self, omega_home: Path) -> dict[str, Any]: ...
37
+
38
+
39
+ class _StubAdapter:
40
+ """Adapter that has no on-disk native layout — logs and returns metadata."""
41
+
42
+ def __init__(self, provider_id: str, reason: str) -> None:
43
+ self.id = provider_id
44
+ self._reason = reason
45
+
46
+ def project(self, omega_home: Path) -> dict[str, Any]:
47
+ msg = f"[sync] {self.id}: {self._reason}"
48
+ print(msg)
49
+ return {"provider": self.id, "projected": False, "reason": self._reason}
50
+
51
+
52
+ # --------------------------------------------------------------------------
53
+ # Claude Code adapter — the only fully wired one for now
54
+ # --------------------------------------------------------------------------
55
+
56
+
57
+ class ClaudeCodeAdapter:
58
+ """Project the SSOT into Claude Code's native `.claude/` layout.
59
+
60
+ Native target tree (idempotent):
61
+ <target>/skills/<id>/SKILL.md
62
+ <target>/commands/<id>.md
63
+ <target>/agents/<id>.md
64
+ <target>/.mcp.json { "mcpServers": { ... } }
65
+ <target>/settings.json { ..., "hooks": {...} }
66
+
67
+ The SSOT is never modified — the adapter is one-way (SSOT → projection).
68
+ Default target: `<omega_home>/Agentik_AI/providers/claude-code/.claude/`.
69
+ """
70
+
71
+ id = "claude-code"
72
+
73
+ def __init__(self, target: str | Path | None = None) -> None:
74
+ self._explicit_target = Path(target) if target else None
75
+
76
+ # ----- helpers -------------------------------------------------------
77
+
78
+ def target_dir(self, omega_home: Path) -> Path:
79
+ if self._explicit_target is not None:
80
+ return self._explicit_target
81
+ return omega_home / "Agentik_AI" / "providers" / "claude-code" / ".claude"
82
+
83
+ @staticmethod
84
+ def _ensure(d: Path) -> Path:
85
+ d.mkdir(parents=True, exist_ok=True)
86
+ return d
87
+
88
+ @staticmethod
89
+ def _stem(path: Path) -> str:
90
+ return path.stem
91
+
92
+ # ----- skills / commands / agents (markdown surfaces) ----------------
93
+
94
+ def _project_markdown_dir(
95
+ self,
96
+ src: Path,
97
+ out_root: Path,
98
+ layout: str, # "skill" | "command" | "agent"
99
+ ) -> list[str]:
100
+ """Copy `src/*.md` AND `src/<name>/SKILL.md` to the native layout.
101
+
102
+ Both shapes are supported in the SSOT:
103
+ 1. Flat: ``Agentik_SSOT/skills/pursue.md``
104
+ 2. Directory: ``Agentik_SSOT/skills/pursue/SKILL.md`` (+ optional
105
+ supporting files like ``scripts/`` or ``examples/``).
106
+
107
+ Directory-based skills are the Claude Code idiom — supporting files
108
+ sit next to ``SKILL.md`` and the agent can reference them via
109
+ ``${CLAUDE_SKILL_DIR}``. We copy the whole directory verbatim so
110
+ those references resolve at the destination.
111
+
112
+ Returns the list of written paths (relative to ``out_root.parent``).
113
+ """
114
+ if not src.is_dir():
115
+ return []
116
+ out_root = self._ensure(out_root)
117
+ written: list[str] = []
118
+
119
+ # 1. flat: src/<name>.md
120
+ for md in sorted(src.glob("*.md")):
121
+ stem = self._stem(md)
122
+ if layout == "skill":
123
+ dest_dir = self._ensure(out_root / stem)
124
+ dest = dest_dir / "SKILL.md"
125
+ else:
126
+ dest = out_root / f"{stem}.md"
127
+ dest.write_text(md.read_text())
128
+ written.append(str(dest.relative_to(out_root.parent)))
129
+
130
+ # 2. directory: src/<name>/SKILL.md (+ supporting files)
131
+ if layout == "skill":
132
+ import shutil as _sh
133
+ for child in sorted(src.iterdir()):
134
+ if not child.is_dir():
135
+ continue
136
+ skill_md = child / "SKILL.md"
137
+ if not skill_md.exists():
138
+ continue
139
+ dest_dir = self._ensure(out_root / child.name)
140
+ # Copy SKILL.md plus any supporting files (scripts/, etc.)
141
+ for item in child.iterdir():
142
+ target = dest_dir / item.name
143
+ if item.is_dir():
144
+ if target.exists():
145
+ _sh.rmtree(target)
146
+ _sh.copytree(item, target)
147
+ else:
148
+ target.write_text(item.read_text())
149
+ written.append(
150
+ str((dest_dir / "SKILL.md").relative_to(out_root.parent))
151
+ )
152
+ return written
153
+
154
+ # ----- MCP config (.mcp.json) ---------------------------------------
155
+
156
+ def _project_mcp(self, omega_home: Path, out_root: Path) -> dict[str, Any]:
157
+ """Compile mcp-config.yaml + the tool registry → Claude Code .mcp.json.
158
+
159
+ Claude Code expects: { "mcpServers": { "<id>": { "command": "...",
160
+ "args": [...],
161
+ "env": {...} } } }
162
+ We resolve `command` from the tool registry invoke path when available.
163
+ """
164
+ try:
165
+ import yaml
166
+ except ImportError:
167
+ return {}
168
+
169
+ cfg_path = omega_home / "Agentik_SSOT" / "mcp" / "mcp-config.yaml"
170
+ catalog_path = omega_home / "Agentik_SSOT" / "mcp" / "mcp-catalog.yaml"
171
+
172
+ cfg: dict[str, Any] = {}
173
+ if cfg_path.exists():
174
+ cfg = yaml.safe_load(cfg_path.read_text()) or {}
175
+
176
+ catalog_by_id: dict[str, dict[str, Any]] = {}
177
+ if catalog_path.exists():
178
+ catalog = yaml.safe_load(catalog_path.read_text()) or {}
179
+ for e in catalog.get("catalog") or []:
180
+ catalog_by_id[str(e.get("id"))] = e
181
+
182
+ # The tool registry tells us where the binary is for each MCP id.
183
+ from omega_engine.tools import ToolRegistry # local import — avoid cycle
184
+ reg = ToolRegistry.load(omega_home)
185
+ tool_by_id = {t.name: t for t in reg.list()}
186
+
187
+ mcp_servers: dict[str, Any] = {}
188
+ for server in cfg.get("servers") or []:
189
+ sid = str(server.get("id", "")).strip()
190
+ if not sid or not server.get("enabled", True):
191
+ continue
192
+ entry: dict[str, Any] = {}
193
+ tool = tool_by_id.get(sid)
194
+ cat = catalog_by_id.get(sid, {})
195
+ install = cat.get("install") or {}
196
+
197
+ # Prefer the locally installed binary; fall back to `npx <package>`.
198
+ if tool and tool.invoke:
199
+ entry["command"] = str(omega_home / tool.invoke)
200
+ entry["args"] = list(server.get("args") or [])
201
+ elif install.get("method") == "npx" and install.get("package"):
202
+ entry["command"] = "npx"
203
+ entry["args"] = ["-y", str(install["package"]), *(server.get("args") or [])]
204
+ else:
205
+ # nothing to invoke — skip rather than write a half-broken entry
206
+ continue
207
+
208
+ from_server = list(server.get("secret_refs") or [])
209
+ from_tool = list(tool.secret_refs) if tool else []
210
+ secret_refs = from_server or from_tool
211
+ if secret_refs:
212
+ # Claude Code's .mcp.json supports an `env` block; we project
213
+ # secret refs by name (the value is filled at runtime from the
214
+ # vault, never written to disk in plaintext).
215
+ entry["env"] = {ref: f"${{{ref}}}" for ref in secret_refs}
216
+
217
+ mcp_servers[sid] = entry
218
+
219
+ out_root = self._ensure(out_root)
220
+ target = out_root / ".mcp.json"
221
+ payload = {"mcpServers": mcp_servers}
222
+ target.write_text(json.dumps(payload, indent=2) + "\n")
223
+ return payload
224
+
225
+ # ----- hooks → settings.json -----------------------------------------
226
+
227
+ def _project_hooks(self, omega_home: Path, out_root: Path) -> dict[str, Any]:
228
+ """Merge `Agentik_SSOT/hooks/*` into <target>/settings.json `hooks`.
229
+
230
+ Each file under hooks/ is one of:
231
+ - *.json — already in Claude Code hook shape; merged shallow into hooks
232
+ - *.yaml/*.yml — same shape, parsed as YAML
233
+ Unknown extensions are ignored.
234
+ """
235
+ hooks_dir = omega_home / "Agentik_SSOT" / "hooks"
236
+ out_root = self._ensure(out_root)
237
+ settings_file = out_root / "settings.json"
238
+
239
+ settings: dict[str, Any] = {}
240
+ if settings_file.exists():
241
+ try:
242
+ settings = json.loads(settings_file.read_text() or "{}")
243
+ except json.JSONDecodeError:
244
+ settings = {}
245
+
246
+ hooks_block: dict[str, Any] = dict(settings.get("hooks") or {})
247
+
248
+ if hooks_dir.is_dir():
249
+ import yaml
250
+ for path in sorted(hooks_dir.iterdir()):
251
+ if not path.is_file():
252
+ continue
253
+ if path.suffix == ".json":
254
+ try:
255
+ data = json.loads(path.read_text() or "{}")
256
+ except json.JSONDecodeError:
257
+ continue
258
+ elif path.suffix in {".yaml", ".yml"}:
259
+ data = yaml.safe_load(path.read_text() or "") or {}
260
+ else:
261
+ continue
262
+ if not isinstance(data, dict):
263
+ continue
264
+ for k, v in data.items():
265
+ hooks_block[k] = v
266
+
267
+ settings["hooks"] = hooks_block
268
+ settings_file.write_text(json.dumps(settings, indent=2) + "\n")
269
+ return hooks_block
270
+
271
+ # ----- bridge to ~/.claude/ (the dir Claude Code actually reads) -----
272
+ #
273
+ # Why this exists
274
+ # ---------------
275
+ # ``project()`` writes the SSOT-derived layout into
276
+ # ``$OMEGA_HOME/Agentik_AI/providers/claude-code/.claude/`` — that tree
277
+ # stays under OmegaOS for portability (vault backup, audit trail, you
278
+ # name it). But the ``claude`` CLI on a real workstation reads skills /
279
+ # commands / agents / .mcp.json from ``~/.claude/`` (user-global) and
280
+ # ``.claude/`` (project-local).
281
+ #
282
+ # Without a bridge, the 24 SSOT skills NEVER become invokable slash
283
+ # commands. ``link_to_user_claude(home)`` is that bridge: for every
284
+ # skill we projected, we create a SYMLINK at
285
+ # ``~/.claude/skills/<id> → $OMEGA_HOME/.../skills/<id>``. This means:
286
+ # - editing the SSOT + re-running ``omega sync`` updates the
287
+ # skill in place (no duplicate copies),
288
+ # - removing the SSOT skill nukes the symlink on the next sync,
289
+ # - the operator's existing ``~/.claude/skills/<other>/`` are
290
+ # untouched (we only manage entries whose targets are inside
291
+ # ``$OMEGA_HOME``).
292
+
293
+ def link_to_user_claude(
294
+ self, omega_home: Path,
295
+ *,
296
+ user_claude: Path | None = None,
297
+ ) -> dict[str, Any]:
298
+ """Bridge the projected tree into ``~/.claude/`` via symlinks.
299
+
300
+ Returns ``{linked_skills, linked_commands, linked_agents,
301
+ removed: [stale_paths]}``. Idempotent.
302
+ """
303
+ import os as _os
304
+ user = Path(user_claude) if user_claude else Path.home() / ".claude"
305
+ target = self.target_dir(omega_home)
306
+ out: dict[str, Any] = {
307
+ "user_claude": str(user),
308
+ "linked_skills": 0,
309
+ "linked_commands": 0,
310
+ "linked_agents": 0,
311
+ "removed": [],
312
+ }
313
+ # The provider-tree target must exist first (project() was called).
314
+ if not target.is_dir():
315
+ return out
316
+
317
+ for layout in ("skills", "commands", "agents"):
318
+ src_root = target / layout
319
+ if not src_root.is_dir():
320
+ continue
321
+ dest_root = self._ensure(user / layout)
322
+
323
+ # Remove stale symlinks we used to manage. A "managed" symlink
324
+ # points anywhere inside `target`. Real dirs and symlinks owned
325
+ # by the user are NEVER touched.
326
+ for child in list(dest_root.iterdir()):
327
+ if not child.is_symlink():
328
+ continue
329
+ try:
330
+ realpath = child.resolve()
331
+ except OSError:
332
+ continue
333
+ # Only nuke our own — points inside the OmegaOS tree.
334
+ if str(realpath).startswith(str(target)) and not (src_root / child.name).exists():
335
+ try:
336
+ child.unlink()
337
+ out["removed"].append(str(child))
338
+ except OSError:
339
+ pass
340
+
341
+ for src in sorted(src_root.iterdir()):
342
+ if not src.is_dir() and not src.suffix == ".md":
343
+ continue
344
+ dest = dest_root / src.name
345
+ if dest.is_symlink():
346
+ try:
347
+ dest.unlink()
348
+ except OSError:
349
+ pass
350
+ elif dest.exists():
351
+ # Don't clobber the user's hand-written content.
352
+ continue
353
+ try:
354
+ _os.symlink(src, dest)
355
+ out[f"linked_{layout}"] += 1
356
+ except OSError:
357
+ # Some filesystems (Windows WSL crossings) refuse symlinks;
358
+ # in that case the user can re-run with --copy.
359
+ pass
360
+ return out
361
+
362
+ # ----- entry point ---------------------------------------------------
363
+
364
+ def project(self, omega_home: Path) -> dict[str, Any]:
365
+ target = self.target_dir(omega_home)
366
+ self._ensure(target)
367
+ ssot = omega_home / "Agentik_SSOT"
368
+
369
+ skills = self._project_markdown_dir(ssot / "skills", target / "skills", "skill")
370
+ commands = self._project_markdown_dir(ssot / "commands", target / "commands", "command")
371
+ agents = self._project_markdown_dir(ssot / "agents", target / "agents", "agent")
372
+ mcp = self._project_mcp(omega_home, target)
373
+ hooks = self._project_hooks(omega_home, target)
374
+
375
+ # Bridge to ~/.claude/ so the projected skills actually become
376
+ # invokable slash-commands. Toggleable via env var (off → only the
377
+ # provider tree is written; user opts in later with `omega skill link`).
378
+ link_info: dict[str, Any] = {}
379
+ import os as _os
380
+ if _os.environ.get("OMEGA_SYNC_NO_LINK") != "1":
381
+ try:
382
+ link_info = self.link_to_user_claude(omega_home)
383
+ except OSError:
384
+ link_info = {}
385
+
386
+ return {
387
+ "provider": self.id,
388
+ "projected": True,
389
+ "target": str(target),
390
+ "skills_written": len(skills),
391
+ "commands_written": len(commands),
392
+ "agents_written": len(agents),
393
+ "mcp_servers": len(mcp.get("mcpServers", {})) if isinstance(mcp, dict) else 0,
394
+ "hooks": list(hooks.keys()),
395
+ "linked_to_user_claude": link_info,
396
+ }
397
+
398
+
399
+ # --------------------------------------------------------------------------
400
+ # Sync engine
401
+ # --------------------------------------------------------------------------
402
+
403
+
404
+ def _active_providers(omega_home: Path) -> list[str]:
405
+ """Read Agentik_Providers/registry.yaml; default to [claude] if missing."""
406
+ try:
407
+ import yaml
408
+ except ImportError:
409
+ return ["claude"]
410
+ path = omega_home / "Agentik_Providers" / "registry.yaml"
411
+ if not path.exists():
412
+ return ["claude"]
413
+ data = yaml.safe_load(path.read_text()) or {}
414
+ return [str(p.get("id")) for p in data.get("providers") or [] if p.get("id")]
415
+
416
+
417
+ class SyncEngine:
418
+ """Run every active provider's adapter against the SSOT."""
419
+
420
+ def __init__(self, adapters: Iterable[ProviderAdapter] | None = None) -> None:
421
+ self._explicit = list(adapters) if adapters is not None else None
422
+
423
+ def adapters_for(self, omega_home: Path) -> list[ProviderAdapter]:
424
+ if self._explicit is not None:
425
+ return list(self._explicit)
426
+ active = _active_providers(omega_home)
427
+ result: list[ProviderAdapter] = []
428
+ for pid in active:
429
+ if pid == "claude":
430
+ result.append(ClaudeCodeAdapter())
431
+ else:
432
+ # GLM / OpenAI / DeepSeek don't have a native on-disk format;
433
+ # MCP/skills/commands are passed via API. Document this.
434
+ result.append(_StubAdapter(
435
+ pid,
436
+ "no native projection — used directly via API",
437
+ ))
438
+ return result
439
+
440
+ def sync_all(self, omega_home: str | Path | None = None) -> list[dict[str, Any]]:
441
+ home = _omega_home(omega_home)
442
+ outcomes: list[dict[str, Any]] = []
443
+ for adapter in self.adapters_for(home):
444
+ outcomes.append(adapter.project(home))
445
+ return outcomes
@@ -0,0 +1,260 @@
1
+ """Per-topic conversation history — fixes the "bot has no memory" bug.
2
+
3
+ When the user types in a Telegram topic, the Telegram daemon used to call
4
+ ``run_mission(intent=text)`` with ONLY the new message. The Oracle saw a
5
+ brand-new mission every turn — no idea what the user was actually talking
6
+ about. The user's reply to a follow-up question landed without context.
7
+
8
+ This module is the fix. It persists every inbound + outbound message per
9
+ topic to a SQLite table; the daemon prepends the last N exchanges to the
10
+ envelope's user message so the agent always has the conversation.
11
+
12
+ Layout
13
+ ------
14
+ ``$OMEGA_HOME/Agentik_Runtime/telegram-history.db``
15
+
16
+ ::
17
+
18
+ CREATE TABLE messages (
19
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
20
+ topic_id INTEGER NOT NULL, -- forum topic id (or 0 for DM root)
21
+ role TEXT NOT NULL, -- 'user' | 'bot'
22
+ text TEXT NOT NULL,
23
+ message_id INTEGER, -- Telegram's own message_id
24
+ timestamp INTEGER NOT NULL
25
+ );
26
+
27
+ Two indexes: one for per-topic recency, one for full-text-ish search.
28
+
29
+ Public API
30
+ ----------
31
+ ``record_inbound(home, topic_id, text, message_id=None)``
32
+ ``record_outbound(home, topic_id, text, message_id=None)``
33
+ ``recent_messages(home, topic_id, limit=20) -> list[Message]``
34
+ ``build_context_prompt(home, topic_id, new_intent, limit=10) -> str``
35
+ """
36
+ from __future__ import annotations
37
+
38
+ import os
39
+ import sqlite3
40
+ import time
41
+ from dataclasses import dataclass, field
42
+ from pathlib import Path
43
+ from typing import Iterable
44
+
45
+
46
+ @dataclass
47
+ class Message:
48
+ id: int
49
+ topic_id: int
50
+ role: str # "user" | "bot"
51
+ text: str
52
+ message_id: int | None
53
+ timestamp: int
54
+
55
+
56
+ def _db_path(omega_home: str | Path) -> Path:
57
+ home = Path(omega_home)
58
+ runtime = home / "Agentik_Runtime"
59
+ runtime.mkdir(parents=True, exist_ok=True)
60
+ return runtime / "telegram-history.db"
61
+
62
+
63
+ def _connect(omega_home: str | Path) -> sqlite3.Connection:
64
+ conn = sqlite3.connect(str(_db_path(omega_home)))
65
+ conn.row_factory = sqlite3.Row
66
+ conn.execute("PRAGMA journal_mode=WAL")
67
+ conn.execute("""
68
+ CREATE TABLE IF NOT EXISTS messages (
69
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
70
+ topic_id INTEGER NOT NULL,
71
+ role TEXT NOT NULL CHECK(role IN ('user', 'bot')),
72
+ text TEXT NOT NULL,
73
+ message_id INTEGER,
74
+ timestamp INTEGER NOT NULL
75
+ )
76
+ """)
77
+ conn.execute("""
78
+ CREATE INDEX IF NOT EXISTS idx_messages_topic_time
79
+ ON messages(topic_id, timestamp DESC)
80
+ """)
81
+ return conn
82
+
83
+
84
+ def _record(
85
+ omega_home: str | Path,
86
+ *,
87
+ topic_id: int,
88
+ role: str,
89
+ text: str,
90
+ message_id: int | None,
91
+ ) -> int:
92
+ """Persist one message. Returns the rowid."""
93
+ if role not in ("user", "bot"):
94
+ raise ValueError(f"role must be 'user' or 'bot', got {role!r}")
95
+ conn = _connect(omega_home)
96
+ try:
97
+ cur = conn.execute(
98
+ "INSERT INTO messages (topic_id, role, text, message_id, timestamp) "
99
+ "VALUES (?, ?, ?, ?, ?)",
100
+ (int(topic_id), role, text, message_id, int(time.time())),
101
+ )
102
+ conn.commit()
103
+ return int(cur.lastrowid)
104
+ finally:
105
+ conn.close()
106
+
107
+
108
+ def record_inbound(
109
+ omega_home: str | Path,
110
+ topic_id: int,
111
+ text: str,
112
+ *,
113
+ message_id: int | None = None,
114
+ ) -> int:
115
+ """The user just sent this in the topic. Persist it."""
116
+ return _record(omega_home, topic_id=topic_id, role="user",
117
+ text=text, message_id=message_id)
118
+
119
+
120
+ def record_outbound(
121
+ omega_home: str | Path,
122
+ topic_id: int,
123
+ text: str,
124
+ *,
125
+ message_id: int | None = None,
126
+ ) -> int:
127
+ """The bot just posted this. Persist it so the next turn has context."""
128
+ return _record(omega_home, topic_id=topic_id, role="bot",
129
+ text=text, message_id=message_id)
130
+
131
+
132
+ def recent_messages(
133
+ omega_home: str | Path,
134
+ topic_id: int,
135
+ *,
136
+ limit: int = 20,
137
+ ) -> list[Message]:
138
+ """Return the last ``limit`` messages for this topic, oldest first.
139
+
140
+ The query selects by timestamp DESC then reverses — gives us
141
+ chronological order with a hard cap.
142
+ """
143
+ conn = _connect(omega_home)
144
+ try:
145
+ rows = conn.execute(
146
+ "SELECT * FROM messages WHERE topic_id = ? "
147
+ "ORDER BY timestamp DESC, id DESC LIMIT ?",
148
+ (int(topic_id), int(limit)),
149
+ ).fetchall()
150
+ finally:
151
+ conn.close()
152
+ return [
153
+ Message(
154
+ id=int(r["id"]),
155
+ topic_id=int(r["topic_id"]),
156
+ role=str(r["role"]),
157
+ text=str(r["text"]),
158
+ message_id=(int(r["message_id"])
159
+ if r["message_id"] is not None else None),
160
+ timestamp=int(r["timestamp"]),
161
+ )
162
+ for r in reversed(rows)
163
+ ]
164
+
165
+
166
+ def build_context_prompt(
167
+ omega_home: str | Path,
168
+ topic_id: int,
169
+ new_intent: str,
170
+ *,
171
+ limit: int = 10,
172
+ ) -> str:
173
+ """Compose a context-aware intent for ``run_mission``.
174
+
175
+ Format::
176
+
177
+ [Conversation history in topic <id>]
178
+ user (10 min ago): previous message
179
+ bot (8 min ago): previous reply
180
+ user (just now): ${new_intent}
181
+
182
+ Respond to the user's latest message — the messages above are
183
+ the conversation so far in this topic; keep your answer
184
+ consistent with them.
185
+
186
+ If there's no prior history, returns ``new_intent`` unchanged so a
187
+ cold conversation behaves as before.
188
+ """
189
+ history = recent_messages(omega_home, topic_id, limit=limit)
190
+ if not history:
191
+ return new_intent
192
+
193
+ now = int(time.time())
194
+ lines: list[str] = [
195
+ f"[Conversation history in topic {topic_id}]"
196
+ ]
197
+ for msg in history:
198
+ delta = now - msg.timestamp
199
+ when = _humanise_age(delta)
200
+ lines.append(f" {msg.role} ({when}): {msg.text}")
201
+
202
+ lines.append("")
203
+ lines.append(f"user (just now): {new_intent}")
204
+ lines.append("")
205
+ lines.append(
206
+ "Respond to the user's latest message — the messages above are "
207
+ "the conversation so far in this topic; keep your answer "
208
+ "consistent with them."
209
+ )
210
+ return "\n".join(lines)
211
+
212
+
213
+ def _humanise_age(seconds: int) -> str:
214
+ """Format an age in seconds as a short human string."""
215
+ if seconds < 60:
216
+ return f"{seconds}s ago"
217
+ if seconds < 3600:
218
+ return f"{seconds // 60}m ago"
219
+ if seconds < 86400:
220
+ return f"{seconds // 3600}h ago"
221
+ return f"{seconds // 86400}d ago"
222
+
223
+
224
+ def prune(
225
+ omega_home: str | Path,
226
+ *,
227
+ older_than_days: int = 90,
228
+ ) -> int:
229
+ """Drop messages older than ``older_than_days``. Returns rows removed."""
230
+ cutoff = int(time.time()) - older_than_days * 86400
231
+ conn = _connect(omega_home)
232
+ try:
233
+ cur = conn.execute(
234
+ "DELETE FROM messages WHERE timestamp < ?", (cutoff,)
235
+ )
236
+ conn.commit()
237
+ return int(cur.rowcount)
238
+ finally:
239
+ conn.close()
240
+
241
+
242
+ def topic_stats(omega_home: str | Path) -> list[dict]:
243
+ """For the doctor: a one-row-per-topic summary."""
244
+ conn = _connect(omega_home)
245
+ try:
246
+ rows = conn.execute(
247
+ "SELECT topic_id, COUNT(*) AS n_msgs, "
248
+ " MAX(timestamp) AS last_seen "
249
+ "FROM messages GROUP BY topic_id ORDER BY last_seen DESC"
250
+ ).fetchall()
251
+ finally:
252
+ conn.close()
253
+ return [
254
+ {
255
+ "topic_id": int(r["topic_id"]),
256
+ "messages": int(r["n_msgs"]),
257
+ "last_seen": int(r["last_seen"]),
258
+ }
259
+ for r in rows
260
+ ]