- Add links field to Ticket model (YAML frontmatter list, roundtrips correctly; omitted from file when empty) - Add TicketStore.linkTickets(), unlinkTickets(), and stats() methods - Add StatsCommand (kanban_stats) — ticket counts by column and type - Add MoveCommand (kanban_move_ticket) — validated column transition - Add LinkCommand (kanban_link_tickets) — track ticket dependencies - Add UnlinkCommand (kanban_unlink_tickets) — remove ticket links - Register all 4 new subcommands in KanbanCommand (12 total) - All 27 tests pass, dart analyze clean Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
36 lines
1 KiB
Dart
36 lines
1 KiB
Dart
import 'package:dew_core/dew_core.dart';
|
|
import 'package:path/path.dart' as p;
|
|
|
|
import '../ticket_store.dart';
|
|
|
|
class UnlinkCommand extends DewCommand with DewToolCommand {
|
|
UnlinkCommand() {
|
|
argParser
|
|
..addOption('id', abbr: 'i', mandatory: true, help: 'Source ticket ID.')
|
|
..addOption('target', abbr: 't', mandatory: true, help: 'Target ticket ID to remove link to.');
|
|
}
|
|
|
|
@override
|
|
final String name = 'unlink';
|
|
|
|
@override
|
|
final String description = 'Remove a link between two tickets.';
|
|
|
|
@override
|
|
final String toolName = 'kanban_unlink_tickets';
|
|
|
|
@override
|
|
Future<String> callAsTool(Map<String, dynamic> args) async {
|
|
final id = (args['id'] as String).toUpperCase();
|
|
final targetId = (args['target'] as String).toUpperCase();
|
|
|
|
final context = await ProjectContext.find();
|
|
final store = TicketStore(
|
|
kanbanDir: p.join(context.root, '.project', 'kanban'),
|
|
prefix: context.config.kanban.prefix,
|
|
);
|
|
|
|
await store.unlinkTickets(id, targetId);
|
|
return 'Unlinked $id → $targetId.';
|
|
}
|
|
}
|