Scaffold docs, packages, and command registration
- Flesh out docs/index.md, docs/config.md, docs/features/mcp.md, docs/features/kanban.md with full content and aligned tables - Fix .markdownlint-cli2.mjs config (rules were outside 'config' key) - Add packages/mcp as a standalone MCP server package - Update all pubspec descriptions - Implement DewCommand + CommandRegistry in core - Implement KanbanCommand and McpCommand stubs with registerCommands() - Wire CLI entry point using CommandRunner + CommandRegistry - Add 'melos run dew' script for running the CLI from workspace root - Update tests across core, kanban, mcp packages Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
b3201fde7b
commit
0723c7d996
20 changed files with 299 additions and 88 deletions
11
.markdownlint-cli2.mjs
Normal file
11
.markdownlint-cli2.mjs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export default {
|
||||
globs: ['**/*.md'],
|
||||
gitignore: true,
|
||||
config: {
|
||||
MD013: false,
|
||||
MD040: true,
|
||||
MD060: {
|
||||
style: 'aligned',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# Dew Configuration
|
||||
|
||||
Dew is configured via a `dew.yaml` file stored in the `.project/` directory at the root of your project. Running `dew init .` will generate this file with sensible defaults.
|
||||
|
||||
## File Location
|
||||
|
||||
```text
|
||||
your-project/
|
||||
└── .project/
|
||||
└── dew.yaml
|
||||
```
|
||||
|
||||
## Full Schema
|
||||
|
||||
```yaml
|
||||
dew:
|
||||
mcp:
|
||||
host: "localhost" # Hostname the MCP server binds to
|
||||
port: 8080 # Port the MCP server listens on
|
||||
|
||||
kanban:
|
||||
prefix: "PROJ" # Short prefix used for ticket IDs (e.g. PROJ-42)
|
||||
|
||||
ticket_types: # The types of tickets your board supports
|
||||
- id: "epic"
|
||||
name: "Epic"
|
||||
- id: "story"
|
||||
name: "Story"
|
||||
- id: "task"
|
||||
name: "Task"
|
||||
- id: "bug"
|
||||
name: "Bug"
|
||||
- id: "spike"
|
||||
name: "Spike"
|
||||
|
||||
columns: # Ordered list of columns on your Kanban board
|
||||
- id: "todo"
|
||||
name: "To Do"
|
||||
color: "blue"
|
||||
- id: "in-progress"
|
||||
name: "In Progress"
|
||||
color: "yellow"
|
||||
- id: "done"
|
||||
name: "Done"
|
||||
color: "green"
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### `dew.mcp`
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
| ------ | ------- | ------------- | --------------------------------- |
|
||||
| `host` | string | `"localhost"` | Hostname the MCP server binds to. |
|
||||
| `port` | integer | `8080` | Port the MCP server listens on. |
|
||||
|
||||
### `dew.kanban`
|
||||
|
||||
| Field | Type | Description |
|
||||
| -------------- | ------ | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `prefix` | string | Short uppercase prefix prepended to ticket IDs (e.g. `PROJ-1`). |
|
||||
| `ticket_types` | list | The ticket types available on the board. Each entry requires an `id` and a `name`. |
|
||||
| `columns` | list | The columns on the board, in order from left to right. Each entry requires an `id`, a `name`, and a `color`. |
|
||||
|
||||
#### Column colors
|
||||
|
||||
The following named colors are supported for column display:
|
||||
|
||||
`red`, `orange`, `yellow`, `green`, `blue`, `purple`, `pink`, `grey`
|
||||
|
|
@ -2,4 +2,22 @@
|
|||
|
||||
The Dew Model Context Protocol (MCP) Server is a feature that allows AI agents to interact with your project. This enables you to integrate AI capabilities into your project management workflow, such as automated task creation, progress tracking, and more.
|
||||
|
||||
The MCP server is implemented in the `packages/core` package, so other packages can interact with it. You can configure the MCP server's host and port in the `dew.yaml` configuration file under the `mcp` section. By default, the server will run on `localhost` at port `8080`.
|
||||
## Package structure
|
||||
|
||||
The MCP feature is split across two packages to keep concerns separate:
|
||||
|
||||
- **`packages/core`** defines the `McpToolProvider` interface. Any feature package that wants to expose tools to AI agents implements this interface — without needing to depend on the MCP server itself.
|
||||
- **`packages/mcp`** implements the actual server. It collects all registered `McpToolProvider` implementations and serves them over the configured host and port. Only the `cli` package depends on `packages/mcp`; feature packages like `kanban` remain decoupled from the transport layer.
|
||||
|
||||
## Configuration
|
||||
|
||||
The MCP server is configured under the `mcp` key in `.project/dew.yaml`. By default it runs on `localhost` at port `8080`.
|
||||
|
||||
```yaml
|
||||
dew:
|
||||
mcp:
|
||||
host: "localhost"
|
||||
port: 8080
|
||||
```
|
||||
|
||||
See the [Configuration documentation](../config.md) for full details.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
# Dew Documentation
|
||||
|
||||
Welcome to the documentation for the Dew project management tool! This documentation provides an overview of Dew's features, configuration options, and instructions for getting started.
|
||||
Welcome to the documentation for the Dew project management tool!
|
||||
|
||||
## Contents
|
||||
|
||||
- [Configuration](./config.md) — Configuring Dew via `dew.yaml`
|
||||
|
||||
### Features
|
||||
|
||||
- [Kanban Board](./features/kanban.md) — Visualize and manage tasks in a column-based workflow
|
||||
- [MCP Server](./features/mcp.md) — AI agent integration via the Model Context Protocol
|
||||
|
||||
## Package Architecture
|
||||
|
||||
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 types (tickets, columns, config) and the `McpToolProvider` interface. |
|
||||
| `packages/kanban` | Kanban board logic. Implements `McpToolProvider` to expose its tools to the MCP server. |
|
||||
| `packages/mcp` | The MCP server. Depends on `core`; collects and serves registered tools from all packages. |
|
||||
|
||||
`kanban` (and future feature packages) depend only on `core` — not on `mcp` — keeping them usable independently of the AI integration layer. The `cli` package is the only one that depends on `mcp` and is responsible for starting the server and registering all providers.
|
||||
|
|
|
|||
|
|
@ -1,57 +1,21 @@
|
|||
import 'package:args/args.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:dew_kanban/dew_kanban.dart' as kanban;
|
||||
import 'package:dew_mcp/dew_mcp.dart' as mcp;
|
||||
|
||||
const String version = '0.0.1';
|
||||
Future<void> main(List<String> args) async {
|
||||
final registry = CommandRegistry();
|
||||
kanban.registerCommands(registry);
|
||||
mcp.registerCommands(registry);
|
||||
|
||||
ArgParser buildParser() {
|
||||
return ArgParser()
|
||||
..addFlag(
|
||||
'help',
|
||||
abbr: 'h',
|
||||
negatable: false,
|
||||
help: 'Print this usage information.',
|
||||
)
|
||||
..addFlag(
|
||||
'verbose',
|
||||
abbr: 'v',
|
||||
negatable: false,
|
||||
help: 'Show additional command output.',
|
||||
)
|
||||
..addFlag('version', negatable: false, help: 'Print the tool version.');
|
||||
}
|
||||
final runner = CommandRunner<void>(
|
||||
'dew',
|
||||
'A project management tool.',
|
||||
);
|
||||
|
||||
void printUsage(ArgParser argParser) {
|
||||
print('Usage: dart dew.dart <flags> [arguments]');
|
||||
print(argParser.usage);
|
||||
}
|
||||
|
||||
void main(List<String> arguments) {
|
||||
final ArgParser argParser = buildParser();
|
||||
try {
|
||||
final ArgResults results = argParser.parse(arguments);
|
||||
bool verbose = false;
|
||||
|
||||
// Process the parsed arguments.
|
||||
if (results.flag('help')) {
|
||||
printUsage(argParser);
|
||||
return;
|
||||
}
|
||||
if (results.flag('version')) {
|
||||
print('dew version: $version');
|
||||
return;
|
||||
}
|
||||
if (results.flag('verbose')) {
|
||||
verbose = true;
|
||||
}
|
||||
|
||||
// Act on the arguments provided.
|
||||
print('Positional arguments: ${results.rest}');
|
||||
if (verbose) {
|
||||
print('[VERBOSE] All arguments: ${results.arguments}');
|
||||
}
|
||||
} on FormatException catch (e) {
|
||||
// Print usage information if an invalid argument was provided.
|
||||
print(e.message);
|
||||
print('');
|
||||
printUsage(argParser);
|
||||
for (final command in registry.commands) {
|
||||
runner.addCommand(command);
|
||||
}
|
||||
|
||||
await runner.run(args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name: dew
|
||||
description: A sample command-line application with basic argument parsing.
|
||||
description: Command-line interface for the Dew project management tool.
|
||||
version: 0.0.1
|
||||
# repository: https://github.com/my_org/my_repo
|
||||
publish_to: none
|
||||
|
|
@ -10,6 +10,12 @@ environment:
|
|||
|
||||
dependencies:
|
||||
args: ^2.7.0
|
||||
dew_core:
|
||||
path: ../core
|
||||
dew_kanban:
|
||||
path: ../kanban
|
||||
dew_mcp:
|
||||
path: ../mcp
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
/// Support for doing something awesome.
|
||||
///
|
||||
/// More dartdocs go here.
|
||||
library;
|
||||
|
||||
export 'src/dew_core_base.dart';
|
||||
|
||||
// TODO: Export any libraries intended for clients of this package.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
// TODO: Put public facing types in this file.
|
||||
import 'package:args/command_runner.dart';
|
||||
|
||||
/// Checks if you are awesome. Spoiler: you are.
|
||||
class Awesome {
|
||||
bool get isAwesome => true;
|
||||
/// Base class for all Dew CLI commands.
|
||||
///
|
||||
/// Feature packages extend this class to provide their commands, then register
|
||||
/// them via [CommandRegistry] so the CLI can assemble them at startup.
|
||||
abstract class DewCommand extends Command<void> {}
|
||||
|
||||
/// Holds the [DewCommand]s registered by feature packages.
|
||||
///
|
||||
/// The CLI creates an instance, passes it to each package's
|
||||
/// `registerCommands` function, then iterates [commands] to populate a
|
||||
/// [CommandRunner].
|
||||
class CommandRegistry {
|
||||
final List<DewCommand> _commands = [];
|
||||
|
||||
/// Adds [command] to the registry.
|
||||
void register(DewCommand command) => _commands.add(command);
|
||||
|
||||
/// An unmodifiable view of all registered commands.
|
||||
List<DewCommand> get commands => List.unmodifiable(_commands);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name: dew_core
|
||||
description: A starting point for Dart libraries or applications.
|
||||
description: Core shared types, interfaces, and configuration for the Dew project management tool.
|
||||
version: 1.0.0
|
||||
# repository: https://github.com/my_org/my_repo
|
||||
publish_to: none
|
||||
|
|
@ -10,6 +10,7 @@ environment:
|
|||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
args: ^2.7.0
|
||||
path: ^1.9.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
|||
|
|
@ -1,16 +1,33 @@
|
|||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('A group of tests', () {
|
||||
final awesome = Awesome();
|
||||
// Minimal concrete command for testing the registry.
|
||||
class _TestCommand extends DewCommand {
|
||||
@override
|
||||
final String name = 'test-cmd';
|
||||
@override
|
||||
final String description = 'A test command.';
|
||||
@override
|
||||
Future<void> run() async {}
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
// Additional setup goes here.
|
||||
void main() {
|
||||
group('CommandRegistry', () {
|
||||
test('starts empty', () {
|
||||
final registry = CommandRegistry();
|
||||
expect(registry.commands, isEmpty);
|
||||
});
|
||||
|
||||
test('First Test', () {
|
||||
expect(awesome.isAwesome, isTrue);
|
||||
test('register adds a command', () {
|
||||
final registry = CommandRegistry();
|
||||
registry.register(_TestCommand());
|
||||
expect(registry.commands, hasLength(1));
|
||||
expect(registry.commands.first.name, 'test-cmd');
|
||||
});
|
||||
|
||||
test('commands list is unmodifiable', () {
|
||||
final registry = CommandRegistry();
|
||||
expect(() => registry.commands.add(_TestCommand()), throwsUnsupportedError);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
/// Support for doing something awesome.
|
||||
///
|
||||
/// More dartdocs go here.
|
||||
library;
|
||||
|
||||
export 'src/dew_kanban_base.dart';
|
||||
|
||||
// TODO: Export any libraries intended for clients of this package.
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:dew_kanban/src/dew_kanban_base.dart';
|
||||
|
||||
/// Registers all Kanban commands into [registry].
|
||||
void registerCommands(CommandRegistry registry) {
|
||||
registry.register(KanbanCommand());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
// TODO: Put public facing types in this file.
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
|
||||
/// Checks if you are awesome. Spoiler: you are.
|
||||
class Awesome {
|
||||
bool get isAwesome => true;
|
||||
/// Top-level CLI command for all Kanban board operations.
|
||||
class KanbanCommand extends DewCommand {
|
||||
@override
|
||||
final String name = 'kanban';
|
||||
|
||||
@override
|
||||
final String description = 'Manage the Kanban board.';
|
||||
|
||||
@override
|
||||
Future<void> run() async => printUsage();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name: dew_kanban
|
||||
description: A starting point for Dart libraries or applications.
|
||||
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/my_org/my_repo
|
||||
publish_to: none
|
||||
|
|
@ -10,6 +10,8 @@ environment:
|
|||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
dew_core:
|
||||
path: ../core
|
||||
path: ^1.9.0
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
import 'package:dew_kanban/dew_kanban.dart';
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('A group of tests', () {
|
||||
final awesome = Awesome();
|
||||
|
||||
setUp(() {
|
||||
// Additional setup goes here.
|
||||
group('KanbanCommand', () {
|
||||
test('has correct name and description', () {
|
||||
final cmd = KanbanCommand();
|
||||
expect(cmd.name, 'kanban');
|
||||
expect(cmd.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('First Test', () {
|
||||
expect(awesome.isAwesome, isTrue);
|
||||
test('registerCommands adds kanban command to registry', () {
|
||||
final registry = CommandRegistry();
|
||||
registerCommands(registry);
|
||||
expect(registry.commands.map((c) => c.name), contains('kanban'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
7
packages/mcp/.gitignore
vendored
Normal file
7
packages/mcp/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# https://dart.dev/guides/libraries/private-files
|
||||
# Created by `dart pub`
|
||||
.dart_tool/
|
||||
|
||||
# Avoid committing pubspec.lock for library packages; see
|
||||
# https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||
pubspec.lock
|
||||
13
packages/mcp/lib/dew_mcp.dart
Normal file
13
packages/mcp/lib/dew_mcp.dart
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
library;
|
||||
|
||||
export 'src/dew_mcp_base.dart';
|
||||
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:dew_mcp/src/dew_mcp_base.dart';
|
||||
|
||||
/// Registers all MCP commands into [registry].
|
||||
void registerCommands(CommandRegistry registry) {
|
||||
registry.register(McpCommand());
|
||||
}
|
||||
|
||||
// TODO: Export any libraries intended for clients of this package.
|
||||
13
packages/mcp/lib/src/dew_mcp_base.dart
Normal file
13
packages/mcp/lib/src/dew_mcp_base.dart
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import 'package:dew_core/dew_core.dart';
|
||||
|
||||
/// Top-level CLI command for MCP server operations.
|
||||
class McpCommand extends DewCommand {
|
||||
@override
|
||||
final String name = 'mcp';
|
||||
|
||||
@override
|
||||
final String description = 'Manage the MCP server.';
|
||||
|
||||
@override
|
||||
Future<void> run() async => printUsage();
|
||||
}
|
||||
18
packages/mcp/pubspec.yaml
Normal file
18
packages/mcp/pubspec.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
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/my_org/my_repo
|
||||
publish_to: none
|
||||
resolution: workspace
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.4
|
||||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
dew_core:
|
||||
path: ../core
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
test: ^1.25.6
|
||||
19
packages/mcp/test/mcp_test.dart
Normal file
19
packages/mcp/test/mcp_test.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:dew_mcp/dew_mcp.dart';
|
||||
import 'package:dew_core/dew_core.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('McpCommand', () {
|
||||
test('has correct name and description', () {
|
||||
final cmd = McpCommand();
|
||||
expect(cmd.name, 'mcp');
|
||||
expect(cmd.description, isNotEmpty);
|
||||
});
|
||||
|
||||
test('registerCommands adds mcp command to registry', () {
|
||||
final registry = CommandRegistry();
|
||||
registerCommands(registry);
|
||||
expect(registry.commands.map((c) => c.name), contains('mcp'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ workspace:
|
|||
- packages/cli
|
||||
- packages/core
|
||||
- packages/kanban
|
||||
- packages/mcp
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^6.0.0
|
||||
|
|
@ -27,3 +28,9 @@ melos:
|
|||
format:
|
||||
description: Format the workspace.
|
||||
run: dart format .
|
||||
dew:
|
||||
description: >-
|
||||
Run the Dew CLI. Pass subcommands and args directly
|
||||
(e.g. melos run dew kanban). Use 'help <command>' for usage
|
||||
(e.g. melos run dew help kanban).
|
||||
run: dart run packages/cli/bin/dew.dart
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue