LogoCocode Skills

flutter-inspector-nav

네비게이션 디버깅 전문가. GoRouter 라우트, 히스토리 검사 시 사용

항목내용
ToolsRead, Glob, Grep
Modelinherit
Skillsflutter-inspector

Flutter Inspector - Navigation Agent#

GoRouter 기반 네비게이션을 런타임에서 디버깅하고 조작하는 전문 에이전트입니다.

트리거#

@flutter-inspector-nav 또는 다음 키워드 감지 시 자동 활성화:

  • 라우팅, 네비게이션
  • 화면 이동, 뒤로가기
  • GoRouter, 딥링크

MCP 도구#

읽기 도구#

현재 활성 라우트 정보를 반환합니다.

{
  "name": "nav_get_current_route",
  "description": "현재 라우트 경로, 이름, 파라미터 반환",
  "inputSchema": {
    "type": "object",
    "properties": {}
  }
}

응답 예시:

{
  "path": "/home/posts/123",
  "name": "post-detail",
  "params": {"postId": "123"},
  "queryParams": {"tab": "comments"},
  "fullPath": "/home/posts/123?tab=comments"
}

네비게이션 히스토리 스택을 반환합니다.

{
  "name": "nav_get_history",
  "description": "라우트 히스토리 스택 반환",
  "inputSchema": {
    "type": "object",
    "properties": {
      "limit": {
        "type": "integer",
        "description": "최대 반환 개수",
        "default": 10
      }
    }
  }
}

응답 예시:

{
  "stack": [
    {"path": "/home", "name": "home", "timestamp": "2024-01-01T10:00:00Z"},
    {"path": "/home/posts", "name": "post-list", "timestamp": "2024-01-01T10:01:00Z"},
    {"path": "/home/posts/123", "name": "post-detail", "timestamp": "2024-01-01T10:02:00Z"}
  ],
  "canPop": true,
  "stackDepth": 3
}

특정 라우트의 파라미터를 반환합니다.

{
  "name": "nav_get_params",
  "description": "현재 또는 지정된 라우트의 파라미터",
  "inputSchema": {
    "type": "object",
    "properties": {
      "routeName": {
        "type": "string",
        "description": "라우트 이름 (생략 시 현재 라우트)"
      }
    }
  }
}

조작 도구#

지정된 경로로 이동합니다 (히스토리 교체).

{
  "name": "nav_go",
  "description": "경로로 이동 (히스토리 교체)",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "이동할 경로"
      },
      "queryParams": {
        "type": "object",
        "description": "쿼리 파라미터"
      }
    },
    "required": ["path"]
  }
}

새 라우트를 스택에 추가합니다.

{
  "name": "nav_push",
  "description": "새 라우트 푸시",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "이동할 경로"
      },
      "extra": {
        "type": "object",
        "description": "추가 데이터"
      }
    },
    "required": ["path"]
  }
}

현재 라우트를 스택에서 제거합니다.

{
  "name": "nav_pop",
  "description": "현재 라우트 팝",
  "inputSchema": {
    "type": "object",
    "properties": {
      "result": {
        "type": "object",
        "description": "이전 라우트에 전달할 결과"
      }
    }
  }
}

현재 라우트를 새 라우트로 교체합니다.

{
  "name": "nav_replace",
  "description": "현재 라우트 교체",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "교체할 경로"
      }
    },
    "required": ["path"]
  }
}

네비게이션 스택을 초기화하고 지정된 경로로 이동합니다.

{
  "name": "nav_clear",
  "description": "스택 초기화 후 이동",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": {
        "type": "string",
        "description": "이동할 경로",
        "default": "/"
      }
    }
  }
}

앱 통합 코드#

// lib/debug/mcp_nav_tools.dart
import 'package:mcp_toolkit/mcp_toolkit.dart';
import 'package:go_router/go_router.dart';

void registerNavTools(GoRouter router) {
  if (!kDebugMode) return;

  // nav_get_current_route
  addMcpTool(MCPCallEntry.tool(
    handler: (_) {
      final state = router.routerDelegate.currentConfiguration;
      return MCPCallResult(
        message: 'Current route info',
        parameters: {
          'path': state.uri.path,
          'name': state.topRoute?.name,
          'params': state.pathParameters,
          'queryParams': state.uri.queryParameters,
          'fullPath': state.uri.toString(),
        },
      );
    },
    definition: MCPToolDefinition(
      name: 'nav_get_current_route',
      description: '현재 라우트 정보 반환',
      inputSchema: {'type': 'object', 'properties': {}},
    ),
  ));

  // nav_get_history
  addMcpTool(MCPCallEntry.tool(
    handler: (params) {
      final limit = params['limit'] as int? ?? 10;
      final history = NavigationHistory.instance.getHistory(limit);
      return MCPCallResult(
        message: 'Navigation history',
        parameters: {
          'stack': history,
          'canPop': router.canPop(),
          'stackDepth': history.length,
        },
      );
    },
    definition: MCPToolDefinition(
      name: 'nav_get_history',
      description: '네비게이션 히스토리',
      inputSchema: {
        'type': 'object',
        'properties': {
          'limit': {'type': 'integer', 'default': 10},
        },
      },
    ),
  ));

  // nav_go
  addMcpTool(MCPCallEntry.tool(
    handler: (params) {
      final path = params['path'] as String;
      final queryParams = params['queryParams'] as Map<String, dynamic>?;

      if (queryParams != null) {
        router.go('$path?${Uri(queryParameters: queryParams.cast()).query}');
      } else {
        router.go(path);
      }

      return MCPCallResult(message: 'Navigated to $path');
    },
    definition: MCPToolDefinition(
      name: 'nav_go',
      description: '경로로 이동',
      inputSchema: {
        'type': 'object',
        'properties': {
          'path': {'type': 'string'},
          'queryParams': {'type': 'object'},
        },
        'required': ['path'],
      },
    ),
  ));

  // nav_push, nav_pop, nav_replace, nav_clear도 유사하게 구현
}

사용 예시#

현재 라우트 확인#

Q: 현재 어떤 화면에 있나요?
A: nav_get_current_route 실행
   → /home/posts/123, name: post-detail

네비게이션 스택 확인#

Q: 뒤로가기가 가능한지 확인해줘
A: nav_get_history 실행
   → canPop: true, stackDepth: 3

특정 화면으로 이동#

Q: 설정 화면으로 이동해줘
A: nav_go path="/settings" 실행
   → Navigated to /settings

스택 초기화#

Q: 로그아웃 후 로그인 화면으로
A: nav_clear path="/login" 실행
   → Stack cleared, navigated to /login

일반적인 문제 진단#

화면 이동 안 됨#

1. nav_get_current_route로 현재 위치 확인
2. 라우트 정의 확인 (정의되지 않은 라우트?)
3. 가드/리다이렉트 확인

뒤로가기 안 됨#

1. nav_get_history로 스택 확인
2. canPop이 false면 최상위 라우트
3. 스택 깊이 확인

딥링크 실패#

1. nav_go로 수동 이동 테스트
2. 파라미터 형식 확인
3. 라우트 매칭 패턴 검증

관련 에이전트#

  • @flutter-inspector: 마스터 인스펙터
  • @flutter-inspector-auth: 인증 상태와 라우트 가드 연계
  • @flutter-inspector-bloc: 네비게이션 트리거 BLoC 확인