@agentikos/omega-os 0.2.0 → 0.19.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) 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/marketplaces/design-discipline.yaml +86 -0
  340. package/omega/Agentik_SSOT/skills/a11yaudit/SKILL.md +161 -0
  341. package/omega/Agentik_SSOT/skills/apiaudit/SKILL.md +157 -0
  342. package/omega/Agentik_SSOT/skills/automationaudit/SKILL.md +161 -0
  343. package/omega/Agentik_SSOT/skills/cadence/SKILL.md +76 -0
  344. package/omega/Agentik_SSOT/skills/codeaudit/SKILL.md +153 -0
  345. package/omega/Agentik_SSOT/skills/copyaudit/SKILL.md +161 -0
  346. package/omega/Agentik_SSOT/skills/dataaudit/SKILL.md +157 -0
  347. package/omega/Agentik_SSOT/skills/debugaudit/SKILL.md +161 -0
  348. package/omega/Agentik_SSOT/skills/dispatch/SKILL.md +79 -0
  349. package/omega/Agentik_SSOT/skills/dxaudit/SKILL.md +161 -0
  350. package/omega/Agentik_SSOT/skills/featureaudit/SKILL.md +161 -0
  351. package/omega/Agentik_SSOT/skills/flowaudit/SKILL.md +165 -0
  352. package/omega/Agentik_SSOT/skills/genesis/SKILL.md +116 -0
  353. package/omega/Agentik_SSOT/skills/handoff/SKILL.md +117 -0
  354. package/omega/Agentik_SSOT/skills/logicaudit/SKILL.md +165 -0
  355. package/omega/Agentik_SSOT/skills/motionaudit/SKILL.md +165 -0
  356. package/omega/Agentik_SSOT/skills/perfaudit/SKILL.md +161 -0
  357. package/omega/Agentik_SSOT/skills/plan/SKILL.md +127 -0
  358. package/omega/Agentik_SSOT/skills/pursue/SKILL.md +68 -0
  359. package/omega/Agentik_SSOT/skills/rag-route.md +9 -0
  360. package/omega/Agentik_SSOT/skills/refontaudit/SKILL.md +165 -0
  361. package/omega/Agentik_SSOT/skills/retentionaudit/SKILL.md +165 -0
  362. package/omega/Agentik_SSOT/skills/secaudit/SKILL.md +157 -0
  363. package/omega/Agentik_SSOT/skills/seoaudit/SKILL.md +161 -0
  364. package/omega/Agentik_SSOT/skills/skill-auditor/SKILL.md +83 -0
  365. package/omega/Agentik_SSOT/skills/skill-finder/SKILL.md +116 -0
  366. package/omega/Agentik_SSOT/skills/uiuxaudit/SKILL.md +165 -0
  367. package/package.json +2 -2
