@trac3r/oh-my-god 2.2.11

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 (638) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/INSTALL-VERIFICATION-INDEX.md +51 -0
  3. package/LICENSE +21 -0
  4. package/OMG-setup.sh +2549 -0
  5. package/QUICK-REFERENCE.md +58 -0
  6. package/README.md +207 -0
  7. package/agents/__init__.py +1 -0
  8. package/agents/__pycache__/model_roles.cpython-313.pyc +0 -0
  9. package/agents/_model_roles.yaml +26 -0
  10. package/agents/designer.md +67 -0
  11. package/agents/explore.md +60 -0
  12. package/agents/model_roles.py +196 -0
  13. package/agents/omg-api-builder.md +23 -0
  14. package/agents/omg-architect-mode.md +41 -0
  15. package/agents/omg-architect.md +13 -0
  16. package/agents/omg-backend-engineer.md +41 -0
  17. package/agents/omg-critic.md +16 -0
  18. package/agents/omg-database-engineer.md +41 -0
  19. package/agents/omg-escalation-router.md +17 -0
  20. package/agents/omg-executor.md +12 -0
  21. package/agents/omg-frontend-designer.md +41 -0
  22. package/agents/omg-implement-mode.md +49 -0
  23. package/agents/omg-infra-engineer.md +41 -0
  24. package/agents/omg-qa-tester.md +16 -0
  25. package/agents/omg-research-mode.md +41 -0
  26. package/agents/omg-security-auditor.md +41 -0
  27. package/agents/omg-testing-engineer.md +41 -0
  28. package/agents/plan.md +80 -0
  29. package/agents/quick_task.md +64 -0
  30. package/agents/reviewer.md +83 -0
  31. package/agents/task.md +71 -0
  32. package/bin/omg +41 -0
  33. package/commands/OMG:ai-commit.md +113 -0
  34. package/commands/OMG:api-twin.md +22 -0
  35. package/commands/OMG:arch.md +313 -0
  36. package/commands/OMG:browser.md +29 -0
  37. package/commands/OMG:ccg.md +22 -0
  38. package/commands/OMG:compat.md +57 -0
  39. package/commands/OMG:cost.md +181 -0
  40. package/commands/OMG:crazy.md +125 -0
  41. package/commands/OMG:create-agent.md +183 -0
  42. package/commands/OMG:deep-plan.md +18 -0
  43. package/commands/OMG:deps.md +248 -0
  44. package/commands/OMG:diagnose-plugins.md +33 -0
  45. package/commands/OMG:doctor.md +37 -0
  46. package/commands/OMG:domain-init.md +11 -0
  47. package/commands/OMG:escalate.md +52 -0
  48. package/commands/OMG:forge.md +103 -0
  49. package/commands/OMG:health-check.md +48 -0
  50. package/commands/OMG:init.md +134 -0
  51. package/commands/OMG:issue.md +56 -0
  52. package/commands/OMG:mode.md +44 -0
  53. package/commands/OMG:playwright.md +17 -0
  54. package/commands/OMG:preflight.md +26 -0
  55. package/commands/OMG:preset.md +49 -0
  56. package/commands/OMG:profile-review.md +58 -0
  57. package/commands/OMG:project-init.md +11 -0
  58. package/commands/OMG:ralph-start.md +43 -0
  59. package/commands/OMG:ralph-stop.md +23 -0
  60. package/commands/OMG:security-check.md +28 -0
  61. package/commands/OMG:session-branch.md +101 -0
  62. package/commands/OMG:session-fork.md +57 -0
  63. package/commands/OMG:session-merge.md +138 -0
  64. package/commands/OMG:setup.md +82 -0
  65. package/commands/OMG:ship.md +18 -0
  66. package/commands/OMG:stats.md +225 -0
  67. package/commands/OMG:teams.md +54 -0
  68. package/commands/OMG:theme.md +44 -0
  69. package/commands/OMG:validate.md +59 -0
  70. package/commands/__init__.py +1 -0
  71. package/docs/command-surface.md +55 -0
  72. package/docs/install/claude-code.md +53 -0
  73. package/docs/install/codex.md +45 -0
  74. package/docs/install/gemini.md +43 -0
  75. package/docs/install/github-action.md +81 -0
  76. package/docs/install/github-app-required-checks.md +107 -0
  77. package/docs/install/github-app.md +161 -0
  78. package/docs/install/kimi.md +43 -0
  79. package/docs/install/opencode.md +38 -0
  80. package/docs/proof.md +182 -0
  81. package/hooks/__init__.py +0 -0
  82. package/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  83. package/hooks/__pycache__/_agent_registry.cpython-313.pyc +0 -0
  84. package/hooks/__pycache__/_analytics.cpython-313.pyc +0 -0
  85. package/hooks/__pycache__/_budget.cpython-313.pyc +0 -0
  86. package/hooks/__pycache__/_common.cpython-313.pyc +0 -0
  87. package/hooks/__pycache__/_compression_optimizer.cpython-313.pyc +0 -0
  88. package/hooks/__pycache__/_cost_ledger.cpython-313.pyc +0 -0
  89. package/hooks/__pycache__/_learnings.cpython-313.pyc +0 -0
  90. package/hooks/__pycache__/_memory.cpython-313.pyc +0 -0
  91. package/hooks/__pycache__/_post_write.cpython-313.pyc +0 -0
  92. package/hooks/__pycache__/_protected_context.cpython-313.pyc +0 -0
  93. package/hooks/__pycache__/_token_counter.cpython-313.pyc +0 -0
  94. package/hooks/__pycache__/branch_manager.cpython-313.pyc +0 -0
  95. package/hooks/__pycache__/budget_governor.cpython-313.pyc +0 -0
  96. package/hooks/__pycache__/circuit-breaker.cpython-313.pyc +0 -0
  97. package/hooks/__pycache__/compression_feedback.cpython-313.pyc +0 -0
  98. package/hooks/__pycache__/config-guard.cpython-313.pyc +0 -0
  99. package/hooks/__pycache__/context_pressure.cpython-313.pyc +0 -0
  100. package/hooks/__pycache__/credential_store.cpython-313.pyc +0 -0
  101. package/hooks/__pycache__/fetch-rate-limits.cpython-313.pyc +0 -0
  102. package/hooks/__pycache__/firewall.cpython-313.pyc +0 -0
  103. package/hooks/__pycache__/hashline-formatter-bridge.cpython-313.pyc +0 -0
  104. package/hooks/__pycache__/hashline-injector.cpython-313.pyc +0 -0
  105. package/hooks/__pycache__/hashline-validator.cpython-313.pyc +0 -0
  106. package/hooks/__pycache__/idle-detector.cpython-313.pyc +0 -0
  107. package/hooks/__pycache__/instructions-loaded.cpython-313.pyc +0 -0
  108. package/hooks/__pycache__/intentgate-keyword-detector.cpython-313.pyc +0 -0
  109. package/hooks/__pycache__/magic-keyword-router.cpython-313.pyc +0 -0
  110. package/hooks/__pycache__/policy_engine.cpython-313.pyc +0 -0
  111. package/hooks/__pycache__/post-tool-failure.cpython-313.pyc +0 -0
  112. package/hooks/__pycache__/post-write.cpython-313.pyc +0 -0
  113. package/hooks/__pycache__/post_write.cpython-313.pyc +0 -0
  114. package/hooks/__pycache__/pre-compact.cpython-313.pyc +0 -0
  115. package/hooks/__pycache__/pre-tool-inject.cpython-313.pyc +0 -0
  116. package/hooks/__pycache__/prompt-enhancer.cpython-313.pyc +0 -0
  117. package/hooks/__pycache__/quality-runner.cpython-313.pyc +0 -0
  118. package/hooks/__pycache__/query.cpython-313.pyc +0 -0
  119. package/hooks/__pycache__/secret-guard.cpython-313.pyc +0 -0
  120. package/hooks/__pycache__/secret_audit.cpython-313.pyc +0 -0
  121. package/hooks/__pycache__/security_validators.cpython-313.pyc +0 -0
  122. package/hooks/__pycache__/session-end-capture.cpython-313.pyc +0 -0
  123. package/hooks/__pycache__/session-start.cpython-313.pyc +0 -0
  124. package/hooks/__pycache__/setup_wizard.cpython-313.pyc +0 -0
  125. package/hooks/__pycache__/shadow_manager.cpython-313.pyc +0 -0
  126. package/hooks/__pycache__/state_migration.cpython-313.pyc +0 -0
  127. package/hooks/__pycache__/stop-gate.cpython-313.pyc +0 -0
  128. package/hooks/__pycache__/stop_dispatcher.cpython-313.pyc +0 -0
  129. package/hooks/__pycache__/tdd-gate.cpython-313.pyc +0 -0
  130. package/hooks/__pycache__/terms-guard.cpython-313.pyc +0 -0
  131. package/hooks/__pycache__/test-validator.cpython-313.pyc +0 -0
  132. package/hooks/__pycache__/test_generator_hook.cpython-313.pyc +0 -0
  133. package/hooks/__pycache__/todo-state-tracker.cpython-313.pyc +0 -0
  134. package/hooks/__pycache__/tool-ledger.cpython-313.pyc +0 -0
  135. package/hooks/__pycache__/trust_review.cpython-313.pyc +0 -0
  136. package/hooks/__pycache__/user-prompt-submit.cpython-313.pyc +0 -0
  137. package/hooks/_agent_registry.py +481 -0
  138. package/hooks/_analytics.py +291 -0
  139. package/hooks/_budget.py +31 -0
  140. package/hooks/_common.py +761 -0
  141. package/hooks/_compression_optimizer.py +119 -0
  142. package/hooks/_cost_ledger.py +176 -0
  143. package/hooks/_learnings.py +126 -0
  144. package/hooks/_memory.py +103 -0
  145. package/hooks/_post_write.py +46 -0
  146. package/hooks/_protected_context.py +150 -0
  147. package/hooks/_token_counter.py +221 -0
  148. package/hooks/branch_manager.py +255 -0
  149. package/hooks/budget_governor.py +326 -0
  150. package/hooks/circuit-breaker.py +270 -0
  151. package/hooks/compression_feedback.py +254 -0
  152. package/hooks/config-guard.py +193 -0
  153. package/hooks/context_pressure.py +119 -0
  154. package/hooks/credential_store.py +970 -0
  155. package/hooks/fetch-rate-limits.py +212 -0
  156. package/hooks/firewall.py +323 -0
  157. package/hooks/hashline-formatter-bridge.py +224 -0
  158. package/hooks/hashline-injector.py +273 -0
  159. package/hooks/hashline-validator.py +216 -0
  160. package/hooks/idle-detector.py +97 -0
  161. package/hooks/instructions-loaded.py +26 -0
  162. package/hooks/intentgate-keyword-detector.py +200 -0
  163. package/hooks/magic-keyword-router.py +195 -0
  164. package/hooks/policy_engine.py +767 -0
  165. package/hooks/post-tool-failure.py +19 -0
  166. package/hooks/post-write.py +233 -0
  167. package/hooks/pre-compact.py +470 -0
  168. package/hooks/pre-tool-inject.py +98 -0
  169. package/hooks/prompt-enhancer.py +879 -0
  170. package/hooks/quality-runner.py +191 -0
  171. package/hooks/query.py +512 -0
  172. package/hooks/secret-guard.py +120 -0
  173. package/hooks/secret_audit.py +144 -0
  174. package/hooks/security_validators.py +93 -0
  175. package/hooks/session-end-capture.py +505 -0
  176. package/hooks/session-start.py +261 -0
  177. package/hooks/setup_wizard.py +1101 -0
  178. package/hooks/shadow_manager.py +476 -0
  179. package/hooks/state_migration.py +228 -0
  180. package/hooks/stop-gate.py +7 -0
  181. package/hooks/stop_dispatcher.py +1259 -0
  182. package/hooks/tdd-gate.py +10 -0
  183. package/hooks/terms-guard.py +98 -0
  184. package/hooks/test-validator.py +462 -0
  185. package/hooks/test_generator_hook.py +123 -0
  186. package/hooks/todo-state-tracker.py +114 -0
  187. package/hooks/tool-ledger.py +165 -0
  188. package/hooks/trust_review.py +662 -0
  189. package/hooks/user-prompt-submit.py +12 -0
  190. package/hud/omg-hud.mjs +1571 -0
  191. package/lab/__init__.py +1 -0
  192. package/lab/__pycache__/__init__.cpython-313.pyc +0 -0
  193. package/lab/__pycache__/axolotl_adapter.cpython-313.pyc +0 -0
  194. package/lab/__pycache__/forge_runner.cpython-313.pyc +0 -0
  195. package/lab/__pycache__/gazebo_adapter.cpython-313.pyc +0 -0
  196. package/lab/__pycache__/isaac_gym_adapter.cpython-313.pyc +0 -0
  197. package/lab/__pycache__/mock_isaac_env.cpython-313.pyc +0 -0
  198. package/lab/__pycache__/pipeline.cpython-313.pyc +0 -0
  199. package/lab/__pycache__/policies.cpython-313.pyc +0 -0
  200. package/lab/__pycache__/pybullet_adapter.cpython-313.pyc +0 -0
  201. package/lab/axolotl_adapter.py +531 -0
  202. package/lab/forge_runner.py +103 -0
  203. package/lab/gazebo_adapter.py +168 -0
  204. package/lab/isaac_gym_adapter.py +190 -0
  205. package/lab/mock_isaac_env.py +47 -0
  206. package/lab/pipeline.py +712 -0
  207. package/lab/policies.py +52 -0
  208. package/lab/pybullet_adapter.py +192 -0
  209. package/package.json +61 -0
  210. package/plugins/README.md +78 -0
  211. package/plugins/__init__.py +1 -0
  212. package/plugins/__pycache__/__init__.cpython-313.pyc +0 -0
  213. package/plugins/advanced/commands/OMG-code-review.md +114 -0
  214. package/plugins/advanced/commands/OMG-deep-plan.md +266 -0
  215. package/plugins/advanced/commands/OMG-handoff.md +115 -0
  216. package/plugins/advanced/commands/OMG-learn.md +110 -0
  217. package/plugins/advanced/commands/OMG-maintainer.md +31 -0
  218. package/plugins/advanced/commands/OMG-ralph-start.md +43 -0
  219. package/plugins/advanced/commands/OMG-ralph-stop.md +23 -0
  220. package/plugins/advanced/commands/OMG-security-review.md +16 -0
  221. package/plugins/advanced/commands/OMG-sequential-thinking.md +20 -0
  222. package/plugins/advanced/commands/OMG-ship.md +46 -0
  223. package/plugins/advanced/commands/OMG:code-review.md +114 -0
  224. package/plugins/advanced/commands/OMG:deep-plan.md +266 -0
  225. package/plugins/advanced/commands/OMG:handoff.md +115 -0
  226. package/plugins/advanced/commands/OMG:learn.md +110 -0
  227. package/plugins/advanced/commands/OMG:maintainer.md +31 -0
  228. package/plugins/advanced/commands/OMG:ralph-start.md +43 -0
  229. package/plugins/advanced/commands/OMG:ralph-stop.md +23 -0
  230. package/plugins/advanced/commands/OMG:security-review.md +16 -0
  231. package/plugins/advanced/commands/OMG:sequential-thinking.md +20 -0
  232. package/plugins/advanced/commands/OMG:ship.md +46 -0
  233. package/plugins/advanced/plugin.json +104 -0
  234. package/plugins/core/plugin.json +204 -0
  235. package/plugins/dephealth/__init__.py +0 -0
  236. package/plugins/dephealth/__pycache__/__init__.cpython-313.pyc +0 -0
  237. package/plugins/dephealth/__pycache__/cve_scanner.cpython-313.pyc +0 -0
  238. package/plugins/dephealth/__pycache__/license_checker.cpython-313.pyc +0 -0
  239. package/plugins/dephealth/__pycache__/manifest_detector.cpython-313.pyc +0 -0
  240. package/plugins/dephealth/__pycache__/vuln_analyzer.cpython-313.pyc +0 -0
  241. package/plugins/dephealth/cve_scanner.py +279 -0
  242. package/plugins/dephealth/license_checker.py +135 -0
  243. package/plugins/dephealth/manifest_detector.py +423 -0
  244. package/plugins/dephealth/vuln_analyzer.py +176 -0
  245. package/plugins/testgen/__init__.py +0 -0
  246. package/plugins/testgen/__pycache__/__init__.cpython-313.pyc +0 -0
  247. package/plugins/testgen/__pycache__/codamosa_engine.cpython-313.pyc +0 -0
  248. package/plugins/testgen/__pycache__/edge_case_synthesizer.cpython-313.pyc +0 -0
  249. package/plugins/testgen/__pycache__/framework_detector.cpython-313.pyc +0 -0
  250. package/plugins/testgen/__pycache__/skeleton_generator.cpython-313.pyc +0 -0
  251. package/plugins/testgen/codamosa_engine.py +402 -0
  252. package/plugins/testgen/edge_case_synthesizer.py +184 -0
  253. package/plugins/testgen/framework_detector.py +271 -0
  254. package/plugins/testgen/skeleton_generator.py +219 -0
  255. package/plugins/viz/__init__.py +0 -0
  256. package/plugins/viz/__pycache__/__init__.cpython-313.pyc +0 -0
  257. package/plugins/viz/__pycache__/ast_parser.cpython-313.pyc +0 -0
  258. package/plugins/viz/__pycache__/diagram_generator.cpython-313.pyc +0 -0
  259. package/plugins/viz/__pycache__/graph_builder.cpython-313.pyc +0 -0
  260. package/plugins/viz/__pycache__/native_parsers.cpython-313.pyc +0 -0
  261. package/plugins/viz/__pycache__/regex_parser.cpython-313.pyc +0 -0
  262. package/plugins/viz/ast_parser.py +139 -0
  263. package/plugins/viz/diagram_generator.py +192 -0
  264. package/plugins/viz/graph_builder.py +444 -0
  265. package/plugins/viz/native_parsers.py +259 -0
  266. package/plugins/viz/regex_parser.py +112 -0
  267. package/pyproject.toml +143 -0
  268. package/registry/__init__.py +1 -0
  269. package/registry/__pycache__/__init__.cpython-313.pyc +0 -0
  270. package/registry/__pycache__/approval_artifact.cpython-313.pyc +0 -0
  271. package/registry/__pycache__/verify_artifact.cpython-313.pyc +0 -0
  272. package/registry/approval_artifact.py +236 -0
  273. package/registry/bundles/algorithms.yaml +45 -0
  274. package/registry/bundles/api-twin.yaml +48 -0
  275. package/registry/bundles/ast-pack.yaml +80 -0
  276. package/registry/bundles/claim-judge.yaml +49 -0
  277. package/registry/bundles/control-plane.yaml +192 -0
  278. package/registry/bundles/data-lineage.yaml +47 -0
  279. package/registry/bundles/delta-classifier.yaml +47 -0
  280. package/registry/bundles/eval-gate.yaml +47 -0
  281. package/registry/bundles/hash-edit.yaml +73 -0
  282. package/registry/bundles/health.yaml +45 -0
  283. package/registry/bundles/hook-governor.yaml +101 -0
  284. package/registry/bundles/incident-replay.yaml +47 -0
  285. package/registry/bundles/lsp-pack.yaml +80 -0
  286. package/registry/bundles/mcp-fabric.yaml +53 -0
  287. package/registry/bundles/plan-council.yaml +56 -0
  288. package/registry/bundles/preflight.yaml +48 -0
  289. package/registry/bundles/proof-gate.yaml +49 -0
  290. package/registry/bundles/remote-supervisor.yaml +49 -0
  291. package/registry/bundles/robotics.yaml +45 -0
  292. package/registry/bundles/secure-worktree-pipeline.yaml +69 -0
  293. package/registry/bundles/security-check.yaml +50 -0
  294. package/registry/bundles/terminal-lane.yaml +61 -0
  295. package/registry/bundles/test-intent-lock.yaml +49 -0
  296. package/registry/bundles/tracebank.yaml +47 -0
  297. package/registry/bundles/vision.yaml +45 -0
  298. package/registry/omg-capability.schema.json +378 -0
  299. package/registry/policy-packs/airgapped.lock.json +11 -0
  300. package/registry/policy-packs/airgapped.signature.json +10 -0
  301. package/registry/policy-packs/airgapped.yaml +16 -0
  302. package/registry/policy-packs/fintech.lock.json +11 -0
  303. package/registry/policy-packs/fintech.signature.json +10 -0
  304. package/registry/policy-packs/fintech.yaml +15 -0
  305. package/registry/policy-packs/locked-prod.lock.json +11 -0
  306. package/registry/policy-packs/locked-prod.signature.json +10 -0
  307. package/registry/policy-packs/locked-prod.yaml +18 -0
  308. package/registry/trusted_signers.json +44 -0
  309. package/registry/verify_artifact.py +493 -0
  310. package/runtime/__init__.py +36 -0
  311. package/runtime/__pycache__/__init__.cpython-313.pyc +0 -0
  312. package/runtime/__pycache__/adoption.cpython-313.pyc +0 -0
  313. package/runtime/__pycache__/agent_selector.cpython-313.pyc +0 -0
  314. package/runtime/__pycache__/api_twin.cpython-313.pyc +0 -0
  315. package/runtime/__pycache__/architecture_signal.cpython-313.pyc +0 -0
  316. package/runtime/__pycache__/artifact_parsers.cpython-313.pyc +0 -0
  317. package/runtime/__pycache__/asset_loader.cpython-313.pyc +0 -0
  318. package/runtime/__pycache__/background_verification.cpython-313.pyc +0 -0
  319. package/runtime/__pycache__/budget_envelopes.cpython-313.pyc +0 -0
  320. package/runtime/__pycache__/business_workflow.cpython-313.pyc +0 -0
  321. package/runtime/__pycache__/canonical_surface.cpython-313.pyc +0 -0
  322. package/runtime/__pycache__/canonical_taxonomy.cpython-313.pyc +0 -0
  323. package/runtime/__pycache__/claim_judge.cpython-313.pyc +0 -0
  324. package/runtime/__pycache__/cli_provider.cpython-313.pyc +0 -0
  325. package/runtime/__pycache__/compat.cpython-313.pyc +0 -0
  326. package/runtime/__pycache__/complexity_scorer.cpython-313.pyc +0 -0
  327. package/runtime/__pycache__/compliance_governor.cpython-313.pyc +0 -0
  328. package/runtime/__pycache__/config_transaction.cpython-313.pyc +0 -0
  329. package/runtime/__pycache__/context_compiler.cpython-313.pyc +0 -0
  330. package/runtime/__pycache__/context_engine.cpython-313.pyc +0 -0
  331. package/runtime/__pycache__/context_limits.cpython-313.pyc +0 -0
  332. package/runtime/__pycache__/contract_compiler.cpython-313.pyc +0 -0
  333. package/runtime/__pycache__/custom_agent_loader.cpython-313.pyc +0 -0
  334. package/runtime/__pycache__/data_lineage.cpython-313.pyc +0 -0
  335. package/runtime/__pycache__/defense_state.cpython-313.pyc +0 -0
  336. package/runtime/__pycache__/delta_classifier.cpython-313.pyc +0 -0
  337. package/runtime/__pycache__/dispatcher.cpython-313.pyc +0 -0
  338. package/runtime/__pycache__/doc_generator.cpython-313.pyc +0 -0
  339. package/runtime/__pycache__/domain_packs.cpython-313.pyc +0 -0
  340. package/runtime/__pycache__/ecosystem.cpython-313.pyc +0 -0
  341. package/runtime/__pycache__/equalizer.cpython-313.pyc +0 -0
  342. package/runtime/__pycache__/eval_gate.cpython-313.pyc +0 -0
  343. package/runtime/__pycache__/evidence_narrator.cpython-313.pyc +0 -0
  344. package/runtime/__pycache__/evidence_query.cpython-313.pyc +0 -0
  345. package/runtime/__pycache__/evidence_registry.cpython-313.pyc +0 -0
  346. package/runtime/__pycache__/evidence_requirements.cpython-313.pyc +0 -0
  347. package/runtime/__pycache__/exec_kernel.cpython-313.pyc +0 -0
  348. package/runtime/__pycache__/explainer_formatter.cpython-313.pyc +0 -0
  349. package/runtime/__pycache__/feature_registry.cpython-313.pyc +0 -0
  350. package/runtime/__pycache__/forge_agents.cpython-313.pyc +0 -0
  351. package/runtime/__pycache__/forge_contracts.cpython-313.pyc +0 -0
  352. package/runtime/__pycache__/forge_domains.cpython-313.pyc +0 -0
  353. package/runtime/__pycache__/forge_run_id.cpython-313.pyc +0 -0
  354. package/runtime/__pycache__/github_integration.cpython-313.pyc +0 -0
  355. package/runtime/__pycache__/github_review_bot.cpython-313.pyc +0 -0
  356. package/runtime/__pycache__/github_review_contract.cpython-313.pyc +0 -0
  357. package/runtime/__pycache__/github_review_formatter.cpython-313.pyc +0 -0
  358. package/runtime/__pycache__/guide_assert.cpython-313.pyc +0 -0
  359. package/runtime/__pycache__/hook_governor.cpython-313.pyc +0 -0
  360. package/runtime/__pycache__/host_parity.cpython-313.pyc +0 -0
  361. package/runtime/__pycache__/incident_replay.cpython-313.pyc +0 -0
  362. package/runtime/__pycache__/install_planner.cpython-313.pyc +0 -0
  363. package/runtime/__pycache__/interaction_journal.cpython-313.pyc +0 -0
  364. package/runtime/__pycache__/issue_surface.cpython-313.pyc +0 -0
  365. package/runtime/__pycache__/legacy_compat.cpython-313.pyc +0 -0
  366. package/runtime/__pycache__/mcp_config_writers.cpython-313.pyc +0 -0
  367. package/runtime/__pycache__/mcp_lifecycle.cpython-313.pyc +0 -0
  368. package/runtime/__pycache__/mcp_memory_server.cpython-313.pyc +0 -0
  369. package/runtime/__pycache__/memory_store.cpython-313.pyc +0 -0
  370. package/runtime/__pycache__/merge_writer.cpython-313.pyc +0 -0
  371. package/runtime/__pycache__/music_omr_testbed.cpython-313.pyc +0 -0
  372. package/runtime/__pycache__/mutation_gate.cpython-313.pyc +0 -0
  373. package/runtime/__pycache__/omc_compat.cpython-313.pyc +0 -0
  374. package/runtime/__pycache__/omg_browser_cli.cpython-313.pyc +0 -0
  375. package/runtime/__pycache__/omg_mcp_server.cpython-313.pyc +0 -0
  376. package/runtime/__pycache__/opus_plan.cpython-313.pyc +0 -0
  377. package/runtime/__pycache__/playwright_adapter.cpython-313.pyc +0 -0
  378. package/runtime/__pycache__/playwright_pack.cpython-313.pyc +0 -0
  379. package/runtime/__pycache__/plugin_diagnostics.cpython-313.pyc +0 -0
  380. package/runtime/__pycache__/plugin_interop.cpython-313.pyc +0 -0
  381. package/runtime/__pycache__/policy_pack_loader.cpython-313.pyc +0 -0
  382. package/runtime/__pycache__/preflight.cpython-313.pyc +0 -0
  383. package/runtime/__pycache__/profile_io.cpython-313.pyc +0 -0
  384. package/runtime/__pycache__/prompt_compiler.cpython-313.pyc +0 -0
  385. package/runtime/__pycache__/proof_chain.cpython-313.pyc +0 -0
  386. package/runtime/__pycache__/proof_gate.cpython-313.pyc +0 -0
  387. package/runtime/__pycache__/provider_parity_eval.cpython-313.pyc +0 -0
  388. package/runtime/__pycache__/release_artifact_audit.cpython-313.pyc +0 -0
  389. package/runtime/__pycache__/release_run_coordinator.cpython-313.pyc +0 -0
  390. package/runtime/__pycache__/release_surface_compiler.cpython-313.pyc +0 -0
  391. package/runtime/__pycache__/release_surface_registry.cpython-313.pyc +0 -0
  392. package/runtime/__pycache__/release_surfaces.cpython-313.pyc +0 -0
  393. package/runtime/__pycache__/remote_supervisor.cpython-313.pyc +0 -0
  394. package/runtime/__pycache__/repro_pack.cpython-313.pyc +0 -0
  395. package/runtime/__pycache__/rollback_manifest.cpython-313.pyc +0 -0
  396. package/runtime/__pycache__/router_critics.cpython-313.pyc +0 -0
  397. package/runtime/__pycache__/router_executor.cpython-313.pyc +0 -0
  398. package/runtime/__pycache__/router_selector.cpython-313.pyc +0 -0
  399. package/runtime/__pycache__/runtime_contracts.cpython-313.pyc +0 -0
  400. package/runtime/__pycache__/runtime_profile.cpython-313.pyc +0 -0
  401. package/runtime/__pycache__/security_check.cpython-313.pyc +0 -0
  402. package/runtime/__pycache__/session_health.cpython-313.pyc +0 -0
  403. package/runtime/__pycache__/skill_evolution.cpython-313.pyc +0 -0
  404. package/runtime/__pycache__/skill_registry.cpython-313.pyc +0 -0
  405. package/runtime/__pycache__/subagent_dispatcher.cpython-313.pyc +0 -0
  406. package/runtime/__pycache__/subscription_tiers.cpython-313.pyc +0 -0
  407. package/runtime/__pycache__/team_router.cpython-313.pyc +0 -0
  408. package/runtime/__pycache__/test_intent_lock.cpython-313-pytest-9.0.2.pyc +0 -0
  409. package/runtime/__pycache__/test_intent_lock.cpython-313.pyc +0 -0
  410. package/runtime/__pycache__/tmux_session_manager.cpython-313.pyc +0 -0
  411. package/runtime/__pycache__/tool_fabric.cpython-313.pyc +0 -0
  412. package/runtime/__pycache__/tool_plan_gate.cpython-313.pyc +0 -0
  413. package/runtime/__pycache__/tool_relevance.cpython-313.pyc +0 -0
  414. package/runtime/__pycache__/tracebank.cpython-313.pyc +0 -0
  415. package/runtime/__pycache__/untrusted_content.cpython-313.pyc +0 -0
  416. package/runtime/__pycache__/validate.cpython-313.pyc +0 -0
  417. package/runtime/__pycache__/verdict_schema.cpython-313.pyc +0 -0
  418. package/runtime/__pycache__/verification_controller.cpython-313.pyc +0 -0
  419. package/runtime/__pycache__/verification_loop.cpython-313.pyc +0 -0
  420. package/runtime/__pycache__/vision_artifacts.cpython-313.pyc +0 -0
  421. package/runtime/__pycache__/vision_cache.cpython-313.pyc +0 -0
  422. package/runtime/__pycache__/vision_jobs.cpython-313.pyc +0 -0
  423. package/runtime/__pycache__/worker_watchdog.cpython-313.pyc +0 -0
  424. package/runtime/adapters/__init__.py +13 -0
  425. package/runtime/adapters/__pycache__/__init__.cpython-313.pyc +0 -0
  426. package/runtime/adapters/__pycache__/claude.cpython-313.pyc +0 -0
  427. package/runtime/adapters/__pycache__/gpt.cpython-313.pyc +0 -0
  428. package/runtime/adapters/__pycache__/local.cpython-313.pyc +0 -0
  429. package/runtime/adapters/claude.py +63 -0
  430. package/runtime/adapters/gpt.py +56 -0
  431. package/runtime/adapters/local.py +56 -0
  432. package/runtime/adoption.py +280 -0
  433. package/runtime/api_twin.py +450 -0
  434. package/runtime/architecture_signal.py +226 -0
  435. package/runtime/artifact_parsers.py +161 -0
  436. package/runtime/asset_loader.py +62 -0
  437. package/runtime/background_verification.py +178 -0
  438. package/runtime/budget_envelopes.py +398 -0
  439. package/runtime/business_workflow.py +234 -0
  440. package/runtime/canonical_surface.py +53 -0
  441. package/runtime/canonical_taxonomy.py +27 -0
  442. package/runtime/claim_judge.py +648 -0
  443. package/runtime/cli_provider.py +105 -0
  444. package/runtime/compat.py +2222 -0
  445. package/runtime/complexity_scorer.py +148 -0
  446. package/runtime/compliance_governor.py +505 -0
  447. package/runtime/config_transaction.py +304 -0
  448. package/runtime/context_compiler.py +131 -0
  449. package/runtime/context_engine.py +708 -0
  450. package/runtime/context_limits.py +363 -0
  451. package/runtime/contract_compiler.py +3664 -0
  452. package/runtime/custom_agent_loader.py +366 -0
  453. package/runtime/data_lineage.py +244 -0
  454. package/runtime/defense_state.py +261 -0
  455. package/runtime/delta_classifier.py +231 -0
  456. package/runtime/dispatcher.py +47 -0
  457. package/runtime/doc_generator.py +319 -0
  458. package/runtime/domain_packs.py +75 -0
  459. package/runtime/ecosystem.py +371 -0
  460. package/runtime/equalizer.py +268 -0
  461. package/runtime/eval_gate.py +96 -0
  462. package/runtime/evidence_narrator.py +147 -0
  463. package/runtime/evidence_query.py +303 -0
  464. package/runtime/evidence_registry.py +16 -0
  465. package/runtime/evidence_requirements.py +157 -0
  466. package/runtime/exec_kernel.py +267 -0
  467. package/runtime/explainer_formatter.py +82 -0
  468. package/runtime/feature_registry.py +109 -0
  469. package/runtime/forge_agents.py +915 -0
  470. package/runtime/forge_contracts.py +519 -0
  471. package/runtime/forge_domains.py +68 -0
  472. package/runtime/forge_run_id.py +86 -0
  473. package/runtime/guide_assert.py +135 -0
  474. package/runtime/hook_governor.py +156 -0
  475. package/runtime/host_parity.py +373 -0
  476. package/runtime/incident_replay.py +310 -0
  477. package/runtime/install_planner.py +617 -0
  478. package/runtime/interaction_journal.py +566 -0
  479. package/runtime/issue_surface.py +472 -0
  480. package/runtime/legacy_compat.py +7 -0
  481. package/runtime/mcp_config_writers.py +360 -0
  482. package/runtime/mcp_lifecycle.py +175 -0
  483. package/runtime/mcp_memory_server.py +220 -0
  484. package/runtime/memory_parsers/__init__.py +0 -0
  485. package/runtime/memory_parsers/__pycache__/__init__.cpython-313.pyc +0 -0
  486. package/runtime/memory_parsers/__pycache__/chatgpt_parser.cpython-313.pyc +0 -0
  487. package/runtime/memory_parsers/__pycache__/claude_import.cpython-313.pyc +0 -0
  488. package/runtime/memory_parsers/__pycache__/export.cpython-313.pyc +0 -0
  489. package/runtime/memory_parsers/__pycache__/gemini_import.cpython-313.pyc +0 -0
  490. package/runtime/memory_parsers/__pycache__/kimi_import.cpython-313.pyc +0 -0
  491. package/runtime/memory_parsers/chatgpt_parser.py +257 -0
  492. package/runtime/memory_parsers/claude_import.py +107 -0
  493. package/runtime/memory_parsers/export.py +97 -0
  494. package/runtime/memory_parsers/gemini_import.py +91 -0
  495. package/runtime/memory_parsers/kimi_import.py +91 -0
  496. package/runtime/memory_store.py +1182 -0
  497. package/runtime/merge_writer.py +445 -0
  498. package/runtime/music_omr_testbed.py +336 -0
  499. package/runtime/mutation_gate.py +320 -0
  500. package/runtime/omc_compat.py +7 -0
  501. package/runtime/omg_browser_cli.py +95 -0
  502. package/runtime/omg_compat_contract_snapshot.json +936 -0
  503. package/runtime/omg_contract_snapshot.json +936 -0
  504. package/runtime/omg_mcp_server.py +306 -0
  505. package/runtime/playwright_adapter.py +39 -0
  506. package/runtime/playwright_pack.py +253 -0
  507. package/runtime/plugin_diagnostics.py +308 -0
  508. package/runtime/plugin_interop.py +1060 -0
  509. package/runtime/policy_pack_loader.py +147 -0
  510. package/runtime/preflight.py +135 -0
  511. package/runtime/profile_io.py +328 -0
  512. package/runtime/proof_chain.py +472 -0
  513. package/runtime/proof_gate.py +442 -0
  514. package/runtime/provider_parity_eval.py +109 -0
  515. package/runtime/providers/__init__.py +0 -0
  516. package/runtime/providers/__pycache__/__init__.cpython-313.pyc +0 -0
  517. package/runtime/providers/__pycache__/codex_provider.cpython-313.pyc +0 -0
  518. package/runtime/providers/__pycache__/gemini_provider.cpython-313.pyc +0 -0
  519. package/runtime/providers/__pycache__/kimi_provider.cpython-313.pyc +0 -0
  520. package/runtime/providers/__pycache__/opencode_provider.cpython-313.pyc +0 -0
  521. package/runtime/providers/codex_provider.py +129 -0
  522. package/runtime/providers/gemini_provider.py +143 -0
  523. package/runtime/providers/kimi_provider.py +167 -0
  524. package/runtime/providers/opencode_provider.py +99 -0
  525. package/runtime/release_artifact_audit.py +556 -0
  526. package/runtime/release_run_coordinator.py +574 -0
  527. package/runtime/release_surface_compiler.py +643 -0
  528. package/runtime/release_surface_registry.py +283 -0
  529. package/runtime/release_surfaces.py +320 -0
  530. package/runtime/remote_supervisor.py +79 -0
  531. package/runtime/repro_pack.py +398 -0
  532. package/runtime/rollback_manifest.py +143 -0
  533. package/runtime/router_critics.py +229 -0
  534. package/runtime/router_executor.py +142 -0
  535. package/runtime/router_selector.py +99 -0
  536. package/runtime/runtime_contracts.py +292 -0
  537. package/runtime/runtime_profile.py +133 -0
  538. package/runtime/security_check.py +1094 -0
  539. package/runtime/session_health.py +546 -0
  540. package/runtime/skill_evolution.py +221 -0
  541. package/runtime/skill_registry.py +53 -0
  542. package/runtime/subagent_dispatcher.py +604 -0
  543. package/runtime/subscription_tiers.py +258 -0
  544. package/runtime/team_router.py +1399 -0
  545. package/runtime/test_intent_lock.py +543 -0
  546. package/runtime/tmux_session_manager.py +172 -0
  547. package/runtime/tool_fabric.py +570 -0
  548. package/runtime/tool_plan_gate.py +460 -0
  549. package/runtime/tracebank.py +125 -0
  550. package/runtime/untrusted_content.py +360 -0
  551. package/runtime/validate.py +293 -0
  552. package/runtime/verdict_schema.py +198 -0
  553. package/runtime/verification_controller.py +235 -0
  554. package/runtime/verification_loop.py +73 -0
  555. package/runtime/vision_artifacts.py +31 -0
  556. package/runtime/vision_cache.py +38 -0
  557. package/runtime/vision_jobs.py +92 -0
  558. package/runtime/worker_watchdog.py +526 -0
  559. package/scripts/__pycache__/audit-published-artifact.cpython-313.pyc +0 -0
  560. package/scripts/__pycache__/check-doc-parity.cpython-313.pyc +0 -0
  561. package/scripts/__pycache__/check-omg-standalone-clean.cpython-313.pyc +0 -0
  562. package/scripts/__pycache__/github_review_helpers.cpython-313.pyc +0 -0
  563. package/scripts/__pycache__/omg.cpython-313.pyc +0 -0
  564. package/scripts/__pycache__/prepare-release-proof-fixtures.cpython-313.pyc +0 -0
  565. package/scripts/__pycache__/sync-release-identity.cpython-313.pyc +0 -0
  566. package/scripts/__pycache__/validate-release-identity.cpython-313.pyc +0 -0
  567. package/scripts/audit-published-artifact.py +59 -0
  568. package/scripts/check-omg-compat-contract-snapshot.py +137 -0
  569. package/scripts/check-omg-contract-snapshot.py +12 -0
  570. package/scripts/check-omg-public-ready.py +273 -0
  571. package/scripts/check-omg-standalone-clean.py +133 -0
  572. package/scripts/emit_host_parity.py +72 -0
  573. package/scripts/legacy_to_omg_migrate.py +29 -0
  574. package/scripts/migrate-legacy.py +464 -0
  575. package/scripts/omc_to_omg_migrate.py +12 -0
  576. package/scripts/omg.py +2962 -0
  577. package/scripts/pre-release-check.sh +38 -0
  578. package/scripts/prepare-release-proof-fixtures.py +602 -0
  579. package/scripts/print-canonical-version.py +80 -0
  580. package/scripts/settings-merge.py +289 -0
  581. package/scripts/sync-release-identity.py +481 -0
  582. package/scripts/validate-release-identity.py +632 -0
  583. package/scripts/verify-no-omc.sh +5 -0
  584. package/scripts/verify-standalone.sh +35 -0
  585. package/settings.json +751 -0
  586. package/tools/__init__.py +2 -0
  587. package/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  588. package/tools/__pycache__/browser_consent.cpython-313.pyc +0 -0
  589. package/tools/__pycache__/browser_stealth.cpython-313.pyc +0 -0
  590. package/tools/__pycache__/browser_tool.cpython-313.pyc +0 -0
  591. package/tools/__pycache__/changelog_generator.cpython-313.pyc +0 -0
  592. package/tools/__pycache__/commit_splitter.cpython-313.pyc +0 -0
  593. package/tools/__pycache__/config_discovery.cpython-313.pyc +0 -0
  594. package/tools/__pycache__/config_merger.cpython-313.pyc +0 -0
  595. package/tools/__pycache__/dashboard_generator.cpython-313.pyc +0 -0
  596. package/tools/__pycache__/git_inspector.cpython-313.pyc +0 -0
  597. package/tools/__pycache__/lsp_client.cpython-313.pyc +0 -0
  598. package/tools/__pycache__/lsp_operations.cpython-313.pyc +0 -0
  599. package/tools/__pycache__/pr_generator.cpython-313.pyc +0 -0
  600. package/tools/__pycache__/python_repl.cpython-313.pyc +0 -0
  601. package/tools/__pycache__/python_sandbox.cpython-313.pyc +0 -0
  602. package/tools/__pycache__/session_snapshot.cpython-313.pyc +0 -0
  603. package/tools/__pycache__/ssh_manager.cpython-313.pyc +0 -0
  604. package/tools/__pycache__/theme_engine.cpython-313.pyc +0 -0
  605. package/tools/__pycache__/theme_selector.cpython-313.pyc +0 -0
  606. package/tools/__pycache__/web_search.cpython-313.pyc +0 -0
  607. package/tools/browser_consent.py +289 -0
  608. package/tools/browser_stealth.py +481 -0
  609. package/tools/browser_tool.py +448 -0
  610. package/tools/changelog_generator.py +347 -0
  611. package/tools/commit_splitter.py +749 -0
  612. package/tools/config_discovery.py +151 -0
  613. package/tools/config_merger.py +449 -0
  614. package/tools/dashboard_generator.py +300 -0
  615. package/tools/git_inspector.py +298 -0
  616. package/tools/lsp_client.py +275 -0
  617. package/tools/lsp_discovery.py +231 -0
  618. package/tools/lsp_operations.py +392 -0
  619. package/tools/pr_generator.py +404 -0
  620. package/tools/python_repl.py +712 -0
  621. package/tools/python_sandbox.py +768 -0
  622. package/tools/search_providers/__init__.py +77 -0
  623. package/tools/search_providers/__pycache__/__init__.cpython-313.pyc +0 -0
  624. package/tools/search_providers/__pycache__/brave.cpython-313.pyc +0 -0
  625. package/tools/search_providers/__pycache__/exa.cpython-313.pyc +0 -0
  626. package/tools/search_providers/__pycache__/jina.cpython-313.pyc +0 -0
  627. package/tools/search_providers/__pycache__/perplexity.cpython-313.pyc +0 -0
  628. package/tools/search_providers/__pycache__/synthetic.cpython-313.pyc +0 -0
  629. package/tools/search_providers/brave.py +115 -0
  630. package/tools/search_providers/exa.py +116 -0
  631. package/tools/search_providers/jina.py +104 -0
  632. package/tools/search_providers/perplexity.py +139 -0
  633. package/tools/search_providers/synthetic.py +74 -0
  634. package/tools/session_snapshot.py +851 -0
  635. package/tools/ssh_manager.py +912 -0
  636. package/tools/theme_engine.py +296 -0
  637. package/tools/theme_selector.py +137 -0
  638. package/tools/web_search.py +675 -0
