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

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 (242) 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 +102 -79
  4. package/dist/cli-node/index.js +102 -79
  5. package/dist/index.js +439 -420
  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/ambience-skill.md +2 -1
  28. package/dist/skills/frontend/references/design/clone-from-url.md +1 -1
  29. package/dist/skills/frontend/references/design/design-system-architecture.md +30 -7
  30. package/dist/skills/frontend/references/design/interaction-skill.md +17 -5
  31. package/dist/skills/programming/SKILL.md +12 -18
  32. package/dist/skills/programming/references/rust/README.md +43 -15
  33. package/dist/skills/programming/references/rust/api-design.md +81 -0
  34. package/dist/skills/programming/references/rust/async-tokio.md +60 -28
  35. package/dist/skills/programming/references/rust/axum-stack.md +1 -13
  36. package/dist/skills/programming/references/rust/cargo-strict.md +44 -8
  37. package/dist/skills/programming/references/rust/clap-stack.md +8 -3
  38. package/dist/skills/programming/references/rust/concurrency.md +66 -52
  39. package/dist/skills/programming/references/rust/libraries.md +35 -25
  40. package/dist/skills/programming/references/rust/macros.md +63 -0
  41. package/dist/skills/programming/references/rust/one-liners.md +5 -3
  42. package/dist/skills/programming/references/rust/proptest-insta.md +8 -0
  43. package/dist/skills/programming/references/rust/type-state.md +50 -12
  44. package/dist/skills/programming/references/rust/unsafe-discipline.md +34 -6
  45. package/dist/skills/programming/references/rust/zero-cost-safety.md +62 -52
  46. package/dist/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  47. package/dist/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  48. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  49. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.test.ts +83 -0
  50. package/dist/skills/programming/scripts/rust/new-project.py +31 -28
  51. package/dist/skills/review-work/SKILL.md +1 -1
  52. package/dist/skills/ultimate-browsing/SKILL.md +27 -20
  53. package/dist/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  54. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  55. package/dist/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  56. package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  57. package/dist/skills/ulw-execute/SKILL.md +4 -4
  58. package/dist/skills/visual-qa/SKILL.md +1 -1
  59. package/dist/skills/visual-qa/references/browser-setup.md +46 -46
  60. package/dist/tui.js +6 -3
  61. package/package.json +15 -14
  62. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  63. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -0
  64. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  65. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  66. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  67. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  68. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  69. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  70. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  71. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  72. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  73. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  74. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  75. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +1 -1
  76. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  77. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  78. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  79. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  80. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  81. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  82. package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
  83. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  84. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +63 -89
  85. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  86. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  87. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  88. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +2 -2
  89. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  90. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +63 -89
  92. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  93. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  94. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +2 -3
  95. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  96. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  116. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  117. package/packages/omo-codex/plugin/package-lock.json +12 -12
  118. package/packages/omo-codex/plugin/package.json +1 -1
  119. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +8 -2
  120. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -2
  121. package/packages/omo-codex/plugin/skills/browser/ATTRIBUTION.md +26 -14
  122. package/packages/omo-codex/plugin/skills/browser/SKILL.md +65 -52
  123. package/packages/omo-codex/plugin/skills/browser/references/commands.md +81 -66
  124. package/packages/omo-codex/plugin/skills/browser/references/install.md +31 -34
  125. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/README.md +41 -21
  126. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  127. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/ladder.md +24 -22
  128. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/network.md +35 -15
  129. package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +13 -11
  130. package/packages/omo-codex/plugin/skills/browser/references/remote.md +5 -4
  131. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +1534 -0
  132. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +9 -0
  133. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  134. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +37 -32
  135. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +31 -44
  136. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +25 -0
  137. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -2
  138. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +3 -3
  139. package/packages/omo-codex/plugin/skills/debugging/references/methodology/08-qa.md +1 -1
  140. package/packages/omo-codex/plugin/skills/debugging/references/tools/browser-qa.md +104 -0
  141. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +1 -1
  142. package/packages/omo-codex/plugin/skills/frontend/references/design/ambience-skill.md +2 -1
  143. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  144. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +30 -7
  145. package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +17 -5
  146. package/packages/omo-codex/plugin/skills/programming/SKILL.md +12 -18
  147. package/packages/omo-codex/plugin/skills/programming/references/rust/README.md +43 -15
  148. package/packages/omo-codex/plugin/skills/programming/references/rust/api-design.md +81 -0
  149. package/packages/omo-codex/plugin/skills/programming/references/rust/async-tokio.md +60 -28
  150. package/packages/omo-codex/plugin/skills/programming/references/rust/axum-stack.md +1 -13
  151. package/packages/omo-codex/plugin/skills/programming/references/rust/cargo-strict.md +44 -8
  152. package/packages/omo-codex/plugin/skills/programming/references/rust/clap-stack.md +8 -3
  153. package/packages/omo-codex/plugin/skills/programming/references/rust/concurrency.md +66 -52
  154. package/packages/omo-codex/plugin/skills/programming/references/rust/libraries.md +35 -25
  155. package/packages/omo-codex/plugin/skills/programming/references/rust/macros.md +63 -0
  156. package/packages/omo-codex/plugin/skills/programming/references/rust/one-liners.md +5 -3
  157. package/packages/omo-codex/plugin/skills/programming/references/rust/proptest-insta.md +8 -0
  158. package/packages/omo-codex/plugin/skills/programming/references/rust/type-state.md +50 -12
  159. package/packages/omo-codex/plugin/skills/programming/references/rust/unsafe-discipline.md +34 -6
  160. package/packages/omo-codex/plugin/skills/programming/references/rust/zero-cost-safety.md +62 -52
  161. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  162. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  163. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  164. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +31 -28
  165. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +1 -1
  166. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +27 -20
  167. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  168. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  169. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  170. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  171. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +63 -89
  172. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +4 -4
  173. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +2 -3
  174. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  175. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +1 -1
  176. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +46 -46
  177. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -2
  178. package/packages/omo-codex/scripts/install-dist/install-local.mjs +4 -2
  179. package/packages/prompts-core/prompts/ultrawork/codex.md +63 -89
  180. package/packages/shared-skills/skills/browser/ATTRIBUTION.md +26 -14
  181. package/packages/shared-skills/skills/browser/SKILL.md +65 -52
  182. package/packages/shared-skills/skills/browser/references/commands.md +81 -66
  183. package/packages/shared-skills/skills/browser/references/install.md +31 -34
  184. package/packages/shared-skills/skills/browser/references/owned-engine/README.md +41 -21
  185. package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  186. package/packages/shared-skills/skills/browser/references/owned-engine/ladder.md +24 -22
  187. package/packages/shared-skills/skills/browser/references/owned-engine/network.md +35 -15
  188. package/packages/shared-skills/skills/browser/references/recipes/1password.md +13 -11
  189. package/packages/shared-skills/skills/browser/references/remote.md +5 -4
  190. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +1534 -0
  191. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +9 -0
  192. package/packages/shared-skills/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  193. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +37 -32
  194. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +31 -44
  195. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +25 -0
  196. package/packages/shared-skills/skills/debugging/SKILL.md +2 -2
  197. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +3 -3
  198. package/packages/shared-skills/skills/debugging/references/methodology/08-qa.md +1 -1
  199. package/packages/shared-skills/skills/debugging/references/tools/browser-qa.md +104 -0
  200. package/packages/shared-skills/skills/frontend/SKILL.md +1 -1
  201. package/packages/shared-skills/skills/frontend/references/design/ambience-skill.md +2 -1
  202. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  203. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +30 -7
  204. package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +17 -5
  205. package/packages/shared-skills/skills/programming/SKILL.md +12 -18
  206. package/packages/shared-skills/skills/programming/references/rust/README.md +43 -15
  207. package/packages/shared-skills/skills/programming/references/rust/api-design.md +81 -0
  208. package/packages/shared-skills/skills/programming/references/rust/async-tokio.md +60 -28
  209. package/packages/shared-skills/skills/programming/references/rust/axum-stack.md +1 -13
  210. package/packages/shared-skills/skills/programming/references/rust/cargo-strict.md +44 -8
  211. package/packages/shared-skills/skills/programming/references/rust/clap-stack.md +8 -3
  212. package/packages/shared-skills/skills/programming/references/rust/concurrency.md +66 -52
  213. package/packages/shared-skills/skills/programming/references/rust/libraries.md +35 -25
  214. package/packages/shared-skills/skills/programming/references/rust/macros.md +63 -0
  215. package/packages/shared-skills/skills/programming/references/rust/one-liners.md +5 -3
  216. package/packages/shared-skills/skills/programming/references/rust/proptest-insta.md +8 -0
  217. package/packages/shared-skills/skills/programming/references/rust/type-state.md +50 -12
  218. package/packages/shared-skills/skills/programming/references/rust/unsafe-discipline.md +34 -6
  219. package/packages/shared-skills/skills/programming/references/rust/zero-cost-safety.md +62 -52
  220. package/packages/shared-skills/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  221. package/packages/shared-skills/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  222. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  223. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.test.ts +83 -0
  224. package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +31 -28
  225. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  226. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +27 -20
  227. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  228. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  229. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  230. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  231. package/packages/shared-skills/skills/ulw-execute/SKILL.md +4 -4
  232. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
  233. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +46 -46
  234. package/dist/skills/browser/scripts/browser-env.mjs +0 -41
  235. package/dist/skills/debugging/references/tools/playwright-cli.md +0 -112
  236. package/dist/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
  237. package/packages/omo-codex/plugin/skills/browser/scripts/browser-env.mjs +0 -41
  238. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +0 -112
  239. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
  240. package/packages/shared-skills/skills/browser/scripts/browser-env.mjs +0 -41
  241. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +0 -112
  242. 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()