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.
- blockwatch_cli-0.16.2/.agents/skills/blockwatch/SKILL.md +14 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/AGENTS.md +5 -4
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/CHANGELOG.md +28 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/CLAUDE.md +5 -4
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/Cargo.lock +1 -1
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/Cargo.toml +1 -1
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/PKG-INFO +1 -1
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/README.md +5 -5
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/blockwatch.toml +2 -2
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/agents.md +11 -12
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/ci.md +2 -2
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/cli.md +6 -11
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/symbols.md +127 -9
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/setup.py +1 -1
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/c.rs +7 -0
- blockwatch_cli-0.16.2/src/language_parsers/c_sharp.rs +1083 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/go.rs +2 -0
- blockwatch_cli-0.16.2/src/language_parsers/java.rs +872 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/mod.rs +2 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/python.rs +1 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/rust.rs +1 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/typescript.rs +3 -10
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/yaml.rs +109 -42
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/skill.md +67 -13
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbols/code.rs +214 -47
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbols/mod.rs +67 -23
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/skill.rs +10 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/symbol_references.rs +14 -0
- blockwatch_cli-0.16.2/tests/testdata/symbol_references/cs_source.rs +3 -0
- blockwatch_cli-0.16.2/tests/testdata/symbol_references/cs_target.cs +6 -0
- blockwatch_cli-0.16.2/tests/testdata/symbol_references/java_source.rs +3 -0
- blockwatch_cli-0.16.2/tests/testdata/symbol_references/java_target.java +5 -0
- blockwatch_cli-0.16.1/.agents/skills/blockwatch/SKILL.md +0 -14
- blockwatch_cli-0.16.1/src/language_parsers/c_sharp.rs +0 -91
- blockwatch_cli-0.16.1/src/language_parsers/java.rs +0 -152
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.agents/.claude-plugin/plugin.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.claude-plugin/marketplace.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/dependabot.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/blockwatch.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/codeql.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/markdownlint.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/pypi.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/release.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/rust.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.github/workflows/trusted-checks.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.gitignore +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.markdownlint-cli2.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.pre-commit-config.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/.pre-commit-hooks.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/LICENSE +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/SECURITY.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/clippy.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/codecov.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/demo.gif +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/dist-workspace.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/README.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/affects.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/check-ai.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/check-lua.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/keep-sorted.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/keep-unique.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/line-count.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/line-pattern.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/docs/validators/same-as.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/pypi/pyproject.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/pyproject.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/release.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/scripts/check_language_count.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/scripts/check_latest_gpt_nano_model.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/block_parser.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/blocks.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/cli.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/config.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/diff_parser.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/explain.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/flags.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/fs.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/bash.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/cmake.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/cpp.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/css.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/dart.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/dockerfile.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/elixir.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/graphql.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/groovy.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/hcl.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/html.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/javascript.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/json.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/json.scm +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/kotlin.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/lean.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/lua.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/makefile.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/markdown.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/mdx.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/nix.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/ocaml.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/php.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/proto.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/ruby.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/scala.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/sql.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/starlark.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/swift.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/toml.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/tsx.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/language_parsers/xml.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/lib.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/main.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/path_arguments.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/paths_glob.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/repo_path.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/report.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/sarif.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/scan.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/settings.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/symbol_path.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/tag_parser.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/target_reference.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/affects.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/check_ai.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/check_lua.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/keep_sorted.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/keep_unique.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/line_count.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/line_pattern.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/mod.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/validators/same_as.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/violation_address.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/src/virtual_blocks.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/affects.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/check_ai.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/check_lua.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/common/empty.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/common/mod.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/config.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/encoding.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/explain.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/general.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/keep_sorted.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/keep_unique.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/line_count.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/line_pattern.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/list.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/path_arguments.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/repository_root.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/same_as.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/sarif.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/suppressions.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/cross_file_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/cross_file_target.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/custom_ext_source.javascript +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/custom_ext_target.javascript +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/dangling.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/missing_symbol.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/more_added_than_deleted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/multiline_tag_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/multiline_tag_target.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/nested_mapping_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/nested_mapping_target.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/sibling.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/symbol_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/symbol_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/table_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/table_target.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/tag_and_content_source.ts +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/tag_and_content_target.ts +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/whole_file_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/affects/whole_file_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_ai/two_blocks.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/affects_drift.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/blocking_io.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/blocking_io.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/echo.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/fail.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/mode.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/os.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pathfmt/report_path.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pathfmt/source.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern_many_matches.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/pattern_no_match.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/success.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/check_lua/success_and_failure.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/config.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/package.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/blue/package.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/green/package.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/config/glob_target/plugins/red/package.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/explain/a.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/explain/check.lua +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/block_selection.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/custom_file_extension.javascript +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/custom_file_extension.python +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/disable_enable.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/invalid.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/subdir/nested_invalid.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/paths/valid.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/general/severity.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/hidden/.github/workflows/ci.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/keep_sorted/orderings.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/keep_unique/basic_and_pattern.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_count/equality_and_greater_than.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_pattern/forbidden_text.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/line_pattern/hex_and_word_patterns.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/.hg/.gitkeep +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/a.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/list/b.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/positions/unicode_columns.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/custom_ext_source.javascript +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/custom_ext_target.javascript +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/package.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths/alpha/item.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths/beta/item.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths_and_block_source.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/paths_source.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/sibling.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/split_table_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/split_table_target.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/symbol_mismatch_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/symbol_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/target.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_mismatch_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/same_as/whole_file_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/advisory.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/clean.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/sorted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/sarif/unnamed.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_gone_a.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_gone_b.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_lowercase_trailer.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_malformed.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/commit_msg_with_noise.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/dangling.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/sorted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/symbol.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/symbol_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/two_rules.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/suppressions/unnamed.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/bzl_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/bzl_target.bzl +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/c_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/c_target.c +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/cpp_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/cpp_target.cpp +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/escapes_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/escapes_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/filter_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/filter_target.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/go_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/go_target.go +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/h_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/h_target.h +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/js_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/js_target.js +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/json_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/json_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/jsonc_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/jsonc_target.jsonc +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/markdown_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/markdown_target.markdown +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/md_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/md_target.md +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mdx_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mdx_target.mdx +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mixed_list_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/mixed_list_target.json +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/py_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/py_target.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/rs_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/rs_target.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/toml_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/toml_target.toml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/ts_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/ts_target.ts +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/tsx_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/tsx_target.tsx +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yaml_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yaml_target.yaml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yml_source.rs +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/symbol_references/yml_target.yml +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/affects/pair.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/counted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/noop.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/notes.txt +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/clean/sorted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/diff/two_blocks.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/failing/unsorted.py +0 -0
- {blockwatch_cli-0.16.1 → blockwatch_cli-0.16.2}/tests/testdata/verbosity/mixed/both_kinds.py +0 -0
- {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
|
|
283
|
-
their projects.
|
|
284
|
-
|
|
285
|
-
|
|
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
|
|
283
|
-
their projects.
|
|
284
|
-
|
|
285
|
-
|
|
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.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blockwatch-cli
|
|
3
|
-
Version: 0.16.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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** |
|
|
62
|
-
| **Codex / generic** |
|
|
62
|
+
| **GitHub Copilot** | `.github/copilot-instructions.md` |
|
|
63
|
+
| **Codex / generic** | `AGENTS.md` |
|
|
63
64
|
|
|
64
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
561
|
-
"semanticVersion": "0.16.
|
|
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.
|
|
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
|
-
|
|
984
|
-
|
|
985
|
-
|
|
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
|
|
261
|
-
the text that the parser had to skip. Other names in the file still resolve. The message shows
|
|
262
|
-
|
|
263
|
-
- **
|
|
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
|
|
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
|
|
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
|
|
475
|
-
stops the run
|
|
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.
|
|
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,
|