taskill 0.1.2__tar.gz → 0.1.3__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.
- {taskill-0.1.2 → taskill-0.1.3}/.gitignore +2 -0
- taskill-0.1.3/.windsurf/workflows/daily-docs-update.md +158 -0
- {taskill-0.1.2 → taskill-0.1.3}/CHANGELOG.md +58 -0
- {taskill-0.1.2 → taskill-0.1.3}/PKG-INFO +174 -6
- {taskill-0.1.2 → taskill-0.1.3}/README.md +173 -5
- {taskill-0.1.2 → taskill-0.1.3}/ROADMAP.md +18 -10
- {taskill-0.1.2 → taskill-0.1.3}/SUMD.md +120 -57
- {taskill-0.1.2 → taskill-0.1.3}/SUMR.md +198 -119
- {taskill-0.1.2 → taskill-0.1.3}/TODO.md +27 -15
- taskill-0.1.3/VERSION +1 -0
- {taskill-0.1.2 → taskill-0.1.3}/app.doql.less +5 -1
- taskill-0.1.3/daily_update.sh +93 -0
- {taskill-0.1.2 → taskill-0.1.3}/planfile.yaml +65 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/README.md +3 -3
- taskill-0.1.3/project/analysis.toon.yaml +85 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/calls.mmd +58 -39
- taskill-0.1.3/project/calls.png +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/calls.toon.yaml +57 -38
- {taskill-0.1.2 → taskill-0.1.3}/project/calls.yaml +397 -190
- taskill-0.1.3/project/compact_flow.mmd +4 -0
- taskill-0.1.3/project/compact_flow.png +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/context.md +190 -147
- {taskill-0.1.2 → taskill-0.1.3}/project/duplication.toon.yaml +6 -6
- {taskill-0.1.2 → taskill-0.1.3}/project/evolution.toon.yaml +19 -7
- taskill-0.1.3/project/flow.mmd +25 -0
- taskill-0.1.3/project/flow.png +0 -0
- taskill-0.1.3/project/index.html +623 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/map.toon.yaml +43 -9
- {taskill-0.1.2 → taskill-0.1.3}/project/mermaid.export +122 -53
- taskill-0.1.3/project/project.toon.yaml +56 -0
- {taskill-0.1.2 → taskill-0.1.3}/project/prompt.txt +4 -6
- {taskill-0.1.2 → taskill-0.1.3}/project.sh +1 -1
- {taskill-0.1.2 → taskill-0.1.3}/pyproject.toml +1 -1
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/__init__.py +12 -2
- taskill-0.1.3/src/taskill/bulk.py +249 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/cli.py +94 -0
- taskill-0.1.3/tests/test_bulk.py +279 -0
- taskill-0.1.3/tree.txt +80 -0
- taskill-0.1.2/VERSION +0 -1
- taskill-0.1.2/project/analysis.toon.yaml +0 -60
- taskill-0.1.2/project/calls.png +0 -0
- taskill-0.1.2/project/compact_flow.mmd +0 -2
- taskill-0.1.2/project/compact_flow.png +0 -0
- taskill-0.1.2/project/flow.mmd +0 -25
- taskill-0.1.2/project/flow.png +0 -0
- taskill-0.1.2/project/index.html +0 -623
- taskill-0.1.2/project/project.toon.yaml +0 -53
- {taskill-0.1.2 → taskill-0.1.3}/LICENSE +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/examples/ansible-playbook.yml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/examples/github-action.yml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/examples/gitlab-ci.yml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/examples/systemd-timer/taskill.service +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/examples/systemd-timer/taskill.timer +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/goal.yaml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/prefact.yaml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/config.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/core.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/git_state.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/providers/__init__.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/providers/algorithmic.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/providers/base.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/providers/openrouter.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/providers/windsurf_mcp.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/state.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/triggers.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/updaters/__init__.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/updaters/base.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/updaters/changelog.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/updaters/readme.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/src/taskill/updaters/todo.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/taskill.yaml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/testql-scenarios/generated-cli-tests.testql.toon.yaml +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/__init__.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/test_algorithmic.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/test_config.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/test_providers.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/test_triggers.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tests/test_updaters.py +0 -0
- {taskill-0.1.2 → taskill-0.1.3}/tree.sh +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Daily documentation update workflow across multiple projects
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Daily Documentation Update Workflow
|
|
6
|
+
|
|
7
|
+
This workflow automates the routine task of keeping README.md, CHANGELOG.md, and TODO.md in sync across multiple projects.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
1. Install taskill: `pip install taskill[mcp,schedule]`
|
|
12
|
+
2. Set up OPENROUTER_API_KEY in .env files (or use Windsurf MCP)
|
|
13
|
+
3. Ensure each project has a taskill.yaml config
|
|
14
|
+
|
|
15
|
+
## Single Project
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd /path/to/project
|
|
19
|
+
taskill status # Preview what would change
|
|
20
|
+
taskill run # Execute the update
|
|
21
|
+
taskill run --dry-run # Preview without writing
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Multiple Projects (Bulk Run)
|
|
25
|
+
|
|
26
|
+
### Option 1: Using CLI command
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Run taskill on all repos under ~/github
|
|
30
|
+
taskill bulk-run --root ~/github --max-depth 2
|
|
31
|
+
|
|
32
|
+
# Dry-run to preview
|
|
33
|
+
taskill bulk-run --root ~/github --max-depth 2 --dry-run
|
|
34
|
+
|
|
35
|
+
# Force run (ignore triggers)
|
|
36
|
+
taskill bulk-run --root ~/github --max-depth 2 --force
|
|
37
|
+
|
|
38
|
+
# Filter specific repos (repeatable)
|
|
39
|
+
taskill bulk-run --root ~/github --filter taskill --filter testql
|
|
40
|
+
|
|
41
|
+
# Limit number of projects per run (useful for rate-limited LLMs)
|
|
42
|
+
taskill bulk-run --root ~/github --max-projects 5
|
|
43
|
+
|
|
44
|
+
# Use a shared config + JSON output
|
|
45
|
+
taskill bulk-run --root ~/github \
|
|
46
|
+
--shared-config ~/github/taskill.yaml \
|
|
47
|
+
--max-projects 10 \
|
|
48
|
+
--json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Option 2: Using the shell wrapper
|
|
52
|
+
|
|
53
|
+
`daily_update.sh` wraps the CLI and reads its defaults from `.env`:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# .env in the project root
|
|
57
|
+
GITHUB_ROOT=$HOME/github
|
|
58
|
+
TASKILL_MAX_DEPTH=2
|
|
59
|
+
TASKILL_MAX_PROJECTS=10
|
|
60
|
+
TASKILL_DRY_RUN=false
|
|
61
|
+
TASKILL_FORCE=false
|
|
62
|
+
TASKILL_FILTER=oqlos,semcod # comma-separated
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
./daily_update.sh # uses .env defaults
|
|
67
|
+
./daily_update.sh --dry-run # preview only
|
|
68
|
+
./daily_update.sh --force # ignore triggers
|
|
69
|
+
./daily_update.sh --filter taskill,testql
|
|
70
|
+
./daily_update.sh --root /tmp/projects # override target directory
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Option 3: Using Python script
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pathlib import Path
|
|
77
|
+
from taskill.bulk import bulk_run
|
|
78
|
+
|
|
79
|
+
result = bulk_run(
|
|
80
|
+
root=Path("/home/tom/github"),
|
|
81
|
+
shared_config=Path("/home/tom/github/taskill.yaml"), # optional
|
|
82
|
+
max_depth=2,
|
|
83
|
+
max_projects=10, # 0 = unlimited
|
|
84
|
+
force=False,
|
|
85
|
+
dry_run=False,
|
|
86
|
+
repo_filter=["taskill", "testql"], # optional substring match
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
print(result.summary())
|
|
90
|
+
# 3/5 ran, 2 changed, 1 skipped, 0 errors
|
|
91
|
+
|
|
92
|
+
for repo, repo_result in result.per_repo.items():
|
|
93
|
+
print(repo.name, "ran" if repo_result.ran else "skipped",
|
|
94
|
+
repo_result.files_changed)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## What taskill does
|
|
98
|
+
|
|
99
|
+
1. **CHANGELOG.md**: Appends new entries under [Unreleased] based on git commits
|
|
100
|
+
2. **TODO.md**: Moves completed items to "Done (moved to CHANGELOG)" section
|
|
101
|
+
3. **README.md**: Updates status block between markers (HEAD, coverage, failing tests)
|
|
102
|
+
4. **SUMD.md/SUMR.md**: Reads these files as context for the LLM provider
|
|
103
|
+
|
|
104
|
+
## Triggers
|
|
105
|
+
|
|
106
|
+
By default, taskill only runs when:
|
|
107
|
+
- At least 24 hours since last run
|
|
108
|
+
- At least 1 new commit
|
|
109
|
+
- Files changed threshold met
|
|
110
|
+
- SUMD.md or SUMR.md modified
|
|
111
|
+
|
|
112
|
+
Use `--force` to override triggers.
|
|
113
|
+
|
|
114
|
+
## Automation
|
|
115
|
+
|
|
116
|
+
### Cron job (daily at 6 AM)
|
|
117
|
+
|
|
118
|
+
```cron
|
|
119
|
+
0 6 * * * cd /home/tom/github && /usr/local/bin/taskill bulk-run --root . --max-depth 2 >> ~/.taskill.log 2>&1
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Systemd timer
|
|
123
|
+
|
|
124
|
+
See `examples/systemd-timer/taskill.service` and `taskill.timer`.
|
|
125
|
+
|
|
126
|
+
## Shared Config
|
|
127
|
+
|
|
128
|
+
Pass a shared `taskill.yaml` via `--shared-config` to provide a default config
|
|
129
|
+
for all discovered repos:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# ~/github/taskill.yaml (the shared base)
|
|
133
|
+
triggers:
|
|
134
|
+
min_hours_since_last_run: 24
|
|
135
|
+
min_commits_since_last_run: 1
|
|
136
|
+
providers:
|
|
137
|
+
- name: openrouter
|
|
138
|
+
enabled: true
|
|
139
|
+
- name: algorithmic
|
|
140
|
+
enabled: true
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Resolution order per repo:
|
|
144
|
+
|
|
145
|
+
1. `<repo>/taskill.yaml` (highest priority)
|
|
146
|
+
2. `<repo>/.taskill.yaml`
|
|
147
|
+
3. `--shared-config` rebased onto the repo's path
|
|
148
|
+
4. Built-in defaults
|
|
149
|
+
|
|
150
|
+
Each repo can override only what it needs by dropping a partial `taskill.yaml`
|
|
151
|
+
into its own root.
|
|
152
|
+
|
|
153
|
+
## Troubleshooting
|
|
154
|
+
|
|
155
|
+
- Use `--verbose` flag for debug output
|
|
156
|
+
- Check `.taskill/state.json` for last run state
|
|
157
|
+
- Use `--dry-run` to preview changes
|
|
158
|
+
- Check provider chain in taskill.yaml (windsurf_mcp → openrouter → algorithmic)
|
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [0.1.10] - 2026-04-25
|
|
9
9
|
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fix string-concat issues (ticket-b239ce82)
|
|
12
|
+
- Fix unused-imports issues (ticket-37e0cb27)
|
|
13
|
+
- Fix llm-generated-code issues (ticket-1c7d5f6a)
|
|
14
|
+
- Fix smart-return-type issues (ticket-a7a0a53e)
|
|
15
|
+
- Fix unused-imports issues (ticket-8dae20d0)
|
|
16
|
+
|
|
17
|
+
## [0.1.10] - 2026-04-25
|
|
18
|
+
|
|
10
19
|
### Fixed
|
|
11
20
|
- Fix unused-imports issues (ticket-db5e9dd3)
|
|
12
21
|
- Fix magic-numbers issues (ticket-dba8c3c5)
|
|
@@ -52,6 +61,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
52
61
|
|
|
53
62
|
## [Unreleased]
|
|
54
63
|
|
|
64
|
+
### Added
|
|
65
|
+
- `taskill bulk-run` command for fleet-wide hygiene runs across multiple git repos (ROADMAP v0.5)
|
|
66
|
+
- `taskill.bulk` module with `find_repos`, `resolve_repo_config`, `bulk_run`, and `BulkResult` (exported from `taskill`)
|
|
67
|
+
- `--max-projects` CLI flag and `max_projects` parameter on `bulk_run` to cap per-run project count
|
|
68
|
+
- `--shared-config` flag so a parent directory's `taskill.yaml` can act as the base for all child repos
|
|
69
|
+
- `--filter` flag (repeatable) to limit `bulk-run` to repos whose name matches a substring
|
|
70
|
+
- Per-repo config resolution: `<repo>/taskill.yaml` → `<repo>/.taskill.yaml` → shared → defaults
|
|
71
|
+
- Plugin protocol for providers via `[project.entry-points."taskill.providers"]` and `discover_providers()` (ROADMAP v0.2.1)
|
|
72
|
+
- Plugin protocol for document updaters via `[project.entry-points."taskill.updaters"]` and `discover_updaters()` (ROADMAP v0.2.3)
|
|
73
|
+
- `DocumentUpdater` ABC and `UpdateResult` dataclass in `taskill.updaters.base`
|
|
74
|
+
- `daily_update.sh` shell wrapper around `bulk-run` with `.env`-driven defaults
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
- Built-in providers (`windsurf_mcp`, `openrouter`, `algorithmic`) re-registered via entry points instead of a hard-coded registry
|
|
78
|
+
- Built-in updaters refactored into classes (`ChangelogUpdater`, `TodoUpdater`, `ReadmeUpdater`); legacy `update_changelog` / `update_todo` / `update_readme` functions kept as backward-compatible wrappers
|
|
79
|
+
|
|
80
|
+
### Docs
|
|
81
|
+
- README: new "Bulk / fleet-wide runs" and "Extending taskill" sections
|
|
82
|
+
- ROADMAP: marked v0.2.1, v0.2.3, and v0.5 baseline as shipped
|
|
83
|
+
|
|
84
|
+
## [0.1.3] - 2026-04-25
|
|
85
|
+
|
|
86
|
+
### Docs
|
|
87
|
+
- Update .windsurf/workflows/daily-docs-update.md
|
|
88
|
+
- Update CHANGELOG.md
|
|
89
|
+
- Update README.md
|
|
90
|
+
- Update ROADMAP.md
|
|
91
|
+
- Update SUMD.md
|
|
92
|
+
- Update SUMR.md
|
|
93
|
+
- Update TODO.md
|
|
94
|
+
- Update project/README.md
|
|
95
|
+
- Update project/context.md
|
|
96
|
+
|
|
97
|
+
### Test
|
|
98
|
+
- Update tests/test_bulk.py
|
|
99
|
+
|
|
100
|
+
### Other
|
|
101
|
+
- Update .env.example
|
|
102
|
+
- Update .gitignore
|
|
103
|
+
- Update app.doql.less
|
|
104
|
+
- Update daily_update.sh
|
|
105
|
+
- Update planfile.yaml
|
|
106
|
+
- Update project.sh
|
|
107
|
+
- Update project/analysis.toon.yaml
|
|
108
|
+
- Update project/calls.mmd
|
|
109
|
+
- Update project/calls.png
|
|
110
|
+
- Update project/calls.toon.yaml
|
|
111
|
+
- ... and 13 more files
|
|
112
|
+
|
|
55
113
|
## [0.1.2] - 2026-04-25
|
|
56
114
|
|
|
57
115
|
### Docs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: taskill
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Daily project hygiene: keep README / CHANGELOG / TODO in sync with reality. LLM-first, algorithmic fallback.
|
|
5
5
|
Project-URL: Homepage, https://github.com/oqlos/taskill
|
|
6
6
|
Project-URL: Issues, https://github.com/oqlos/taskill/issues
|
|
@@ -37,10 +37,10 @@ Description-Content-Type: text/markdown
|
|
|
37
37
|
|
|
38
38
|
## AI Cost Tracking
|
|
39
39
|
|
|
40
|
-
    
|
|
41
|
+
  
|
|
42
42
|
|
|
43
|
-
- 🤖 **LLM usage:** $0.
|
|
43
|
+
- 🤖 **LLM usage:** $0.3000 (2 commits)
|
|
44
44
|
- 👤 **Human dev:** ~$200 (2.0h @ $100/h, 30min dedup)
|
|
45
45
|
|
|
46
46
|
Generated on 2026-04-25 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
@@ -81,7 +81,22 @@ Every run produces three (idempotent) edits:
|
|
|
81
81
|
|
|
82
82
|
1. **`CHANGELOG.md`** — appends new entries under `## [Unreleased]`, grouped by Conventional Commit type (`### Added`, `### Fixed`, `### Performance`, etc.). Uses [Keep a Changelog](https://keepachangelog.com/) layout. Existing entries are deduplicated.
|
|
83
83
|
2. **`TODO.md`** — moves completed items to a `## Done (moved to CHANGELOG)` section, and appends `TODO:` / `FIXME:` markers found in new commit bodies under `## Discovered`.
|
|
84
|
-
3. **`README.md`** — refreshes only the block between `<!-- taskill:status:start
|
|
84
|
+
3. **`README.md`** — refreshes only the block between `<!-- taskill:status:start -->
|
|
85
|
+
|
|
86
|
+
## Status
|
|
87
|
+
|
|
88
|
+
_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 09:23 UTC_
|
|
89
|
+
|
|
90
|
+
| Metric | Value |
|
|
91
|
+
|---|---|
|
|
92
|
+
| HEAD | `4618c29` |
|
|
93
|
+
| Coverage | — |
|
|
94
|
+
| Failing tests | — |
|
|
95
|
+
| Commits in last cycle | 0 |
|
|
96
|
+
|
|
97
|
+
> No changes were made to the project since the last taskill run.
|
|
98
|
+
|
|
99
|
+
<!-- taskill:status:end -->` markers (HEAD, coverage, failing tests, summary). Never touches the rest of the file.
|
|
85
100
|
|
|
86
101
|
## Provider chain
|
|
87
102
|
|
|
@@ -128,6 +143,18 @@ triggers:
|
|
|
128
143
|
0 6 * * * cd /path/to/project && /usr/local/bin/taskill run >> ~/.taskill.log 2>&1
|
|
129
144
|
```
|
|
130
145
|
|
|
146
|
+
### Bulk run (multiple projects)
|
|
147
|
+
|
|
148
|
+
For fleet-wide hygiene across many repos:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
taskill bulk-run --root ~/github --max-depth 2
|
|
152
|
+
taskill bulk-run --root ~/github --max-depth 2 --dry-run # preview
|
|
153
|
+
taskill bulk-run --root ~/github --filter taskill --filter testql # filter repos
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
See `/daily-docs-update` workflow for complete documentation.
|
|
157
|
+
|
|
131
158
|
### GitHub Actions
|
|
132
159
|
|
|
133
160
|
See `examples/github-action.yml`. Triggers on `push` to main, runs `taskill run`, opens a PR if files changed.
|
|
@@ -149,10 +176,138 @@ taskill run # execute (respects triggers)
|
|
|
149
176
|
taskill run --force # ignore triggers
|
|
150
177
|
taskill run --dry-run # don't write files or state
|
|
151
178
|
taskill run --json # machine-readable output
|
|
179
|
+
taskill bulk-run # run across all git repos in a directory
|
|
152
180
|
taskill release X.Y.Z # promote [Unreleased] → versioned heading
|
|
153
181
|
taskill clean-todo # wipe TODO.md (after a release)
|
|
154
182
|
```
|
|
155
183
|
|
|
184
|
+
## Bulk / fleet-wide runs
|
|
185
|
+
|
|
186
|
+
When you maintain many small repos (a personal "github" folder, a self-hosted
|
|
187
|
+
GitLab group, a monorepo of independent packages), `taskill bulk-run` runs the
|
|
188
|
+
same hygiene job across all of them with a single command:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Scan ~/github (depth 2), use a shared taskill.yaml as the base config
|
|
192
|
+
taskill bulk-run --root ~/github --shared-config ~/github/taskill.yaml
|
|
193
|
+
|
|
194
|
+
# Same, but only run on repos whose name matches one of the filters
|
|
195
|
+
taskill bulk-run --root ~/github -f oqlos -f semcod
|
|
196
|
+
|
|
197
|
+
# Process at most 5 projects per run (useful for rate-limited LLMs)
|
|
198
|
+
taskill bulk-run --root ~/github --max-projects 5
|
|
199
|
+
|
|
200
|
+
# Preview without writing anything
|
|
201
|
+
taskill bulk-run --root ~/github --dry-run --force
|
|
202
|
+
|
|
203
|
+
# Machine-readable summary for CI / dashboards
|
|
204
|
+
taskill bulk-run --root ~/github --json
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Config resolution per repo
|
|
208
|
+
|
|
209
|
+
Per-repo `taskill.yaml` (or `.taskill.yaml`) takes precedence over the shared
|
|
210
|
+
config, so you can have one default policy plus per-project overrides. Repos
|
|
211
|
+
without any local config inherit the shared one with their own `project_root`.
|
|
212
|
+
|
|
213
|
+
Resolution order for each discovered repo:
|
|
214
|
+
|
|
215
|
+
1. `<repo>/taskill.yaml` — local override (highest priority)
|
|
216
|
+
2. `<repo>/.taskill.yaml` — alternative local override
|
|
217
|
+
3. Shared config from `--shared-config`, rebased onto the repo
|
|
218
|
+
4. Built-in defaults
|
|
219
|
+
|
|
220
|
+
### Discovery rules
|
|
221
|
+
|
|
222
|
+
`bulk-run` walks the directory tree starting at `--root` up to `--max-depth`
|
|
223
|
+
levels deep (default 2). A directory containing a `.git` entry is treated as a
|
|
224
|
+
repo, and `bulk-run` does **not** descend into nested repos. Hidden directories
|
|
225
|
+
and common noise (`node_modules`, `__pycache__`, `.venv`, `dist`, `build`,
|
|
226
|
+
`target`, `.tox`, `.pytest_cache`) are skipped automatically.
|
|
227
|
+
|
|
228
|
+
### Daily-run wrapper
|
|
229
|
+
|
|
230
|
+
A shell wrapper (`daily_update.sh`) reads its defaults from `.env`:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# .env
|
|
234
|
+
GITHUB_ROOT=$HOME/github
|
|
235
|
+
TASKILL_MAX_DEPTH=2
|
|
236
|
+
TASKILL_MAX_PROJECTS=10 # cap per cron tick
|
|
237
|
+
TASKILL_DRY_RUN=false
|
|
238
|
+
TASKILL_FORCE=false
|
|
239
|
+
TASKILL_FILTER=oqlos,semcod # comma-separated
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
./daily_update.sh # uses .env
|
|
244
|
+
./daily_update.sh --dry-run # CLI override
|
|
245
|
+
./daily_update.sh --root /tmp/my-projects # different root
|
|
246
|
+
./daily_update.sh --filter taskill,testql # narrow scope
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Extending taskill: providers and updaters as plugins
|
|
250
|
+
|
|
251
|
+
Both providers (LLM/algorithmic backends) and document updaters (CHANGELOG /
|
|
252
|
+
TODO / README writers) are discovered through Python entry points, so a
|
|
253
|
+
third-party package can register a new provider or updater without touching
|
|
254
|
+
this codebase.
|
|
255
|
+
|
|
256
|
+
### Custom provider
|
|
257
|
+
|
|
258
|
+
```toml
|
|
259
|
+
# my_pkg/pyproject.toml
|
|
260
|
+
[project.entry-points."taskill.providers"]
|
|
261
|
+
my_provider = "my_pkg.provider:MyProvider"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
# my_pkg/provider.py
|
|
266
|
+
from taskill.providers.base import Provider, GeneratedDocs
|
|
267
|
+
|
|
268
|
+
class MyProvider(Provider):
|
|
269
|
+
name = "my_provider"
|
|
270
|
+
|
|
271
|
+
def is_available(self) -> bool:
|
|
272
|
+
return True
|
|
273
|
+
|
|
274
|
+
def generate(self, context) -> GeneratedDocs:
|
|
275
|
+
...
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Then reference it from `taskill.yaml` like any built-in:
|
|
279
|
+
|
|
280
|
+
```yaml
|
|
281
|
+
providers:
|
|
282
|
+
- name: my_provider
|
|
283
|
+
enabled: true
|
|
284
|
+
options: { ... }
|
|
285
|
+
- name: algorithmic
|
|
286
|
+
enabled: true
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Custom updater
|
|
290
|
+
|
|
291
|
+
```toml
|
|
292
|
+
[project.entry-points."taskill.updaters"]
|
|
293
|
+
wiki = "my_pkg.wiki:WikiUpdater"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
from taskill.updaters.base import DocumentUpdater, UpdateResult
|
|
298
|
+
|
|
299
|
+
class WikiUpdater(DocumentUpdater):
|
|
300
|
+
name = "wiki"
|
|
301
|
+
|
|
302
|
+
def apply(self, path, snapshot, docs) -> UpdateResult:
|
|
303
|
+
...
|
|
304
|
+
return UpdateResult(changed=True, path=path, updater_name=self.name)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Built-in updaters (`changelog`, `todo`, `readme`) are registered the same way,
|
|
308
|
+
so removing or replacing them is just a matter of the entry-point taking
|
|
309
|
+
precedence.
|
|
310
|
+
|
|
156
311
|
## Configuration reference
|
|
157
312
|
|
|
158
313
|
See [`taskill.yaml`](./taskill.yaml) at the repo root for the annotated default config.
|
|
@@ -188,5 +343,18 @@ Licensed under Apache-2.0.
|
|
|
188
343
|
## Status
|
|
189
344
|
|
|
190
345
|
<!-- taskill:status:start -->
|
|
191
|
-
|
|
346
|
+
|
|
347
|
+
## Status
|
|
348
|
+
|
|
349
|
+
_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 09:23 UTC_
|
|
350
|
+
|
|
351
|
+
| Metric | Value |
|
|
352
|
+
|---|---|
|
|
353
|
+
| HEAD | `4618c29` |
|
|
354
|
+
| Coverage | — |
|
|
355
|
+
| Failing tests | — |
|
|
356
|
+
| Commits in last cycle | 0 |
|
|
357
|
+
|
|
358
|
+
> No changes were made to the project since the last taskill run.
|
|
359
|
+
|
|
192
360
|
<!-- taskill:status:end -->
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
    
|
|
7
|
+
  
|
|
8
8
|
|
|
9
|
-
- 🤖 **LLM usage:** $0.
|
|
9
|
+
- 🤖 **LLM usage:** $0.3000 (2 commits)
|
|
10
10
|
- 👤 **Human dev:** ~$200 (2.0h @ $100/h, 30min dedup)
|
|
11
11
|
|
|
12
12
|
Generated on 2026-04-25 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
@@ -47,7 +47,22 @@ Every run produces three (idempotent) edits:
|
|
|
47
47
|
|
|
48
48
|
1. **`CHANGELOG.md`** — appends new entries under `## [Unreleased]`, grouped by Conventional Commit type (`### Added`, `### Fixed`, `### Performance`, etc.). Uses [Keep a Changelog](https://keepachangelog.com/) layout. Existing entries are deduplicated.
|
|
49
49
|
2. **`TODO.md`** — moves completed items to a `## Done (moved to CHANGELOG)` section, and appends `TODO:` / `FIXME:` markers found in new commit bodies under `## Discovered`.
|
|
50
|
-
3. **`README.md`** — refreshes only the block between `<!-- taskill:status:start
|
|
50
|
+
3. **`README.md`** — refreshes only the block between `<!-- taskill:status:start -->
|
|
51
|
+
|
|
52
|
+
## Status
|
|
53
|
+
|
|
54
|
+
_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 09:23 UTC_
|
|
55
|
+
|
|
56
|
+
| Metric | Value |
|
|
57
|
+
|---|---|
|
|
58
|
+
| HEAD | `4618c29` |
|
|
59
|
+
| Coverage | — |
|
|
60
|
+
| Failing tests | — |
|
|
61
|
+
| Commits in last cycle | 0 |
|
|
62
|
+
|
|
63
|
+
> No changes were made to the project since the last taskill run.
|
|
64
|
+
|
|
65
|
+
<!-- taskill:status:end -->` markers (HEAD, coverage, failing tests, summary). Never touches the rest of the file.
|
|
51
66
|
|
|
52
67
|
## Provider chain
|
|
53
68
|
|
|
@@ -94,6 +109,18 @@ triggers:
|
|
|
94
109
|
0 6 * * * cd /path/to/project && /usr/local/bin/taskill run >> ~/.taskill.log 2>&1
|
|
95
110
|
```
|
|
96
111
|
|
|
112
|
+
### Bulk run (multiple projects)
|
|
113
|
+
|
|
114
|
+
For fleet-wide hygiene across many repos:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
taskill bulk-run --root ~/github --max-depth 2
|
|
118
|
+
taskill bulk-run --root ~/github --max-depth 2 --dry-run # preview
|
|
119
|
+
taskill bulk-run --root ~/github --filter taskill --filter testql # filter repos
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
See `/daily-docs-update` workflow for complete documentation.
|
|
123
|
+
|
|
97
124
|
### GitHub Actions
|
|
98
125
|
|
|
99
126
|
See `examples/github-action.yml`. Triggers on `push` to main, runs `taskill run`, opens a PR if files changed.
|
|
@@ -115,10 +142,138 @@ taskill run # execute (respects triggers)
|
|
|
115
142
|
taskill run --force # ignore triggers
|
|
116
143
|
taskill run --dry-run # don't write files or state
|
|
117
144
|
taskill run --json # machine-readable output
|
|
145
|
+
taskill bulk-run # run across all git repos in a directory
|
|
118
146
|
taskill release X.Y.Z # promote [Unreleased] → versioned heading
|
|
119
147
|
taskill clean-todo # wipe TODO.md (after a release)
|
|
120
148
|
```
|
|
121
149
|
|
|
150
|
+
## Bulk / fleet-wide runs
|
|
151
|
+
|
|
152
|
+
When you maintain many small repos (a personal "github" folder, a self-hosted
|
|
153
|
+
GitLab group, a monorepo of independent packages), `taskill bulk-run` runs the
|
|
154
|
+
same hygiene job across all of them with a single command:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Scan ~/github (depth 2), use a shared taskill.yaml as the base config
|
|
158
|
+
taskill bulk-run --root ~/github --shared-config ~/github/taskill.yaml
|
|
159
|
+
|
|
160
|
+
# Same, but only run on repos whose name matches one of the filters
|
|
161
|
+
taskill bulk-run --root ~/github -f oqlos -f semcod
|
|
162
|
+
|
|
163
|
+
# Process at most 5 projects per run (useful for rate-limited LLMs)
|
|
164
|
+
taskill bulk-run --root ~/github --max-projects 5
|
|
165
|
+
|
|
166
|
+
# Preview without writing anything
|
|
167
|
+
taskill bulk-run --root ~/github --dry-run --force
|
|
168
|
+
|
|
169
|
+
# Machine-readable summary for CI / dashboards
|
|
170
|
+
taskill bulk-run --root ~/github --json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Config resolution per repo
|
|
174
|
+
|
|
175
|
+
Per-repo `taskill.yaml` (or `.taskill.yaml`) takes precedence over the shared
|
|
176
|
+
config, so you can have one default policy plus per-project overrides. Repos
|
|
177
|
+
without any local config inherit the shared one with their own `project_root`.
|
|
178
|
+
|
|
179
|
+
Resolution order for each discovered repo:
|
|
180
|
+
|
|
181
|
+
1. `<repo>/taskill.yaml` — local override (highest priority)
|
|
182
|
+
2. `<repo>/.taskill.yaml` — alternative local override
|
|
183
|
+
3. Shared config from `--shared-config`, rebased onto the repo
|
|
184
|
+
4. Built-in defaults
|
|
185
|
+
|
|
186
|
+
### Discovery rules
|
|
187
|
+
|
|
188
|
+
`bulk-run` walks the directory tree starting at `--root` up to `--max-depth`
|
|
189
|
+
levels deep (default 2). A directory containing a `.git` entry is treated as a
|
|
190
|
+
repo, and `bulk-run` does **not** descend into nested repos. Hidden directories
|
|
191
|
+
and common noise (`node_modules`, `__pycache__`, `.venv`, `dist`, `build`,
|
|
192
|
+
`target`, `.tox`, `.pytest_cache`) are skipped automatically.
|
|
193
|
+
|
|
194
|
+
### Daily-run wrapper
|
|
195
|
+
|
|
196
|
+
A shell wrapper (`daily_update.sh`) reads its defaults from `.env`:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# .env
|
|
200
|
+
GITHUB_ROOT=$HOME/github
|
|
201
|
+
TASKILL_MAX_DEPTH=2
|
|
202
|
+
TASKILL_MAX_PROJECTS=10 # cap per cron tick
|
|
203
|
+
TASKILL_DRY_RUN=false
|
|
204
|
+
TASKILL_FORCE=false
|
|
205
|
+
TASKILL_FILTER=oqlos,semcod # comma-separated
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
./daily_update.sh # uses .env
|
|
210
|
+
./daily_update.sh --dry-run # CLI override
|
|
211
|
+
./daily_update.sh --root /tmp/my-projects # different root
|
|
212
|
+
./daily_update.sh --filter taskill,testql # narrow scope
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Extending taskill: providers and updaters as plugins
|
|
216
|
+
|
|
217
|
+
Both providers (LLM/algorithmic backends) and document updaters (CHANGELOG /
|
|
218
|
+
TODO / README writers) are discovered through Python entry points, so a
|
|
219
|
+
third-party package can register a new provider or updater without touching
|
|
220
|
+
this codebase.
|
|
221
|
+
|
|
222
|
+
### Custom provider
|
|
223
|
+
|
|
224
|
+
```toml
|
|
225
|
+
# my_pkg/pyproject.toml
|
|
226
|
+
[project.entry-points."taskill.providers"]
|
|
227
|
+
my_provider = "my_pkg.provider:MyProvider"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
# my_pkg/provider.py
|
|
232
|
+
from taskill.providers.base import Provider, GeneratedDocs
|
|
233
|
+
|
|
234
|
+
class MyProvider(Provider):
|
|
235
|
+
name = "my_provider"
|
|
236
|
+
|
|
237
|
+
def is_available(self) -> bool:
|
|
238
|
+
return True
|
|
239
|
+
|
|
240
|
+
def generate(self, context) -> GeneratedDocs:
|
|
241
|
+
...
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Then reference it from `taskill.yaml` like any built-in:
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
providers:
|
|
248
|
+
- name: my_provider
|
|
249
|
+
enabled: true
|
|
250
|
+
options: { ... }
|
|
251
|
+
- name: algorithmic
|
|
252
|
+
enabled: true
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Custom updater
|
|
256
|
+
|
|
257
|
+
```toml
|
|
258
|
+
[project.entry-points."taskill.updaters"]
|
|
259
|
+
wiki = "my_pkg.wiki:WikiUpdater"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from taskill.updaters.base import DocumentUpdater, UpdateResult
|
|
264
|
+
|
|
265
|
+
class WikiUpdater(DocumentUpdater):
|
|
266
|
+
name = "wiki"
|
|
267
|
+
|
|
268
|
+
def apply(self, path, snapshot, docs) -> UpdateResult:
|
|
269
|
+
...
|
|
270
|
+
return UpdateResult(changed=True, path=path, updater_name=self.name)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Built-in updaters (`changelog`, `todo`, `readme`) are registered the same way,
|
|
274
|
+
so removing or replacing them is just a matter of the entry-point taking
|
|
275
|
+
precedence.
|
|
276
|
+
|
|
122
277
|
## Configuration reference
|
|
123
278
|
|
|
124
279
|
See [`taskill.yaml`](./taskill.yaml) at the repo root for the annotated default config.
|
|
@@ -154,5 +309,18 @@ Licensed under Apache-2.0.
|
|
|
154
309
|
## Status
|
|
155
310
|
|
|
156
311
|
<!-- taskill:status:start -->
|
|
157
|
-
|
|
312
|
+
|
|
313
|
+
## Status
|
|
314
|
+
|
|
315
|
+
_Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 09:23 UTC_
|
|
316
|
+
|
|
317
|
+
| Metric | Value |
|
|
318
|
+
|---|---|
|
|
319
|
+
| HEAD | `4618c29` |
|
|
320
|
+
| Coverage | — |
|
|
321
|
+
| Failing tests | — |
|
|
322
|
+
| Commits in last cycle | 0 |
|
|
323
|
+
|
|
324
|
+
> No changes were made to the project since the last taskill run.
|
|
325
|
+
|
|
158
326
|
<!-- taskill:status:end -->
|