Adds basic task management tools.
This commit is contained in:
@@ -1,130 +1,55 @@
|
|||||||
---
|
---
|
||||||
name: execute-tasks
|
name: execute-tasks
|
||||||
description: >-
|
description: "Execute and complete a specified list of project tasks sequentially. Use when asked to work on, implement, execute, or do a set of task IDs. Supports writing, research, planning, software, and other projects; verifies results, records human review steps, and transitions completed work to testing."
|
||||||
Execute and complete a specific list of tasks one by one. Use this skill
|
|
||||||
whenever the user asks to work on, implement, execute, or do a specific set
|
|
||||||
or batch of task IDs (e.g. "Do tasks OT-001, OT-002", "Work on these tasks
|
|
||||||
one at a time"). Validates task statuses, executes implementation
|
|
||||||
sequentially, updates documentation, transitions tasks to testing, records
|
|
||||||
follow-up tasks, includes tasks.md changes in git commits, logs verification
|
|
||||||
instructions in docs/task-verification.md, and checks project-description timestamps.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Execute Tasks Workflow Skill
|
# Execute Tasks
|
||||||
|
|
||||||
This skill defines the standardized procedure for executing a specific set of tasks sequentially with strict status validation, documentation updates, follow-up tracking, inclusion of `tasks.md` changes, per-task commits, and comprehensive verification instructions.
|
## Orient
|
||||||
|
|
||||||
---
|
1. Read [AGENTS.md](../../../AGENTS.md),
|
||||||
|
[project-config.json](../../../project-config.json), and
|
||||||
|
[the task tracker](../../../docs/tasks.md).
|
||||||
|
2. Load the `task-management` skill and query each requested task with
|
||||||
|
`./scripts/get-task <ID>`. Do not assume a prefix or software project.
|
||||||
|
3. Confirm tasks are ready for work. If not, explain the status and ask for
|
||||||
|
direction; do not silently bypass blocked or unscoped work.
|
||||||
|
4. Inspect existing materials and changes. Preserve unrelated work.
|
||||||
|
|
||||||
## 1. Task Status Validation & Confirmation
|
## Execute Sequentially
|
||||||
|
|
||||||
Before starting execution on any given task ID, inspect its status using `./scripts/get-task <ID>`:
|
For each task:
|
||||||
|
|
||||||
- **Valid Statuses to Work On**:
|
1. Transition it to `in_progress` using `update-task`.
|
||||||
- `ready` / `pending` (Ready for implementation)
|
2. Resolve material ambiguities with the user and agree on acceptance criteria.
|
||||||
- `in_progress` (Work currently active)
|
3. Complete the requested deliverable using the project's established methods.
|
||||||
|
For a novel this may be manuscript edits; for research it may be source
|
||||||
|
analysis; for software it may be code. Do not invent a language or platform.
|
||||||
|
4. Update directly related documentation and verify acceptance criteria.
|
||||||
|
Use configured commands only when applicable. For non-command workflows,
|
||||||
|
review deliverables and report what still needs human judgment.
|
||||||
|
5. When editing the bundled task tooling, run
|
||||||
|
`python3 -m unittest discover -s scripts/tests -v`.
|
||||||
|
6. Record step-by-step human verification in `docs/task-verification.md`,
|
||||||
|
creating it if needed. Include expected results and limitations.
|
||||||
|
7. Transition successful work to `testing` with `--check-all`, then query
|
||||||
|
the task again to verify the transition. Never mark your own work `done`.
|
||||||
|
8. Record newly discovered work with `add-task`; do not expand scope silently.
|
||||||
|
|
||||||
- **Invalid / Ambiguous Statuses**:
|
Stop and explain blockers when an acceptance criterion cannot be met. Do not
|
||||||
- `planning`: Scoping incomplete; requirements still unknown.
|
present unverified work as complete.
|
||||||
- `triage`: Requirements known, but prioritization or technical approach unconfirmed.
|
|
||||||
- `research`: Technical investigation required before planning.
|
|
||||||
- `testing`: Feature is already implemented and currently awaiting human verification.
|
|
||||||
- `done` / `fixed`: Task is already completed and verified.
|
|
||||||
- `cancelled`: Task was discarded or rejected.
|
|
||||||
- `blocked`: Task is waiting on external dependencies or decisions.
|
|
||||||
|
|
||||||
> [!WARNING]
|
## Persistence
|
||||||
> **Status Check Rule**: If any requested task is in an invalid status (such as `planning`, `triage`, `research`, `testing`, `done`, `cancelled`, or `blocked`), you **must stop, report the task ID and its current status to the user, explain why it is not ready for implementation, and ask for explicit confirmation** before proceeding with that task.
|
|
||||||
|
|
||||||
---
|
- Do not commit unless asked. If asked, inspect `git status` and include the
|
||||||
|
task/verification changes relevant to the deliverable. Do not stage unrelated
|
||||||
## 2. Step-by-Step Task Execution Loop
|
edits blindly.
|
||||||
|
- Use descriptive commit messages including task IDs and the required
|
||||||
Process each validated task **strictly one at a time** in the requested order:
|
co-author trailer where applicable.
|
||||||
|
- If project-description documents exist, check their last update and refresh
|
||||||
```mermaid
|
verification timestamps after major changes or 20 commits. Do not require
|
||||||
graph TD
|
nonexistent project-specific documents.
|
||||||
A[Inspect & Validate Task Status] --> B[Mark Task In Progress]
|
- Human reviewers move `testing` to `done` and migrate verification steps to
|
||||||
B --> C[Implement Code & Fixes]
|
`docs/human-tests.md`, creating it when first needed.
|
||||||
C --> D[Run Build & Verification Tests]
|
- If CLI tools cannot run, disclose that and agree on a manual workflow with
|
||||||
D --> E[Update Relevant Documentation]
|
the user rather than reporting fabricated checks.
|
||||||
E --> F[Check Off Requirements & Transition to Testing]
|
|
||||||
F --> G[Add Verification Steps to docs/task-verification.md]
|
|
||||||
G --> H[Check 20-Commit Rule on docs/project-description.md]
|
|
||||||
H --> I[Stage tasks.md & Create Git Commit per Task]
|
|
||||||
I --> J{More Tasks in Batch?}
|
|
||||||
J -- Yes --> A
|
|
||||||
J -- No --> K[Output Verification Summary to User]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step A: Mark In Progress
|
|
||||||
Transition the task to active work:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task <ID> --status in_progress
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step B: Implement Requirements
|
|
||||||
1. Read the task requirements using `./scripts/get-task <ID>`.
|
|
||||||
2. Inspect the relevant source files and implement the requested changes adhering to project architecture and best practices.
|
|
||||||
3. If partial implementation is required or edge cases emerge, record notes directly in the task description.
|
|
||||||
|
|
||||||
### Step C: Verify & Test
|
|
||||||
Run build verification and automated tests to ensure no regressions:
|
|
||||||
```bash
|
|
||||||
npm test -w @oldbear/client
|
|
||||||
npm test -w @oldbear/shared
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step D: Update Documentation
|
|
||||||
Check if the changes affect:
|
|
||||||
- [README.md](file:///Users/tom/Projects/OldBearBattles/README.md)
|
|
||||||
- `docs/` specifications or architecture guides
|
|
||||||
Update the corresponding documentation files accordingly.
|
|
||||||
|
|
||||||
### Step E: Transition Task to Testing (Not Done)
|
|
||||||
Check off completed checklist items and transition status to `testing`:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task <ID> --status testing --check-all
|
|
||||||
```
|
|
||||||
If specific items need implementation notes:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task <ID> --status testing --append-description "### Implementation Notes:\n- Completed core logic."
|
|
||||||
```
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> **Testing vs Done**: The agent sets the status to `testing`. The user will manually test the feature and create their own commit transitioning the status to `done` once verified.
|
|
||||||
|
|
||||||
### Step F: Record Newly Discovered Tasks
|
|
||||||
If during the work any new bugs, edge cases, refactor opportunities, or follow-ups are discovered, log them immediately in `planning` status:
|
|
||||||
```bash
|
|
||||||
./scripts/add-task "Follow-up: <Descriptive Title>" --project=<proj> --type=<type> --status=planning -d "Discovered during work on <ID>:\n- [ ] Detail"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step G: Update `docs/task-verification.md`
|
|
||||||
Add clear, step-by-step verification instructions for the completed task into [docs/task-verification.md](file:///Users/tom/Projects/OldBearBattles/docs/task-verification.md) under the appropriate section:
|
|
||||||
- Include task ID, title, where to find it in the UI, exact steps to execute, and pass/fail criteria.
|
|
||||||
- *(Note: Once a human tester verifies a feature and marks it `done`, the verification steps are migrated from `docs/task-verification.md` into `docs/human-tests.md` as permanent regression tests).*
|
|
||||||
|
|
||||||
### Step H: Check 20-Commit Rule on Project Description
|
|
||||||
Check the number of commits since `docs/project-description.md` was last modified:
|
|
||||||
```bash
|
|
||||||
LAST_COMMIT=$(git log -n 1 --pretty=format:"%H" -- docs/project-description.md)
|
|
||||||
git rev-list --count ${LAST_COMMIT}..HEAD
|
|
||||||
```
|
|
||||||
If the count is $\ge 20$ (or if major features/technologies were added):
|
|
||||||
1. Update `docs/project-description.md` with current UTC timestamp (`- Last Verified UTC: YYYY-MM-DDTHH:MM:SSZ`) and any major feature changes.
|
|
||||||
2. Update `docs/project-description.json` with `"lastVerifiedUtc": "YYYY-MM-DDTHH:MM:SSZ"`.
|
|
||||||
3. Include these files in the commit (resetting the 20-commit counter).
|
|
||||||
|
|
||||||
### Step I: Include tasks.md & Create Git Commit
|
|
||||||
When creating the commit for the task:
|
|
||||||
1. **Always include `docs/tasks.md` and `docs/task-verification.md`**: Check `git status`. Ensure all changes to `docs/tasks.md` (including user edits or pre-staged edits) and `docs/task-verification.md` are staged:
|
|
||||||
```bash
|
|
||||||
git add docs/tasks.md docs/task-verification.md <other-modified-files>
|
|
||||||
git commit -m "<type>(<project>): <concise summary of task ID>"
|
|
||||||
```
|
|
||||||
*(At least one commit must be made per completed task before moving to the next task).*
|
|
||||||
|
|
||||||
### Step J: Verification Instructions in Response
|
|
||||||
Always provide clear verification instructions so the user can easily test the work:
|
|
||||||
1. **Single Task / Small Batch**: Include clear, actionable step-by-step verification instructions directly in your response to the user.
|
|
||||||
2. **Batch / Many Tasks**: If executing a batch of multiple tasks, create a dedicated verification report in `docs/` (e.g. `docs/verification-report.md`) detailing the changes, commits, and verification steps for each task, and link to it in your final response.
|
|
||||||
|
|||||||
93
.agents/skills/initial-setup/SKILL.md
Normal file
93
.agents/skills/initial-setup/SKILL.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
name: initial-setup
|
||||||
|
description: "Set up or customize a freshly cloned generic project template. Use when asked for initial setup, getting started, onboarding, creating project configuration, or replacing sample project values. Interview the user and configure task tracking for any project, including novels, research, events, and software, without assuming a language or platform."
|
||||||
|
---
|
||||||
|
|
||||||
|
# Initial Project Setup
|
||||||
|
|
||||||
|
Configure this clone for its actual project, not for the project that originally
|
||||||
|
supplied the template. This workflow is equally valid for a novel, research,
|
||||||
|
an event, or software.
|
||||||
|
|
||||||
|
## Inspect First
|
||||||
|
|
||||||
|
Read [the README](../../../README.md),
|
||||||
|
[project-config.json](../../../project-config.json),
|
||||||
|
[AGENTS.md](../../../AGENTS.md), and
|
||||||
|
[task frontmatter and details](../../../docs/tasks.md). Check Git status.
|
||||||
|
Preserve existing materials and uncommitted changes.
|
||||||
|
|
||||||
|
## Interview
|
||||||
|
|
||||||
|
Use the available user-question tool, one question at a time. Reuse answers
|
||||||
|
already given; do not ask again unnecessarily. Collect:
|
||||||
|
|
||||||
|
1. Project name.
|
||||||
|
2. A short description of its purpose, audience, and intended outcome.
|
||||||
|
3. Task ID prefix (recommend `EX` for an example; otherwise let the user choose).
|
||||||
|
Validate `[A-Za-z][A-Za-z0-9_-]*`; display IDs will be uppercase.
|
||||||
|
4. Whether there is one project category or several. Collect each label,
|
||||||
|
unique stable key, and repository-relative path (`.` for a single project).
|
||||||
|
5. How completed work should be verified. Ask about named commands only if
|
||||||
|
relevant. Do not assume tests, builds, a development server, a programming
|
||||||
|
language, or a target platform. Editorial review is a valid answer.
|
||||||
|
6. Whether to keep and adapt the sample task. Preserve real tasks unless the
|
||||||
|
user explicitly approves replacing them. Collect any desired task-type
|
||||||
|
changes; generic `task` and `chore` are sufficient for many projects.
|
||||||
|
|
||||||
|
Present a concise configuration summary and obtain confirmation before
|
||||||
|
replacing existing configuration or task content.
|
||||||
|
|
||||||
|
## Write the Configuration
|
||||||
|
|
||||||
|
Update `project-config.json` as valid JSON:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Example Project",
|
||||||
|
"description": "Describe the project's purpose and intended outcome.",
|
||||||
|
"commands": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`name` and `description` must be non-empty strings. `commands` maps arbitrary
|
||||||
|
non-empty names to non-empty command strings. Leave it empty when no commands
|
||||||
|
are applicable. Record non-command acceptance/review criteria in AGENTS.md or
|
||||||
|
the task descriptions. Never store secrets or machine-specific absolute paths.
|
||||||
|
Commands are prompt guidance, not automatically run by the task-agent helpers.
|
||||||
|
|
||||||
|
Update task frontmatter with the agreed prefix and project categories.
|
||||||
|
Keep YAML in the flat format understood by the task parser: unindented scalar
|
||||||
|
fields, two-space list items, and four-space item fields. Do not introduce YAML
|
||||||
|
anchors, nested mappings, or multiline scalar values. Keep the existing
|
||||||
|
status lifecycle unless the user explicitly requests changes.
|
||||||
|
|
||||||
|
If renaming a project key, migrate matching task anchor `data-project`
|
||||||
|
attributes. Preserve task numbers, descriptions, checklists, epic/subproject
|
||||||
|
assignments, and existing internal links. Do not duplicate task configuration
|
||||||
|
in JSON. Update the README's project description and examples to match, keeping
|
||||||
|
Getting Started at the top. Update AGENTS.md only with confirmed project facts
|
||||||
|
and verification criteria; never invent an application architecture.
|
||||||
|
|
||||||
|
## Synchronize and Verify
|
||||||
|
|
||||||
|
If the optional CLI runtime is available:
|
||||||
|
|
||||||
|
1. Check whether `TASK_ID_PREFIX` or `TASKS_FILE` overrides the intended
|
||||||
|
configuration; explain conflicts rather than silently changing the result.
|
||||||
|
2. Run `./scripts/update-tasks -f docs/tasks.md`. This migrates IDs/internal
|
||||||
|
links and regenerates tables. Do not manually edit generated tables.
|
||||||
|
3. Run `./scripts/get-tasks --all -f docs/tasks.md` and query a task by number.
|
||||||
|
4. Run `python3 -m json.tool project-config.json` and
|
||||||
|
`python3 -m unittest discover -s scripts/tests -v`.
|
||||||
|
5. Verify the configured name, description, commands, project labels, and task
|
||||||
|
prefix persisted. Check for stale template identities and broken links.
|
||||||
|
6. Summarize changed files, verification results, and any remaining human review.
|
||||||
|
|
||||||
|
The tracker synchronizer currently requires at least one detailed task. Do
|
||||||
|
not remove the last task and claim synchronization succeeded; keep/adapt it or
|
||||||
|
ask how to handle an explicitly requested empty tracker.
|
||||||
|
|
||||||
|
If the runtime is unavailable, disclose that and offer either tool installation
|
||||||
|
or a manual Markdown workflow. Do not run application commands merely because
|
||||||
|
setup recorded them. Do not commit unless the user asks.
|
||||||
@@ -1,155 +1,67 @@
|
|||||||
---
|
---
|
||||||
name: task-management
|
name: task-management
|
||||||
description: >-
|
description: "Manage, query, create, triage, research, and update project tasks using scripts/ and docs/tasks.md. Use when reading, creating, editing, prioritizing, or updating tasks, checklists, or project progress for any kind of project."
|
||||||
Manage, query, create, triage, research, and update project tasks using the
|
|
||||||
repository's task CLI scripts in scripts/ (get-tasks, get-task, add-task,
|
|
||||||
update-task, update-tasks, triage, research) and docs/tasks.md. Activate this
|
|
||||||
skill whenever reading, creating, editing, prioritizing, or updating tasks,
|
|
||||||
checklists, or project progress.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Task Management Skill
|
# Task Management
|
||||||
|
|
||||||
This skill provides operational guidelines and procedures for managing project tasks using the automation scripts in `scripts/` and the Single Source of Truth (SSOT) document `docs/tasks.md`.
|
Read [the script guide](../../../scripts/README.md) and
|
||||||
|
[the tracker](../../../docs/tasks.md). Use its configured prefix, project keys,
|
||||||
|
statuses, and types, not an assumed project or software stack.
|
||||||
|
Examples below use task numbers so they work with any prefix.
|
||||||
|
|
||||||
---
|
## Environment
|
||||||
|
|
||||||
## Quick Reference & Environment Setup
|
The optional CLI tools require Python 3.9+ and Bash or Zsh:
|
||||||
|
|
||||||
To make scripts available on your `PATH` and load shell aliases:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
source ./scripts/env.sh
|
source ./scripts/env.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**: For local configurations that should not be committed (such as custom environment variables, agent endpoints, or tokens), create a `scripts/env.local.sh` or `.env.local` file. It will be automatically sourced by `env.sh` and is ignored by Git.
|
Keep local overrides in ignored `scripts/env.sh.local` or `.env`. These are
|
||||||
|
trusted shell scripts. `TASKS_FILE` chooses the tracker; `TASK_ID_PREFIX`
|
||||||
|
overrides its prefix. All task commands accept `-f /path/to/tasks.md`.
|
||||||
|
|
||||||
---
|
## Querying
|
||||||
|
|
||||||
## Core Procedures
|
|
||||||
|
|
||||||
### 1. Querying and Inspecting Tasks
|
|
||||||
|
|
||||||
- **List active pending tasks**:
|
|
||||||
```bash
|
|
||||||
./scripts/get-tasks
|
|
||||||
```
|
|
||||||
- **List tasks in Planning and Triage**:
|
|
||||||
```bash
|
|
||||||
./scripts/get-tasks --planning
|
|
||||||
# or alias: get-planning-tasks
|
|
||||||
```
|
|
||||||
- **List all tasks**:
|
|
||||||
```bash
|
|
||||||
./scripts/get-tasks --all
|
|
||||||
```
|
|
||||||
- **Filter tasks**:
|
|
||||||
```bash
|
|
||||||
./scripts/get-tasks --accept "Status:In Progress"
|
|
||||||
./scripts/get-tasks --reject "Project:Android"
|
|
||||||
./scripts/get-tasks --sort asc
|
|
||||||
```
|
|
||||||
- **Inspect a specific task**:
|
|
||||||
```bash
|
|
||||||
./scripts/get-task OT-001
|
|
||||||
# Output as JSON:
|
|
||||||
./scripts/get-task OT-001 --json
|
|
||||||
# View description and checklist only:
|
|
||||||
./scripts/get-task OT-001 --description-only
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Creating New Tasks
|
|
||||||
|
|
||||||
Use `add-task` to add a new entry to `docs/tasks.md`. The script automatically assigns the next monotonic ID and re-synchronizes the summary table:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/add-task "Task Title" --project=<project-key> --type=<type> --status=<status> -d "Description text"
|
./scripts/get-tasks
|
||||||
|
./scripts/get-tasks --all
|
||||||
|
./scripts/get-tasks --planning
|
||||||
|
./scripts/get-tasks --accept "Status:Ready"
|
||||||
|
./scripts/get-task 1
|
||||||
|
./scripts/get-task 1 --json
|
||||||
|
./scripts/get-task 1 --description-only
|
||||||
```
|
```
|
||||||
|
|
||||||
**Common Flags**:
|
## Creating and Updating
|
||||||
- `-p`, `--project`: Project value from frontmatter (e.g., `example-project`, `android`, `ios`, `shared`).
|
|
||||||
- `-t`, `--type`: Task type (`feature`, `bug`, `chore`, `lint`). Default: `feature`.
|
|
||||||
- `-s`, `--status`: Initial status (`planning`, `triage`, `pending`, `in_progress`, `done`, `blocked`, `cancelled`, `research`). Default: `triage`.
|
|
||||||
- `-d`, `--description`: Initial description and markdown checklist items.
|
|
||||||
- `--subproject`: Subproject name if applicable.
|
|
||||||
|
|
||||||
---
|
Read valid project/type/status values from frontmatter before invoking:
|
||||||
|
|
||||||
### 3. Updating Tasks
|
|
||||||
|
|
||||||
Modify task attributes, title, status, and checklist items using `update-task`:
|
|
||||||
|
|
||||||
- **Change status**:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task OT-001 --status in_progress
|
|
||||||
./scripts/update-task OT-001 --status done
|
|
||||||
```
|
|
||||||
- **Update title or description**:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task OT-001 --title "Updated Descriptive Title"
|
|
||||||
./scripts/update-task OT-001 --description "New full description text"
|
|
||||||
```
|
|
||||||
- **Append checklist items or notes**:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task OT-001 --append-description "- [ ] New requirement step"
|
|
||||||
```
|
|
||||||
- **Check/uncheck checklist items**:
|
|
||||||
```bash
|
|
||||||
# Check all items:
|
|
||||||
./scripts/update-task OT-001 --check-all
|
|
||||||
# Check specific item by keyword:
|
|
||||||
./scripts/update-task OT-001 --check-items "Define initial requirements"
|
|
||||||
# Uncheck all items:
|
|
||||||
./scripts/update-task OT-001 --uncheck-all
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Synchronizing the Document
|
|
||||||
|
|
||||||
If tasks are modified or if table alignment needs re-calculation, run `update-tasks`:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/update-tasks
|
./scripts/add-task "Task Title" --project example-project --type task --status triage -d "Description and review criteria"
|
||||||
|
./scripts/update-task 1 --status in_progress
|
||||||
|
./scripts/update-task 1 --title "Updated Title"
|
||||||
|
./scripts/update-task 1 --append-description "- [ ] Additional criterion"
|
||||||
|
./scripts/update-task 1 --check-all
|
||||||
|
./scripts/update-task 1 --status testing
|
||||||
```
|
```
|
||||||
|
|
||||||
This script:
|
Use `--epic` or `--subproject` only with values defined in frontmatter.
|
||||||
1. Re-indexes and sorts all detailed task chunks strictly by numeric ID.
|
Numbers and configured prefixed IDs are accepted.
|
||||||
2. Re-renders the **Overall Progress Table** (`#tasks-list`).
|
|
||||||
3. Re-renders the metadata enum tables (**Projects**, **Task Statuses**, **Task Types**) based on frontmatter.
|
|
||||||
|
|
||||||
---
|
## Synchronization and Review
|
||||||
|
|
||||||
### 5. Running Triage & Research Workflows
|
- Anchor attributes in Detailed Tasks are the canonical task metadata.
|
||||||
|
- Do not manually edit generated summary/enum tables. Run
|
||||||
- **Triage a task**:
|
`./scripts/update-tasks` to regenerate them.
|
||||||
```bash
|
- Run `./scripts/get-task <number>` after edits to verify persisted values.
|
||||||
./scripts/triage OT-001
|
- `planning` / `triage` / `research` scope work; `ready` permits execution;
|
||||||
./scripts/triage OT-001 --agy
|
`in_progress` tracks active work; `testing` awaits human verification.
|
||||||
```
|
- `testing` applies to any project, including writing and research. It need
|
||||||
- **Research a task**:
|
not involve automated tests. Humans confirm `done`.
|
||||||
```bash
|
- Optional `triage` / `research` helpers require a supported external agent CLI;
|
||||||
./scripts/research OT-001
|
normal task management does not.
|
||||||
./scripts/research OT-001 --agy
|
- If the CLI runtime is unavailable, explain that limitation. With user
|
||||||
```
|
agreement, maintain canonical task details in Markdown and ensure tables
|
||||||
|
remain consistent; do not silently claim script verification succeeded.
|
||||||
---
|
|
||||||
|
|
||||||
## Operational Rules & Best Practices
|
|
||||||
|
|
||||||
1. **Single Source of Truth (SSOT)**:
|
|
||||||
- The `<a id="ot-XXX" class="task" data-project="..." data-status="..." data-task-type="..."></a>` anchor tag in `## Detailed Tasks` is the canonical record.
|
|
||||||
- **Never manually edit the summary table** in `docs/tasks.md`. Always modify task entries using `update-task` or run `update-tasks` after editing details.
|
|
||||||
2. **Lifecycle Discipline**:
|
|
||||||
- `planning`: Scoping and defining requirements.
|
|
||||||
- `triage`: Prioritizing and deciding architecture.
|
|
||||||
- `pending`: Clear scope, ready for execution.
|
|
||||||
- `in_progress`: Work actively being executed.
|
|
||||||
- `done`: All requirements verified and complete.
|
|
||||||
- `blocked`: Waiting on an unresolved external dependency.
|
|
||||||
- `cancelled`: No longer applicable.
|
|
||||||
- `research`: Technical investigation needed before planning.
|
|
||||||
3. **Verification**:
|
|
||||||
- Always run `./scripts/get-tasks` or `./scripts/get-task <ID>` after updating to verify that status transitions and checklist updates have persisted accurately.
|
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1 +1,7 @@
|
|||||||
.worktrees
|
.worktrees
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
scripts/env.sh.local
|
||||||
|
scripts/env.local.sh
|
||||||
|
|||||||
161
AGENTS.md
161
AGENTS.md
@@ -1,121 +1,60 @@
|
|||||||
# AGENTS.md — Old Bear Battles Operational & Architecture Guide
|
# Repository Guide
|
||||||
|
|
||||||
Welcome to **Old Bear Battles** (`OldBearBattles`). This document serves as the primary operational orientation, architectural reference, and workflow guide for all AI agents working in this repository.
|
This is a generic project starter, not an application scaffold. A project can
|
||||||
|
be a novel, research, an event, software, or anything else.
|
||||||
|
Read [project-config.json](./project-config.json) for the project name,
|
||||||
|
description, and any optional commands. Do not assume software, a language,
|
||||||
|
platform, framework, package manager, architecture, or deployment target.
|
||||||
|
|
||||||
---
|
## Structure
|
||||||
|
|
||||||
## 1. Project Overview & Core Tenets
|
- [README.md](./README.md): getting started and configuration instructions.
|
||||||
|
- [project-config.json](./project-config.json): project identity and commands.
|
||||||
|
- [docs/tasks.md](./docs/tasks.md): canonical task metadata and backlog.
|
||||||
|
- [scripts/](./scripts/): Python and shell task-management tools.
|
||||||
|
- [.agents/skills/](./.agents/skills/): shared setup and task workflows.
|
||||||
|
|
||||||
OldBearBattles is a lightweight, mobile-friendly, zero-install Virtual Tabletop (VTT) and tactical tabletop wargaming platform (`Brawl`).
|
## Initial Setup
|
||||||
|
|
||||||
### Core Design Tenets
|
Use the `initial-setup` skill when cloning this template or reconfiguring a
|
||||||
1. **Local-First & Zero-Mandatory Auth**: All player and scene data (maps, tokens, audio, character sheets) is stored in local browser storage (`IndexedDB` / `localStorage`). Users can join a room by URL without account friction.
|
project. Ask the user for the project name, description, task prefix, project
|
||||||
2. **Hybrid P2P & Relay Networking**: Fast WebRTC mesh audio and room synchronization over WebSocket signaling, with graceful server relay fallback.
|
categories, and how they want to verify work. Ask about commands only when
|
||||||
3. **High-Performance 2D Canvas**: Custom 60 FPS HTML5 Canvas engine designed for seamless trackpad gestures (two-finger pan, pinch-to-zoom) and touch usability without heavy external canvas frameworks.
|
relevant; a writing project might use editorial review instead. Preserve existing work.
|
||||||
4. **System-Agnostic Entity Architecture**: Attacks, spells, items, and abilities share a unified `EntityAction` and `EntityStatBlock` schema, enabling flexible play across D&D 5e, Pathfinder 2e, and homebrew systems.
|
Keep task prefixes and project categories in task frontmatter, not duplicated
|
||||||
5. **Dual Game Modes (`VTT` & `Brawl`)**:
|
in the JSON configuration.
|
||||||
- `vtt`: Traditional TTRPG mode (initiative tracker, D&D/PF2e character sheets, spellbooks, fog of war).
|
|
||||||
- `brawl`: Tabletop wargaming mode (armies, units, coherency graph halos, chess clocks, round phase stepper, victory point scoreboard).
|
|
||||||
- Configured via `GAME_MODE` environment variable (`vtt`, `brawl`, or multi-mode `vtt,brawl` with in-app toggle).
|
|
||||||
|
|
||||||
---
|
## Working and Validation
|
||||||
|
|
||||||
## 2. Monorepo Structure
|
- Verify work using the project's agreed criteria, whether editorial review,
|
||||||
|
checklists, research validation, or automated tests.
|
||||||
|
- Run commands only when configured and appropriate. Empty `commands` means
|
||||||
|
none are configured; do not invent a test, build, or development command.
|
||||||
|
- Using the bundled CLI tools requires Python 3.9+ and Bash or Zsh. Their tests
|
||||||
|
use only the Python standard library. A project using this template need
|
||||||
|
not use those tools or any programming language.
|
||||||
|
- When changing the bundled tooling, run
|
||||||
|
`python3 -m unittest discover -s scripts/tests -v`.
|
||||||
|
- Follow existing patterns and avoid unrelated changes.
|
||||||
|
- Use relative links in repository documentation.
|
||||||
|
- Never commit credentials or local environment overrides.
|
||||||
|
|
||||||
```
|
## Task Workflow
|
||||||
OldBearBattles/
|
|
||||||
├── packages/
|
|
||||||
│ ├── client/ # React 18 + Vite frontend
|
|
||||||
│ │ └── src/
|
|
||||||
│ │ ├── common/ # Shared canvas engine, networking, dice, status, widgets
|
|
||||||
│ │ ├── vtt/ # TTRPG VTT application (AppVtt, character sheets, tokens)
|
|
||||||
│ │ └── brawl/ # Tabletop wargaming platform (AppBrawl, armies, coherency)
|
|
||||||
│ ├── server/ # Node.js + WebSocket signaling & relay server
|
|
||||||
│ └── shared/ # Shared TypeScript schemas, protocol payloads, entity types
|
|
||||||
├── docs/ # Specifications, architecture guides, task tracking
|
|
||||||
├── scripts/ # Python CLI tools for task management (get-tasks, update-task, etc.)
|
|
||||||
└── .agents/ # Agent skills (execute-tasks, task-management)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
Use the `task-management` skill for task queries and edits, and `execute-tasks`
|
||||||
|
for implementation of specified task IDs.
|
||||||
|
|
||||||
## 3. Mandatory Development & Testing Commands
|
- Use the task CLI scripts; do not manually edit generated summary/enum tables.
|
||||||
|
- Read the configured prefix and statuses from task frontmatter. Numbers alone
|
||||||
Before committing any code or declaring a task ready for testing:
|
can be used when invoking task commands.
|
||||||
|
- Lifecycle: `planning` / `triage` / `research` -> `ready` -> `in_progress` ->
|
||||||
- **Run Client Tests**:
|
`testing` -> `done`. Here `testing` means awaiting human verification, not
|
||||||
```bash
|
necessarily software testing. Humans, not working agents, confirm `done`.
|
||||||
npm test -w @oldbear/client
|
- Record human verification steps in `docs/task-verification.md` when a task
|
||||||
```
|
moves to `testing`; create that document when first needed.
|
||||||
- **Run Shared Tests**:
|
- When human verification succeeds, migrate those steps to
|
||||||
```bash
|
`docs/human-tests.md`, creating it when needed.
|
||||||
npm test -w @oldbear/shared
|
- Commit only when requested. Include relevant task and verification changes,
|
||||||
```
|
but do not stage unrelated edits or commit another person's work blindly.
|
||||||
- **Start Local Dev Server**:
|
- If the project maintains project-description documents, refresh their
|
||||||
```bash
|
verification timestamps after major changes or 20 commits since their last
|
||||||
npm run dev
|
update. Do not assume those optional documents already exist.
|
||||||
```
|
|
||||||
- **Build Production Bundle** (only when validating build cleanliness):
|
|
||||||
```bash
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Task Management & Execution Workflow
|
|
||||||
|
|
||||||
All project tasks are tracked directly in [docs/tasks.md](file:///Users/tom/Projects/OldBearBattles/docs/tasks.md). Always use the `execute-tasks` or `task-management` skills and CLI scripts.
|
|
||||||
|
|
||||||
### Task Status Lifecycles
|
|
||||||
- `triage` / `planning`: Under research or requirements definition.
|
|
||||||
- `ready`: Ready for implementation.
|
|
||||||
- `in_progress`: Actively being worked on by an agent or developer.
|
|
||||||
- `testing`: Feature implementation is complete and currently awaiting human verification.
|
|
||||||
- `done`: Human tester has verified the feature and committed the completion.
|
|
||||||
- `blocked` / `cancelled`: Paused or abandoned.
|
|
||||||
|
|
||||||
### Rules for Agent Task Execution
|
|
||||||
1. **Transition to `testing` (Not `done`)**:
|
|
||||||
When an agent finishes implementing a task and all tests pass:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task <ID> --status testing --check-all
|
|
||||||
```
|
|
||||||
Do **NOT** transition tasks directly to `done`. The human user verifies the feature and commits the transition to `done`.
|
|
||||||
2. **Log Verification in [docs/task-verification.md](file:///Users/tom/Projects/OldBearBattles/docs/task-verification.md)**:
|
|
||||||
Add step-by-step instructions to `docs/task-verification.md` for testing the feature.
|
|
||||||
3. **Permanent Human Regression Tests in [docs/human-tests.md](file:///Users/tom/Projects/OldBearBattles/docs/human-tests.md)**:
|
|
||||||
When a feature is verified and moved from `testing` to `done`, its verification steps are migrated from `docs/task-verification.md` to `docs/human-tests.md` as an ongoing regression test suite.
|
|
||||||
4. **Always Stage `docs/tasks.md` and `docs/task-verification.md`**:
|
|
||||||
Before committing, always check `git status`. Ensure that any changes to `docs/tasks.md` (including user edits or pre-staged items) and `docs/task-verification.md` are included:
|
|
||||||
```bash
|
|
||||||
git add docs/tasks.md docs/task-verification.md <modified-files>
|
|
||||||
git commit -m "<type>(<project>): <summary> (<ID>)"
|
|
||||||
```
|
|
||||||
5. **The 20-Commit Project Description Rule**:
|
|
||||||
`docs/project-description.md` and `docs/project-description.json` are consumed by external repositories and catalog scanners.
|
|
||||||
- Count commits since `docs/project-description.md` was last modified:
|
|
||||||
```bash
|
|
||||||
LAST_COMMIT=$(git log -n 1 --pretty=format:"%H" -- docs/project-description.md)
|
|
||||||
git rev-list --count ${LAST_COMMIT}..HEAD
|
|
||||||
```
|
|
||||||
- If $\ge 20$ commits have elapsed (or if major features/technologies were added), update the `- Last Verified UTC: YYYY-MM-DDTHH:MM:SSZ` timestamp in `docs/project-description.md` and `"lastVerifiedUtc"` in `docs/project-description.json`, stage them, and commit. This resets the 20-commit counter.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Documentation Sitemap & Index
|
|
||||||
|
|
||||||
When working in specific functional areas, refer to these authoritative domain documents:
|
|
||||||
|
|
||||||
| Topic / Domain | Authoritative Documentation |
|
|
||||||
| :--- | :--- |
|
|
||||||
| **All Implemented VTT Features** | [Features.md](file:///Users/tom/Projects/OldBearBattles/Features.md) |
|
|
||||||
| **Wargaming Platform (Brawl)** | [docs/brawl-project-plan.md](file:///Users/tom/Projects/OldBearBattles/docs/brawl-project-plan.md) |
|
|
||||||
| **System-Agnostic Entity & Imports** | [docs/system-agnostic-import.md](file:///Users/tom/Projects/OldBearBattles/docs/system-agnostic-import.md) |
|
|
||||||
| **Active Task Backlog** | [docs/tasks.md](file:///Users/tom/Projects/OldBearBattles/docs/tasks.md) |
|
|
||||||
| **Features Awaiting Verification** | [docs/task-verification.md](file:///Users/tom/Projects/OldBearBattles/docs/task-verification.md) |
|
|
||||||
| **Human Regression Testing Suites** | [docs/human-tests.md](file:///Users/tom/Projects/OldBearBattles/docs/human-tests.md) |
|
|
||||||
| **HelpTip Component & Copy Guide** | [docs/helptip-locations.md](file:///Users/tom/Projects/OldBearBattles/docs/helptip-locations.md) |
|
|
||||||
| **Codebase Refactoring Plan** | [docs/refactor-1.md](file:///Users/tom/Projects/OldBearBattles/docs/refactor-1.md) |
|
|
||||||
| **Backlog Research & Architecture** | [docs/backlog-implementation-guide.md](file:///Users/tom/Projects/OldBearBattles/docs/backlog-implementation-guide.md) |
|
|
||||||
| **Task CLI Tooling Guide** | [scripts/README.md](file:///Users/tom/Projects/OldBearBattles/scripts/README.md) |
|
|
||||||
| **Historical Vision & Kickstarter Plans** | [docs/archive/idea.md](file:///Users/tom/Projects/OldBearBattles/docs/archive/idea.md), [docs/archive/initial-project-plan.md](file:///Users/tom/Projects/OldBearBattles/docs/archive/initial-project-plan.md) |
|
|
||||||
|
|||||||
88
README.md
88
README.md
@@ -0,0 +1,88 @@
|
|||||||
|
# Getting Started
|
||||||
|
|
||||||
|
1. Clone this repository and enter the clone directory.
|
||||||
|
2. No project language or platform is prescribed. To use the optional bundled
|
||||||
|
task CLI tools, install **Python 3.9+** and use **Bash or Zsh**. The Markdown
|
||||||
|
tracker and agent skills can also be used without those tools.
|
||||||
|
3. In your coding assistant, request **"Run initial setup for this repository"**
|
||||||
|
or invoke `/initial-setup`. The shared skill asks for your project details
|
||||||
|
and creates your configuration without assuming software or an application
|
||||||
|
stack. A novel, research project, or event plan is equally valid.
|
||||||
|
4. If using the CLI tools, validate the tooling and inspect the sample task:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m unittest discover -s scripts/tests -v
|
||||||
|
./scripts/get-task EX-001
|
||||||
|
./scripts/get-tasks --all
|
||||||
|
```
|
||||||
|
|
||||||
|
After choosing a different prefix, use your new ID or simply
|
||||||
|
`./scripts/get-task 1`.
|
||||||
|
|
||||||
|
5. Optionally load task commands and aliases into your shell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ./scripts/env.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example Project
|
||||||
|
|
||||||
|
A generic project starter with task tracking and reusable agent workflows.
|
||||||
|
It includes one sample task, not an application or deployment stack. The
|
||||||
|
project's subject, language, platform, and way of verifying work are unspecified.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
[project-config.json](./project-config.json) is the shared configuration for
|
||||||
|
the project name, description, and optional named commands. The `triage` and
|
||||||
|
`research` helpers read it when building agent prompts. Commands are guidance,
|
||||||
|
not automatically executed by those helpers. The sample's `commands` is empty.
|
||||||
|
Add commands only if relevant, for example a manuscript word-count command or
|
||||||
|
a software test command. Human review needs no command.
|
||||||
|
|
||||||
|
[docs/tasks.md](./docs/tasks.md) owns task configuration:
|
||||||
|
|
||||||
|
- `task-id-prefix`: `EX` in this example.
|
||||||
|
- `projects`: labels, keys, and repository-relative paths. The sample key is
|
||||||
|
`example-project`.
|
||||||
|
- `task-statuses`, `task-types`, and optional `epics` / `subprojects`.
|
||||||
|
|
||||||
|
For manual setup, edit the JSON configuration and task frontmatter, then run
|
||||||
|
`./scripts/update-tasks`. It regenerates tables and migrates task IDs and
|
||||||
|
internal links when the prefix changes. Preserve numeric IDs and existing
|
||||||
|
tasks. If changing project keys, also update their task anchor `data-project`
|
||||||
|
attributes before synchronizing.
|
||||||
|
|
||||||
|
`TASK_ID_PREFIX` overrides frontmatter; without either, scripts default to
|
||||||
|
`EX`. `TASKS_FILE` or `-f /path/to/tasks.md` selects another tracker.
|
||||||
|
Keep machine-specific overrides in ignored `scripts/env.sh.local` or `.env`,
|
||||||
|
which are sourced by the optional environment helper. These must contain
|
||||||
|
trusted shell syntax, not arbitrary dotenv syntax.
|
||||||
|
|
||||||
|
## Task Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/add-task "Outline the first deliverable" --project example-project --type task --status triage
|
||||||
|
./scripts/get-task 1 --json
|
||||||
|
./scripts/update-task 1 --status ready
|
||||||
|
./scripts/work-on-task 1 --start
|
||||||
|
./scripts/update-task 1 --status testing --check-all
|
||||||
|
./scripts/update-tasks
|
||||||
|
```
|
||||||
|
|
||||||
|
Working agents move completed work to `testing`; humans verify it before
|
||||||
|
moving it to `done`. `testing` means review/verification, not necessarily
|
||||||
|
automated software testing.
|
||||||
|
|
||||||
|
`triage` and `research` optionally launch Hermes or Antigravity. Those external
|
||||||
|
CLIs are not required for the core task commands or tests. See the
|
||||||
|
[script guide](./scripts/README.md) for options.
|
||||||
|
|
||||||
|
## Shared Agent Skills
|
||||||
|
|
||||||
|
- **initial-setup**: interview the user and configure a fresh clone.
|
||||||
|
- **task-management**: query, add, update, and synchronize tasks.
|
||||||
|
- **execute-tasks**: implement specified tasks sequentially and record checks.
|
||||||
|
|
||||||
|
These live in [.agents/skills/](./.agents/skills/). The repository-wide
|
||||||
|
[agent guide](./AGENTS.md) keeps workflows independent of any particular stack.
|
||||||
222
docs/tasks.md
222
docs/tasks.md
@@ -1,120 +1,101 @@
|
|||||||
---
|
---
|
||||||
# Most projects only have one or two projects. label is used in prose and value is used as an index. Setup those task-id-prefix and projects values.
|
task-id-prefix: 'EX'
|
||||||
|
|
||||||
task-id-prefix: 'OB'
|
|
||||||
projects:
|
projects:
|
||||||
- label: 'Old Bear VTT'
|
- label: 'Example Project'
|
||||||
path: '.'
|
path: '.'
|
||||||
prefix: 'OBV'
|
value: 'example-project'
|
||||||
value: 'old-bear-vtt'
|
|
||||||
- label: 'Old Bear Brawl'
|
|
||||||
path: '.'
|
|
||||||
prefix: 'OBB'
|
|
||||||
value: 'old-bear-brawl'
|
|
||||||
- label: 'Common'
|
|
||||||
path: '.'
|
|
||||||
prefix: 'CMN'
|
|
||||||
value: 'cmn'
|
|
||||||
task-statuses:
|
task-statuses:
|
||||||
- label: 'Planning'
|
- label: 'Planning'
|
||||||
value: 'planning'
|
value: 'planning'
|
||||||
description: 'We do not yet know what it should do.'
|
description: 'Define the goals and scope.'
|
||||||
- label: 'Triage'
|
- label: 'Triage'
|
||||||
value: 'triage'
|
value: 'triage'
|
||||||
description: 'We do not yet know how to do it.'
|
description: 'Decide how to approach the work.'
|
||||||
|
- label: 'Research'
|
||||||
|
value: 'research'
|
||||||
|
description: 'Investigate before planning or execution.'
|
||||||
- label: 'Ready'
|
- label: 'Ready'
|
||||||
value: 'ready'
|
value: 'ready'
|
||||||
description: 'Task is ready to be worked on.'
|
description: 'Ready to be worked on.'
|
||||||
- label: 'In Progress'
|
- label: 'In Progress'
|
||||||
value: 'in-progress'
|
value: 'in_progress'
|
||||||
description: 'Task is currently being worked on.'
|
description: 'Work is underway.'
|
||||||
- label: 'Testing'
|
- label: 'Testing'
|
||||||
value: 'testing'
|
value: 'testing'
|
||||||
description: 'Task is currently being tested.'
|
description: 'Awaiting human review or verification.'
|
||||||
- label: 'Blocked'
|
- label: 'Blocked'
|
||||||
value: 'blocked'
|
value: 'blocked'
|
||||||
description: 'Task is waiting on external dependencies.'
|
description: 'Waiting on a dependency or decision.'
|
||||||
- label: 'Done'
|
- label: 'Done'
|
||||||
value: 'done'
|
value: 'done'
|
||||||
description: 'Task is completed and verified.'
|
description: 'Completed and verified by a human.'
|
||||||
|
- label: 'Cancelled'
|
||||||
|
value: 'cancelled'
|
||||||
|
description: 'No longer applicable.'
|
||||||
task-types:
|
task-types:
|
||||||
- value: 'bug'
|
- value: 'task'
|
||||||
prefix: 'BUG'
|
label: 'Task'
|
||||||
label: 'Bug'
|
description: 'A project deliverable or activity.'
|
||||||
description: 'The task is a bug to fix.'
|
|
||||||
- value: 'feature'
|
|
||||||
prefix: 'ENH'
|
|
||||||
label: 'Feature'
|
|
||||||
description: 'The task is a new feature to implement.'
|
|
||||||
- value: 'chore'
|
- value: 'chore'
|
||||||
prefix: 'CHR'
|
|
||||||
label: 'Chore'
|
label: 'Chore'
|
||||||
description: 'The task is a routine maintenance or administrative task.'
|
description: 'Routine maintenance or administrative work.'
|
||||||
|
- value: 'feature'
|
||||||
|
label: 'Feature'
|
||||||
|
description: 'A new capability, when relevant to the project.'
|
||||||
|
- value: 'bug'
|
||||||
|
label: 'Bug'
|
||||||
|
description: 'A defect to fix, when relevant to the project.'
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project Task Tracker
|
# Project Task Tracker
|
||||||
|
|
||||||
## Instructions for Working with Tasks
|
## Working with Tasks
|
||||||
|
|
||||||
### Quick Start (Environment Setup)
|
This tracker works for any project, including writing, research, and software.
|
||||||
|
`testing` means awaiting review or verification; it does not require automated
|
||||||
|
tests. This is a sample backlog. Customize the sample task for your project.
|
||||||
|
|
||||||
Before running task commands, source the helper environment script in your shell to load convenient aliases and paths:
|
### Configuration
|
||||||
|
|
||||||
|
- `task-id-prefix` controls display IDs and anchors. This example uses `EX`.
|
||||||
|
- `TASK_ID_PREFIX` overrides frontmatter; the script default is `EX`.
|
||||||
|
- Prefixes start with a letter and contain letters, digits, underscores, or
|
||||||
|
hyphens. Display IDs are uppercase; anchors are lowercase.
|
||||||
|
- Numbers are globally monotonic with at least three digits. Use a number alone
|
||||||
|
with task commands to avoid dependence on the configured prefix.
|
||||||
|
- After changing the prefix, run `./scripts/update-tasks` to migrate IDs and
|
||||||
|
internal links without changing task numbers.
|
||||||
|
- `projects` defines labels, keys, and repository-relative paths. If renaming
|
||||||
|
a project key, update corresponding task anchor `data-project` attributes.
|
||||||
|
- All task commands accept `-f /path/to/tasks.md`; exported `TASKS_FILE` sets
|
||||||
|
the default tracker.
|
||||||
|
- Optional `epics` and `subprojects` can group work. Define their values and
|
||||||
|
labels in frontmatter before assigning them.
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
The CLI tools require Python 3.9+ and Bash or Zsh. They are optional; you can
|
||||||
|
also maintain this Markdown tracker with your assistant.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
source ./scripts/env.sh
|
source ./scripts/env.sh
|
||||||
|
./scripts/get-tasks --all
|
||||||
|
./scripts/get-tasks --accept "Status:Ready"
|
||||||
|
./scripts/get-task 1 --json
|
||||||
|
./scripts/add-task "Outline the next deliverable" --project example-project --type task --status triage
|
||||||
|
./scripts/update-task 1 --status in_progress
|
||||||
|
./scripts/update-task 1 --append-description "- [ ] Additional review criterion"
|
||||||
|
./scripts/update-task 1 --status testing --check-all
|
||||||
|
./scripts/update-tasks
|
||||||
```
|
```
|
||||||
|
|
||||||
### Task ID Configuration
|
Task anchor attributes in **Detailed Tasks** are the canonical metadata.
|
||||||
|
Do not manually edit generated summary or enum tables; regenerate them with
|
||||||
|
`update-tasks`. Working agents transition completed work to `testing`, not
|
||||||
|
`done`. A human confirms completion.
|
||||||
|
|
||||||
- Set the document-wide `task-id-prefix` in YAML frontmatter (this tracker uses `OB`).
|
See the [script guide](../scripts/README.md) and
|
||||||
- Optionally export `TASK_ID_PREFIX` in your shell or in the local settings sourced by `scripts/env.sh` (`scripts/env.sh.local` or `.env`). It overrides frontmatter; when neither is set, the default is `OT`.
|
[getting started guide](../README.md) for details.
|
||||||
- Prefixes must start with a letter and contain only letters, digits, underscores, or hyphens. Display IDs are uppercase and anchors are lowercase.
|
|
||||||
- Numbers remain globally monotonic across the document, with at least three digits. Project and task-type `prefix` fields do not control these IDs.
|
|
||||||
- After changing the prefix, run `update-tasks` to normalize existing IDs and internal anchor links. Numeric IDs can still be used with task commands.
|
|
||||||
- All task commands accept `-f /path/to/tasks.md`; `TASKS_FILE` supplies the default path when exported.
|
|
||||||
|
|
||||||
### Command Reference
|
|
||||||
|
|
||||||
You can manage tasks using the provided automation scripts in `./scripts/` (or via their aliases):
|
|
||||||
|
|
||||||
- **List tasks**:
|
|
||||||
- `get-tasks` (or `./scripts/get-tasks`): Show active pending tasks.
|
|
||||||
- `get-planning-tasks` (or `get-tasks --planning`): Show tasks in _Planning_ or _Triage_ status.
|
|
||||||
- `get-tasks --all`: List all tasks regardless of status.
|
|
||||||
- `get-tasks --accept "Status:In Progress"` / `get-tasks --reject "Project:Example"`: Filter tasks.
|
|
||||||
- `get-tasks --all --accept "Epic:poc" --select "ID,Title,Epic"`: Filter or select the Epic column. Epic filters accept frontmatter values (`poc`) or labels (`Proof of Concept`), case-insensitively.
|
|
||||||
- `get-tasks --all --reject "Epic:poc"`: Exclude an Epic by value or label; comma-separated lists such as `Epic:poc,bootstrap` also work.
|
|
||||||
- **View a specific task**:
|
|
||||||
- `get-task OT-001` (or `./scripts/get-task 1`): Inspect task details, requirements, and metadata.
|
|
||||||
- `get-task OT-001 --json`: Output task data in JSON format, including `epic` (value) and `epic_label`.
|
|
||||||
- `get-task OT-001 --epic`: Output only the canonical Epic value.
|
|
||||||
- **Add a new task**:
|
|
||||||
- `add-task "Task Title" --project=example-project --type=feature --status=triage`
|
|
||||||
- (Optionally supply `-d "Description and checklist"`)
|
|
||||||
- Add `--epic=poc` (or `--epic="Proof of Concept"`) to assign an Epic defined in frontmatter.
|
|
||||||
- **Update an existing task**:
|
|
||||||
- `update-task OT-001 --status in_progress`
|
|
||||||
- `update-task OT-001 --title "New Title"`
|
|
||||||
- `update-task OT-001 --status done --check-all`
|
|
||||||
- `update-task OT-001 --append-description "- [ ] Additional subtask"`
|
|
||||||
- `update-task OT-001 --epic=poc` / `update-task OT-001 --clear-epic`: Assign or remove an Epic.
|
|
||||||
- **Synchronize document**:
|
|
||||||
- `update-tasks` (or `./scripts/update-tasks`): Re-indexes task IDs, re-renders the summary progress table, and regenerates metadata enum tables.
|
|
||||||
|
|
||||||
### Workflow Guidelines
|
|
||||||
|
|
||||||
1. **Do Not Edit the Summary Table Manually**: The summary table below is automatically regenerated from the detailed task entries. Use `./scripts/add-task` and `./scripts/update-task`, or edit the detailed task blocks directly and run `./scripts/update-tasks`.
|
|
||||||
2. **Anchor Tags as SSOT**: Each task in `## Detailed Tasks` is defined by an anchor tag:
|
|
||||||
`<a id="ot-XXX" class="task" data-project="PROJECT" data-epic="EPIC" data-status="STATUS" data-task-type="TYPE"></a>`
|
|
||||||
The attributes on this anchor tag are the canonical source of truth for the task's state.
|
|
||||||
`data-epic` is optional; its value comes from frontmatter `epics`. Summary and detail views display the corresponding label.
|
|
||||||
3. **Task Lifecycle**:
|
|
||||||
- **Triage**: Conceptualization and scoping phase.
|
|
||||||
- **Ready**: Ready to be picked up for implementation.
|
|
||||||
- **In Progress**: Actively being worked on.
|
|
||||||
- **Testing**: Code complete and ready for verification.
|
|
||||||
- **Done**: Completed and verified.
|
|
||||||
- **Blocked**: Waiting on external dependencies.
|
|
||||||
|
|
||||||
<a id="tasks-summary"></a>
|
<a id="tasks-summary"></a>
|
||||||
|
|
||||||
@@ -123,52 +104,25 @@ You can manage tasks using the provided automation scripts in `./scripts/` (or v
|
|||||||
<a id="tasks-list"></a>
|
<a id="tasks-list"></a>
|
||||||
|
|
||||||
| ID | Title | Project | Status | Type |
|
| ID | Title | Project | Status | Type |
|
||||||
|:-----|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------|:-------|:-----------------|
|
|:-----|:-------------------------|:--------------|:-----|:--------------|
|
||||||
| OB-001 | In voice and audio settings the 4th button for streaming is mostly off screen | Old Bear VTT | Done | [Feature](#ob-001) |
|
| EX-001 | Define the project's goals | Example Project | Ready | [Task](#ex-001) |
|
||||||
| OB-002 | When adding a new token to the board try to not put it on top of an existing one | Old Bear VTT | Done | [Feature](#ob-002) |
|
|
||||||
| OB-003 | When uploading files allow selecting multiple files at once | Old Bear VTT | Done | [Feature](#ob-003) | | Common | Ready | [Feature](#ob-211) |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<a id="task-details"></a>
|
|
||||||
|
|
||||||
## Detailed Tasks
|
## Detailed Tasks
|
||||||
|
|
||||||
<a id="ob-001" class="task" data-project="old-bear-vtt" data-status="done" data-task-type="feature"></a>
|
<a id="ex-001" class="task" data-project="example-project" data-status="ready" data-task-type="task"></a>
|
||||||
### In voice and audio settings the 4th button for streaming is mostly off screen
|
### Define the project's goals
|
||||||
**ID:** OB-001
|
**ID:** EX-001
|
||||||
**Project:** Old Bear VTT
|
**Project:** Example Project
|
||||||
**Status:** Done
|
**Status:** Ready
|
||||||
**Type:** Feature
|
**Type:** Task
|
||||||
|
|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
|
Replace this sample with the first meaningful activity for your project.
|
||||||
In voice and audio settings the 4th button for streaming is mostly off screen
|
- [ ] Describe the intended outcome and audience.
|
||||||
|
- [ ] Identify the first deliverable.
|
||||||
<a id="ob-002" class="task" data-project="old-bear-vtt" data-status="done" data-task-type="feature"></a>
|
- [ ] Agree on how the deliverable will be reviewed or verified.
|
||||||
### When adding a new token to the board try to not put it on top of an existing one
|
|
||||||
**ID:** OB-002
|
|
||||||
**Project:** Old Bear VTT
|
|
||||||
**Status:** Done
|
|
||||||
**Type:** Feature
|
|
||||||
|
|
||||||
|
|
||||||
**Description:**
|
|
||||||
|
|
||||||
When adding a new token to the board try to not put it on top of an existing one
|
|
||||||
|
|
||||||
<a id="ob-003" class="task" data-project="old-bear-vtt" data-status="done" data-task-type="feature"></a>
|
|
||||||
### When uploading files allow selecting multiple files at once
|
|
||||||
**ID:** OB-003
|
|
||||||
**Project:** Old Bear VTT
|
|
||||||
**Status:** Done
|
|
||||||
**Type:** Feature
|
|
||||||
|
|
||||||
|
|
||||||
**Description:**
|
|
||||||
|
|
||||||
When uploading files allow selecting multiple files at once
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -176,26 +130,6 @@ When uploading files allow selecting multiple files at once
|
|||||||
|
|
||||||
#### Projects (Rendered from frontmatter projects)
|
#### Projects (Rendered from frontmatter projects)
|
||||||
|
|
||||||
| Value | Label | Prefix | Path |
|
|
||||||
| :------------- | :------------- | :----- | :--- |
|
|
||||||
| old-bear-vtt | Old Bear VTT | OBV | . |
|
|
||||||
| old-bear-brawl | Old Bear Brawl | OBB | . |
|
|
||||||
|
|
||||||
#### Task Statuses (Rendered from frontmatter task-statuses)
|
#### Task Statuses (Rendered from frontmatter task-statuses)
|
||||||
|
|
||||||
| Value | Label | Description |
|
|
||||||
| :---------- | :---------- | :---------------------------------------- |
|
|
||||||
| triage | Triage | Task is still being defined. |
|
|
||||||
| ready | Ready | Task is ready to be worked on. |
|
|
||||||
| in-progress | In Progress | Task is currently being worked on. |
|
|
||||||
| testing | Testing | Task is currently being tested. |
|
|
||||||
| blocked | Blocked | Task is waiting on external dependencies. |
|
|
||||||
| done | Done | Task is completed and verified. |
|
|
||||||
|
|
||||||
#### Task Types (Rendered from frontmatter task-types)
|
#### Task Types (Rendered from frontmatter task-types)
|
||||||
|
|
||||||
| Value | Label | Prefix | Description |
|
|
||||||
| :------ | :------ | :----- | :-------------------------------------------------------- |
|
|
||||||
| bug | Bug | BUG | The task is a bug to fix. |
|
|
||||||
| feature | Feature | ENH | The task is a new feature to implement. |
|
|
||||||
| chore | Chore | CHR | The task is a routine maintenance or administrative task. |
|
|
||||||
|
|||||||
5
project-config.json
Normal file
5
project-config.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "Example Project",
|
||||||
|
"description": "A generic project starter with task tracking and reusable agent workflows.",
|
||||||
|
"commands": {}
|
||||||
|
}
|
||||||
@@ -1,67 +1,77 @@
|
|||||||
# Project Scripts
|
# Project Scripts
|
||||||
|
|
||||||
This directory contains repository maintenance, task management, and release automation scripts for **Old Bear Battles**.
|
Optional task-management tools for any kind of project. They require
|
||||||
|
Python 3.9+ and Bash or Zsh, but no third-party Python packages. They do not
|
||||||
|
prescribe the project's language, platform, or subject.
|
||||||
|
|
||||||
---
|
Tasks live in [docs/tasks.md](../docs/tasks.md). Project identity and optional
|
||||||
|
commands live in [project-config.json](../project-config.json).
|
||||||
|
|
||||||
## Active Task Management Tooling
|
## Environment
|
||||||
|
|
||||||
All work items and backlog features are tracked directly in repository Markdown at [docs/tasks.md](file:///Users/tom/Projects/OldBearBattles/docs/tasks.md). The Python CLI scripts below provide fast query, insertion, update, and normalization capabilities:
|
|
||||||
|
|
||||||
### `get-tasks`
|
|
||||||
Lists tasks from `docs/tasks.md` with sorting, column selection, and flexible predicate filtering:
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/get-tasks # List all tasks sorted by ID (desc)
|
source ./scripts/env.sh
|
||||||
./scripts/get-tasks --accept 'Status:Testing' # List tasks currently awaiting verification
|
|
||||||
./scripts/get-tasks -p # List tasks in Triage and Planning status
|
|
||||||
./scripts/get-tasks --all # Show all tasks including Done and Cancelled
|
|
||||||
./scripts/get-tasks --sort asc # Sort in ascending order
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### `get-task <ID>`
|
This adds scripts to `PATH` and defines task aliases. It sources trusted local
|
||||||
Displays detailed information, metadata fields, and full description for a specific task ID:
|
shell settings from `scripts/env.sh.local`, or `.env` if the first file is
|
||||||
```bash
|
absent. Both are ignored by Git. An existing `TASKS_FILE` is preserved.
|
||||||
./scripts/get-task OB-206
|
`TASK_ID_PREFIX` overrides task frontmatter; the default prefix is `EX`.
|
||||||
```
|
All task commands accept `-f /path/to/tasks.md`.
|
||||||
|
|
||||||
### `add-task <title>`
|
## Query and Edit Tasks
|
||||||
Appends a new task entry to `docs/tasks.md` with frontmatter and structured markdown anchor tags:
|
|
||||||
```bash
|
|
||||||
./scripts/add-task "Descriptive Title" -p cmn -t feature -s ready -d "Task description and criteria"
|
|
||||||
```
|
|
||||||
**Options**:
|
|
||||||
- `-p, --project`: Project code (`vtt`, `cmn`, `platform`, `shared`, `brawl`)
|
|
||||||
- `-t, --type`: Task type (`feature`, `bug`, `chore`)
|
|
||||||
- `-s, --status`: Initial status (`triage`, `planning`, `ready`, `in_progress`, `testing`, `done`, `blocked`, `cancelled`)
|
|
||||||
- `-d, --description`: Markdown description text
|
|
||||||
|
|
||||||
### `update-task <ID>`
|
|
||||||
Updates status, checks off checklist items, or appends notes to a task:
|
|
||||||
```bash
|
|
||||||
./scripts/update-task OB-206 --status testing
|
|
||||||
./scripts/update-task OB-206 --check-all
|
|
||||||
./scripts/update-task OB-206 --append-description "### Implementation Notes:\n- Added test coverage."
|
|
||||||
```
|
|
||||||
|
|
||||||
### `update-tasks`
|
|
||||||
Validates and normalizes `docs/tasks.md` tables, frontmatter, and anchor IDs:
|
|
||||||
```bash
|
```bash
|
||||||
|
./scripts/get-tasks --all
|
||||||
|
./scripts/get-tasks --accept 'Status:Testing'
|
||||||
|
./scripts/get-tasks --planning
|
||||||
|
./scripts/get-tasks --sort asc
|
||||||
|
./scripts/get-task EX-001
|
||||||
|
./scripts/get-task 1 --json
|
||||||
|
./scripts/add-task "Describe the first deliverable" -p example-project -t task -s triage
|
||||||
|
./scripts/update-task 1 --status ready
|
||||||
|
./scripts/work-on-task 1 --start
|
||||||
|
./scripts/update-task 1 --status testing --check-all
|
||||||
|
./scripts/update-task 1 --append-description "- [ ] Additional review criterion"
|
||||||
./scripts/update-tasks
|
./scripts/update-tasks
|
||||||
```
|
```
|
||||||
|
|
||||||
### `triage` / `research`
|
- `get-tasks`: triage tasks by default; `--all` includes completed work.
|
||||||
Interactive helpers for rapidly reviewing tasks in triage or conducting architectural research on backlog items.
|
Supports column selection and filters; `--help` lists the options.
|
||||||
|
- `get-task`: metadata and full description for a prefixed ID or task number.
|
||||||
|
- `add-task`: assigns the next numeric ID. Supply a project key and type from
|
||||||
|
frontmatter; the legacy defaults are `shared` and `feature`.
|
||||||
|
- `update-task`: edits metadata, descriptions, and checklist items.
|
||||||
|
- `work-on-task`: validates readiness and optionally starts work.
|
||||||
|
- `update-tasks`: regenerates summary/enum tables and normalizes IDs and links.
|
||||||
|
|
||||||
---
|
`testing` means awaiting human verification, whether that is editorial review,
|
||||||
|
a planning checklist, or software tests. Agents do not mark their own work
|
||||||
|
`done`.
|
||||||
|
|
||||||
## Release Tooling
|
## Optional Agent Helpers
|
||||||
|
|
||||||
- **`build-release`**: Automated release build pipeline (runs test suites, packages production build).
|
```bash
|
||||||
- **`package-release`**: Distribution packaging script for reproducible standalone releases.
|
./scripts/triage 1 --hermes
|
||||||
|
./scripts/research 1 --agy
|
||||||
|
```
|
||||||
|
|
||||||
---
|
These launch an installed Hermes or Antigravity CLI. Core task commands and
|
||||||
|
tests do not need either. Select an agent with `--agent`, a shortcut above,
|
||||||
|
or `TASK_AGENT`. Missing agents are reported as errors.
|
||||||
|
|
||||||
## Note on `ot` (Open Tasks)
|
`triage` accepts `planning` / `triage`; `research` accepts `research`.
|
||||||
|
Their prompts read the shared JSON configuration and refer to
|
||||||
|
[AGENTS.md](../AGENTS.md), rather than assuming a particular project or stack.
|
||||||
|
An empty `commands` object means no project commands are configured. Configured
|
||||||
|
commands are included as guidance, not executed by these helpers.
|
||||||
|
|
||||||
> [!NOTE]
|
## Tooling Tests
|
||||||
> Any references to `ot` (Open Tasks) refer to an upcoming standalone task management tool that is currently under development and not yet released. In the meantime, all tasks in this repository are managed directly in [docs/tasks.md](file:///Users/tom/Projects/OldBearBattles/docs/tasks.md) using the scripts documented above.
|
|
||||||
|
```bash
|
||||||
|
python3 -m unittest discover -s scripts/tests -v
|
||||||
|
```
|
||||||
|
|
||||||
|
This validates the bundled tools, not your project's deliverables.
|
||||||
|
No release scripts are provided: publishing or deployment should be added only
|
||||||
|
when the project's needs are known.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,10 +2,10 @@
|
|||||||
"""
|
"""
|
||||||
add-task
|
add-task
|
||||||
|
|
||||||
Appends a new task to Documentation/Tasks.md and re-synchronizes the task list.
|
Appends a new task to docs/tasks.md and re-synchronizes the task list.
|
||||||
Usage:
|
Usage:
|
||||||
add-task "My Title Goes Here" --project=shared --type=chore
|
add-task "My Title Goes Here" --project=shared --type=chore
|
||||||
add-task "My Title Goes Here" -p editor -t feature -s triage -d "Description text"
|
add-task "My Title Goes Here" -p example-project -t feature -s triage -d "Description text"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Build and verify a production release of Open Tasks
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
|
|
||||||
|
|
||||||
VERSION=""
|
|
||||||
OUTPUT_DIR="${REPO_ROOT}/dist"
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--version|-v)
|
|
||||||
VERSION="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--output-dir|-o)
|
|
||||||
OUTPUT_DIR="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
VERSION="$1"
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$VERSION" ]; then
|
|
||||||
VERSION=$(python3 -c "import ot; print(ot.__version__)")
|
|
||||||
fi
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
echo "=== 1. Running Test Suite ==="
|
|
||||||
python3 -m unittest discover -s "${REPO_ROOT}/tests"
|
|
||||||
|
|
||||||
echo "=== 2. Building Release Artifact (v${VERSION}) ==="
|
|
||||||
python3 -m ot.packaging \
|
|
||||||
--version "$VERSION" \
|
|
||||||
--src-dir "${REPO_ROOT}/src" \
|
|
||||||
--output-dir "$OUTPUT_DIR" \
|
|
||||||
--artifact-name "ot-${VERSION}.zipapp"
|
|
||||||
|
|
||||||
# Also maintain canonical ot.zipapp copy in dist/
|
|
||||||
cp "${OUTPUT_DIR}/ot-${VERSION}.zipapp" "${OUTPUT_DIR}/ot.zipapp"
|
|
||||||
|
|
||||||
echo "=== 3. Generating SHA256 Checksums ==="
|
|
||||||
cd "$OUTPUT_DIR"
|
|
||||||
if command -v sha256sum >/dev/null 2>&1; then
|
|
||||||
sha256sum "ot-${VERSION}.zipapp" "ot.zipapp" > SHA256SUMS
|
|
||||||
elif command -v shasum >/dev/null 2>&1; then
|
|
||||||
shasum -a 256 "ot-${VERSION}.zipapp" "ot.zipapp" > SHA256SUMS
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "=== 4. Validating Built Release Artifact ==="
|
|
||||||
python3 "${OUTPUT_DIR}/ot-${VERSION}.zipapp" version
|
|
||||||
|
|
||||||
echo "=========================================="
|
|
||||||
echo "Release Pipeline completed successfully for v${VERSION}!"
|
|
||||||
echo "Artifacts created in ${OUTPUT_DIR}:"
|
|
||||||
ls -la "${OUTPUT_DIR}"
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# ==============================================================================
|
|
||||||
# Old Bear Battles - Production Container Build & CI Publish Script
|
|
||||||
# Sourced from single source of truth: VERSION file in repository root
|
|
||||||
# ==============================================================================
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
||||||
cd "${ROOT_DIR}"
|
|
||||||
|
|
||||||
# 1. Read version from single source of truth (VERSION file in repo root)
|
|
||||||
APP_VERSION=""
|
|
||||||
if [ -f "${ROOT_DIR}/VERSION" ]; then
|
|
||||||
APP_VERSION="$(tr -d ' \r\n' < "${ROOT_DIR}/VERSION")"
|
|
||||||
fi
|
|
||||||
if [ -z "${APP_VERSION}" ]; then
|
|
||||||
APP_VERSION="0.1.0-alpha5"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Get short git commit hash
|
|
||||||
GIT_COMMIT_SHORT="$(git rev-parse --short HEAD 2>/dev/null || echo "dev")"
|
|
||||||
|
|
||||||
# Default configuration (can be overridden via CLI args or environment variables)
|
|
||||||
IMAGE_REGISTRY="${IMAGE_REGISTRY:-ghcr.io/headhunter45/}"
|
|
||||||
IMAGE_REGISTRY="$(echo "${IMAGE_REGISTRY}" | tr '[:upper:]' '[:lower:]')"
|
|
||||||
if [ -n "${IMAGE_REGISTRY}" ] && [[ "${IMAGE_REGISTRY}" != */ ]]; then
|
|
||||||
IMAGE_REGISTRY="${IMAGE_REGISTRY}/"
|
|
||||||
fi
|
|
||||||
|
|
||||||
IMAGE_TAG="${IMAGE_TAG:-${APP_VERSION}}"
|
|
||||||
DO_PUSH=false
|
|
||||||
RUN_TESTS=false
|
|
||||||
|
|
||||||
# Parse command line options
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--registry)
|
|
||||||
IMAGE_REGISTRY="$(echo "$2" | tr '[:upper:]' '[:lower:]')"
|
|
||||||
if [ -n "${IMAGE_REGISTRY}" ] && [[ "${IMAGE_REGISTRY}" != */ ]]; then
|
|
||||||
IMAGE_REGISTRY="${IMAGE_REGISTRY}/"
|
|
||||||
fi
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--tag)
|
|
||||||
IMAGE_TAG="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
--push)
|
|
||||||
DO_PUSH=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--test)
|
|
||||||
RUN_TESTS=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
echo "Usage: $0 [OPTIONS]"
|
|
||||||
echo ""
|
|
||||||
echo "Options:"
|
|
||||||
echo " --registry <URL> Container registry prefix (default: ${IMAGE_REGISTRY})"
|
|
||||||
echo " --tag <TAG> Container image tag (default: ${IMAGE_TAG} from VERSION file)"
|
|
||||||
echo " --push Push container images to registry after building"
|
|
||||||
echo " --test Run test suites before building images"
|
|
||||||
echo " -h, --help Show this help message"
|
|
||||||
echo ""
|
|
||||||
echo "Version info:"
|
|
||||||
echo " VERSION file : ${APP_VERSION}"
|
|
||||||
echo " Git commit hash : ${GIT_COMMIT_SHORT}"
|
|
||||||
echo ""
|
|
||||||
echo "Examples:"
|
|
||||||
echo " $0"
|
|
||||||
echo " $0 --push"
|
|
||||||
echo " $0 --registry ghcr.io/headhunter45/ --tag v0.1.0 --push"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown option: $1" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "======================================================================"
|
|
||||||
echo " Old Bear Battles - Production Container Build"
|
|
||||||
echo "======================================================================"
|
|
||||||
echo " Application Ver : ${APP_VERSION} (from VERSION)"
|
|
||||||
echo " Git Commit Hash : ${GIT_COMMIT_SHORT}"
|
|
||||||
echo " Primary Tag : ${IMAGE_TAG}"
|
|
||||||
echo " Registry Prefix : ${IMAGE_REGISTRY:-<local docker>}"
|
|
||||||
echo " Push to Registry: ${DO_PUSH}"
|
|
||||||
echo " Project Root : ${ROOT_DIR}"
|
|
||||||
echo "======================================================================"
|
|
||||||
|
|
||||||
# Optional test run
|
|
||||||
if [ "${RUN_TESTS}" = true ]; then
|
|
||||||
echo ""
|
|
||||||
echo "==> Running automated test suites..."
|
|
||||||
npm test
|
|
||||||
fi
|
|
||||||
|
|
||||||
CLIENT_IMAGE="${IMAGE_REGISTRY}oldbear_client:${IMAGE_TAG}"
|
|
||||||
CLIENT_IMAGE_COMMIT="${IMAGE_REGISTRY}oldbear_client:${GIT_COMMIT_SHORT}"
|
|
||||||
CLIENT_IMAGE_LATEST="${IMAGE_REGISTRY}oldbear_client:latest"
|
|
||||||
|
|
||||||
SERVER_IMAGE="${IMAGE_REGISTRY}oldbear_server:${IMAGE_TAG}"
|
|
||||||
SERVER_IMAGE_COMMIT="${IMAGE_REGISTRY}oldbear_server:${GIT_COMMIT_SHORT}"
|
|
||||||
SERVER_IMAGE_LATEST="${IMAGE_REGISTRY}oldbear_server:latest"
|
|
||||||
|
|
||||||
NGINX_IMAGE="${IMAGE_REGISTRY}oldbear_nginx:${IMAGE_TAG}"
|
|
||||||
NGINX_IMAGE_COMMIT="${IMAGE_REGISTRY}oldbear_nginx:${GIT_COMMIT_SHORT}"
|
|
||||||
NGINX_IMAGE_LATEST="${IMAGE_REGISTRY}oldbear_nginx:latest"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "==> 1/3 Building Client container (${CLIENT_IMAGE})..."
|
|
||||||
docker build \
|
|
||||||
-t "${CLIENT_IMAGE}" \
|
|
||||||
-t "${CLIENT_IMAGE_COMMIT}" \
|
|
||||||
-t "${CLIENT_IMAGE_LATEST}" \
|
|
||||||
-f docker/Dockerfile.client \
|
|
||||||
--build-arg CLIENT_PORT=80 \
|
|
||||||
--build-arg APP_VERSION="${APP_VERSION}" \
|
|
||||||
--build-arg GIT_COMMIT_HASH="${GIT_COMMIT_SHORT}" \
|
|
||||||
.
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "==> 2/3 Building Server container (${SERVER_IMAGE})..."
|
|
||||||
docker build \
|
|
||||||
-t "${SERVER_IMAGE}" \
|
|
||||||
-t "${SERVER_IMAGE_COMMIT}" \
|
|
||||||
-t "${SERVER_IMAGE_LATEST}" \
|
|
||||||
-f docker/Dockerfile.server \
|
|
||||||
--build-arg SERVER_PORT=3001 \
|
|
||||||
--build-arg APP_VERSION="${APP_VERSION}" \
|
|
||||||
--build-arg GIT_COMMIT_HASH="${GIT_COMMIT_SHORT}" \
|
|
||||||
.
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "==> 3/3 Building Nginx proxy container (${NGINX_IMAGE})..."
|
|
||||||
docker build \
|
|
||||||
-t "${NGINX_IMAGE}" \
|
|
||||||
-t "${NGINX_IMAGE_COMMIT}" \
|
|
||||||
-t "${NGINX_IMAGE_LATEST}" \
|
|
||||||
-f docker/Dockerfile.nginx \
|
|
||||||
.
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "======================================================================"
|
|
||||||
echo " Build Completed Successfully!"
|
|
||||||
echo " Images built:"
|
|
||||||
echo " - ${CLIENT_IMAGE}, ${CLIENT_IMAGE_COMMIT}, ${CLIENT_IMAGE_LATEST}"
|
|
||||||
echo " - ${SERVER_IMAGE}, ${SERVER_IMAGE_COMMIT}, ${SERVER_IMAGE_LATEST}"
|
|
||||||
echo " - ${NGINX_IMAGE}, ${NGINX_IMAGE_COMMIT}, ${NGINX_IMAGE_LATEST}"
|
|
||||||
echo "======================================================================"
|
|
||||||
|
|
||||||
if [ "${DO_PUSH}" = true ]; then
|
|
||||||
echo ""
|
|
||||||
echo "==> Pushing images to registry: ${IMAGE_REGISTRY}..."
|
|
||||||
docker push "${CLIENT_IMAGE}"
|
|
||||||
docker push "${CLIENT_IMAGE_COMMIT}"
|
|
||||||
docker push "${CLIENT_IMAGE_LATEST}"
|
|
||||||
docker push "${SERVER_IMAGE}"
|
|
||||||
docker push "${SERVER_IMAGE_COMMIT}"
|
|
||||||
docker push "${SERVER_IMAGE_LATEST}"
|
|
||||||
docker push "${NGINX_IMAGE}"
|
|
||||||
docker push "${NGINX_IMAGE_COMMIT}"
|
|
||||||
docker push "${NGINX_IMAGE_LATEST}"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "======================================================================"
|
|
||||||
echo " All images successfully pushed to ${IMAGE_REGISTRY}!"
|
|
||||||
echo "======================================================================"
|
|
||||||
fi
|
|
||||||
@@ -31,13 +31,12 @@ esac
|
|||||||
|
|
||||||
# Export Repo & Tasks Context
|
# Export Repo & Tasks Context
|
||||||
export REPO_ROOT
|
export REPO_ROOT
|
||||||
export TASKS_FILE="$REPO_ROOT/docs/tasks.md"
|
export TASKS_FILE="${TASKS_FILE:-$REPO_ROOT/docs/tasks.md}"
|
||||||
# Optional document-wide prefix override; unset uses frontmatter, then OT.
|
# Optional document-wide prefix override; unset uses frontmatter, then EX.
|
||||||
# export TASK_ID_PREFIX="OT"
|
# export TASK_ID_PREFIX="EX"
|
||||||
|
|
||||||
# Define Aliases
|
# Define Aliases
|
||||||
alias run-editor='(cd Editor/App && npm run tauri dev -- -- "../../Content/Episodes/Episode 1/Episode.xml")'
|
alias get-ready-tasks="$SCRIPTS_DIR/get-tasks --accept 'Status:Ready' | sed -E 's/ +\\|$/ |/; s/-{10,}/---/'"
|
||||||
alias get-ready-tasks="$SCRIPTS_DIR/get-tasks | sed -E 's/ +\\|$/ |/; s/-{10,}/---/'"
|
|
||||||
alias get-planning-tasks="$SCRIPTS_DIR/get-tasks --planning | sed -E 's/ +\\|$/ |/; s/-{10,}/---/'"
|
alias get-planning-tasks="$SCRIPTS_DIR/get-tasks --planning | sed -E 's/ +\\|$/ |/; s/-{10,}/---/'"
|
||||||
alias add-task="$SCRIPTS_DIR/add-task"
|
alias add-task="$SCRIPTS_DIR/add-task"
|
||||||
alias get-task="$SCRIPTS_DIR/get-task"
|
alias get-task="$SCRIPTS_DIR/get-task"
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
"""
|
"""
|
||||||
get-task
|
get-task
|
||||||
|
|
||||||
Retrieves detailed information and metadata for a specific task in Documentation/Tasks.md.
|
Retrieves detailed information and metadata for a specific task in docs/tasks.md.
|
||||||
Usage:
|
Usage:
|
||||||
./scripts/get-task OT-018
|
./scripts/get-task EX-018
|
||||||
./scripts/get-task 18 --json
|
./scripts/get-task 18 --json
|
||||||
./scripts/get-task OT-099 --description-only
|
./scripts/get-task EX-099 --description-only
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
#
|
#
|
||||||
# get-tasks
|
# get-tasks
|
||||||
#
|
#
|
||||||
# Lists tasks from Documentation/Tasks.md sorted by ID.
|
# Lists tasks from docs/tasks.md sorted by ID.
|
||||||
# Supports --accept, --reject, and --sort [asc|desc] (defaults to descending).
|
# Supports --accept, --reject, and --sort [asc|desc] (defaults to descending).
|
||||||
# Defaults to Pending tasks, or Triage & Planning with -p / --planning.
|
# Defaults to Triage tasks, or Triage & Planning with -p / --planning.
|
||||||
# Uses filter-table if available, with a fast built-in fallback.
|
# Uses filter-table if available, with a fast built-in fallback.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
"""Shared automation library for PlanB task tooling."""
|
"""Shared automation library for project task tooling."""
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -8,6 +9,27 @@ from typing import Any, Dict, List, Optional
|
|||||||
from agents import BaseAgent, get_agent, get_default_agent, list_agents
|
from agents import BaseAgent, get_agent, get_default_agent, list_agents
|
||||||
|
|
||||||
|
|
||||||
|
def load_project_config(config_path: Optional[Path] = None) -> Dict[str, Any]:
|
||||||
|
path = config_path if config_path is not None else Path(__file__).resolve().parents[2] / "project-config.json"
|
||||||
|
try:
|
||||||
|
config = json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, json.JSONDecodeError) as error:
|
||||||
|
raise ValueError(f"Cannot read project configuration {path}: {error}") from error
|
||||||
|
if not isinstance(config, dict):
|
||||||
|
raise ValueError(f"Project configuration {path} must be a JSON object")
|
||||||
|
for field in ("name", "description"):
|
||||||
|
if not isinstance(config.get(field), str) or not config[field].strip():
|
||||||
|
raise ValueError(f"Project configuration {path} requires a non-empty '{field}' string")
|
||||||
|
commands = config.get("commands")
|
||||||
|
if not isinstance(commands, dict) or any(
|
||||||
|
not isinstance(name, str) or not name.strip()
|
||||||
|
or not isinstance(command, str) or not command.strip()
|
||||||
|
for name, command in commands.items()
|
||||||
|
):
|
||||||
|
raise ValueError(f"Project configuration {path} requires 'commands' to map names to non-empty command strings")
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
def load_get_task_module():
|
def load_get_task_module():
|
||||||
"""Dynamically load scripts/get-task."""
|
"""Dynamically load scripts/get-task."""
|
||||||
repo_root = Path(__file__).resolve().parent.parent.parent
|
repo_root = Path(__file__).resolve().parent.parent.parent
|
||||||
@@ -53,12 +75,19 @@ def build_workflow_prompt(
|
|||||||
extra_context: str = "",
|
extra_context: str = "",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Construct a standardized, high-fidelity prompt for an AI agent."""
|
"""Construct a standardized, high-fidelity prompt for an AI agent."""
|
||||||
|
config = load_project_config()
|
||||||
|
commands = "\n".join(f"- {name}: `{command}`" for name, command in config["commands"].items())
|
||||||
|
if not commands:
|
||||||
|
commands = "- No commands configured. Agree on relevant verification criteria with the user."
|
||||||
desc = task["description"].strip() if task.get("description") else "(No description provided yet)"
|
desc = task["description"].strip() if task.get("description") else "(No description provided yet)"
|
||||||
subproj_line = f"- Subproject: {task['subproject']}\n" if task.get("subproject") else ""
|
subproj_line = f"- Subproject: {task['subproject']}\n" if task.get("subproject") else ""
|
||||||
epic_line = f"- Epic: {task.get('epic_label', task['epic'])} ({task['epic']})\n" if task.get("epic") else ""
|
epic_line = f"- Epic: {task.get('epic_label', task['epic'])} ({task['epic']})\n" if task.get("epic") else ""
|
||||||
epic_arg = f" --epic={task['epic']}" if task.get("epic") else ""
|
epic_arg = f" --epic={task['epic']}" if task.get("epic") else ""
|
||||||
|
|
||||||
prompt = f"""You are {workflow_name} task {task['id']} in the PlanBForGreatJustice repository.
|
prompt = f"""You are {workflow_name} task {task['id']} for {config['name']}.
|
||||||
|
|
||||||
|
### Project:
|
||||||
|
{config['description']}
|
||||||
|
|
||||||
### Target Task:
|
### Target Task:
|
||||||
- ID: {task['id']}
|
- ID: {task['id']}
|
||||||
@@ -71,23 +100,25 @@ def build_workflow_prompt(
|
|||||||
{desc}
|
{desc}
|
||||||
|
|
||||||
### Repository Context & Guidelines:
|
### Repository Context & Guidelines:
|
||||||
1. SSoT & Task Management (GEMINI.md):
|
1. SSoT & Task Management (AGENTS.md):
|
||||||
- You MUST use `./scripts/update-task {task['id']} ...` to update task metadata, description, title, or checklist items.
|
- You MUST use `./scripts/update-task {task['id']} ...` to update task metadata, description, title, or checklist items.
|
||||||
- If this task needs to be split into subtasks, use `./scripts/add-task "Subtask Title" --project={task['project']} --type={task['type']}{epic_arg}`.
|
- If this task needs to be split into subtasks, use `./scripts/add-task "Subtask Title" --project={task['project']} --type={task['type']}{epic_arg}`.
|
||||||
- Do NOT edit docs/tasks.md manually.
|
- Do NOT edit docs/tasks.md manually.
|
||||||
2. Architecture Overview:
|
2. Project Context:
|
||||||
- C++ Story Engine: Engine/PlanB/Engine/ (Actions, Expressions, Sequences, GameState, StoryModel).
|
- Read AGENTS.md, README.md, and relevant project documents before starting.
|
||||||
- Desktop Editor: Editor/App/ (Tauri + Vite + React, Sequence Simulator, Expression Graph Canvas, XML converters).
|
- Do not assume this is software or prescribe a language, platform, or architecture.
|
||||||
- Content: Content/Episode 1/Episode1/Episode.xml.
|
- Use the project's agreed verification criteria, including human review when appropriate.
|
||||||
- Specifications: docs/Schema/ (e.g., PBScript_Specification.md, grammar files).
|
|
||||||
- Legacy Reference: Editor/Sources/ (WPF C# editor for comparison if applicable).
|
### Optional Project Commands (guidance, not automatically executed):
|
||||||
|
{commands}
|
||||||
|
|
||||||
3. Objectives for this session:
|
3. Objectives for this session:
|
||||||
{workflow_objective}
|
{workflow_objective}
|
||||||
"""
|
"""
|
||||||
if extra_context:
|
if extra_context:
|
||||||
prompt += f"\n### Additional Context:\n{extra_context}\n"
|
prompt += f"\n### Additional Context:\n{extra_context}\n"
|
||||||
|
|
||||||
prompt += f"\nBegin by reviewing the task, inspecting the relevant code, and collaborating interactively with the user.\n"
|
prompt += "\nBegin by reviewing the task, inspecting the relevant project materials, and collaborating interactively with the user.\n"
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Package Open Tasks release artifact
|
|
||||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
export PYTHONPATH="${REPO_ROOT}/src:${PYTHONPATH:-}"
|
|
||||||
|
|
||||||
python3 -m ot.packaging "$@"
|
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
"""
|
"""
|
||||||
research
|
research
|
||||||
|
|
||||||
Researches a task from Documentation/Tasks.md using an AI CLI agent (Antigravity or Hermes).
|
Researches a task from docs/tasks.md using an AI CLI agent (Antigravity or Hermes).
|
||||||
Validates that the task is in 'research' status, prepares task and codebase context,
|
Validates that the task is in 'research' status, prepares task and project context,
|
||||||
and launches the agent interactively.
|
and launches the agent interactively.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./scripts/research 037
|
./scripts/research 037
|
||||||
./scripts/research OT-037 --hermes
|
./scripts/research EX-037 --hermes
|
||||||
./scripts/research 037 --agy
|
./scripts/research 037 --agy
|
||||||
./scripts/research --help
|
./scripts/research --help
|
||||||
"""
|
"""
|
||||||
@@ -28,17 +28,17 @@ from task_context import (
|
|||||||
resolve_selected_agent,
|
resolve_selected_agent,
|
||||||
)
|
)
|
||||||
|
|
||||||
RESEARCH_OBJECTIVES = """- Deeply investigate the technical requirements, architecture, and code models needed for this task.
|
RESEARCH_OBJECTIVES = """- Investigate the requirements, background, and evidence needed for this task.
|
||||||
- Inspect existing codebase, grammar definitions, or schemas to identify gaps or technical hurdles.
|
- Inspect existing project materials to identify gaps or challenges.
|
||||||
- Perform web searches or documentation lookups if external formats, libraries, or protocols are involved.
|
- Consult relevant sources when needed and record citations.
|
||||||
- Collaborate interactively with the user to explore technical trade-offs and possible approaches.
|
- Collaborate interactively with the user to explore trade-offs and possible approaches.
|
||||||
- Document research findings, technical recommendations, and proposed solutions.
|
- Document research findings, recommendations, and proposed next steps.
|
||||||
- When research is complete, update the task description/notes via `./scripts/update-task {task_id}` and determine if it's ready to transition to 'planning' or 'pending'."""
|
- When research is complete, update the task description/notes via `./scripts/update-task {task_id}` and determine if it's ready to transition to 'planning' or 'ready'."""
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Research a task in Documentation/Tasks.md using an AI CLI agent. Requires status to be 'research'."
|
description="Research a task in docs/tasks.md using an AI CLI agent. Requires status to be 'research'."
|
||||||
)
|
)
|
||||||
parser.add_argument("task_id", help="Task number or prefixed ID (e.g. 37, PREFIX-037)")
|
parser.add_argument("task_id", help="Task number or prefixed ID (e.g. 37, PREFIX-037)")
|
||||||
add_common_agent_arguments(parser)
|
add_common_agent_arguments(parser)
|
||||||
|
|||||||
Binary file not shown.
@@ -21,7 +21,7 @@ def tracker(prefix=None, epics=True, number=1):
|
|||||||
label: "Team's Release"
|
label: "Team's Release"
|
||||||
description: 'Ship the product.'
|
description: 'Ship the product.'
|
||||||
""" if epics else ""
|
""" if epics else ""
|
||||||
anchor_prefix = prefix.lower() if prefix else "ot"
|
anchor_prefix = prefix.lower() if prefix else "ex"
|
||||||
return f"""---
|
return f"""---
|
||||||
{prefix_line}projects:
|
{prefix_line}projects:
|
||||||
- value: 'shared'
|
- value: 'shared'
|
||||||
@@ -101,7 +101,7 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_epic_add_update_clear_and_preserve(self):
|
def test_epic_add_update_clear_and_preserve(self):
|
||||||
self.run_cli("add-task", "New task", "--epic", "Proof of Concept", "--subproject", "engine")
|
self.run_cli("add-task", "New task", "--epic", "Proof of Concept", "--subproject", "engine")
|
||||||
task = self.get_task("OT-002")
|
task = self.get_task("EX-002")
|
||||||
self.assertEqual((task["epic"], task["epic_label"]), ("poc", "Proof of Concept"))
|
self.assertEqual((task["epic"], task["epic_label"]), ("poc", "Proof of Concept"))
|
||||||
self.assertEqual(task["subproject"], "engine")
|
self.assertEqual(task["subproject"], "engine")
|
||||||
self.assertIn('data-epic="poc"', task["raw_markdown"])
|
self.assertIn('data-epic="poc"', task["raw_markdown"])
|
||||||
@@ -181,7 +181,7 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
def test_default_prefix_without_epics_and_environment_file(self):
|
def test_default_prefix_without_epics_and_environment_file(self):
|
||||||
self.path.write_text(tracker(epics=False))
|
self.path.write_text(tracker(epics=False))
|
||||||
self.run_cli("update-tasks")
|
self.run_cli("update-tasks")
|
||||||
self.assertEqual(self.get_task()["id"], "OT-001")
|
self.assertEqual(self.get_task()["id"], "EX-001")
|
||||||
self.assertEqual(self.get_task()["epic"], "")
|
self.assertEqual(self.get_task()["epic"], "")
|
||||||
self.assertNotIn("| Epic", self.path.read_text())
|
self.assertNotIn("| Epic", self.path.read_text())
|
||||||
env = {**self.env, "TASKS_FILE": str(self.path)}
|
env = {**self.env, "TASKS_FILE": str(self.path)}
|
||||||
@@ -190,7 +190,7 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
env=env, text=True, capture_output=True,
|
env=env, text=True, capture_output=True,
|
||||||
)
|
)
|
||||||
self.assertEqual(result.returncode, 0, result.stderr)
|
self.assertEqual(result.returncode, 0, result.stderr)
|
||||||
self.assertEqual(result.stdout.strip(), "OT-001")
|
self.assertEqual(result.stdout.strip(), "EX-001")
|
||||||
|
|
||||||
def test_invalid_prefix_and_duplicate_numbers(self):
|
def test_invalid_prefix_and_duplicate_numbers(self):
|
||||||
for prefix in ("", "1BAD", "BAD SPACE", "BAD/"):
|
for prefix in ("", "1BAD", "BAD SPACE", "BAD/"):
|
||||||
@@ -216,7 +216,7 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
self.assertNotIn("<<<<<<<", updated)
|
self.assertNotIn("<<<<<<<", updated)
|
||||||
self.assertNotIn("=======", updated)
|
self.assertNotIn("=======", updated)
|
||||||
self.assertNotIn(">>>>>>>", updated)
|
self.assertNotIn(">>>>>>>", updated)
|
||||||
self.assertIn("OT-001", updated)
|
self.assertIn("EX-001", updated)
|
||||||
self.assertIn("Original", updated)
|
self.assertIn("Original", updated)
|
||||||
|
|
||||||
|
|
||||||
@@ -226,30 +226,30 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
env = {**self.env, "PATH": "/usr/bin:/bin"}
|
env = {**self.env, "PATH": "/usr/bin:/bin"}
|
||||||
output = self.run_cli("get-tasks", "--all", "--sort", "asc", env=env).stdout
|
output = self.run_cli("get-tasks", "--all", "--sort", "asc", env=env).stdout
|
||||||
self.assertIn("Epic", output)
|
self.assertIn("Epic", output)
|
||||||
self.assertLess(output.index("OT-001"), output.index("OT-002"))
|
self.assertLess(output.index("EX-001"), output.index("EX-002"))
|
||||||
output = self.run_cli(
|
output = self.run_cli(
|
||||||
"get-tasks", "--all", "--accept", "Epic:Team's Release", "--select", "ID,Epic", env=env,
|
"get-tasks", "--all", "--accept", "Epic:Team's Release", "--select", "ID,Epic", env=env,
|
||||||
).stdout
|
).stdout
|
||||||
self.assertIn("OT-001", output)
|
self.assertIn("EX-001", output)
|
||||||
self.assertNotIn("OT-002", output)
|
self.assertNotIn("EX-002", output)
|
||||||
self.assertNotIn("Title", output)
|
self.assertNotIn("Title", output)
|
||||||
output = self.run_cli("get-tasks", "--all", "--reject", "Epic:Proof of Concept", env=env).stdout
|
output = self.run_cli("get-tasks", "--all", "--reject", "Epic:Proof of Concept", env=env).stdout
|
||||||
self.assertNotIn("OT-002", output)
|
self.assertNotIn("EX-002", output)
|
||||||
self.assertIn("OT-001", output)
|
self.assertIn("EX-001", output)
|
||||||
for value in ("poc", "POC", "Proof of Concept"):
|
for value in ("poc", "POC", "Proof of Concept"):
|
||||||
with self.subTest(value=value):
|
with self.subTest(value=value):
|
||||||
output = self.run_cli("get-tasks", "--accept", f"Epic:{value}", env=env).stdout
|
output = self.run_cli("get-tasks", "--accept", f"Epic:{value}", env=env).stdout
|
||||||
self.assertIn("OT-002", output)
|
self.assertIn("EX-002", output)
|
||||||
self.assertNotIn("OT-001", output)
|
self.assertNotIn("EX-001", output)
|
||||||
output = self.run_cli("get-tasks", "--all", "--reject", "Epic:poc", env=env).stdout
|
output = self.run_cli("get-tasks", "--all", "--reject", "Epic:poc", env=env).stdout
|
||||||
self.assertNotIn("OT-002", output)
|
self.assertNotIn("EX-002", output)
|
||||||
self.assertIn("OT-001", output)
|
self.assertIn("EX-001", output)
|
||||||
output = self.run_cli(
|
output = self.run_cli(
|
||||||
"get-tasks", "--accept", "Epic:poc,release", "--accept", "Status:Triage", env=env,
|
"get-tasks", "--accept", "Epic:poc,release", "--accept", "Status:Triage", env=env,
|
||||||
).stdout
|
).stdout
|
||||||
self.assertIn("OT-002", output)
|
self.assertIn("EX-002", output)
|
||||||
self.assertNotIn("OT-001", output)
|
self.assertNotIn("EX-001", output)
|
||||||
self.assertNotIn("OT-001", self.run_cli("get-tasks", "--accept", "Epic:missing", env=env).stdout)
|
self.assertNotIn("EX-001", self.run_cli("get-tasks", "--accept", "Epic:missing", env=env).stdout)
|
||||||
|
|
||||||
def test_listing_external_filter_table_selects_epic(self):
|
def test_listing_external_filter_table_selects_epic(self):
|
||||||
self.run_cli("update-tasks")
|
self.run_cli("update-tasks")
|
||||||
@@ -291,6 +291,117 @@ class TaskScriptsTest(unittest.TestCase):
|
|||||||
self.assertIn("- Epic: Proof of Concept (poc)", prompt)
|
self.assertIn("- Epic: Proof of Concept (poc)", prompt)
|
||||||
self.assertIn("--epic=poc", prompt)
|
self.assertIn("--epic=poc", prompt)
|
||||||
|
|
||||||
|
def test_ready_task_can_be_started(self):
|
||||||
|
self.run_cli("update-task", "1", "--status", "ready")
|
||||||
|
self.run_cli("work-on-task", "1", "--start")
|
||||||
|
self.assertEqual(self.get_task()["status"], "in_progress")
|
||||||
|
self.run_cli("work-on-task", "1")
|
||||||
|
|
||||||
|
def test_hyphenated_in_progress_is_already_started(self):
|
||||||
|
self.run_cli("update-task", "1", "--status", "in-progress")
|
||||||
|
before = self.path.read_text()
|
||||||
|
self.run_cli("work-on-task", "1", "--start")
|
||||||
|
self.assertEqual(before, self.path.read_text())
|
||||||
|
|
||||||
|
def test_repository_sample_and_config_are_consistent(self):
|
||||||
|
config = json.loads((SCRIPTS.parent / "project-config.json").read_text())
|
||||||
|
sample = SCRIPTS.parent / "docs" / "tasks.md"
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, str(SCRIPTS / "get-task"), "1", "-f", str(sample), "--json"],
|
||||||
|
env=self.env, text=True, capture_output=True,
|
||||||
|
)
|
||||||
|
self.assertEqual(result.returncode, 0, result.stderr)
|
||||||
|
task = json.loads(result.stdout)
|
||||||
|
self.assertIsInstance(config["name"], str)
|
||||||
|
sys.path.insert(0, str(SCRIPTS / "lib"))
|
||||||
|
try:
|
||||||
|
import task_context
|
||||||
|
update = task_context.load_get_task_module().load_update_tasks_module()
|
||||||
|
finally:
|
||||||
|
sys.path.pop(0)
|
||||||
|
frontmatter = update.read_frontmatter(sample.read_text())
|
||||||
|
project = next(item for item in frontmatter["projects"] if item["value"] == task["project"])
|
||||||
|
self.assertIn(f"**Project:** {project['label']}", task["raw_markdown"])
|
||||||
|
self.assertEqual(task["id"].rsplit("-", 1)[0], update.get_task_id_prefix(frontmatter))
|
||||||
|
copy = Path(self.temp.name) / "sample.md"
|
||||||
|
copy.write_text(sample.read_text())
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, str(SCRIPTS / "update-tasks"), "-f", str(copy)],
|
||||||
|
env=self.env, text=True, capture_output=True,
|
||||||
|
)
|
||||||
|
self.assertEqual(result.returncode, 0, result.stderr)
|
||||||
|
self.assertEqual(sample.read_text(), copy.read_text())
|
||||||
|
|
||||||
|
def test_environment_preserves_external_tracker(self):
|
||||||
|
env = {**self.env, "TASKS_FILE": str(self.path)}
|
||||||
|
result = subprocess.run(
|
||||||
|
["bash", "-c", 'source "$1" >/dev/null; printf "%s\\n" "$TASKS_FILE"; command -v get-task',
|
||||||
|
"bash", str(SCRIPTS / "env.sh")],
|
||||||
|
env=env, text=True, capture_output=True,
|
||||||
|
)
|
||||||
|
self.assertEqual(result.returncode, 0, result.stderr)
|
||||||
|
self.assertEqual(result.stdout.splitlines(), [str(self.path), str(SCRIPTS / "get-task")])
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectConfigTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
sys.path.insert(0, str(SCRIPTS / "lib"))
|
||||||
|
try:
|
||||||
|
import task_context
|
||||||
|
self.context = task_context
|
||||||
|
finally:
|
||||||
|
sys.path.pop(0)
|
||||||
|
self.temp = tempfile.TemporaryDirectory()
|
||||||
|
self.addCleanup(self.temp.cleanup)
|
||||||
|
self.path = Path(self.temp.name) / "project-config.json"
|
||||||
|
self.config = {
|
||||||
|
"name": "The Lighthouse Novel",
|
||||||
|
"description": "A novel about a coastal community.",
|
||||||
|
"commands": {},
|
||||||
|
}
|
||||||
|
self.path.write_text(json.dumps(self.config))
|
||||||
|
|
||||||
|
def test_nonsoftware_configuration_in_prompt(self):
|
||||||
|
task = {
|
||||||
|
"id": "BOOK-001", "title": "Outline chapter one", "project": "manuscript",
|
||||||
|
"status": "triage", "type": "task", "description": "Review the narrative arc.",
|
||||||
|
}
|
||||||
|
with patch.object(self.context, "load_project_config", return_value=self.context.load_project_config(self.path)):
|
||||||
|
prompt = self.context.build_workflow_prompt(task, "triaging", "Outline the chapter")
|
||||||
|
self.assertIn("for The Lighthouse Novel.", prompt)
|
||||||
|
self.assertIn(self.config["description"], prompt)
|
||||||
|
self.assertIn("No commands configured", prompt)
|
||||||
|
self.assertIn("Do not assume this is software", prompt)
|
||||||
|
self.assertIn("AGENTS.md", prompt)
|
||||||
|
|
||||||
|
def test_arbitrary_named_commands_are_guidance(self):
|
||||||
|
self.config["commands"] = {"word-count": "wc -w manuscript.txt"}
|
||||||
|
self.path.write_text(json.dumps(self.config))
|
||||||
|
config = self.context.load_project_config(self.path)
|
||||||
|
task = {"id": "1", "title": "Review", "project": "manuscript", "status": "triage", "type": "task"}
|
||||||
|
with patch.object(self.context, "load_project_config", return_value=config):
|
||||||
|
prompt = self.context.build_workflow_prompt(task, "reviewing", "Review")
|
||||||
|
self.assertIn("- word-count: `wc -w manuscript.txt`", prompt)
|
||||||
|
self.assertIn("not automatically executed", prompt)
|
||||||
|
|
||||||
|
def test_invalid_configuration_is_reported(self):
|
||||||
|
invalid_configs = (
|
||||||
|
[], {}, {**self.config, "name": ""}, {**self.config, "description": None},
|
||||||
|
{**self.config, "commands": []}, {**self.config, "commands": {"test": None}},
|
||||||
|
{**self.config, "commands": {"": "echo ok"}},
|
||||||
|
{**self.config, "commands": {"review": " "}},
|
||||||
|
)
|
||||||
|
for config in invalid_configs:
|
||||||
|
with self.subTest(config=config):
|
||||||
|
self.path.write_text(json.dumps(config))
|
||||||
|
with self.assertRaisesRegex(ValueError, "Project configuration"):
|
||||||
|
self.context.load_project_config(self.path)
|
||||||
|
self.path.write_text("{")
|
||||||
|
with self.assertRaisesRegex(ValueError, "Cannot read project configuration"):
|
||||||
|
self.context.load_project_config(self.path)
|
||||||
|
with self.assertRaisesRegex(ValueError, "Cannot read project configuration"):
|
||||||
|
self.context.load_project_config(self.path.parent / "missing.json")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
"""
|
"""
|
||||||
triage
|
triage
|
||||||
|
|
||||||
Triages a task from Documentation/Tasks.md using an AI CLI agent (Antigravity or Hermes).
|
Triages a task from docs/tasks.md using an AI CLI agent (Antigravity or Hermes).
|
||||||
Validates that the task is in 'planning' or 'triage' status, prepares full
|
Validates that the task is in 'planning' or 'triage' status, prepares full
|
||||||
architectural and task context, and launches the agent interactively.
|
architectural and task context, and launches the agent interactively.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./scripts/triage 094
|
./scripts/triage 094
|
||||||
./scripts/triage OT-120 --hermes
|
./scripts/triage EX-120 --hermes
|
||||||
./scripts/triage 094 --agy
|
./scripts/triage 094 --agy
|
||||||
./scripts/triage --help
|
./scripts/triage --help
|
||||||
"""
|
"""
|
||||||
@@ -28,17 +28,17 @@ from task_context import (
|
|||||||
resolve_selected_agent,
|
resolve_selected_agent,
|
||||||
)
|
)
|
||||||
|
|
||||||
TRIAGE_OBJECTIVES = """- Inspect the codebase to understand the current implementation and scope for this task.
|
TRIAGE_OBJECTIVES = """- Inspect the project materials to understand the current work and scope for this task.
|
||||||
- Clarify ambiguities: ask the user any critical design or scoping questions interactively.
|
- Clarify ambiguities: ask the user any critical design or scoping questions interactively.
|
||||||
- Formulate a clear, actionable checklist of engineering deliverables (- [ ]).
|
- Formulate a clear, actionable checklist of deliverables and review criteria (- [ ]).
|
||||||
- Document any open decisions, architectural considerations, or trade-offs in triage notes.
|
- Document any open decisions, architectural considerations, or trade-offs in triage notes.
|
||||||
- Once scoped, update the task using `./scripts/update-task {task_id}`.
|
- Once scoped, update the task using `./scripts/update-task {task_id}`.
|
||||||
- If ready for implementation, propose moving status to 'pending', or keep in 'triage'/'planning' if awaiting user decisions."""
|
- If ready for implementation, propose moving status to 'ready', or keep in 'triage'/'planning' if awaiting user decisions."""
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Triage a task in Documentation/Tasks.md using an AI CLI agent. Requires status to be 'planning' or 'triage'."
|
description="Triage a task in docs/tasks.md using an AI CLI agent. Requires status to be 'planning' or 'triage'."
|
||||||
)
|
)
|
||||||
parser.add_argument("task_id", help="Task number or prefixed ID (e.g. 94, PREFIX-094)")
|
parser.add_argument("task_id", help="Task number or prefixed ID (e.g. 94, PREFIX-094)")
|
||||||
add_common_agent_arguments(parser)
|
add_common_agent_arguments(parser)
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
"""
|
"""
|
||||||
update-task
|
update-task
|
||||||
|
|
||||||
Modifies metadata, title, and/or description of a specific task in Documentation/Tasks.md
|
Modifies metadata, title, and/or description of a specific task in docs/tasks.md
|
||||||
and automatically synchronizes the document tables and sorting.
|
and automatically synchronizes the document tables and sorting.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./scripts/update-task OT-018 --status pending
|
./scripts/update-task EX-018 --status ready
|
||||||
./scripts/update-task OT-018 --title "Updated Title"
|
./scripts/update-task EX-018 --title "Updated Title"
|
||||||
./scripts/update-task OT-018 --description "New description..."
|
./scripts/update-task EX-018 --description "New description..."
|
||||||
./scripts/update-task OT-018 --append-description "- [ ] Additional checklist item"
|
./scripts/update-task EX-018 --append-description "- [ ] Additional checklist item"
|
||||||
./scripts/update-task OT-018 --check-all
|
./scripts/update-task EX-018 --check-all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
"""
|
"""
|
||||||
update-tasks
|
update-tasks
|
||||||
|
|
||||||
Synchronizes and regenerates Documentation/Tasks.md:
|
Synchronizes and regenerates docs/tasks.md:
|
||||||
1. Parses YAML frontmatter for projects, epics, task-statuses, task-types, and task-id-prefix.
|
1. Parses YAML frontmatter for projects, epics, task-statuses, task-types, and task-id-prefix.
|
||||||
2. Extracts all task chunks and sorts the Detailed Tasks section strictly by numeric task ID.
|
2. Extracts all task chunks and sorts the Detailed Tasks section strictly by numeric task ID.
|
||||||
3. Updates the Detailed Tasks section:
|
3. Updates the Detailed Tasks section:
|
||||||
- Normalizes all task IDs to uniform digit width (minimum 3 digits, e.g. OT-001).
|
- Normalizes all task IDs to uniform digit width (minimum 3 digits, e.g. EX-001).
|
||||||
- Synchronizes task detail blocks (including optional **Epic:**) with anchor tags (SSOT).
|
- Synchronizes task detail blocks (including optional **Epic:**) with anchor tags (SSOT).
|
||||||
4. Re-renders the Overall Progress Table (tasks-list) from the sorted, updated task details:
|
4. Re-renders the Overall Progress Table (tasks-list) from the sorted, updated task details:
|
||||||
- Bold (**Title**) for pending tasks
|
- Bold (**Title**) for pending tasks
|
||||||
- Italic (*Title*) for planning and triage tasks
|
- Italic (*Title*) for planning and triage tasks
|
||||||
- Plain (Title) for fixed/done/other tasks
|
- Plain (Title) for fixed/done/other tasks
|
||||||
- Type column links ([Type](#ot-xxx))
|
- Type column links ([Type](#ex-xxx))
|
||||||
5. Re-renders the metadata derived enum tables at the end of the document:
|
5. Re-renders the metadata derived enum tables at the end of the document:
|
||||||
- Projects (Rendered from frontmatter projects)
|
- Projects (Rendered from frontmatter projects)
|
||||||
- Task Statuses (Rendered from frontmatter task-statuses)
|
- Task Statuses (Rendered from frontmatter task-statuses)
|
||||||
@@ -106,7 +106,7 @@ def read_frontmatter(text):
|
|||||||
|
|
||||||
|
|
||||||
def get_task_id_prefix(fm_data):
|
def get_task_id_prefix(fm_data):
|
||||||
prefix = os.environ.get("TASK_ID_PREFIX", fm_data.get("task-id-prefix", "OT"))
|
prefix = os.environ.get("TASK_ID_PREFIX", fm_data.get("task-id-prefix", "EX"))
|
||||||
if not isinstance(prefix, str) or not re.fullmatch(r"[A-Za-z][A-Za-z0-9_-]*", prefix):
|
if not isinstance(prefix, str) or not re.fullmatch(r"[A-Za-z][A-Za-z0-9_-]*", prefix):
|
||||||
raise ValueError("Task ID prefix must start with a letter and contain only letters, digits, underscores, or hyphens")
|
raise ValueError("Task ID prefix must start with a letter and contain only letters, digits, underscores, or hyphens")
|
||||||
return prefix.upper()
|
return prefix.upper()
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ Validates a task's status for active development, displays its requirements,
|
|||||||
and optionally transitions it to 'in_progress'.
|
and optionally transitions it to 'in_progress'.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
./scripts/work-on-task OT-001
|
./scripts/work-on-task EX-001
|
||||||
./scripts/work-on-task OT-001 --start
|
./scripts/work-on-task EX-001 --start
|
||||||
./scripts/work-on-task OT-001 --force
|
./scripts/work-on-task EX-001 --force
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -24,7 +24,7 @@ def main():
|
|||||||
parser = argparse.ArgumentParser(description="Validate and begin work on a task.")
|
parser = argparse.ArgumentParser(description="Validate and begin work on a task.")
|
||||||
parser.add_argument("task_id", help="Task number or prefixed ID (e.g., 1 or PREFIX-001)")
|
parser.add_argument("task_id", help="Task number or prefixed ID (e.g., 1 or PREFIX-001)")
|
||||||
parser.add_argument("--start", action="store_true", help="Transition status to 'in_progress'")
|
parser.add_argument("--start", action="store_true", help="Transition status to 'in_progress'")
|
||||||
parser.add_argument("--force", action="store_true", help="Proceed even if status is not pending/in_progress")
|
parser.add_argument("--force", action="store_true", help="Proceed even if status is not ready/pending/in_progress")
|
||||||
parser.add_argument("-f", "--file", dest="file", default=None, help="Path to tasks.md")
|
parser.add_argument("-f", "--file", dest="file", default=None, help="Path to tasks.md")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -35,9 +35,7 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
status = task.get("status", "").strip().lower()
|
status = task.get("status", "").strip().lower()
|
||||||
valid_work_statuses = ["pending", "in_progress"]
|
valid_work_statuses = ["ready", "pending", "in_progress", "in-progress"]
|
||||||
invalid_statuses = ["planning", "triage", "research", "done", "cancelled", "blocked"]
|
|
||||||
|
|
||||||
if status not in valid_work_statuses and not args.force:
|
if status not in valid_work_statuses and not args.force:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
f"WARNING: Task {task['id']} is currently in '{task['status']}' status.\n"
|
f"WARNING: Task {task['id']} is currently in '{task['status']}' status.\n"
|
||||||
@@ -56,7 +54,7 @@ def main():
|
|||||||
print("\nRequirements & Description:")
|
print("\nRequirements & Description:")
|
||||||
print(task["description"])
|
print(task["description"])
|
||||||
|
|
||||||
if args.start and status != "in_progress":
|
if args.start and status not in ("in_progress", "in-progress"):
|
||||||
mod = load_get_task_module()
|
mod = load_get_task_module()
|
||||||
update_mod = mod.load_update_tasks_module()
|
update_mod = mod.load_update_tasks_module()
|
||||||
script_dir = Path(__file__).resolve().parent
|
script_dir = Path(__file__).resolve().parent
|
||||||
|
|||||||
Reference in New Issue
Block a user