pyfltr 2.2.2__tar.gz → 3.0.0__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 (106) hide show
  1. {pyfltr-2.2.2 → pyfltr-3.0.0}/.claude/agents/tool-compat-checker.md +1 -1
  2. {pyfltr-2.2.2 → pyfltr-3.0.0}/.claude/skills/pyfltr-add-tool/SKILL.md +20 -6
  3. {pyfltr-2.2.2 → pyfltr-3.0.0}/.github/workflows/ci.yaml +2 -2
  4. {pyfltr-2.2.2 → pyfltr-3.0.0}/.gitignore +6 -0
  5. pyfltr-3.0.0/.textlintignore +2 -0
  6. pyfltr-3.0.0/CLAUDE.md +35 -0
  7. {pyfltr-2.2.2 → pyfltr-3.0.0}/PKG-INFO +40 -21
  8. pyfltr-3.0.0/README.md +49 -0
  9. pyfltr-3.0.0/docs/development/architecture.md +135 -0
  10. pyfltr-3.0.0/docs/development/archive-and-cache.md +174 -0
  11. pyfltr-3.0.0/docs/development/index.md +16 -0
  12. pyfltr-3.0.0/docs/development/jsonl-output.md +160 -0
  13. pyfltr-3.0.0/docs/development/mcp-server.md +109 -0
  14. pyfltr-3.0.0/docs/development/subcommands.md +129 -0
  15. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/configuration-tools.md +214 -118
  16. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/configuration.md +98 -36
  17. pyfltr-3.0.0/docs/guide/index.md +84 -0
  18. pyfltr-3.0.0/docs/guide/migration-v3.md +270 -0
  19. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/recommended-nonpython.md +17 -23
  20. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/recommended.md +22 -23
  21. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/usage.md +179 -17
  22. pyfltr-3.0.0/docs/index.md +16 -0
  23. pyfltr-3.0.0/mkdocs.yml +159 -0
  24. pyfltr-3.0.0/pyfltr/archive.py +391 -0
  25. pyfltr-3.0.0/pyfltr/cache.py +304 -0
  26. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/cli.py +158 -9
  27. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/command.py +327 -90
  28. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/config.py +231 -65
  29. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/error_parser.py +106 -46
  30. pyfltr-3.0.0/pyfltr/github_annotations.py +58 -0
  31. pyfltr-3.0.0/pyfltr/llm_output.py +414 -0
  32. pyfltr-3.0.0/pyfltr/main.py +836 -0
  33. pyfltr-3.0.0/pyfltr/mcp_.py +394 -0
  34. pyfltr-3.0.0/pyfltr/only_failed.py +241 -0
  35. pyfltr-3.0.0/pyfltr/paths.py +28 -0
  36. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/precommit.py +32 -0
  37. pyfltr-3.0.0/pyfltr/retry.py +257 -0
  38. pyfltr-3.0.0/pyfltr/rule_urls.py +87 -0
  39. pyfltr-3.0.0/pyfltr/runs.py +385 -0
  40. pyfltr-3.0.0/pyfltr/sarif_output.py +129 -0
  41. pyfltr-3.0.0/pyfltr/shell_completion.py +228 -0
  42. pyfltr-3.0.0/pyfltr/stage_runner.py +37 -0
  43. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/ui.py +117 -9
  44. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/warnings_.py +10 -2
  45. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyproject.toml +22 -14
  46. pyfltr-3.0.0/tests/archive_test.py +269 -0
  47. pyfltr-3.0.0/tests/cache_test.py +231 -0
  48. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/cli_test.py +78 -3
  49. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/command_test.py +268 -0
  50. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/config_test.py +435 -158
  51. pyfltr-3.0.0/tests/conftest.py +128 -0
  52. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/error_parser_test.py +235 -3
  53. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/executor_test.py +13 -9
  54. pyfltr-3.0.0/tests/github_annotations_test.py +68 -0
  55. pyfltr-3.0.0/tests/llm_output_test.py +334 -0
  56. pyfltr-3.0.0/tests/main_test.py +392 -0
  57. pyfltr-3.0.0/tests/mcp_test.py +271 -0
  58. pyfltr-3.0.0/tests/only_failed_test.py +276 -0
  59. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/output_format_test.py +102 -39
  60. pyfltr-3.0.0/tests/paths_test.py +67 -0
  61. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/precommit_test.py +64 -0
  62. pyfltr-3.0.0/tests/retry_test.py +267 -0
  63. pyfltr-3.0.0/tests/rule_urls_test.py +77 -0
  64. pyfltr-3.0.0/tests/runs_test.py +349 -0
  65. pyfltr-3.0.0/tests/sarif_output_test.py +90 -0
  66. pyfltr-3.0.0/tests/shell_completion_test.py +107 -0
  67. pyfltr-3.0.0/tests/stage_runner_test.py +115 -0
  68. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/warnings_test.py +15 -6
  69. {pyfltr-2.2.2 → pyfltr-3.0.0}/uv.lock +511 -174
  70. pyfltr-2.2.2/CLAUDE.md +0 -18
  71. pyfltr-2.2.2/README.md +0 -27
  72. pyfltr-2.2.2/docs/development/index.md +0 -7
  73. pyfltr-2.2.2/docs/guide/index.md +0 -72
  74. pyfltr-2.2.2/docs/index.md +0 -8
  75. pyfltr-2.2.2/mkdocs.yml +0 -129
  76. pyfltr-2.2.2/pyfltr/llm_output.py +0 -246
  77. pyfltr-2.2.2/pyfltr/main.py +0 -467
  78. pyfltr-2.2.2/tests/conftest.py +0 -73
  79. pyfltr-2.2.2/tests/llm_output_test.py +0 -95
  80. pyfltr-2.2.2/tests/main_test.py +0 -266
  81. {pyfltr-2.2.2 → pyfltr-3.0.0}/.claude/agents/error-parser-reviewer.md +0 -0
  82. {pyfltr-2.2.2 → pyfltr-3.0.0}/.editorconfig +0 -0
  83. {pyfltr-2.2.2 → pyfltr-3.0.0}/.gitattributes +0 -0
  84. {pyfltr-2.2.2 → pyfltr-3.0.0}/.github/workflows/docs.yaml +0 -0
  85. {pyfltr-2.2.2 → pyfltr-3.0.0}/.github/workflows/release.yaml +0 -0
  86. {pyfltr-2.2.2 → pyfltr-3.0.0}/.gitmessage +0 -0
  87. {pyfltr-2.2.2 → pyfltr-3.0.0}/.markdownlint-cli2.yaml +0 -0
  88. {pyfltr-2.2.2 → pyfltr-3.0.0}/.npmrc +0 -0
  89. {pyfltr-2.2.2 → pyfltr-3.0.0}/.pre-commit-config.yaml +0 -0
  90. {pyfltr-2.2.2 → pyfltr-3.0.0}/.pylintrc +0 -0
  91. {pyfltr-2.2.2 → pyfltr-3.0.0}/.python-version +0 -0
  92. {pyfltr-2.2.2 → pyfltr-3.0.0}/.textlintrc.yaml +0 -0
  93. {pyfltr-2.2.2 → pyfltr-3.0.0}/.vscode/extensions.json +0 -0
  94. {pyfltr-2.2.2 → pyfltr-3.0.0}/.vscode/settings.json +0 -0
  95. {pyfltr-2.2.2 → pyfltr-3.0.0}/LICENSE +0 -0
  96. {pyfltr-2.2.2 → pyfltr-3.0.0}/Makefile +0 -0
  97. {pyfltr-2.2.2 → pyfltr-3.0.0}/cliff.toml +0 -0
  98. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/.markdownlint-cli2.yaml +0 -0
  99. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/development/development.md +0 -0
  100. {pyfltr-2.2.2 → pyfltr-3.0.0}/docs/guide/custom-commands.md +0 -0
  101. {pyfltr-2.2.2 → pyfltr-3.0.0}/mise.toml +0 -0
  102. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/__init__.py +0 -0
  103. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/__main__.py +0 -0
  104. {pyfltr-2.2.2 → pyfltr-3.0.0}/pyfltr/executor.py +0 -0
  105. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/__init__.py +0 -0
  106. {pyfltr-2.2.2 → pyfltr-3.0.0}/tests/ui_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tool-compat-checker
3
- description: pyfltr が呼び出す外部ツール(ruff/mypy/pytest/pylint/pyright/ty/black/isort/autoflake/pyupgrade/pflake8/markdownlint/textlint)のコマンドライン引数・出力フォーマットが最新版と乖離していないか検査する。PRレビュー前や make update 後に呼び出す。必ず「チェック対象ツール名」または「ALL」を引数として与えること。
3
+ description: pyfltr が呼び出す外部ツール(ruff/mypy/pytest/pylint/pyright/ty/markdownlint/textlint/shellcheck/shfmt/typos/actionlint/eslint/biome/oxlint/prettier/tsc/vitest/cargo-fmt/cargo-clippy/cargo-check/cargo-test/cargo-deny/dotnet-format/dotnet-build/dotnet-test/uv-sort/ec/pre-commit)のコマンドライン引数・出力フォーマットが最新版と乖離していないか検査する。PRレビュー前や make update 後に呼び出す。必ず「チェック対象ツール名」または「ALL」を引数として与えること。
4
4
  tools: Read, Grep, Glob, WebFetch, Bash
5
5
  ---
6
6
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: pyfltr-add-tool
3
- description: pyfltr に新しい formatter / linter / tester を追加する際の定型手順チェックリスト。config.py / command.py / error_parser.py / docs/index.md / tests を一貫して更新する。
4
- disable-model-invocation: true
3
+ description: pyfltr に新しい formatter / linter / tester を追加する際の定型手順チェックリスト。config.py / command.py / error_parser.py / docs/guide/index.md / tests を一貫して更新する。
5
4
  ---
6
5
 
7
6
  # pyfltr 新ツール追加チェックリスト
@@ -45,7 +44,22 @@ BUILTIN_COMMANDS: dict[str, CommandInfo] = {
45
44
  "<new-tool>-fast": True, # fast 実行対象か
46
45
  ```
47
46
 
48
- ### 1-3. プリセット(`load_config` 内)
47
+ ### 1-3. 言語カテゴリ定数(`config.py` 上部)
48
+
49
+ 新ツールが特定言語専用の場合、対応する定数タプルに追加する。
50
+
51
+ ```python
52
+ PYTHON_COMMANDS: tuple[str, ...] = (
53
+ ...
54
+ "<new-tool>",
55
+ )
56
+ ```
57
+
58
+ カテゴリ: `PYTHON_COMMANDS`・`JAVASCRIPT_COMMANDS`・`RUST_COMMANDS`・`DOTNET_COMMANDS`。
59
+ カテゴリに属するツールは `python`/`javascript`/`rust`/`dotnet` キーが `False` のときゲートで無効化される。
60
+ 全言語共通のツール(`typos`・`ec`・`actionlint` 等)はいずれのカテゴリにも属さない。
61
+
62
+ ### 1-4. プリセット(`load_config` 内)
49
63
 
50
64
  `preset = "latest"` 等で既定挙動を変えたい場合、`config.values["<new-tool>"]` を明示的にon/offする。
51
65
 
@@ -87,9 +101,9 @@ uv add --optional <extra> <new-tool-package>
87
101
 
88
102
  ## 6. ドキュメント
89
103
 
90
- - `docs/index.md` の「対応ツール」一覧に追記する
104
+ - `docs/guide/index.md` の「対応ツール」一覧に追記する
91
105
 
92
- 対応ツール一覧は`docs/index.md`に一元化されている。`README.md`には書かない。
106
+ 対応ツール一覧は`docs/guide/index.md`に一元化されている。`README.md`には書かない。
93
107
 
94
108
  ## 7. 検証
95
109
 
@@ -103,7 +117,7 @@ uv run pyfltr run-for-agent
103
117
 
104
118
  雛形にすべき既存ツールは `pyfltr/command.py` と `pyfltr/error_parser.py` を参照:
105
119
 
106
- - formatterの例: `ruff-format` / `black`
120
+ - formatterの例: `ruff-format` / `prettier`
107
121
  - linterの例: `ruff-check` / `mypy`
108
122
  - testerの例: `pytest`(ほぼ唯一なので新規testerは要相談)
109
123
 
@@ -72,7 +72,7 @@ jobs:
72
72
  run: uv sync --all-extras --all-groups
73
73
 
74
74
  - name: Test with pyfltr
75
- run: uv run pyfltr ci
75
+ run: uv run pyfltr ci --output-format=github-annotations
76
76
 
77
77
  - name: Prune uv cache for CI
78
78
  run: uv cache prune --ci
@@ -119,7 +119,7 @@ jobs:
119
119
  run: uv sync --all-extras --all-groups
120
120
 
121
121
  - name: Test with pyfltr
122
- run: uv run pyfltr ci
122
+ run: uv run pyfltr ci --output-format=github-annotations
123
123
 
124
124
  - name: Prune uv cache for CI
125
125
  run: uv cache prune --ci
@@ -211,3 +211,9 @@ __marimo__/
211
211
  # Claude Code (個人設定とランタイム生成ファイル)
212
212
  .claude/settings.local.json
213
213
  .claude/.format-dirty
214
+
215
+ # spec-driven 一時ファイル (作業中メモ・サブエージェント出力)
216
+ # `respect-gitignore=true` 既定動作により pyfltr の textlint からも自動除外される
217
+ *.working.md
218
+ *.review-*.md
219
+ *.research-*.md
@@ -0,0 +1,2 @@
1
+ # spec-drivenワークフローの一時ドキュメント(実装完了時に削除される)
2
+ **/*.working.md
pyfltr-3.0.0/CLAUDE.md ADDED
@@ -0,0 +1,35 @@
1
+ # CLAUDE.md: pyfltr
2
+
3
+ ## 開発手順
4
+
5
+ - `make update`: 依存更新 + pre-commit autoupdate + pinactアクション更新 + 全テスト実行
6
+ - `make update-actions`: GitHub Actionsのハッシュピン更新のみ(mise経由でpinact実行)
7
+ - テストコードは`pyfltr/xxx_.py`に対して`tests/xxx_test.py`として配置する
8
+ - 実行パイプラインの構造: `run_pipeline`(main.py)がTUI/非TUI分岐の最上位関数。パイプライン共通の前処理(ファイル展開など)はこの関数内でTUI起動前に実行する
9
+ - コミット前の検証方法: `uv run pyfltr run-for-agent`
10
+ - ドキュメントなどのみの変更の場合は省略可(pre-commitで実行されるため)
11
+ - テストコードの単体実行なども極力 `uv run pyfltr run-for-agent <path>` を使う(pytestを直接呼び出さない)
12
+ - 詳細な情報などが必要な場合に限り `uv run pytest -vv <path>` などを使用
13
+ - JSONL出力は`header`(実行環境・`run_id`・`schema_hints`)→ `diagnostic`+`tool`(ツール完了ごと)→ `warning`→ `summary`(末尾)の順に出力される。末尾の`summary`で`failed`と`diagnostics`を確認し、必要に応じて`diagnostic`行のファイル・行番号・メッセージを参照する。`header.run_id`(ULID)は実行アーカイブの参照キー
14
+ - `header.schema_hints`はJSONL各フィールドの意味をLLM向け英語ガイドとして毎runに付与する
15
+ - `summary.guidance`(英語配列)は`failed > 0`のときのみ付与され、`tool.retry_command` / `--only-failed` / `show-run` の案内を示す
16
+ - `diagnostic`の任意フィールド: `rule`・`rule_url`(対応ツールのみ)・`severity`(3値に正規化)・`fix`(値域の詳細は後述)
17
+ - `fix`は`"safe"` / `"unsafe"` / `"suggested"` / `"none"`の4値。ツールが自動修正情報を返さない場合はフィールドごと省略
18
+ - `tool`の任意フィールド: `retry_command`(当該ツールで失敗したファイルのみに絞った再実行コマンド)・`truncated`(smart truncation発生時。`archive`パスで全文参照)
19
+ - `retry_command`の追加仕様: 失敗時(`has_error=true`)のみ出力。成功時・`cached=true`時は出力されない。失敗ファイルを特定できない場合はターゲット位置引数が空
20
+ - `tool`のキャッシュ関連フィールド: `cached`(ファイルhashキャッシュから復元されたとき `true`)・`cached_from`(`cached=true` 時のソース `run_id`)
21
+ - 詳細仕様は`docs/guide/usage.md`の「jsonlスキーマ」節および`llms.txt`を参照。`--output-format=sarif` / `github-annotations` でCI向け形式にも切り替え可能
22
+ - `--fail-fast`: 1ツールでもエラーが出た時点で残りを打ち切る(起動済みはterminate、未開始はskipped扱い)
23
+ - `--no-cache`: ファイルhashキャッシュを無効化する。現状はtextlintのみ対象
24
+ - `--only-failed`: 直前runから失敗ツール・失敗ファイルを抽出し、ツール別にその組み合わせのみ再実行する。直前run無し/失敗ツール無し/targets交差空ならメッセージを出してrc=0で成功終了する
25
+ - `--from-run <RUN_ID>`: `--only-failed`の参照対象runを明示指定する(前方一致・`latest`対応)。併用前提で単独指定は拒否。不在`<RUN_ID>`時は警告を出してrc=0で早期終了する
26
+ - `header.run_id`はユーザーキャッシュに保存された該当runの参照キー。`pyfltr list-runs`で一覧、`pyfltr show-run <run_id>`で詳細(`<run_id>`は前方一致・`latest`エイリアス可)を参照する。`--tool <name>`でdiagnostics全件、`--tool <name> --output`で`output.log`全文が得られる
27
+ - MCPクライアント(Claude Desktopなど)からは`pyfltr mcp`でMCPサーバーを起動する。提供ツールは`list_runs` / `show_run` / `show_run_diagnostics` / `show_run_output` / `run_for_agent`の5種類で、アーカイブ参照と実行を行える
28
+
29
+ ## 注意点
30
+
31
+ - `uv run mkdocs build --strict`でリンク・nav整合性を検証(ただし日本語アンカーリンク`#見出し日本語`はMkDocs TOCで解決できずINFO通知のみで`--strict`でも検知されないため手動確認要)
32
+ - 内部リンクは英数アンカーを優先する。MkDocs(Material)のslugifyは英数のみを採用してアンカー生成するが、markdownlint MD051は見出し原文を見るため、`{#id}`記法で明示併設する(例:「### jsonl形式の使い方 {#jsonl}」)
33
+ - `docs/guide/index.md`の対応ツール一覧と`mkdocs.yml`内llmstxt `markdown_description`の「対応ツール」節は人手同期(SSOT化しない運用)
34
+ - `mkdocs.yml`内llmstxt `markdown_description`にはLLMが利用する際に有用な情報のみ記載する(`run-for-agent`サブコマンド、主要オプションなど)。LLMにとって不要な情報はdocs側をSSOTとし、多重管理を避ける
35
+ - ドキュメント構成変更時は`docs/development/development.md`の「READMEとdocsの役割分担」節を先に参照
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyfltr
3
- Version: 2.2.2
3
+ Version: 3.0.0
4
4
  Summary: Python Formatters, Linters, and Testers Runner.
5
5
  Project-URL: Homepage, https://github.com/ak110/pyfltr
6
6
  Author-email: "aki." <mark@aur.ll.to>
@@ -16,28 +16,25 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Programming Language :: Python :: 3.14
17
17
  Classifier: Topic :: Software Development :: Quality Assurance
18
18
  Requires-Python: <4.0,>=3.11
19
- Requires-Dist: autoflake>=2.0
20
- Requires-Dist: black>=22.0
21
- Requires-Dist: dill>=0.3
22
- Requires-Dist: flake8-bugbear>=23.0
23
- Requires-Dist: flake8-tidy-imports>=4.11.0
24
- Requires-Dist: isort>=5.0
25
- Requires-Dist: mypy>=1.0
19
+ Requires-Dist: mcp>=1.0
26
20
  Requires-Dist: natsort>=8.4.0
27
- Requires-Dist: pre-commit>=4.5.1
28
- Requires-Dist: pylint-pydantic>=0.4.1
29
- Requires-Dist: pylint>=3.0
30
- Requires-Dist: pyproject-flake8>=7.0
31
- Requires-Dist: pyright[nodejs]>=1.1.403
32
- Requires-Dist: pytest-asyncio>=1.0.0
33
- Requires-Dist: pytest>=7.0
34
- Requires-Dist: pyupgrade>=3.0
21
+ Requires-Dist: platformdirs>=4.0
22
+ Requires-Dist: psutil>=6.0
23
+ Requires-Dist: python-ulid>=3.0
35
24
  Requires-Dist: pyyaml>=6.0.3
36
- Requires-Dist: ruff>=0.12.1
37
25
  Requires-Dist: textual>=8.0.0
38
- Requires-Dist: ty>=0.0.26
39
- Requires-Dist: uv-sort>=0.5
40
- Provides-Extra: pyright
26
+ Provides-Extra: python
27
+ Requires-Dist: dill>=0.3; extra == 'python'
28
+ Requires-Dist: mypy>=1.0; extra == 'python'
29
+ Requires-Dist: pre-commit>=4.5.1; extra == 'python'
30
+ Requires-Dist: pylint-pydantic>=0.4.1; extra == 'python'
31
+ Requires-Dist: pylint>=3.0; extra == 'python'
32
+ Requires-Dist: pyright[nodejs]>=1.1.403; extra == 'python'
33
+ Requires-Dist: pytest-asyncio>=1.0.0; extra == 'python'
34
+ Requires-Dist: pytest>=7.0; extra == 'python'
35
+ Requires-Dist: ruff>=0.12.1; extra == 'python'
36
+ Requires-Dist: ty>=0.0.26; extra == 'python'
37
+ Requires-Dist: uv-sort>=0.5; extra == 'python'
41
38
  Description-Content-Type: text/markdown
42
39
 
43
40
  # pyfltr: Python Formatters, Linters, and Testers Runner
@@ -45,7 +42,8 @@ Description-Content-Type: text/markdown
45
42
  [![CI](https://github.com/ak110/pyfltr/actions/workflows/ci.yaml/badge.svg)](https://github.com/ak110/pyfltr/actions/workflows/ci.yaml)
46
43
  [![PyPI version](https://badge.fury.io/py/pyfltr.svg)](https://badge.fury.io/py/pyfltr)
47
44
 
48
- 各種formatter / linter / testerをまとめて並列実行するツール。
45
+ Python / Rust / .NET / TypeScript・JavaScript / ドキュメントなど多言語プロジェクトのformatter・linter・testerを単一コマンドで並列実行するCLIツール。
46
+ (要Python 3.11以上)
49
47
 
50
48
  ## 特徴
51
49
 
@@ -55,13 +53,34 @@ Description-Content-Type: text/markdown
55
53
  - 除外指定(exclude)の書式差をツール間で吸収
56
54
  - 自動修正系ツール(ruff format・prettierなど)を修正と失敗扱いの両立で実行
57
55
  - LLMエージェント向けJSON Lines出力(`pyfltr run-for-agent`・`PYFLTR_OUTPUT_FORMAT`環境変数・`--output-format=jsonl`)に対応
56
+ - MCPサーバーを本体同梱(`pyfltr mcp`)。Claude Desktopなどのエージェントから直接lint実行・アーカイブ参照が行える
57
+ - シェル補完スクリプト生成(`pyfltr generate-shell-completion`)に対応
58
58
 
59
59
  ## インストール
60
60
 
61
61
  ```shell
62
62
  pip install pyfltr
63
+ # uv を使う場合
64
+ uv add --dev pyfltr
63
65
  ```
64
66
 
67
+ uvxでの実行も可能。
68
+
69
+ ```shell
70
+ uvx pyfltr --help
71
+ ```
72
+
73
+ Python系ツール(ruff / mypy / pylint / pyright / ty / pytest / uv-sort)を利用する場合は、extrasで追加依存を導入する。
74
+
75
+ ```shell
76
+ pip install 'pyfltr[python]'
77
+ ```
78
+
79
+ Python / JavaScript / Rust / .NETの各言語カテゴリに属するツールはすべて既定で無効(opt-in)である。
80
+ `preset = "latest"` + 言語カテゴリキー(`python` / `javascript` / `rust` / `dotnet`)の`true`指定だけで、当該言語の推奨ツール一式が有効化される。
81
+ プリセット非収録のツール(`ty`など)を追加したい場合のみ個別に`{command} = true`を指定する。
82
+ 詳細は[設定項目](docs/guide/configuration.md)を参照。
83
+
65
84
  ## ドキュメント
66
85
 
67
86
  - <https://ak110.github.io/pyfltr/> — 概要・対応ツール一覧・設定リファレンス
pyfltr-3.0.0/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # pyfltr: Python Formatters, Linters, and Testers Runner
2
+
3
+ [![CI](https://github.com/ak110/pyfltr/actions/workflows/ci.yaml/badge.svg)](https://github.com/ak110/pyfltr/actions/workflows/ci.yaml)
4
+ [![PyPI version](https://badge.fury.io/py/pyfltr.svg)](https://badge.fury.io/py/pyfltr)
5
+
6
+ Python / Rust / .NET / TypeScript・JavaScript / ドキュメントなど多言語プロジェクトのformatter・linter・testerを単一コマンドで並列実行するCLIツール。
7
+ (要Python 3.11以上)
8
+
9
+ ## 特徴
10
+
11
+ - 多言語対応のformatter・linter・testerをまとめて呼び出す単一コマンド
12
+ - 複数ツールの並列実行による総実行時間の短縮
13
+ - 設定の集約: `pyproject.toml`に寄せた統一設定
14
+ - 除外指定(exclude)の書式差をツール間で吸収
15
+ - 自動修正系ツール(ruff format・prettierなど)を修正と失敗扱いの両立で実行
16
+ - LLMエージェント向けJSON Lines出力(`pyfltr run-for-agent`・`PYFLTR_OUTPUT_FORMAT`環境変数・`--output-format=jsonl`)に対応
17
+ - MCPサーバーを本体同梱(`pyfltr mcp`)。Claude Desktopなどのエージェントから直接lint実行・アーカイブ参照が行える
18
+ - シェル補完スクリプト生成(`pyfltr generate-shell-completion`)に対応
19
+
20
+ ## インストール
21
+
22
+ ```shell
23
+ pip install pyfltr
24
+ # uv を使う場合
25
+ uv add --dev pyfltr
26
+ ```
27
+
28
+ uvxでの実行も可能。
29
+
30
+ ```shell
31
+ uvx pyfltr --help
32
+ ```
33
+
34
+ Python系ツール(ruff / mypy / pylint / pyright / ty / pytest / uv-sort)を利用する場合は、extrasで追加依存を導入する。
35
+
36
+ ```shell
37
+ pip install 'pyfltr[python]'
38
+ ```
39
+
40
+ Python / JavaScript / Rust / .NETの各言語カテゴリに属するツールはすべて既定で無効(opt-in)である。
41
+ `preset = "latest"` + 言語カテゴリキー(`python` / `javascript` / `rust` / `dotnet`)の`true`指定だけで、当該言語の推奨ツール一式が有効化される。
42
+ プリセット非収録のツール(`ty`など)を追加したい場合のみ個別に`{command} = true`を指定する。
43
+ 詳細は[設定項目](docs/guide/configuration.md)を参照。
44
+
45
+ ## ドキュメント
46
+
47
+ - <https://ak110.github.io/pyfltr/> — 概要・対応ツール一覧・設定リファレンス
48
+ - <https://ak110.github.io/pyfltr/llms.txt> — LLM向け構造化インデックス
49
+ - [docs/development/development.md](docs/development/development.md) — 開発者向け情報
@@ -0,0 +1,135 @@
1
+ # アーキテクチャ概要
2
+
3
+ pyfltrの実装構造とモジュール責務分離の設計判断をまとめる。
4
+ 本ページは保守・拡張に携わる開発者向け。
5
+ 利用者向けの機能解説は[CLIコマンド](../guide/usage.md)・[設定項目](../guide/configuration.md)を参照。
6
+
7
+ ## 実行パイプライン
8
+
9
+ `pyfltr.main.run_pipeline()`がCLI/MCPの双方から呼び出される最上位エントリ。
10
+ TUI/非TUIの分岐はこの関数の内側で行い、パイプライン共通の前処理(ファイル展開・`--only-failed`絞り込み・アーカイブ初期化など)はTUI起動より前に集約する。
11
+
12
+ 実行ステージは次の3段で構成する。
13
+
14
+ 1. fixステージ — `{command}-fix-args`が定義された有効なlinterを順次`--fix`付きで実行する(`ci`サブコマンドは無効)
15
+ 2. formatterステージ — `ruff-format`・`prettier`等のformatterを直列または並列で実行する
16
+ 3. linter/testerステージ — 残りのlinter/testerを並列実行する
17
+
18
+ 各ステージの結果は`CommandResult`に集約され、ステージ完了ごとに`archive_hook`へ渡される。
19
+ ステージ間の中断(`--fail-fast`時の打ち切りなど)は`stage_runner`の共通ヘルパーで吸収する。
20
+
21
+ ## モジュール構成
22
+
23
+ `run_pipeline()`から呼び出される主要モジュールと責務を示す。
24
+
25
+ ### CLIエントリ
26
+
27
+ | モジュール | 責務 |
28
+ | --- | --- |
29
+ | `main.py` | argparse構築・サブコマンドディスパッチ・`run_pipeline()`本体・retry_command生成委譲 |
30
+ | `cli.py` | 非TUI実行器。3ステージのループとログ出力を担う |
31
+ | `ui.py` | TUI実行器。Textualベース。`call_from_thread`を介して非同期にステージを駆動する |
32
+ | `stage_runner.py` | `cli.py`/`ui.py`共通の小さなヘルパー(`make_skipped_result()`・`cancel_pending_futures()`) |
33
+ | `executor.py` | プロセスプール管理 |
34
+
35
+ ### コマンド実行
36
+
37
+ | モジュール | 責務 |
38
+ | --- | --- |
39
+ | `command.py` | `execute_command()`(subprocess起動・ファイル渡し・結果収集)と`CommandResult`データクラス |
40
+ | `error_parser.py` | ツール出力の解析と`ErrorLocation`生成 |
41
+ | `rule_urls.py` | ツール別の公式ドキュメントURL組み立てテンプレート |
42
+ | `precommit.py` | `.pre-commit-config.yaml`の解釈(自動SKIP対応) |
43
+
44
+ ### 設定とパス処理
45
+
46
+ | モジュール | 責務 |
47
+ | --- | --- |
48
+ | `config.py` | `pyproject.toml`読み込み・`CommandInfo`定義・プリセット・言語カテゴリ(python / javascript / rust / dotnet)ゲート処理 |
49
+ | `paths.py` | `normalize_separators()`によるパス区切りの統一 |
50
+ | `warnings_.py` | JSONL `warning`レコード生成 |
51
+
52
+ ### 出力フォーマット
53
+
54
+ | モジュール | 責務 |
55
+ | --- | --- |
56
+ | `llm_output.py` | JSONL出力(`header`/`diagnostic`/`tool`/`warning`/`summary`の各レコード生成)・smart truncation |
57
+ | `sarif_output.py` | SARIF 2.1.0形式のJSON生成 |
58
+ | `github_annotations.py` | GitHub Annotation形式(`::error file=...`等)の生成 |
59
+ | `shell_completion.py` | bash/PowerShell補完スクリプト生成 |
60
+
61
+ ### 実行アーカイブと再実行支援
62
+
63
+ | モジュール | 責務 |
64
+ | --- | --- |
65
+ | `archive.py` | `ArchiveStore`(書き込み・読み取り・クリーンアップ)・`policy_from_config()` |
66
+ | `cache.py` | `CacheStore`(ファイルhashベースのスキップキャッシュ)・`is_cacheable()`・`resolve_config_files()` |
67
+ | `runs.py` | `list-runs`/`show-run`サブコマンド本体・`resolve_run_id()`(前方一致・`latest`エイリアス) |
68
+ | `retry.py` | `retry_command`生成ヘルパー群(`detect_launcher_prefix()`・`build_retry_args_template()`等) |
69
+ | `only_failed.py` | `--only-failed`フィルター本体・`ToolTargets` dataclass |
70
+
71
+ ### MCPサーバー
72
+
73
+ | モジュール | 責務 |
74
+ | --- | --- |
75
+ | `mcp_.py` | FastMCPサーバー本体・5ツール(`list_runs`/`show_run`/`show_run_diagnostics`/`show_run_output`/`run_for_agent`)・stdio隔離 |
76
+
77
+ ## サブコマンドとargparse
78
+
79
+ argparse subparsers(`required=True`)でサブコマンドを必須化し、引数なし実行時のフォールバック挙動は持たない。
80
+ 共通オプションは`parents=[common]`で各サブパーサーへ継承する。
81
+ サブコマンド別の既定値(`exit_zero_even_if_formatted`・`commands`・`output_format`・`include_fix_stage`)は`_apply_subcommand_defaults()`で手動注入する。
82
+ `set_defaults()`経由の注入を避けたのは、共通親パーサーを継承しているサブパーサーに対して他サブパーサーのdefaultが書き換わる既知挙動を回避するため。
83
+
84
+ サブコマンド一覧と用途は[CLIコマンド](../guide/usage.md)を参照。
85
+
86
+ ## 主要な設計判断
87
+
88
+ ### 言語カテゴリはゲートとして働く
89
+
90
+ `python` / `javascript` / `rust` / `dotnet`の各言語カテゴリに属するツールは既定で無効(カテゴリキーが既定`false`)。
91
+ 対象外プロジェクトで意図しないツール実行が起こることを避けるため、対応する言語カテゴリキー(例: `python = true`)でゲートを開けるか、`{command} = true`の個別明示が必要。
92
+
93
+ プリセットは各時点の推奨ツール構成を示すスナップショットで言語別ツールも含むが、カテゴリキーが`false`のままだとプリセット由来の該当ツール`true`をゲート処理で`false`へ押し戻す。
94
+ 個別`{command} = true`はゲートを越えて最優先される。
95
+ Python系の追加依存は`pyfltr[python]`オプショナルグループに分離する。
96
+ JavaScript / Rust / .NET系は各言語のツールチェイン(Node.js・cargo・dotnet CLI)が前提のため、pyfltr本体はこれらの依存を抱えない。
97
+
98
+ 代替案として「完全別パッケージ(`pyfltr-python`)に分離」も検討したが、リポジトリ・リリース・バージョン整合の複雑度が増し、ユーザー体験もextras方式より劣るため不採用とした。
99
+
100
+ ### 必須依存は最小化
101
+
102
+ 本体必須依存は次の役割に限定する。
103
+
104
+ - 骨組み: `textual`(TUI)・`natsort`(自然順ソート)・`pyyaml`(pre-commit設定)
105
+ - run_id生成: `python-ulid`
106
+ - MCP同梱: `mcp`・`platformdirs`
107
+ - プロセス判定: `psutil`(`git commit`経由起動を親系列で検出してMM状態ガイダンスを出す用途)
108
+
109
+ `mcp`を本体必須に含めるのはサーバー同梱体験(`pyfltr mcp`が即座に使える)を保つため。
110
+
111
+ ### subprocess実行はPopen一本化
112
+
113
+ `command._run_subprocess()`は`subprocess.Popen`ベースに統一する。
114
+ `--fail-fast`の中断処理(外部スレッドからの`terminate()`呼び出し)が成立する基盤として必要。
115
+ `_active_processes`は`threading.Lock`で排他し、追加・削除と中断の衝突を防ぐ。
116
+
117
+ `_resolve_bin_commandline()`の`mise --version`、`_filter_by_gitignore()`の`git check-ignore`、`main.py`の`cls`/`clear`はパイプライン外のため対象外。
118
+
119
+ ### `cli.py`/`ui.py`の共通化はヘルパーに絞る
120
+
121
+ `cli.py`は`call_from_thread`を持たない直接呼び出し、`ui.py`はRich UIへの`call_from_thread`埋め込みという構造差がある。
122
+ 完全共通化はlock取得タイミング差で実装が複雑になるため、`make_skipped_result()`・`cancel_pending_futures()`の2関数を`stage_runner.py`へ抽出するに留める。
123
+ 残余重複は`# pylint: disable=duplicate-code`を理由コメント付きで維持する。
124
+
125
+ ### `main.py`分割の方針
126
+
127
+ retry系ヘルパー・`--only-failed`フィルター・パス正規化を専用モジュールへ分離し、`main.py`の肥大化を抑える。
128
+ `run_pipeline()`本体は中核として残し、分割対象から外す。
129
+
130
+ | 移動先 | 内容 |
131
+ | --- | --- |
132
+ | `retry.py` | `detect_launcher_prefix()`・`build_retry_args_template()`等のretry系5関数と`_VALUE_OPTIONS` |
133
+ | `only_failed.py` | `apply_filter()`(5サブ関数に責務分割)・`ToolTargets` dataclass |
134
+ | `paths.py` | `normalize_separators()` |
135
+ | `stage_runner.py` | `cli.py`/`ui.py`共通の2ヘルパー |
@@ -0,0 +1,174 @@
1
+ # 実行アーカイブとファイルhashキャッシュ
2
+
3
+ pyfltrが提供する2つのユーザーキャッシュ基盤の設計判断と内部仕様。
4
+ 利用者向けの設定キーや有効/無効化方法は[設定項目](../guide/configuration.md)を参照。
5
+
6
+ ## 共通の前提
7
+
8
+ 両機能は同じユーザーキャッシュディレクトリ配下に保存先を持つ。
9
+ 保存ルートは`platformdirs.user_cache_dir("pyfltr")`で解決し、環境変数`PYFLTR_CACHE_DIR`で上書きできる(テスト・運用上の強制上書き用)。
10
+
11
+ | OS | 既定の保存ルート |
12
+ | --- | --- |
13
+ | Linux | `~/.cache/pyfltr/` |
14
+ | macOS | `~/Library/Caches/pyfltr/` |
15
+ | Windows | `%LOCALAPPDATA%\pyfltr\Cache` |
16
+
17
+ プロジェクトローカルにキャッシュを作らない方針を採る。
18
+ `.gitignore`運用の負担を増やさず、複数プロジェクト横断での参照を可能にするため。
19
+
20
+ ## 実行アーカイブ
21
+
22
+ ### 目的
23
+
24
+ エージェント連携時にJSONL出力のsmart truncationで削られた情報やツール生出力を事後参照可能にする。
25
+ `list-runs`/`show-run`サブコマンドおよびMCPの読み取り系ツール群は本アーカイブを単一の真実源とする。
26
+
27
+ ### ディレクトリ構造
28
+
29
+ ```text
30
+ <cache_root>/runs/<run_id>/meta.json
31
+ <cache_root>/runs/<run_id>/tools/<tool>/output.log
32
+ <cache_root>/runs/<run_id>/tools/<tool>/diagnostics.jsonl
33
+ <cache_root>/runs/<run_id>/tools/<tool>/tool.json
34
+ ```
35
+
36
+ `meta.json`は実行単位のメタ情報。
37
+
38
+ - `run_id`(ULID)・`version`・`python`・`executable`・`platform`・`cwd`
39
+ - `argv`(起動時引数列)・`commands`(実行対象ツール列)・`files`(対象ファイル数)
40
+ - `started_at` / `finished_at`(ISO 8601 UTC)・`exit_code`(finalize後)
41
+
42
+ `tool.json`はツール単位のメタ情報(`tool`/`type`/`status`/`returncode`/`files`/`elapsed`/`diagnostics`/`has_error`/`commandline`)。
43
+ `output.log`はツールの標準出力・標準エラーの結合した生文字列。
44
+ `diagnostics.jsonl`は`ErrorLocation`を1件1行でJSONLシリアライズしたもの。
45
+
46
+ ### run_id
47
+
48
+ ULID(26文字、Crockford Base32、タイムスタンプ由来で辞書順ソート可能)を採用する。
49
+ `python-ulid`パッケージで生成し、JSONLの`header`レコードに`run_id`フィールドとして含める。
50
+
51
+ UUID v4ではなくULIDを採用した理由は次の3点。
52
+
53
+ - タイムスタンプ由来で辞書順ソート=時系列順ソートとなる。`list_runs`の実装・デバッグが簡潔になる
54
+ - 人が見たときに新旧の判別がしやすい
55
+ - 十分な衝突耐性(48bit timestamp + 80bit random)
56
+
57
+ ### 自動クリーンアップ
58
+
59
+ 世代数・合計サイズ・保存期間の3軸で制御する。
60
+ いずれかの閾値を超過した時点で古い順(run_id昇順)に削除する。
61
+
62
+ | 設定キー | 既定値 | 0以下を指定した場合 |
63
+ | --- | --- | --- |
64
+ | `archive-max-runs` | 100 | 世代軸の自動削除を無効化 |
65
+ | `archive-max-size-mb` | 1024 | サイズ軸の自動削除を無効化 |
66
+ | `archive-max-age-days` | 30 | 期間軸の自動削除を無効化 |
67
+
68
+ クリーンアップは各実行冒頭で`ArchiveStore.cleanup()`を同期実行する。
69
+ 将来的な非同期化の余地は残すが、v3初版では単純な同期実行で開始する。
70
+
71
+ ### 書き込み経路
72
+
73
+ TUI経路・非TUI経路・JSONL stdout有無のいずれでもアーカイブ書き込みを発生させる。
74
+ 漏れを防ぐため、`execute_command`戻り値受信直後の独立フックとして提供する。
75
+
76
+ 実装の流れ。
77
+
78
+ 1. `run_pipeline`が`ArchiveStore`を生成し、`start_run`でrun_idを採番する
79
+ 2. `run_pipeline`が`_archive_hook`クロージャを組み立て、`cli.run_commands_with_cli`と`ui.run_commands_with_ui`の`archive_hook`引数へ注入する
80
+ 3. 各実行器はツール完了時(fixステージも含む)に`archive_hook(result)`を呼ぶ
81
+ 4. `run_pipeline`終端で`finalize_run`を呼び、`exit_code`/`finished_at`を書き込む
82
+
83
+ JSONL stdoutストリーミングの`on_result`とは独立した経路にすることで、どちらか一方を切り替えても他方が失われない。
84
+
85
+ ### オプトアウト
86
+
87
+ 既定で有効。次のいずれかで無効化できる。
88
+
89
+ - `--no-archive` CLIオプション
90
+ - `archive = false` 設定
91
+
92
+ 無効化時は`ArchiveStore`を生成せず、`archive_hook`も`None`のまま。
93
+ JSONLの`header`レコードから`run_id`フィールドも省略される。
94
+
95
+ オプトイン化(既定無効)は却下した。
96
+ エージェント連携時のUXを損なうため、既定有効+自動削除で肥大化を抑える設計とした。
97
+
98
+ ### diagnosticシリアライズの方針
99
+
100
+ アーカイブ用の`_error_to_dict`はLLM向け出力(`llm_output.py`)と独立した最小構造とする。
101
+ `ErrorLocation`の全フィールドを保存することで、`rule_url`等のフィールドが追加された際の追従コストを抑える。
102
+
103
+ ## ファイルhashキャッシュ
104
+
105
+ ### キャッシュの目的
106
+
107
+ 同じ入力に対するツール再実行をスキップし、エージェント連携時の待ち時間と無駄な再計算を削減する。
108
+
109
+ ### 対象ツール
110
+
111
+ ファイル間依存を持たず、設定ファイルもCWDでのみ解決するlinterに限定する。
112
+ 具体的には`textlint`のみ。
113
+
114
+ 対象判定は`CommandInfo.cacheable: bool`で明示する。
115
+ 新ツール追加時の判断ミスを防ぐため既定値は`False`とし、対象ツールのみ`True`を指定する。
116
+
117
+ 以下はいずれも対象外とする。
118
+
119
+ - 書き込み型formatter(`ruff-format`/`prettier`/`shfmt`/`uv-sort`)— ヒット時にファイル書き換えがスキップされ、ファイル状態と結果が不整合になる
120
+ - tester(`pytest`/`vitest`)— 対象ファイル以外のソース・設定・環境への依存があり、依存解析またはプロジェクト全体hashが必要で実装コストに見合わない
121
+ - 依存型linter(`mypy`/`ruff-check`/`pylint`等)— import先や型情報のキャッシュが必要で、対象ファイル単独のhashでは整合性を保てない
122
+ - 外部参照linter(`shellcheck`/`actionlint`)— `source`文やreusable workflowなど外部参照を含みうるため安全側で除外
123
+ - 階層型設定を参照するlinter(`ec`/`markdownlint`/`typos`)— 階層型の設定解決は静的列挙では網羅できない
124
+
125
+ ### キャッシュキー
126
+
127
+ 誤ヒットを防ぐため、次の情報をすべてsha256で連結する。
128
+
129
+ - ツール名
130
+ - 実効コマンドライン全体(`--{command}-args`反映後のリスト)
131
+ - ステージ区別(`fix_stage`フラグの真偽)
132
+ - 構造化出力の設定値(`--human-readable`反映後、ツールが構造化出力を持つ場合)
133
+ - 対象ファイル群のsha256(ファイル内容+相対パス)
134
+ - ツール固有設定ファイル群のsha256(存在しない場合は空文字扱い)
135
+ - pyfltrのMAJORバージョン(メジャー更新で出力フォーマット変更時に旧キャッシュを無効化)
136
+
137
+ ツール本体のバージョンはキャッシュキーに含めない。
138
+ `pnpx`/`mise @latest`経由で実体が変わりうるが、短期破棄前提(既定12時間)で実害を許容する方針。
139
+
140
+ ### textlintのconfig_files
141
+
142
+ 公式に自動読み込みされる設定ファイル候補を完全列挙する。
143
+
144
+ - `.textlintrc` / `.textlintrc.json` / `.textlintrc.yml` / `.textlintrc.yaml`
145
+ - `.textlintrc.js` / `.textlintrc.cjs`
146
+ - `package.json`(`textlint`フィールド)
147
+ - `.textlintignore`
148
+
149
+ ### 外部ファイル参照引数の安全策
150
+
151
+ `--{command}-args`に`--config`/`--ignore-path`を含む場合、当該実行ではキャッシュを無効化する(書き込みも読み出しもスキップ)。
152
+ 指定されたパスを動的に解釈する複雑さを避けるための安全側の実装。
153
+
154
+ ### 保存先とクリーンアップ
155
+
156
+ `<cache_root>/cache/<tool>/<hash>.json`として保存する。
157
+ クリーンアップは期間軸のみ(既定`cache-max-age-hours=12`)。
158
+ サイズ・世代数の軸は採用しない(短期破棄前提でストレージ暴発リスクが小さいため)。
159
+
160
+ ### ヒット時の挙動
161
+
162
+ - ツール実行をスキップして`CommandResult`を完全復元し、`cached=True`/`cached_from=<ソースrun_id>`を設定する
163
+ - アーカイブ書き込みは行わない(同じ結果を重複記録しない方針。ソースrunを`cached_from`で参照誘導する)
164
+ - JSONLの`tool`レコードに`cached`/`cached_from`を出力する
165
+ - `retry_command`は出力しない(再実行不要)
166
+
167
+ ### キャッシュのオプトアウト
168
+
169
+ 既定で有効。次のいずれかで無効化できる。
170
+
171
+ - `--no-cache` CLIオプション
172
+ - `cache = false` 設定
173
+
174
+ 実行アーカイブと方針を揃え、エージェント連携時のUXを毀損しないようにする。
@@ -0,0 +1,16 @@
1
+ # 開発者向けガイド
2
+
3
+ pyfltr本体の保守・貢献に必要な情報をまとめている。
4
+ 対象読者は本リポジトリへパッチを送る開発者や、ローカルでpyfltr自身の動作確認を行う利用者。
5
+
6
+ ## 開発手順
7
+
8
+ - [開発手順](development.md) — 開発環境構築・サプライチェーン対策・ドキュメント運用・リリース手順
9
+
10
+ ## 内部設計
11
+
12
+ - [アーキテクチャ概要](architecture.md) — 実行パイプライン・モジュール構成・主要設計判断
13
+ - [実行アーカイブとファイルhashキャッシュ](archive-and-cache.md) — `<cache_root>/runs/`と`<cache_root>/cache/`の保存先・自動クリーンアップ・対象判定
14
+ - [JSONL出力の設計](jsonl-output.md) — severity正規化・rule_url・retry_command・smart truncation・SARIF/GitHub Annotation
15
+ - [詳細参照サブコマンドと再実行支援](subcommands.md) — `list-runs`/`show-run`の実装配置・`--only-failed`/`--from-run`の絞り込み戦略
16
+ - [MCPサーバー](mcp-server.md) — `pyfltr mcp`サブコマンドとMCPツール5種・FastMCP採用・stdio隔離