dot-tasks 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dot_tasks-0.1.0/LICENSE +21 -0
- dot_tasks-0.1.0/PKG-INFO +173 -0
- dot_tasks-0.1.0/README.md +142 -0
- dot_tasks-0.1.0/pyproject.toml +57 -0
- dot_tasks-0.1.0/setup.cfg +4 -0
- dot_tasks-0.1.0/src/dot_tasks/__init__.py +5 -0
- dot_tasks-0.1.0/src/dot_tasks/__main__.py +4 -0
- dot_tasks-0.1.0/src/dot_tasks/_version.py +3 -0
- dot_tasks-0.1.0/src/dot_tasks/agents_snippet.py +80 -0
- dot_tasks-0.1.0/src/dot_tasks/cli.py +900 -0
- dot_tasks-0.1.0/src/dot_tasks/models.py +74 -0
- dot_tasks-0.1.0/src/dot_tasks/prompt_ui.py +441 -0
- dot_tasks-0.1.0/src/dot_tasks/render.py +288 -0
- dot_tasks-0.1.0/src/dot_tasks/resources/agents/task-management-dot-tasks.md +21 -0
- dot_tasks-0.1.0/src/dot_tasks/selector_ui.py +195 -0
- dot_tasks-0.1.0/src/dot_tasks/service.py +400 -0
- dot_tasks-0.1.0/src/dot_tasks/storage.py +513 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/PKG-INFO +173 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/SOURCES.txt +28 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/dependency_links.txt +1 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/entry_points.txt +2 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/requires.txt +7 -0
- dot_tasks-0.1.0/src/dot_tasks.egg-info/top_level.txt +1 -0
- dot_tasks-0.1.0/tests/test_agents_snippet.py +63 -0
- dot_tasks-0.1.0/tests/test_cli.py +1034 -0
- dot_tasks-0.1.0/tests/test_examples_demo.py +41 -0
- dot_tasks-0.1.0/tests/test_logo_assets.py +84 -0
- dot_tasks-0.1.0/tests/test_prompt_ui.py +559 -0
- dot_tasks-0.1.0/tests/test_render.py +184 -0
- dot_tasks-0.1.0/tests/test_storage.py +240 -0
dot_tasks-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Awni
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
dot_tasks-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dot-tasks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Human-readable and agent-readable task manager with a minimal CLI
|
|
5
|
+
Author: dot-tasks contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Awni00/dot-tasks
|
|
8
|
+
Project-URL: Repository, https://github.com/Awni00/dot-tasks
|
|
9
|
+
Project-URL: Issues, https://github.com/Awni00/dot-tasks/issues
|
|
10
|
+
Keywords: tasks,cli,workflow,productivity,automation
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: typer>=0.12
|
|
25
|
+
Requires-Dist: PyYAML>=6.0
|
|
26
|
+
Requires-Dist: InquirerPy>=0.3.4
|
|
27
|
+
Requires-Dist: rich>=13.7.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<picture>
|
|
34
|
+
<source srcset="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-dark.svg" media="(prefers-color-scheme: dark)">
|
|
35
|
+
<source srcset="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-light.svg" media="(prefers-color-scheme: light)">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-light.svg" alt="dot-tasks logo">
|
|
37
|
+
</picture>
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
`dot-tasks` is a small CLI for managing project-level tasks in a local `.tasks/` directory, using human- and agent-readable files.
|
|
41
|
+
|
|
42
|
+
It started as a personal workflow tool: keep task specs in files, let agents work from those specs, and keep progress updates in the repo instead of chat history. It is shared here in case the same approach is useful to others.
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<a href="https://github.com/Awni00/dot-tasks/actions/workflows/tests.yml"><img src="https://github.com/Awni00/dot-tasks/actions/workflows/tests.yml/badge.svg" alt="Unit Tests"></a>
|
|
48
|
+
<a href="https://github.com/Awni00/dot-tasks/actions/workflows/publish.yml"><img src="https://github.com/Awni00/dot-tasks/actions/workflows/publish.yml/badge.svg" alt="Publish"></a>
|
|
49
|
+
<a href="https://pypi.org/project/dot-tasks/"><img src="https://img.shields.io/pypi/v/dot-tasks" alt="PyPI version"></a>
|
|
50
|
+
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License">
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
## High-level Workflow
|
|
54
|
+
|
|
55
|
+
This is the workflow I usually follow.
|
|
56
|
+
|
|
57
|
+
| Step | What happens | Command(s) | Files touched |
|
|
58
|
+
| --- | --- | --- | --- |
|
|
59
|
+
| Make note of new to-do | Write down the task spec. Often I have an agent draft a spec from a rough note. | `dot-tasks create` | Creates task dir `.tasks/todo/<created-date>-<task_name>/` with `task.md`, `activity.md`|
|
|
60
|
+
| Choose task to work on | Scan what is in `todo`/`doing` and pick the next task to start. | `dot-tasks list` | read-only inspection of `.tasks/` |
|
|
61
|
+
| Start active work | Move the task to active status when implementation begins. | `dot-tasks start` | Move task from `.tasks/todo/` to `.tasks/doing/`; `plan.md` created |
|
|
62
|
+
| Work loop | Log notable progress updates so humans and agents share context. | `dot-tasks update` | `task.md`, `activity.md` |
|
|
63
|
+
| Finish and archive state | Mark done when acceptance criteria are met, preserving full history in files. | `dot-tasks complete` | task directory moves to `.tasks/done/`|
|
|
64
|
+
|
|
65
|
+
## Contents
|
|
66
|
+
|
|
67
|
+
- [High-level Workflow](#high-level-workflow)
|
|
68
|
+
- [Installation](#installation)
|
|
69
|
+
- [Quick Start](#quick-start)
|
|
70
|
+
- [Task Layout](#task-layout)
|
|
71
|
+
- [Commands](#commands)
|
|
72
|
+
- [AI Agent Integration](#ai-agent-integration)
|
|
73
|
+
- [Example Project](#example-project)
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
### Install via pip (PyPI)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install dot-tasks
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Quick check:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
dot-tasks --help
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Install Latest from GitHub
|
|
90
|
+
|
|
91
|
+
Install the latest from GitHub:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pip install "git+https://github.com/Awni00/dot-tasks.git"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Development Install (with uv)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://github.com/Awni00/dot-tasks.git
|
|
101
|
+
cd dot-tasks
|
|
102
|
+
uv sync --dev
|
|
103
|
+
uv run dot-tasks --help
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Editable install:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
uv pip install -e ".[dev]"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Quick Start
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
dot-tasks init
|
|
116
|
+
dot-tasks create add-task-manager --summary "Build initial package"
|
|
117
|
+
dot-tasks start add-task-manager
|
|
118
|
+
dot-tasks update add-task-manager --note "Implemented storage layer"
|
|
119
|
+
dot-tasks complete add-task-manager
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Task Layout
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
.tasks/
|
|
126
|
+
todo/
|
|
127
|
+
doing/
|
|
128
|
+
done/
|
|
129
|
+
trash/
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Each task lives in `.tasks/<status-bucket>/<created-date>-<task_name>/` and contains:
|
|
133
|
+
|
|
134
|
+
- `task.md` (canonical metadata frontmatter + task body)
|
|
135
|
+
- `activity.md` (append-only audit log)
|
|
136
|
+
- `plan.md` (created when the task is started)
|
|
137
|
+
|
|
138
|
+
## Commands
|
|
139
|
+
|
|
140
|
+
| Command | Purpose | Typical usage |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `init` | Create `.tasks/` and write/update managed config settings; can also append workflow guidance section AGENTS.md and install the skill via `npx skills`. | `dot-tasks init` |
|
|
143
|
+
| `create` | Add a new task to `todo/`. | `dot-tasks create <task_name>` |
|
|
144
|
+
| `start` | Move a task to `doing/` and create `plan.md`. | `dot-tasks start <task_name>` |
|
|
145
|
+
| `complete` | Move a task to `done/`. | `dot-tasks complete <task_name>` |
|
|
146
|
+
| `list` | List tasks by status (rich/plain/JSON depending on context). | `dot-tasks list [todo|doing|done] [--json]` |
|
|
147
|
+
| `view` | Show full details for one task. | `dot-tasks view <task_name> [--json]` |
|
|
148
|
+
| `update` | Update metadata, dependencies, tags, or add notes. | `dot-tasks update <task_name> ...` |
|
|
149
|
+
| `rename` | Rename a task. | `dot-tasks rename <task_name> <new_task_name>` |
|
|
150
|
+
| `delete` | Move a task to `trash/`, or delete permanently with `--hard`. | `dot-tasks delete <task_name> [--hard]` |
|
|
151
|
+
|
|
152
|
+
## AI Agent Integration
|
|
153
|
+
|
|
154
|
+
`dot-tasks` is designed so humans and agents can work from the same file-based task state in `.tasks/` instead of relying on chat context.
|
|
155
|
+
|
|
156
|
+
Typical agent workflow:
|
|
157
|
+
|
|
158
|
+
1. Capture or refine a task spec with `dot-tasks create`.
|
|
159
|
+
2. If asked what to work on, check `dot-tasks list` (`todo`/`doing`) and propose the top few options with a short rationale.
|
|
160
|
+
3. Move selected work into active state with `dot-tasks start`.
|
|
161
|
+
4. Log meaningful progress with `dot-tasks update --note ...` as work evolves.
|
|
162
|
+
5. Close the loop with `dot-tasks complete` when acceptance criteria are met.
|
|
163
|
+
|
|
164
|
+
`dot-tasks init` can also set up integration pieces:
|
|
165
|
+
|
|
166
|
+
- It can append a canonical **“Task management with `dot-tasks`”** section to your project `AGENTS.md`.
|
|
167
|
+
- It can run:
|
|
168
|
+
`npx skills add Awni00/dot-tasks --skill dot-tasks`
|
|
169
|
+
to install the `dot-tasks` skill.
|
|
170
|
+
|
|
171
|
+
## Example Project
|
|
172
|
+
|
|
173
|
+
For a full demo of the workflow, see [`examples/basic-demo/`](examples/basic-demo/) and the walkthrough in [`examples/basic-demo/README.md`](examples/basic-demo/README.md).
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source srcset="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-dark.svg" media="(prefers-color-scheme: dark)">
|
|
4
|
+
<source srcset="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-light.svg" media="(prefers-color-scheme: light)">
|
|
5
|
+
<img src="https://raw.githubusercontent.com/Awni00/dot-tasks/main/assets/logo/svg/banner-light.svg" alt="dot-tasks logo">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
`dot-tasks` is a small CLI for managing project-level tasks in a local `.tasks/` directory, using human- and agent-readable files.
|
|
10
|
+
|
|
11
|
+
It started as a personal workflow tool: keep task specs in files, let agents work from those specs, and keep progress updates in the repo instead of chat history. It is shared here in case the same approach is useful to others.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://github.com/Awni00/dot-tasks/actions/workflows/tests.yml"><img src="https://github.com/Awni00/dot-tasks/actions/workflows/tests.yml/badge.svg" alt="Unit Tests"></a>
|
|
17
|
+
<a href="https://github.com/Awni00/dot-tasks/actions/workflows/publish.yml"><img src="https://github.com/Awni00/dot-tasks/actions/workflows/publish.yml/badge.svg" alt="Publish"></a>
|
|
18
|
+
<a href="https://pypi.org/project/dot-tasks/"><img src="https://img.shields.io/pypi/v/dot-tasks" alt="PyPI version"></a>
|
|
19
|
+
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License">
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
## High-level Workflow
|
|
23
|
+
|
|
24
|
+
This is the workflow I usually follow.
|
|
25
|
+
|
|
26
|
+
| Step | What happens | Command(s) | Files touched |
|
|
27
|
+
| --- | --- | --- | --- |
|
|
28
|
+
| Make note of new to-do | Write down the task spec. Often I have an agent draft a spec from a rough note. | `dot-tasks create` | Creates task dir `.tasks/todo/<created-date>-<task_name>/` with `task.md`, `activity.md`|
|
|
29
|
+
| Choose task to work on | Scan what is in `todo`/`doing` and pick the next task to start. | `dot-tasks list` | read-only inspection of `.tasks/` |
|
|
30
|
+
| Start active work | Move the task to active status when implementation begins. | `dot-tasks start` | Move task from `.tasks/todo/` to `.tasks/doing/`; `plan.md` created |
|
|
31
|
+
| Work loop | Log notable progress updates so humans and agents share context. | `dot-tasks update` | `task.md`, `activity.md` |
|
|
32
|
+
| Finish and archive state | Mark done when acceptance criteria are met, preserving full history in files. | `dot-tasks complete` | task directory moves to `.tasks/done/`|
|
|
33
|
+
|
|
34
|
+
## Contents
|
|
35
|
+
|
|
36
|
+
- [High-level Workflow](#high-level-workflow)
|
|
37
|
+
- [Installation](#installation)
|
|
38
|
+
- [Quick Start](#quick-start)
|
|
39
|
+
- [Task Layout](#task-layout)
|
|
40
|
+
- [Commands](#commands)
|
|
41
|
+
- [AI Agent Integration](#ai-agent-integration)
|
|
42
|
+
- [Example Project](#example-project)
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
### Install via pip (PyPI)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install dot-tasks
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Quick check:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
dot-tasks --help
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Install Latest from GitHub
|
|
59
|
+
|
|
60
|
+
Install the latest from GitHub:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install "git+https://github.com/Awni00/dot-tasks.git"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Development Install (with uv)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/Awni00/dot-tasks.git
|
|
70
|
+
cd dot-tasks
|
|
71
|
+
uv sync --dev
|
|
72
|
+
uv run dot-tasks --help
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Editable install:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
uv pip install -e ".[dev]"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Quick Start
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
dot-tasks init
|
|
85
|
+
dot-tasks create add-task-manager --summary "Build initial package"
|
|
86
|
+
dot-tasks start add-task-manager
|
|
87
|
+
dot-tasks update add-task-manager --note "Implemented storage layer"
|
|
88
|
+
dot-tasks complete add-task-manager
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Task Layout
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
.tasks/
|
|
95
|
+
todo/
|
|
96
|
+
doing/
|
|
97
|
+
done/
|
|
98
|
+
trash/
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Each task lives in `.tasks/<status-bucket>/<created-date>-<task_name>/` and contains:
|
|
102
|
+
|
|
103
|
+
- `task.md` (canonical metadata frontmatter + task body)
|
|
104
|
+
- `activity.md` (append-only audit log)
|
|
105
|
+
- `plan.md` (created when the task is started)
|
|
106
|
+
|
|
107
|
+
## Commands
|
|
108
|
+
|
|
109
|
+
| Command | Purpose | Typical usage |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| `init` | Create `.tasks/` and write/update managed config settings; can also append workflow guidance section AGENTS.md and install the skill via `npx skills`. | `dot-tasks init` |
|
|
112
|
+
| `create` | Add a new task to `todo/`. | `dot-tasks create <task_name>` |
|
|
113
|
+
| `start` | Move a task to `doing/` and create `plan.md`. | `dot-tasks start <task_name>` |
|
|
114
|
+
| `complete` | Move a task to `done/`. | `dot-tasks complete <task_name>` |
|
|
115
|
+
| `list` | List tasks by status (rich/plain/JSON depending on context). | `dot-tasks list [todo|doing|done] [--json]` |
|
|
116
|
+
| `view` | Show full details for one task. | `dot-tasks view <task_name> [--json]` |
|
|
117
|
+
| `update` | Update metadata, dependencies, tags, or add notes. | `dot-tasks update <task_name> ...` |
|
|
118
|
+
| `rename` | Rename a task. | `dot-tasks rename <task_name> <new_task_name>` |
|
|
119
|
+
| `delete` | Move a task to `trash/`, or delete permanently with `--hard`. | `dot-tasks delete <task_name> [--hard]` |
|
|
120
|
+
|
|
121
|
+
## AI Agent Integration
|
|
122
|
+
|
|
123
|
+
`dot-tasks` is designed so humans and agents can work from the same file-based task state in `.tasks/` instead of relying on chat context.
|
|
124
|
+
|
|
125
|
+
Typical agent workflow:
|
|
126
|
+
|
|
127
|
+
1. Capture or refine a task spec with `dot-tasks create`.
|
|
128
|
+
2. If asked what to work on, check `dot-tasks list` (`todo`/`doing`) and propose the top few options with a short rationale.
|
|
129
|
+
3. Move selected work into active state with `dot-tasks start`.
|
|
130
|
+
4. Log meaningful progress with `dot-tasks update --note ...` as work evolves.
|
|
131
|
+
5. Close the loop with `dot-tasks complete` when acceptance criteria are met.
|
|
132
|
+
|
|
133
|
+
`dot-tasks init` can also set up integration pieces:
|
|
134
|
+
|
|
135
|
+
- It can append a canonical **“Task management with `dot-tasks`”** section to your project `AGENTS.md`.
|
|
136
|
+
- It can run:
|
|
137
|
+
`npx skills add Awni00/dot-tasks --skill dot-tasks`
|
|
138
|
+
to install the `dot-tasks` skill.
|
|
139
|
+
|
|
140
|
+
## Example Project
|
|
141
|
+
|
|
142
|
+
For a full demo of the workflow, see [`examples/basic-demo/`](examples/basic-demo/) and the walkthrough in [`examples/basic-demo/README.md`](examples/basic-demo/README.md).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dot-tasks"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Human-readable and agent-readable task manager with a minimal CLI"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "dot-tasks contributors"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Software Development :: Build Tools",
|
|
23
|
+
"Topic :: Utilities",
|
|
24
|
+
]
|
|
25
|
+
keywords = ["tasks", "cli", "workflow", "productivity", "automation"]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"typer>=0.12",
|
|
28
|
+
"PyYAML>=6.0",
|
|
29
|
+
"InquirerPy>=0.3.4",
|
|
30
|
+
"rich>=13.7.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/Awni00/dot-tasks"
|
|
35
|
+
Repository = "https://github.com/Awni00/dot-tasks"
|
|
36
|
+
Issues = "https://github.com/Awni00/dot-tasks/issues"
|
|
37
|
+
|
|
38
|
+
[project.optional-dependencies]
|
|
39
|
+
dev = ["pytest>=8.0"]
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
dot-tasks = "dot_tasks.cli:main"
|
|
43
|
+
|
|
44
|
+
[tool.setuptools]
|
|
45
|
+
package-dir = {"" = "src"}
|
|
46
|
+
|
|
47
|
+
[tool.setuptools.packages.find]
|
|
48
|
+
where = ["src"]
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.package-data]
|
|
51
|
+
dot_tasks = ["resources/agents/*.md"]
|
|
52
|
+
|
|
53
|
+
[tool.setuptools.dynamic]
|
|
54
|
+
version = {attr = "dot_tasks._version.__version__"}
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Helpers for loading and upserting AGENTS.md snippets."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import resources
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
BEGIN_MARKER = "<!-- dot-tasks:begin task-management -->"
|
|
11
|
+
END_MARKER = "<!-- dot-tasks:end task-management -->"
|
|
12
|
+
RESOURCE_PATH = "resources/agents/task-management-dot-tasks.md"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _normalize_newlines(text: str) -> str:
|
|
16
|
+
return text.replace("\r\n", "\n")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _validate_markers(text: str) -> None:
|
|
20
|
+
begin = text.find(BEGIN_MARKER)
|
|
21
|
+
end = text.find(END_MARKER)
|
|
22
|
+
if begin == -1 or end == -1 or begin > end:
|
|
23
|
+
raise ValueError("Invalid task-management snippet: missing or misordered markers.")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def load_task_management_snippet() -> str:
|
|
27
|
+
"""Load canonical markdown section for AGENTS integration."""
|
|
28
|
+
content = resources.files("dot_tasks").joinpath(RESOURCE_PATH).read_text(encoding="utf-8")
|
|
29
|
+
normalized = _normalize_newlines(content).strip("\n")
|
|
30
|
+
_validate_markers(normalized)
|
|
31
|
+
return normalized + "\n"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def resolve_agents_file(project_root: Path, agents_file: Path | None) -> Path:
|
|
35
|
+
target = Path("AGENTS.md") if agents_file is None else agents_file
|
|
36
|
+
if target.is_absolute():
|
|
37
|
+
return target
|
|
38
|
+
return (project_root / target).resolve()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def upsert_task_management_snippet(
|
|
42
|
+
target_file: Path,
|
|
43
|
+
snippet_text: str,
|
|
44
|
+
) -> Literal["created", "updated", "appended", "unchanged"]:
|
|
45
|
+
"""Insert or replace canonical task-management snippet in target markdown file."""
|
|
46
|
+
block = _normalize_newlines(snippet_text).strip("\n")
|
|
47
|
+
_validate_markers(block)
|
|
48
|
+
block = block + "\n"
|
|
49
|
+
|
|
50
|
+
target_file.parent.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
if not target_file.exists():
|
|
52
|
+
target_file.write_text(block, encoding="utf-8")
|
|
53
|
+
return "created"
|
|
54
|
+
|
|
55
|
+
existing = _normalize_newlines(target_file.read_text(encoding="utf-8"))
|
|
56
|
+
begin = existing.find(BEGIN_MARKER)
|
|
57
|
+
end = existing.find(END_MARKER)
|
|
58
|
+
|
|
59
|
+
if begin != -1 and end != -1 and begin < end:
|
|
60
|
+
end_with_marker = end + len(END_MARKER)
|
|
61
|
+
replacement = existing[:begin] + block.rstrip("\n") + existing[end_with_marker:]
|
|
62
|
+
if not replacement.endswith("\n"):
|
|
63
|
+
replacement = replacement + "\n"
|
|
64
|
+
if replacement == existing:
|
|
65
|
+
return "unchanged"
|
|
66
|
+
target_file.write_text(replacement, encoding="utf-8")
|
|
67
|
+
return "updated"
|
|
68
|
+
|
|
69
|
+
if block.rstrip("\n") in existing:
|
|
70
|
+
return "unchanged"
|
|
71
|
+
|
|
72
|
+
separator = ""
|
|
73
|
+
if existing and not existing.endswith("\n"):
|
|
74
|
+
separator = "\n"
|
|
75
|
+
if existing.rstrip("\n"):
|
|
76
|
+
separator = separator + "\n"
|
|
77
|
+
|
|
78
|
+
appended = existing + separator + block
|
|
79
|
+
target_file.write_text(appended, encoding="utf-8")
|
|
80
|
+
return "appended"
|