@agentikos/omega-os 0.2.0 → 0.19.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/README.md +33 -3
  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 +790 -21
  10. package/bootstrap/manifest.example.yaml +87 -1
  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/GAP-ANALYSIS.md +214 -0
  48. package/docs/INSTALL.md +47 -9
  49. package/docs/MCP-AND-PLUGINS.md +31 -4
  50. package/docs/SIMULATION.md +171 -0
  51. package/docs/simulate.sh +211 -0
  52. package/install.sh +164 -17
  53. package/omega/Agentik_Engine/README.md +4 -2
  54. package/omega/Agentik_Engine/omega_engine/__init__.py +147 -1
  55. package/omega/Agentik_Engine/omega_engine/__pycache__/__init__.cpython-313.pyc +0 -0
  56. package/omega/Agentik_Engine/omega_engine/__pycache__/account.cpython-313.pyc +0 -0
  57. package/omega/Agentik_Engine/omega_engine/__pycache__/agent_messages.cpython-313.pyc +0 -0
  58. package/omega/Agentik_Engine/omega_engine/__pycache__/aisb_chat.cpython-313.pyc +0 -0
  59. package/omega/Agentik_Engine/omega_engine/__pycache__/audit.cpython-313.pyc +0 -0
  60. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_arsenal.cpython-313.pyc +0 -0
  61. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_diff.cpython-313.pyc +0 -0
  62. package/omega/Agentik_Engine/omega_engine/__pycache__/audit_gate.cpython-313.pyc +0 -0
  63. package/omega/Agentik_Engine/omega_engine/__pycache__/auto_update.cpython-313.pyc +0 -0
  64. package/omega/Agentik_Engine/omega_engine/__pycache__/autonomous.cpython-313.pyc +0 -0
  65. package/omega/Agentik_Engine/omega_engine/__pycache__/backup.cpython-313.pyc +0 -0
  66. package/omega/Agentik_Engine/omega_engine/__pycache__/barrier.cpython-313.pyc +0 -0
  67. package/omega/Agentik_Engine/omega_engine/__pycache__/bus.cpython-313.pyc +0 -0
  68. package/omega/Agentik_Engine/omega_engine/__pycache__/cadence.cpython-313.pyc +0 -0
  69. package/omega/Agentik_Engine/omega_engine/__pycache__/classifier.cpython-313.pyc +0 -0
  70. package/omega/Agentik_Engine/omega_engine/__pycache__/cleanup.cpython-313.pyc +0 -0
  71. package/omega/Agentik_Engine/omega_engine/__pycache__/cli.cpython-313.pyc +0 -0
  72. package/omega/Agentik_Engine/omega_engine/__pycache__/completions.cpython-313.pyc +0 -0
  73. package/omega/Agentik_Engine/omega_engine/__pycache__/costs.cpython-313.pyc +0 -0
  74. package/omega/Agentik_Engine/omega_engine/__pycache__/done_signal.cpython-313.pyc +0 -0
  75. package/omega/Agentik_Engine/omega_engine/__pycache__/envelope.cpython-313.pyc +0 -0
  76. package/omega/Agentik_Engine/omega_engine/__pycache__/events.cpython-313.pyc +0 -0
  77. package/omega/Agentik_Engine/omega_engine/__pycache__/executor.cpython-313.pyc +0 -0
  78. package/omega/Agentik_Engine/omega_engine/__pycache__/handoff.cpython-313.pyc +0 -0
  79. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes.cpython-313.pyc +0 -0
  80. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_bootstrap.cpython-313.pyc +0 -0
  81. package/omega/Agentik_Engine/omega_engine/__pycache__/hermes_desktop.cpython-313.pyc +0 -0
  82. package/omega/Agentik_Engine/omega_engine/__pycache__/learning.cpython-313.pyc +0 -0
  83. package/omega/Agentik_Engine/omega_engine/__pycache__/managed_agent.cpython-313.pyc +0 -0
  84. package/omega/Agentik_Engine/omega_engine/__pycache__/memory.cpython-313.pyc +0 -0
  85. package/omega/Agentik_Engine/omega_engine/__pycache__/menu.cpython-313.pyc +0 -0
  86. package/omega/Agentik_Engine/omega_engine/__pycache__/mission.cpython-313.pyc +0 -0
  87. package/omega/Agentik_Engine/omega_engine/__pycache__/plan.cpython-313.pyc +0 -0
  88. package/omega/Agentik_Engine/omega_engine/__pycache__/progress.cpython-313.pyc +0 -0
  89. package/omega/Agentik_Engine/omega_engine/__pycache__/project.cpython-313.pyc +0 -0
  90. package/omega/Agentik_Engine/omega_engine/__pycache__/prompts.cpython-313.pyc +0 -0
  91. package/omega/Agentik_Engine/omega_engine/__pycache__/provider.cpython-313.pyc +0 -0
  92. package/omega/Agentik_Engine/omega_engine/__pycache__/prune.cpython-313.pyc +0 -0
  93. package/omega/Agentik_Engine/omega_engine/__pycache__/pursue.cpython-313.pyc +0 -0
  94. package/omega/Agentik_Engine/omega_engine/__pycache__/reducer.cpython-313.pyc +0 -0
  95. package/omega/Agentik_Engine/omega_engine/__pycache__/report.cpython-313.pyc +0 -0
  96. package/omega/Agentik_Engine/omega_engine/__pycache__/router.cpython-313.pyc +0 -0
  97. package/omega/Agentik_Engine/omega_engine/__pycache__/skill_routing.cpython-313.pyc +0 -0
  98. package/omega/Agentik_Engine/omega_engine/__pycache__/smoke.cpython-313.pyc +0 -0
  99. package/omega/Agentik_Engine/omega_engine/__pycache__/store.cpython-313.pyc +0 -0
  100. package/omega/Agentik_Engine/omega_engine/__pycache__/supervisor.cpython-313.pyc +0 -0
  101. package/omega/Agentik_Engine/omega_engine/__pycache__/sync.cpython-313.pyc +0 -0
  102. package/omega/Agentik_Engine/omega_engine/__pycache__/task.cpython-313.pyc +0 -0
  103. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram.cpython-313.pyc +0 -0
  104. package/omega/Agentik_Engine/omega_engine/__pycache__/telegram_history.cpython-313.pyc +0 -0
  105. package/omega/Agentik_Engine/omega_engine/__pycache__/tmux.cpython-313.pyc +0 -0
  106. package/omega/Agentik_Engine/omega_engine/__pycache__/tools.cpython-313.pyc +0 -0
  107. package/omega/Agentik_Engine/omega_engine/__pycache__/understand_anything.cpython-313.pyc +0 -0
  108. package/omega/Agentik_Engine/omega_engine/__pycache__/updater.cpython-313.pyc +0 -0
  109. package/omega/Agentik_Engine/omega_engine/__pycache__/validate.cpython-313.pyc +0 -0
  110. package/omega/Agentik_Engine/omega_engine/__pycache__/vault.cpython-313.pyc +0 -0
  111. package/omega/Agentik_Engine/omega_engine/__pycache__/webhooks.cpython-313.pyc +0 -0
  112. package/omega/Agentik_Engine/omega_engine/__pycache__/worker.cpython-313.pyc +0 -0
  113. package/omega/Agentik_Engine/omega_engine/account.py +28 -31
  114. package/omega/Agentik_Engine/omega_engine/agent_messages.py +167 -0
  115. package/omega/Agentik_Engine/omega_engine/aisb_chat.py +128 -0
  116. package/omega/Agentik_Engine/omega_engine/audit_diff.py +99 -0
  117. package/omega/Agentik_Engine/omega_engine/audit_gate.py +149 -0
  118. package/omega/Agentik_Engine/omega_engine/audits/__init__.py +60 -0
  119. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/__init__.cpython-313.pyc +0 -0
  120. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/batcher.cpython-313.pyc +0 -0
  121. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/dispatcher.cpython-313.pyc +0 -0
  122. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/generator.cpython-313.pyc +0 -0
  123. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/history.cpython-313.pyc +0 -0
  124. package/omega/Agentik_Engine/omega_engine/audits/__pycache__/pipeline.cpython-313.pyc +0 -0
  125. package/omega/Agentik_Engine/omega_engine/audits/batcher.py +218 -0
  126. package/omega/Agentik_Engine/omega_engine/audits/dispatcher.py +92 -0
  127. package/omega/Agentik_Engine/omega_engine/audits/generator.py +234 -0
  128. package/omega/Agentik_Engine/omega_engine/audits/history.py +168 -0
  129. package/omega/Agentik_Engine/omega_engine/audits/pipeline.py +198 -0
  130. package/omega/Agentik_Engine/omega_engine/auto_update.py +339 -0
  131. package/omega/Agentik_Engine/omega_engine/backup.py +215 -0
  132. package/omega/Agentik_Engine/omega_engine/cadence.py +158 -0
  133. package/omega/Agentik_Engine/omega_engine/classifier.py +215 -0
  134. package/omega/Agentik_Engine/omega_engine/cleanup.py +673 -0
  135. package/omega/Agentik_Engine/omega_engine/cli.py +4156 -86
  136. package/omega/Agentik_Engine/omega_engine/completions.py +260 -0
  137. package/omega/Agentik_Engine/omega_engine/costs.py +100 -0
  138. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/__init__.cpython-313.pyc +0 -0
  139. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/autonomous.cpython-313.pyc +0 -0
  140. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/engine.cpython-313.pyc +0 -0
  141. package/omega/Agentik_Engine/omega_engine/daemons/__pycache__/telegram.cpython-313.pyc +0 -0
  142. package/omega/Agentik_Engine/omega_engine/daemons/engine.py +53 -4
  143. package/omega/Agentik_Engine/omega_engine/daemons/telegram.py +101 -17
  144. package/omega/Agentik_Engine/omega_engine/done_signal.py +154 -0
  145. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/__init__.cpython-313.pyc +0 -0
  146. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/artifact.cpython-313.pyc +0 -0
  147. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/automation.cpython-313.pyc +0 -0
  148. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/base.cpython-313.pyc +0 -0
  149. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/claudecode.cpython-313.pyc +0 -0
  150. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/connection.cpython-313.pyc +0 -0
  151. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/coworker.cpython-313.pyc +0 -0
  152. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/loop.cpython-313.pyc +0 -0
  153. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/prompt.cpython-313.pyc +0 -0
  154. package/omega/Agentik_Engine/omega_engine/educators/__pycache__/skill.cpython-313.pyc +0 -0
  155. package/omega/Agentik_Engine/omega_engine/envelope.py +219 -0
  156. package/omega/Agentik_Engine/omega_engine/executor.py +149 -10
  157. package/omega/Agentik_Engine/omega_engine/genesis/__init__.py +134 -0
  158. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/__init__.cpython-313.pyc +0 -0
  159. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/orchestrator.cpython-313.pyc +0 -0
  160. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/phases.cpython-313.pyc +0 -0
  161. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/stack.cpython-313.pyc +0 -0
  162. package/omega/Agentik_Engine/omega_engine/genesis/__pycache__/state.cpython-313.pyc +0 -0
  163. package/omega/Agentik_Engine/omega_engine/genesis/orchestrator.py +262 -0
  164. package/omega/Agentik_Engine/omega_engine/genesis/phases.py +950 -0
  165. package/omega/Agentik_Engine/omega_engine/genesis/stack.py +324 -0
  166. package/omega/Agentik_Engine/omega_engine/genesis/state.py +353 -0
  167. package/omega/Agentik_Engine/omega_engine/handoff.py +459 -0
  168. package/omega/Agentik_Engine/omega_engine/hermes.py +426 -0
  169. package/omega/Agentik_Engine/omega_engine/hermes_bootstrap.py +382 -0
  170. package/omega/Agentik_Engine/omega_engine/hermes_desktop.py +469 -0
  171. package/omega/Agentik_Engine/omega_engine/integrations/__init__.py +30 -0
  172. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/__init__.cpython-313.pyc +0 -0
  173. package/omega/Agentik_Engine/omega_engine/integrations/__pycache__/graphify.cpython-313.pyc +0 -0
  174. package/omega/Agentik_Engine/omega_engine/integrations/graphify.py +234 -0
  175. package/omega/Agentik_Engine/omega_engine/learning.py +268 -0
  176. package/omega/Agentik_Engine/omega_engine/managed_agent.py +467 -0
  177. package/omega/Agentik_Engine/omega_engine/memory.py +271 -0
  178. package/omega/Agentik_Engine/omega_engine/menu.py +1065 -0
  179. package/omega/Agentik_Engine/omega_engine/migrations/__init__.py +144 -0
  180. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/__init__.cpython-313.pyc +0 -0
  181. package/omega/Agentik_Engine/omega_engine/migrations/__pycache__/v0_14_0.cpython-313.pyc +0 -0
  182. package/omega/Agentik_Engine/omega_engine/migrations/v0_14_0.py +29 -0
  183. package/omega/Agentik_Engine/omega_engine/mission.py +16 -13
  184. package/omega/Agentik_Engine/omega_engine/plan.py +846 -0
  185. package/omega/Agentik_Engine/omega_engine/prompts.py +158 -0
  186. package/omega/Agentik_Engine/omega_engine/provider.py +161 -12
  187. package/omega/Agentik_Engine/omega_engine/prune.py +151 -0
  188. package/omega/Agentik_Engine/omega_engine/pursue.py +205 -0
  189. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/__init__.cpython-313.pyc +0 -0
  190. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/agentic.cpython-313.pyc +0 -0
  191. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/base.cpython-313.pyc +0 -0
  192. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/corrective.cpython-313.pyc +0 -0
  193. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/graph.cpython-313.pyc +0 -0
  194. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/hybrid.cpython-313.pyc +0 -0
  195. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/multimodal.cpython-313.pyc +0 -0
  196. package/omega/Agentik_Engine/omega_engine/rag/__pycache__/router.cpython-313.pyc +0 -0
  197. package/omega/Agentik_Engine/omega_engine/router.py +28 -0
  198. package/omega/Agentik_Engine/omega_engine/skill_discovery/__init__.py +48 -0
  199. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/__init__.cpython-313.pyc +0 -0
  200. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/auditor.cpython-313.pyc +0 -0
  201. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/finder.cpython-313.pyc +0 -0
  202. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/installer.cpython-313.pyc +0 -0
  203. package/omega/Agentik_Engine/omega_engine/skill_discovery/__pycache__/marketplaces.cpython-313.pyc +0 -0
  204. package/omega/Agentik_Engine/omega_engine/skill_discovery/auditor.py +232 -0
  205. package/omega/Agentik_Engine/omega_engine/skill_discovery/finder.py +94 -0
  206. package/omega/Agentik_Engine/omega_engine/skill_discovery/installer.py +129 -0
  207. package/omega/Agentik_Engine/omega_engine/skill_discovery/marketplaces.py +80 -0
  208. package/omega/Agentik_Engine/omega_engine/skill_routing.py +388 -0
  209. package/omega/Agentik_Engine/omega_engine/smoke.py +81 -0
  210. package/omega/Agentik_Engine/omega_engine/store.py +88 -41
  211. package/omega/Agentik_Engine/omega_engine/sync.py +142 -1
  212. package/omega/Agentik_Engine/omega_engine/telegram_history.py +260 -0
  213. package/omega/Agentik_Engine/omega_engine/tmux.py +526 -0
  214. package/omega/Agentik_Engine/omega_engine/understand_anything.py +275 -0
  215. package/omega/Agentik_Engine/omega_engine/updater.py +70 -0
  216. package/omega/Agentik_Engine/omega_engine/validate.py +186 -0
  217. package/omega/Agentik_Engine/omega_engine/vault.py +342 -0
  218. package/omega/Agentik_Engine/omega_engine/webhooks.py +262 -0
  219. package/omega/Agentik_Engine/omega_engine/worker.py +526 -0
  220. package/omega/Agentik_Engine/pyproject.toml +1 -1
  221. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313-pytest-8.4.2.pyc +0 -0
  222. package/omega/Agentik_Engine/tests/__pycache__/test_account.cpython-313.pyc +0 -0
  223. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313-pytest-8.4.2.pyc +0 -0
  224. package/omega/Agentik_Engine/tests/__pycache__/test_adversarial.cpython-313.pyc +0 -0
  225. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313-pytest-8.4.2.pyc +0 -0
  226. package/omega/Agentik_Engine/tests/__pycache__/test_agents_envelope.cpython-313.pyc +0 -0
  227. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313-pytest-8.4.2.pyc +0 -0
  228. package/omega/Agentik_Engine/tests/__pycache__/test_audit_arsenal.cpython-313.pyc +0 -0
  229. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313-pytest-8.4.2.pyc +0 -0
  230. package/omega/Agentik_Engine/tests/__pycache__/test_audits_pipeline.cpython-313.pyc +0 -0
  231. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313-pytest-8.4.2.pyc +0 -0
  232. package/omega/Agentik_Engine/tests/__pycache__/test_auto_update_and_migrations.cpython-313.pyc +0 -0
  233. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313-pytest-8.4.2.pyc +0 -0
  234. package/omega/Agentik_Engine/tests/__pycache__/test_autonomous.cpython-313.pyc +0 -0
  235. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313-pytest-8.4.2.pyc +0 -0
  236. package/omega/Agentik_Engine/tests/__pycache__/test_educators.cpython-313.pyc +0 -0
  237. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313-pytest-8.4.2.pyc +0 -0
  238. package/omega/Agentik_Engine/tests/__pycache__/test_executor.cpython-313.pyc +0 -0
  239. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313-pytest-8.4.2.pyc +0 -0
  240. package/omega/Agentik_Engine/tests/__pycache__/test_genesis_and_plan.cpython-313.pyc +0 -0
  241. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313-pytest-8.4.2.pyc +0 -0
  242. package/omega/Agentik_Engine/tests/__pycache__/test_graphify.cpython-313.pyc +0 -0
  243. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313-pytest-8.4.2.pyc +0 -0
  244. package/omega/Agentik_Engine/tests/__pycache__/test_handoff.cpython-313.pyc +0 -0
  245. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313-pytest-8.4.2.pyc +0 -0
  246. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_and_ua.cpython-313.pyc +0 -0
  247. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313-pytest-8.4.2.pyc +0 -0
  248. package/omega/Agentik_Engine/tests/__pycache__/test_hermes_bootstrap_and_desktop.cpython-313.pyc +0 -0
  249. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313-pytest-8.4.2.pyc +0 -0
  250. package/omega/Agentik_Engine/tests/__pycache__/test_install_steps.cpython-313.pyc +0 -0
  251. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313-pytest-8.4.2.pyc +0 -0
  252. package/omega/Agentik_Engine/tests/__pycache__/test_install_ux.cpython-313.pyc +0 -0
  253. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313-pytest-8.4.2.pyc +0 -0
  254. package/omega/Agentik_Engine/tests/__pycache__/test_installer_wiring.cpython-313.pyc +0 -0
  255. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313-pytest-8.4.2.pyc +0 -0
  256. package/omega/Agentik_Engine/tests/__pycache__/test_intelligence.cpython-313.pyc +0 -0
  257. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313-pytest-8.4.2.pyc +0 -0
  258. package/omega/Agentik_Engine/tests/__pycache__/test_llm_clis_and_uninstall.cpython-313.pyc +0 -0
  259. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313-pytest-8.4.2.pyc +0 -0
  260. package/omega/Agentik_Engine/tests/__pycache__/test_managed_agent.cpython-313.pyc +0 -0
  261. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313-pytest-8.4.2.pyc +0 -0
  262. package/omega/Agentik_Engine/tests/__pycache__/test_max_provider_and_menu.cpython-313.pyc +0 -0
  263. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313-pytest-8.4.2.pyc +0 -0
  264. package/omega/Agentik_Engine/tests/__pycache__/test_menu_coverage.cpython-313.pyc +0 -0
  265. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313-pytest-8.4.2.pyc +0 -0
  266. package/omega/Agentik_Engine/tests/__pycache__/test_mission.cpython-313.pyc +0 -0
  267. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313-pytest-8.4.2.pyc +0 -0
  268. package/omega/Agentik_Engine/tests/__pycache__/test_progress.cpython-313.pyc +0 -0
  269. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313-pytest-8.4.2.pyc +0 -0
  270. package/omega/Agentik_Engine/tests/__pycache__/test_project.cpython-313.pyc +0 -0
  271. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313-pytest-8.4.2.pyc +0 -0
  272. package/omega/Agentik_Engine/tests/__pycache__/test_pursue_cadence.cpython-313.pyc +0 -0
  273. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313-pytest-8.4.2.pyc +0 -0
  274. package/omega/Agentik_Engine/tests/__pycache__/test_rag.cpython-313.pyc +0 -0
  275. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313-pytest-8.4.2.pyc +0 -0
  276. package/omega/Agentik_Engine/tests/__pycache__/test_reducer.cpython-313.pyc +0 -0
  277. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313-pytest-8.4.2.pyc +0 -0
  278. package/omega/Agentik_Engine/tests/__pycache__/test_report.cpython-313.pyc +0 -0
  279. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313-pytest-8.4.2.pyc +0 -0
  280. package/omega/Agentik_Engine/tests/__pycache__/test_role_aliases_and_ssot.cpython-313.pyc +0 -0
  281. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313-pytest-8.4.2.pyc +0 -0
  282. package/omega/Agentik_Engine/tests/__pycache__/test_skill_discovery_and_gate.cpython-313.pyc +0 -0
  283. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313-pytest-8.4.2.pyc +0 -0
  284. package/omega/Agentik_Engine/tests/__pycache__/test_skill_power.cpython-313.pyc +0 -0
  285. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313-pytest-8.4.2.pyc +0 -0
  286. package/omega/Agentik_Engine/tests/__pycache__/test_skill_routing.cpython-313.pyc +0 -0
  287. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313-pytest-8.4.2.pyc +0 -0
  288. package/omega/Agentik_Engine/tests/__pycache__/test_snapshot_partial.cpython-313.pyc +0 -0
  289. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313-pytest-8.4.2.pyc +0 -0
  290. package/omega/Agentik_Engine/tests/__pycache__/test_telegram_history.cpython-313.pyc +0 -0
  291. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313-pytest-8.4.2.pyc +0 -0
  292. package/omega/Agentik_Engine/tests/__pycache__/test_tmux_and_aisb_chat.cpython-313.pyc +0 -0
  293. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313-pytest-8.4.2.pyc +0 -0
  294. package/omega/Agentik_Engine/tests/__pycache__/test_tools_and_sync.cpython-313.pyc +0 -0
  295. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313-pytest-8.4.2.pyc +0 -0
  296. package/omega/Agentik_Engine/tests/__pycache__/test_v06_features.cpython-313.pyc +0 -0
  297. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313-pytest-8.4.2.pyc +0 -0
  298. package/omega/Agentik_Engine/tests/__pycache__/test_vault.cpython-313.pyc +0 -0
  299. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313-pytest-8.4.2.pyc +0 -0
  300. package/omega/Agentik_Engine/tests/__pycache__/test_webhooks_and_readiness.cpython-313.pyc +0 -0
  301. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313-pytest-8.4.2.pyc +0 -0
  302. package/omega/Agentik_Engine/tests/__pycache__/test_worker_and_cleanup.cpython-313.pyc +0 -0
  303. package/omega/Agentik_Engine/tests/test_account.py +8 -3
  304. package/omega/Agentik_Engine/tests/test_adversarial.py +351 -0
  305. package/omega/Agentik_Engine/tests/test_agents_envelope.py +274 -0
  306. package/omega/Agentik_Engine/tests/test_audits_pipeline.py +348 -0
  307. package/omega/Agentik_Engine/tests/test_auto_update_and_migrations.py +394 -0
  308. package/omega/Agentik_Engine/tests/test_genesis_and_plan.py +573 -0
  309. package/omega/Agentik_Engine/tests/test_graphify.py +190 -0
  310. package/omega/Agentik_Engine/tests/test_handoff.py +311 -0
  311. package/omega/Agentik_Engine/tests/test_hermes_and_ua.py +387 -0
  312. package/omega/Agentik_Engine/tests/test_hermes_bootstrap_and_desktop.py +358 -0
  313. package/omega/Agentik_Engine/tests/test_install_steps.py +359 -0
  314. package/omega/Agentik_Engine/tests/test_install_ux.py +151 -0
  315. package/omega/Agentik_Engine/tests/test_installer_wiring.py +496 -0
  316. package/omega/Agentik_Engine/tests/test_intelligence.py +285 -0
  317. package/omega/Agentik_Engine/tests/test_llm_clis_and_uninstall.py +228 -0
  318. package/omega/Agentik_Engine/tests/test_managed_agent.py +363 -0
  319. package/omega/Agentik_Engine/tests/test_max_provider_and_menu.py +231 -0
  320. package/omega/Agentik_Engine/tests/test_menu_coverage.py +72 -0
  321. package/omega/Agentik_Engine/tests/test_pursue_cadence.py +217 -0
  322. package/omega/Agentik_Engine/tests/test_role_aliases_and_ssot.py +207 -0
  323. package/omega/Agentik_Engine/tests/test_skill_discovery_and_gate.py +337 -0
  324. package/omega/Agentik_Engine/tests/test_skill_power.py +259 -0
  325. package/omega/Agentik_Engine/tests/test_skill_routing.py +189 -0
  326. package/omega/Agentik_Engine/tests/test_telegram_history.py +209 -0
  327. package/omega/Agentik_Engine/tests/test_tmux_and_aisb_chat.py +223 -0
  328. package/omega/Agentik_Engine/tests/test_v06_features.py +370 -0
  329. package/omega/Agentik_Engine/tests/test_vault.py +173 -0
  330. package/omega/Agentik_Engine/tests/test_webhooks_and_readiness.py +277 -0
  331. package/omega/Agentik_Engine/tests/test_worker_and_cleanup.py +541 -0
  332. package/omega/Agentik_Extra/etc/secrets/.vault-key +3 -0
  333. package/omega/Agentik_Extra/etc/secrets/.vault-pub +1 -0
  334. package/omega/Agentik_Runtime/audits.db +0 -0
  335. package/omega/Agentik_SSOT/VERSION +1 -1
  336. package/omega/Agentik_SSOT/claude-plugins/claude-plugins.yaml +100 -0
  337. package/omega/Agentik_SSOT/docs/LAYERS.md +90 -0
  338. package/omega/Agentik_SSOT/docs/USER-JOURNEY.md +283 -0
  339. package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-INTERCONNECTIONS.md +283 -0
  340. package/omega/Agentik_SSOT/docs/quality-arsenal/ARSENAL-ORCHESTRATION-PLAYBOOK.md +364 -0
  341. package/omega/Agentik_SSOT/docs/quality-arsenal/AUDIT-VERIFICATION-CONTRACT.md +272 -0
  342. package/omega/Agentik_SSOT/docs/quality-arsenal/QUALITY-ARSENAL-PREAMBLE.md +462 -0
  343. package/omega/Agentik_SSOT/marketplaces/design-discipline.yaml +86 -0
  344. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  345. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  346. package/omega/Agentik_SSOT/skills/audit-orchestrator.md +212 -0
  347. package/omega/Agentik_SSOT/skills/audit-pilot.md +466 -0
  348. package/omega/Agentik_SSOT/skills/audit-tracker.md +147 -0
  349. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  350. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  351. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  352. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  353. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  354. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  355. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  356. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  357. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  358. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  359. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  360. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  361. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  362. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  363. package/omega/Agentik_SSOT/skills/newcmd.md +300 -0
  364. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  365. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  366. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  367. package/omega/Agentik_SSOT/skills/quality-arsenal.md +180 -0
  368. package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
  369. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  370. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  371. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  372. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  373. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  374. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  375. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  376. package/package.json +2 -2
