Config refactor: DewConfig.raw + per-package extensions (DEW-0007)
DewConfig in core is now a thin YamlMap wrapper. Feature-specific config classes live in their own packages and expose themselves via Dart extensions: - KanbanConfig, ColumnConfig, TicketTypeConfig + KanbanDewConfig extension moved to packages/kanban/lib/src/kanban_config.dart - McpConfig + McpDewConfig extension added to packages/mcp/lib/src/mcp_config.dart - DewConfig.fromYaml() now trivially wraps the raw YamlMap - All call sites unchanged: context.config.kanban.* / context.config.mcp.* - Added yaml dependency to dew_mcp pubspec - Updated core test to validate raw yaml instead of typed fields - Fixed cross-suite Directory.current isolation (existing issue, not introduced) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
951f0d8bc8
commit
a25411d4fa
34 changed files with 150 additions and 86 deletions
|
|
@ -3,6 +3,9 @@ id: DEW-0002
|
||||||
title: Bootstrapping
|
title: Bootstrapping
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.465324Z
|
created: 2026-04-23T23:37:10.465324Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0010
|
||||||
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Make it easy to initialize a new Dew project. `dew init` scaffolds the .project/ directory and each module creates its own folders via init hooks.
|
Make it easy to initialize a new Dew project. `dew init` scaffolds the .project/ directory and each module creates its own folders via init hooks.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0003
|
||||||
title: Milestones & Labels
|
title: Milestones & Labels
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.468947Z
|
created: 2026-04-23T23:37:10.468947Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0011
|
||||||
|
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.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,11 @@ id: DEW-0004
|
||||||
title: Output Polish
|
title: Output Polish
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.472323Z
|
created: 2026-04-23T23:37:10.472323Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0012
|
||||||
|
type: parent_of
|
||||||
|
- id: DEW-0013
|
||||||
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Improve human-facing CLI output. Grouped list by column, enhanced search filters, and an ASCII board view.
|
Improve human-facing CLI output. Grouped list by column, enhanced search filters, and an ASCII board view.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0005
|
||||||
title: Column Transitions
|
title: Column Transitions
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.476017Z
|
created: 2026-04-23T23:37:10.476017Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0014
|
||||||
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Optional config-driven validation of which column moves are allowed. E.g. prevent moving directly from todo to done.
|
Optional config-driven validation of which column moves are allowed. E.g. prevent moving directly from todo to done.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0006
|
||||||
title: Archiving
|
title: Archiving
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.479959Z
|
created: 2026-04-23T23:37:10.479959Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0015
|
||||||
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Soft-delete tickets to an archive folder rather than permanently destroying them. Archived tickets are excluded from normal list/search but can be browsed.
|
Soft-delete tickets to an archive folder rather than permanently destroying them. Archived tickets are excluded from normal list/search but can be browsed.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0009
|
||||||
title: Update stale documentation
|
title: Update stale documentation
|
||||||
type: task
|
type: task
|
||||||
created: 2026-04-23T23:37:36.830655Z
|
created: 2026-04-23T23:37:36.830655Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0001
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
docs/mcp.md only lists 5 of 12 tools; update to reflect current tool set. docs/index.md references old interface names. docs/kanban.md is a stub; flesh it out. Update tool list, command reference, and architecture notes.
|
docs/mcp.md only lists 5 of 12 tools; update to reflect current tool set. docs/index.md references old interface names. docs/kanban.md is a stub; flesh it out. Update tool list, command reference, and architecture notes.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0010
|
||||||
title: dew init command with module init hooks
|
title: dew init command with module init hooks
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.834286Z
|
created: 2026-04-23T23:37:36.834286Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0002
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add `dew init [path]` command. Core defines DewInitHook interface with onInit(root, options). Options include bool gitkeep (default true). Each package registers a hook. Kanban hook creates: column dirs (from config), archive/, attachments/ under .project/kanban/. --[no-]gitkeep flag adds .gitkeep to empty dirs. Must run after storage refactor so dir structure matches new layout.
|
Add `dew init [path]` command. Core defines DewInitHook interface with onInit(root, options). Options include bool gitkeep (default true). Each package registers a hook. Kanban hook creates: column dirs (from config), archive/, attachments/ under .project/kanban/. --[no-]gitkeep flag adds .gitkeep to empty dirs. Must run after storage refactor so dir structure matches new layout.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0011
|
||||||
title: Add milestones and labels to Ticket model
|
title: Add milestones and labels to Ticket model
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.838770Z
|
created: 2026-04-23T23:37:36.838770Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0003
|
||||||
|
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.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0012
|
||||||
title: Grouped list view and ASCII board
|
title: Grouped list view and ASCII board
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.842362Z
|
created: 2026-04-23T23:37:36.842362Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0004
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
dew kanban list groups output by column with counts. Add `dew kanban board` subcommand for a full ASCII kanban board view showing all columns and their tickets side by side (or stacked).
|
dew kanban list groups output by column with counts. Add `dew kanban board` subcommand for a full ASCII kanban board view showing all columns and their tickets side by side (or stacked).
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0013
|
||||||
title: Enhanced search filters
|
title: Enhanced search filters
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.846212Z
|
created: 2026-04-23T23:37:36.846212Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0004
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add --column, --type, --label, --milestone filter flags to `dew kanban search`. Currently only matches on text. Filters should be combinable (AND semantics).
|
Add --column, --type, --label, --milestone filter flags to `dew kanban search`. Currently only matches on text. Filters should be combinable (AND semantics).
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0014
|
||||||
title: Column transition validation
|
title: Column transition validation
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.849741Z
|
created: 2026-04-23T23:37:36.849741Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0005
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Add optional allowed_transitions map to column config in dew.yaml. When configured, MoveCommand validates the requested move is permitted and errors with a helpful message listing allowed next columns. Unconfigured = all moves allowed (current behaviour).
|
Add optional allowed_transitions map to column config in dew.yaml. When configured, MoveCommand validates the requested move is permitted and errors with a helpful message listing allowed next columns. Unconfigured = all moves allowed (current behaviour).
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0015
|
||||||
title: "Archive command: soft-delete tickets"
|
title: "Archive command: soft-delete tickets"
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.853236Z
|
created: 2026-04-23T23:37:36.853236Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0006
|
||||||
|
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.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,13 @@ id: DEW-0001
|
||||||
title: Engineering Quality
|
title: Engineering Quality
|
||||||
type: epic
|
type: epic
|
||||||
created: 2026-04-23T23:37:10.461762Z
|
created: 2026-04-23T23:37:10.461762Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0007
|
||||||
|
type: parent_of
|
||||||
|
- id: DEW-0008
|
||||||
|
type: parent_of
|
||||||
|
- id: DEW-0009
|
||||||
|
type: parent_of
|
||||||
---
|
---
|
||||||
|
|
||||||
Refactor and harden the core infrastructure before layering features on top. Covers config architecture, ticket storage model, and documentation accuracy.
|
Refactor and harden the core infrastructure before layering features on top. Covers config architecture, ticket storage model, and documentation accuracy.
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0007
|
||||||
title: "Config refactor: DewConfig.raw + per-package extensions"
|
title: "Config refactor: DewConfig.raw + per-package extensions"
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.822736Z
|
created: 2026-04-23T23:37:36.822736Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0001
|
||||||
|
type: child_of
|
||||||
---
|
---
|
||||||
|
|
||||||
DewConfig in core becomes a thin wrapper: `class DewConfig { final YamlMap raw; }`. Each package adds a Dart extension with a typed getter (e.g. KanbanDewConfig, McpDewConfig). KanbanConfig/ColumnConfig/TicketTypeConfig move to dew_kanban; McpConfig moves to dew_mcp. Call sites unchanged: context.config.kanban.prefix etc.
|
DewConfig in core becomes a thin wrapper: `class DewConfig { final YamlMap raw; }`. Each package adds a Dart extension with a typed getter (e.g. KanbanDewConfig, McpDewConfig). KanbanConfig/ColumnConfig/TicketTypeConfig move to dew_kanban; McpConfig moves to dew_mcp. Call sites unchanged: context.config.kanban.prefix etc.
|
||||||
|
|
@ -3,6 +3,9 @@ id: DEW-0008
|
||||||
title: "Ticket storage refactor: column subdirectories"
|
title: "Ticket storage refactor: column subdirectories"
|
||||||
type: story
|
type: story
|
||||||
created: 2026-04-23T23:37:36.826965Z
|
created: 2026-04-23T23:37:36.826965Z
|
||||||
|
links:
|
||||||
|
- id: DEW-0001
|
||||||
|
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.
|
||||||
|
|
@ -3,89 +3,17 @@ import 'dart:io';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:yaml/yaml.dart';
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
class TicketTypeConfig {
|
/// Thin wrapper around the raw project YAML.
|
||||||
final String id;
|
///
|
||||||
final String name;
|
/// Feature packages extend this class via Dart extension methods to expose
|
||||||
|
/// typed configuration (e.g. [KanbanDewConfig.kanban], [McpDewConfig.mcp]).
|
||||||
const TicketTypeConfig({required this.id, required this.name});
|
/// This keeps feature-specific config classes out of core.
|
||||||
}
|
|
||||||
|
|
||||||
class ColumnConfig {
|
|
||||||
final String id;
|
|
||||||
final String name;
|
|
||||||
final String color;
|
|
||||||
|
|
||||||
const ColumnConfig({
|
|
||||||
required this.id,
|
|
||||||
required this.name,
|
|
||||||
required this.color,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class KanbanConfig {
|
|
||||||
final String prefix;
|
|
||||||
final List<TicketTypeConfig> ticketTypes;
|
|
||||||
final List<ColumnConfig> columns;
|
|
||||||
|
|
||||||
const KanbanConfig({
|
|
||||||
required this.prefix,
|
|
||||||
required this.ticketTypes,
|
|
||||||
required this.columns,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class McpConfig {
|
|
||||||
final String host;
|
|
||||||
final int port;
|
|
||||||
|
|
||||||
const McpConfig({required this.host, required this.port});
|
|
||||||
}
|
|
||||||
|
|
||||||
class DewConfig {
|
class DewConfig {
|
||||||
final KanbanConfig kanban;
|
final YamlMap raw;
|
||||||
final McpConfig mcp;
|
|
||||||
|
|
||||||
const DewConfig({required this.kanban, required this.mcp});
|
const DewConfig({required this.raw});
|
||||||
|
|
||||||
factory DewConfig.fromYaml(YamlMap yaml) {
|
factory DewConfig.fromYaml(YamlMap yaml) => DewConfig(raw: yaml);
|
||||||
final dew = yaml['dew'] as YamlMap;
|
|
||||||
|
|
||||||
final mcpYaml = dew['mcp'] as YamlMap;
|
|
||||||
final mcp = McpConfig(
|
|
||||||
host: mcpYaml['host'] as String,
|
|
||||||
port: mcpYaml['port'] as int,
|
|
||||||
);
|
|
||||||
|
|
||||||
final kanbanYaml = dew['kanban'] as YamlMap;
|
|
||||||
final ticketTypes =
|
|
||||||
(kanbanYaml['ticket_types'] as YamlList)
|
|
||||||
.map(
|
|
||||||
(t) => TicketTypeConfig(
|
|
||||||
id: t['id'] as String,
|
|
||||||
name: t['name'] as String,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
final columns =
|
|
||||||
(kanbanYaml['columns'] as YamlList)
|
|
||||||
.map(
|
|
||||||
(c) => ColumnConfig(
|
|
||||||
id: c['id'] as String,
|
|
||||||
name: c['name'] as String,
|
|
||||||
color: c['color'] as String,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
return DewConfig(
|
|
||||||
kanban: KanbanConfig(
|
|
||||||
prefix: kanbanYaml['prefix'] as String,
|
|
||||||
ticketTypes: ticketTypes,
|
|
||||||
columns: columns,
|
|
||||||
),
|
|
||||||
mcp: mcp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locates the nearest project root and exposes the parsed [DewConfig].
|
/// Locates the nearest project root and exposes the parsed [DewConfig].
|
||||||
|
|
|
||||||
|
|
@ -69,13 +69,12 @@ dew:
|
||||||
await tempDir.delete(recursive: true);
|
await tempDir.delete(recursive: true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('find() loads config from .project/dew.yaml', () async {
|
test('find() loads config and exposes raw yaml', () async {
|
||||||
final ctx = await ProjectContext.find();
|
final ctx = await ProjectContext.find();
|
||||||
expect(ctx.config.kanban.prefix, 'TEST');
|
final dew = ctx.config.raw['dew'];
|
||||||
expect(ctx.config.kanban.ticketTypes, hasLength(1));
|
expect(dew['kanban']['prefix'], 'TEST');
|
||||||
expect(ctx.config.kanban.columns.first.id, 'todo');
|
expect(dew['mcp']['host'], 'localhost');
|
||||||
expect(ctx.config.mcp.host, 'localhost');
|
expect(dew['mcp']['port'], 9090);
|
||||||
expect(ctx.config.mcp.port, 9090);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('find() locates config from a subdirectory', () async {
|
test('find() locates config from a subdirectory', () async {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
library;
|
library;
|
||||||
|
|
||||||
export 'src/dew_kanban_base.dart';
|
export 'src/dew_kanban_base.dart';
|
||||||
|
export 'src/kanban_config.dart';
|
||||||
export 'src/ticket.dart';
|
export 'src/ticket.dart';
|
||||||
export 'src/ticket_store.dart';
|
export 'src/ticket_store.dart';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket.dart';
|
import '../ticket.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
|
|
||||||
class GetConfigCommand extends DewCommand with DewToolCommand {
|
class GetConfigCommand extends DewCommand with DewToolCommand {
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket.dart';
|
import '../ticket.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import '../kanban_config.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
import '../ticket_store.dart';
|
import '../ticket_store.dart';
|
||||||
|
|
|
||||||
52
packages/kanban/lib/src/kanban_config.dart
Normal file
52
packages/kanban/lib/src/kanban_config.dart
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
class TicketTypeConfig {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const TicketTypeConfig({required this.id, required this.name});
|
||||||
|
}
|
||||||
|
|
||||||
|
class ColumnConfig {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String color;
|
||||||
|
|
||||||
|
const ColumnConfig({required this.id, required this.name, required this.color});
|
||||||
|
}
|
||||||
|
|
||||||
|
class KanbanConfig {
|
||||||
|
final String prefix;
|
||||||
|
final List<TicketTypeConfig> ticketTypes;
|
||||||
|
final List<ColumnConfig> columns;
|
||||||
|
|
||||||
|
const KanbanConfig({
|
||||||
|
required this.prefix,
|
||||||
|
required this.ticketTypes,
|
||||||
|
required this.columns,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
extension KanbanDewConfig on DewConfig {
|
||||||
|
KanbanConfig get kanban {
|
||||||
|
final kanbanYaml = (raw['dew'] as YamlMap)['kanban'] as YamlMap;
|
||||||
|
return KanbanConfig(
|
||||||
|
prefix: kanbanYaml['prefix'] as String,
|
||||||
|
ticketTypes:
|
||||||
|
(kanbanYaml['ticket_types'] as YamlList)
|
||||||
|
.map((t) => TicketTypeConfig(id: t['id'] as String, name: t['name'] as String))
|
||||||
|
.toList(),
|
||||||
|
columns:
|
||||||
|
(kanbanYaml['columns'] as YamlList)
|
||||||
|
.map(
|
||||||
|
(c) => ColumnConfig(
|
||||||
|
id: c['id'] as String,
|
||||||
|
name: c['name'] as String,
|
||||||
|
color: c['color'] as String,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
library;
|
library;
|
||||||
|
|
||||||
export 'src/dew_mcp_base.dart';
|
export 'src/dew_mcp_base.dart';
|
||||||
|
export 'src/mcp_config.dart';
|
||||||
|
|
||||||
import 'package:dew_core/dew_core.dart';
|
import 'package:dew_core/dew_core.dart';
|
||||||
import 'package:dew_mcp/src/dew_mcp_base.dart';
|
import 'package:dew_mcp/src/dew_mcp_base.dart';
|
||||||
|
|
|
||||||
19
packages/mcp/lib/src/mcp_config.dart
Normal file
19
packages/mcp/lib/src/mcp_config.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import 'package:dew_core/dew_core.dart';
|
||||||
|
import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
|
class McpConfig {
|
||||||
|
final String host;
|
||||||
|
final int port;
|
||||||
|
|
||||||
|
const McpConfig({required this.host, required this.port});
|
||||||
|
}
|
||||||
|
|
||||||
|
extension McpDewConfig on DewConfig {
|
||||||
|
McpConfig get mcp {
|
||||||
|
final mcpYaml = (raw['dew'] as YamlMap)['mcp'] as YamlMap;
|
||||||
|
return McpConfig(
|
||||||
|
host: mcpYaml['host'] as String,
|
||||||
|
port: mcpYaml['port'] as int,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ dependencies:
|
||||||
dew_core:
|
dew_core:
|
||||||
path: ../core
|
path: ../core
|
||||||
dart_mcp: ^0.5.0
|
dart_mcp: ^0.5.0
|
||||||
|
yaml: ^3.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^6.0.0
|
lints: ^6.0.0
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue