chore: prepare v0.1.0 release
This commit is contained in:
parent
7e1e7d0502
commit
07e8c98c7c
37 changed files with 363 additions and 147 deletions
12
.markdownlint-cli2.jsonc
Normal file
12
.markdownlint-cli2.jsonc
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"globs": [
|
||||||
|
"**/*.md"
|
||||||
|
],
|
||||||
|
"gitignore": true,
|
||||||
|
"config": {
|
||||||
|
"MD013": false,
|
||||||
|
"MD060": {
|
||||||
|
"style": "aligned"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
export default {
|
|
||||||
globs: ['**/*.md'],
|
|
||||||
gitignore: true,
|
|
||||||
config: {
|
|
||||||
MD013: false,
|
|
||||||
MD040: true,
|
|
||||||
MD060: {
|
|
||||||
style: 'aligned',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -12,6 +12,7 @@ labels:
|
||||||
Publish all four packages to pub.dev in dependency order, then tag the release.
|
Publish all four packages to pub.dev in dependency order, then tag the release.
|
||||||
|
|
||||||
Order:
|
Order:
|
||||||
|
|
||||||
1. `cd packages/core && dart pub publish`
|
1. `cd packages/core && dart pub publish`
|
||||||
2. `cd packages/kanban && dart pub publish`
|
2. `cd packages/kanban && dart pub publish`
|
||||||
3. `cd packages/mcp && dart pub publish`
|
3. `cd packages/mcp && dart pub publish`
|
||||||
|
|
@ -20,10 +21,11 @@ Order:
|
||||||
Wait for each to appear on pub.dev before publishing the next (pub.dev propagation can take a few minutes).
|
Wait for each to appear on pub.dev before publishing the next (pub.dev propagation can take a few minutes).
|
||||||
|
|
||||||
After all four are published:
|
After all four are published:
|
||||||
|
|
||||||
1. `git checkout main`
|
1. `git checkout main`
|
||||||
2. `git merge develop`
|
2. `git merge develop`
|
||||||
3. `git tag v1.0.0`
|
3. `git tag v1.0.0`
|
||||||
4. `git push origin main --tags`
|
4. `git push origin main --tags`
|
||||||
5. Create GitHub release at https://github.com/artificery-dev/dew/releases with CHANGELOG.md 1.0.0 section as body.
|
5. Create GitHub release at <https://github.com/artificery-dev/dew/releases> with CHANGELOG.md 1.0.0 section as body.
|
||||||
|
|
||||||
Prerequisite: DEW-0027 (final validation) must be done first.
|
Prerequisite: DEW-0027 (final validation) must be done first.
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ links:
|
||||||
type: parent_of
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add freeform milestone and label fields to tickets for grouping and filtering. Both are List<String> in ticket frontmatter.
|
Add freeform milestone and label fields to tickets for grouping and filtering. Both are `List<String>` in ticket frontmatter.
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ links:
|
||||||
type: child_of
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Move ticket .md files from flat .project/kanban/ into column subdirectories (.project/kanban/todo/DEW-0001.md). Attachments live at .project/kanban/attachments/<ticket-id>/ (stable path, unaffected by moves). TicketStore changes: _filePath needs column, findById searches all column dirs, move physically moves the .md file, delete removes .md + attachments/<id>/ if present, create writes into correct column dir.
|
Move ticket .md files from flat .project/kanban/ into column subdirectories (.project/kanban/todo/DEW-0001.md). Attachments live at `.project/kanban/attachments/<ticket-id>/` (stable path, unaffected by moves). TicketStore changes: _filePath needs column, findById searches all column dirs, move physically moves the .md file, delete removes .md + `attachments/<id>/` if present, create writes into correct column dir.
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ links:
|
||||||
type: child_of
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add milestones: List<String> and labels: List<String> to the Ticket model and YAML frontmatter. Support --milestone and --label flags on create/update. Add --label and --milestone filter flags to list and search commands. Depends on storage refactor.
|
Add milestones: `List<String>` and labels: `List<String>` to the Ticket model and YAML frontmatter. Support --milestone and --label flags on create/update. Add --label and --milestone filter flags to list and search commands. Depends on storage refactor.
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ links:
|
||||||
type: child_of
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add `dew kanban archive --id <id>` that moves a ticket to .project/kanban/archive/ (and its attachments stay at attachments/<id>/). Archived tickets excluded from list/search by default; add --include-archived flag to opt in. Depends on storage refactor.
|
Add `dew kanban archive --id <id>` that moves a ticket to .project/kanban/archive/ (and its attachments stay at `attachments/<id>/`). Archived tickets excluded from list/search by default; add --include-archived flag to opt in. Depends on storage refactor.
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ labels:
|
||||||
|
|
||||||
Check that all four package names are available on pub.dev before we invest in publishing prep:
|
Check that all four package names are available on pub.dev before we invest in publishing prep:
|
||||||
|
|
||||||
- https://pub.dev/packages/dew
|
- <https://pub.dev/packages/dew>
|
||||||
- https://pub.dev/packages/dew_core
|
- <https://pub.dev/packages/dew_core>
|
||||||
- https://pub.dev/packages/dew_kanban
|
- <https://pub.dev/packages/dew_kanban>
|
||||||
- https://pub.dev/packages/dew_mcp
|
- <https://pub.dev/packages/dew_mcp>
|
||||||
|
|
||||||
If any name is taken, we need to decide on alternatives (e.g. `dew_cli`, `dew_board`, etc.) and update package names + imports throughout the codebase.
|
If any name is taken, we need to decide on alternatives (e.g. `dew_cli`, `dew_board`, etc.) and update package names + imports throughout the codebase.
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Update all pubspec.yaml files for the 1.0 release:
|
||||||
- All four packages: add `issue_tracker: https://github.com/artificery-dev/dew/issues`
|
- All four packages: add `issue_tracker: https://github.com/artificery-dev/dew/issues`
|
||||||
|
|
||||||
Files to edit:
|
Files to edit:
|
||||||
|
|
||||||
- packages/cli/pubspec.yaml
|
- packages/cli/pubspec.yaml
|
||||||
- packages/core/pubspec.yaml
|
- packages/core/pubspec.yaml
|
||||||
- packages/kanban/pubspec.yaml
|
- packages/kanban/pubspec.yaml
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,13 @@ labels:
|
||||||
pub.dev rejects path dependencies. Switch all inter-package deps to versioned, and use dependency_overrides in the workspace root for local development.
|
pub.dev rejects path dependencies. Switch all inter-package deps to versioned, and use dependency_overrides in the workspace root for local development.
|
||||||
|
|
||||||
Changes needed:
|
Changes needed:
|
||||||
|
|
||||||
- `packages/cli/pubspec.yaml`: change dew_core, dew_kanban, dew_mcp from `path: ../x` to `^1.0.0`
|
- `packages/cli/pubspec.yaml`: change dew_core, dew_kanban, dew_mcp from `path: ../x` to `^1.0.0`
|
||||||
- `packages/kanban/pubspec.yaml`: change dew_core from `path: ../core` to `^1.0.0`
|
- `packages/kanban/pubspec.yaml`: change dew_core from `path: ../core` to `^1.0.0`
|
||||||
- `packages/mcp/pubspec.yaml`: change dew_core from `path: ../core` to `^1.0.0`
|
- `packages/mcp/pubspec.yaml`: change dew_core from `path: ../core` to `^1.0.0`
|
||||||
|
|
||||||
Add to root `pubspec.yaml`:
|
Add to root `pubspec.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
dew_core:
|
dew_core:
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ labels:
|
||||||
Remove `publish_to: none` from all four package pubspec.yaml files so they can be published to pub.dev.
|
Remove `publish_to: none` from all four package pubspec.yaml files so they can be published to pub.dev.
|
||||||
|
|
||||||
Files:
|
Files:
|
||||||
|
|
||||||
- packages/cli/pubspec.yaml
|
- packages/cli/pubspec.yaml
|
||||||
- packages/core/pubspec.yaml
|
- packages/core/pubspec.yaml
|
||||||
- packages/kanban/pubspec.yaml
|
- packages/kanban/pubspec.yaml
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,10 @@ labels:
|
||||||
|
|
||||||
Write /CHANGELOG.md at the repo root covering the full 0.x → 1.0.0 history.
|
Write /CHANGELOG.md at the repo root covering the full 0.x → 1.0.0 history.
|
||||||
|
|
||||||
Format: Keep a Changelog (https://keepachangelog.com/en/1.0.0/)
|
Format: Keep a Changelog (<https://keepachangelog.com/en/1.0.0/>)
|
||||||
|
|
||||||
The 1.0.0 section should cover all major features shipped:
|
The 1.0.0 section should cover all major features shipped:
|
||||||
|
|
||||||
- dew init command
|
- dew init command
|
||||||
- Kanban CLI: create, list, get, update, delete, move, search, comment, archive, unarchive, link, unlink, stats, config
|
- Kanban CLI: create, list, get, update, delete, move, search, comment, archive, unarchive, link, unlink, stats, config
|
||||||
- Kanban TUI: interactive board, column nav, ticket detail, editor modal, search/filter, delete, link, type picker, help overlay, auto-refresh, SIGWINCH resize
|
- Kanban TUI: interactive board, column nav, ticket detail, editor modal, search/filter, delete, link, type picker, help overlay, auto-refresh, SIGWINCH resize
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ labels:
|
||||||
Overhaul /README.md for a compelling 1.0 release page.
|
Overhaul /README.md for a compelling 1.0 release page.
|
||||||
|
|
||||||
Must include:
|
Must include:
|
||||||
|
|
||||||
- Elevator pitch (1-2 sentences: what dew is, who it's for)
|
- Elevator pitch (1-2 sentences: what dew is, who it's for)
|
||||||
- Feature highlights with brief descriptions (Kanban CLI, TUI, MCP server)
|
- Feature highlights with brief descriptions (Kanban CLI, TUI, MCP server)
|
||||||
- Installation: `dart pub global activate dew`
|
- Installation: `dart pub global activate dew`
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ labels:
|
||||||
docs/features/kanban.md currently has zero coverage of `dew kanban tui`. Add a full TUI section.
|
docs/features/kanban.md currently has zero coverage of `dew kanban tui`. Add a full TUI section.
|
||||||
|
|
||||||
The section should include:
|
The section should include:
|
||||||
|
|
||||||
- What the TUI is and how to launch it (`dew kanban tui`)
|
- What the TUI is and how to launch it (`dew kanban tui`)
|
||||||
- Overview of the three modes: Board, Detail, Editor
|
- Overview of the three modes: Board, Detail, Editor
|
||||||
- Full keybinding reference table (mirrors the F1 help overlay):
|
- Full keybinding reference table (mirrors the F1 help overlay):
|
||||||
|
|
|
||||||
|
|
@ -13,28 +13,37 @@ labels:
|
||||||
Create /CONTRIBUTING.md at the repo root.
|
Create /CONTRIBUTING.md at the repo root.
|
||||||
|
|
||||||
Should cover:
|
Should cover:
|
||||||
|
|
||||||
- Prerequisites: Dart SDK ^3.11.4
|
- Prerequisites: Dart SDK ^3.11.4
|
||||||
- Clone & setup:
|
- Clone & setup:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/artificery-dev/dew.git
|
git clone https://github.com/artificery-dev/dew.git
|
||||||
cd dew
|
cd dew
|
||||||
dart pub get
|
dart pub get
|
||||||
```
|
```
|
||||||
|
|
||||||
- Running the CLI locally:
|
- Running the CLI locally:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dart run packages/cli/bin/dew.dart kanban list
|
dart run packages/cli/bin/dew.dart kanban list
|
||||||
```
|
```
|
||||||
|
|
||||||
- Running tests:
|
- Running tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dart test packages/core/test/
|
dart test packages/core/test/
|
||||||
dart test packages/kanban/test/
|
dart test packages/kanban/test/
|
||||||
dart test packages/mcp/test/
|
dart test packages/mcp/test/
|
||||||
```
|
```
|
||||||
|
|
||||||
- Linting and formatting:
|
- Linting and formatting:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dart analyze
|
dart analyze
|
||||||
dart format .
|
dart format .
|
||||||
```
|
```
|
||||||
|
|
||||||
- Branch strategy: feature branches off `develop`, PRs into `develop`, releases merge to `main`
|
- Branch strategy: feature branches off `develop`, PRs into `develop`, releases merge to `main`
|
||||||
- Commit message conventions (reference existing commit style in git log)
|
- Commit message conventions (reference existing commit style in git log)
|
||||||
- How to add a new kanban command (implement DewToolCommand, register in dew_kanban_base.dart)
|
- How to add a new kanban command (implement DewToolCommand, register in dew_kanban_base.dart)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ Add end-to-end integration tests that exercise the full CLI against real temp di
|
||||||
Create packages/cli/test/integration_test.dart (or packages/kanban/test/integration_test.dart).
|
Create packages/cli/test/integration_test.dart (or packages/kanban/test/integration_test.dart).
|
||||||
|
|
||||||
Test flows:
|
Test flows:
|
||||||
|
|
||||||
1. `dew init <tmpdir>` → .project/dew.yaml and .project/kanban/ are created
|
1. `dew init <tmpdir>` → .project/dew.yaml and .project/kanban/ are created
|
||||||
2. `dew kanban create --title "Test" --type task` → ticket file appears in backlog
|
2. `dew kanban create --title "Test" --type task` → ticket file appears in backlog
|
||||||
3. `dew kanban list` → returns the created ticket
|
3. `dew kanban list` → returns the created ticket
|
||||||
|
|
|
||||||
42
CHANGELOG.md
42
CHANGELOG.md
|
|
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [1.0.0] - 2026-04-25
|
## [0.1.0] - 2026-04-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
@ -20,24 +20,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
Full set of kanban subcommands, each also registered as an MCP tool automatically:
|
Full set of kanban subcommands, each also registered as an MCP tool automatically:
|
||||||
|
|
||||||
| Subcommand | Description |
|
| Subcommand | Description |
|
||||||
| ------------ | ------------------------------------------------------------------------ |
|
| ----------- | ---------------------------------------------------------------------------- |
|
||||||
| `create` | Create a new ticket with title, type, column, body, labels, and milestones |
|
| `create` | Create a new ticket with title, type, column, body, labels, and milestones |
|
||||||
| `list` | List tickets filtered by column, type, label, milestone, or archived state |
|
| `list` | List tickets filtered by column, type, label, milestone, or archived state |
|
||||||
| `get` | Fetch a single ticket by ID |
|
| `get` | Fetch a single ticket by ID |
|
||||||
| `update` | Update any field on a ticket (title, type, column, body, labels, milestones) |
|
| `update` | Update any field on a ticket (title, type, column, body, labels, milestones) |
|
||||||
| `delete` | Permanently delete a ticket |
|
| `delete` | Permanently delete a ticket |
|
||||||
| `move` | Move a ticket to a different column (validates column transition rules) |
|
| `move` | Move a ticket to a different column (validates column transition rules) |
|
||||||
| `search` | Full-text search across ticket titles, bodies, and comments |
|
| `search` | Full-text search across ticket titles, bodies, and comments |
|
||||||
| `comment` | Append a comment to a ticket |
|
| `comment` | Append a comment to a ticket |
|
||||||
| `archive` | Soft-delete a ticket by moving it to the archive column |
|
| `archive` | Soft-delete a ticket by moving it to the archive column |
|
||||||
| `unarchive` | Restore an archived ticket to a column |
|
| `unarchive` | Restore an archived ticket to a column |
|
||||||
| `link` | Create a typed bidirectional link between two tickets |
|
| `link` | Create a typed bidirectional link between two tickets |
|
||||||
| `unlink` | Remove a link between two tickets |
|
| `unlink` | Remove a link between two tickets |
|
||||||
| `stats` | Display ticket counts grouped by column and type |
|
| `stats` | Display ticket counts grouped by column and type |
|
||||||
| `board` | Print an ASCII representation of the board |
|
| `board` | Print an ASCII representation of the board |
|
||||||
| `config` | Print the current kanban configuration |
|
| `config` | Print the current kanban configuration |
|
||||||
| `tui` | Launch the interactive terminal UI |
|
| `tui` | Launch the interactive terminal UI |
|
||||||
|
|
||||||
- File-based storage: each ticket is a Markdown file with YAML frontmatter for
|
- File-based storage: each ticket is a Markdown file with YAML frontmatter for
|
||||||
metadata and inline `---` separators for comments. Column is derived from the
|
metadata and inline `---` separators for comments. Column is derived from the
|
||||||
|
|
@ -86,5 +86,5 @@ Full set of kanban subcommands, each also registered as an MCP tool automaticall
|
||||||
- `ProjectDirs` with injectable filesystem abstraction (`package:file`) for
|
- `ProjectDirs` with injectable filesystem abstraction (`package:file`) for
|
||||||
testable path resolution.
|
testable path resolution.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/artificery-dev/dew/compare/v1.0.0...HEAD
|
[Unreleased]: https://github.com/artificerchris/dew/compare/v0.1.0...HEAD
|
||||||
[1.0.0]: https://github.com/artificery-dev/dew/releases/tag/v1.0.0
|
[0.1.0]: https://github.com/artificerchris/dew/releases/tag/v0.1.0
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@ Fix any analysis warnings before opening a PR. The project uses the rules define
|
||||||
|
|
||||||
## Branch strategy
|
## Branch strategy
|
||||||
|
|
||||||
| Branch | Purpose |
|
| Branch | Purpose |
|
||||||
| --------- | ---------------------------------------------------------- |
|
| --------- | ------------------------------------------------------- |
|
||||||
| `main` | Stable, released code. Only merged into from `develop`. |
|
| `main` | Stable, released code. Only merged into from `develop`. |
|
||||||
| `develop` | Integration branch. All PRs target this branch. |
|
| `develop` | Integration branch. All PRs target this branch. |
|
||||||
| `feat/*` | Feature branches cut from `develop`. |
|
| `feat/*` | Feature branches cut from `develop`. |
|
||||||
| `fix/*` | Bug-fix branches cut from `develop`. |
|
| `fix/*` | Bug-fix branches cut from `develop`. |
|
||||||
|
|
||||||
**Workflow:**
|
**Workflow:**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
16 subcommands cover the full lifecycle of a ticket:
|
16 subcommands cover the full lifecycle of a ticket:
|
||||||
|
|
||||||
```
|
```text
|
||||||
create list get update delete move
|
create list get update delete move
|
||||||
search comment archive unarchive link unlink
|
search comment archive unarchive link unlink
|
||||||
stats board config tui
|
stats board config tui
|
||||||
|
|
|
||||||
|
|
@ -51,35 +51,35 @@ Second comment.
|
||||||
|
|
||||||
All commands are available under `dew kanban <subcommand>`.
|
All commands are available under `dew kanban <subcommand>`.
|
||||||
|
|
||||||
| Subcommand | Description |
|
| Subcommand | Description |
|
||||||
| ------------- | ------------------------------------------------------------------------------ |
|
| ----------- | ----------------------------------------------------------------------------------- |
|
||||||
| `create` | Create a new ticket (`--title`, `--type`, `--column`, `--body`) |
|
| `create` | Create a new ticket (`--title`, `--type`, `--column`, `--body`) |
|
||||||
| `list` | List tickets (`--column`, `--type`, `--label`, `--milestone`, `--include-archived`) |
|
| `list` | List tickets (`--column`, `--type`, `--label`, `--milestone`, `--include-archived`) |
|
||||||
| `get` | Get a ticket by ID (`--id`) |
|
| `get` | Get a ticket by ID (`--id`) |
|
||||||
| `update` | Update fields on a ticket (`--id`, `--title`, `--type`, `--column`, `--body`) |
|
| `update` | Update fields on a ticket (`--id`, `--title`, `--type`, `--column`, `--body`) |
|
||||||
| `delete` | Delete a ticket permanently (`--id`) |
|
| `delete` | Delete a ticket permanently (`--id`) |
|
||||||
| `move` | Move a ticket to a different column (`--id`, `--column`) |
|
| `move` | Move a ticket to a different column (`--id`, `--column`) |
|
||||||
| `search` | Full-text search across all ticket content (`--query`, `--include-archived`) |
|
| `search` | Full-text search across all ticket content (`--query`, `--include-archived`) |
|
||||||
| `comment` | Append a comment to a ticket (`--id`, `--comment`) |
|
| `comment` | Append a comment to a ticket (`--id`, `--comment`) |
|
||||||
| `archive` | Soft-delete a ticket by moving it to the archive column (`--id`) |
|
| `archive` | Soft-delete a ticket by moving it to the archive column (`--id`) |
|
||||||
| `unarchive` | Restore an archived ticket to a column (`--id`, `--column`) |
|
| `unarchive` | Restore an archived ticket to a column (`--id`, `--column`) |
|
||||||
| `link` | Link two tickets with a typed relationship (`--id`, `--target`, `--type`) |
|
| `link` | Link two tickets with a typed relationship (`--id`, `--target`, `--type`) |
|
||||||
| `unlink` | Remove a link between two tickets (`--id`, `--target`) |
|
| `unlink` | Remove a link between two tickets (`--id`, `--target`) |
|
||||||
| `stats` | Show ticket counts by column and type |
|
| `stats` | Show ticket counts by column and type |
|
||||||
| `board` | Print an ASCII representation of the board |
|
| `board` | Print an ASCII representation of the board |
|
||||||
| `config` | Print the current kanban configuration |
|
| `config` | Print the current kanban configuration |
|
||||||
| `tui` | Launch the interactive terminal UI |
|
| `tui` | Launch the interactive terminal UI |
|
||||||
|
|
||||||
## Ticket links
|
## Ticket links
|
||||||
|
|
||||||
Links are typed and bidirectional — writing one side automatically writes the inverse on the target.
|
Links are typed and bidirectional — writing one side automatically writes the inverse on the target.
|
||||||
|
|
||||||
| Type | Inverse | Use case |
|
| Type | Inverse | Use case |
|
||||||
| ----------------- | ------------------ | --------------------------------- |
|
| ------------ | ------------------ | -------------------------------- |
|
||||||
| `blocks` | `is_blocked_by` | Dependency between tickets |
|
| `blocks` | `is_blocked_by` | Dependency between tickets |
|
||||||
| `relates_to` | `relates_to` | General relationship (symmetric) |
|
| `relates_to` | `relates_to` | General relationship (symmetric) |
|
||||||
| `duplicates` | `is_duplicated_by` | Duplicate ticket tracking |
|
| `duplicates` | `is_duplicated_by` | Duplicate ticket tracking |
|
||||||
| `parent_of` | `child_of` | Epic → story → task hierarchy |
|
| `parent_of` | `child_of` | Epic → story → task hierarchy |
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
@ -120,41 +120,41 @@ The TUI has three modes. Press **F1** in any mode for a context-sensitive help o
|
||||||
|
|
||||||
### Modes
|
### Modes
|
||||||
|
|
||||||
| Mode | How to enter | How to leave |
|
| Mode | How to enter | How to leave |
|
||||||
| ---------- | ----------------------------------- | ------------------ |
|
| ---------- | ---------------------------------- | ------------------------ |
|
||||||
| **Board** | Default on launch | `q` to quit |
|
| **Board** | Default on launch | `q` to quit |
|
||||||
| **Detail** | Press `Enter` on a ticket in Board | `b` or `Esc` |
|
| **Detail** | Press `Enter` on a ticket in Board | `b` or `Esc` |
|
||||||
| **Editor** | Press `e` in Board or Detail mode | `s` save / `Esc` discard |
|
| **Editor** | Press `e` in Board or Detail mode | `s` save / `Esc` discard |
|
||||||
|
|
||||||
### Keybinding reference
|
### Keybinding reference
|
||||||
|
|
||||||
#### Board mode
|
#### Board mode
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
| --------- | ----------------------------------------------- |
|
| --------- | ------------------------------------------------------ |
|
||||||
| `↑` / `↓` | Navigate tickets within the current column |
|
| `↑` / `↓` | Navigate tickets within the current column |
|
||||||
| `←` / `→` | Switch to the previous / next column |
|
| `←` / `→` | Switch to the previous / next column |
|
||||||
| `<` / `>` | Move the selected ticket to the previous / next column |
|
| `<` / `>` | Move the selected ticket to the previous / next column |
|
||||||
| `Enter` | Open Detail view for the selected ticket |
|
| `Enter` | Open Detail view for the selected ticket |
|
||||||
| `n` | Create a new ticket (opens Editor) |
|
| `n` | Create a new ticket (opens Editor) |
|
||||||
| `e` | Edit the selected ticket (opens Editor) |
|
| `e` | Edit the selected ticket (opens Editor) |
|
||||||
| `a` | Archive the selected ticket |
|
| `a` | Archive the selected ticket |
|
||||||
| `D` | Delete the selected ticket (with confirmation) |
|
| `D` | Delete the selected ticket (with confirmation) |
|
||||||
| `c` | Append a comment to the selected ticket |
|
| `c` | Append a comment to the selected ticket |
|
||||||
| `L` | Link the selected ticket to another ticket |
|
| `L` | Link the selected ticket to another ticket |
|
||||||
| `?` | Open the live filter / search overlay |
|
| `?` | Open the live filter / search overlay |
|
||||||
| `F1` | Toggle the help overlay |
|
| `F1` | Toggle the help overlay |
|
||||||
| `q` | Quit |
|
| `q` | Quit |
|
||||||
|
|
||||||
#### Detail mode
|
#### Detail mode
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
| --------- | ----------------------------- |
|
| ----------- | ------------------------------ |
|
||||||
| `↑` / `↓` | Scroll the ticket content |
|
| `↑` / `↓` | Scroll the ticket content |
|
||||||
| `e` | Edit the ticket (opens Editor) |
|
| `e` | Edit the ticket (opens Editor) |
|
||||||
| `b` / `Esc` | Return to Board mode |
|
| `b` / `Esc` | Return to Board mode |
|
||||||
| `F1` | Toggle the help overlay |
|
| `F1` | Toggle the help overlay |
|
||||||
| `q` | Quit |
|
| `q` | Quit |
|
||||||
|
|
||||||
#### Editor mode
|
#### Editor mode
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,4 +87,3 @@ The following tools are registered by the `kanban` package:
|
||||||
| `is_duplicated_by`| `duplicates` | No |
|
| `is_duplicated_by`| `duplicates` | No |
|
||||||
| `parent_of` | `child_of` | No |
|
| `parent_of` | `child_of` | No |
|
||||||
| `child_of` | `parent_of` | No |
|
| `child_of` | `parent_of` | No |
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,18 +15,18 @@ Welcome to the documentation for the Dew project management tool!
|
||||||
|
|
||||||
Dew is structured as a Dart workspace with the following packages:
|
Dew is structured as a Dart workspace with the following packages:
|
||||||
|
|
||||||
| Package | Description |
|
| Package | Description |
|
||||||
| ----------------- | ----------------------------------------------------------------------------------------------- |
|
| ----------------- | -------------------------------------------------------------------------------------------- |
|
||||||
| `packages/cli` | The `dew` command-line tool. Wires all packages together at startup. |
|
| `packages/cli` | The `dew` command-line tool. Wires all packages together at startup. |
|
||||||
| `packages/core` | Shared foundation: `DewCommand`, `DewToolCommand` mixin, `CommandRegistry`, and `DewConfig`. |
|
| `packages/core` | Shared foundation: `DewCommand`, `DewToolCommand` mixin, `CommandRegistry`, and `DewConfig`. |
|
||||||
| `packages/kanban` | Kanban board logic. Each command automatically registers itself as an MCP tool. |
|
| `packages/kanban` | Kanban board logic. Each command automatically registers itself as an MCP tool. |
|
||||||
| `packages/mcp` | The MCP server. Collects tools from `CommandRegistry` and serves them over stdio. |
|
| `packages/mcp` | The MCP server. Collects tools from `CommandRegistry` and serves them over stdio. |
|
||||||
|
|
||||||
### How commands become MCP tools
|
### How commands become MCP tools
|
||||||
|
|
||||||
Every CLI command that mixes in `DewToolCommand` is automatically registered as an MCP tool — no separate registration needed. The mixin derives the JSON Schema for the tool's input from the command's own `ArgParser`, so argument definitions are written exactly once.
|
Every CLI command that mixes in `DewToolCommand` is automatically registered as an MCP tool — no separate registration needed. The mixin derives the JSON Schema for the tool's input from the command's own `ArgParser`, so argument definitions are written exactly once.
|
||||||
|
|
||||||
```
|
```text
|
||||||
ArgParser definition
|
ArgParser definition
|
||||||
│
|
│
|
||||||
├─► dew kanban create (human CLI)
|
├─► dew kanban create (human CLI)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.0.0 — 2026-04-25
|
## 0.1.0 — 2026-04-25
|
||||||
|
|
||||||
Initial stable release.
|
Initial release.
|
||||||
|
|
||||||
- `dew init` — initialise a Dew project
|
- `dew init` — initialise a Dew project
|
||||||
- `dew kanban` — full kanban board management (16 subcommands + TUI)
|
- `dew kanban` — full kanban board management (16 subcommands + TUI)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
A git-native, file-based project management CLI with a kanban board and MCP server.
|
A git-native, file-based project management CLI with a kanban board and MCP server.
|
||||||
|
|
||||||
See the [full documentation](https://github.com/artificery-dev/dew#readme) for installation, quick-start, and all available commands.
|
See the [full documentation](https://github.com/artificerchris/dew#readme) for installation, quick-start, and all available commands.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
name: dew
|
name: dew
|
||||||
description: Command-line interface for the Dew project management tool.
|
description: Command-line interface for the Dew project management tool.
|
||||||
version: 1.0.0
|
version: 0.1.0
|
||||||
repository: https://github.com/artificery-dev/dew
|
repository: https://github.com/artificerchris/dew
|
||||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -10,9 +10,9 @@ environment:
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
args: ^2.7.0
|
args: ^2.7.0
|
||||||
dew_core: ^1.0.0
|
dew_core: ^0.1.0
|
||||||
dew_kanban: ^1.0.0
|
dew_kanban: ^0.1.0
|
||||||
dew_mcp: ^1.0.0
|
dew_mcp: ^0.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^6.0.0
|
lints: ^6.0.0
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.0.0 — 2026-04-25
|
## 0.1.0 — 2026-04-25
|
||||||
|
|
||||||
Initial stable release.
|
Initial release.
|
||||||
|
|
||||||
- `DewCommand` base class with arg-parser-driven CLI and MCP tool dual-mode
|
- `DewCommand` base class with arg-parser-driven CLI and MCP tool dual-mode
|
||||||
- `DewToolCommand` mixin for commands that expose an MCP tool
|
- `DewToolCommand` mixin for commands that expose an MCP tool
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# dew_core
|
# dew_core
|
||||||
|
|
||||||
Core abstractions for the [Dew](https://github.com/artificery-dev/dew) project management tool.
|
Core abstractions for the [Dew](https://github.com/artificerchris/dew) project management tool.
|
||||||
|
|
||||||
Provides `DewCommand`, `DewToolCommand`, `CommandRegistry`, and `ProjectContext` — the building blocks used by every Dew feature package.
|
Provides `DewCommand`, `DewToolCommand`, `CommandRegistry`, and `ProjectContext` — the building blocks used by every Dew feature package.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
name: dew_core
|
name: dew_core
|
||||||
description: Core shared types, interfaces, and configuration for the Dew project management tool.
|
description: Core shared types, interfaces, and configuration for the Dew project management tool.
|
||||||
version: 1.0.0
|
version: 0.1.0
|
||||||
repository: https://github.com/artificery-dev/dew
|
repository: https://github.com/artificerchris/dew
|
||||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.0.0 — 2026-04-25
|
## 0.1.0 — 2026-04-25
|
||||||
|
|
||||||
Initial stable release.
|
Initial release.
|
||||||
|
|
||||||
- 16 kanban CLI subcommands: `create`, `list`, `move`, `get`, `update`, `delete`, `archive`, `unarchive`, `link`, `unlink`, `comment`, `search`, `board`, `stats`, `config`, `tui`
|
- 16 kanban CLI subcommands: `create`, `list`, `move`, `get`, `update`, `delete`, `archive`, `unarchive`, `link`, `unlink`, `comment`, `search`, `board`, `stats`, `config`, `tui`
|
||||||
- Interactive TUI with board view, ticket detail, inline editor, and help overlay
|
- Interactive TUI with board view, ticket detail, inline editor, and help overlay
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
# dew_kanban
|
# dew_kanban
|
||||||
|
|
||||||
Kanban board feature package for the [Dew](https://github.com/artificery-dev/dew) project management tool.
|
Kanban board feature package for the [Dew](https://github.com/artificerchris/dew) project management tool.
|
||||||
|
|
||||||
Provides all kanban CLI commands (`create`, `list`, `move`, `get`, `update`, `delete`, `archive`, `unarchive`, `link`, `unlink`, `comment`, `search`, `board`, `stats`, `config`, `tui`) plus the interactive terminal UI and MCP tool definitions.
|
Provides all kanban CLI commands (`create`, `list`, `move`, `get`, `update`, `delete`, `archive`, `unarchive`, `link`, `unlink`, `comment`, `search`, `board`, `stats`, `config`, `tui`) plus the interactive terminal UI and MCP tool definitions.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
This package is consumed by the `dew` CLI and `dew_mcp` packages. See the [main README](https://github.com/artificery-dev/dew#readme) for full documentation.
|
This package is consumed by the `dew` CLI and `dew_mcp` packages. See the [main README](https://github.com/artificerchris/dew#readme) for full documentation.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,15 +121,17 @@ class Ticket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf.writeln('---');
|
buf.writeln('---');
|
||||||
if (body.isNotEmpty) {
|
final normalizedBody = _normalizeMarkdownSection(body);
|
||||||
|
if (normalizedBody.isNotEmpty) {
|
||||||
buf.writeln();
|
buf.writeln();
|
||||||
buf.writeln(body);
|
buf.writeln(normalizedBody);
|
||||||
}
|
}
|
||||||
for (final comment in comments) {
|
for (final comment in comments) {
|
||||||
|
final normalizedComment = _normalizeMarkdownSection(comment);
|
||||||
buf.writeln();
|
buf.writeln();
|
||||||
buf.writeln('---');
|
buf.writeln('---');
|
||||||
buf.writeln();
|
buf.writeln();
|
||||||
buf.writeln(comment);
|
buf.writeln(normalizedComment);
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -200,4 +202,119 @@ class Ticket {
|
||||||
if (!needsQuoting) return value;
|
if (!needsQuoting) return value;
|
||||||
return '"${value.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"';
|
return '"${value.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String _normalizeMarkdownSection(String value) {
|
||||||
|
final normalizedNewlines = value
|
||||||
|
.replaceAll('\r\n', '\n')
|
||||||
|
.replaceAll('\r', '\n')
|
||||||
|
.trimRight();
|
||||||
|
if (normalizedNewlines.isEmpty) return '';
|
||||||
|
|
||||||
|
final lines = normalizedNewlines.split('\n');
|
||||||
|
final out = <String>[];
|
||||||
|
var inFence = false;
|
||||||
|
var inListBlock = false;
|
||||||
|
var justClosedFence = false;
|
||||||
|
|
||||||
|
for (final line in lines) {
|
||||||
|
final wasInFence = inFence;
|
||||||
|
final isBlank = line.trim().isEmpty;
|
||||||
|
final isFenceBoundary = _isMarkdownFenceBoundary(line);
|
||||||
|
final isOpeningFence = isFenceBoundary && !wasInFence;
|
||||||
|
final isClosingFence = isFenceBoundary && wasInFence;
|
||||||
|
final isListItem = !wasInFence && _isMarkdownListItem(line);
|
||||||
|
final isListContinuation =
|
||||||
|
!wasInFence &&
|
||||||
|
inListBlock &&
|
||||||
|
!isBlank &&
|
||||||
|
_isMarkdownListContinuation(line);
|
||||||
|
|
||||||
|
if (isBlank && !wasInFence && out.isNotEmpty && out.last.trim().isEmpty) {
|
||||||
|
justClosedFence = false;
|
||||||
|
inListBlock = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (justClosedFence && !isBlank && out.last.trim().isNotEmpty) {
|
||||||
|
out.add('');
|
||||||
|
}
|
||||||
|
justClosedFence = false;
|
||||||
|
|
||||||
|
if (isOpeningFence && out.isNotEmpty && out.last.trim().isNotEmpty) {
|
||||||
|
out.add('');
|
||||||
|
} else if (!isOpeningFence &&
|
||||||
|
isListItem &&
|
||||||
|
!inListBlock &&
|
||||||
|
out.isNotEmpty &&
|
||||||
|
out.last.trim().isNotEmpty) {
|
||||||
|
out.add('');
|
||||||
|
} else if (inListBlock &&
|
||||||
|
!isBlank &&
|
||||||
|
!isListItem &&
|
||||||
|
!isListContinuation &&
|
||||||
|
out.isNotEmpty &&
|
||||||
|
out.last.trim().isNotEmpty) {
|
||||||
|
out.add('');
|
||||||
|
}
|
||||||
|
|
||||||
|
out.add(isOpeningFence ? _fenceLineWithDefaultLanguage(line) : line);
|
||||||
|
|
||||||
|
if (isFenceBoundary) {
|
||||||
|
inFence = !inFence;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClosingFence) {
|
||||||
|
inListBlock = false;
|
||||||
|
justClosedFence = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasInFence || isOpeningFence) {
|
||||||
|
inListBlock = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlank) {
|
||||||
|
inListBlock = false;
|
||||||
|
} else if (isListItem || isListContinuation) {
|
||||||
|
inListBlock = true;
|
||||||
|
} else {
|
||||||
|
inListBlock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join('\n').trimRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _isMarkdownListItem(String line) =>
|
||||||
|
RegExp(r'^( {0,3})(?:[-+*]|\d+[.)])\s+').hasMatch(line);
|
||||||
|
|
||||||
|
static bool _isMarkdownListContinuation(String line) =>
|
||||||
|
line.startsWith(' ') || line.startsWith('\t');
|
||||||
|
|
||||||
|
static String _fenceLineWithDefaultLanguage(String line) {
|
||||||
|
final marker = _markdownFenceMarker(line);
|
||||||
|
if (marker == null) return line;
|
||||||
|
|
||||||
|
final trimmed = line.trimLeft();
|
||||||
|
final info = trimmed.substring(marker.length).trim();
|
||||||
|
if (info.isNotEmpty) return line;
|
||||||
|
|
||||||
|
final indent = line.substring(0, line.length - trimmed.length);
|
||||||
|
return '$indent${marker}text';
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _isMarkdownFenceBoundary(String line) =>
|
||||||
|
_markdownFenceMarker(line) != null;
|
||||||
|
|
||||||
|
static String? _markdownFenceMarker(String line) {
|
||||||
|
final trimmed = line.trimLeft();
|
||||||
|
if (trimmed.startsWith('```')) {
|
||||||
|
return RegExp(r'^`{3,}').stringMatch(trimmed);
|
||||||
|
}
|
||||||
|
if (trimmed.startsWith('~~~')) {
|
||||||
|
return RegExp(r'^~{3,}').stringMatch(trimmed);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
name: dew_kanban
|
name: dew_kanban
|
||||||
description: Kanban board feature for the Dew project management tool. Implements McpToolProvider to expose board tools to the MCP server.
|
description: Kanban board feature for the Dew project management tool. Implements McpToolProvider to expose board tools to the MCP server.
|
||||||
version: 1.0.0
|
version: 0.1.0
|
||||||
repository: https://github.com/artificery-dev/dew
|
repository: https://github.com/artificerchris/dew
|
||||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -10,7 +10,7 @@ environment:
|
||||||
|
|
||||||
# Add regular dependencies here.
|
# Add regular dependencies here.
|
||||||
dependencies:
|
dependencies:
|
||||||
dew_core: ^1.0.0
|
dew_core: ^0.1.0
|
||||||
dart_console: ^4.1.2
|
dart_console: ^4.1.2
|
||||||
file: ^7.0.1
|
file: ^7.0.1
|
||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
|
|
|
||||||
|
|
@ -276,9 +276,89 @@ dew:
|
||||||
expect(parsed.comments, isEmpty);
|
expect(parsed.comments, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('links roundtrip serialisation', () {
|
test('serializes markdown lists with surrounding blank lines', () {
|
||||||
final t = Ticket(
|
final t = Ticket(
|
||||||
id: 'TEST-0003',
|
id: 'TEST-0003',
|
||||||
|
title: 'List spacing',
|
||||||
|
type: 'task',
|
||||||
|
column: 'todo',
|
||||||
|
created: DateTime.utc(2026, 1, 3),
|
||||||
|
body: '''
|
||||||
|
Scope:
|
||||||
|
- First item
|
||||||
|
- Second item
|
||||||
|
Outcome:
|
||||||
|
1. Done
|
||||||
|
2. Verified
|
||||||
|
''',
|
||||||
|
comments: const [
|
||||||
|
'''
|
||||||
|
Notes:
|
||||||
|
- Comment item
|
||||||
|
Next paragraph.
|
||||||
|
''',
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final content = t.toFileContent();
|
||||||
|
expect(
|
||||||
|
content,
|
||||||
|
contains('Scope:\n\n- First item\n- Second item\n\nOutcome:'),
|
||||||
|
);
|
||||||
|
expect(content, contains('Outcome:\n\n1. Done\n2. Verified'));
|
||||||
|
expect(content, contains('Notes:\n\n- Comment item\n\nNext paragraph.'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not alter list-like lines inside fenced code blocks', () {
|
||||||
|
final t = Ticket(
|
||||||
|
id: 'TEST-0004',
|
||||||
|
title: 'Fence spacing',
|
||||||
|
type: 'task',
|
||||||
|
column: 'todo',
|
||||||
|
created: DateTime.utc(2026, 1, 4),
|
||||||
|
body: '''
|
||||||
|
Example:
|
||||||
|
```text
|
||||||
|
- keep this adjacent
|
||||||
|
next line
|
||||||
|
```
|
||||||
|
Then:
|
||||||
|
- Real item
|
||||||
|
''',
|
||||||
|
comments: const [],
|
||||||
|
);
|
||||||
|
|
||||||
|
final content = t.toFileContent();
|
||||||
|
expect(content, contains('Example:\n\n```text'));
|
||||||
|
expect(
|
||||||
|
content,
|
||||||
|
contains('```text\n- keep this adjacent\nnext line\n```\n\nThen:'),
|
||||||
|
);
|
||||||
|
expect(content, contains('Then:\n\n- Real item'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('adds a default language to unlabeled fenced code blocks', () {
|
||||||
|
final t = Ticket(
|
||||||
|
id: 'TEST-0005',
|
||||||
|
title: 'Fence language',
|
||||||
|
type: 'task',
|
||||||
|
column: 'todo',
|
||||||
|
created: DateTime.utc(2026, 1, 5),
|
||||||
|
body: '''
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
plain output
|
||||||
|
```
|
||||||
|
''',
|
||||||
|
comments: const [],
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(t.toFileContent(), contains('Example:\n\n```text\nplain output'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('links roundtrip serialisation', () {
|
||||||
|
final t = Ticket(
|
||||||
|
id: 'TEST-0006',
|
||||||
title: 'Linked',
|
title: 'Linked',
|
||||||
type: 'task',
|
type: 'task',
|
||||||
column: 'todo',
|
column: 'todo',
|
||||||
|
|
@ -300,7 +380,7 @@ dew:
|
||||||
|
|
||||||
test('no links field when links is empty', () {
|
test('no links field when links is empty', () {
|
||||||
final t = Ticket(
|
final t = Ticket(
|
||||||
id: 'TEST-0004',
|
id: 'TEST-0007',
|
||||||
title: 'No links',
|
title: 'No links',
|
||||||
type: 'task',
|
type: 'task',
|
||||||
column: 'todo',
|
column: 'todo',
|
||||||
|
|
@ -313,7 +393,7 @@ dew:
|
||||||
|
|
||||||
test('milestones and labels roundtrip serialisation', () {
|
test('milestones and labels roundtrip serialisation', () {
|
||||||
final t = Ticket(
|
final t = Ticket(
|
||||||
id: 'TEST-0005',
|
id: 'TEST-0008',
|
||||||
title: 'Tagged',
|
title: 'Tagged',
|
||||||
type: 'task',
|
type: 'task',
|
||||||
column: 'todo',
|
column: 'todo',
|
||||||
|
|
@ -330,7 +410,7 @@ dew:
|
||||||
|
|
||||||
test('no milestones/labels fields when empty', () {
|
test('no milestones/labels fields when empty', () {
|
||||||
final t = Ticket(
|
final t = Ticket(
|
||||||
id: 'TEST-0006',
|
id: 'TEST-0009',
|
||||||
title: 'Plain',
|
title: 'Plain',
|
||||||
type: 'task',
|
type: 'task',
|
||||||
column: 'todo',
|
column: 'todo',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 1.0.0 — 2026-04-25
|
## 0.1.0 — 2026-04-25
|
||||||
|
|
||||||
Initial stable release.
|
Initial release.
|
||||||
|
|
||||||
- `DewMcpServer` stdio MCP server exposing all kanban tools
|
- `DewMcpServer` stdio MCP server exposing all kanban tools
|
||||||
- 15 MCP tools covering the full kanban lifecycle
|
- 15 MCP tools covering the full kanban lifecycle
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# dew_mcp
|
# dew_mcp
|
||||||
|
|
||||||
MCP (Model Context Protocol) server package for the [Dew](https://github.com/artificery-dev/dew) project management tool.
|
MCP (Model Context Protocol) server package for the [Dew](https://github.com/artificerchris/dew) project management tool.
|
||||||
|
|
||||||
Exposes all Dew kanban operations as MCP tools so AI assistants (GitHub Copilot, Claude, etc.) can manage your kanban board directly.
|
Exposes all Dew kanban operations as MCP tools so AI assistants (GitHub Copilot, Claude, etc.) can manage your kanban board directly.
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ Exposes all Dew kanban operations as MCP tools so AI assistants (GitHub Copilot,
|
||||||
dew mcp serve
|
dew mcp serve
|
||||||
```
|
```
|
||||||
|
|
||||||
Connect your MCP client to the process via stdio. See the [main README](https://github.com/artificery-dev/dew#readme) for full setup instructions.
|
Connect your MCP client to the process via stdio. See the [main README](https://github.com/artificerchris/dew#readme) for full setup instructions.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
name: dew_mcp
|
name: dew_mcp
|
||||||
description: MCP server for the Dew project management tool. Collects and serves tools registered by feature packages via the McpToolProvider interface.
|
description: MCP server for the Dew project management tool. Collects and serves tools registered by feature packages via the McpToolProvider interface.
|
||||||
version: 1.0.0
|
version: 0.1.0
|
||||||
repository: https://github.com/artificery-dev/dew
|
repository: https://github.com/artificerchris/dew
|
||||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||||
resolution: workspace
|
resolution: workspace
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
@ -10,11 +10,11 @@ environment:
|
||||||
|
|
||||||
# Add regular dependencies here.
|
# Add regular dependencies here.
|
||||||
dependencies:
|
dependencies:
|
||||||
dew_core: ^1.0.0
|
dew_core: ^0.1.0
|
||||||
dart_mcp: ^0.5.0
|
dart_mcp: ^0.5.0
|
||||||
yaml: ^3.1.0
|
yaml: ^3.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^6.0.0
|
lints: ^6.0.0
|
||||||
test: ^1.25.6
|
test: ^1.25.6
|
||||||
dew_kanban: ^1.0.0
|
dew_kanban: ^0.1.0
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
name: dew_workspace
|
name: dew_workspace
|
||||||
description: A Dart workspace for the dew project management tool.
|
description: A Dart workspace for the dew project management tool.
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
# repository: https://github.com/my_org/my_repo
|
repository: https://github.com/artificerchris/dew
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue