backlog.md 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/backlog-darwin-arm64/backlog +0 -0
- package/bin/backlog-darwin-x64/backlog +0 -0
- package/bin/backlog-linux-arm64/backlog +0 -0
- package/{cli → bin/backlog-linux-x64}/backlog +0 -0
- package/bin/backlog-win32-x64/backlog.exe +0 -0
- package/cli.js +62 -0
- package/package.json +57 -46
- package/.backlog/archive/drafts/readme.md +0 -3
- package/.backlog/archive/drafts/task-41 - temporary-test-task.md +0 -13
- package/.backlog/archive/readme.md +0 -6
- package/.backlog/archive/tasks/readme.md +0 -3
- package/.backlog/archive/tasks/task-41 - cli-migrate-terminal-ui-to-bblessed.md +0 -14
- package/.backlog/config.yml +0 -7
- package/.backlog/decisions/readme.md +0 -7
- package/.backlog/docs/readme.md +0 -20
- package/.backlog/drafts/readme.md +0 -3
- package/.backlog/drafts/task-26 - docs-add-board-export-step-to-agent-dod.md +0 -21
- package/.backlog/drafts/task-28 - add-code-of-conduct.md +0 -20
- package/.backlog/drafts/task-30 - create-changelog.md +0 -19
- package/.backlog/milestones/m-0 - project-setup.md +0 -8
- package/.backlog/milestones/m-1 - cli.md +0 -8
- package/.backlog/milestones/m-2 - cli-kanban.md +0 -8
- package/.backlog/milestones/m-3 - gui.md +0 -8
- package/.backlog/milestones/m-4 - gui-kanban.md +0 -8
- package/.backlog/milestones/m-5 - gui-advanced.md +0 -12
- package/.backlog/milestones/readme.md +0 -3
- package/.backlog/readme.md +0 -5
- package/.backlog/tasks/readme.md +0 -37
- package/.backlog/tasks/task-1 - cli-setup-core-project.md +0 -23
- package/.backlog/tasks/task-10 - gui-init-packaging.md +0 -23
- package/.backlog/tasks/task-11 - gui-kanban-board.md +0 -26
- package/.backlog/tasks/task-12 - gui-advanced.md +0 -25
- package/.backlog/tasks/task-13 - cli-add-agent-instruction-prompt.md +0 -53
- package/.backlog/tasks/task-13.1 - cli-agent-instruction-file-selection.md +0 -40
- package/.backlog/tasks/task-14 - gui-introduction-screens.md +0 -21
- package/.backlog/tasks/task-15 - improve-tasks-readme-with-generic-example-and-cli-reference.md +0 -20
- package/.backlog/tasks/task-16 - improve-docs-readme-with-generic-example-and-cli-reference.md +0 -20
- package/.backlog/tasks/task-17 - improve-drafts-readme-with-generic-example-and-cli-reference.md +0 -20
- package/.backlog/tasks/task-18 - improve-decisions-readme-with-generic-example-and-cli-reference.md +0 -20
- package/.backlog/tasks/task-19 - cli-fix-default-task-status-and-remove-draft-from-statuses.md +0 -55
- package/.backlog/tasks/task-2 - cli-core-logic-library.md +0 -28
- package/.backlog/tasks/task-20 - add-agent-guideline-to-mark-tasks-in-progress-on-start.md +0 -32
- package/.backlog/tasks/task-21 - kanban-board-vertical-layout.md +0 -31
- package/.backlog/tasks/task-22 - cli-prevent-double-dash-in-task-filenames.md +0 -24
- package/.backlog/tasks/task-23 - cli-kanban-board-order-tasks-by-id-asc.md +0 -30
- package/.backlog/tasks/task-24 - handle-subtasks-in-the-kanban-view.md +0 -38
- package/.backlog/tasks/task-24.1 - cli-kanban-board-milestone-view.md +0 -19
- package/.backlog/tasks/task-25 - cli-export-kanban-board-to-readme.md +0 -28
- package/.backlog/tasks/task-27 - add-contributing-guidelines.md +0 -27
- package/.backlog/tasks/task-29 - add-github-templates.md +0 -28
- package/.backlog/tasks/task-3 - cli-implement-backlog-init.md +0 -63
- package/.backlog/tasks/task-31 - update-readme-for-open-source.md +0 -26
- package/.backlog/tasks/task-32 - cli-hide-empty-'no-status'-column.md +0 -31
- package/.backlog/tasks/task-33 - cli-export-milestones-board-as-roadmap.md +0 -20
- package/.backlog/tasks/task-34 - split-readme.md-for-users-and-contributors.md +0 -26
- package/.backlog/tasks/task-35 - finalize-package.json-metadata-for-publishing.md +0 -24
- package/.backlog/tasks/task-36 - cli-prompt-for-project-name-in-init.md +0 -24
- package/.backlog/tasks/task-37 - cli-board-view-open-tasks-in-ide.md +0 -19
- package/.backlog/tasks/task-38 - cli-improved-agent-selection-for-init.md +0 -25
- package/.backlog/tasks/task-39 - cli-fix-empty-agent-instruction-files-on-init.md +0 -31
- package/.backlog/tasks/task-4 - cli-task-management-commands.md +0 -28
- package/.backlog/tasks/task-4.1 - cli-task-create.md +0 -27
- package/.backlog/tasks/task-4.10 - use-cli-to-mark-tasks-done.md +0 -51
- package/.backlog/tasks/task-4.11 - docs-add-definition-of-done-to-agent-guidelines.md +0 -23
- package/.backlog/tasks/task-4.12 - cli-handle-task-id-conflicts-across-branches.md +0 -53
- package/.backlog/tasks/task-4.13 - cli-fix-config-command-local-global-logic.md +0 -58
- package/.backlog/tasks/task-4.2 - cli-task-list-view.md +0 -25
- package/.backlog/tasks/task-4.3 - cli-task-edit.md +0 -24
- package/.backlog/tasks/task-4.4 - cli-task-archive-transition.md +0 -27
- package/.backlog/tasks/task-4.5 - cli-init-prompts-for-reporter-name-and-global-local-config.md +0 -28
- package/.backlog/tasks/task-4.6 - cli-add-empty-assignee-array-field-for-new-tasks.md +0 -35
- package/.backlog/tasks/task-4.7 - cli-parse-unquoted-created_date.md +0 -40
- package/.backlog/tasks/task-4.8 - cli-enforce-description-header.md +0 -48
- package/.backlog/tasks/task-4.9 - cli-normalize-task-id-inputs.md +0 -66
- package/.backlog/tasks/task-40 - cli-board-command-defaults-to-view.md +0 -38
- package/.backlog/tasks/task-41 - cli-migrate-terminal-ui-to-bblessed.md +0 -93
- package/.backlog/tasks/task-41.1 - cli-bblessed-init-wizard.md +0 -42
- package/.backlog/tasks/task-41.2 - cli-bblessed-task-view.md +0 -44
- package/.backlog/tasks/task-41.3 - cli-bblessed-doc-view.md +0 -45
- package/.backlog/tasks/task-41.4 - cli-bblessed-board-view.md +0 -49
- package/.backlog/tasks/task-41.5 - cli-audit-remaining-ui-for-bblessed.md +0 -55
- package/.backlog/tasks/task-42 - visual-hierarchy.md +0 -54
- package/.backlog/tasks/task-43 - remove-duplicate-acceptance-criteria-and-style-metadata.md +0 -56
- package/.backlog/tasks/task-44 - checklist-alignment.md +0 -24
- package/.backlog/tasks/task-45 - safe-line-wrapping.md +0 -23
- package/.backlog/tasks/task-46 - split-pane-layout.md +0 -24
- package/.backlog/tasks/task-47 - sticky-header-in-detail-view.md +0 -43
- package/.backlog/tasks/task-48 - footer-hint-line.md +0 -21
- package/.backlog/tasks/task-49 - status-styling.md +0 -53
- package/.backlog/tasks/task-5 - cli-docs-decisions.md +0 -57
- package/.backlog/tasks/task-50 - borders-&-padding.md +0 -22
- package/.backlog/tasks/task-51 - code-path-styling.md +0 -23
- package/.backlog/tasks/task-52 - cli-filter-tasks-list-by-status-or-assignee.md +0 -29
- package/.backlog/tasks/task-6 - cli-packaging.md +0 -65
- package/.backlog/tasks/task-6.1 - cli-local-installation-support-for-bunx-npx.md +0 -49
- package/.backlog/tasks/task-6.2 - cli-github-actions-for-build-&-publish.md +0 -64
- package/.backlog/tasks/task-7 - cli-kanban-view.md +0 -60
- package/.backlog/tasks/task-7.1 - cli-kanban-board-detect-remote-task-status.md +0 -62
- package/.backlog/tasks/task-8 - gui-project-setup.md +0 -21
- package/.backlog/tasks/task-9 - gui-task-crud.md +0 -24
- package/.cursorrules +0 -223
- package/.gitattributes +0 -2
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -15
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -8
- package/.github/workflows/ci.yml +0 -36
- package/.husky/pre-commit +0 -1
- package/AGENTS.md +0 -65
- package/CLAUDE.md +0 -87
- package/CONTRIBUTING.md +0 -19
- package/DEVELOPMENT.md +0 -37
- package/biome.json +0 -31
- package/bun.lock +0 -152
- package/cli/.cursorrules-xh86jabm.md +0 -82
- package/cli/AGENTS-xh86jabm.md +0 -82
- package/cli/CLAUDE-xh86jabm.md +0 -82
- package/cli/cli.js +0 -19622
- package/cli/index.js +0 -2
- package/docs/npm-publishing.md +0 -69
- package/scripts/build.js +0 -73
- package/src/agent-instructions.ts +0 -54
- package/src/board.ts +0 -263
- package/src/cli.ts +0 -806
- package/src/constants/index.ts +0 -48
- package/src/core/backlog.ts +0 -183
- package/src/core/remote-tasks.ts +0 -168
- package/src/file-system/operations.ts +0 -515
- package/src/git/operations.ts +0 -189
- package/src/guidelines/.cursorrules.md +0 -82
- package/src/guidelines/AGENTS.md +0 -82
- package/src/guidelines/CLAUDE.md +0 -82
- package/src/guidelines/index.ts +0 -7
- package/src/index.ts +0 -30
- package/src/markdown/parser.ts +0 -145
- package/src/markdown/serializer.ts +0 -71
- package/src/test/agent-instructions.test.ts +0 -62
- package/src/test/board.test.ts +0 -291
- package/src/test/build.test.ts +0 -28
- package/src/test/checklist.test.ts +0 -273
- package/src/test/cli.test.ts +0 -1300
- package/src/test/code-path.test.ts +0 -204
- package/src/test/core.test.ts +0 -330
- package/src/test/filesystem.test.ts +0 -435
- package/src/test/git.test.ts +0 -26
- package/src/test/heading.test.ts +0 -102
- package/src/test/line-wrapping.test.ts +0 -252
- package/src/test/local-install.test.ts +0 -34
- package/src/test/markdown.test.ts +0 -526
- package/src/test/parallel-loading.test.ts +0 -160
- package/src/test/parent-id-normalization.test.ts +0 -48
- package/src/test/remote-id-conflict.test.ts +0 -60
- package/src/test/status-icon.test.ts +0 -93
- package/src/types/blessed.d.ts +0 -14
- package/src/types/index.ts +0 -55
- package/src/types/raw.d.ts +0 -4
- package/src/ui/board.ts +0 -322
- package/src/ui/checklist.ts +0 -103
- package/src/ui/code-path.ts +0 -113
- package/src/ui/heading.ts +0 -121
- package/src/ui/loading.ts +0 -216
- package/src/ui/status-icon.ts +0 -53
- package/src/ui/task-list.ts +0 -168
- package/src/ui/task-viewer.ts +0 -640
- package/src/ui/tui.ts +0 -301
- package/tsconfig.json +0 -26
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# AI Agent Guidelines
|
|
2
|
-
|
|
3
|
-
*How to collaborate on Backlog.md–driven projects*
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Source of Truth
|
|
8
|
-
- Tasks live under **`.backlog/tasks/`** (drafts under **`.backlog/drafts/`**).
|
|
9
|
-
- Every implementation decision starts with reading the corresponding Markdown task file.
|
|
10
|
-
|
|
11
|
-
## 2. Typical Workflow
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# 1 Identify work
|
|
15
|
-
backlog task list --status "To Do"
|
|
16
|
-
|
|
17
|
-
# 2 Read details
|
|
18
|
-
backlog task view 42
|
|
19
|
-
|
|
20
|
-
# 3 Start work: assign yourself & move column
|
|
21
|
-
backlog task edit 42 -a @ai-bot -s "In Progress"
|
|
22
|
-
|
|
23
|
-
# 4 Break work down if needed
|
|
24
|
-
backlog task create "Refactor DB layer" --parent 42 -a @ai-bot
|
|
25
|
-
|
|
26
|
-
# 5 Complete and mark Done
|
|
27
|
-
backlog task edit 42 -s Done
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## 3. Definition of Done (DOD)
|
|
31
|
-
|
|
32
|
-
A task is **Done** only when **all** of the following hold:
|
|
33
|
-
|
|
34
|
-
1. **Acceptance criteria** checklist in the task file is fully checked.
|
|
35
|
-
2. **Automated tests** (unit + integration) cover new logic and CI passes.
|
|
36
|
-
3. **Static analysis**: linter & formatter succeed (when available).
|
|
37
|
-
4. **Documentation**:
|
|
38
|
-
- Docs updated.
|
|
39
|
-
- Task file appended with a `## Implementation Notes` section summarising approach, trade‑offs and follow‑ups.
|
|
40
|
-
5. **Review**: code reviewed.
|
|
41
|
-
6. **Task hygiene**: status set to **Done** via CLI.
|
|
42
|
-
7. **No regressions**: performance, security and licence checks green.
|
|
43
|
-
|
|
44
|
-
## 4. Recommended Task Anatomy
|
|
45
|
-
|
|
46
|
-
```markdown
|
|
47
|
-
# task‑42 - Add GraphQL resolver
|
|
48
|
-
|
|
49
|
-
## Description
|
|
50
|
-
Short, imperative explanation of the work.
|
|
51
|
-
|
|
52
|
-
## Acceptance Criteria
|
|
53
|
-
- [ ] Resolver returns correct data for happy path
|
|
54
|
-
- [ ] Error response matches REST
|
|
55
|
-
- [ ] P95 latency ≤ 50 ms under 100 RPS
|
|
56
|
-
|
|
57
|
-
## Implementation Notes (only added after working on the task)
|
|
58
|
-
*Created by @ai-bot on 2025‑06‑13*
|
|
59
|
-
|
|
60
|
-
- Added `src/graphql/resolvers/user.ts`
|
|
61
|
-
- Considered DataLoader but deferred
|
|
62
|
-
- Follow‑up: integrate cache layer
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## 5. Handy CLI Commands
|
|
66
|
-
|
|
67
|
-
| Purpose | Command |
|
|
68
|
-
|---------|---------|
|
|
69
|
-
| Create task | `backlog task create "Add OAuth"` |
|
|
70
|
-
| Create sub task | `backlog task create --parent 14 "Add Google auth"` |
|
|
71
|
-
| List tasks | `backlog task list` |
|
|
72
|
-
| View detail | `backlog task 7` |
|
|
73
|
-
| Edit | `backlog task edit 7 -a @sara -l auth,backend` |
|
|
74
|
-
| Archive | `backlog task archive 7` |
|
|
75
|
-
| Draft flow | `backlog draft create "Spike GraphQL"` → `backlog draft promote 3.1` |
|
|
76
|
-
| Demote to draft| `backlog task demote <id>` |
|
|
77
|
-
|
|
78
|
-
## 6. Tips for AI Agents
|
|
79
|
-
- Keep tasks **small, atomic, and testable**; create subtasks liberally.
|
|
80
|
-
- Prefer **idempotent** changes so reruns remain safe.
|
|
81
|
-
- Leave **breadcrumbs** in `## Implementation Notes`; humans may continue your thread.
|
|
82
|
-
- If uncertain, **draft a new task** describing the ambiguity rather than guessing.
|
package/src/guidelines/AGENTS.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# AI Agent Guidelines
|
|
2
|
-
|
|
3
|
-
*How to collaborate on Backlog.md–driven projects*
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Source of Truth
|
|
8
|
-
- Tasks live under **`.backlog/tasks/`** (drafts under **`.backlog/drafts/`**).
|
|
9
|
-
- Every implementation decision starts with reading the corresponding Markdown task file.
|
|
10
|
-
|
|
11
|
-
## 2. Typical Workflow
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# 1 Identify work
|
|
15
|
-
backlog task list --status "To Do"
|
|
16
|
-
|
|
17
|
-
# 2 Read details
|
|
18
|
-
backlog task view 42
|
|
19
|
-
|
|
20
|
-
# 3 Start work: assign yourself & move column
|
|
21
|
-
backlog task edit 42 -a @ai-bot -s "In Progress"
|
|
22
|
-
|
|
23
|
-
# 4 Break work down if needed
|
|
24
|
-
backlog task create "Refactor DB layer" --parent 42 -a @ai-bot
|
|
25
|
-
|
|
26
|
-
# 5 Complete and mark Done
|
|
27
|
-
backlog task edit 42 -s Done
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## 3. Definition of Done (DOD)
|
|
31
|
-
|
|
32
|
-
A task is **Done** only when **all** of the following hold:
|
|
33
|
-
|
|
34
|
-
1. **Acceptance criteria** checklist in the task file is fully checked.
|
|
35
|
-
2. **Automated tests** (unit + integration) cover new logic and CI passes.
|
|
36
|
-
3. **Static analysis**: linter & formatter succeed (when available).
|
|
37
|
-
4. **Documentation**:
|
|
38
|
-
- Docs updated.
|
|
39
|
-
- Task file appended with a `## Implementation Notes` section summarising approach, trade‑offs and follow‑ups.
|
|
40
|
-
5. **Review**: code reviewed.
|
|
41
|
-
6. **Task hygiene**: status set to **Done** via CLI.
|
|
42
|
-
7. **No regressions**: performance, security and licence checks green.
|
|
43
|
-
|
|
44
|
-
## 4. Recommended Task Anatomy
|
|
45
|
-
|
|
46
|
-
```markdown
|
|
47
|
-
# task‑42 - Add GraphQL resolver
|
|
48
|
-
|
|
49
|
-
## Description
|
|
50
|
-
Short, imperative explanation of the work.
|
|
51
|
-
|
|
52
|
-
## Acceptance Criteria
|
|
53
|
-
- [ ] Resolver returns correct data for happy path
|
|
54
|
-
- [ ] Error response matches REST
|
|
55
|
-
- [ ] P95 latency ≤ 50 ms under 100 RPS
|
|
56
|
-
|
|
57
|
-
## Implementation Notes (only added after working on the task)
|
|
58
|
-
*Created by @ai-bot on 2025‑06‑13*
|
|
59
|
-
|
|
60
|
-
- Added `src/graphql/resolvers/user.ts`
|
|
61
|
-
- Considered DataLoader but deferred
|
|
62
|
-
- Follow‑up: integrate cache layer
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## 5. Handy CLI Commands
|
|
66
|
-
|
|
67
|
-
| Purpose | Command |
|
|
68
|
-
|---------|---------|
|
|
69
|
-
| Create task | `backlog task create "Add OAuth"` |
|
|
70
|
-
| Create sub task | `backlog task create --parent 14 "Add Google auth"` |
|
|
71
|
-
| List tasks | `backlog task list` |
|
|
72
|
-
| View detail | `backlog task 7` |
|
|
73
|
-
| Edit | `backlog task edit 7 -a @sara -l auth,backend` |
|
|
74
|
-
| Archive | `backlog task archive 7` |
|
|
75
|
-
| Draft flow | `backlog draft create "Spike GraphQL"` → `backlog draft promote 3.1` |
|
|
76
|
-
| Demote to draft| `backlog task demote <id>` |
|
|
77
|
-
|
|
78
|
-
## 6. Tips for AI Agents
|
|
79
|
-
- Keep tasks **small, atomic, and testable**; create subtasks liberally.
|
|
80
|
-
- Prefer **idempotent** changes so reruns remain safe.
|
|
81
|
-
- Leave **breadcrumbs** in `## Implementation Notes`; humans may continue your thread.
|
|
82
|
-
- If uncertain, **draft a new task** describing the ambiguity rather than guessing.
|
package/src/guidelines/CLAUDE.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# AI Agent Guidelines
|
|
2
|
-
|
|
3
|
-
*How to collaborate on Backlog.md–driven projects*
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Source of Truth
|
|
8
|
-
- Tasks live under **`.backlog/tasks/`** (drafts under **`.backlog/drafts/`**).
|
|
9
|
-
- Every implementation decision starts with reading the corresponding Markdown task file.
|
|
10
|
-
|
|
11
|
-
## 2. Typical Workflow
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
# 1 Identify work
|
|
15
|
-
backlog task list --status "To Do"
|
|
16
|
-
|
|
17
|
-
# 2 Read details
|
|
18
|
-
backlog task view 42
|
|
19
|
-
|
|
20
|
-
# 3 Start work: assign yourself & move column
|
|
21
|
-
backlog task edit 42 -a @ai-bot -s "In Progress"
|
|
22
|
-
|
|
23
|
-
# 4 Break work down if needed
|
|
24
|
-
backlog task create "Refactor DB layer" --parent 42 -a @ai-bot
|
|
25
|
-
|
|
26
|
-
# 5 Complete and mark Done
|
|
27
|
-
backlog task edit 42 -s Done
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## 3. Definition of Done (DOD)
|
|
31
|
-
|
|
32
|
-
A task is **Done** only when **all** of the following hold:
|
|
33
|
-
|
|
34
|
-
1. **Acceptance criteria** checklist in the task file is fully checked.
|
|
35
|
-
2. **Automated tests** (unit + integration) cover new logic and CI passes.
|
|
36
|
-
3. **Static analysis**: linter & formatter succeed (when available).
|
|
37
|
-
4. **Documentation**:
|
|
38
|
-
- Docs updated.
|
|
39
|
-
- Task file appended with a `## Implementation Notes` section summarising approach, trade‑offs and follow‑ups.
|
|
40
|
-
5. **Review**: code reviewed.
|
|
41
|
-
6. **Task hygiene**: status set to **Done** via CLI.
|
|
42
|
-
7. **No regressions**: performance, security and licence checks green.
|
|
43
|
-
|
|
44
|
-
## 4. Recommended Task Anatomy
|
|
45
|
-
|
|
46
|
-
```markdown
|
|
47
|
-
# task‑42 - Add GraphQL resolver
|
|
48
|
-
|
|
49
|
-
## Description
|
|
50
|
-
Short, imperative explanation of the work.
|
|
51
|
-
|
|
52
|
-
## Acceptance Criteria
|
|
53
|
-
- [ ] Resolver returns correct data for happy path
|
|
54
|
-
- [ ] Error response matches REST
|
|
55
|
-
- [ ] P95 latency ≤ 50 ms under 100 RPS
|
|
56
|
-
|
|
57
|
-
## Implementation Notes (only added after working on the task)
|
|
58
|
-
*Created by @ai-bot on 2025‑06‑13*
|
|
59
|
-
|
|
60
|
-
- Added `src/graphql/resolvers/user.ts`
|
|
61
|
-
- Considered DataLoader but deferred
|
|
62
|
-
- Follow‑up: integrate cache layer
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## 5. Handy CLI Commands
|
|
66
|
-
|
|
67
|
-
| Purpose | Command |
|
|
68
|
-
|---------|---------|
|
|
69
|
-
| Create task | `backlog task create "Add OAuth"` |
|
|
70
|
-
| Create sub task | `backlog task create --parent 14 "Add Google auth"` |
|
|
71
|
-
| List tasks | `backlog task list` |
|
|
72
|
-
| View detail | `backlog task 7` |
|
|
73
|
-
| Edit | `backlog task edit 7 -a @sara -l auth,backend` |
|
|
74
|
-
| Archive | `backlog task archive 7` |
|
|
75
|
-
| Draft flow | `backlog draft create "Spike GraphQL"` → `backlog draft promote 3.1` |
|
|
76
|
-
| Demote to draft| `backlog task demote <id>` |
|
|
77
|
-
|
|
78
|
-
## 6. Tips for AI Agents
|
|
79
|
-
- Keep tasks **small, atomic, and testable**; create subtasks liberally.
|
|
80
|
-
- Prefer **idempotent** changes so reruns remain safe.
|
|
81
|
-
- Leave **breadcrumbs** in `## Implementation Notes`; humans may continue your thread.
|
|
82
|
-
- If uncertain, **draft a new task** describing the ambiguity rather than guessing.
|
package/src/guidelines/index.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import CURSOR_GUIDELINES from "./.cursorrules.md";
|
|
2
|
-
import AGENT_GUIDELINES from "./AGENTS.md";
|
|
3
|
-
import CLAUDE_GUIDELINES from "./CLAUDE.md";
|
|
4
|
-
|
|
5
|
-
const README_GUIDELINES = `## AI Agent Guidelines\n\n${AGENT_GUIDELINES.replace(/^#.*\n/, "")}`;
|
|
6
|
-
|
|
7
|
-
export { AGENT_GUIDELINES, CLAUDE_GUIDELINES, CURSOR_GUIDELINES, README_GUIDELINES };
|
package/src/index.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Types
|
|
2
|
-
export * from "./types/index.ts";
|
|
3
|
-
|
|
4
|
-
// Constants
|
|
5
|
-
export * from "./constants/index.ts";
|
|
6
|
-
|
|
7
|
-
// Markdown operations
|
|
8
|
-
export * from "./markdown/parser.ts";
|
|
9
|
-
export * from "./markdown/serializer.ts";
|
|
10
|
-
|
|
11
|
-
// File system operations
|
|
12
|
-
export { FileSystem } from "./file-system/operations.ts";
|
|
13
|
-
|
|
14
|
-
// Git operations
|
|
15
|
-
export {
|
|
16
|
-
GitOperations,
|
|
17
|
-
isGitRepository,
|
|
18
|
-
initializeGitRepository,
|
|
19
|
-
} from "./git/operations.ts";
|
|
20
|
-
|
|
21
|
-
// Core entry point
|
|
22
|
-
export { Core } from "./core/backlog.ts";
|
|
23
|
-
|
|
24
|
-
// Kanban board utilities
|
|
25
|
-
export { generateKanbanBoard, exportKanbanBoardToFile } from "./board.ts";
|
|
26
|
-
export {
|
|
27
|
-
addAgentInstructions,
|
|
28
|
-
type AgentInstructionFile,
|
|
29
|
-
_loadAgentGuideline,
|
|
30
|
-
} from "./agent-instructions.ts";
|
package/src/markdown/parser.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import matter from "gray-matter";
|
|
2
|
-
import type { DecisionLog, Document, ParsedMarkdown, Task } from "../types/index.ts";
|
|
3
|
-
|
|
4
|
-
function preprocessFrontmatter(frontmatter: string): string {
|
|
5
|
-
return frontmatter
|
|
6
|
-
.split("\n")
|
|
7
|
-
.map((line) => {
|
|
8
|
-
// Handle both assignee and reporter fields that start with @
|
|
9
|
-
const match = line.match(/^(\s*(?:assignee|reporter):\s*)(.*)$/);
|
|
10
|
-
if (!match) return line;
|
|
11
|
-
|
|
12
|
-
const [, prefix, raw] = match;
|
|
13
|
-
const value = raw.trim();
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
value &&
|
|
17
|
-
!value.startsWith("[") &&
|
|
18
|
-
!value.startsWith("'") &&
|
|
19
|
-
!value.startsWith('"') &&
|
|
20
|
-
!value.startsWith("-")
|
|
21
|
-
) {
|
|
22
|
-
return `${prefix}"${value.replace(/"/g, '\\"')}"`;
|
|
23
|
-
}
|
|
24
|
-
return line;
|
|
25
|
-
})
|
|
26
|
-
.join("\n");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function normalizeDate(value: unknown): string {
|
|
30
|
-
if (!value) return "";
|
|
31
|
-
if (value instanceof Date) {
|
|
32
|
-
return value.toISOString().slice(0, 10);
|
|
33
|
-
}
|
|
34
|
-
const str = String(value)
|
|
35
|
-
.trim()
|
|
36
|
-
.replace(/^['"]|['"]$/g, "");
|
|
37
|
-
if (!str) return "";
|
|
38
|
-
let match: RegExpMatchArray | null = str.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
39
|
-
if (match) {
|
|
40
|
-
return `${match[1]}-${match[2]}-${match[3]}`;
|
|
41
|
-
}
|
|
42
|
-
match = str.match(/^(\d{2})-(\d{2})-(\d{2})$/);
|
|
43
|
-
if (match) {
|
|
44
|
-
const [day, month, year] = match.slice(1);
|
|
45
|
-
return `20${year}-${month}-${day}`;
|
|
46
|
-
}
|
|
47
|
-
match = str.match(/^(\d{2})\/(\d{2})\/(\d{2})$/);
|
|
48
|
-
if (match) {
|
|
49
|
-
const [day, month, year] = match.slice(1);
|
|
50
|
-
return `20${year}-${month}-${day}`;
|
|
51
|
-
}
|
|
52
|
-
match = str.match(/^(\d{2})\.(\d{2})\.(\d{2})$/);
|
|
53
|
-
if (match) {
|
|
54
|
-
const [day, month, year] = match.slice(1);
|
|
55
|
-
return `20${year}-${month}-${day}`;
|
|
56
|
-
}
|
|
57
|
-
return str;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function parseMarkdown(content: string): ParsedMarkdown {
|
|
61
|
-
const fmRegex = /^---\n([\s\S]*?)\n---/;
|
|
62
|
-
const match = content.match(fmRegex);
|
|
63
|
-
let toParse = content;
|
|
64
|
-
|
|
65
|
-
if (match) {
|
|
66
|
-
const processed = preprocessFrontmatter(match[1]);
|
|
67
|
-
toParse = content.replace(fmRegex, `---\n${processed}\n---`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const parsed = matter(toParse);
|
|
71
|
-
return {
|
|
72
|
-
frontmatter: parsed.data,
|
|
73
|
-
content: parsed.content.trim(),
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function parseTask(content: string): Task {
|
|
78
|
-
const { frontmatter, content: description } = parseMarkdown(content);
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
id: String(frontmatter.id || ""),
|
|
82
|
-
title: String(frontmatter.title || ""),
|
|
83
|
-
status: String(frontmatter.status || ""),
|
|
84
|
-
assignee: Array.isArray(frontmatter.assignee)
|
|
85
|
-
? frontmatter.assignee.map(String)
|
|
86
|
-
: frontmatter.assignee
|
|
87
|
-
? [String(frontmatter.assignee)]
|
|
88
|
-
: [],
|
|
89
|
-
reporter: frontmatter.reporter ? String(frontmatter.reporter) : undefined,
|
|
90
|
-
createdDate: normalizeDate(frontmatter.created_date),
|
|
91
|
-
updatedDate: frontmatter.updated_date ? normalizeDate(frontmatter.updated_date) : undefined,
|
|
92
|
-
labels: Array.isArray(frontmatter.labels) ? frontmatter.labels.map(String) : [],
|
|
93
|
-
milestone: frontmatter.milestone ? String(frontmatter.milestone) : undefined,
|
|
94
|
-
dependencies: Array.isArray(frontmatter.dependencies) ? frontmatter.dependencies.map(String) : [],
|
|
95
|
-
description: description,
|
|
96
|
-
acceptanceCriteria: extractAcceptanceCriteria(description),
|
|
97
|
-
parentTaskId: frontmatter.parent_task_id ? String(frontmatter.parent_task_id) : undefined,
|
|
98
|
-
subtasks: Array.isArray(frontmatter.subtasks) ? frontmatter.subtasks.map(String) : undefined,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function parseDecisionLog(content: string): DecisionLog {
|
|
103
|
-
const { frontmatter, content: body } = parseMarkdown(content);
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
id: String(frontmatter.id || ""),
|
|
107
|
-
title: String(frontmatter.title || ""),
|
|
108
|
-
date: normalizeDate(frontmatter.date),
|
|
109
|
-
status: String(frontmatter.status || "proposed") as DecisionLog["status"],
|
|
110
|
-
context: extractSection(body, "Context") || "",
|
|
111
|
-
decision: extractSection(body, "Decision") || "",
|
|
112
|
-
consequences: extractSection(body, "Consequences") || "",
|
|
113
|
-
alternatives: extractSection(body, "Alternatives"),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function parseDocument(content: string): Document {
|
|
118
|
-
const { frontmatter, content: body } = parseMarkdown(content);
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
id: String(frontmatter.id || ""),
|
|
122
|
-
title: String(frontmatter.title || ""),
|
|
123
|
-
type: String(frontmatter.type || "other") as Document["type"],
|
|
124
|
-
createdDate: normalizeDate(frontmatter.created_date),
|
|
125
|
-
updatedDate: frontmatter.updated_date ? normalizeDate(frontmatter.updated_date) : undefined,
|
|
126
|
-
content: body,
|
|
127
|
-
tags: Array.isArray(frontmatter.tags) ? frontmatter.tags.map(String) : undefined,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function extractAcceptanceCriteria(content: string): string[] {
|
|
132
|
-
const criteriaSection = extractSection(content, "Acceptance Criteria");
|
|
133
|
-
if (!criteriaSection) return [];
|
|
134
|
-
|
|
135
|
-
return criteriaSection
|
|
136
|
-
.split("\n")
|
|
137
|
-
.filter((line) => line.trim().startsWith("- [ ]") || line.trim().startsWith("- [x]"))
|
|
138
|
-
.map((line) => line.trim().replace(/^- \[[ x]\] /, ""));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function extractSection(content: string, sectionTitle: string): string | undefined {
|
|
142
|
-
const regex = new RegExp(`## ${sectionTitle}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`, "i");
|
|
143
|
-
const match = content.match(regex);
|
|
144
|
-
return match?.[1]?.trim();
|
|
145
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import matter from "gray-matter";
|
|
2
|
-
import type { DecisionLog, Document, Task } from "../types/index.ts";
|
|
3
|
-
|
|
4
|
-
export function serializeTask(task: Task): string {
|
|
5
|
-
const frontmatter = {
|
|
6
|
-
id: task.id,
|
|
7
|
-
title: task.title,
|
|
8
|
-
status: task.status,
|
|
9
|
-
assignee: task.assignee,
|
|
10
|
-
...(task.reporter && { reporter: task.reporter }),
|
|
11
|
-
created_date: task.createdDate,
|
|
12
|
-
...(task.updatedDate && { updated_date: task.updatedDate }),
|
|
13
|
-
labels: task.labels,
|
|
14
|
-
...(task.milestone && { milestone: task.milestone }),
|
|
15
|
-
dependencies: task.dependencies,
|
|
16
|
-
...(task.parentTaskId && { parent_task_id: task.parentTaskId }),
|
|
17
|
-
...(task.subtasks && task.subtasks.length > 0 && { subtasks: task.subtasks }),
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const serialized = matter.stringify(task.description, frontmatter);
|
|
21
|
-
// Ensure there's a blank line between frontmatter and content
|
|
22
|
-
return serialized.replace(/^(---\n(?:.*\n)*?---)\n(?!$)/, "$1\n\n");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function serializeDecisionLog(decision: DecisionLog): string {
|
|
26
|
-
const frontmatter = {
|
|
27
|
-
id: decision.id,
|
|
28
|
-
title: decision.title,
|
|
29
|
-
date: decision.date,
|
|
30
|
-
status: decision.status,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
let content = `## Context\n\n${decision.context}\n\n`;
|
|
34
|
-
content += `## Decision\n\n${decision.decision}\n\n`;
|
|
35
|
-
content += `## Consequences\n\n${decision.consequences}`;
|
|
36
|
-
|
|
37
|
-
if (decision.alternatives) {
|
|
38
|
-
content += `\n\n## Alternatives\n\n${decision.alternatives}`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return matter.stringify(content, frontmatter);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function serializeDocument(document: Document): string {
|
|
45
|
-
const frontmatter = {
|
|
46
|
-
id: document.id,
|
|
47
|
-
title: document.title,
|
|
48
|
-
type: document.type,
|
|
49
|
-
created_date: document.createdDate,
|
|
50
|
-
...(document.updatedDate && { updated_date: document.updatedDate }),
|
|
51
|
-
...(document.tags && document.tags.length > 0 && { tags: document.tags }),
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return matter.stringify(document.content, frontmatter);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function updateTaskAcceptanceCriteria(content: string, criteria: string[]): string {
|
|
58
|
-
// Find if there's already an Acceptance Criteria section
|
|
59
|
-
const criteriaRegex = /## Acceptance Criteria\s*\n([\s\S]*?)(?=\n## |$)/i;
|
|
60
|
-
const match = content.match(criteriaRegex);
|
|
61
|
-
|
|
62
|
-
const newCriteria = criteria.map((criterion) => `- [ ] ${criterion}`).join("\n");
|
|
63
|
-
const newSection = `## Acceptance Criteria\n\n${newCriteria}`;
|
|
64
|
-
|
|
65
|
-
if (match) {
|
|
66
|
-
// Replace existing section
|
|
67
|
-
return content.replace(criteriaRegex, newSection);
|
|
68
|
-
}
|
|
69
|
-
// Add new section at the end
|
|
70
|
-
return `${content}\n\n${newSection}`;
|
|
71
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdir, rm } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import {
|
|
5
|
-
AGENT_GUIDELINES,
|
|
6
|
-
CLAUDE_GUIDELINES,
|
|
7
|
-
CURSOR_GUIDELINES,
|
|
8
|
-
README_GUIDELINES,
|
|
9
|
-
addAgentInstructions,
|
|
10
|
-
} from "../index.ts";
|
|
11
|
-
import { _loadAgentGuideline } from "../index.ts";
|
|
12
|
-
|
|
13
|
-
const TEST_DIR = join(process.cwd(), "test-agents");
|
|
14
|
-
|
|
15
|
-
describe("addAgentInstructions", () => {
|
|
16
|
-
beforeEach(async () => {
|
|
17
|
-
await rm(TEST_DIR, { recursive: true, force: true });
|
|
18
|
-
await mkdir(TEST_DIR, { recursive: true });
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
afterEach(async () => {
|
|
22
|
-
await rm(TEST_DIR, { recursive: true, force: true });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("creates guideline files when none exist", async () => {
|
|
26
|
-
await addAgentInstructions(TEST_DIR);
|
|
27
|
-
const agents = await Bun.file(join(TEST_DIR, "AGENTS.md")).text();
|
|
28
|
-
const claude = await Bun.file(join(TEST_DIR, "CLAUDE.md")).text();
|
|
29
|
-
const cursor = await Bun.file(join(TEST_DIR, ".cursorrules")).text();
|
|
30
|
-
expect(agents).toBe(await _loadAgentGuideline(AGENT_GUIDELINES));
|
|
31
|
-
expect(claude).toBe(await _loadAgentGuideline(CLAUDE_GUIDELINES));
|
|
32
|
-
expect(cursor).toBe(await _loadAgentGuideline(CURSOR_GUIDELINES));
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("appends guideline files when they already exist", async () => {
|
|
36
|
-
await Bun.write(join(TEST_DIR, "AGENTS.md"), "Existing\n");
|
|
37
|
-
await addAgentInstructions(TEST_DIR);
|
|
38
|
-
const agents = await Bun.file(join(TEST_DIR, "AGENTS.md")).text();
|
|
39
|
-
expect(agents.startsWith("Existing\n")).toBe(true);
|
|
40
|
-
expect(agents.trimEnd()).toBe(`Existing\n${await _loadAgentGuideline(AGENT_GUIDELINES)}`.trimEnd());
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("creates only selected files", async () => {
|
|
44
|
-
await addAgentInstructions(TEST_DIR, undefined, ["AGENTS.md", "readme.md"]);
|
|
45
|
-
|
|
46
|
-
const agentsExists = await Bun.file(join(TEST_DIR, "AGENTS.md")).exists();
|
|
47
|
-
const claudeExists = await Bun.file(join(TEST_DIR, "CLAUDE.md")).exists();
|
|
48
|
-
const cursorExists = await Bun.file(join(TEST_DIR, ".cursorrules")).exists();
|
|
49
|
-
const readme = await Bun.file(join(TEST_DIR, "readme.md")).text();
|
|
50
|
-
|
|
51
|
-
expect(agentsExists).toBe(true);
|
|
52
|
-
expect(claudeExists).toBe(false);
|
|
53
|
-
expect(cursorExists).toBe(false);
|
|
54
|
-
expect(readme.trim()).toBe((await _loadAgentGuideline(README_GUIDELINES)).trim());
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("loads guideline content from file paths", async () => {
|
|
58
|
-
const pathGuideline = join(__dirname, "../guidelines/AGENTS.md");
|
|
59
|
-
const content = await _loadAgentGuideline(pathGuideline);
|
|
60
|
-
expect(content).toContain("AI Agent Guidelines");
|
|
61
|
-
});
|
|
62
|
-
});
|