@@ -0,0 +1,459 @@
1
+ """Handoff — structured session-end memo so the next agent picks up cleanly.
2
+
3
+ The 5-section contract
4
+ ----------------------
5
+
6
+ Every handoff has EXACTLY these five sections, in this order:
7
+
8
+ 1. **Mission** — one-sentence statement of what the session was trying
9
+ to achieve.
10
+ 2. **State** — what works, what doesn't (concrete, observed runtime).
11
+ 3. **Files touched** — exact paths (no guessing) + the relevant
12
+ line numbers when applicable.
13
+ 4. **Dead ends** — what was tried and DOESN'T work, so the next agent
14
+ doesn't re-walk the same wall.
15
+ 5. **Next** — the first concrete action for the next session.
16
+
17
+ Why this exists
18
+ ---------------
19
+
20
+ When an agent does ``/clear`` or its session times out, the next agent
21
+ re-discovers everything from scratch — re-reads files, re-runs commands,
22
+ re-makes the same mistakes. The handoff IS the institutional memory
23
+ between sessions. It's not optional documentation; it's a load-bearing
24
+ piece of the agentic OS.
25
+
26
+ Storage
27
+ -------
28
+
29
+ ::
30
+
31
+ $OMEGA_HOME/
32
+ Agentik_Coding/projects/<slug>/
33
+ HANDOFF.md ← always-latest (overwritten)
34
+ .omega/handoffs/<iso-ts>-<short>.md ← timestamped archive
35
+
36
+ $OMEGA_HOME/Agentik_Runtime/sessions/<task_id>/
37
+ handoff.md ← per-task (auto-generated
38
+ from .done.json + git
39
+ when a worker finishes)
40
+
41
+ The same dataclass + writer power all three; only the path resolution
42
+ differs.
43
+ """
44
+ from __future__ import annotations
45
+
46
+ import json
47
+ import os
48
+ import re
49
+ import shutil
50
+ import subprocess
51
+ import time
52
+ from dataclasses import asdict, dataclass, field
53
+ from datetime import datetime, timezone
54
+ from pathlib import Path
55
+ from typing import Any
56
+
57
+
58
+ # ---------------------------------------------------------------------------
59
+ # Dataclass
60
+ # ---------------------------------------------------------------------------
61
+
62
+
63
+ @dataclass
64
+ class Handoff:
65
+ mission: str # one-sentence statement
66
+ state: str # markdown body — works vs broken
67
+ files_touched: list[str] # exact paths
68
+ dead_ends: list[str] # short bullets, what NOT to retry
69
+ next_steps: list[str] # first action(s) for next session
70
+ author: str = "" # "worker" | "oracle" | "human" | ...
71
+ task_id: str = "" # optional anchor
72
+ mission_id: str = "" # optional anchor
73
+ project: str = "" # project slug if any
74
+ created_at: str = field(
75
+ default_factory=lambda: datetime.now(timezone.utc).isoformat(
76
+ timespec="seconds"
77
+ )
78
+ )
79
+
80
+ def to_markdown(self) -> str:
81
+ """Render the canonical 5-section markdown."""
82
+ files = "\n".join(f"- `{p}`" for p in self.files_touched) or "_(none)_"
83
+ dead = "\n".join(f"- {d}" for d in self.dead_ends) or "_(none)_"
84
+ nxt = "\n".join(f"{i+1}. {step}"
85
+ for i, step in enumerate(self.next_steps)) \
86
+ or "_(none)_"
87
+ anchors: list[str] = []
88
+ if self.project: anchors.append(f"project=`{self.project}`")
89
+ if self.mission_id: anchors.append(f"mission=`{self.mission_id}`")
90
+ if self.task_id: anchors.append(f"task=`{self.task_id}`")
91
+ if self.author: anchors.append(f"author=`{self.author}`")
92
+ meta = " · ".join(anchors)
93
+ return f"""\
94
+ # Handoff — {self.created_at}
95
+
96
+ {meta}
97
+
98
+ ## 1. Mission
99
+
100
+ {self.mission.strip()}
101
+
102
+ ## 2. State (what works / what doesn't)
103
+
104
+ {self.state.strip() if self.state.strip() else "_(no state captured)_"}
105
+
106
+ ## 3. Files touched
107
+
108
+ {files}
109
+
110
+ ## 4. Dead ends — DO NOT retry
111
+
112
+ {dead}
113
+
114
+ ## 5. Next — start here
115
+
116
+ {nxt}
117
+ """
118
+
119
+ def to_json(self) -> str:
120
+ return json.dumps(asdict(self), indent=2)
121
+
122
+ @staticmethod
123
+ def from_dict(d: dict[str, Any]) -> "Handoff":
124
+ return Handoff(
125
+ mission=str(d.get("mission", "")),
126
+ state=str(d.get("state", "")),
127
+ files_touched=list(d.get("files_touched") or []),
128
+ dead_ends=list(d.get("dead_ends") or []),
129
+ next_steps=list(d.get("next_steps") or []),
130
+ author=str(d.get("author", "")),
131
+ task_id=str(d.get("task_id", "")),
132
+ mission_id=str(d.get("mission_id", "")),
133
+ project=str(d.get("project", "")),
134
+ created_at=str(
135
+ d.get("created_at",
136
+ datetime.now(timezone.utc).isoformat(timespec="seconds"))
137
+ ),
138
+ )
139
+
140
+ @staticmethod
141
+ def from_markdown(text: str) -> "Handoff":
142
+ """Best-effort parse — reads back a handoff written by to_markdown.
143
+
144
+ Tolerant: if a section is missing or differently formatted, that
145
+ field comes back empty. We only require that the 5 section
146
+ headings appear in order; everything else is recovered.
147
+ """
148
+ sections = _split_sections(text)
149
+ return Handoff(
150
+ mission=sections.get("1", "").strip(),
151
+ state=sections.get("2", "").strip(),
152
+ files_touched=_parse_bullets(sections.get("3", "")),
153
+ dead_ends=_parse_bullets(sections.get("4", "")),
154
+ next_steps=_parse_numbered(sections.get("5", "")),
155
+ created_at=_extract_created_at(text),
156
+ )
157
+
158
+
159
+ _SECTION_RE = re.compile(r"^##\s+(\d)\.", re.MULTILINE)
160
+ _BULLET_RE = re.compile(r"^[-*]\s+(.+?)\s*$", re.MULTILINE)
161
+ _NUM_RE = re.compile(r"^\d+\.\s+(.+?)\s*$", re.MULTILINE)
162
+ _CREATED_RE = re.compile(r"^#\s+Handoff\s+—\s+(.+?)\s*$", re.MULTILINE)
163
+
164
+
165
+ def _split_sections(text: str) -> dict[str, str]:
166
+ """Return ``{"1": "..body..", "2": "..", ...}`` from a 5-section handoff."""
167
+ matches = list(_SECTION_RE.finditer(text))
168
+ out: dict[str, str] = {}
169
+ for i, m in enumerate(matches):
170
+ start = m.end()
171
+ end = matches[i + 1].start() if i + 1 < len(matches) else len(text)
172
+ # strip the heading line itself
173
+ body_start = text.find("\n", start)
174
+ if body_start == -1:
175
+ continue
176
+ out[m.group(1)] = text[body_start + 1:end].strip()
177
+ return out
178
+
179
+
180
+ def _parse_bullets(body: str) -> list[str]:
181
+ out: list[str] = []
182
+ for m in _BULLET_RE.finditer(body):
183
+ raw = m.group(1).strip()
184
+ if raw == "_(none)_":
185
+ return []
186
+ # strip surrounding backticks for paths
187
+ raw = raw.strip("`")
188
+ out.append(raw)
189
+ return out
190
+
191
+
192
+ def _parse_numbered(body: str) -> list[str]:
193
+ out: list[str] = []
194
+ for m in _NUM_RE.finditer(body):
195
+ raw = m.group(1).strip()
196
+ if raw == "_(none)_":
197
+ return []
198
+ out.append(raw)
199
+ return out
200
+
201
+
202
+ def _extract_created_at(text: str) -> str:
203
+ m = _CREATED_RE.search(text)
204
+ if m:
205
+ return m.group(1).strip()
206
+ return datetime.now(timezone.utc).isoformat(timespec="seconds")
207
+
208
+
209
+ # ---------------------------------------------------------------------------
210
+ # Path resolution
211
+ # ---------------------------------------------------------------------------
212
+
213
+
214
+ def _omega_home(home: str | Path | None) -> Path:
215
+ if home is not None:
216
+ return Path(home)
217
+ return Path(os.environ.get("OMEGA_HOME", str(Path.home() / "Omega")))
218
+
219
+
220
+ def project_handoff_dir(home: Path, slug: str) -> Path:
221
+ """Per-project archive dir (one file per past handoff)."""
222
+ return home / "Agentik_Coding" / "projects" / slug / ".omega" / "handoffs"
223
+
224
+
225
+ def project_latest_path(home: Path, slug: str) -> Path:
226
+ """Always-latest pointer at the project root — friendly for `cat HANDOFF.md`."""
227
+ return home / "Agentik_Coding" / "projects" / slug / "HANDOFF.md"
228
+
229
+
230
+ def task_handoff_path(home: Path, task_id: str) -> Path:
231
+ """Per-task handoff lives next to the .done.json."""
232
+ return (
233
+ home / "Agentik_Runtime" / "sessions" / task_id / "handoff.md"
234
+ )
235
+
236
+
237
+ # ---------------------------------------------------------------------------
238
+ # Atomic write helpers
239
+ # ---------------------------------------------------------------------------
240
+
241
+
242
+ def _atomic_write(path: Path, content: str) -> None:
243
+ """Write `content` to `path` atomically (temp + rename + fsync)."""
244
+ path.parent.mkdir(parents=True, exist_ok=True)
245
+ import threading
246
+ tmp = path.with_suffix(
247
+ path.suffix + f".tmp.{os.getpid()}.{threading.get_ident()}"
248
+ )
249
+ fd = os.open(str(tmp), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)
250
+ with os.fdopen(fd, "w") as fh:
251
+ fh.write(content)
252
+ fh.flush()
253
+ try:
254
+ os.fsync(fh.fileno())
255
+ except OSError:
256
+ pass
257
+ os.replace(tmp, path)
258
+
259
+
260
+ # ---------------------------------------------------------------------------
261
+ # Public API — write / read / list
262
+ # ---------------------------------------------------------------------------
263
+
264
+
265
+ def write_handoff(
266
+ home: str | Path,
267
+ handoff: Handoff,
268
+ *,
269
+ target: str = "project", # "project" | "task" | "both"
270
+ ) -> dict[str, str]:
271
+ """Persist a handoff. Returns ``{written: [path, ...]}``.
272
+
273
+ Targets:
274
+ * ``project`` — writes HANDOFF.md at project root + an archive copy
275
+ under .omega/handoffs/<ts>-<slug>.md
276
+ (requires ``handoff.project``)
277
+ * ``task`` — writes Agentik_Runtime/sessions/<task_id>/handoff.md
278
+ (requires ``handoff.task_id``)
279
+ * ``both`` — both of the above
280
+ """
281
+ home = _omega_home(home)
282
+ md = handoff.to_markdown()
283
+ written: list[str] = []
284
+
285
+ if target in ("project", "both"):
286
+ if not handoff.project:
287
+ raise ValueError("target=project requires handoff.project to be set")
288
+ latest = project_latest_path(home, handoff.project)
289
+ _atomic_write(latest, md)
290
+ written.append(str(latest))
291
+ # archive copy — never overwrite
292
+ ts = handoff.created_at.replace(":", "").replace("-", "").replace("+", "p")
293
+ short = re.sub(r"[^A-Za-z0-9]+", "-", handoff.mission[:40]).strip("-") or "handoff"
294
+ archive = project_handoff_dir(home, handoff.project) / f"{ts}-{short}.md"
295
+ _atomic_write(archive, md)
296
+ written.append(str(archive))
297
+
298
+ if target in ("task", "both"):
299
+ if not handoff.task_id:
300
+ raise ValueError("target=task requires handoff.task_id to be set")
301
+ p = task_handoff_path(home, handoff.task_id)
302
+ _atomic_write(p, md)
303
+ written.append(str(p))
304
+
305
+ return {"written": written}
306
+
307
+
308
+ def read_handoff(
309
+ home: str | Path,
310
+ *,
311
+ project: str | None = None,
312
+ task_id: str | None = None,
313
+ ) -> Handoff | None:
314
+ """Read the latest handoff for a project or a task. None if missing."""
315
+ home = _omega_home(home)
316
+ if project:
317
+ p = project_latest_path(home, project)
318
+ elif task_id:
319
+ p = task_handoff_path(home, task_id)
320
+ else:
321
+ raise ValueError("read_handoff requires either project=... or task_id=...")
322
+ if not p.exists():
323
+ return None
324
+ try:
325
+ return Handoff.from_markdown(p.read_text())
326
+ except OSError:
327
+ return None
328
+
329
+
330
+ def list_handoffs(
331
+ home: str | Path, project: str,
332
+ ) -> list[dict[str, str]]:
333
+ """Chronological list of archived handoffs for a project (newest first)."""
334
+ home = _omega_home(home)
335
+ d = project_handoff_dir(home, project)
336
+ if not d.is_dir():
337
+ return []
338
+ out: list[dict[str, str]] = []
339
+ for f in sorted(d.glob("*.md"), reverse=True):
340
+ try:
341
+ ho = Handoff.from_markdown(f.read_text())
342
+ except OSError:
343
+ continue
344
+ out.append({
345
+ "path": str(f),
346
+ "created_at": ho.created_at,
347
+ "mission": ho.mission[:80],
348
+ "next_first": ho.next_steps[0] if ho.next_steps else "",
349
+ })
350
+ return out
351
+
352
+
353
+ # ---------------------------------------------------------------------------
354
+ # Auto-draft from a worker's .done.json + git status
355
+ # ---------------------------------------------------------------------------
356
+
357
+
358
+ def from_done_signal(
359
+ home: str | Path, task_id: str,
360
+ *,
361
+ cwd: str | Path | None = None,
362
+ ) -> Handoff:
363
+ """Build a handoff draft from a worker's .done.json + the git diff at cwd.
364
+
365
+ The draft is intentionally INCOMPLETE — sections like "dead_ends" can't
366
+ be auto-inferred. The expectation is that a human or a follow-up agent
367
+ polishes it before the next /clear. The point is to seed the file
368
+ instead of leaving the next session with nothing.
369
+ """
370
+ home = _omega_home(home)
371
+ from omega_engine.done_signal import read_done
372
+
373
+ sig = read_done(home, task_id)
374
+ mission = ""
375
+ state = ""
376
+ files_touched: list[str] = []
377
+ if sig is not None:
378
+ # Mission inferred from the brief's intent (best-effort)
379
+ try:
380
+ from omega_engine.worker import read_brief
381
+ b = read_brief(home, task_id)
382
+ mission = b.intent[:200]
383
+ except Exception: # noqa: BLE001
384
+ pass
385
+ state = sig.summary or ""
386
+ files_touched = list(sig.files_changed or [])
387
+
388
+ # Augment files_touched with `git diff --name-only` if a cwd is given.
389
+ if cwd:
390
+ try:
391
+ proc = subprocess.run(
392
+ ["git", "-C", str(cwd), "diff", "--name-only", "HEAD"],
393
+ capture_output=True, text=True, timeout=15, check=False,
394
+ )
395
+ if proc.returncode == 0:
396
+ for line in proc.stdout.splitlines():
397
+ line = line.strip()
398
+ if line and line not in files_touched:
399
+ files_touched.append(line)
400
+ except (OSError, subprocess.SubprocessError):
401
+ pass
402
+
403
+ next_steps: list[str] = []
404
+ if sig is not None and sig.status == "pending" and sig.pending_actions:
405
+ next_steps = list(sig.pending_actions)
406
+ elif sig is not None and sig.status == "failed":
407
+ next_steps = [
408
+ f"investigate the failure: {sig.errors[0]}"
409
+ if sig.errors else "investigate the failure"
410
+ ]
411
+
412
+ return Handoff(
413
+ mission=mission or f"(task {task_id})",
414
+ state=state,
415
+ files_touched=files_touched,
416
+ dead_ends=[],
417
+ next_steps=next_steps,
418
+ author=f"worker:{task_id}",
419
+ task_id=task_id,
420
+ )
421
+
422
+
423
+ # ---------------------------------------------------------------------------
424
+ # Template — exported so the CLI / skill can show it
425
+ # ---------------------------------------------------------------------------
426
+
427
+
428
+ TEMPLATE = """\
429
+ # Handoff — <iso-timestamp>
430
+
431
+ project=`<slug>` · mission=`<id>` · task=`<id>` · author=`<who>`
432
+
433
+ ## 1. Mission
434
+
435
+ One sentence: what was this session trying to achieve?
436
+
437
+ ## 2. State (what works / what doesn't)
438
+
439
+ - Works: <concrete, observed runtime — e.g. "auth flow signs in, /dashboard renders">
440
+ - Broken: <concrete, observed — e.g. "/settings throws 500 on PATCH /api/profile">
441
+ - Verified by: <how you know — `npm test` / playwright / curl / manual>
442
+
443
+ ## 3. Files touched
444
+
445
+ - `path/to/file1.ts`
446
+ - `path/to/file2.tsx:42-78`
447
+ - `tests/foo.test.ts`
448
+
449
+ ## 4. Dead ends — DO NOT retry
450
+
451
+ - Tried <approach A>; failed because <reason>. Don't re-walk this wall.
452
+ - Tried <approach B>; produced <wrong behaviour>. Causes <side-effect>.
453
+
454
+ ## 5. Next — start here
455
+
456
+ 1. First concrete action the next agent should take.
457
+ 2. Second concrete action (if obviously chained).
458
+ 3. Validation: how to confirm the next step worked.
459
+ """