blockwatch-cli 0.16.1__tar.gz → 0.16.2__tar.gz

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 (297) hide show
  1. blockwatch_cli-0.16.2/.agents/skills/blockwatch/SKILL.md +14 -0
  2. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/AGENTS.md +5 -4
  3. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/CHANGELOG.md +28 -0
  4. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/CLAUDE.md +5 -4
  5. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/Cargo.lock +1 -1
  6. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/Cargo.toml +1 -1
  7. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/PKG-INFO +1 -1
  8. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/README.md +5 -5
  9. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/blockwatch.toml +2 -2
  10. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/agents.md +11 -12
  11. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/ci.md +2 -2
  12. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/cli.md +6 -11
  13. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/symbols.md +127 -9
  14. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/setup.py +1 -1
  15. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/c.rs +7 -0
  16. blockwatch_cli-0.16.2/src/language_parsers/c_sharp.rs +1083 -0
  17. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/go.rs +2 -0
  18. blockwatch_cli-0.16.2/src/language_parsers/java.rs +872 -0
  19. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/mod.rs +2 -0
  20. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/python.rs +1 -0
  21. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/rust.rs +1 -0
  22. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/typescript.rs +3 -10
  23. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/yaml.rs +109 -42
  24. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/skill.md +67 -13
  25. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbols/code.rs +214 -47
  26. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbols/mod.rs +67 -23
  27. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/skill.rs +10 -0
  28. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/symbol_references.rs +14 -0
  29. blockwatch_cli-0.16.2/tests/testdata/symbol_references/cs_source.rs +3 -0
  30. blockwatch_cli-0.16.2/tests/testdata/symbol_references/cs_target.cs +6 -0
  31. blockwatch_cli-0.16.2/tests/testdata/symbol_references/java_source.rs +3 -0
  32. blockwatch_cli-0.16.2/tests/testdata/symbol_references/java_target.java +5 -0
  33. blockwatch_cli-0.16.1/.agents/skills/blockwatch/SKILL.md +0 -14
  34. blockwatch_cli-0.16.1/src/language_parsers/c_sharp.rs +0 -91
  35. blockwatch_cli-0.16.1/src/language_parsers/java.rs +0 -152
  36. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.agents/.claude-plugin/plugin.json +0 -0
  37. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.claude-plugin/marketplace.json +0 -0
  38. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/dependabot.yml +0 -0
  39. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/blockwatch.yml +0 -0
  40. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/codeql.yml +0 -0
  41. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/markdownlint.yml +0 -0
  42. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/pypi.yml +0 -0
  43. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/release.yml +0 -0
  44. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/rust.yml +0 -0
  45. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/trusted-checks.yml +0 -0
  46. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.gitignore +0 -0
  47. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.markdownlint-cli2.yaml +0 -0
  48. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.pre-commit-config.yaml +0 -0
  49. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.pre-commit-hooks.yaml +0 -0
  50. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/LICENSE +0 -0
  51. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/SECURITY.md +0 -0
  52. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/clippy.toml +0 -0
  53. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/codecov.yml +0 -0
  54. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/demo.gif +0 -0
  55. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/dist-workspace.toml +0 -0
  56. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/README.md +0 -0
  57. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/affects.md +0 -0
  58. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/check-ai.md +0 -0
  59. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/check-lua.md +0 -0
  60. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/keep-sorted.md +0 -0
  61. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/keep-unique.md +0 -0
  62. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/line-count.md +0 -0
  63. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/line-pattern.md +0 -0
  64. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/same-as.md +0 -0
  65. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/pypi/pyproject.toml +0 -0
  66. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/pyproject.toml +0 -0
  67. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/release.toml +0 -0
  68. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/scripts/check_language_count.lua +0 -0
  69. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/scripts/check_latest_gpt_nano_model.lua +0 -0
  70. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/block_parser.rs +0 -0
  71. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/blocks.rs +0 -0
  72. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/cli.rs +0 -0
  73. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/config.rs +0 -0
  74. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/diff_parser.rs +0 -0
  75. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/explain.rs +0 -0
  76. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/flags.rs +0 -0
  77. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/fs.rs +0 -0
  78. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/bash.rs +0 -0
  79. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/cmake.rs +0 -0
  80. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/cpp.rs +0 -0
  81. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/css.rs +0 -0
  82. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/dart.rs +0 -0
  83. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/dockerfile.rs +0 -0
  84. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/elixir.rs +0 -0
  85. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/graphql.rs +0 -0
  86. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/groovy.rs +0 -0
  87. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/hcl.rs +0 -0
  88. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/html.rs +0 -0
  89. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/javascript.rs +0 -0
  90. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/json.rs +0 -0
  91. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/json.scm +0 -0
  92. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/kotlin.rs +0 -0
  93. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/lean.rs +0 -0
  94. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/lua.rs +0 -0
  95. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/makefile.rs +0 -0
  96. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/markdown.rs +0 -0
  97. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/mdx.rs +0 -0
  98. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/nix.rs +0 -0
  99. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/ocaml.rs +0 -0
  100. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/php.rs +0 -0
  101. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/proto.rs +0 -0
  102. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/ruby.rs +0 -0
  103. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/scala.rs +0 -0
  104. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/sql.rs +0 -0
  105. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/starlark.rs +0 -0
  106. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/swift.rs +0 -0
  107. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/toml.rs +0 -0
  108. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/tsx.rs +0 -0
  109. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/xml.rs +0 -0
  110. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/lib.rs +0 -0
  111. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/main.rs +0 -0
  112. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/path_arguments.rs +0 -0
  113. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/paths_glob.rs +0 -0
  114. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/repo_path.rs +0 -0
  115. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/report.rs +0 -0
  116. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/sarif.rs +0 -0
  117. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/scan.rs +0 -0
  118. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/settings.rs +0 -0
  119. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbol_path.rs +0 -0
  120. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/tag_parser.rs +0 -0
  121. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/target_reference.rs +0 -0
  122. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/affects.rs +0 -0
  123. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/check_ai.rs +0 -0
  124. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/check_lua.rs +0 -0
  125. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/keep_sorted.rs +0 -0
  126. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/keep_unique.rs +0 -0
  127. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/line_count.rs +0 -0
  128. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/line_pattern.rs +0 -0
  129. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/mod.rs +0 -0
  130. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/same_as.rs +0 -0
  131. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/violation_address.rs +0 -0
  132. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/virtual_blocks.rs +0 -0
  133. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/affects.rs +0 -0
  134. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/check_ai.rs +0 -0
  135. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/check_lua.rs +0 -0
  136. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/common/empty.toml +0 -0
  137. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/common/mod.rs +0 -0
  138. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/config.rs +0 -0
  139. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/encoding.rs +0 -0
  140. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/explain.rs +0 -0
  141. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/general.rs +0 -0
  142. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/keep_sorted.rs +0 -0
  143. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/keep_unique.rs +0 -0
  144. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/line_count.rs +0 -0
  145. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/line_pattern.rs +0 -0
  146. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/list.rs +0 -0
  147. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/path_arguments.rs +0 -0
  148. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/repository_root.rs +0 -0
  149. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/same_as.rs +0 -0
  150. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/sarif.rs +0 -0
  151. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/suppressions.rs +0 -0
  152. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/cross_file_source.rs +0 -0
  153. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/cross_file_target.md +0 -0
  154. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/custom_ext_source.javascript +0 -0
  155. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/custom_ext_target.javascript +0 -0
  156. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/dangling.md +0 -0
  157. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/missing_symbol.rs +0 -0
  158. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/more_added_than_deleted.py +0 -0
  159. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/multiline_tag_source.rs +0 -0
  160. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/multiline_tag_target.rs +0 -0
  161. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/nested_mapping_source.rs +0 -0
  162. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/nested_mapping_target.yaml +0 -0
  163. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/sibling.md +0 -0
  164. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/symbol_source.rs +0 -0
  165. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/symbol_target.json +0 -0
  166. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/table_source.rs +0 -0
  167. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/table_target.toml +0 -0
  168. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/tag_and_content_source.ts +0 -0
  169. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/tag_and_content_target.ts +0 -0
  170. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/whole_file_source.rs +0 -0
  171. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/whole_file_target.json +0 -0
  172. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_ai/two_blocks.py +0 -0
  173. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects.lua +0 -0
  174. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects.py +0 -0
  175. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects_drift.py +0 -0
  176. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/blocking_io.lua +0 -0
  177. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/blocking_io.py +0 -0
  178. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/echo.lua +0 -0
  179. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/fail.lua +0 -0
  180. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/mode.py +0 -0
  181. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/os.lua +0 -0
  182. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pathfmt/report_path.lua +0 -0
  183. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pathfmt/source.py +0 -0
  184. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern.py +0 -0
  185. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern_many_matches.py +0 -0
  186. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern_no_match.py +0 -0
  187. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/success.lua +0 -0
  188. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/success_and_failure.py +0 -0
  189. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/config.toml +0 -0
  190. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/package.json +0 -0
  191. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/blue/package.json +0 -0
  192. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/green/package.json +0 -0
  193. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/red/package.json +0 -0
  194. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/explain/a.py +0 -0
  195. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/explain/check.lua +0 -0
  196. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/block_selection.py +0 -0
  197. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/custom_file_extension.javascript +0 -0
  198. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/custom_file_extension.python +0 -0
  199. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/disable_enable.py +0 -0
  200. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/invalid.py +0 -0
  201. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/subdir/nested_invalid.py +0 -0
  202. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/valid.py +0 -0
  203. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/severity.py +0 -0
  204. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/hidden/.github/workflows/ci.yml +0 -0
  205. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/keep_sorted/orderings.py +0 -0
  206. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/keep_unique/basic_and_pattern.py +0 -0
  207. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_count/equality_and_greater_than.py +0 -0
  208. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_pattern/forbidden_text.py +0 -0
  209. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_pattern/hex_and_word_patterns.py +0 -0
  210. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/.hg/.gitkeep +0 -0
  211. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/a.py +0 -0
  212. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/b.py +0 -0
  213. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/positions/unicode_columns.py +0 -0
  214. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/custom_ext_source.javascript +0 -0
  215. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/custom_ext_target.javascript +0 -0
  216. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/package.json +0 -0
  217. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths/alpha/item.txt +0 -0
  218. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths/beta/item.txt +0 -0
  219. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths_and_block_source.md +0 -0
  220. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths_source.md +0 -0
  221. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/sibling.rs +0 -0
  222. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/source.rs +0 -0
  223. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/split_table_source.rs +0 -0
  224. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/split_table_target.toml +0 -0
  225. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/symbol_mismatch_source.rs +0 -0
  226. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/symbol_source.rs +0 -0
  227. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/target.md +0 -0
  228. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_mismatch_source.rs +0 -0
  229. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_source.rs +0 -0
  230. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_target.json +0 -0
  231. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/advisory.py +0 -0
  232. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/clean.py +0 -0
  233. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/sorted.py +0 -0
  234. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/unnamed.py +0 -0
  235. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg.txt +0 -0
  236. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_gone_a.txt +0 -0
  237. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_gone_b.txt +0 -0
  238. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_lowercase_trailer.txt +0 -0
  239. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_malformed.txt +0 -0
  240. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_with_noise.txt +0 -0
  241. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/dangling.py +0 -0
  242. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/sorted.py +0 -0
  243. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/symbol.py +0 -0
  244. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/symbol_target.json +0 -0
  245. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/two_rules.py +0 -0
  246. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/unnamed.py +0 -0
  247. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/bzl_source.rs +0 -0
  248. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/bzl_target.bzl +0 -0
  249. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/c_source.rs +0 -0
  250. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/c_target.c +0 -0
  251. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/cpp_source.rs +0 -0
  252. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/cpp_target.cpp +0 -0
  253. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/escapes_source.rs +0 -0
  254. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/escapes_target.json +0 -0
  255. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/filter_source.rs +0 -0
  256. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/filter_target.yaml +0 -0
  257. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/go_source.rs +0 -0
  258. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/go_target.go +0 -0
  259. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/h_source.rs +0 -0
  260. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/h_target.h +0 -0
  261. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/js_source.rs +0 -0
  262. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/js_target.js +0 -0
  263. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/json_source.rs +0 -0
  264. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/json_target.json +0 -0
  265. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/jsonc_source.rs +0 -0
  266. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/jsonc_target.jsonc +0 -0
  267. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/markdown_source.rs +0 -0
  268. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/markdown_target.markdown +0 -0
  269. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/md_source.rs +0 -0
  270. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/md_target.md +0 -0
  271. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mdx_source.rs +0 -0
  272. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mdx_target.mdx +0 -0
  273. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mixed_list_source.rs +0 -0
  274. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mixed_list_target.json +0 -0
  275. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/py_source.rs +0 -0
  276. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/py_target.py +0 -0
  277. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/rs_source.rs +0 -0
  278. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/rs_target.rs +0 -0
  279. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/toml_source.rs +0 -0
  280. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/toml_target.toml +0 -0
  281. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/ts_source.rs +0 -0
  282. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/ts_target.ts +0 -0
  283. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/tsx_source.rs +0 -0
  284. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/tsx_target.tsx +0 -0
  285. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yaml_source.rs +0 -0
  286. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yaml_target.yaml +0 -0
  287. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yml_source.rs +0 -0
  288. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yml_target.yml +0 -0
  289. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/affects/pair.py +0 -0
  290. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/counted.py +0 -0
  291. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/noop.py +0 -0
  292. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/notes.txt +0 -0
  293. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/sorted.py +0 -0
  294. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/diff/two_blocks.py +0 -0
  295. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/failing/unsorted.py +0 -0
  296. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/mixed/both_kinds.py +0 -0
  297. {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/verbosity.rs +0 -0
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: blockwatch
3
+ description: Use when a change touches something that another place must match, such as an enum and its docs, a constant and its config, a version written in two files, or a list that must stay sorted or unique. Also use it when a file you edit holds `<block ...>` tags, or `blockwatch.toml` points at it.
4
+ allowed-tools: Bash(blockwatch skill)
5
+ ---
6
+
7
+ # blockwatch skill
8
+
9
+ `blockwatch skill` prints the skill for the installed version:
10
+
11
+ !`blockwatch skill`
12
+
13
+ If its output is not shown above, run `blockwatch skill` and follow what it prints. If `blockwatch` is not installed,
14
+ run `uvx --from blockwatch-cli blockwatch skill` instead.
@@ -279,10 +279,11 @@ default), `safe` or `unsafe`.
279
279
  `src/skill.md`, `.agents/skills/blockwatch/SKILL.md` and `.claude-plugin/` are part of the *product*. They make up the
