oh-my-opencode 5.0.0-beta.86 → 5.0.0-beta.87

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 (233) hide show
  1. package/.agents/skills/hyperplan/SKILL.md +1 -1
  2. package/.opencode/skills/hyperplan/SKILL.md +1 -1
  3. package/dist/cli/index.js +27 -21
  4. package/dist/cli-node/index.js +27 -21
  5. package/dist/index.js +85 -87
  6. package/dist/skills/browser/ATTRIBUTION.md +26 -14
  7. package/dist/skills/browser/SKILL.md +65 -52
  8. package/dist/skills/browser/references/commands.md +81 -66
  9. package/dist/skills/browser/references/install.md +31 -34
  10. package/dist/skills/browser/references/owned-engine/README.md +41 -21
  11. package/dist/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  12. package/dist/skills/browser/references/owned-engine/ladder.md +24 -22
  13. package/dist/skills/browser/references/owned-engine/network.md +35 -15
  14. package/dist/skills/browser/references/recipes/1password.md +13 -11
  15. package/dist/skills/browser/references/remote.md +5 -4
  16. package/dist/skills/browser/runtime/omowright/index.js +1534 -0
  17. package/dist/skills/browser/runtime/omowright/manifest.json +9 -0
  18. package/dist/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  19. package/dist/skills/browser/scripts/browser-doctor.mjs +37 -32
  20. package/dist/skills/browser/scripts/browser-install.mjs +31 -44
  21. package/dist/skills/browser/scripts/omowright.mjs +25 -0
  22. package/dist/skills/debugging/SKILL.md +2 -2
  23. package/dist/skills/debugging/references/methodology/06-fix.md +3 -3
  24. package/dist/skills/debugging/references/methodology/08-qa.md +1 -1
  25. package/dist/skills/debugging/references/tools/browser-qa.md +104 -0
  26. package/dist/skills/frontend/SKILL.md +1 -1
  27. package/dist/skills/frontend/references/design/clone-from-url.md +1 -1
  28. package/dist/skills/programming/SKILL.md +12 -18
  29. package/dist/skills/programming/references/rust/README.md +43 -15
  30. package/dist/skills/programming/references/rust/api-design.md +81 -0
  31. package/dist/skills/programming/references/rust/async-tokio.md +60 -28
  32. package/dist/skills/programming/references/rust/axum-stack.md +1 -13
  33. package/dist/skills/programming/references/rust/cargo-strict.md +44 -8
  34. package/dist/skills/programming/references/rust/clap-stack.md +8 -3
  35. package/dist/skills/programming/references/rust/concurrency.md +66 -52
  36. package/dist/skills/programming/references/rust/libraries.md +35 -25
  37. package/dist/skills/programming/references/rust/macros.md +63 -0
  38. package/dist/skills/programming/references/rust/one-liners.md +5 -3
  39. package/dist/skills/programming/references/rust/proptest-insta.md +8 -0
  40. package/dist/skills/programming/references/rust/type-state.md +50 -12
  41. package/dist/skills/programming/references/rust/unsafe-discipline.md +34 -6
  42. package/dist/skills/programming/references/rust/zero-cost-safety.md +62 -52
  43. package/dist/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  44. package/dist/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  45. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  46. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.test.ts +83 -0
  47. package/dist/skills/programming/scripts/rust/new-project.py +31 -28
  48. package/dist/skills/review-work/SKILL.md +1 -1
  49. package/dist/skills/ultimate-browsing/SKILL.md +27 -20
  50. package/dist/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  51. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  52. package/dist/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  53. package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  54. package/dist/skills/ulw-execute/SKILL.md +4 -4
  55. package/dist/skills/visual-qa/SKILL.md +1 -1
  56. package/dist/skills/visual-qa/references/browser-setup.md +46 -46
  57. package/dist/tui.js +6 -3
  58. package/package.json +15 -14
  59. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  60. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -0
  61. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  62. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  63. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  64. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  65. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  66. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  67. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  68. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  69. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  70. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  71. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  72. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +1 -1
  73. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  74. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  75. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  76. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  77. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  78. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  79. package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
  80. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  81. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +63 -89
  82. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  83. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  84. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  85. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +2 -2
  86. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  87. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  88. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +63 -89
  89. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  90. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +2 -3
  92. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  93. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  114. package/packages/omo-codex/plugin/package-lock.json +12 -12
  115. package/packages/omo-codex/plugin/package.json +1 -1
  116. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +8 -2
  117. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -2
  118. package/packages/omo-codex/plugin/skills/browser/ATTRIBUTION.md +26 -14
  119. package/packages/omo-codex/plugin/skills/browser/SKILL.md +65 -52
  120. package/packages/omo-codex/plugin/skills/browser/references/commands.md +81 -66
  121. package/packages/omo-codex/plugin/skills/browser/references/install.md +31 -34
  122. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/README.md +41 -21
  123. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  124. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/ladder.md +24 -22
  125. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/network.md +35 -15
  126. package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +13 -11
  127. package/packages/omo-codex/plugin/skills/browser/references/remote.md +5 -4
  128. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +1534 -0
  129. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +9 -0
  130. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  131. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +37 -32
  132. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +31 -44
  133. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +25 -0
  134. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -2
  135. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +3 -3
  136. package/packages/omo-codex/plugin/skills/debugging/references/methodology/08-qa.md +1 -1
  137. package/packages/omo-codex/plugin/skills/debugging/references/tools/browser-qa.md +104 -0
  138. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +1 -1
  139. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  140. package/packages/omo-codex/plugin/skills/programming/SKILL.md +12 -18
  141. package/packages/omo-codex/plugin/skills/programming/references/rust/README.md +43 -15
  142. package/packages/omo-codex/plugin/skills/programming/references/rust/api-design.md +81 -0
  143. package/packages/omo-codex/plugin/skills/programming/references/rust/async-tokio.md +60 -28
  144. package/packages/omo-codex/plugin/skills/programming/references/rust/axum-stack.md +1 -13
  145. package/packages/omo-codex/plugin/skills/programming/references/rust/cargo-strict.md +44 -8
  146. package/packages/omo-codex/plugin/skills/programming/references/rust/clap-stack.md +8 -3
  147. package/packages/omo-codex/plugin/skills/programming/references/rust/concurrency.md +66 -52
  148. package/packages/omo-codex/plugin/skills/programming/references/rust/libraries.md +35 -25
  149. package/packages/omo-codex/plugin/skills/programming/references/rust/macros.md +63 -0
  150. package/packages/omo-codex/plugin/skills/programming/references/rust/one-liners.md +5 -3
  151. package/packages/omo-codex/plugin/skills/programming/references/rust/proptest-insta.md +8 -0
  152. package/packages/omo-codex/plugin/skills/programming/references/rust/type-state.md +50 -12
  153. package/packages/omo-codex/plugin/skills/programming/references/rust/unsafe-discipline.md +34 -6
  154. package/packages/omo-codex/plugin/skills/programming/references/rust/zero-cost-safety.md +62 -52
  155. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  156. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  157. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  158. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +31 -28
  159. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +1 -1
  160. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +27 -20
  161. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  162. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  163. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  164. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  165. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +63 -89
  166. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +4 -4
  167. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +2 -3
  168. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  169. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +1 -1
  170. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +46 -46
  171. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -2
  172. package/packages/omo-codex/scripts/install-dist/install-local.mjs +4 -2
  173. package/packages/prompts-core/prompts/ultrawork/codex.md +63 -89
  174. package/packages/shared-skills/skills/browser/ATTRIBUTION.md +26 -14
  175. package/packages/shared-skills/skills/browser/SKILL.md +65 -52
  176. package/packages/shared-skills/skills/browser/references/commands.md +81 -66
  177. package/packages/shared-skills/skills/browser/references/install.md +31 -34
  178. package/packages/shared-skills/skills/browser/references/owned-engine/README.md +41 -21
  179. package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  180. package/packages/shared-skills/skills/browser/references/owned-engine/ladder.md +24 -22
  181. package/packages/shared-skills/skills/browser/references/owned-engine/network.md +35 -15
  182. package/packages/shared-skills/skills/browser/references/recipes/1password.md +13 -11
  183. package/packages/shared-skills/skills/browser/references/remote.md +5 -4
  184. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +1534 -0
  185. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +9 -0
  186. package/packages/shared-skills/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  187. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +37 -32
  188. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +31 -44
  189. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +25 -0
  190. package/packages/shared-skills/skills/debugging/SKILL.md +2 -2
  191. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +3 -3
  192. package/packages/shared-skills/skills/debugging/references/methodology/08-qa.md +1 -1
  193. package/packages/shared-skills/skills/debugging/references/tools/browser-qa.md +104 -0
  194. package/packages/shared-skills/skills/frontend/SKILL.md +1 -1
  195. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  196. package/packages/shared-skills/skills/programming/SKILL.md +12 -18
  197. package/packages/shared-skills/skills/programming/references/rust/README.md +43 -15
  198. package/packages/shared-skills/skills/programming/references/rust/api-design.md +81 -0
  199. package/packages/shared-skills/skills/programming/references/rust/async-tokio.md +60 -28
  200. package/packages/shared-skills/skills/programming/references/rust/axum-stack.md +1 -13
  201. package/packages/shared-skills/skills/programming/references/rust/cargo-strict.md +44 -8
  202. package/packages/shared-skills/skills/programming/references/rust/clap-stack.md +8 -3
  203. package/packages/shared-skills/skills/programming/references/rust/concurrency.md +66 -52
  204. package/packages/shared-skills/skills/programming/references/rust/libraries.md +35 -25
  205. package/packages/shared-skills/skills/programming/references/rust/macros.md +63 -0
  206. package/packages/shared-skills/skills/programming/references/rust/one-liners.md +5 -3
  207. package/packages/shared-skills/skills/programming/references/rust/proptest-insta.md +8 -0
  208. package/packages/shared-skills/skills/programming/references/rust/type-state.md +50 -12
  209. package/packages/shared-skills/skills/programming/references/rust/unsafe-discipline.md +34 -6
  210. package/packages/shared-skills/skills/programming/references/rust/zero-cost-safety.md +62 -52
  211. package/packages/shared-skills/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  212. package/packages/shared-skills/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  213. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  214. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.test.ts +83 -0
  215. package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +31 -28
  216. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  217. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +27 -20
  218. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  219. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  220. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  221. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  222. package/packages/shared-skills/skills/ulw-execute/SKILL.md +4 -4
  223. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
  224. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +46 -46
  225. package/dist/skills/browser/scripts/browser-env.mjs +0 -41
  226. package/dist/skills/debugging/references/tools/playwright-cli.md +0 -112
  227. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
  228. package/packages/omo-codex/plugin/skills/browser/scripts/browser-env.mjs +0 -41
  229. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +0 -112
  230. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
  231. package/packages/shared-skills/skills/browser/scripts/browser-env.mjs +0 -41
  232. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +0 -112
  233. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
