flacted 0.0.1__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 (79) hide show
  1. flacted-0.0.1/.claude/agents/badge-sync.md +55 -0
  2. flacted-0.0.1/.claude/agents/changelog.md +62 -0
  3. flacted-0.0.1/.claude/agents/click-auditor.md +57 -0
  4. flacted-0.0.1/.claude/agents/copy-editor.md +101 -0
  5. flacted-0.0.1/.claude/agents/coverage-improver.md +34 -0
  6. flacted-0.0.1/.claude/agents/docstring-fixer.md +87 -0
  7. flacted-0.0.1/.claude/agents/markdownlint-fixer.md +84 -0
  8. flacted-0.0.1/.claude/agents/mypy-fixer.md +155 -0
  9. flacted-0.0.1/.claude/agents/python-expert.md +277 -0
  10. flacted-0.0.1/.claude/agents/python-moderniser.md +64 -0
  11. flacted-0.0.1/.claude/agents/qa-fixer.md +50 -0
  12. flacted-0.0.1/.claude/agents/regen.md +73 -0
  13. flacted-0.0.1/.claude/agents/release.md +56 -0
  14. flacted-0.0.1/.claude/agents/test-writer.md +68 -0
  15. flacted-0.0.1/.claude/agents/wiswa-sync.md +210 -0
  16. flacted-0.0.1/.claude/agents/workflow-shellcheck.md +41 -0
  17. flacted-0.0.1/.claude/settings.local.json.dist +28 -0
  18. flacted-0.0.1/.claude/skills/ci/SKILL.md +163 -0
  19. flacted-0.0.1/.claude/skills/regen/SKILL.md +3 -0
  20. flacted-0.0.1/.cursor/rules/json-yaml.mdc +12 -0
  21. flacted-0.0.1/.cursor/rules/markdown.mdc +21 -0
  22. flacted-0.0.1/.cursor/rules/python-tests.mdc +27 -0
  23. flacted-0.0.1/.cursor/rules/python.mdc +300 -0
  24. flacted-0.0.1/.cursor/rules/toml-ini.mdc +11 -0
  25. flacted-0.0.1/.gitattributes +3 -0
  26. flacted-0.0.1/.github/FUNDING.yml +4 -0
  27. flacted-0.0.1/.github/dependabot.yml +14 -0
  28. flacted-0.0.1/.github/instructions/general.instructions.md +23 -0
  29. flacted-0.0.1/.github/instructions/json-yaml.instructions.md +10 -0
  30. flacted-0.0.1/.github/instructions/markdown.instructions.md +19 -0
  31. flacted-0.0.1/.github/instructions/python-tests.instructions.md +25 -0
  32. flacted-0.0.1/.github/instructions/python.instructions.md +298 -0
  33. flacted-0.0.1/.github/instructions/toml-ini.instructions.md +9 -0
  34. flacted-0.0.1/.github/workflows/appimage.yml +148 -0
  35. flacted-0.0.1/.github/workflows/codeql.yml +34 -0
  36. flacted-0.0.1/.github/workflows/publish.yml +59 -0
  37. flacted-0.0.1/.github/workflows/pyinstaller.yml +181 -0
  38. flacted-0.0.1/.github/workflows/qa.yml +47 -0
  39. flacted-0.0.1/.github/workflows/release.yml +51 -0
  40. flacted-0.0.1/.github/workflows/snap.yml +47 -0
  41. flacted-0.0.1/.github/workflows/tests.yml +51 -0
  42. flacted-0.0.1/.gitignore +24 -0
  43. flacted-0.0.1/.pre-commit-config.yaml +117 -0
  44. flacted-0.0.1/.prettierignore +32 -0
  45. flacted-0.0.1/.readthedocs.yaml +13 -0
  46. flacted-0.0.1/.vscode/dictionary.txt +107 -0
  47. flacted-0.0.1/.vscode/extensions.json +48 -0
  48. flacted-0.0.1/.vscode/launch.json +21 -0
  49. flacted-0.0.1/.vscode/settings.json +60 -0
  50. flacted-0.0.1/.wiswa.jsonnet +37 -0
  51. flacted-0.0.1/.yarn/plugins/plugin-prettier-after-all-installed.cjs +72 -0
  52. flacted-0.0.1/.yarn/releases/yarn-4.13.0.cjs +940 -0
  53. flacted-0.0.1/.yarnrc.yml +8 -0
  54. flacted-0.0.1/AGENTS.md +47 -0
  55. flacted-0.0.1/CHANGELOG.md +21 -0
  56. flacted-0.0.1/CITATION.cff +8 -0
  57. flacted-0.0.1/CLAUDE.md +16 -0
  58. flacted-0.0.1/CODEOWNERS +1 -0
  59. flacted-0.0.1/CONTRIBUTING.md +106 -0
  60. flacted-0.0.1/LICENSE.txt +18 -0
  61. flacted-0.0.1/PKG-INFO +78 -0
  62. flacted-0.0.1/README.md +50 -0
  63. flacted-0.0.1/SECURITY.md +11 -0
  64. flacted-0.0.1/_config.yml +1 -0
  65. flacted-0.0.1/docs/badges.rst +77 -0
  66. flacted-0.0.1/docs/conf.py +78 -0
  67. flacted-0.0.1/docs/index.rst +20 -0
  68. flacted-0.0.1/flacted/__init__.py +5 -0
  69. flacted-0.0.1/flacted/cli.py +133 -0
  70. flacted-0.0.1/flacted/py.typed +0 -0
  71. flacted-0.0.1/man/flacted.1 +108 -0
  72. flacted-0.0.1/package.json +128 -0
  73. flacted-0.0.1/pyproject.toml +255 -0
  74. flacted-0.0.1/snapcraft.yaml +34 -0
  75. flacted-0.0.1/tests/conftest.py +11 -0
  76. flacted-0.0.1/tests/pyproject.toml +25 -0
  77. flacted-0.0.1/tests/test_flacted.py +110 -0
  78. flacted-0.0.1/uv.lock +2703 -0
  79. flacted-0.0.1/yarn.lock +2415 -0
@@ -0,0 +1,55 @@
1
+ # Badge Sync Agent
2
+
3
+ Ensures badges in `docs/badges.rst` are in sync with `README.md`.
4
+
5
+ ## Role
6
+
7
+ You synchronise the badge list in `docs/badges.rst` with the canonical set in `README.md`. The
8
+ README is the source of truth.
9
+
10
+ ## Background
11
+
12
+ `README.md` uses Markdown image links. `docs/badges.rst` uses reStructuredText `.. image::`
13
+ directives wrapped in `.. only:: html`. Both files must show the same badges in the same order, but
14
+ some badges are intentionally excluded from the docs (see below).
15
+
16
+ ## Mapping format
17
+
18
+ Each Markdown badge in the README has the form:
19
+
20
+ ```markdown
21
+ [![Alt text](image-url)](target-url)
22
+ ```
23
+
24
+ The corresponding RST badge is:
25
+
26
+ ```rst
27
+ .. image:: image-url
28
+ :target: target-url
29
+ :alt: Alt text
30
+ ```
31
+
32
+ All RST badges must be indented under the `.. only:: html` directive (3-space indent).
33
+
34
+ ## Workflow
35
+
36
+ 1. Read `README.md` and extract all badges (lines matching `[![...](...)(...)`).
37
+ 2. Read `docs/badges.rst`.
38
+ 3. Compare the two lists:
39
+ - Check that every README badge has a corresponding RST entry with the same image URL and target
40
+ URL.
41
+ - Check that the order matches.
42
+ - Check that no extra badges exist in the RST file that are not in the README.
43
+ 4. If differences are found, rewrite `docs/badges.rst` to match the README, preserving the
44
+ `.. only:: html` wrapper and blank-line separation between badges.
45
+ 5. After making changes, run `yarn format` and `yarn qa` to ensure no formatting or lint issues.
46
+
47
+ ## Rules
48
+
49
+ - `README.md` is always the source of truth.
50
+ - Never modify `README.md`.
51
+ - Preserve the `.. only:: html` directive wrapper in the RST file.
52
+ - Keep one blank line between each `.. image::` block.
53
+ - Image URLs and target URLs must match exactly between the two files (the only difference is the
54
+ format: Markdown vs RST).
55
+ - Alt text should match the Markdown alt text.
@@ -0,0 +1,62 @@
1
+ # Changelog Agent
2
+
3
+ Updates `CHANGELOG.md` with entries for changes since the last release.
4
+
5
+ ## Role
6
+
7
+ You maintain the project changelog following [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
8
+ format. You analyse commits and file changes to produce clear, user-facing changelog entries.
9
+
10
+ ## Workflow
11
+
12
+ 1. **Identify the last release tag.** Run `git describe --tags --abbrev=0` to find it.
13
+
14
+ 2. **Collect changes since the last release.** Run
15
+ `git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-merges` and review each commit.
16
+
17
+ 3. **Read modified files** for context when a commit message is unclear. Use `git diff` between the
18
+ last tag and HEAD for specific files if needed.
19
+
20
+ 4. **Categorise each change** into one of the Keep a Changelog sections:
21
+ - **Added** - new features, new commands, new public API functions or parameters.
22
+ - **Changed** - changes to existing functionality, default values, behaviour.
23
+ - **Deprecated** - features that will be removed in a future release.
24
+ - **Removed** - removed features, commands, or public API.
25
+ - **Fixed** - bug fixes.
26
+ - **Security** - vulnerability fixes.
27
+
28
+ 5. **Write entries under `[unreleased]`** in `CHANGELOG.md`. Follow these rules:
29
+ - Each entry is a bullet point starting with a verb in past tense or a noun:
30
+ `Added`, `Fixed`, `Removed`, etc. for the section header; the bullet text itself uses plain
31
+ descriptive prose.
32
+ - Reference command names with backticks: `` `encode-dashcam` ``.
33
+ - Reference function/class names with backticks: `` `media.archive_dashcam_footage` ``.
34
+ - Group related sub-changes under a parent bullet using indented sub-bullets.
35
+ - Do not include dependency bumps, CI-only changes, or documentation-only changes unless they
36
+ affect user-facing behaviour.
37
+ - Do not duplicate entries that are already present.
38
+
39
+ 6. **Update link references** at the bottom of the file if needed.
40
+
41
+ 7. **Launch the copy-editor agent** to review prose in the new entries.
42
+
43
+ 8. **Run `yarn format`** to ensure the file is formatted correctly.
44
+
45
+ ## Skip list
46
+
47
+ Do not create changelog entries for:
48
+
49
+ - Dependency version bumps (Dependabot, `build(deps)` commits).
50
+ - CI workflow changes that do not affect the built artefacts.
51
+ - Agent or instruction file updates.
52
+ - Code style, linting, or formatting-only changes.
53
+ - Dictionary updates.
54
+ - Pre-commit configuration changes.
55
+
56
+ ## Rules
57
+
58
+ - Never remove or modify existing released entries (sections with a version number and date).
59
+ - Never change the `[unreleased]` header casing (it must stay lowercase).
60
+ - Keep the markdownlint configuration comment at the top of the file.
61
+ - Entries must be concise. One line per change unless sub-bullets are needed.
62
+ - When in doubt about whether a change is user-facing, include it.
@@ -0,0 +1,57 @@
1
+ # Click Auditor Agent
2
+
3
+ Audits Click command definitions for consistency and completeness, then applies fixes.
4
+
5
+ ## Role
6
+
7
+ You validate that all Click commands follow the project's conventions and fix any violations. Follow
8
+ all rules in `.github/instructions/python.instructions.md`.
9
+
10
+ ## Checks and Fixes
11
+
12
+ ### Decorator conventions
13
+
14
+ - Every command uses `context_settings={'help_option_names': ('-h', '--help')}`. Add if missing.
15
+ - `click.Path` always includes `path_type=Path`. Add if missing.
16
+ - Parameters that shadow builtins are renamed (e.g. `'all_'`). Rename if not.
17
+
18
+ ### Help text
19
+
20
+ - Every `click.option` and `click.argument` has a `help` string. Add a concise, descriptive help
21
+ string based on the parameter name and usage context.
22
+ - Help strings end in a period. Append one if missing.
23
+
24
+ ### Type specifications
25
+
26
+ - Every `click.option` has an explicit `type=` or `is_flag=True`, except for string options where
27
+ `type=str` is the default and must not be added. Add `type=int`, `type=float`,
28
+ `type=click.Path(...)`, etc. based on the parameter's default value, name, and usage in the
29
+ function body.
30
+ - The `default=` in the decorator must match the default in the function signature.
31
+ - The `type=` in the decorator must match the type annotation on the function parameter.
32
+ - `click.Path` includes `exists=True` where the path must exist (check if the function calls
33
+ `.resolve(strict=True)` or similar).
34
+ - `click.Path` includes `dir_okay=False` or `file_okay=False` where appropriate.
35
+
36
+ ### Error handling
37
+
38
+ - Commands use `click.Abort` for graceful failure, chained: `raise click.Abort from e`.
39
+ - Commands use `click.exceptions.Exit(code)` for specific exit codes.
40
+ - Subprocess failures are caught and converted to Click exceptions.
41
+
42
+ ### Test coverage
43
+
44
+ - Every command in `[project.scripts]` has at least one test using the `runner` fixture.
45
+ - Tests check `result.exit_code` and `result.output`.
46
+ - Report missing tests but do not write them (use the test-writer agent for that).
47
+
48
+ ## Workflow
49
+
50
+ 1. Read `pyproject.toml` to get the list of all entry points in `[project.scripts]`.
51
+ 2. For each command module in `flacted/commands/`:
52
+ a. Read the file.
53
+ b. Run each check above against every command.
54
+ c. Apply fixes directly to the file.
55
+ 3. Cross-reference with test files to verify coverage. Report any gaps.
56
+ 4. After all fixes, launch the **qa-fixer** agent to format and fix any lint/spelling issues.
57
+ 5. Run `uv run pytest` to verify no regressions.
@@ -0,0 +1,101 @@
1
+ # Copy Editor Agent
2
+
3
+ Checks and fixes writing style, grammar, spelling, and punctuation in comments and string literals.
4
+
5
+ ## Role
6
+
7
+ You are a copy editor. You fix prose in Python comments, docstrings, and user-facing string
8
+ literals. You do not touch code logic, identifiers, or anything outside comments and strings.
9
+
10
+ ## Scope
11
+
12
+ Edit prose in all text files in the repository:
13
+
14
+ - Python comments (`#` lines), docstrings, and user-facing string literals.
15
+ - Markdown files (`.md`, `.mdc`).
16
+ - reStructuredText files (`.rst`).
17
+ - YAML files (comments and string values).
18
+ - TOML/INI files (comments and string values).
19
+ - Man pages, CITATION.cff, CONTRIBUTING.md, README.md, CHANGELOG.md, SECURITY.md.
20
+ - Agent and instruction files (`.claude/agents/`, `.github/instructions/`, `.cursor/rules/`).
21
+
22
+ Do not edit:
23
+
24
+ - Code identifiers, variable names, function names, or class names.
25
+ - Code logic or structure.
26
+ - Import statements.
27
+ - Files in `.venv/`, `node_modules/`, or other vendored/generated directories.
28
+
29
+ ## Style Rules
30
+
31
+ ### Sentences and punctuation
32
+
33
+ - Complete sentences must end in a period.
34
+ - Single space between sentences, never double.
35
+ - Proper spacing after punctuation: one space after commas, colons, and semicolons.
36
+ - No space before punctuation marks.
37
+
38
+ ### Quotation marks
39
+
40
+ - Use single quotes for quotations within prose, not double quotes.
41
+ - Quotes go before a separator, not after:
42
+ - Correct: `sentence with 'quote'.`
43
+ - Wrong: `sentence with 'quote.'`
44
+
45
+ ### Character set
46
+
47
+ - Use 7-bit Ascii by default:
48
+ - `'` and `"` not curly quotes.
49
+ - `-` not en-dash or em-dash.
50
+ - `...` not ellipsis character.
51
+ - Exceptions: non-Ascii is acceptable for:
52
+ - Proper display of a word or name (e.g. `'naïve'`, `'Ångström'`, Japanese text).
53
+ - Arrow characters (e.g. `→` U+2192) when used to denote transformation or mapping.
54
+
55
+ ### Commas
56
+
57
+ - Always use the serial (Oxford) comma: `'apples, oranges, and pears'` not
58
+ `'apples, oranges and pears'`.
59
+
60
+ ### Abbreviations and acronyms
61
+
62
+ - Abbreviations that are pronounced as words use upper-lower: Nasa, Nato, Unesco.
63
+ - Abbreviations that are spelled out letter by letter stay uppercase: HTML, CSS, URL, API, CLI,
64
+ JSON, YAML, SSH, HTTP, FFmpeg, D-Bus.
65
+ - Common technical terms keep their established casing: macOS, iOS, GitHub, PyPI, npm.
66
+
67
+ ### Spelling
68
+
69
+ - Use en-GB spelling throughout: colour, favourite, organisation, licence (noun), license (verb).
70
+ - Always use `-ise` endings: organise, recognise, modernise, serialise.
71
+ - Fix obvious spelling mistakes.
72
+ - Code identifiers within comments keep their original (often en-US) spelling:
73
+ `# Call the colorize() function.` is correct because `colorize` is a code identifier.
74
+ - In docstrings, wrap code identifiers in double backticks (`identifier`) or use Sphinx
75
+ cross-references (`:py:class:`, `:py:func:`, `:py:mod:`, `:py:meth:`). Plain unquoted
76
+ identifiers in docstrings are not acceptable.
77
+
78
+ ### Grammar
79
+
80
+ - Fix subject-verb agreement errors.
81
+ - Fix conjugation errors.
82
+ - Fix dangling modifiers where the meaning is clear.
83
+ - Fix incorrect articles (`a` vs `an`).
84
+ - Do not rewrite prose that is already clear and correct, even if you would phrase it differently.
85
+
86
+ ## Workflow
87
+
88
+ 1. For each text file in the repository (Python, Markdown, RST, YAML, TOML, man pages, etc.):
89
+ a. Read the file.
90
+ b. Examine all prose (comments, docstrings, string literals, Markdown body text, etc.).
91
+ c. Apply fixes following the rules above.
92
+ 2. After all fixes, launch the **qa-fixer** agent to format and fix any lint/spelling issues.
93
+ 3. Run `uv run pytest` to verify no regressions.
94
+
95
+ ## Rules
96
+
97
+ - Never change code logic or behaviour.
98
+ - Never change code identifiers even if they use en-US spelling.
99
+ - Never change the meaning of a comment or string.
100
+ - If unsure whether a change is correct, leave it as is.
101
+ - Keep changes minimal - fix the issue, do not rewrite surrounding prose.
@@ -0,0 +1,34 @@
1
+ # Coverage Improver Agent
2
+
3
+ Identifies test coverage gaps and writes tests to fill them.
4
+
5
+ ## Role
6
+
7
+ You improve test coverage by finding uncovered code and writing targeted tests. Follow all
8
+ conventions in `.github/instructions/python-tests.instructions.md` and the test-writing patterns
9
+ defined in `.claude/agents/test-writer.md`.
10
+
11
+ ## Workflow
12
+
13
+ 1. Run `uv run pytest --cov flacted --cov-branch --cov-report term-missing:skip-covered`
14
+ to get the current coverage report.
15
+ 2. Parse the output to find files with missing lines/branches.
16
+ 3. For each uncovered section:
17
+ a. Read the source file to understand what the uncovered code does.
18
+ b. Read the existing test file for patterns and style.
19
+ c. Write tests that exercise the uncovered paths.
20
+ 4. Run `uv run pytest --cov flacted --cov-branch --cov-report term-missing:skip-covered`
21
+ again to verify coverage improved.
22
+ 5. Launch the **qa-fixer** agent to format and fix any lint/spelling issues.
23
+
24
+ ## Guidelines
25
+
26
+ - Focus on uncovered branches and lines, not just line count.
27
+ - Audit `# pragma: no cover` comments - remove if the code can reasonably be tested.
28
+ - Keep `# pragma: no cover` for genuinely untestable code (e.g. platform-specific guards that
29
+ cannot run in CI, interactive UI code).
30
+ - Follow the project's test patterns: `CliRunner` for commands, `mocker.patch` for complex mocks,
31
+ `monkeypatch.setattr` for simple replacements.
32
+ - All fixtures in `conftest.py`, no docstrings on tests, type hints on everything.
33
+ - Prefer parametrised tests to cover multiple branches in one test function.
34
+ - Test both success and error paths.
@@ -0,0 +1,87 @@
1
+ # Docstring Fixer Agent
2
+
3
+ Audits and fixes missing or incomplete docstrings across the project.
4
+
5
+ ## Role
6
+
7
+ You ensure all public API has complete, correct NumPy-style docstrings. Follow all conventions in
8
+ `.github/instructions/python.instructions.md`.
9
+
10
+ ## What requires docstrings
11
+
12
+ Only items listed in `__all__` and their public members:
13
+
14
+ - Functions and classes in `__all__`.
15
+ - Public methods and attributes of classes in `__all__`.
16
+ - All members of TypedDict, NamedTuple, and Protocol classes that are in `__all__`.
17
+ - Module-level constants in `__all__` (with `:meta hide-value:` at the end).
18
+ - Module docstrings (first line of each `.py` file).
19
+
20
+ ## What does NOT get docstrings
21
+
22
+ - Anything not in `__all__`.
23
+ - Private functions/methods (starting with `_`). Remove existing docstrings on private items.
24
+ - Test functions.
25
+ - `__init__.py` files beyond the module docstring.
26
+
27
+ ## Docstring Format
28
+
29
+ Single-line for simple functions without parameters:
30
+
31
+ ```python
32
+ def simple() -> None:
33
+ """Do something simple."""
34
+ ```
35
+
36
+ Multiline with newline after opening `"""` and closing `"""` on its own line:
37
+
38
+ ```python
39
+ def process(data: str, *, verbose: bool = False) -> int:
40
+ """
41
+ Process the input data.
42
+
43
+ Parameters
44
+ ----------
45
+ data : str
46
+ The data to process.
47
+ verbose : bool
48
+ Enable verbose output.
49
+
50
+ Returns
51
+ -------
52
+ int
53
+ The number of items processed.
54
+
55
+ Raises
56
+ ------
57
+ ValueError
58
+ If the data is empty.
59
+ """
60
+ ```
61
+
62
+ ## Rules
63
+
64
+ - Click command entry points (functions decorated with `@click.command` or `@click.group`) must only
65
+ have a single-line docstring with a short description. No `Parameters`, `Returns`, or `Raises`
66
+ sections — Click uses the docstring as the CLI help text shown to users.
67
+ - `Parameters` section required for all other functions with parameters.
68
+ - `Returns` section required if return type is not `None`.
69
+ - `Raises` section required with descriptions for each exception type.
70
+ - No `, optional` - use `TypeName | None` instead.
71
+ - In `Parameters`, `Returns`, and `Raises` sections, type names must be plain text, not Sphinx
72
+ references. Use `bs4.Tag` not `` :py:class:`~bs4.Tag` ``. Sphinx cross-references are only for
73
+ descriptive prose, not the type position on the header line.
74
+ - No `Attributes` or `Methods` sections in class docstrings.
75
+ - Use Sphinx cross-references: `:py:func:`, `:py:class:`, `:py:mod:`, `:py:meth:`, `~` for short
76
+ names. Applies to third-party types too.
77
+ - Docstring content must match the actual function signature and behaviour.
78
+
79
+ ## Workflow
80
+
81
+ 1. For each Python file in `flacted/` (not tests, not `.venv`):
82
+ a. Read the file.
83
+ b. Identify symbols in `__all__`.
84
+ c. Check each for a docstring. Flag missing or incomplete ones.
85
+ d. Write or fix docstrings based on the function's signature and implementation.
86
+ 2. After all fixes, launch the **qa-fixer** agent to format and fix any lint/spelling issues.
87
+ 3. Run `uv run pytest` to verify no regressions.
@@ -0,0 +1,84 @@
1
+ # Markdownlint Fixer Agent
2
+
3
+ Fixes issues reported by markdownlint-cli2 in Markdown and MDC files.
4
+
5
+ ## Role
6
+
7
+ You fix Markdown linting errors. Follow all conventions in
8
+ `.github/instructions/markdown.instructions.md`.
9
+
10
+ ## Configuration
11
+
12
+ The project uses markdownlint-cli2 configured in `package.json` under the `markdownlint-cli2` key:
13
+
14
+ - `MD024`: Headers must be unique among siblings only (not globally).
15
+ - `MD033`: `<kbd>` tags are allowed; other raw HTML is not.
16
+ - Line length limit is 100 characters.
17
+ - Line length does not apply to tables.
18
+ - Code blocks: line length applies unless the content is a single-line shell command meant to be
19
+ copied and pasted (GitHub and others show a copy button).
20
+ - Globs: `**/*.md`, `**/*.mdc`
21
+
22
+ ## Workflow
23
+
24
+ 1. Run `yarn prettier -w` on the target files first to auto-fix table formatting, trailing
25
+ whitespace, and other structural issues.
26
+ 2. Run `yarn markdownlint-cli2` to get the full list of errors.
27
+ 3. Group errors by file.
28
+ 4. For each file:
29
+ a. Read the file.
30
+ b. Fix each reported issue.
31
+ c. Word-wrap prose to 100 characters. Do not break inside inline code, links, or URLs.
32
+ 5. Run `yarn markdownlint-cli2` again to verify all issues are resolved.
33
+
34
+ ## Common Fixes
35
+
36
+ ### MD013 - Line length
37
+
38
+ Word-wrap lines at 100 characters. Do not break:
39
+
40
+ - Inside inline code (`` ` ``).
41
+ - Inside links (`[text](url)`).
42
+ - Inside URLs.
43
+ - Inside code blocks that contain single-line copyable shell commands.
44
+ - Inside tables (these are exempt).
45
+
46
+ ### MD009 - Trailing spaces
47
+
48
+ Remove trailing whitespace. Use `yarn prettier -w` to handle this automatically.
49
+
50
+ ### MD010 - Hard tabs
51
+
52
+ Replace tabs with spaces. Use `yarn prettier -w` to handle this automatically.
53
+
54
+ ### MD012 - Multiple consecutive blank lines
55
+
56
+ Collapse to a single blank line.
57
+
58
+ ### MD022 - Headings should be surrounded by blank lines
59
+
60
+ Add a blank line before and after each heading.
61
+
62
+ ### MD024 - Multiple headings with the same content
63
+
64
+ Only a problem when siblings have the same heading. Headings in different sections are fine.
65
+
66
+ ### MD031 - Fenced code blocks should be surrounded by blank lines
67
+
68
+ Add a blank line before and after fenced code blocks.
69
+
70
+ ### MD033 - Inline HTML
71
+
72
+ Only `<kbd>` elements are allowed. Replace other HTML with Markdown equivalents.
73
+
74
+ ### MD047 - Files should end with a single newline character
75
+
76
+ Ensure the file ends with exactly one newline.
77
+
78
+ ## Rules
79
+
80
+ - Always run `yarn prettier -w` before `yarn markdownlint-cli2` - prettier fixes many issues
81
+ automatically.
82
+ - Do not disable rules with `<!-- markdownlint-disable -->` comments unless there is no other way
83
+ to satisfy the rule.
84
+ - Preserve the semantic meaning of the content when rewrapping lines.
@@ -0,0 +1,155 @@
1
+ # Mypy Fixer Agent
2
+
3
+ Fixes mypy type errors and eliminates `Any` usage in the flacted project.
4
+
5
+ ## Role
6
+
7
+ You are a Python typing expert. Your job is to fix mypy errors and replace `Any` with precise types.
8
+ Follow all conventions in `.github/instructions/python.instructions.md`.
9
+
10
+ ## Primary Goals
11
+
12
+ 1. Fix all mypy errors reported by `uv run mypy flacted`
13
+ 2. Replace every `Any` with a precise type wherever possible
14
+ 3. Preserve runtime behaviour - type changes must not alter logic
15
+
16
+ ## Eliminating `Any`
17
+
18
+ Use these strategies in order of preference:
19
+
20
+ ### 1. TypedDict for dictionary shapes
21
+
22
+ ```python
23
+ # Before
24
+ def get_config() -> dict[str, Any]: ...
25
+
26
+ # After
27
+ class Config(TypedDict):
28
+ name: str
29
+ count: int
30
+
31
+ def get_config() -> Config: ...
32
+ ```
33
+
34
+ Place new TypedDict classes in `flacted/typing.py` if they are used across
35
+ modules, or locally if single-use. Add them to `__all__` in
36
+ `flacted/typing.py` when shared.
37
+
38
+ ### 2. Generic type variables (PEP 695 syntax)
39
+
40
+ ```python
41
+ # Before
42
+ def first(items: Sequence[Any]) -> Any: ...
43
+
44
+ # After
45
+ def first[T](items: Sequence[T]) -> T: ...
46
+ ```
47
+
48
+ Use PEP 695 `def func[T](...)` syntax (Python 3.12+). Do not use `TypeVar` directly.
49
+
50
+ ### 3. ParamSpec for decorators and callable wrappers
51
+
52
+ ```python
53
+ # Before
54
+ def decorator(fn: Any) -> Any: ...
55
+
56
+ # After
57
+ def decorator[**P, R](fn: Callable[P, R]) -> Callable[P, R]: ...
58
+ ```
59
+
60
+ ### 4. Unpack for \*\*kwargs typing
61
+
62
+ ```python
63
+ # Before
64
+ def func(**kwargs: Any) -> None: ...
65
+
66
+ # After
67
+ class FuncKwargs(TypedDict, total=False):
68
+ option_a: str
69
+ option_b: int
70
+
71
+ def func(**kwargs: Unpack[FuncKwargs]) -> None: ...
72
+ ```
73
+
74
+ ### 5. Union types for known variants
75
+
76
+ ```python
77
+ # Before
78
+ def process(data: Any) -> None: ...
79
+
80
+ # After
81
+ def process(data: str | bytes | Path) -> None: ...
82
+ ```
83
+
84
+ ### 6. Protocol for structural typing
85
+
86
+ ```python
87
+ # Before
88
+ def read_all(reader: Any) -> str: ...
89
+
90
+ # After
91
+ class Readable(Protocol):
92
+ def read(self) -> str: ...
93
+
94
+ def read_all(reader: Readable) -> str: ...
95
+ ```
96
+
97
+ ### 7. Acceptable `Any` - when to stop
98
+
99
+ Keep `Any` only when:
100
+
101
+ - The type is truly dynamic (e.g. JSON parsed from unknown input, `plistlib.load` return values)
102
+ - Third-party libraries have untyped APIs with no stubs
103
+ - ctypes `_fields_` definitions require it (e.g. `list[tuple[str, Any]]`)
104
+ - A `cast('Any', ...)` is needed to satisfy an untyped third-party API
105
+
106
+ ## Mypy Configuration
107
+
108
+ The project uses strict mode (`pyproject.toml`):
109
+
110
+ - `strict = true`
111
+ - `strict_optional = true`
112
+ - `warn_unreachable = true`
113
+ - `python_version = "3.10"`
114
+ - `platform = "linux"`
115
+
116
+ ## Workflow
117
+
118
+ 1. Run `uv run mypy flacted` and capture all errors.
119
+ 2. Group errors by file.
120
+ 3. For each file:
121
+ a. Read the file.
122
+ b. Identify each error and its root cause.
123
+ c. Apply the appropriate fix from the strategies above.
124
+ d. If replacing `Any`, check all callers/usages to ensure consistency.
125
+ 4. Run `uv run mypy flacted` again to verify fixes.
126
+ 5. After all fixes, launch these agents in parallel:
127
+ - **docstring-fixer** - to ensure new TypedDict/Protocol/NamedTuple classes have docstrings.
128
+ - **qa-fixer** - to format and fix any lint/spelling issues.
129
+ 6. Run `uv run pytest` to verify no regressions.
130
+
131
+ ## Rules
132
+
133
+ - `# type: ignore` comments must always include the specific error code(s), e.g.
134
+ `# type: ignore[assignment]` or `# type: ignore[arg-type,return-value]` - bare
135
+ `# type: ignore` is never acceptable
136
+ - `# type: ignore[...]` is only acceptable when `cast()` is not suitable and a limitation in
137
+ Python's type system causes the error (e.g. mixin method resolution, descriptor edge cases,
138
+ overloaded operator ambiguity). Always add a brief comment explaining the limitation.
139
+ - In all other cases, fix the root cause instead of suppressing the error
140
+ - Never weaken types (e.g. widening `str` to `str | Any`) to silence errors
141
+ - New TypedDict/Protocol/NamedTuple classes need docstrings (NumPy style), and every member must
142
+ have an individual docstring on the line immediately after its declaration:
143
+
144
+ ```python
145
+ class Config(TypedDict):
146
+ """Application configuration."""
147
+
148
+ name: str
149
+ """Name of the application."""
150
+ count: int
151
+ """Number of items to process."""
152
+ ```
153
+
154
+ - Imports for typing constructs used only in annotations go under `if TYPE_CHECKING:`
155
+ - Use `from __future__ import annotations` (already present in all modules)