@@ -0,0 +1,150 @@
1
+ """Protected context registry for PreCompact hook.
2
+
3
+ Reads .claude-context-protect entries (file paths, regex patterns, literal strings)
4
+ and collects protected context items to re-inject via additionalContext during compaction.
5
+
6
+ Default protections (when no .claude-context-protect exists):
7
+ - CLAUDE.md content
8
+ - Active task definitions (## Task:, - [ ])
9
+ - Recent error messages (Error:, Exception:, FAILED)
10
+
11
+ Pure stdlib — no external dependencies.
12
+ """
13
+ import os
14
+ import re
15
+
16
+
17
+ PROTECT_FILE_NAME = ".claude-context-protect"
18
+
19
+ # Default protection patterns (used when no protect file exists)
20
+ _DEFAULT_TASK_PATTERNS = [
21
+ re.compile(r"^## Task:"),
22
+ re.compile(r"^- \[ \]"),
23
+ ]
24
+ _DEFAULT_ERROR_KEYWORDS = ("Error:", "Exception:", "FAILED")
25
+
26
+
27
+ def load_protect_entries(project_dir):
28
+ """Read .claude-context-protect file, return list of entries or None if missing.
29
+
30
+ Returns:
31
+ list[str] | None: List of non-empty, non-comment lines. None if file missing.
32
+ """
33
+ protect_path = os.path.join(project_dir, PROTECT_FILE_NAME)
34
+ if not os.path.isfile(protect_path):
35
+ return None
36
+
37
+ try:
38
+ with open(protect_path, "r", encoding="utf-8", errors="ignore") as f:
39
+ lines = f.readlines()
40
+ except Exception:
41
+ return None
42
+
43
+ entries = []
44
+ for line in lines:
45
+ stripped = line.strip()
46
+ if stripped and not stripped.startswith("#"):
47
+ entries.append(stripped)
48
+ return entries
49
+
50
+
51
+ def _read_file_content(file_path):
52
+ """Read file content. Returns stripped string or None on failure."""
53
+ try:
54
+ if not os.path.isfile(file_path):
55
+ return None
56
+ with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
57
+ content = f.read().strip()
58
+ return content if content else None
59
+ except Exception:
60
+ return None
61
+
62
+
63
+ def _match_entry_against_lines(entry, context_lines):
64
+ """Match entry against context lines. Tries regex first, falls back to literal.
65
+
66
+ Returns:
67
+ list[str]: Matching lines.
68
+ """
69
+ try:
70
+ pattern = re.compile(entry)
71
+ return [line for line in context_lines if pattern.search(line)]
72
+ except re.error:
73
+ # Invalid regex — fall back to literal substring match
74
+ return [line for line in context_lines if entry in line]
75
+
76
+
77
+ def _process_entry(entry, project_dir, context_lines):
78
+ """Process a single protect entry. Returns list of protected strings.
79
+
80
+ Resolution order:
81
+ 1. If entry resolves to an existing file → include file content
82
+ 2. Otherwise, try regex match against context lines
83
+ 3. If regex fails (re.error), fall back to literal substring match
84
+ """
85
+ # 1. Try as file path
86
+ file_path = os.path.join(project_dir, entry)
87
+ content = _read_file_content(file_path)
88
+ if content is not None:
89
+ return [content]
90
+
91
+ # 2. Try as regex/literal against context lines
92
+ return _match_entry_against_lines(entry, context_lines)
93
+
94
+
95
+ def _get_default_protections(project_dir, context_lines):
96
+ """Apply default protections when no .claude-context-protect exists.
97
+
98
+ Default protected items:
99
+ - CLAUDE.md content (if file exists)
100
+ - Active task definitions (## Task:, - [ ])
101
+ - Recent error messages (Error:, Exception:, FAILED)
102
+ """
103
+ parts = []
104
+
105
+ # 1. CLAUDE.md content
106
+ claude_md_path = os.path.join(project_dir, "CLAUDE.md")
107
+ claude_content = _read_file_content(claude_md_path)
108
+ if claude_content:
109
+ parts.append(claude_content)
110
+
111
+ # 2. Active task definitions
112
+ for line in context_lines:
113
+ for pat in _DEFAULT_TASK_PATTERNS:
114
+ if pat.search(line):
115
+ parts.append(line)
116
+ break
117
+
118
+ # 3. Recent error messages
119
+ for line in context_lines:
120
+ if any(kw in line for kw in _DEFAULT_ERROR_KEYWORDS):
121
+ parts.append(line)
122
+
123
+ return parts
124
+
125
+
126
+ def collect_protected_context(project_dir, context_text=""):
127
+ """Collect all protected context items and return as a single string.
128
+
129
+ Args:
130
+ project_dir: Project root directory.
131
+ context_text: Current context text to scan for regex/literal matches.
132
+
133
+ Returns:
134
+ str: Protected context items joined by newlines. Empty string if nothing.
135
+ """
136
+ context_lines = [l for l in context_text.split("\n") if l.strip()] if context_text else []
137
+ protected_parts = []
138
+
139
+ entries = load_protect_entries(project_dir)
140
+
141
+ if entries is None:
142
+ # No protect file — use defaults
143
+ protected_parts = _get_default_protections(project_dir, context_lines)
144
+ else:
145
+ # Process each entry from protect file
146
+ for entry in entries:
147
+ matched = _process_entry(entry, project_dir, context_lines)
148
+ protected_parts.extend(matched)
149
+
150
+ return "\n".join(protected_parts) if protected_parts else ""
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env python3
2
+ """Tiered token estimation helpers for OMG hooks."""
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import importlib
8
+ import urllib.request
9
+ from collections.abc import Iterable
10
+
11
+ API_URL = "https://api.anthropic.com/v1/messages/count_tokens"
12
+ API_MODEL = "claude-3-5-haiku-20241022"
13
+
14
+ _FEATURE_UI_DISPLAY = "ui_display"
15
+ _FEATURE_BUDGET_ENFORCEMENT = "budget_enforcement"
16
+ _FEATURE_PREFLIGHT = "preflight"
17
+
18
+
19
+ def _safe_int(value: float) -> int:
20
+ if value <= 0:
21
+ return 0
22
+ return int(value)
23
+
24
+
25
+ def _extract_features(text: str) -> tuple[int, int, int]:
26
+ encoded = text.encode("utf-8")
27
+ byte_count = len(encoded)
28
+ word_count = len(text.split())
29
+ line_count = text.count("\n") + (1 if text else 0)
30
+ return byte_count, word_count, line_count
31
+
32
+
33
+ def _default_coefficients() -> tuple[float, float, float, float]:
34
+ return (1.0, 0.19, 0.75, 1.1)
35
+
36
+
37
+ def _gaussian_solve(matrix: list[list[float]], vector: list[float]) -> list[float] | None:
38
+ n = len(vector)
39
+ if n == 0:
40
+ return None
41
+ try:
42
+ for i in range(n):
43
+ pivot = i
44
+ for r in range(i + 1, n):
45
+ if abs(matrix[r][i]) > abs(matrix[pivot][i]):
46
+ pivot = r
47
+ if abs(matrix[pivot][i]) < 1e-12:
48
+ return None
49
+
50
+ if pivot != i:
51
+ matrix[i], matrix[pivot] = matrix[pivot], matrix[i]
52
+ vector[i], vector[pivot] = vector[pivot], vector[i]
53
+
54
+ pivot_val = matrix[i][i]
55
+ for c in range(i, n):
56
+ matrix[i][c] /= pivot_val
57
+ vector[i] /= pivot_val
58
+
59
+ for r in range(n):
60
+ if r == i:
61
+ continue
62
+ factor = matrix[r][i]
63
+ if factor == 0:
64
+ continue
65
+ for c in range(i, n):
66
+ matrix[r][c] -= factor * matrix[i][c]
67
+ vector[r] -= factor * vector[i]
68
+ return vector
69
+ except Exception:
70
+ return None
71
+
72
+
73
+ def _fit_linear_coefficients(samples: Iterable[tuple[str, int]]) -> tuple[float, float, float, float]:
74
+ rows: list[list[float]] = []
75
+ targets: list[float] = []
76
+ for text, tokens in samples:
77
+ bcount, wcount, lcount = _extract_features(text)
78
+ rows.append([1.0, float(bcount), float(wcount), float(lcount)])
79
+ targets.append(float(tokens))
80
+
81
+ dim = 4
82
+ if len(rows) < dim:
83
+ return _default_coefficients()
84
+
85
+ xtx = [[0.0 for _ in range(dim)] for _ in range(dim)]
86
+ xty = [0.0 for _ in range(dim)]
87
+ for row, target in zip(rows, targets):
88
+ for i in range(dim):
89
+ xty[i] += row[i] * target
90
+ for j in range(dim):
91
+ xtx[i][j] += row[i] * row[j]
92
+
93
+ solved = _gaussian_solve(xtx, xty)
94
+ if solved is None:
95
+ return _default_coefficients()
96
+
97
+ return (float(solved[0]), float(solved[1]), float(solved[2]), float(solved[3]))
98
+
99
+
100
+ _CALIBRATION_SAMPLES: tuple[tuple[str, int], ...] = (
101
+ ("ls", 5),
102
+ ("git status", 7),
103
+ ("echo 'hello world'", 10),
104
+ ("python3 -m pytest tests/hooks/test_feature_flags_v2.py -q", 18),
105
+ ("def hello():\n return 'world'\n", 24),
106
+ (
107
+ """from pathlib import Path\nfor path in Path('hooks').glob('*.py'):\n print(path.name)\n""",
108
+ 44,
109
+ ),
110
+ (
111
+ """def estimate_tokens(text: str, tier: int = 1) -> int:\n if tier == 1:\n return max(1, int(len(text) / 3.5))\n return 0\n""",
112
+ 80,
113
+ ),
114
+ (
115
+ "\n".join(["line with common code and comments" for _ in range(80)]),
116
+ 720,
117
+ ),
118
+ (
119
+ "\n".join(["longer source line with punctuation () {} [] == != <= >=" for _ in range(250)]),
120
+ 1800,
121
+ ),
122
+ )
123
+
124
+ _COEFFICIENTS = _fit_linear_coefficients(_CALIBRATION_SAMPLES)
125
+
126
+
127
+ def _estimate_tier1(text: str) -> int:
128
+ if not text:
129
+ return 0
130
+ return max(1, int(len(text) / 3.5))
131
+
132
+
133
+ def _estimate_tier2(text: str) -> int:
134
+ if not text:
135
+ return 0
136
+ bias, w_bytes, w_words, w_lines = _COEFFICIENTS
137
+ bcount, wcount, lcount = _extract_features(text)
138
+ prediction = bias + (w_bytes * bcount) + (w_words * wcount) + (w_lines * lcount)
139
+ return max(1, _safe_int(prediction))
140
+
141
+
142
+ def _get_anthropic_api_key() -> str | None:
143
+ try:
144
+ store_mod = importlib.import_module("credential_store")
145
+ key = store_mod.get_active_key("anthropic")
146
+ if key:
147
+ return key
148
+ except (ImportError, RuntimeError, ValueError, OSError, AttributeError):
149
+ pass
150
+ return os.environ.get("ANTHROPIC_API_KEY")
151
+
152
+
153
+ def _estimate_tier3(text: str) -> int:
154
+ if not text:
155
+ return 0
156
+
157
+ api_key = _get_anthropic_api_key()
158
+ if not api_key:
159
+ return _estimate_tier2(text)
160
+
161
+ payload = {
162
+ "model": API_MODEL,
163
+ "messages": [{"role": "user", "content": text}],
164
+ }
165
+ body = json.dumps(payload).encode("utf-8")
166
+ request = urllib.request.Request(
167
+ API_URL,
168
+ data=body,
169
+ method="POST",
170
+ headers={
171
+ "content-type": "application/json",
172
+ "x-api-key": api_key,
173
+ "anthropic-version": "2023-06-01",
174
+ },
175
+ )
176
+
177
+ try:
178
+ with urllib.request.urlopen(request, timeout=8) as response:
179
+ raw = response.read().decode("utf-8")
180
+ parsed = json.loads(raw)
181
+ token_value = parsed.get("input_tokens")
182
+ if isinstance(token_value, int) and token_value >= 0:
183
+ return token_value
184
+ except Exception:
185
+ return _estimate_tier2(text)
186
+
187
+ return _estimate_tier2(text)
188
+
189
+
190
+ def auto_select_tier(operation: str, text: str = "") -> int:
191
+ normalized = (operation or "").strip().lower()
192
+ if normalized == _FEATURE_UI_DISPLAY:
193
+ return 1
194
+ if normalized == _FEATURE_BUDGET_ENFORCEMENT:
195
+ return 2
196
+ if normalized == _FEATURE_PREFLIGHT:
197
+ if len(text) >= 8000:
198
+ return 3
199
+ if _estimate_tier2(text) >= 1000:
200
+ return 3
201
+ return 2
202
+ return 1
203
+
204
+
205
+ def estimate_tokens(text: str, tier: int = 1) -> int:
206
+ """Estimate token count with 3 reliability/cost tiers.
207
+
208
+ Tier 1: fast heuristic (`len(text)/3.5`).
209
+ Tier 2: calibrated linear model using bytes, words, lines.
210
+ Tier 3: Anthropic count_tokens API with graceful fallback to tier 2.
211
+ """
212
+ try:
213
+ if tier == 1:
214
+ return _estimate_tier1(text)
215
+ if tier == 2:
216
+ return _estimate_tier2(text)
217
+ if tier == 3:
218
+ return _estimate_tier3(text)
219
+ return _estimate_tier1(text)
220
+ except Exception:
221
+ return _estimate_tier1(text)
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ """SessionStart Hook — Smart Branch Manager.
3
+
4
+ Auto-creates a feature branch when on main/master/develop.
5
+ Extracts task description from OMG state files for branch naming.
6
+
7
+ Feature-gated: OMG_GIT_WORKFLOW_ENABLED (uses get_feature_flag('GIT_WORKFLOW'))
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+ import re
14
+ import subprocess
15
+ import sys
16
+ from datetime import datetime
17
+
18
+ HOOKS_DIR = os.path.dirname(__file__)
19
+ if HOOKS_DIR not in sys.path:
20
+ sys.path.insert(0, HOOKS_DIR)
21
+
22
+ from _common import setup_crash_handler, json_input, get_feature_flag
23
+
24
+ setup_crash_handler("branch-manager", fail_closed=False)
25
+
26
+ # Default branches that trigger feature branch creation
27
+ DEFAULT_BRANCHES = frozenset({"main", "master", "develop"})
28
+
29
+ # Max length for the descriptive part of branch name
30
+ MAX_BRANCH_NAME_LEN = 50
31
+
32
+
33
+ def _get_project_dir() -> str:
34
+ """Get project directory from env or cwd."""
35
+ return os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
36
+
37
+
38
+ def _has_git(project_dir: str) -> bool:
39
+ """Check if project_dir is inside a git repo."""
40
+ try:
41
+ result = subprocess.run(
42
+ ["git", "-C", project_dir, "rev-parse", "--git-dir"],
43
+ capture_output=True, text=True, timeout=5,
44
+ )
45
+ return result.returncode == 0
46
+ except Exception:
47
+ return False
48
+
49
+
50
+ def _current_branch(project_dir: str) -> str | None:
51
+ """Get current branch name. Returns None on failure."""
52
+ try:
53
+ result = subprocess.run(
54
+ ["git", "-C", project_dir, "rev-parse", "--abbrev-ref", "HEAD"],
55
+ capture_output=True, text=True, timeout=5,
56
+ )
57
+ if result.returncode == 0:
58
+ return result.stdout.strip()
59
+ except Exception:
60
+ pass
61
+ return None
62
+
63
+
64
+ def _sanitize_branch_name(description: str) -> str:
65
+ """Sanitize a description into a valid git branch name segment.
66
+
67
+ Rules:
68
+ - Lowercase
69
+ - Replace spaces/underscores with hyphens
70
+ - Strip special characters (keep alphanumeric and hyphens)
71
+ - Collapse consecutive hyphens
72
+ - Strip leading/trailing hyphens
73
+ - Max MAX_BRANCH_NAME_LEN chars
74
+ """
75
+ name = description.lower().strip()
76
+ # Replace spaces and underscores with hyphens
77
+ name = re.sub(r"[\s_]+", "-", name)
78
+ # Remove everything except alphanumeric and hyphens
79
+ name = re.sub(r"[^a-z0-9-]", "", name)
80
+ # Collapse consecutive hyphens
81
+ name = re.sub(r"-{2,}", "-", name)
82
+ # Strip leading/trailing hyphens
83
+ name = name.strip("-")
84
+ # Truncate to max length, but don't cut mid-word if possible
85
+ if len(name) > MAX_BRANCH_NAME_LEN:
86
+ truncated = name[:MAX_BRANCH_NAME_LEN]
87
+ # Try to cut at last hyphen to avoid mid-word truncation
88
+ last_hyphen = truncated.rfind("-")
89
+ if last_hyphen > 20:
90
+ truncated = truncated[:last_hyphen]
91
+ name = truncated.rstrip("-")
92
+ return name
93
+
94
+
95
+ def _extract_task_description(project_dir: str) -> str | None:
96
+ """Extract task description from OMG state files.
97
+
98
+ Priority order:
99
+ (a) .omg/state/_plan.md title (first # heading)
100
+ (b) .omg/state/_checklist.md first item
101
+ (c) .omg/state/working-memory.md last entry
102
+ (d) fallback: None (caller uses session-{timestamp})
103
+ """
104
+ state_dir = os.path.join(project_dir, ".omg", "state")
105
+
106
+ # (a) Plan title
107
+ plan_path = os.path.join(state_dir, "_plan.md")
108
+ if os.path.isfile(plan_path):
109
+ try:
110
+ with open(plan_path, "r", encoding="utf-8", errors="ignore") as f:
111
+ for line in f:
112
+ line = line.strip()
113
+ if line.startswith("# "):
114
+ title = line[2:].strip()
115
+ if title:
116
+ return title
117
+ except Exception:
118
+ pass
119
+
120
+ # (b) Checklist first item
121
+ checklist_path = os.path.join(state_dir, "_checklist.md")
122
+ if os.path.isfile(checklist_path):
123
+ try:
124
+ with open(checklist_path, "r", encoding="utf-8", errors="ignore") as f:
125
+ for line in f:
126
+ line = line.strip()
127
+ # Match markdown checkbox items: - [ ] or - [x]
128
+ m = re.match(r"^-\s*\[.\]\s*(.+)$", line)
129
+ if m:
130
+ item = m.group(1).strip()
131
+ if item:
132
+ return item
133
+ except Exception:
134
+ pass
135
+
136
+ # (c) Working memory last entry
137
+ wm_path = os.path.join(state_dir, "working-memory.md")
138
+ if os.path.isfile(wm_path):
139
+ try:
140
+ with open(wm_path, "r", encoding="utf-8", errors="ignore") as f:
141
+ content = f.read()
142
+ # Split by ## headings, take last entry's content
143
+ sections = re.split(r"\n## ", content)
144
+ if len(sections) > 1:
145
+ # Last section: first line is heading, rest is content
146
+ last_lines = sections[-1].split("\n")
147
+ # Find first non-empty content line after heading
148
+ for line in last_lines[1:]:
149
+ line = line.strip()
150
+ if line:
151
+ return line
152
+ # Fallback to heading if no content
153
+ heading = last_lines[0].strip()
154
+ if heading:
155
+ return heading
156
+ elif sections:
157
+ # Single section — try first non-empty non-heading line
158
+ for line in sections[0].split("\n"):
159
+ line = line.strip()
160
+ if line and not line.startswith("#"):
161
+ return line
162
+ except Exception:
163
+ pass
164
+
165
+ # (d) No state files found
166
+ return None
167
+
168
+
169
+ def _is_merge_writer_locked(project_dir: str) -> bool:
170
+ try:
171
+ _root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
172
+ if _root not in sys.path:
173
+ sys.path.insert(0, _root)
174
+ from runtime.merge_writer import MergeWriter # pyright: ignore[reportMissingImports]
175
+ return MergeWriter(project_dir).is_locked()
176
+ except Exception:
177
+ return False
178
+
179
+
180
+ def _create_branch(project_dir: str, branch_name: str) -> bool:
181
+ """Create and checkout a new branch. Returns True on success."""
182
+ if _is_merge_writer_locked(project_dir):
183
+ print(
184
+ f"[OMG branch-manager] Branch creation blocked: merge-writer lock is held",
185
+ file=sys.stderr,
186
+ )
187
+ return False
188
+ try:
189
+ result = subprocess.run(
190
+ ["git", "-C", project_dir, "checkout", "-b", branch_name],
191
+ capture_output=True, text=True, timeout=10,
192
+ )
193
+ return result.returncode == 0
194
+ except Exception:
195
+ return False
196
+
197
+
198
+ def main() -> None:
199
+ """Main hook entry point."""
200
+ data = json_input()
201
+
202
+ # Feature gate: exit silently if disabled
203
+ if not get_feature_flag("GIT_WORKFLOW", default=False):
204
+ sys.exit(0)
205
+
206
+ project_dir = _get_project_dir()
207
+
208
+ # No-op if not a git repo
209
+ if not _has_git(project_dir):
210
+ sys.exit(0)
211
+
212
+ # Get current branch
213
+ branch = _current_branch(project_dir)
214
+ if branch is None:
215
+ sys.exit(0)
216
+
217
+ # No-op if already on a non-default branch (feature branch, etc.)
218
+ if branch not in DEFAULT_BRANCHES:
219
+ sys.exit(0)
220
+
221
+ # Extract task description and build branch name
222
+ description = _extract_task_description(project_dir)
223
+ if description:
224
+ sanitized = _sanitize_branch_name(description)
225
+ else:
226
+ sanitized = ""
227
+
228
+ if not sanitized:
229
+ # Fallback: session-{timestamp}
230
+ sanitized = f"session-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
231
+
232
+ target_branch = f"feature/{sanitized}"
233
+
234
+ # Dry-run mode: output what would happen without executing
235
+ dry_run = os.environ.get("OMG_GIT_WORKFLOW_DRY_RUN", "").lower() in ("1", "true", "yes")
236
+ if dry_run:
237
+ print(
238
+ f"[OMG branch-manager] DRY-RUN: Would create branch '{target_branch}' from '{branch}'",
239
+ file=sys.stderr,
240
+ )
241
+ sys.exit(0)
242
+
243
+ # Create the feature branch
244
+ success = _create_branch(project_dir, target_branch)
245
+ if success:
246
+ print(
247
+ f"[OMG branch-manager] Created branch '{target_branch}' from '{branch}'",
248
+ file=sys.stderr,
249
+ )
250
+
251
+ sys.exit(0)
252
+
253
+
254
+ if __name__ == "__main__":
255
+ main()