@@ -1,296 +0,0 @@
1
- #!/usr/bin/env -S uv run --script
2
- # /// script
3
- # requires-python = ">=3.11"
4
- # dependencies = []
5
- # ///
6
- #
7
- # How to run:
8
- # uv run --script check-no-excuse-rules.py src/lib.rs src/main.rs
9
- # uv run --script check-no-excuse-rules.py src/ # recursively finds .rs files
10
- # uv run --script check-no-excuse-rules.py . # entire tree
11
- #
12
- # No-excuse rule checker for Rust files — Python rewrite of check-no-excuse-rules.sh.
13
- # Only rules enforceable via pure text matching live here.
14
- # Everything semantic is on clippy + miri + nextest.
15
- #
16
- # Rules:
17
- # unwrap .unwrap() outside tests without // SAFE-UNWRAP:
18
- # expect .expect() outside tests without // SAFE-EXPECT:
19
- # placeholder-macro todo!/unimplemented!/unreachable!/unreachable_unchecked! in committed code
20
- # box-dyn-error Box<dyn Error> in non-test code
21
- # lib-panic panic!() in library code
22
- # unsafe-no-safety unsafe { without // SAFETY: in preceding 5 lines
23
- # unjustified-clippy-allow #[allow(clippy::...)] without // CLIPPY-ALLOW:
24
- # narrowing-as-cast possible narrowing 'as' cast
25
- #
26
- # Opt-out: place the appropriate comment on the previous line:
27
- # // SAFE-UNWRAP: <reason>
28
- # // SAFE-EXPECT: <reason>
29
- # // SAFETY: <reason> (for unsafe blocks, within 5 lines above)
30
- # // CLIPPY-ALLOW: <reason>
31
- #
32
- # Test paths (exempt from unwrap/expect/placeholder/box-dyn-error/lib-panic):
33
- # tests/, benches/, examples/, build.rs, *_test.rs, #[cfg(test)] regions
34
-
35
- from __future__ import annotations
36
-
37
- import re
38
- import sys
39
- from pathlib import Path
40
-
41
- # ---------------------------------------------------------------------------
42
- # Patterns (compiled once)
43
- # ---------------------------------------------------------------------------
44
-
45
- RE_UNWRAP = re.compile(r"\.unwrap\(\)")
46
- RE_EXPECT = re.compile(r"\.expect\(")
47
- RE_PLACEHOLDER = re.compile(r"\b(todo!|unimplemented!|unreachable!|unreachable_unchecked!)")
48
- RE_BOX_DYN_ERROR = re.compile(r"Box<dyn\s+Error")
49
- RE_PANIC = re.compile(r"\bpanic!\(")
50
- RE_UNSAFE_BLOCK = re.compile(r"\bunsafe\s*\{")
51
- RE_CLIPPY_ALLOW = re.compile(r"#\[allow\(clippy::")
52
- RE_CFG_TEST = re.compile(r"#\[cfg\(test\)\]")
53
- RE_SAFE_UNWRAP = re.compile(r"//\s*SAFE-UNWRAP:")
54
- RE_SAFE_EXPECT = re.compile(r"//\s*SAFE-EXPECT:")
55
- RE_SAFETY = re.compile(r"//\s*SAFETY:")
56
- RE_CLIPPY_ALLOW_JUST = re.compile(r"//\s*CLIPPY-ALLOW:")
57
-
58
- # Narrowing cast: (wider) as (narrower)
59
- # Wider types that lose bits when cast to narrower targets.
60
- # No leading \b — must match e.g. `999u64 as u32` where a digit precedes the type.
61
- _WIDER = r"(?:u16|u32|u64|u128|usize|i16|i32|i64|i128|isize)"
62
- _NARROWER = r"(?:u8|u16|u32|i8|i16|i32)"
63
- RE_NARROWING_CAST = re.compile(
64
- rf"{_WIDER}\s+as\s+{_NARROWER}"
65
- )
66
-
67
- # Test-path fragments.
68
- _TEST_PATH_PARTS = {"tests", "benches", "examples"}
69
-
70
-
71
- # ---------------------------------------------------------------------------
72
- # Helpers
73
- # ---------------------------------------------------------------------------
74
-
75
- violations = 0
76
-
77
-
78
- def report(file: str, line: int, rule: str, detail: str) -> None:
79
- """Emit a GitHub-Actions-compatible error annotation to stderr."""
80
- global violations
81
- print(f"::error file={file},line={line}::[{rule}] {detail}", file=sys.stderr)
82
- violations += 1
83
-
84
-
85
- def is_test_path(path: Path) -> bool:
86
- """Return True if *path* is in a test/bench/example directory or is a test file."""
87
- parts = path.parts
88
- for part in parts:
89
- if part in _TEST_PATH_PARTS:
90
- return True
91
- if path.name == "build.rs":
92
- return True
93
- if path.name.endswith("_test.rs"):
94
- return True
95
- return False
96
-
97
-
98
- def is_lib_path(file: Path) -> bool:
99
- """Heuristic: is this file library code (not main.rs, not src/bin/*)."""
100
- parts = path_parts_str(file)
101
- # Must live under src/
102
- if "src" not in parts:
103
- return False
104
- if file.name == "main.rs":
105
- return False
106
- # src/bin/* is binary code
107
- try:
108
- src_idx = parts.index("src")
109
- if src_idx + 1 < len(parts) and parts[src_idx + 1] == "bin":
110
- return False
111
- except ValueError:
112
- return False
113
- return True
114
-
115
-
116
- def path_parts_str(p: Path) -> list[str]:
117
- return list(p.parts)
118
-
119
-
120
- def strip_line_comment(line: str) -> str:
121
- """Return the portion of *line* before any ``//`` line comment.
122
-
123
- This is a crude heuristic — it does not handle ``//`` inside string
124
- literals, but matches the behaviour of the bash version.
125
- """
126
- idx = line.find("//")
127
- if idx == -1:
128
- return line
129
- return line[:idx]
130
-
131
-
132
- def collect_rs_files(args: list[str]) -> list[Path]:
133
- """Expand CLI arguments: files are kept as-is, directories are walked."""
134
- result: list[Path] = []
135
- for arg in args:
136
- p = Path(arg)
137
- if p.is_file():
138
- if p.suffix == ".rs":
139
- result.append(p)
140
- elif p.is_dir():
141
- result.extend(sorted(p.rglob("*.rs")))
142
- # Ignore non-existent / non-.rs
143
- return result
144
-
145
-
146
- # ---------------------------------------------------------------------------
147
- # Main checker
148
- # ---------------------------------------------------------------------------
149
-
150
- def check_file(file: Path) -> None:
151
- in_test_file = is_test_path(file)
152
- in_cfg_test = False
153
- cfg_test_brace_depth = 0
154
-
155
- try:
156
- lines = file.read_text(encoding="utf-8", errors="replace").splitlines()
157
- except OSError as exc:
158
- print(f"warning: cannot read {file}: {exc}", file=sys.stderr)
159
- return
160
-
161
- for line_no_0, raw_line in enumerate(lines):
162
- line_no = line_no_0 + 1 # 1-indexed
163
-
164
- # --- #[cfg(test)] region tracker ---
165
- if RE_CFG_TEST.search(raw_line):
166
- in_cfg_test = True
167
- cfg_test_brace_depth = 0
168
-
169
- if in_cfg_test:
170
- opens = raw_line.count("{")
171
- closes = raw_line.count("}")
172
- cfg_test_brace_depth += opens - closes
173
- if cfg_test_brace_depth <= 0 and not RE_CFG_TEST.search(raw_line):
174
- in_cfg_test = False
175
-
176
- exempt = in_test_file or in_cfg_test
177
- code_only = strip_line_comment(raw_line)
178
-
179
- if not exempt:
180
- # .unwrap()
181
- if RE_UNWRAP.search(code_only):
182
- prev = lines[line_no_0 - 1] if line_no_0 > 0 else ""
183
- if not RE_SAFE_UNWRAP.search(prev):
184
- report(
185
- str(file), line_no, "unwrap",
186
- ".unwrap() outside tests - use ? / ok_or / pattern match "
187
- "or annotate previous line with // SAFE-UNWRAP: <reason>",
188
- )
189
-
190
- # .expect(...)
191
- if RE_EXPECT.search(code_only):
192
- prev = lines[line_no_0 - 1] if line_no_0 > 0 else ""
193
- if not RE_SAFE_EXPECT.search(prev):
194
- report(
195
- str(file), line_no, "expect",
196
- ".expect() outside tests - use ? or annotate previous "
197
- "line with // SAFE-EXPECT: <reason>",
198
- )
199
-
200
- # todo!/unimplemented!/unreachable!/unreachable_unchecked!
201
- if RE_PLACEHOLDER.search(code_only):
202
- report(
203
- str(file), line_no, "placeholder-macro",
204
- "todo!/unimplemented!/unreachable! in committed code",
205
- )
206
-
207
- # Box<dyn Error>
208
- if RE_BOX_DYN_ERROR.search(code_only):
209
- report(
210
- str(file), line_no, "box-dyn-error",
211
- "Box<dyn Error> in non-test code - use anyhow::Error (apps) "
212
- "or thiserror enum (libs)",
213
- )
214
-
215
- # panic!() in library code
216
- if is_lib_path(file) and RE_PANIC.search(code_only):
217
- report(
218
- str(file), line_no, "lib-panic",
219
- "panic!() in library code - return Result",
220
- )
221
-
222
- # unsafe { without // SAFETY: — always enforced, even in tests
223
- if RE_UNSAFE_BLOCK.search(code_only):
224
- start = max(0, line_no_0 - 5)
225
- window = "\n".join(lines[start : line_no_0 + 1])
226
- if not RE_SAFETY.search(window):
227
- report(
228
- str(file), line_no, "unsafe-no-safety-comment",
229
- "unsafe block without // SAFETY: comment in preceding 5 lines",
230
- )
231
-
232
- # #[allow(clippy::...)] without // CLIPPY-ALLOW: — always enforced
233
- if RE_CLIPPY_ALLOW.search(code_only):
234
- prev = lines[line_no_0 - 1] if line_no_0 > 0 else ""
235
- if not RE_CLIPPY_ALLOW_JUST.search(prev):
236
- report(
237
- str(file), line_no, "unjustified-clippy-allow",
238
- "#[allow(clippy::...)] without // CLIPPY-ALLOW: <reason> on "
239
- "previous line",
240
- )
241
-
242
- # Narrowing numeric `as` casts
243
- if RE_NARROWING_CAST.search(code_only):
244
- report(
245
- str(file), line_no, "narrowing-as-cast",
246
- "possible narrowing 'as' cast - use TryFrom / try_into() for "
247
- "fallible conversion",
248
- )
249
-
250
-
251
- # ---------------------------------------------------------------------------
252
- # Entry point
253
- # ---------------------------------------------------------------------------
254
-
255
- def main() -> None:
256
- global violations
257
-
258
- if len(sys.argv) < 2:
259
- print(f"Usage: {sys.argv[0]} <file.rs|dir> [file.rs|dir ...]", file=sys.stderr)
260
- sys.exit(2)
261
-
262
- files = collect_rs_files(sys.argv[1:])
263
- if not files:
264
- print("warning: no .rs files found in the given arguments", file=sys.stderr)
265
- sys.exit(0)
266
-
267
- for f in files:
268
- check_file(f)
269
-
270
- if violations > 0:
271
- print("", file=sys.stderr)
272
- print(
273
- f"rust-programmer: {violations} violation(s). Fix before declaring work done.",
274
- file=sys.stderr,
275
- )
276
- print("", file=sys.stderr)
277
- print("Then run the full toolchain gate:", file=sys.stderr)
278
- print(" cargo +stable fmt --all -- --check", file=sys.stderr)
279
- print(
280
- " cargo +stable clippy --all-targets --all-features -- -D warnings",
281
- file=sys.stderr,
282
- )
283
- print(" cargo nextest run --all-targets --all-features", file=sys.stderr)
284
- print(
285
- " cargo +nightly miri nextest run --all-features # if unsafe touched",
286
- file=sys.stderr,
287
- )
288
- print(" cargo machete", file=sys.stderr)
289
- print(" cargo deny check", file=sys.stderr)
290
- sys.exit(1)
291
-
292
- print(f"rust-programmer: no-excuse rules passed for {len(files)} file(s).")
293
-
294
-
295
- if __name__ == "__main__":
296
- main()