280
280
  skill this project ships, so that agents can add blocks to **other** repositories:
281
281
 
282
- - `src/skill.md` is the skill. `blockwatch skill` prints it with the version filled in, and users save that output in
283
- their projects.
284
- - `.agents/skills/blockwatch/SKILL.md` is a stub for the plugin in `.claude-plugin/`. It runs `blockwatch skill` each
285
- time it loads. It has its own copy of the description, and `tests/skill.rs` checks that the two copies match.
282
+ - `src/skill.md` is the skill. `blockwatch skill` prints it with the version filled in. Its section "Installing this
283
+ skill" holds the stub that users save in their projects. The stub runs `blockwatch skill` each time an agent loads
284
+ it.
285
+ - `.agents/skills/blockwatch/SKILL.md` is that stub, for the plugin in `.claude-plugin/`. `tests/skill.rs` checks that
286
+ it is the stub in `src/skill.md`, and that its description matches the one at the top of `src/skill.md`.
286
287
 
287
288
  They are not instructions for working on blockwatch, and changing them changes what users get. This file is the
288
289
  guidance for working on blockwatch.
@@ -12,6 +12,34 @@ Releases up to and including v0.3.11 predate this file. Their notes live on the
12
12
 
13
13
  ## [Unreleased] - ReleaseDate
14
14
 
15
+ ## [0.16.2] - 2026-10-30
16
+
17
+ ### Added
18
+
19
+ - Symbols in Java files. `Config.java#/Config/MAX_RETRIES` points at a field of the class `Config`, and
20
+ `#/Config/Mode/RED` at an enum constant. Each type is a symbol, and so is each field, method, enum constant and
21
+ nested type in it. A text block counts as the text Java reads, without the indentation its lines share. See
22
+ [Java](docs/symbols.md#java).
23
+ - Symbols in C# files. `Config.cs#/Acme/Billing/Config/MaxRetries` points at a constant of the class `Config` in the
24
+ namespace `Acme.Billing`. Each type is a symbol, and so is each field, property, method, event, enum member and
25
+ nested type in it. A raw string counts as the text C# reads, without the white space before its closing quotes. See
26
+ [C#](docs/symbols.md#c).
27
+
28
+ ### Changed
29
+
30
+ - Projects now install the agent skill as a short stub that runs `blockwatch skill` each time an agent loads it. So the
31
+ skill always matches the installed version. Before, projects saved the whole skill, which went stale until an agent
32
+ saved it again after an upgrade. A saved copy now tells the agent to replace it with the stub. See
33
+ [Annotating Codebases with AI Agents](docs/agents.md).
34
+ - The agent skill now loads when a change touches something that another place must match, such as an enum and its
35
+ docs, or a list that must stay sorted. It also loads for files with block tags, or that `blockwatch.toml` points at.
36
+ Before, it loaded for every code change. This applies to the Claude Code plugin too.
37
+
38
+ ### Fixed
39
+
40
+ - A path into a YAML file with lists or mappings nested hundreds of levels deep, such as `a: [[[...]]]`, no longer
41
+ crashes blockwatch with a stack overflow.
42
+
15
43
  ## [0.16.1] - 2026-10-28
16
44
 
17
45
  ### Added
@@ -279,10 +279,11 @@ default), `safe` or `unsafe`.
279
279
  `src/skill.md`, `.agents/skills/blockwatch/SKILL.md` and `.claude-plugin/` are part of the *product*. They make up the
280
280
  skill this project ships, so that agents can add blocks to **other** repositories:
281
281
 
282
- - `src/skill.md` is the skill. `blockwatch skill` prints it with the version filled in, and users save that output in
283
- their projects.
284
- - `.agents/skills/blockwatch/SKILL.md` is a stub for the plugin in `.claude-plugin/`. It runs `blockwatch skill` each
285
- time it loads. It has its own copy of the description, and `tests/skill.rs` checks that the two copies match.
282
+ - `src/skill.md` is the skill. `blockwatch skill` prints it with the version filled in. Its section "Installing this
283
+ skill" holds the stub that users save in their projects. The stub runs `blockwatch skill` each time an agent loads
284
+ it.
285
+ - `.agents/skills/blockwatch/SKILL.md` is that stub, for the plugin in `.claude-plugin/`. `tests/skill.rs` checks that
286
+ it is the stub in `src/skill.md`, and that its description matches the one at the top of `src/skill.md`.
286
287
 
287
288
  They are not instructions for working on blockwatch, and changing them changes what users get. This file is the
288
289
  guidance for working on blockwatch.
@@ -274,7 +274,7 @@ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
274
274
 
275
275
  [[package]]
276
276
  name = "blockwatch"
277
- version = "0.16.1"
277
+ version = "0.16.2"
278
278
  dependencies = [
279
279
  "anyhow",
280
280
  "assert-json-diff",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "blockwatch"
3
- version = "0.16.1"
3
+ version = "0.16.2"
4
4
  edition = "2024"
5
5
  repository = "https://github.com/mennanov/blockwatch"
6
6
  description = "Language agnostic linter that keeps your code and documentation in sync and valid"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockwatch-cli
3
- Version: 0.16.1
3
+ Version: 0.16.2
4
4
  Summary: Language agnostic linter that keeps your code and documentation in sync and valid
5
5
  Keywords: linter,sync,drift,comments,agents
6
6
  Home-Page: https://github.com/mennanov/blockwatch
@@ -29,7 +29,7 @@ Then paste this prompt into your AI coding agent:
29
29
  <!-- <block name="agent-prompt"> -->
30
30
 
31
31
  ```text
32
- Run `blockwatch skill` and save its output as `blockwatch/SKILL.md` in this project's skills directory. Then use the
32
+ Run `blockwatch skill` and install the skill in this project as its "Installing this skill" section says. Then use the
33
33
  skill to annotate the project and add `blockwatch.toml` if needed. List each block you added and the mistake it
34
34
  catches.
35
35
  ```
@@ -37,8 +37,8 @@ catches.
37
37
  <!-- </block> -->
38
38
 
39
39
  Review the suggested blocks and commit them. The skill stays in the project, so agents working on it later know
40
- the rules too. When you upgrade blockwatch, the skill tells the agent to save it again. To check every future change,
41
- add blockwatch to your [pre-commit hook or CI](#ci-integration).
40
+ the rules too. It runs `blockwatch skill` each time it loads, so it always matches the installed version. To check every
41
+ future change, add blockwatch to your [pre-commit hook or CI](#ci-integration).
42
42
 
43
43
  ## How it works
44
44
 
@@ -89,7 +89,7 @@ Two validators work across files:
89
89
  - `same-as` fails when a block and its target hold different values. It needs no diff.
90
90
 
91
91
  Both can point to a block, a whole file, a specific value in a file like `package.json#/version`, a section of a
92
- Markdown file, or a constant in a Go, C, C++, Python, Rust, TypeScript or JavaScript file (see
92
+ Markdown file, or a constant in a Go, C, C++, Python, Rust, TypeScript, JavaScript, Java or C# file (see
93
93
  [Symbols](docs/symbols.md)). The other validators check a single block on their own: the things you'd otherwise have to
94
94
  nitpick in code review.
95
95
 
@@ -219,7 +219,7 @@ exclusions, and custom extension mappings.
219
219
 
220
220
  ```yaml
221
221
  - repo: https://github.com/mennanov/blockwatch
222
- rev: v0.16.1 # Use latest release
222
+ rev: v0.16.2 # Use latest release
223
223
  hooks:
224
224
  - id: blockwatch
225
225
  ```
@@ -39,8 +39,8 @@ same-as = '''.github/workflows/codeql.yml,
39
39
  .github/workflows/rust.yml'''
40
40
  same-as-pattern = '(?:actions/checkout@|^)(?P<value>v\d+)$'
41
41
 
42
- # `blockwatch skill` prints src/skill.md, and projects save that output. A tag in that file would become a block in
43
- # every one of those projects. So blocks point at its sections by their headings, and these entries hold the pattern
42
+ # `blockwatch skill` prints src/skill.md, and some projects hold a saved copy of that output. A tag in that file would
43
+ # become a block in every one of those projects. So blocks point at its sections by their headings, and these entries hold the pattern
44
44
  # that reads a section, which the section can't hold itself.
45
45
  [[block]]
46
46
  target = 'src/skill.md#/blockwatch/Validator reference'
@@ -20,16 +20,16 @@ Paste this prompt into your agent. The agent installs the skill in your project
20
20
  <!-- <block same-as="README.md:agent-prompt"> -->
21
21
 
22
22
  ```text
23
- Run `blockwatch skill` and save its output as `blockwatch/SKILL.md` in this project's skills directory. Then use the
23
+ Run `blockwatch skill` and install the skill in this project as its "Installing this skill" section says. Then use the
24
24
  skill to annotate the project and add `blockwatch.toml` if needed. List each block you added and the mistake it
25
25
  catches.
26
26
  ```
27
27
 
28
28
  <!-- </block> -->
29
29
 
30
- The skill stays in the project, so agents that work on it later know the rules too. It records the version of
31
- blockwatch that wrote it. When `blockwatch --version` prints a newer one, the skill tells the agent to save it again.
32
- Always inspect the generated diff before committing to ensure the added blocks are necessary and accurate.
30
+ The agent saves a short stub, not the whole skill. The stub runs `blockwatch skill` each time it loads, so it always
31
+ matches the installed version. It stays in the project, so agents that work on it later know the rules too. Always
32
+ inspect the generated diff before committing to ensure the added blocks are necessary and accurate.
33
33
 
34
34
  ## 3. Enable Automated Checks
35
35
 
@@ -52,21 +52,20 @@ The plugin's skill runs `blockwatch skill` each time it loads, so it always matc
52
52
 
53
53
  ### Other AI Tools
54
54
 
55
- For other environments or project-local setups, save the output of `blockwatch skill` to the expected skill location:
55
+ To set up a project by hand, save the stub from
56
+ [Installing this skill](../src/skill.md#installing-this-skill) where your agent reads it:
56
57
 
57
58
  | Agent | Location |
58
59
  |---------------------|--------------------------------------------------------|
59
60
  | **Claude Code** | Plugin (above) or `.claude/skills/blockwatch/SKILL.md` |
60
61
  | **Cursor** | `.cursor/rules/blockwatch.mdc` |
61
- | **GitHub Copilot** | Append to `.github/copilot-instructions.md` |
62
- | **Codex / generic** | Append to `AGENTS.md` |
62
+ | **GitHub Copilot** | `.github/copilot-instructions.md` |
63
+ | **Codex / generic** | `AGENTS.md` |
63
64
 
64
- For example, for Claude Code:
65
+ `.github/copilot-instructions.md` and `AGENTS.md` hold other instructions too. Add only the stub's description there,
66
+ and the sentence "Then run `blockwatch skill` and follow what it prints."
65
67
 
66
- ```shell
67
- mkdir -p .claude/skills/blockwatch
68
- blockwatch skill > .claude/skills/blockwatch/SKILL.md
69
- ```
68
+ Don't save the output of `blockwatch skill` itself. A saved copy goes stale when blockwatch is upgraded.
70
69
 
71
70
  ---
72
71
 
@@ -19,7 +19,7 @@ To use [pre-commit](https://pre-commit.com), add the hook to `.pre-commit-config
19
19
 
20
20
  ```yaml
21
21
  - repo: https://github.com/mennanov/blockwatch
22
- rev: v0.16.1 # Use latest release
22
+ rev: v0.16.2 # Use latest release
23
23
  hooks:
24
24
  - id: blockwatch
25
25
  ```
@@ -59,7 +59,7 @@ The `blockwatch` hook runs before the commit message exists, so it cannot see a
59
59
 
60
60
  ```yaml
61
61
  - repo: https://github.com/mennanov/blockwatch
62
- rev: v0.16.1 # Use latest release
62
+ rev: v0.16.2 # Use latest release
63
63
  hooks:
64
64
  - id: blockwatch-commit-msg
65
65
  ```
@@ -557,15 +557,15 @@ Nothing else about the run changes: the same violations are found, and the exit
557
557
  "tool": {
558
558
  "driver": {
559
559
  "name": "blockwatch",
560
- "version": "0.16.1",
561
- "semanticVersion": "0.16.1",
560
+ "version": "0.16.2",
561
+ "semanticVersion": "0.16.2",
562
562
  "informationUri": "https://github.com/mennanov/blockwatch",
563
563
  "rules": [
564
564
  {
565
565
  "id": "keep-sorted",
566
566
  "name": "keep-sorted",
567
567
  "shortDescription": { "text": "Requires the lines of a block to stay in order." },
568
- "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.1/docs/validators/keep-sorted.md"
568
+ "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.2/docs/validators/keep-sorted.md"
569
569
  }
570
570
  ]
571
571
  }
@@ -980,14 +980,9 @@ stay on stderr, under the same file paths and line numbers.
980
980
  add value, how to write them, and how to check its work. The text is built into the binary, so it always matches the
981
981
  installed version. The command works in any directory, even outside a repository.
982
982
 
983
- Save it into your agent's skills directory:
984
-
985
- ```shell
986
- blockwatch skill > .claude/skills/blockwatch/SKILL.md
987
- ```
988
-
989
- The saved skill records the version that wrote it. When `blockwatch --version` prints a newer one, the skill tells the
990
- agent to save it again. See [Annotating Codebases with AI Agents](agents.md).
983
+ Don't save the output itself, because a saved copy goes stale when blockwatch is upgraded. Save the stub from the
984
+ [Installing this skill](../src/skill.md#installing-this-skill) section instead. The stub runs `blockwatch skill` each
985
+ time an agent loads it. See [Annotating Codebases with AI Agents](agents.md).
991
986
 
992
987
  ## Exit Codes
993
988
 
@@ -37,6 +37,8 @@ declares, instead of tags in a comment.
37
37
  | Rust | `.rs` | [Rust](#rust) |
38
38
  | TypeScript | `.ts`, `.mts`, `.cts`, `.d.ts`, `.tsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
39
39
  | JavaScript | `.js`, `.mjs`, `.cjs`, `.jsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
40
+ | Java | `.java` | [Java](#java) |
41
+ | C# | `.cs` | [C#](#c) |
40
42
 
41
43
  <!-- </block> -->
42
44
 
@@ -247,7 +249,8 @@ Clone the repository.
247
249
 
248
250
  In a code file, each top-level name is a symbol: a constant, a variable, a type, a function or a macro. Its path is
249
251
  `#/NAME`.
250
- With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`.
252
+ With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`. In Java and C#, the members of a type
253
+ are symbols too, under the type's name: `Config.java#/Config/MAX_PORTS`.
251
254
 
252
255
  - **A value is the initializer as written.** blockwatch never works it out: `20 * 1024 * 1024` stays as it is, and so
253
256
  does `0x10`. Use `same-as-pattern` to take the part you need.
@@ -257,10 +260,11 @@ With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`.
257
260
  - **A symbol covers its own definition**, keywords included, but not the comments above it. `affects` counts a change
258
261
  to that text only.
259
262
  - **A name defined twice is a violation**, because blockwatch can't tell which copy you mean.
260
- - **A syntax error stops the run only for the names near it**: a name whose definition holds the error, and any name in
261
- the text that the parser had to skip. Other names in the file still resolve. The message shows where the error is.
262
- - **A string that blockwatch can't decode stops the run** for its name only.
263
- - **Members are not symbols yet**, such as a method or a field.
263
+ - **A syntax error stops the run only for the names near it**: a name whose definition holds the error, and every path
264
+ with a name from the text that the parser had to skip. Other names in the file still resolve. The message shows
265
+ where the error is.
266
+ - **A path to a string that blockwatch can't decode stops the run.** Other paths in the file still resolve.
267
+ - **Members are not symbols yet**, such as a method or a field, except in Java and C#.
264
268
 
265
269
  <!-- </block> -->
266
270
 
@@ -298,7 +302,7 @@ func Helper() {}
298
302
  - **Names get their values by position.** In `var x, y = f()`, one call gives both names, so neither has a value.
299
303
  - **A type is not part of a value.** `const X Mode = 3` is `3`.
300
304
  - **Strings follow Go's escapes.** `"\xc3\xa9"` is `é`. A raw string loses its carriage returns. A rune, such as `'r'`,
301
- stays as written. A string whose bytes are not UTF-8 text stops the run for its name.
305
+ stays as written. A path to a string whose bytes are not UTF-8 text stops the run.
302
306
  - **Methods, `func init` and `_` are not symbols.**
303
307
  - **`go.mod`, `go.sum` and `go.work` have no symbols.**
304
308
 
@@ -386,7 +390,7 @@ def load(path):
386
390
  value: `type Pair[T] = tuple[T, T]` is `#/Pair`.
387
391
  - **Strings follow Python's escapes.** `"\xe9"` is `é`. An escape Python doesn't know, such as `\d`, stays as written.
388
392
  A raw string is its text. An f-string without a field is its text, with `{{` as `{`. An f-string with a field and
389
- bytes stay as written. A `\N{...}` escape stops the run for its name.
393
+ bytes stay as written. A path to a string with a `\N{...}` escape stops the run.
390
394
  - **Starlark files, such as `BUILD` and `.bzl`, follow the same rules.** A rule call, such as
391
395
  `cc_library(name = "lib")`, is not a symbol.
392
396
  - **Class members are not symbols yet.**
@@ -471,12 +475,126 @@ function normalize(text: string): string {
471
475
  - **Imports, `export { ... }`, `const { a } = b`, `module.exports`, an anonymous `export default` and `_` are not
472
476
  symbols.**
473
477
  - **Strings follow JavaScript's escapes.** `"\uD83D\uDE00"` is `😀`. A template without `${...}` is its text. A template
474
- with a field and a tagged template, such as ``String.raw`a` ``, stay as written. A legacy escape, such as `\07`,
475
- stops the run for its name.
478
+ with a field and a tagged template, such as ``String.raw`a` ``, stay as written. A path to a string with a legacy
479
+ escape, such as `\07`, stops the run.
476
480
  - **Enum members, class members and the contents of a namespace are not symbols yet.**
477
481
 
478
482
  <!-- </block> -->
479
483
 
484
+ ## Java
485
+
486
+ <!-- <block name="java-paths"> -->
487
+
488
+ ```java
489
+ public class Config {
490
+ @Native
491
+ public static final int MAX_RETRIES = 20 * 1024;
492
+ static final String QUERY = """
493
+ SELECT *
494
+ FROM t
495
+ """;
496
+
497
+ void run() {}
498
+ void run(int times) {}
499
+
500
+ enum Mode { RED, GREEN }
501
+
502
+ static class Limits {
503
+ static final long ID = 0x10L;
504
+ }
505
+ }
506
+ ```
507
+
508
+ | Path | Points at |
509
+ |------------------------|-----------------------------------------------|
510
+ | `#/Config` | the whole class |
511
+ | `#/Config/MAX_RETRIES` | `20 * 1024` |
512
+ | `#/Config/QUERY` | `SELECT *` and `FROM t`, on two lines |
513
+ | `#/Config/run` | a violation, as `run` is defined twice |
514
+ | `#/Config/Mode/GREEN` | `GREEN`, as it has no value |
515
+ | `#/Config/Limits/ID` | `0x10L` |
516
+
517
+ - **Each type is a symbol, and so is each member in it**: a field, a method, an enum constant, an annotation element
518
+ or a nested type. A path goes from the top-level type down, as code refers to it: `#/Config/Limits/ID`.
519
+ - **Overloads are defined twice, and so are a field and a method with one name**, such as `name` and `name()`. Wrap the
520
+ one you mean in a block instead.
521
+ - **Annotations are part of a definition. Javadoc is not.** In `int a = 1, b = 2;`, a name covers only its own part.
522
+ - **An annotation element's value is its `default`.** `String value() default "x";` is `x`.
523
+ - **A method without a body, such as one in an interface, is a symbol.**
524
+ - **Constructors, initializer blocks, record components, local and anonymous classes, and the members in the body of an
525
+ enum constant are not symbols.** An accessor you write in a record, such as `int x()`, is a method.
526
+ - **A file with methods and fields at its top level, as Java 25 allows, gives them paths such as `#/main`.**
527
+ - **Strings follow Java's escapes.** `"caf\u00e9"` is `café`. A text block counts as the text Java reads, without the
528
+ indentation its lines share and the white space at the ends of its lines. A character, such as `'a'`, and a string
529
+ template stay as written. A path to a string with `\u005c` stops the run. Java turns `\u005c` into a backslash
530
+ before it reads the other escapes, so `"\u005cn"` is `"\n"`.
531
+ - **A syntax error stops the run for the member that holds it, and for each type around that member.** The other
532
+ members still resolve.
533
+
534
+ <!-- </block> -->
535
+
536
+ ## C\#
537
+
538
+ <!-- <block name="c-sharp-paths"> -->
539
+
540
+ ```csharp
541
+ namespace Acme.Billing;
542
+
543
+ public class Config
544
+ {
545
+ [Obsolete]
546
+ public const int MaxRetries = 20 * 1024;
547
+ public static readonly string Query = """
548
+ SELECT *
549
+ FROM t
550
+ """;
551
+ public string Name { get; set; } = "default";
552
+ public static string Url => $"https://{Host}/x";
553
+
554
+ void Run() {}
555
+ void Run(int times) {}
556
+
557
+ public enum Mode { Red = 1, Green }
558
+
559
+ class Limits { const long Id = 0x10L; }
560
+ }
561
+ ```
562
+
563
+ | Path | Points at |
564
+ |------------------------------------|----------------------------------------|
565
+ | `#/Acme/Billing/Config` | the whole class |
566
+ | `#/Acme/Billing/Config/MaxRetries` | `20 * 1024` |
567
+ | `#/Acme/Billing/Config/Query` | `SELECT *` and `FROM t`, on two lines |
568
+ | `#/Acme/Billing/Config/Name` | `default` |
569
+ | `#/Acme/Billing/Config/Url` | `$"https://{Host}/x"`, as written |
570
+ | `#/Acme/Billing/Config/Run` | a violation, as `Run` is defined twice |
571
+ | `#/Acme/Billing/Config/Mode/Green` | `Green`, as it has no value |
572
+ | `#/Acme/Billing/Config/Limits/Id` | `0x10L` |
573
+
574
+ - **A namespace is part of the path, but not a symbol.** `namespace Acme.Billing { }` and
575
+ `namespace Acme { namespace Billing { } }` give the same paths as `namespace Acme.Billing;`. `#/Acme/Billing` alone
576
+ is not found. A type outside any namespace starts at the top: `#/Config/MaxRetries`.
577
+ - **Each type is a symbol, and so is each member in it**: a field, a constant, a property, a method, an event, an enum
578
+ member or a nested type. Classes, structs, interfaces, enums, records and delegates are types.
579
+ - **Overloads are defined twice.** So are the copies of a name in `#if` and `#else`, and `Cache` next to `Cache<T>`,
580
+ as a path has no place for `<T>`. A member that only one of them has still resolves. Wrap the one you mean in a
581
+ block instead.
582
+ - **A property's value is the one it starts with**: `v` in `X { get; set; } = v;` and in `X => v;`. A method has no
583
+ value, even with `=> v`.
584
+ - **Attributes are part of a definition. `///` comments are not.** In `int a = 1, b = 2;`, a name covers only its own
585
+ part. The code in `#if`, `#elif` and `#else` counts as if the directives were not there.
586
+ - **A name written with `@` keeps it**: `#/Config/@switch`.
587
+ - **Constructors, finalizers, indexers, operators, explicit interface members such as `void IDisposable.Dispose()`,
588
+ record parameters and top-level statements are not symbols.** A property you write in a record's body is a symbol.
589
+ - **Strings follow C#'s escapes.** A verbatim string, such as `@"C:\temp"`, has none. A raw string counts as the text
590
+ C# reads, without the white space before its closing quotes. `$"v1"` is `v1`. A string with a hole, such as
591
+ `$"v{Major}"`, stays as written, and so do `"abc"u8` and a character such as `'a'`. A path to a string that C#
592
+ rejects stops the run, such as `"\?"` or a raw string with a line less indented than its closing quotes.
593
+ - **A syntax error stops the run for the member that holds it, and for each type around that member.** The other
594
+ members still resolve.
595
+
596
+ <!-- </block> -->
597
+
480
598
  ---
481
599
 
482
600
  [← Return to README](../README.md)
@@ -6,7 +6,7 @@ setup(
6
6
  name='blockwatch-pre-commit-placeholder',
7
7
  version='0.0.0',
8
8
  # <block name="blockwatch-cli-version" same-as-pattern="blockwatch-cli==(?P<value>\d+\.\d+\.\d+)">
9
- install_requires=['blockwatch-cli==0.16.1'],
9
+ install_requires=['blockwatch-cli==0.16.2'],
10
10
  # </block>
11
11
  # Without it, setuptools takes the directories under src/ for Python packages.
12
12
  packages=[],
@@ -158,6 +158,7 @@ fn top_level_definitions<'tree>(
158
158
  "alias_declaration" => node
159
159
  .child_by_field_name("name")
160
160
  .map(|name| Definition {
161
+ parents: Vec::new(),
161
162
  names: vec![name],
162
163
  range: start..node.end_byte(),
163
164
  value: None,
@@ -202,6 +203,7 @@ fn declaration_definitions(declaration: Node<'_>, start: usize) -> Vec<Definitio
202
203
  continue;
203
204
  }
204
205
  definitions.push(Definition {
206
+ parents: Vec::new(),
205
207
  names: vec![name],
206
208
  range: if alone {
207
209
  start..declaration.end_byte()
@@ -242,6 +244,7 @@ fn typedef_definitions<'tree>(
242
244
  let mut definitions = Vec::new();
243
245
  if !names.is_empty() {
244
246
  definitions.push(Definition {
247
+ parents: Vec::new(),
245
248
  names,
246
249
  range: start..typedef.end_byte(),
247
250
  value: None,
@@ -256,6 +259,7 @@ fn typedef_definitions<'tree>(
256
259
  fn function_definition(function: Node<'_>, start: usize) -> Option<Definition<'_>> {
257
260
  let (name, _) = declared_name(function.child_by_field_name("declarator")?)?;
258
261
  Some(Definition {
262
+ parents: Vec::new(),
259
263
  names: vec![name],
260
264
  range: start..function.end_byte(),
261
265
  value: None,
@@ -267,6 +271,7 @@ fn function_definition(function: Node<'_>, start: usize) -> Option<Definition<'_
267
271
  fn type_definitions(specifier: Node<'_>, start: usize) -> Vec<Definition<'_>> {
268
272
  let mut definitions: Vec<Definition> = defined_type_name(specifier)
269
273
  .map(|name| Definition {
274
+ parents: Vec::new(),
270
275
  names: vec![name],
271
276
  range: start..specifier.end_byte(),
272
277
  value: None,
@@ -302,6 +307,7 @@ fn enumerators(specifier: Node<'_>) -> Vec<Definition<'_>> {
302
307
  .filter(|child| child.kind() == "enumerator")
303
308
  .filter_map(|enumerator| {
304
309
  Some(Definition {
310
+ parents: Vec::new(),
305
311
  names: vec![enumerator.child_by_field_name("name")?],
306
312
  range: enumerator.byte_range(),
307
313
  value: enumerator
@@ -364,6 +370,7 @@ fn macro_definition<'tree>(
364
370
  // The node holds the line end after the macro.
365
371
  let end = node.start_byte() + node_text(&node, source).trim_end().len();
366
372
  Ok(Some(Definition {
373
+ parents: Vec::new(),
367
374
  names: vec![name],
368
375
  range: node.start_byte()..end,
369
376
  value,