@@ -0,0 +1,190 @@
1
+ """Tests for the graphify integration.
2
+
3
+ Reality check: `graphify` is a Claude Code SKILL. The CLI (`graphifyy` on
4
+ PyPI) only manages the skill (`install`, `uninstall`) and queries an
5
+ existing graph (`path`, `explain`, `diagnose`). The graph itself is built
6
+ inside Claude Code by typing `/graphify .`.
7
+
8
+ So this test suite verifies:
9
+
10
+ 1. `is_graphify_installed()` correctly reflects PATH state.
11
+ 2. `graphify_install_skill()` calls the CLI with `install --platform <p>`
12
+ and surfaces failures.
13
+ 3. `graphify_load_graph(target)` reads an existing
14
+ `<target>/graphify-out/graph.json` and parses nodes/edges/summary.
15
+ 4. Missing graph.json raises the dedicated `GraphifyGraphMissing` error
16
+ with a helpful message.
17
+ 5. `graphify_into_rag(report, GraphRetriever)` merges into a real
18
+ retriever and the merged nodes are queryable.
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ import subprocess
24
+ import sys
25
+ import tempfile
26
+ import unittest
27
+ from pathlib import Path
28
+ from unittest import mock
29
+
30
+
31
+ HERE = Path(__file__).resolve().parent
32
+ sys.path.insert(0, str(HERE.parent)) # Agentik_Engine/
33
+
34
+ from omega_engine.integrations import ( # noqa: E402
35
+ GraphifyError,
36
+ GraphifyGraphMissing,
37
+ GraphifyNotInstalled,
38
+ GraphifyReport,
39
+ graphify_install_skill,
40
+ graphify_into_rag,
41
+ graphify_load_graph,
42
+ is_graphify_installed,
43
+ )
44
+ from omega_engine.rag import GraphRetriever # noqa: E402
45
+
46
+
47
+ def _write_graph(dir: Path, payload: dict) -> Path:
48
+ out = dir / "graphify-out"
49
+ out.mkdir(parents=True, exist_ok=True)
50
+ p = out / "graph.json"
51
+ p.write_text(json.dumps(payload))
52
+ return p
53
+
54
+
55
+ class TestGraphifyDetection(unittest.TestCase):
56
+ def test_not_installed_returns_false(self):
57
+ with mock.patch("shutil.which", return_value=None):
58
+ self.assertFalse(is_graphify_installed())
59
+
60
+ def test_install_skill_raises_when_not_installed(self):
61
+ with mock.patch("shutil.which", return_value=None):
62
+ with self.assertRaises(GraphifyNotInstalled):
63
+ graphify_install_skill()
64
+
65
+
66
+ class TestGraphifyInstallSkill(unittest.TestCase):
67
+ def test_install_invokes_graphify_install_with_platform(self):
68
+ captured = {}
69
+
70
+ def _run(argv, *args, **kwargs):
71
+ captured["argv"] = list(argv)
72
+ return subprocess.CompletedProcess(
73
+ argv, returncode=0,
74
+ stdout="installed skill at ~/.claude/skills/graphify/",
75
+ stderr="",
76
+ )
77
+
78
+ with mock.patch("shutil.which", return_value="/fake/graphify"), \
79
+ mock.patch(
80
+ "omega_engine.integrations.graphify.subprocess.run",
81
+ side_effect=_run,
82
+ ):
83
+ result = graphify_install_skill(platform="claude")
84
+
85
+ self.assertEqual(captured["argv"][0], "graphify")
86
+ self.assertEqual(captured["argv"][1], "install")
87
+ self.assertIn("--platform", captured["argv"])
88
+ self.assertIn("claude", captured["argv"])
89
+ self.assertEqual(result["platform"], "claude")
90
+ self.assertIn("installed skill", result["stdout"])
91
+
92
+ def test_install_failure_raises(self):
93
+ with mock.patch("shutil.which", return_value="/fake/graphify"), \
94
+ mock.patch(
95
+ "omega_engine.integrations.graphify.subprocess.run",
96
+ return_value=subprocess.CompletedProcess(
97
+ ["graphify"], returncode=2, stdout="", stderr="nope",
98
+ ),
99
+ ):
100
+ with self.assertRaises(GraphifyError) as ctx:
101
+ graphify_install_skill()
102
+ self.assertIn("nope", str(ctx.exception))
103
+
104
+
105
+ class TestGraphifyLoadGraph(unittest.TestCase):
106
+ def test_loads_existing_graph_json(self):
107
+ payload = {
108
+ "version": "1.0",
109
+ "mode": "deep",
110
+ "nodes": [
111
+ {"id": "auth.py", "kind": "module"},
112
+ {"id": "login", "kind": "function"},
113
+ ],
114
+ "edges": [
115
+ {"source": "auth.py", "target": "login", "kind": "defines"},
116
+ ],
117
+ }
118
+ with tempfile.TemporaryDirectory() as td:
119
+ repo = Path(td) / "repo"
120
+ repo.mkdir()
121
+ _write_graph(repo, payload)
122
+
123
+ report = graphify_load_graph(repo)
124
+
125
+ self.assertIsInstance(report, GraphifyReport)
126
+ self.assertEqual(len(report.nodes), 2)
127
+ self.assertEqual(len(report.edges), 1)
128
+ self.assertEqual(report.summary.get("version"), "1.0")
129
+ self.assertEqual(report.summary.get("mode"), "deep")
130
+ self.assertTrue(report.json_path.exists())
131
+
132
+ def test_missing_graph_raises_friendly_error(self):
133
+ with tempfile.TemporaryDirectory() as td:
134
+ repo = Path(td) / "repo"
135
+ repo.mkdir()
136
+ with self.assertRaises(GraphifyGraphMissing) as ctx:
137
+ graphify_load_graph(repo)
138
+ msg = str(ctx.exception)
139
+ self.assertIn("graph.json", msg)
140
+ self.assertIn("/graphify", msg)
141
+
142
+ def test_custom_json_path_overrides_default(self):
143
+ with tempfile.TemporaryDirectory() as td:
144
+ custom = Path(td) / "weird-location" / "g.json"
145
+ custom.parent.mkdir(parents=True)
146
+ custom.write_text(json.dumps({"nodes": [], "edges": []}))
147
+
148
+ report = graphify_load_graph("/does/not/exist", json_path=custom)
149
+ self.assertEqual(report.json_path, custom)
150
+
151
+ def test_unparsable_json_raises(self):
152
+ with tempfile.TemporaryDirectory() as td:
153
+ repo = Path(td) / "repo"
154
+ repo.mkdir()
155
+ out = repo / "graphify-out"
156
+ out.mkdir()
157
+ (out / "graph.json").write_text("{not valid json")
158
+ with self.assertRaises(GraphifyError):
159
+ graphify_load_graph(repo)
160
+
161
+
162
+ class TestGraphifyIntoRag(unittest.TestCase):
163
+ def test_merges_into_graph_retriever(self):
164
+ report = GraphifyReport(
165
+ output_dir=Path("/tmp/unused"),
166
+ nodes=[
167
+ {"id": "auth.py", "name": "auth.py", "kind": "module"},
168
+ {"id": "login", "name": "login", "kind": "function"},
169
+ {"id": "session", "name": "session", "kind": "class"},
170
+ {"name": "bare_name"}, # only `name` — falls back to that
171
+ ],
172
+ edges=[
173
+ {"source": "auth.py", "target": "login", "kind": "defines"},
174
+ {"source": "login", "target": "session", "kind": "uses"},
175
+ {"target": "session"}, # malformed — should be dropped
176
+ ],
177
+ )
178
+ with tempfile.TemporaryDirectory() as td:
179
+ graph = GraphRetriever(json_path=Path(td) / "g.json")
180
+ counts = graphify_into_rag(report, graph)
181
+
182
+ self.assertEqual(counts["nodes"], 4)
183
+ self.assertEqual(counts["edges"], 2) # malformed edge dropped
184
+ node_set = set(graph.nodes())
185
+ self.assertIn("login", node_set)
186
+ self.assertIn("session", node_set)
187
+
188
+
189
+ if __name__ == "__main__":
190
+ unittest.main(verbosity=2)
@@ -0,0 +1,311 @@
1
+ """Tests for omega_engine.handoff — 5-section session-end memo.
2
+
3
+ Covers: dataclass round-trip (json + markdown), atomic write, project +
4
+ task target resolution, archive accumulation, from_done_signal draft.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ import os
10
+ import subprocess
11
+ import sys
12
+ import tempfile
13
+ import time
14
+ import unittest
15
+ from pathlib import Path
16
+
17
+
18
+ HERE = Path(__file__).resolve().parent
19
+ sys.path.insert(0, str(HERE.parent))
20
+
21
+ from omega_engine import handoff as H # noqa: E402
22
+ from omega_engine.done_signal import DoneSignal, write_done # noqa: E402
23
+ from omega_engine.worker import WorkerBrief, write_brief # noqa: E402
24
+
25
+
26
+ def _fresh_handoff() -> H.Handoff:
27
+ return H.Handoff(
28
+ mission="Implement OAuth login + green tests/auth.test.ts",
29
+ state=(
30
+ "- Works: sign-in redirects to /dashboard, screenshot at "
31
+ "audits/.flow/auth.png\n"
32
+ "- Broken: /api/profile PATCH returns 500 — TypeError line 142\n"
33
+ "- Verified by: `npm test -- tests/auth.test.ts`"
34
+ ),
35
+ files_touched=[
36
+ "apps/web/src/routes/api/auth/google.ts",
37
+ "apps/web/src/components/SignInForm.tsx:42-78",
38
+ "tests/auth.test.ts",
39
+ ],
40
+ dead_ends=[
41
+ "Tried Authorization header for /userinfo — got 401. Don't.",
42
+ "Tried next-auth v5 beta — incompatible with Next 14. Don't.",
43
+ ],
44
+ next_steps=[
45
+ "Add NEXTAUTH_SECRET to .env.local",
46
+ "Wire the new endpoint into [...nextauth]/route.ts",
47
+ "Re-run `npm test -- tests/auth.test.ts`",
48
+ ],
49
+ author="worker:t-oauth-123",
50
+ project="myapp",
51
+ task_id="t-oauth-123",
52
+ mission_id="m-oauth",
53
+ )
54
+
55
+
56
+ # ---------------------------------------------------------------------------
57
+ # Dataclass round-trips
58
+ # ---------------------------------------------------------------------------
59
+
60
+
61
+ class TestRoundTrip(unittest.TestCase):
62
+ def test_to_json_and_back(self):
63
+ ho = _fresh_handoff()
64
+ loaded = H.Handoff.from_dict(json.loads(ho.to_json()))
65
+ self.assertEqual(loaded.mission, ho.mission)
66
+ self.assertEqual(loaded.files_touched, ho.files_touched)
67
+ self.assertEqual(loaded.dead_ends, ho.dead_ends)
68
+ self.assertEqual(loaded.next_steps, ho.next_steps)
69
+ self.assertEqual(loaded.project, ho.project)
70
+
71
+ def test_markdown_has_five_sections(self):
72
+ md = _fresh_handoff().to_markdown()
73
+ for n in range(1, 6):
74
+ self.assertIn(f"## {n}.", md, f"missing section {n}")
75
+
76
+ def test_markdown_parse_back(self):
77
+ ho = _fresh_handoff()
78
+ md = ho.to_markdown()
79
+ parsed = H.Handoff.from_markdown(md)
80
+ self.assertEqual(parsed.mission, ho.mission)
81
+ self.assertEqual(parsed.files_touched, ho.files_touched)
82
+ self.assertEqual(parsed.dead_ends, ho.dead_ends)
83
+ self.assertEqual(parsed.next_steps, ho.next_steps)
84
+
85
+ def test_empty_sections_round_trip(self):
86
+ ho = H.Handoff(
87
+ mission="quick fix",
88
+ state="",
89
+ files_touched=[],
90
+ dead_ends=[],
91
+ next_steps=[],
92
+ project="x",
93
+ )
94
+ md = ho.to_markdown()
95
+ parsed = H.Handoff.from_markdown(md)
96
+ self.assertEqual(parsed.files_touched, [])
97
+ self.assertEqual(parsed.dead_ends, [])
98
+ self.assertEqual(parsed.next_steps, [])
99
+
100
+
101
+ # ---------------------------------------------------------------------------
102
+ # write_handoff — project / task / both targets
103
+ # ---------------------------------------------------------------------------
104
+
105
+
106
+ class TestWriteHandoff(unittest.TestCase):
107
+ def test_project_target_writes_latest_and_archive(self):
108
+ with tempfile.TemporaryDirectory() as tmp:
109
+ home = Path(tmp)
110
+ ho = _fresh_handoff()
111
+ res = H.write_handoff(home, ho, target="project")
112
+ self.assertEqual(len(res["written"]), 2)
113
+ latest = H.project_latest_path(home, "myapp")
114
+ self.assertTrue(latest.exists())
115
+ self.assertIn("## 1. Mission", latest.read_text())
116
+ # Archive copy
117
+ archive_dir = H.project_handoff_dir(home, "myapp")
118
+ archived = list(archive_dir.glob("*.md"))
119
+ self.assertEqual(len(archived), 1)
120
+
121
+ def test_task_target_writes_session_dir(self):
122
+ with tempfile.TemporaryDirectory() as tmp:
123
+ home = Path(tmp)
124
+ ho = _fresh_handoff()
125
+ res = H.write_handoff(home, ho, target="task")
126
+ self.assertEqual(len(res["written"]), 1)
127
+ p = H.task_handoff_path(home, "t-oauth-123")
128
+ self.assertTrue(p.exists())
129
+ self.assertIn("Mission", p.read_text())
130
+
131
+ def test_both_target_writes_three_paths(self):
132
+ with tempfile.TemporaryDirectory() as tmp:
133
+ home = Path(tmp)
134
+ ho = _fresh_handoff()
135
+ res = H.write_handoff(home, ho, target="both")
136
+ self.assertEqual(len(res["written"]), 3)
137
+ self.assertTrue(H.project_latest_path(home, "myapp").exists())
138
+ self.assertTrue(H.task_handoff_path(home, "t-oauth-123").exists())
139
+
140
+ def test_project_target_requires_project(self):
141
+ with tempfile.TemporaryDirectory() as tmp:
142
+ home = Path(tmp)
143
+ ho = H.Handoff(mission="x", state="", files_touched=[],
144
+ dead_ends=[], next_steps=[])
145
+ with self.assertRaises(ValueError):
146
+ H.write_handoff(home, ho, target="project")
147
+
148
+ def test_task_target_requires_task_id(self):
149
+ with tempfile.TemporaryDirectory() as tmp:
150
+ home = Path(tmp)
151
+ ho = H.Handoff(mission="x", state="", files_touched=[],
152
+ dead_ends=[], next_steps=[], project="x")
153
+ with self.assertRaises(ValueError):
154
+ H.write_handoff(home, ho, target="task")
155
+
156
+ def test_archive_accumulates_across_writes(self):
157
+ """Each write_handoff adds a new archive file; latest is overwritten."""
158
+ with tempfile.TemporaryDirectory() as tmp:
159
+ home = Path(tmp)
160
+ ho1 = _fresh_handoff()
161
+ ho1.created_at = "2026-05-23T10:00:00+00:00"
162
+ H.write_handoff(home, ho1, target="project")
163
+ ho2 = _fresh_handoff()
164
+ ho2.created_at = "2026-05-23T11:00:00+00:00"
165
+ ho2.mission = "Second pass on the auth bug"
166
+ H.write_handoff(home, ho2, target="project")
167
+ archived = sorted(H.project_handoff_dir(home, "myapp").glob("*.md"))
168
+ self.assertEqual(len(archived), 2)
169
+ # Latest has the most recent content
170
+ latest_text = H.project_latest_path(home, "myapp").read_text()
171
+ self.assertIn("Second pass", latest_text)
172
+
173
+
174
+ # ---------------------------------------------------------------------------
175
+ # read_handoff + list_handoffs
176
+ # ---------------------------------------------------------------------------
177
+
178
+
179
+ class TestReadAndList(unittest.TestCase):
180
+ def test_read_returns_none_when_missing(self):
181
+ with tempfile.TemporaryDirectory() as tmp:
182
+ self.assertIsNone(H.read_handoff(Path(tmp), project="nope"))
183
+ self.assertIsNone(H.read_handoff(Path(tmp), task_id="nope"))
184
+
185
+ def test_read_project_after_write(self):
186
+ with tempfile.TemporaryDirectory() as tmp:
187
+ home = Path(tmp)
188
+ ho = _fresh_handoff()
189
+ H.write_handoff(home, ho, target="project")
190
+ loaded = H.read_handoff(home, project="myapp")
191
+ self.assertIsNotNone(loaded)
192
+ self.assertEqual(loaded.mission, ho.mission)
193
+ self.assertEqual(loaded.files_touched, ho.files_touched)
194
+
195
+ def test_list_chronological_newest_first(self):
196
+ with tempfile.TemporaryDirectory() as tmp:
197
+ home = Path(tmp)
198
+ for ts, mission in [
199
+ ("2026-05-23T10:00:00+00:00", "older mission"),
200
+ ("2026-05-23T11:00:00+00:00", "middle mission"),
201
+ ("2026-05-23T12:00:00+00:00", "latest mission"),
202
+ ]:
203
+ ho = _fresh_handoff()
204
+ ho.created_at = ts
205
+ ho.mission = mission
206
+ H.write_handoff(home, ho, target="project")
207
+ rows = H.list_handoffs(home, "myapp")
208
+ self.assertEqual(len(rows), 3)
209
+ # The archive filename starts with the timestamp; sorted reverse
210
+ # therefore puts newest first.
211
+ self.assertIn("latest", rows[0]["mission"])
212
+
213
+ def test_read_requires_project_or_task_id(self):
214
+ with tempfile.TemporaryDirectory() as tmp:
215
+ with self.assertRaises(ValueError):
216
+ H.read_handoff(Path(tmp))
217
+
218
+
219
+ # ---------------------------------------------------------------------------
220
+ # from_done_signal — auto-draft
221
+ # ---------------------------------------------------------------------------
222
+
223
+
224
+ class TestFromDoneSignal(unittest.TestCase):
225
+ def test_draft_pulls_summary_and_files(self):
226
+ with tempfile.TemporaryDirectory() as tmp:
227
+ home = Path(tmp)
228
+ # Seed a brief + a .done.json
229
+ brief = WorkerBrief(
230
+ task_id="t-draft", role="worker",
231
+ intent="Add OAuth login",
232
+ )
233
+ write_brief(home, brief)
234
+ sig = DoneSignal(
235
+ status="done_clean",
236
+ summary="OAuth endpoint added; tests green",
237
+ files_changed=["apps/web/src/auth/google.ts"],
238
+ )
239
+ write_done(home, "t-draft", sig)
240
+ draft = H.from_done_signal(home, "t-draft")
241
+ self.assertIn("OAuth", draft.mission)
242
+ self.assertIn("OAuth", draft.state)
243
+ self.assertIn("apps/web/src/auth/google.ts", draft.files_touched)
244
+ self.assertEqual(draft.task_id, "t-draft")
245
+
246
+ def test_draft_for_pending_status_seeds_next_steps(self):
247
+ with tempfile.TemporaryDirectory() as tmp:
248
+ home = Path(tmp)
249
+ brief = WorkerBrief(task_id="t-pending", role="worker",
250
+ intent="Finish the auth bug")
251
+ write_brief(home, brief)
252
+ sig = DoneSignal(
253
+ status="pending",
254
+ summary="Most of the bug fixed; one edge case remains",
255
+ files_changed=["auth.ts"],
256
+ pending_actions=["handle expired refresh_token edge case",
257
+ "add test for the edge case"],
258
+ )
259
+ write_done(home, "t-pending", sig)
260
+ draft = H.from_done_signal(home, "t-pending")
261
+ self.assertEqual(len(draft.next_steps), 2)
262
+ self.assertIn("refresh_token", draft.next_steps[0])
263
+
264
+ def test_draft_when_no_done_or_brief(self):
265
+ with tempfile.TemporaryDirectory() as tmp:
266
+ home = Path(tmp)
267
+ # No brief, no done — still returns a Handoff with the task_id.
268
+ draft = H.from_done_signal(home, "t-missing")
269
+ self.assertIn("t-missing", draft.mission)
270
+ self.assertEqual(draft.task_id, "t-missing")
271
+
272
+ def test_git_diff_augments_files(self):
273
+ """When --cwd points at a git repo with uncommitted edits, files_touched
274
+ is enriched with `git diff --name-only HEAD`."""
275
+ with tempfile.TemporaryDirectory() as tmp:
276
+ home = Path(tmp)
277
+ # Mini git repo
278
+ repo = Path(tmp) / "repo"
279
+ repo.mkdir()
280
+ subprocess.run(["git", "init", "-q"], cwd=repo, check=True, timeout=10)
281
+ subprocess.run(["git", "config", "user.email", "t@t.com"],
282
+ cwd=repo, check=True, timeout=5)
283
+ subprocess.run(["git", "config", "user.name", "t"],
284
+ cwd=repo, check=True, timeout=5)
285
+ (repo / "a.py").write_text("# initial\n")
286
+ subprocess.run(["git", "add", "."], cwd=repo, check=True, timeout=5)
287
+ subprocess.run(["git", "commit", "-q", "-m", "init"],
288
+ cwd=repo, check=True, timeout=10)
289
+ # Edit + add a new file
290
+ (repo / "a.py").write_text("# edited\n")
291
+ (repo / "b.py").write_text("# new\n")
292
+ subprocess.run(["git", "add", "b.py"], cwd=repo, check=True, timeout=5)
293
+ # No .done.json — draft built only from git
294
+ draft = H.from_done_signal(home, "t-git", cwd=repo)
295
+ self.assertIn("a.py", draft.files_touched)
296
+ self.assertIn("b.py", draft.files_touched)
297
+
298
+
299
+ # ---------------------------------------------------------------------------
300
+ # Template / CLI shape (smoke)
301
+ # ---------------------------------------------------------------------------
302
+
303
+
304
+ class TestTemplate(unittest.TestCase):
305
+ def test_template_has_five_sections(self):
306
+ for n in range(1, 6):
307
+ self.assertIn(f"## {n}.", H.TEMPLATE)
308
+
309
+
310
+ if __name__ == "__main__":
311
+ unittest.main()