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.
- flacted-0.0.1/.claude/agents/badge-sync.md +55 -0
- flacted-0.0.1/.claude/agents/changelog.md +62 -0
- flacted-0.0.1/.claude/agents/click-auditor.md +57 -0
- flacted-0.0.1/.claude/agents/copy-editor.md +101 -0
- flacted-0.0.1/.claude/agents/coverage-improver.md +34 -0
- flacted-0.0.1/.claude/agents/docstring-fixer.md +87 -0
- flacted-0.0.1/.claude/agents/markdownlint-fixer.md +84 -0
- flacted-0.0.1/.claude/agents/mypy-fixer.md +155 -0
- flacted-0.0.1/.claude/agents/python-expert.md +277 -0
- flacted-0.0.1/.claude/agents/python-moderniser.md +64 -0
- flacted-0.0.1/.claude/agents/qa-fixer.md +50 -0
- flacted-0.0.1/.claude/agents/regen.md +73 -0
- flacted-0.0.1/.claude/agents/release.md +56 -0
- flacted-0.0.1/.claude/agents/test-writer.md +68 -0
- flacted-0.0.1/.claude/agents/wiswa-sync.md +210 -0
- flacted-0.0.1/.claude/agents/workflow-shellcheck.md +41 -0
- flacted-0.0.1/.claude/settings.local.json.dist +28 -0
- flacted-0.0.1/.claude/skills/ci/SKILL.md +163 -0
- flacted-0.0.1/.claude/skills/regen/SKILL.md +3 -0
- flacted-0.0.1/.cursor/rules/json-yaml.mdc +12 -0
- flacted-0.0.1/.cursor/rules/markdown.mdc +21 -0
- flacted-0.0.1/.cursor/rules/python-tests.mdc +27 -0
- flacted-0.0.1/.cursor/rules/python.mdc +300 -0
- flacted-0.0.1/.cursor/rules/toml-ini.mdc +11 -0
- flacted-0.0.1/.gitattributes +3 -0
- flacted-0.0.1/.github/FUNDING.yml +4 -0
- flacted-0.0.1/.github/dependabot.yml +14 -0
- flacted-0.0.1/.github/instructions/general.instructions.md +23 -0
- flacted-0.0.1/.github/instructions/json-yaml.instructions.md +10 -0
- flacted-0.0.1/.github/instructions/markdown.instructions.md +19 -0
- flacted-0.0.1/.github/instructions/python-tests.instructions.md +25 -0
- flacted-0.0.1/.github/instructions/python.instructions.md +298 -0
- flacted-0.0.1/.github/instructions/toml-ini.instructions.md +9 -0
- flacted-0.0.1/.github/workflows/appimage.yml +148 -0
- flacted-0.0.1/.github/workflows/codeql.yml +34 -0
- flacted-0.0.1/.github/workflows/publish.yml +59 -0
- flacted-0.0.1/.github/workflows/pyinstaller.yml +181 -0
- flacted-0.0.1/.github/workflows/qa.yml +47 -0
- flacted-0.0.1/.github/workflows/release.yml +51 -0
- flacted-0.0.1/.github/workflows/snap.yml +47 -0
- flacted-0.0.1/.github/workflows/tests.yml +51 -0
- flacted-0.0.1/.gitignore +24 -0
- flacted-0.0.1/.pre-commit-config.yaml +117 -0
- flacted-0.0.1/.prettierignore +32 -0
- flacted-0.0.1/.readthedocs.yaml +13 -0
- flacted-0.0.1/.vscode/dictionary.txt +107 -0
- flacted-0.0.1/.vscode/extensions.json +48 -0
- flacted-0.0.1/.vscode/launch.json +21 -0
- flacted-0.0.1/.vscode/settings.json +60 -0
- flacted-0.0.1/.wiswa.jsonnet +37 -0
- flacted-0.0.1/.yarn/plugins/plugin-prettier-after-all-installed.cjs +72 -0
- flacted-0.0.1/.yarn/releases/yarn-4.13.0.cjs +940 -0
- flacted-0.0.1/.yarnrc.yml +8 -0
- flacted-0.0.1/AGENTS.md +47 -0
- flacted-0.0.1/CHANGELOG.md +21 -0
- flacted-0.0.1/CITATION.cff +8 -0
- flacted-0.0.1/CLAUDE.md +16 -0
- flacted-0.0.1/CODEOWNERS +1 -0
- flacted-0.0.1/CONTRIBUTING.md +106 -0
- flacted-0.0.1/LICENSE.txt +18 -0
- flacted-0.0.1/PKG-INFO +78 -0
- flacted-0.0.1/README.md +50 -0
- flacted-0.0.1/SECURITY.md +11 -0
- flacted-0.0.1/_config.yml +1 -0
- flacted-0.0.1/docs/badges.rst +77 -0
- flacted-0.0.1/docs/conf.py +78 -0
- flacted-0.0.1/docs/index.rst +20 -0
- flacted-0.0.1/flacted/__init__.py +5 -0
- flacted-0.0.1/flacted/cli.py +133 -0
- flacted-0.0.1/flacted/py.typed +0 -0
- flacted-0.0.1/man/flacted.1 +108 -0
- flacted-0.0.1/package.json +128 -0
- flacted-0.0.1/pyproject.toml +255 -0
- flacted-0.0.1/snapcraft.yaml +34 -0
- flacted-0.0.1/tests/conftest.py +11 -0
- flacted-0.0.1/tests/pyproject.toml +25 -0
- flacted-0.0.1/tests/test_flacted.py +110 -0
- flacted-0.0.1/uv.lock +2703 -0
- 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
|
+
[](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)
|