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.
|
||||
|
||||
Order:
|
||||
|
||||
1. `cd packages/core && dart pub publish`
|
||||
2. `cd packages/kanban && 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).
|
||||
|
||||
After all four are published:
|
||||
|
||||
1. `git checkout main`
|
||||
2. `git merge develop`
|
||||
3. `git tag v1.0.0`
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ links:
|
|||
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
|
||||
---
|
||||
|
||||
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
|
||||
---
|
||||
|
||||
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
|
||||
---
|
||||
|
||||
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:
|
||||
|
||||
- https://pub.dev/packages/dew
|
||||
- https://pub.dev/packages/dew_core
|
||||
- https://pub.dev/packages/dew_kanban
|
||||
- https://pub.dev/packages/dew_mcp
|
||||
- <https://pub.dev/packages/dew>
|
||||
- <https://pub.dev/packages/dew_core>
|
||||
- <https://pub.dev/packages/dew_kanban>
|
||||
- <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.
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
||||
Files to edit:
|
||||
|
||||
- packages/cli/pubspec.yaml
|
||||
- packages/core/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.
|
||||
|
||||
Changes needed:
|
||||
|
||||
- `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/mcp/pubspec.yaml`: change dew_core from `path: ../core` to `^1.0.0`
|
||||
|
||||
Add to root `pubspec.yaml`:
|
||||
|
||||
```yaml
|
||||
dependency_overrides:
|
||||
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.
|
||||
|
||||
Files:
|
||||
|
||||
- packages/cli/pubspec.yaml
|
||||
- packages/core/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.
|
||||
|
||||
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:
|
||||
|
||||
- dew init command
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ labels:
|
|||
Overhaul /README.md for a compelling 1.0 release page.
|
||||
|
||||
Must include:
|
||||
|
||||
- Elevator pitch (1-2 sentences: what dew is, who it's for)
|
||||
- Feature highlights with brief descriptions (Kanban CLI, TUI, MCP server)
|
||||
- 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.
|
||||
|
||||
The section should include:
|
||||
|
||||
- What the TUI is and how to launch it (`dew kanban tui`)
|
||||
- Overview of the three modes: Board, Detail, Editor
|
||||
- Full keybinding reference table (mirrors the F1 help overlay):
|
||||
|
|
|
|||
|
|
@ -13,28 +13,37 @@ labels:
|
|||
Create /CONTRIBUTING.md at the repo root.
|
||||
|
||||
Should cover:
|
||||
|
||||
- Prerequisites: Dart SDK ^3.11.4
|
||||
- Clone & setup:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/artificery-dev/dew.git
|
||||
cd dew
|
||||
dart pub get
|
||||
```
|
||||
|
||||
- Running the CLI locally:
|
||||
|
||||
```bash
|
||||
dart run packages/cli/bin/dew.dart kanban list
|
||||
```
|
||||
|
||||
- Running tests:
|
||||
|
||||
```bash
|
||||
dart test packages/core/test/
|
||||
dart test packages/kanban/test/
|
||||
dart test packages/mcp/test/
|
||||
```
|
||||
|
||||
- Linting and formatting:
|
||||
|
||||
```bash
|
||||
dart analyze
|
||||
dart format .
|
||||
```
|
||||
|
||||
- Branch strategy: feature branches off `develop`, PRs into `develop`, releases merge to `main`
|
||||
- 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)
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
Test flows:
|
||||
|
||||
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
|
||||
3. `dew kanban list` → returns the created ticket
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.0] - 2026-04-25
|
||||
## [0.1.0] - 2026-04-25
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ 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:
|
||||
|
||||
| Subcommand | Description |
|
||||
| ------------ | ------------------------------------------------------------------------ |
|
||||
| ----------- | ---------------------------------------------------------------------------- |
|
||||
| `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 |
|
||||
| `get` | Fetch a single ticket by ID |
|
||||
|
|
@ -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
|
||||
testable path resolution.
|
||||
|
||||
[Unreleased]: https://github.com/artificery-dev/dew/compare/v1.0.0...HEAD
|
||||
[1.0.0]: https://github.com/artificery-dev/dew/releases/tag/v1.0.0
|
||||
[Unreleased]: https://github.com/artificerchris/dew/compare/v0.1.0...HEAD
|
||||
[0.1.0]: https://github.com/artificerchris/dew/releases/tag/v0.1.0
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ Fix any analysis warnings before opening a PR. The project uses the rules define
|
|||
## Branch strategy
|
||||
|
||||
| Branch | Purpose |
|
||||
| --------- | ---------------------------------------------------------- |
|
||||
| --------- | ------------------------------------------------------- |
|
||||
| `main` | Stable, released code. Only merged into from `develop`. |
|
||||
| `develop` | Integration branch. All PRs target this branch. |
|
||||
| `feat/*` | Feature branches cut from `develop`. |
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
16 subcommands cover the full lifecycle of a ticket:
|
||||
|
||||
```
|
||||
```text
|
||||
create list get update delete move
|
||||
search comment archive unarchive link unlink
|
||||
stats board config tui
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Second comment.
|
|||
All commands are available under `dew kanban <subcommand>`.
|
||||
|
||||
| Subcommand | Description |
|
||||
| ------------- | ------------------------------------------------------------------------------ |
|
||||
| ----------- | ----------------------------------------------------------------------------------- |
|
||||
| `create` | Create a new ticket (`--title`, `--type`, `--column`, `--body`) |
|
||||
| `list` | List tickets (`--column`, `--type`, `--label`, `--milestone`, `--include-archived`) |
|
||||
| `get` | Get a ticket by ID (`--id`) |
|
||||
|
|
@ -75,7 +75,7 @@ All commands are available under `dew kanban <subcommand>`.
|
|||
Links are typed and bidirectional — writing one side automatically writes the inverse on the target.
|
||||
|
||||
| Type | Inverse | Use case |
|
||||
| ----------------- | ------------------ | --------------------------------- |
|
||||
| ------------ | ------------------ | -------------------------------- |
|
||||
| `blocks` | `is_blocked_by` | Dependency between tickets |
|
||||
| `relates_to` | `relates_to` | General relationship (symmetric) |
|
||||
| `duplicates` | `is_duplicated_by` | Duplicate ticket tracking |
|
||||
|
|
@ -121,7 +121,7 @@ The TUI has three modes. Press **F1** in any mode for a context-sensitive help o
|
|||
### Modes
|
||||
|
||||
| Mode | How to enter | How to leave |
|
||||
| ---------- | ----------------------------------- | ------------------ |
|
||||
| ---------- | ---------------------------------- | ------------------------ |
|
||||
| **Board** | Default on launch | `q` to quit |
|
||||
| **Detail** | Press `Enter` on a ticket in Board | `b` or `Esc` |
|
||||
| **Editor** | Press `e` in Board or Detail mode | `s` save / `Esc` discard |
|
||||
|
|
@ -131,7 +131,7 @@ The TUI has three modes. Press **F1** in any mode for a context-sensitive help o
|
|||
#### Board mode
|
||||
|
||||
| Key | Action |
|
||||
| --------- | ----------------------------------------------- |
|
||||
| --------- | ------------------------------------------------------ |
|
||||
| `↑` / `↓` | Navigate tickets within the current column |
|
||||
| `←` / `→` | Switch to the previous / next column |
|
||||
| `<` / `>` | Move the selected ticket to the previous / next column |
|
||||
|
|
@ -149,7 +149,7 @@ The TUI has three modes. Press **F1** in any mode for a context-sensitive help o
|
|||
#### Detail mode
|
||||
|
||||
| Key | Action |
|
||||
| --------- | ----------------------------- |
|
||||
| ----------- | ------------------------------ |
|
||||
| `↑` / `↓` | Scroll the ticket content |
|
||||
| `e` | Edit the ticket (opens Editor) |
|
||||
| `b` / `Esc` | Return to Board mode |
|
||||
|
|
|
|||
|
|
@ -87,4 +87,3 @@ The following tools are registered by the `kanban` package:
|
|||
| `is_duplicated_by`| `duplicates` | No |
|
||||
| `parent_of` | `child_of` | No |
|
||||
| `child_of` | `parent_of` | No |
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Welcome to the documentation for the Dew project management tool!
|
|||
Dew is structured as a Dart workspace with the following packages:
|
||||
|
||||
| Package | Description |
|
||||
| ----------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `packages/cli` | The `dew` command-line tool. Wires all packages together at startup. |
|
||||
| `packages/core` | Shared foundation: `DewCommand`, `DewToolCommand` mixin, `CommandRegistry`, and `DewConfig`. |
|
||||
| `packages/kanban` | Kanban board logic. Each command automatically registers itself as an MCP tool. |
|
||||
|
|
@ -26,7 +26,7 @@ Dew is structured as a Dart workspace with the following packages:
|
|||
|
||||
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
|
||||
│
|
||||
├─► dew kanban create (human CLI)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# 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 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.
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
name: dew
|
||||
description: Command-line interface for the Dew project management tool.
|
||||
version: 1.0.0
|
||||
repository: https://github.com/artificery-dev/dew
|
||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
||||
version: 0.1.0
|
||||
repository: https://github.com/artificerchris/dew
|
||||
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
|
|
@ -10,9 +10,9 @@ environment:
|
|||
|
||||
dependencies:
|
||||
args: ^2.7.0
|
||||
dew_core: ^1.0.0
|
||||
dew_kanban: ^1.0.0
|
||||
dew_mcp: ^1.0.0
|
||||
dew_core: ^0.1.0
|
||||
dew_kanban: ^0.1.0
|
||||
dew_mcp: ^0.1.0
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# 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
|
||||
- `DewToolCommand` mixin for commands that expose an MCP tool
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 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.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
name: dew_core
|
||||
description: Core shared types, interfaces, and configuration for the Dew project management tool.
|
||||
version: 1.0.0
|
||||
repository: https://github.com/artificery-dev/dew
|
||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
||||
version: 0.1.0
|
||||
repository: https://github.com/artificerchris/dew
|
||||
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# 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`
|
||||
- Interactive TUI with board view, ticket detail, inline editor, and help overlay
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# 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.
|
||||
|
||||
## 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
|
||||
|
||||
|
|
|
|||
|
|
@ -121,15 +121,17 @@ class Ticket {
|
|||
}
|
||||
}
|
||||
buf.writeln('---');
|
||||
if (body.isNotEmpty) {
|
||||
final normalizedBody = _normalizeMarkdownSection(body);
|
||||
if (normalizedBody.isNotEmpty) {
|
||||
buf.writeln();
|
||||
buf.writeln(body);
|
||||
buf.writeln(normalizedBody);
|
||||
}
|
||||
for (final comment in comments) {
|
||||
final normalizedComment = _normalizeMarkdownSection(comment);
|
||||
buf.writeln();
|
||||
buf.writeln('---');
|
||||
buf.writeln();
|
||||
buf.writeln(comment);
|
||||
buf.writeln(normalizedComment);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
@ -200,4 +202,119 @@ class Ticket {
|
|||
if (!needsQuoting) return value;
|
||||
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
|
||||
description: Kanban board feature for the Dew project management tool. Implements McpToolProvider to expose board tools to the MCP server.
|
||||
version: 1.0.0
|
||||
repository: https://github.com/artificery-dev/dew
|
||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
||||
version: 0.1.0
|
||||
repository: https://github.com/artificerchris/dew
|
||||
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
|
|
@ -10,7 +10,7 @@ environment:
|
|||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
dew_core: ^1.0.0
|
||||
dew_core: ^0.1.0
|
||||
dart_console: ^4.1.2
|
||||
file: ^7.0.1
|
||||
path: ^1.9.0
|
||||
|
|
|
|||
|
|
@ -276,9 +276,89 @@ dew:
|
|||
expect(parsed.comments, isEmpty);
|
||||
});
|
||||
|
||||
test('links roundtrip serialisation', () {
|
||||
test('serializes markdown lists with surrounding blank lines', () {
|
||||
final t = Ticket(
|
||||
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',
|
||||
type: 'task',
|
||||
column: 'todo',
|
||||
|
|
@ -300,7 +380,7 @@ dew:
|
|||
|
||||
test('no links field when links is empty', () {
|
||||
final t = Ticket(
|
||||
id: 'TEST-0004',
|
||||
id: 'TEST-0007',
|
||||
title: 'No links',
|
||||
type: 'task',
|
||||
column: 'todo',
|
||||
|
|
@ -313,7 +393,7 @@ dew:
|
|||
|
||||
test('milestones and labels roundtrip serialisation', () {
|
||||
final t = Ticket(
|
||||
id: 'TEST-0005',
|
||||
id: 'TEST-0008',
|
||||
title: 'Tagged',
|
||||
type: 'task',
|
||||
column: 'todo',
|
||||
|
|
@ -330,7 +410,7 @@ dew:
|
|||
|
||||
test('no milestones/labels fields when empty', () {
|
||||
final t = Ticket(
|
||||
id: 'TEST-0006',
|
||||
id: 'TEST-0009',
|
||||
title: 'Plain',
|
||||
type: 'task',
|
||||
column: 'todo',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# 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
|
||||
- 15 MCP tools covering the full kanban lifecycle
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 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.
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ Exposes all Dew kanban operations as MCP tools so AI assistants (GitHub Copilot,
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
name: dew_mcp
|
||||
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
|
||||
repository: https://github.com/artificery-dev/dew
|
||||
issue_tracker: https://github.com/artificery-dev/dew/issues
|
||||
version: 0.1.0
|
||||
repository: https://github.com/artificerchris/dew
|
||||
issue_tracker: https://github.com/artificerchris/dew/issues
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
|
|
@ -10,11 +10,11 @@ environment:
|
|||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
dew_core: ^1.0.0
|
||||
dew_core: ^0.1.0
|
||||
dart_mcp: ^0.5.0
|
||||
yaml: ^3.1.0
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
test: ^1.25.6
|
||||
dew_kanban: ^1.0.0
|
||||
dew_kanban: ^0.1.0
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
name: dew_workspace
|
||||
description: A Dart workspace for the dew project management tool.
|
||||
version: 0.1.0
|
||||
# repository: https://github.com/my_org/my_repo
|
||||
repository: https://github.com/artificerchris/dew
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue