{"owner":"pinpoint-apm","repo":"pinpoint","hasSkills":true,"totalSkillsCount":147,"totalTokensCount":60142,"categories":["anthropic-skill","plugin-manifest","subagent-persona"],"hasMcp":false,"mcpConfig":null,"found":["web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md","web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md","web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md","web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md","web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md","web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md","web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md","web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md","web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md",".claude/rules/build.md","web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md",".claude/rules/testing.md","agent-module/plugins/README.md","agent-module/plugins/type-provider-schema.json","agent-module/agent-tools/README.md","agent-module/agent-plugins/README.md","agent-module/plugins/pekko-http/README.md","agent-module/plugins/paho-mqtt/README.md","agent-module/plugins/oracle-jdbc/README.md","agent-module/plugins/openwhisk/README.md","agent-module/plugins/okhttp/README.md","agent-module/plugins/ning-asynchttpclient/README.md","agent-module/plugins/mysql-jdbc/README.md","agent-module/plugins/mybatis/README.md","agent-module/plugins/mssql-jdbc/README.md","agent-module/plugins/mongodb/README.md","agent-module/plugins/mariadb-jdbc/README.md","agent-module/plugins/logback/README.md","agent-module/plugins/log4j2/README.md","agent-module/plugins/log4j/README.md","agent-module/plugins/ktor/README.md","agent-module/plugins/kotlin-coroutines/README.md","agent-module/plugins/kafka/README.md","agent-module/plugins/jtds/README.md","agent-module/plugins/json-lib/README.md","agent-module/plugins/jetty/README.md","agent-module/plugins/jdk-httpclient/README.md","agent-module/plugins/jdk-http/README.md","agent-module/plugins/jboss/README.md","agent-module/plugins/jackson/README.md","agent-module/plugins/informix-jdbc/README.md","agent-module/plugins/ibatis/README.md","agent-module/plugins/hystrix/README.md","agent-module/plugins/httpclient5/README.md","agent-module/plugins/httpclient4/README.md","agent-module/plugins/httpclient3/README.md","agent-module/plugins/hikaricp/README.md","agent-module/plugins/hbase/README.md","agent-module/plugins/gson/README.md","agent-module/plugins/grpc/README.md","agent-module/plugins/google-httpclient/README.md","agent-module/plugins/fastjson/README.md","agent-module/plugins/elasticsearch8/README.md","agent-module/plugins/elasticsearch/README.md","agent-module/plugins/druid/README.md","agent-module/plugins/dbcp2/README.md","agent-module/plugins/dbcp/README.md","agent-module/plugins/db2-jdbc/README.md","agent-module/plugins/dameng-jdbc/README.md","agent-module/plugins/cxf/README.md","agent-module/plugins/cubrid-jdbc/README.md","agent-module/plugins/cassandra4/README.md","agent-module/plugins/cassandra/README.md","agent-module/plugins/aws-sdk-s3/README.md","agent-module/plugins/arcus/README.md","agent-module/plugins/apache-dubbo/README.md","agent-module/plugins/akka-http/README.md","agent-module/plugins/activemq-client/README.md","agent-module/plugins/postgresql-jdbc/README.md","agent-module/plugins/process/README.md","agent-module/plugins/pulsar/README.md","agent-module/plugins/rabbitmq/README.md","agent-module/plugins/reactor/README.md","agent-module/plugins/reactor-netty/README.md","agent-module/plugins/redis/README.md","agent-module/plugins/redis-lettuce/README.md","agent-module/plugins/redis-redisson/README.md","agent-module/plugins/resilience4j/README.md","agent-module/plugins/rocketmq/README.md","agent-module/plugins/rxjava/README.md","agent-module/plugins/spring/README.md","agent-module/plugins/spring-boot/README.md","agent-module/plugins/spring-cloud-sleuth/README.md","agent-module/plugins/spring-data-r2dbc/README.md","agent-module/plugins/spring-tx/README.md","agent-module/plugins/spring-webflux/README.md","agent-module/plugins/thread/README.md","agent-module/plugins/thrift/README.md","agent-module/plugins/tomcat/README.md","agent-module/plugins/undertow/README.md","agent-module/plugins/undertow-servlet/README.md","agent-module/plugins/user/README.md","agent-module/plugins/vertx/README.md","agent-module/plugins/weblogic/README.md","agent-module/plugins/websphere/README.md","agent-module/agent-plugins/proxy-apache/README.md","agent-module/agent-plugins/proxy-app/README.md","agent-module/agent-plugins/proxy-nginx/README.md","agent-module/agent-plugins/proxy-user/README.md","web-frontend/src/main/v3/.claude/rules/api-hooks.md","web-frontend/src/main/v3/.claude/rules/code-review-policy.md","web-frontend/src/main/v3/.claude/rules/code-style.md","web-frontend/src/main/v3/.claude/rules/components.md","web-frontend/src/main/v3/.claude/rules/git-workflow.md","web-frontend/src/main/v3/.claude/rules/i18n.md","web-frontend/src/main/v3/.claude/rules/monorepo.md","web-frontend/src/main/v3/.claude/rules/routing.md","web-frontend/src/main/v3/.claude/rules/service-map.md","web-frontend/src/main/v3/.claude/rules/state-management.md","web-frontend/src/main/v3/.claude/rules/testing.md","web-frontend/src/main/v3/.claude/rules/tool-usage.md","web-frontend/src/main/v3/packages/ui/components.json","web-frontend/src/main/v3/packages/ui/package.json","web-frontend/src/main/v3/packages/ui/README.md","web-frontend/src/main/v3/packages/ui/tsconfig.json","web-frontend/src/main/v3/packages/ui/tsconfig.node.json","web-frontend/src/main/v3/packages/server-map/package.json","web-frontend/src/main/v3/packages/server-map/README.md","web-frontend/src/main/v3/packages/server-map/tsconfig.json","web-frontend/src/main/v3/packages/scatter-chart/package.json","web-frontend/src/main/v3/packages/scatter-chart/README.md","web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json","web-frontend/src/main/v3/packages/datetime-picker/package.json","web-frontend/src/main/v3/packages/datetime-picker/README.md","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json","web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md","web-frontend/src/main/v3/.claude/agents/explorer/explorer.md","web-frontend/src/main/v3/.claude/agents/debugger/debugger.md","web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md","web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md","web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json","web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json","web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json"],"skills":{"web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md":"---\nname: write-test\ndescription: 변경되었거나 테스트가 없는 Pinpoint 프론트엔드 코드에 대한 Jest 테스트를 작성합니다. 훅, 아톰, 유틸리티, 컴포넌트에 테스트가 필요하거나 커버리지를 높여야 할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 테스트 작성\n\n`$ARGUMENTS`의 코드에 대한 Jest 테스트를 작성합니다 (경로가 없으면 최근 변경된 파일 대상).\n\n## 1단계: 테스트가 필요한 파일 탐색\n\n인자가 없는 경우:\n\n```bash\ngit diff upstream/master --name-only\n```\n\n변경된 각 `.ts` / `.tsx` 파일에 대해 해당하는 `.test.ts` / `.test.tsx` 파일이 있는지 확인합니다.\n테스트가 **없는** 파일 목록 — 이것이 우선 타겟입니다.\n\n## 2단계: 코드 분석\n\n각 타겟 파일을 완전히 읽고 파악합니다:\n\n- **수행하는 것** (구현이 아닌 동작)\n- **받는 입력** (props, 인자, 아톰 값, URL 파라미터)\n- **생성하는 출력** (반환 값, 렌더링 출력, 사이드 이펙트, 아톰 업데이트)\n- **의존성** (fetch 호출, 아톰, 다른 훅)\n\n## 3단계: 테스트 작성\n\n`.claude/rules/testing.md`의 프로젝트 테스트 패턴을 따릅니다.\n\n> **규칙: 테스트 이름(`describe` / `test` / `it` 문자열)은 반드시 영어로 작성합니다.**\n\n### 유틸리티 함수 테스트\n\n```typescript\nimport { theUtil } from \"./theUtil\";\n\ndescribe(\"theUtil\", () => {\n  test(\"should return [expected behavior] given [normal input]\", () => {\n    expect(theUtil(normalInput)).toBe(expected);\n  });\n\n  test(\"should handle null/undefined input gracefully\", () => {\n    expect(theUtil(null)).toBe(fallback);\n  });\n\n  test(\"should handle edge cases\", () => {\n    expect(theUtil(edgeCase)).toBe(edgeExpected);\n  });\n});\n```\n\n### Jotai 아톰 테스트\n\n```typescript\nimport { renderHook, act } from \"@testing-library/react\";\nimport { useAtom } from \"jotai\";\nimport { theAtom } from \"./theAtom\";\n\ndescribe(\"theAtom\", () => {\n  test(\"should initialize with default value\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    expect(result.current[0]).toEqual(defaultValue);\n  });\n\n  test(\"should update when setter is called\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    act(() => {\n      result.current[1](newValue);\n    });\n    expect(result.current[0]).toEqual(newValue);\n  });\n});\n```\n\n### API 훅 테스트 (useGetXxx)\n\n```typescript\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { createWrapper } from \"../testUtils\"; // QueryClient wrapper\nimport { useGetXxx } from \"./useGetXxx\";\n\ndescribe(\"useGetXxx\", () => {\n  beforeEach(() => {\n    global.fetch = jest.fn();\n  });\n\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n\n  test(\"should fetch data with correct endpoint and params\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: true,\n      json: async () => ({ data: mockData }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isSuccess).toBe(true));\n\n    expect(global.fetch).toHaveBeenCalledWith(\n      expect.stringContaining(\"/api/expected-endpoint\"),\n      expect.any(Object),\n    );\n    expect(result.current.data).toEqual(expectedData);\n  });\n\n  test(\"should not fetch when required params are missing\", () => {\n    const { result } = renderHook(() => useGetXxx(null), {\n      wrapper: createWrapper(),\n    });\n    expect(result.current.isFetching).toBe(false);\n    expect(global.fetch).not.toHaveBeenCalled();\n  });\n\n  test(\"should handle API error response\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: false,\n      status: 500,\n      json: async () => ({ title: \"Internal Server Error\" }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isError).toBe(true));\n  });\n});\n```\n\n### 라우트 로더 테스트\n\n```typescript\nimport { loader } from \"./loader\";\n\ndescribe(\"loader\", () => {\n  test(\"should redirect with correct date format when from/to are invalid\", async () => {\n    const request = new Request(\n      \"http://localhost/page?from=invalid&to=invalid\",\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeInstanceOf(Response); // redirect\n  });\n\n  test(\"should return null for valid date params\", async () => {\n    const now = Date.now();\n    const request = new Request(\n      `http://localhost/page?from=${now - 3600000}&to=${now}`,\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeNull();\n  });\n});\n```\n\n## 4단계: 커버리지 목표\n\n각 파일에 대해 다음을 커버하는 것을 목표로 합니다:\n\n- [ ] 정상 / 해피 패스\n- [ ] 빈 / null / undefined 입력\n- [ ] 오류 상태 (API 실패, 잘못된 데이터)\n- [ ] 경계값 (빈 배열, 최대값)\n- [ ] 훅의 `enabled` 조건 (파라미터 없을 때 페칭 안 함)\n\n## 5단계: 배치 및 등록\n\n- 테스트 파일은 소스와 함께 위치: `myHook.ts` → `myHook.test.ts`\n- 테스트 통과 확인을 위해 실행: `yarn workspace @pinpoint-fe/ui jest path/to/file.test.ts`\n\n작성된 테스트와 통과/실패 여부를 보고합니다.\n","web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md":"---\nname: review-code\ndescription: Pinpoint 프로젝트 규약에 따라 코드 변경을 리뷰합니다. 커밋 전, PR 리뷰, 또는 코드 품질을 점검할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰\n\n> **이 스킬은 다음 두 에이전트를 사용하여 실행합니다:**\n> 1. `.claude/agents/explorer/explorer.md` — 코드베이스 탐색 및 변경 사항 파악\n> 2. `.claude/agents/code-reviewer/code-reviewer.md` — 실제 코드 리뷰 수행\n>\n> 리뷰 시 두 에이전트의 사고방식과 체크리스트를 따르세요.\n\n**인자 형식**: `/review-code [파일경로 또는 경로 목록]`\n- `$ARGUMENTS`에 파일 경로를 전달하면 해당 파일을 리뷰합니다. 예: `/review-code packages/ui/src/hooks/api/useGetServerMap.ts`\n- 경로 없이 실행하면 `git diff upstream/master --name-only`로 변경된 파일을 자동 감지합니다.\n\n`$ARGUMENTS`의 코드를 리뷰합니다 (경로가 없으면 최근 git 변경 사항 리뷰).\n\n## 리뷰 체크리스트\n\n### 1. 아키텍처\n- [ ] 올바른 패키지에 코드 위치 (라우팅은 apps/web, 나머지는 packages/ui)\n- [ ] 페이지가 올바른 중첩 레이아웃 outlet에 배치 (InitialFetchOutlet / ConfigurationOutlet)\n- [ ] API 훅이 reactQueryHelper의 공유 queryFn 사용\n- [ ] 상태 관리가 올바른 계층 사용 (URL → Jotai → React Query)\n\n### 2. 코드 스타일\n- [ ] Prettier 포맷팅 (100자, 작은따옴표, 후행 쉼표, 세미콜론)\n- [ ] TypeScript strict 준수 (`any` 금지, 적절한 타입 좁히기)\n- [ ] 임포트 순서: external → @pinpoint-fe/* → relative\n- [ ] 딥 임포트: `@pinpoint-fe/ui` 대신 `@pinpoint-fe/ui/src/constants`\n\n### 3. 컴포넌트\n- [ ] UI 프리미티브가 shadcn/ui 패턴 준수 (Radix + CVA + Tailwind)\n- [ ] 도메인 컴포넌트가 UI 프리미티브를 조합하여 구성\n- [ ] className 병합에 `cn()` 사용\n- [ ] 인라인 스타일이나 CSS 모듈 없음\n\n### 4. 데이터 페칭\n- [ ] 엔드포인트가 EndPoints.ts에 정의됨\n- [ ] 타입이 네임스페이스 패턴으로 정의됨\n- [ ] `enabled` 옵션으로 조기 쿼리 실행 방지\n- [ ] ProblemDetail 패턴을 통한 오류 처리\n\n### 5. i18n\n- [ ] 모든 사용자 노출 문자열에 `t()` 함수 사용\n- [ ] 키가 en.json과 ko.json 모두에 추가됨\n- [ ] 키 네이밍이 SECTION.KEY_NAME 규칙을 따름\n\n### 6. 일반적인 함정\n- [ ] React 훅 의존성 누락 없음\n- [ ] 메모리 누수 없음 (useEffect에 클린업)\n- [ ] 새 페이지에 지연 로딩 사용\n- [ ] 하드코딩된 API 경로 없음 (END_POINTS 상수 사용)\n\n결과를 심각도 순으로 정리: Critical > Warning > Suggestion\n","web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md":"---\nname: mvn-web\ndescription: web-frontend, web, web-starter Maven 모듈을 skipTests 옵션으로 순차 빌드합니다.\n---\n\n# Maven Web 빌드\n\n## 0단계: Pinpoint 루트 디렉토리 탐색\n\n현재 작업 디렉토리부터 상위 디렉토리로 올라가며 `web-frontend`, `web`, `web-starter` 서브디렉토리를 포함하는 `pinpoint`라는 이름의 가장 가까운 상위 디렉토리를 찾습니다. 이 경로를 `PINPOINT_ROOT`로 저장합니다.\n\n```bash\nPINPOINT_ROOT=$(d=\"$PWD\"; while [ \"$d\" != \"/\" ]; do if [ \"$(basename \"$d\")\" = \"pinpoint\" ] && [ -d \"$d/web-frontend\" ] && [ -d \"$d/web\" ] && [ -d \"$d/web-starter\" ]; then echo \"$d\"; break; fi; d=\"$(dirname \"$d\")\"; done)\n```\n\n`PINPOINT_ROOT`가 비어 있으면 즉시 중단하고 pinpoint 루트 디렉토리를 찾을 수 없다고 보고합니다.\n\n## 1~3단계: 모듈 순차 빌드\n\n아래 모듈에 대해 정해진 순서대로 `mvn clean install -DskipTests=true`를 순차 실행합니다. 각 단계는 반드시 성공해야 다음 단계로 진행할 수 있습니다. 실패 시 즉시 중단하고 오류를 보고합니다.\n\n1. `cd $PINPOINT_ROOT/web-frontend && mvn clean install -DskipTests=true`\n2. `cd $PINPOINT_ROOT/web && mvn clean install -DskipTests=true`\n3. `cd $PINPOINT_ROOT/web-starter && mvn clean install -DskipTests=true`\n","web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md":"---\nname: create-component\ndescription: 프로젝트의 shadcn/ui + Tailwind 패턴에 따라 새 React 컴포넌트를 생성합니다. UI 프리미티브(버튼, 다이얼로그 등) 또는 도메인 컴포넌트(ServerMap, Inspector 등)를 새로 만들 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 컴포넌트 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 컴포넌트를 생성합니다.\n\n## 1. 컴포넌트 유형 결정\n\n### UI 프리미티브 (packages/ui/src/components/ui/)\n재사용 가능한 일반 UI 컴포넌트(버튼 변형, 다이얼로그, 입력 등):\n- shadcn/ui 패턴 준수: Radix UI + CVA + Tailwind\n- `@pinpoint-fe/ui/src/lib/utils`의 `cn()` 사용\n- 적절한 경우 Radix Slot을 통한 `asChild` 지원\n- ref 전달을 위한 `React.forwardRef` 사용\n- CVA(class-variance-authority)로 variants 정의\n\n### 도메인 컴포넌트 (packages/ui/src/components/{DomainName}/)\n기능별 컴포넌트(ServerMap, ErrorAnalysis 등):\n- `packages/ui/src/components/` 아래 서브디렉토리 생성\n- UI 프리미티브를 조합하여 구성\n- 데이터 페칭에 React Query 훅 사용\n- 공유 상태에 Jotai 아톰 사용\n- 비동기 콘텐츠를 Suspense + ErrorBoundary로 감싸기\n\n## 2. 기존 예시 읽기\n- UI 프리미티브: `packages/ui/src/components/ui/button.tsx` 또는 `dialog.tsx` 읽기\n- 도메인 컴포넌트: 타겟과 유사한 기존 도메인 컴포넌트 읽기\n\n## 3. 컴포넌트 생성\n\n### UI 프리미티브 템플릿\n```tsx\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\n\nconst componentVariants = cva('base-classes', {\n  variants: { variant: { default: '...', outline: '...' }, size: { default: '...', sm: '...' } },\n  defaultVariants: { variant: 'default', size: 'default' },\n});\n\nexport interface ComponentProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof componentVariants> {}\n\nconst Component = React.forwardRef<HTMLDivElement, ComponentProps>(\n  ({ className, variant, size, ...props }, ref) => (\n    <div ref={ref} className={cn(componentVariants({ variant, size, className }))} {...props} />\n  ),\n);\nComponent.displayName = 'Component';\nexport { Component, componentVariants };\n```\n\n### 도메인 컴포넌트 템플릿\n```tsx\nimport React, { Suspense } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { useTranslation } from 'react-i18next';\nimport { useAtomValue } from 'jotai';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\nimport { someSearchParamAtom } from '@pinpoint-fe/ui/src/atoms';\nimport { useGetMyData } from '@pinpoint-fe/ui/src/hooks/api';\n\nexport interface MyComponentProps {\n  className?: string;\n}\n\nconst MyComponentContent = ({ className }: MyComponentProps) => {\n  const { t } = useTranslation();\n  const searchParam = useAtomValue(someSearchParamAtom);\n  const { data } = useGetMyData({ param: searchParam });\n\n  if (!data) return null;\n\n  return <div className={cn('...', className)}>{/* 렌더링 */}</div>;\n};\n\nexport const MyComponent = ({ className }: MyComponentProps) => (\n  <ErrorBoundary fallback={<div>Error</div>}>\n    <Suspense fallback={<div>Loading...</div>}>\n      <MyComponentContent className={className} />\n    </Suspense>\n  </ErrorBoundary>\n);\n```\n\n## 4. 스타일링 규칙\n- Tailwind CSS만 사용 — 인라인 스타일, CSS 모듈 금지\n- 테마에는 CSS 변수 사용: `var(--ui-primary)`, `var(--ui-border)`\n- 모든 className 합성에 `cn()` 사용\n- Tailwind 브레이크포인트로 반응형 디자인\n\n## 5. 완료\n- `packages/ui/src/components/index.ts` (또는 해당 서브디렉토리의 `index.ts`)에서 컴포넌트 익스포트\n- `yarn build`로 TypeScript 오류 없음 확인\n","web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md":"---\nname: qa-pr\ndescription: Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요.\n---\n\n# PR 전 QA 게이트\n\n> **이 스킬은 `.claude/agents/qa-engineer/qa-engineer.md`에 정의된 `qa-engineer` 에이전트를 사용하여 실행합니다.**\n> QA 수행 시 해당 에이전트의 사고방식, 체크리스트, 출력 형식을 따르세요.\n\n**실행 시점: 커밋하거나 푸시하기 전에 반드시 실행하세요. QA 판정이 FAIL이면 문제를 해결하기 전까지 커밋하지 마세요.**\n\nPR 제출 전에 현재 변경 사항에 대한 전체 QA를 수행합니다.\n\n## 1단계: 변경 사항 파악\n\n```bash\ngit diff upstream/master --name-only\ngit diff upstream/master --stat\n```\n\n변경된 모든 파일을 나열하고 수정된 내용을 요약합니다.\n\n## 2단계: 빌드 및 테스트\n\n순서대로 실행하세요. **실패 시 즉시 중단하고 보고하세요. 빌드나 테스트 실패 상태에서는 커밋하지 마세요.**\n\n```bash\nyarn build\nyarn test\n```\n\n각각의 통과/실패 여부와 오류 출력을 보고합니다.\n\n## 3단계: 동작 QA\n\n변경된 각 컴포넌트, 훅, 페이지에 대해 기능 분석을 수행합니다:\n\n### 3a. 해피 패스\n- 정상 데이터로 기대되는 동작은 무엇인가?\n- 구현이 그 기대에 부합하는가?\n- 사용자 액션 → 상태 변경 → UI 업데이트 추적\n\n### 3b. 엣지 케이스\n변경된 UI 컴포넌트에 대해 다음을 각각 확인:\n- [ ] 빈/null 데이터 상태 — API가 빈 배열이나 null을 반환할 때 무엇이 렌더링되나?\n- [ ] 로딩 상태 — 스켈레톤/스피너가 표시되나? 빠른 로드에서 깜빡이지 않나?\n- [ ] 오류 상태 — API 실패 / 네트워크 오류. 사용자에게 오류가 표시되나?\n- [ ] 경계값 — 날짜 범위, 페이지 제한, 대용량 데이터셋\n- [ ] 동시 요청 — 빠른 클릭, 여러 탭 전환\n\n### 3c. 상태 무결성\n- [ ] URL 파라미터가 UI 상태를 올바르게 반영 (from/to, application)\n- [ ] 페이지 새로고침이 상태를 유지 (URL이 진실의 원천)\n- [ ] 아톰 상태가 내비게이션 간에 누출되지 않음 (클린업 확인)\n- [ ] React Query 캐시가 뮤테이션 후 오래된 데이터를 표시하지 않음\n\n### 3d. 컴포넌트 상호작용\n- [ ] 변경된 props가 모든 부모 컴포넌트 호출 위치를 만족함\n- [ ] 이벤트 핸들러가 올바르게 발생하고 중복 액션을 생성하지 않음\n- [ ] 무한 리렌더 루프 없음 (아톰 의존성 변경, 불안정한 참조)\n\n## 4단계: Pinpoint 특화 확인\n\n- [ ] application/from/to가 변경될 때 ServerMap이 여전히 렌더링됨\n- [ ] 변경된 코드 근처의 스캐터 차트 상호작용(드래그 선택, 클릭)이 여전히 작동\n- [ ] 트랜잭션 목록 / Inspector 내비게이션이 손상되지 않음\n- [ ] 설정 기반 기능이 여전히 설정을 올바르게 확인함\n\n## 5단계: 회귀 요약\n\n다음을 나열합니다:\n1. **변경된 파일**: (개수와 목록)\n2. **실행된 테스트**: 통과/실패\n3. **빌드**: 통과/실패\n4. **발견된 동작 이슈**: (심각도와 함께 목록)\n5. **QA 판정**: ✅ PASS / ❌ FAIL / ⚠️ PASS WITH WARNINGS\n\nFAIL 또는 PASS WITH WARNINGS인 경우, 머지 전에 필요한 구체적인 조치 사항을 나열합니다.\n","web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md":"---\nname: create-page\ndescription: Pinpoint 프로젝트 패턴에 따라 새 페이지를 생성합니다. 애플리케이션에 새 라우트/페이지를 추가하거나, 새 화면을 만들거나, 기존 라우팅 구조에 페이지를 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 페이지 생성\n\n**인자 형식**: `/create-page <PageName> [설명]`\n- `$0` — 생성할 페이지 이름 (PascalCase, 예: `RealTimeDashboard`)\n- `$ARGUMENTS` — 페이지 목적 설명 (선택 사항, 예: `실시간 메트릭 대시보드`)\n- 인자 없이 실행하면 사용자에게 페이지 이름과 목적을 먼저 질문합니다.\n\n`$ARGUMENTS` 설명을 가진 `$0` 페이지를 생성합니다.\n\n다음 단계를 엄격히 따르세요:\n\n## 1. 기존 페이지 분석\n- `packages/ui/src/constants/path.ts`를 읽어 APP_PATH 패턴 파악\n- `apps/web/src/routes/index.tsx`를 읽어 라우팅 구조 확인\n- `packages/ui/src/pages/`의 유사한 기존 페이지와 `apps/web/src/pages/`의 래퍼 읽기\n\n## 2. 파일 생성 (순서대로)\n\n### 2a. 라우트 경로 추가\n`packages/ui/src/constants/path.ts`의 `APP_PATH`에 새 경로 상수 추가.\n\n### 2b. 페이지 컴포넌트 생성\n`packages/ui/src/pages/{PageName}.tsx` 생성:\n- `@pinpoint-fe/ui`에서 훅과 컴포넌트 임포트\n- `configuration` prop 받기 (페이지 래퍼의 `configurationAtom`에서 읽음)\n- 적절한 검색 파라미터 훅 사용\n- 데이터 페칭에 React Query 훅 사용\n\n### 2c. 페이지 컴포넌트 익스포트\n`packages/ui/src/pages/index.ts`에서 페이지 익스포트 (없으면 생성).\n\n### 2d. 라우트 로더 생성 (날짜 파라미터가 필요한 경우)\n기존 로더의 패턴을 따라 `packages/ui/src/loader/{pageName}.ts` 생성:\n- URL 파라미터에서 application 파싱\n- `periodMax` 설정에 대해 날짜 범위 검증\n- 유효하지 않으면 올바른 날짜로 리다이렉트\n\n### 2e. 페이지 래퍼 생성\n`apps/web/src/pages/<PageName>.tsx` 생성:\n```tsx\n// <PageName>을 실제 페이지 이름으로 교체 (예: Inspector, ErrorAnalysis)\nimport { useAtomValue } from 'jotai';\nimport { <PageName>Page } from '@pinpoint-fe/ui';\nimport { configurationAtom } from '@pinpoint-fe/ui/src/atoms';\n\nexport default function <PageName>() {\n  const configuration = useAtomValue(configurationAtom);\n  return <<PageName>Page configuration={configuration} />;\n}\n```\n\n### 2f. 라우트 추가\n`apps/web/src/routes/index.tsx`에 라우트 추가:\n- 상단에 lazy 임포트 추가\n- `InitialFetchOutlet` children에 라우트 항목 추가 (설정 페이지는 `ConfigurationOutlet`)\n- 로더와 엘리먼트 포함\n\n## 3. i18n 키 추가\n사용자 노출 문자열을 `packages/ui/src/constants/locales/`의 `en.json`과 `ko.json` 모두에 추가.\n\n## 4. 검증\n- 라우트 경로가 고유한지 확인\n- 모든 임포트가 올바른지 확인\n- 라우트 트리에서 페이지가 올바른 레이아웃 outlet 내에 배치되었는지 확인\n","web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md":"---\nname: merge-check\ndescription: PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. \"머지해도 되나\", \"머지 전에 봐줘\", \"이 PR 리뷰해줘\", \"PR 괜찮은지 확인\", \"approve해도 되나\", \"머지 전에 뭘 확인해야 하나\" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다.\n---\n\n# 머지 전 최종 리뷰 (merge-check)\n\n**이 스킬의 목적은 \"머지 버튼을 눌러도 안전한가\"에 답하는 것입니다.**\n\n가장 중요한 판단 기준은 하나입니다: **기존에 잘 동작하던 기능이 그대로 동작하는가.**\n새 기능이 조금 부족한 건 다음 PR에서 고칠 수 있지만, 잘 쓰던 기능이 깨지면 사용자가 바로 피해를 봅니다.\n그래서 이 스킬은 \"새로 추가된 코드가 예쁜가\"보다 **\"이 변경이 무엇을 건드렸고, 그것을 쓰던 곳들이 아직 멀쩡한가\"**에 시간을 더 씁니다.\n\n## 절대 하지 않는 것\n\n- **머지하지 않습니다.** `gh pr merge`는 어떤 경우에도 실행하지 않습니다. 이 스킬은 판단만 하고, 머지는 사용자가 합니다.\n- **코드를 고치지 않습니다.** 문제를 찾으면 보고합니다. 고치는 건 별개 작업(`/apply-review`)입니다.\n- **GitHub에 아무것도 쓰지 않습니다.** 결과는 대화창에만 한국어로 보고합니다. PR 코멘트나 Approve는 사용자가 명시적으로 요청할 때만, 확인을 받고 남깁니다.\n- **확인하지 않은 것을 확인한 척하지 않습니다.** 못 본 건 \"확인 못 함\"으로 적습니다. 근거 없는 ✅ 는 이 스킬을 쓰는 의미를 지웁니다.\n\n## 0단계: 어떤 PR인지 확정 + 작업 중인 내용 보호\n\n```bash\ngit branch --show-current\ngit status --porcelain          # 커밋 안 된 작업이 있는지 먼저 확인\ngit rev-parse HEAD              # 로컬이 보고 있는 코드\ngh pr view --json number,title,url,headRefName,headRefOid,baseRefName,state,mergeable,author\n```\n\n**대상 PR 정하기**\n\n- `gh pr view`가 PR을 찾으면 → 그 PR이 대상입니다. 링크를 따로 받지 않습니다.\n- 못 찾거나 현재 브랜치가 `master`이면 → **멈추고 PR 링크를 요청**합니다. 추측하지 않습니다.\n  예: \"현재 브랜치에 연결된 PR을 찾지 못했어요. 리뷰할 PR 링크를 알려주세요.\"\n- 사용자가 링크를 줬으면 항상 그 링크가 우선입니다. 링크에서 `{owner}/{repo}`와 PR 번호를 파싱합니다.\n\n**내가 읽는 코드가 정말 그 PR의 코드인가 (놓치기 쉬움)**\n\n`git rev-parse HEAD`와 PR의 `headRefOid`가 다르면, **로컬에서 보고 있는 코드가 PR에 올라간 코드가\n아닙니다.** 리베이스했지만 아직 푸시하지 않은 경우가 흔합니다. 이때 그냥 리뷰하면 \"PR을 검증했다\"고\n말할 수 없습니다. 두 커밋의 코드가 실제로 같은지 확인하세요:\n\n```bash\ngit diff --stat {headRefOid} HEAD    # 비어 있으면 코드는 동일하고 베이스만 다르다\n```\n\n- **차이가 없거나 무관한 파일뿐이면** → 그대로 진행하고, 보고에 \"로컬이 리베이스로 앞서 있으나 코드는\n  동일\"이라고 한 줄 적습니다.\n- **차이가 있으면** → 어느 쪽을 리뷰할지 사용자에게 확인합니다. 로컬만 있는 수정은 PR에 없으므로,\n  그것까지 통과 판정에 넣으면 실제 머지될 코드와 어긋납니다.\n\n**사용자의 작업 보호**\n\n검증을 위해 브랜치를 옮겨야 할 수도 있습니다. 다만 항상 위험한 건 아니니 구분하세요:\n\n- **이미 그 PR의 브랜치에 있으면** 체크아웃이 필요 없습니다. 그냥 진행합니다.\n- **untracked 파일(`??`)만 있으면** 체크아웃·머지가 그 파일을 건드리지 않으므로 그대로 진행합니다.\n  (보고에 한 줄 언급만)\n- **수정·스테이징된 변경(`M`, `A` 등)이 있으면** 체크아웃하지 말고 사용자에게 먼저 묻습니다:\n  \"커밋되지 않은 변경이 있어요. ① 코드 읽기만으로 리뷰 ② stash 후 진행 — 어느 쪽으로 할까요?\"\n\n브랜치를 옮겼다면 **리뷰가 끝나고 반드시 원래 브랜치로 돌려놓고**, 그 사실을 보고에 적습니다.\n\n## 1단계: 이 PR이 무엇을 했는지 먼저 요약한다\n\n판정보다 요약이 먼저입니다. **무엇을 하려던 PR인지 모르면 \"제대로 했는지\"도 판단할 수 없습니다.**\n\n```bash\ngh pr view {number} --repo {owner}/{repo} --json title,body,commits,files,additions,deletions\n\n# 변경 규모는 git으로 봅니다. (`gh pr diff`에는 --stat이 없는 버전이 있어 그대로 쓰면 실패합니다.)\ngit fetch upstream master\ngit diff --stat upstream/master...HEAD          # 세 점: 공통 조상부터 이 브랜치까지\n```\n\n읽을 것:\n\n- **PR 제목·본문·연결된 이슈** — 이 PR이 풀려던 문제가 무엇인가\n- **커밋 메시지들** — 어떤 순서로 무엇을 했는가\n- **변경 파일 목록과 규모** — 어디를 건드렸는가\n\n여기서 나오는 요약은 사용자에게 보여주는 첫 항목이며, **의도(PR 본문)와 실제(diff)가 어긋나는지**를 보는 기준이기도 합니다.\n\"본문에는 A만 고쳤다고 썼는데 diff에는 B도 바뀌어 있다\" — 이건 그 자체로 리뷰 대상입니다.\n의도하지 않은 파일이 섞여 들어온 것일 수 있고, 그게 회귀의 흔한 원인입니다.\n\n## 2단계: 실제로 빌드·테스트를 돌린다\n\n기본 동작은 **실제 실행**입니다. 코드를 읽어서 \"괜찮아 보인다\"와 빌드가 통과하는 것은 다른 증거입니다.\n(사용자가 \"빠르게 봐줘\"라고 했다면 이 단계를 건너뛰고 CI 결과 조회로 대체하되, **보고에 \"직접 실행하지 않음\"을 명시**합니다.)\n\n검증은 **머지된 뒤의 코드**에 대해 해야 의미가 있습니다. PR 브랜치 단독으로 통과해도,\n그 사이 master에 들어간 다른 변경과 부딪히면 머지 직후에 깨집니다. 그래서 합쳐 놓고 돌립니다.\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\ngit fetch upstream master\ngit merge --no-commit --no-ff upstream/master   # 커밋하지 않고 합친 상태만 만든다\n```\n\n- **충돌이 나면** → `git merge --abort` 후, 충돌 파일을 보고 항목으로 올립니다(조건부 또는 머지 불가 사유).\n  이후 리뷰는 PR 브랜치 상태로 코드 읽기 중심으로 이어갑니다.\n- **깨끗하게 합쳐지면** → 그 상태(= 머지 후 master의 모습)에서 검증을 돌립니다.\n\n```bash\n# web-frontend/src/main/v3 에서\nyarn build      # TypeScript 검사 + 프로덕션 빌드\nyarn test       # 전체 워크스페이스 테스트\nyarn lint\n```\n\n검증이 끝나면 `git merge --abort`로 합친 상태를 되돌립니다. (머지 결과를 남기지 않습니다.)\n\n- **빌드 실패 → 무조건 머지 불가.** 더 볼 것 없습니다.\n- **테스트 실패 → 실패한 테스트가 이 PR 때문인지 확인.** upstream/master에서도 같은 테스트가 실패하면 기존 문제입니다.\n  그 구분을 하지 않고 \"테스트 실패\"라고만 보고하면 사용자가 헛수고합니다.\n- **CI 결과도 함께 봅니다.** `gh pr checks`는 실패 여부만 알려주고 이유를 말해주지 않으니,\n  실패한 것이 있으면 반드시 내용까지 읽습니다. (품질 게이트 실패는 저장소 자체의 머지 기준입니다.)\n\n```bash\ngh pr checks {number} --repo {owner}/{repo}\n\n# 실패한 검사의 실제 사유 (예: SonarCloud 품질 게이트가 무엇을 걸었는지)\ngh api repos/{owner}/{repo}/commits/{headRefOid}/check-runs \\\n  --jq '.check_runs[] | select(.conclusion==\"failure\") | \"\\(.name) | \\(.output.title) | \\(.output.summary)\"'\n```\n\n## 3단계: 기존 기능 회귀 점검 — 이 스킬의 핵심\n\n여기에 가장 많은 시간을 씁니다. 방법이 중요합니다. diff를 위에서 아래로 훑어 읽는 것은\n**추가된 코드**를 보게 만들 뿐이고, 회귀는 거의 항상 **추가가 아니라 변경과 삭제**에서 나옵니다.\n\n### 3a. PR을 만든 뒤 master가 얻은 변경과 부딪히는지 본다\n\n**이건 이 PR의 diff만 봐서는 절대 보이지 않습니다.** PR 브랜치 안에서는 완벽한 코드가, 그사이 master에\n들어온 다른 변경과 만나 깨질 수 있습니다. 머지 리뷰가 일반 코드 리뷰와 다른 지점이 바로 여기입니다.\n\n```bash\n# 이 PR의 베이스 이후 master가 새로 얻은 커밋\ngit log --oneline $(git merge-base HEAD upstream/master)..upstream/master\n```\n\n커밋 목록을 **읽고**, 이 PR이 건드린 영역과 겹치는 것이 있으면 그 커밋의 diff를 직접 확인합니다.\n특히 백엔드 변경은 프론트와 계약으로 연결돼 있어 겹치기 쉽습니다:\n\n- **API 응답·상태 코드가 바뀌었나** — 프론트가 특정 상태 코드(404 등)나 필드를 보고 분기한다면,\n  그 규칙이 아직 유효한지 확인합니다. (실제로 \"없는 이름은 404\" 프론트 + \"400을 반환\" 백엔드가\n  같은 시점에 올라온 적이 있습니다.)\n- **필수 파라미터가 늘었나** — 프론트가 그 값 없이 보내는 경로가 있으면 머지 직후 400이 됩니다.\n- **조용히 넘어가던 것이 예외가 되었나** — 기본값으로 대체되던 동작이 오류로 바뀌면, 그에 의존한\n  화면이 깨집니다.\n\n겹치는 것이 없으면 \"master의 새 커밋 N개, 이 PR과 겹치는 영역 없음\"이라고 적고 넘어갑니다.\n\n### 3b. \"위험한 변경\"만 골라낸다\n\ndiff에서 다음을 뽑아 목록으로 만듭니다. 추가만 된 코드는 회귀 위험이 낮으니 뒤로 미룹니다.\n\n```bash\ngit diff upstream/master...HEAD          # 전체 diff를 실제로 읽습니다\n```\n\n| 위험 신호 | 왜 위험한가 |\n|---|---|\n| 지워진 줄 / 삭제된 파일 · export | 쓰던 곳이 남아 있으면 그대로 깨집니다 |\n| 함수 시그니처 · props · 반환 타입 변경 | 호출자가 옛 계약을 기대합니다 |\n| 기본값 변경, optional ↔ required 변경 | 인자를 안 넘기던 호출자의 동작이 조용히 바뀝니다 |\n| 조건문(`if`, 삼항, `&&`) 수정 | 기존 경로가 새 조건에 걸려 빠질 수 있습니다 |\n| 이름 변경 (rename) | 참조를 하나라도 놓치면 깨집니다 |\n| 공용 파일 수정 (hooks/api, atoms, constants, utils) | 소비자가 많아 파급이 큽니다 |\n\n### 3c. 목록의 항목마다 \"쓰던 곳 전부\"를 찾아 확인한다\n\n**이게 핵심 작업입니다.** 변경된 심볼 하나하나에 대해:\n\n```bash\ngit grep -n \"심볼이름\" -- '*.ts' '*.tsx'      # 사용처 전부. 개수를 셉니다\n```\n\n그리고 **사용처를 샘플링하지 말고 전부 확인합니다.** 3곳뿐이면 3곳 다, 20곳이면 20곳 다.\n너무 많아 전부 못 봤으면 **몇 곳 중 몇 곳을 봤는지 숫자로 보고**합니다 (\"18곳 중 12곳 확인\").\n\"대충 괜찮아 보인다\"는 이 스킬에서 가장 위험한 문장입니다.\n\n각 사용처에서 확인할 것: **이번 변경 후에도 이 호출이 예전과 같은 결과를 내는가.**\n타입 체크만 통과하는 것으로는 부족합니다 — 타입은 맞는데 동작만 달라지는 변경이 제일 잡기 어렵습니다\n(기본값 변경, 조건 뒤집힘, 정렬 순서 변경, 캐시 키 변경 등).\n\n`.claude/rules/code-review-policy.md`의 영향 분석 절차를 그대로 따릅니다.\n\n### 3d. Pinpoint에서 실제로 회귀가 났던 자리들\n\n이 프로젝트에서 조용히 깨지기 쉬운 지점입니다. 해당하는 변경이 있으면 반드시 확인합니다.\n\n- **설정 플래그 분기** — `experimental.enableServiceMap` 같은 플래그. **플래그가 꺼진 기존 사용자의 경로가\n  그대로인가**를 별도로 확인합니다. 켠 쪽만 확인하고 넘어가는 실수가 흔합니다. 그 기능에 대한 규칙\n  문서가 `.claude/rules/`에 있으면 함께 읽습니다.\n- **Jotai 아톰** — 아톰은 화면 remount로 지워지지 않습니다. 아톰을 추가·수정했으면 **읽는 모든 컴포넌트**와\n  **초기화 시점**을 확인합니다. 안 지워진 옛 값으로 조회가 나가 400을 받는 사고가 실제로 있었습니다.\n- **React Query 쿼리 키** — 키가 바뀌면 캐시 무효화가 깨지거나, 다른 데이터가 같은 키에 섞입니다.\n- **라우트 경로 / URL 파라미터** — 경로 형태가 바뀌면 기존 링크·북마크가 죽습니다. 로더의 검증·리다이렉트가\n  옛 형태도 받아주는지 확인합니다.\n- **i18n 키** — 제거·이름 변경된 키를 다른 화면이 아직 쓰고 있지 않은지 `git grep`으로 확인합니다.\n- **컴포넌트 props** — 렌더하는 모든 부모가 유효한 props를 넘기는지 확인합니다.\n- **API 엔드포인트 · 응답 타입** — Java 쪽이 함께 바뀌었으면, 프론트가 기대하는 필드·형태와 맞는지 대조합니다.\n  (백엔드 코드는 이 계약 부분만 봅니다. 그 외 Java 내부 로직은 이 스킬의 범위가 아니라고 밝히세요.)\n\n### 3e. 판단이 안 서면 \"모르겠다\"가 정답이다\n\n코드만으로 확신이 안 서면 **추측으로 ✅ 하지 말고** 그 항목을 \"확인 필요\"로 남기고,\n사용자가 무엇을 어떻게 확인하면 되는지 알려줍니다 (예: \"dev 서버에서 A 화면 → B 클릭 순서로 확인\").\n머지 여부를 잘못 통과시키는 비용이, 한 번 더 확인하는 비용보다 훨씬 큽니다.\n\n## 4단계: PR이 의도한 동작을 정확히 하는가\n\n1단계 요약에서 정리한 \"이 PR이 풀려던 문제\"를 다시 꺼내 대조합니다.\n\n- 이슈에 적힌 증상이 이 변경으로 **실제로** 해소되는가 (코드를 따라가며 확인)\n- 해피 패스뿐 아니라 **빈 데이터 · 로딩 · 오류 · 경계값**에서도 의도대로 동작하는가\n- 문제를 근본에서 고쳤는가, 증상만 가렸는가\n- 놓친 케이스가 있는가 (예: 한 화면만 고치고 같은 문제를 가진 다른 화면은 그대로)\n\n깊은 동작 QA가 필요하면 `/qa-pr` 의 체크리스트(엣지 케이스, 상태 무결성, 컴포넌트 상호작용)를 활용합니다.\n\n## 5단계: 그 밖에 머지 전에 봐야 하는 것들\n\n- **코드 스타일 일관성** — `.claude/rules/code-style.md`, `/review-code` 체크리스트 기준.\n  포맷팅뿐 아니라 **주변 코드와 같은 방식으로 쓰였는가**를 봅니다 (같은 일을 다른 패턴으로 하는 코드가\n  섞이면 다음 사람이 어느 쪽을 따라야 할지 모르게 됩니다).\n- **아키텍처 위치** — 라우팅은 `apps/web`, 나머지는 `packages/ui`. 훅·아톰·상수가 제자리에 있는가.\n- **남아 있는 디버그 코드** — `console.log`, 주석 처리된 코드, `TODO`, 임시 하드코딩:\n  ```bash\n  git diff upstream/master...HEAD -- '*.ts' '*.tsx' | grep -nE '^\\+.*(console\\.(log|debug)|debugger|FIXME|XXX)'\n  ```\n- **커밋 메시지 규약** — `[#issue_number] Description`, 영어 (`.claude/rules/git-workflow.md`)\n- **PR 범위** — 이슈와 무관한 변경이 섞여 있지 않은가\n- **테스트** — 아톰·유틸·API 훅·라우트 로더가 바뀌었는데 테스트가 없으면 지적합니다 (핵심 경로)\n- **타입 안전성** — 새로 들어온 `any`, 위험한 단언(`as`), 무시된 null 체크\n- **성능** — 불필요한 리렌더, 누락된 `useEffect` 클린업, 큰 목록의 비효율 처리\n\n## 6단계: 직접 눈으로 확인할 화면 목록을 만든다 (필수)\n\n코드 추적·빌드·테스트로는 **실제로 화면에 무엇이 그려지는지**를 알 수 없습니다. 그래서 이 스킬은\n\"확인 못 했다\"로 끝내지 않고, **사용자가 `yarn dev`로 무엇을 열어 무엇을 봐야 하는지**를 항상\n목록으로 내놓습니다. 목록이 없으면 사용자는 어디서부터 봐야 할지 몰라 결국 아무것도 확인하지 않습니다.\n\n```bash\nyarn dev     # 포트 3000. /api/*는 localhost:8080(백엔드)로 프록시되므로 백엔드가 떠 있어야 데이터가 보인다\n```\n\n### 화면 목록을 뽑는 방법\n\n변경된 파일에서 **화면까지 거슬러 올라갑니다.** 컴포넌트·훅은 그 자체로 화면이 아니므로, 사용처를\n따라 `pages/`와 라우트까지 올라가야 어떤 주소를 열어야 할지 나옵니다.\n\n```bash\n# 변경된 컴포넌트/훅을 누가 쓰는지 → 그 사용처를 또 누가 쓰는지 (pages/ 까지)\ngit grep -n \"변경된컴포넌트\\|변경된훅\" -- '*.tsx' '*.ts'\n```\n\n주소는 `packages/ui/src/constants/path.ts`의 `APP_PATH`에서 확인합니다.\n\n### 목록에 반드시 들어가야 하는 것\n\n1. **기존 화면 (회귀 확인)** — 이번에 바뀐 공용 코드를 쓰는 **모든** 기존 화면. 새 기능 화면보다\n   **먼저** 적습니다. 사용자가 제일 걱정하는 건 \"잘 쓰던 게 깨졌나\"입니다.\n   공용 코드(`hooks/api`, `atoms`, `utils`, 공유 컴포넌트)를 건드렸다면 소비 화면이 여러 개일 테니\n   샘플링하지 말고 다 적습니다.\n2. **새 기능 화면 (의도 확인)** — 이 PR이 만든 동작. PR 본문의 테스트 계획에 있으면 그것을 재사용합니다.\n3. **설정 플래그가 있으면 양쪽 다** — 켠 상태와 **끈 상태**. 끈 쪽이 기존 사용자의 화면이므로 더 중요합니다.\n4. **코드로 확신이 안 섰던 항목** (3e에서 남긴 것) — 그게 바로 눈으로 봐야 하는 것입니다.\n\n각 항목은 **\"무엇을 보면 정상인지\"**까지 적습니다. \"servermap 확인\" 같은 문장은 도움이 안 됩니다.\n\"노드를 클릭하면 오른쪽 패널에 그 노드 이름과 차트가 뜨는지\" 처럼 판정 가능한 문장으로 씁니다.\n브라우저 개발자도구 네트워크 탭에서 볼 것이 있으면(400 응답, 중복 요청 등) 그것도 적습니다.\n\n## 7단계: 보고 (대화창, 한국어)\n\n**항상 이 구조로** 보고합니다. 요약이 판정보다 먼저 오는 순서를 지킵니다 —\n사용자는 \"무엇을 한 PR인지\" 이해한 뒤에 판정을 봐야 그 판정을 신뢰할 수 있습니다.\n\n```markdown\n## 1. 이 PR이 한 일\n- **목적**: (이슈/PR 본문 기준, 한두 문장)\n- **바꾼 것**: (파일 N개 / +A −B 줄, 핵심 변경 3~5개를 쉬운 말로)\n- **의도와 diff의 차이**: (없으면 \"없음\")\n\n## 2. 검증 결과\n| 항목 | 결과 |\n|---|---|\n| upstream/master 병합 | 충돌 없음 / 충돌 (파일) |\n| yarn build | 통과 / 실패 |\n| yarn test | 통과 / 실패 (N건, 이 PR 때문인지 여부) |\n| yarn lint | 통과 / 실패 |\n| CI | 상태 |\n\n## 3. 기존 기능 회귀 점검 (가장 중요)\n**master의 새 변경과의 충돌**: 새 커밋 N개 → 겹치는 것마다 판단 + 근거 (없으면 \"겹침 없음\")\n**위험 변경마다**: (항목) — 사용처 N곳 중 M곳 확인 → 판단 + 근거 (`파일:라인`)\n**확인하지 못한 것**: (항목) — 왜 확인 못 했는지 (→ 6번 목록으로 넘긴다)\n\n## 4. 동작 정확성\n- 의도한 문제가 해소되는가: 판단 + 근거\n- 엣지 케이스: 확인 결과\n\n## 5. 그 외 (스타일 · 구조 · 기타)\n심각도 순으로: Critical / Warning / Suggestion\n\n## 6. 직접 확인할 화면 (`yarn dev`)\n기존 화면 — 회귀 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n| (화면 이름) | `/경로/...` | (판정 가능한 문장) |\n\n새 기능 — 의도 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n\n## 7. 판정\n**✅ 머지 가능** / **⚠️ 조건부** / **❌ 머지 불가**\n- 이유: (한두 문장)\n- 머지 전에 해야 할 일: (있으면 목록)\n```\n\n### 판정 기준\n\n- **❌ 머지 불가** — 빌드·테스트 실패, 기존 기능이 깨진 것을 **확인**했음, 머지 충돌 미해결\n- **⚠️ 조건부** — 회귀 위험이 있는데 코드만으로는 확정할 수 없음, CI 검사(품질 게이트 등)가 빨간불,\n  또는 고쳐야 할 문제가 남았지만 치명적이지 않음.\n  **무엇을 확인·수정하면 ✅ 가 되는지 반드시 적습니다.**\n- **✅ 머지 가능** — 검증·CI 통과 + 위험 변경의 사용처를 확인했고 문제 없음\n\n> 6번의 화면 목록은 판정과 무관하게 **항상** 내놓습니다. ✅ 라도 \"코드로는 문제를 못 찾았다\"는\n> 뜻이지 \"화면을 봤다\"는 뜻은 아니고, 그 차이를 사용자가 알아야 스스로 판단할 수 있습니다.\n\n> 애매하면 ✅ 를 주지 마세요. ⚠️ 는 사용자가 5분 더 확인하게 만들지만, 잘못된 ✅ 는 깨진 코드를 배포합니다.\n> 다만 근거 없이 ⚠️ 를 남발하는 것도 도움이 되지 않습니다 — ⚠️ 에는 항상 \"무엇을 확인해야 하는지\"가 붙어야 합니다.\n\n### 마지막 정리\n\n- 브랜치를 옮겼다면 원래 브랜치로 복귀했는지 확인하고 보고에 한 줄 적습니다.\n- `git merge --abort`, stash 복원 등 임시 상태가 남지 않았는지 확인합니다.\n- 사용자가 PR 코멘트나 Approve를 원하면 그때 확인을 받고 남깁니다. 본문은 **영어**입니다\n  (`.claude/rules/git-workflow.md`).\n","web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md":"---\nname: create-api-hook\ndescription: useGetXxx 패턴에 따라 새 React Query API 훅을 생성합니다. 새 백엔드 API를 연동하거나, 엔드포인트에 대한 훅이 필요하거나, 데이터 페칭 로직을 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 API 훅 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 엔드포인트에 대한 새 API 훅을 생성합니다.\n\n다음 단계를 따르세요:\n\n## 1. 기존 패턴 분석\n- `packages/ui/src/hooks/api/reactQueryHelper.ts`를 읽어 queryFn과 queryClient 이해\n- `packages/ui/src/constants/EndPoints.ts`에서 엔드포인트 네이밍 확인\n- `packages/ui/src/hooks/api/`의 유사한 기존 훅에서 패턴 파악\n\n## 2. 엔드포인트 정의\n`packages/ui/src/constants/EndPoints.ts`에 엔드포인트 상수 추가:\n```typescript\nexport const NEW_ENDPOINT = `/api/path/to/endpoint`;\n```\n\n## 3. 타입 정의\n`packages/ui/src/constants/types/`에 타입 생성 또는 확장:\n```typescript\nexport namespace GetNewData {\n  export interface Parameters {\n    applicationName: string;\n    from: number;\n    to: number;\n    // ... 기타 파라미터\n  }\n  export interface Response {\n    // ... 응답 형태\n  }\n}\n```\n`packages/ui/src/constants/types/index.ts`에서 익스포트.\n\n## 4. 훅 생성\n`packages/ui/src/hooks/api/useGetNewData.ts` 생성:\n```typescript\nimport { useQuery } from '@tanstack/react-query';\nimport { END_POINTS, GetNewData } from '@pinpoint-fe/ui/src/constants';\nimport { convertParamsToQueryString } from '@pinpoint-fe/ui/src/utils';\nimport { queryFn } from './reactQueryHelper';\n\nexport const useGetNewData = (params: GetNewData.Parameters) => {\n  const queryString = convertParamsToQueryString(params);\n\n  return useQuery<GetNewData.Response>({\n    queryKey: [END_POINTS.NEW_ENDPOINT, queryString],\n    queryFn: queryFn(`${END_POINTS.NEW_ENDPOINT}?${queryString}`),\n    enabled: !!params.applicationName,\n    gcTime: 30000,\n  });\n};\n```\n\n## 5. 훅 익스포트\n`packages/ui/src/hooks/api/index.ts` (또는 해당하는 배럴 파일)에서 익스포트.\n\n## 6. 핵심 가이드라인\n- 필수 파라미터 없이 쿼리가 실행되지 않도록 `enabled` 사용\n- `reactQueryHelper.ts`의 `queryFn` 사용 — 직접 fetch를 구현하지 마세요\n- 쿼리 키에는 응답에 영향을 미치는 엔드포인트와 모든 파라미터 포함\n- POST 뮤테이션은 `useQuery` 대신 `useMutation` 사용\n- 폴링의 경우 `gcTime: 0` 설정, 부드러운 전환을 위해 `placeholderData: (prev) => prev` 사용\n","web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md":"---\nname: add-translation\ndescription: 영어와 한국어 로케일 파일 모두에 i18n 번역 키를 추가합니다. 사용자 노출 문자열을 추가하거나, 번역 키가 누락되었거나, 새 UI 텍스트를 국제화할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 번역 키 추가\n\n영어 텍스트 `$1`과 한국어 텍스트 `$2`를 가진 번역 키 `$0`을 추가합니다.\n\n## 단계\n\n1. `packages/ui/src/constants/locales/en.json` 읽기\n2. `packages/ui/src/constants/locales/ko.json` 읽기\n3. 키 접두사를 기반으로 올바른 섹션 결정 (COMMON, SERVER_MAP, TRANSACTION 등)\n4. 올바른 섹션의 **두 파일 모두**에 키 추가, 섹션 내 알파벳 순서 유지\n5. 한국어 텍스트가 제공되지 않은 경우, 나중에 쉽게 찾아 바꿀 수 있도록 `[TODO]` 접두사를 붙인 영어 텍스트를 플레이스홀더로 추가 (예: `\"[TODO] English text\"`)\n\n## 키 네이밍\n- 점으로 구분된 섹션을 사용하는 SCREAMING_SNAKE_CASE\n- 예시: `COMMON.SAVE`, `SERVER_MAP.NODE_COUNT`, `ERROR_ANALYSIS.CHART_TITLE`\n\n## 가이드라인\n- 항상 en.json과 ko.json을 동시에 업데이트\n- 한국어 번역은 직역 금지, 자연스러운 한국어로 작성\n- 동적 값은 이중 중괄호로 보간: `\"Hello, {{name}}!\"` / `\"안녕하세요, {{name}}님!\"`\n- 복수형에는 i18next 복수 접미사 사용: `_one`, `_other`\n",".claude/rules/build.md":"---\ndescription: Maven build commands for multi-module project, frontend build\nglobs:\n---\n\n## Build Commands\n\nMaven wrapper (`./mvnw`) is the build tool. This is a multi-module Maven project with 30+ top-level modules.\n\n```bash\n# Build everything (skip tests)\n./mvnw install -Dmaven.test.skip=true\n\n# Build specific modules with dependencies\n./mvnw install -pl agent -am -Dmaven.test.skip=true\n./mvnw install -pl collector -am -Dmaven.test.skip=true\n./mvnw install -pl web -am -Dmaven.test.skip=true\n\n# Build web without frontend\n./mvnw install -pl web -am -Dbuild.frontend.skip=true -Dmaven.test.skip=true\n```\n\n## Frontend\n\nLocated at `web-frontend/src/main/v3/`. Built via Maven frontend plugin using Yarn. Can be skipped with `-Dbuild.frontend.skip=true`.","web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md":"---\nname: apply-review\ndescription: 현재 작업 중인 PR에 달린 코드 리뷰를 확인하고, 타당한 리뷰는 코드를 고쳐 반영(커밋·푸시·PR 갱신)하고, 부당한 리뷰는 이유를 설명하며 무시합니다. PR 리뷰 코멘트를 반영하거나, 리뷰 피드백에 대응하거나, \"리뷰 반영\", \"리뷰 적용\", \"코드리뷰 처리\"를 요청할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰 반영 (apply-review)\n\n현재 작업의 PR에 달린 코드 리뷰를 가져와 **하나씩 평가**하고, 타당하면 코드에 반영하고 부당하면 무시합니다.\n모든 판단은 **대화창에 설명**하고 **PR 코멘트로도 남깁니다** (적용한 것·무시한 것 모두).\n\n## 핵심 원칙\n\n- **모든 설명은 개발자가 아니어도 이해할 수 있게, 짧고 쉽게.** 전문 용어 대신 \"무엇을 왜 바꿨는지/안 바꿨는지\"를 한두 문장으로.\n- **언어 규칙**: 사용자 대화창 설명은 **한국어**, PR 코멘트·커밋 메시지·PR 본문은 **영어** (`.claude/rules/git-workflow.md`).\n- **리뷰를 맹목적으로 따르지 않습니다.** 각 리뷰가 정말 맞는지, 우리 코드 맥락에서 타당한지 직접 판단합니다. 틀리거나 불필요하면 정중히 무시하고 이유를 댑니다.\n- **되돌리기 어려운 작업(커밋·푸시·PR 갱신) 전에는 반드시 `/qa-pr`을 통과해야 합니다.**\n\n## 0단계: PR 컨텍스트 확정\n\n먼저 지금 어떤 PR을 다루는지 정합니다.\n\n```bash\ngit branch --show-current\ngh pr view --json number,title,url\n```\n\n다음 두 경우에는 **작업을 멈추고 사용자에게 PR 링크를 요청하세요.** 추측해서 진행하지 않습니다.\n\n- 현재 브랜치가 `master`인 경우 (master에서는 직접 작업하지 않습니다 — `.claude/rules/git-workflow.md`)\n- `gh pr view`가 실패하는 등 **현재 컨텍스트로 PR을 알 수 없는 경우**\n\n요청 예시: \"현재 브랜치가 master라(또는 연결된 PR을 찾지 못해) 어떤 PR의 리뷰를 반영할지 알 수 없어요. PR 링크를 알려주세요.\"\n\n링크를 받으면 거기서 `{owner}/{repo}`와 PR 번호를 파싱하고, 해당 PR 브랜치로 이동해 작업합니다:\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\n```\n\n체크아웃 후 다시 `git branch --show-current`로 master가 아님을 확인합니다.\n리모트: `origin`=내 포크(jihea-park/pinpoint), `upstream`=pinpoint-apm/pinpoint.\n\n## 1단계: 리뷰 수집\n\n확정된 PR의 리뷰 전부(요약 리뷰 + 인라인 코멘트, Copilot·사람 모두)를 가져옵니다.\n\n```bash\n# PR 번호와 저장소가 아직 없으면 다시 확인\ngh pr view --json number,title,url\n\n# 리뷰 요약(승인/변경요청/총평) — 리뷰어와 본문\ngh api repos/{owner}/{repo}/pulls/{number}/reviews \\\n  --jq '.[] | {id, user: .user.login, state, body}'\n\n# 인라인 코드 코멘트 — 파일·라인·내용·comment id (반영 대상의 핵심)\ngh api repos/{owner}/{repo}/pulls/{number}/comments \\\n  --jq '.[] | {id, user: .user.login, path, line, body}'\n```\n\n`{owner}/{repo}`는 PR이 올라간 저장소(보통 `pinpoint-apm/pinpoint`). 위 `gh pr view`의 `url`(예: `https://github.com/pinpoint-apm/pinpoint/pull/13913`)에서 파싱해 채웁니다.\n이미 답글이 달려 처리된 코멘트는 중복 대응하지 않도록 `in_reply_to_id`가 없는(최상위) 코멘트 위주로 봅니다.\n\n## 2단계: 각 리뷰를 하나씩 평가\n\n리뷰 코멘트마다 다음을 따집니다. **추측하지 말고 실제 코드를 열어 확인하세요.**\n\n1. **무엇을 지적하는가** — 코멘트가 가리키는 파일·라인을 직접 읽습니다.\n2. **타당한가** — 우리 코드 맥락에서 실제 문제인지, 프로젝트 규약(`.claude/rules/`)에 비춰 맞는지 판단합니다.\n3. **부수효과는 없는가** — 고쳤을 때 다른 동작이 깨지지 않는지 봅니다.\n\n판단은 두 갈래입니다:\n\n- **타당함 → 반영** (3단계로)\n- **부당하거나 불필요함 → 무시**: 왜 적용하지 않는지 쉬운 말로 설명합니다. 예) 리뷰가 가정한 상황이 실제로는 생기지 않음 / 이미 다른 곳에서 처리됨 / 이슈 범위 밖 / 제안대로면 오히려 기존 동작이 깨짐.\n\n> 부당해 보여도 단정하기 전에 한 번 더 코드로 확인하세요. 반대로 \"리뷰어가 그렇게 말했으니까\"는 적용의 이유가 될 수 없습니다.\n\n## 3단계: 타당한 리뷰 반영 — 영향 분석 후 수정\n\n코드를 고치기 전에 `.claude/rules/code-review-policy.md`의 회귀 방지 절차를 따릅니다:\n\n- 고칠 파일의 **모든 호출자·소비자**를 먼저 파악합니다 (타입/훅/아톰/props/엔드포인트 변경 시 사용처 전부 Grep).\n- 수정이 **이번 PR이 해결하려던 이슈와 충돌하지 않는지** 확인합니다. (PR 제목·본문·연결 이슈의 의도를 다시 읽기)\n- 수정 후, 영향받은 파일을 다시 읽어 기존 시그니처·반환 타입·props·import 경로가 깨지지 않았는지 검증합니다.\n\n여러 리뷰를 반영할 경우 관련 수정을 모아 **하나의 커밋**으로 묶습니다(성격이 전혀 다르면 분리 가능).\n\n## 4단계: 리베이스로 최종 코드 만든 뒤 `/qa-pr` 필수 (게이트)\n\nQA는 **커밋·푸시될 최종 코드**에 대해 해야 의미가 있습니다. 리베이스로 충돌을 해결하면 코드가 바뀌므로, **리베이스를 먼저 끝내고 그 결과에 `/qa-pr`을 실행**합니다. (QA 뒤에 리베이스를 하면 변경된 코드가 검증되지 않은 채 커밋될 수 있습니다.)\n\n```bash\n# 1) 먼저 upstream 최신화 리베이스 — 충돌이 있으면 해결까지 완료 (git-workflow.md)\ngit fetch upstream master\ngit rebase upstream/master\n```\n\n```text\n# 2) 그 다음 /qa-pr 실행 — 빌드(yarn build)·테스트(yarn test)·동작 QA·회귀 점검\n```\n\n판정이 **FAIL이면 절대 커밋하지 말고** 문제를 먼저 해결합니다. (`.claude/rules/git-workflow.md`의 QA 게이트)\n`/qa-pr` 통과 후 셀프 체크: 디버그 코드(`console.log` 등) 없음, 코드 스타일 준수, 기존 기능 정상.\n\n## 5단계: 커밋 · 푸시 · PR 갱신\n\n리베이스와 QA가 모두 끝나고 PASS일 때만 진행합니다.\n\n```bash\ngit add <변경 파일>\ngit commit -m \"[#issue_number] Description\"   # 영어로. 같은 플랫폼이면 #issue_number, 다른 플랫폼이면 #noissue (git-workflow.md)\ngit push origin <branch-name>                 # 기존 PR 갱신이므로 -u 불필요 (이미 origin 추적 중)\n```\n\n커밋·PR 메시지는 **항상 영어**. 기존 PR이 같은 브랜치를 추적하므로 push만으로 PR이 갱신됩니다.\n\n## 6단계: 판단을 PR 코멘트로 남기기 (적용·무시 모두)\n\n각 리뷰 코멘트에 **답글**로 결론을 남깁니다. 답글 본문은 **영어**로, 짧고 명확하게.\n\n```bash\n# 특정 인라인 리뷰 코멘트에 답글 (본문은 영어로 — 플레이스홀더도 영어)\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Applied. <one-line reason in English>\"\n# 또는 무시한 경우\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Not applied. <one-line reason in English>\"\n```\n\n요약 리뷰(인라인이 아닌 총평)에 대응할 때는 PR 본문 코멘트를 사용:\n\n```bash\ngh pr comment {number} --body \"<summary of applied/ignored items in English>\"\n```\n\n## 7단계: 대화창 보고\n\n마지막으로 사용자에게 쉬운 말로 정리해 보여줍니다:\n\n1. **적용한 리뷰**: 무엇을, 왜 타당해서, 어떻게 고쳤는지 (각 한두 문장)\n2. **무시한 리뷰**: 무엇을, 왜 적용하지 않았는지 (각 한두 문장)\n3. **QA 결과**: PASS / FAIL\n4. **반영 결과**: 커밋 해시, 푸시·PR 갱신 여부, 남긴 PR 코멘트\n\n> 적용/무시 어느 쪽이든 \"왜\"가 가장 중요합니다. 비개발자도 납득할 수 있게 설명하세요.\n",".claude/rules/testing.md":"# Rules Skill\n\nPath: `.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/testing.md)","agent-module/plugins/README.md":"# plugins Documentation\n\nPath: `agent-module/plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/README.md)","agent-module/plugins/type-provider-schema.json":"# Plugins Skill\n\nPath: `agent-module/plugins/type-provider-schema.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/type-provider-schema.json)","agent-module/agent-tools/README.md":"# agent-tools Documentation\n\nPath: `agent-module/agent-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-tools/README.md)","agent-module/agent-plugins/README.md":"# agent-plugins Documentation\n\nPath: `agent-module/agent-plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/README.md)","agent-module/plugins/pekko-http/README.md":"# pekko-http Documentation\n\nPath: `agent-module/plugins/pekko-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pekko-http/README.md)","agent-module/plugins/paho-mqtt/README.md":"# paho-mqtt Documentation\n\nPath: `agent-module/plugins/paho-mqtt/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/paho-mqtt/README.md)","agent-module/plugins/oracle-jdbc/README.md":"# oracle-jdbc Documentation\n\nPath: `agent-module/plugins/oracle-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/oracle-jdbc/README.md)","agent-module/plugins/openwhisk/README.md":"# openwhisk Documentation\n\nPath: `agent-module/plugins/openwhisk/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/openwhisk/README.md)","agent-module/plugins/okhttp/README.md":"# okhttp Documentation\n\nPath: `agent-module/plugins/okhttp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/okhttp/README.md)","agent-module/plugins/ning-asynchttpclient/README.md":"# ning-asynchttpclient Documentation\n\nPath: `agent-module/plugins/ning-asynchttpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ning-asynchttpclient/README.md)","agent-module/plugins/mysql-jdbc/README.md":"# mysql-jdbc Documentation\n\nPath: `agent-module/plugins/mysql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mysql-jdbc/README.md)","agent-module/plugins/mybatis/README.md":"# mybatis Documentation\n\nPath: `agent-module/plugins/mybatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mybatis/README.md)","agent-module/plugins/mssql-jdbc/README.md":"# mssql-jdbc Documentation\n\nPath: `agent-module/plugins/mssql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mssql-jdbc/README.md)","agent-module/plugins/mongodb/README.md":"# mongodb Documentation\n\nPath: `agent-module/plugins/mongodb/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mongodb/README.md)","agent-module/plugins/mariadb-jdbc/README.md":"# mariadb-jdbc Documentation\n\nPath: `agent-module/plugins/mariadb-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mariadb-jdbc/README.md)","agent-module/plugins/logback/README.md":"# logback Documentation\n\nPath: `agent-module/plugins/logback/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/logback/README.md)","agent-module/plugins/log4j2/README.md":"# log4j2 Documentation\n\nPath: `agent-module/plugins/log4j2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j2/README.md)","agent-module/plugins/log4j/README.md":"# log4j Documentation\n\nPath: `agent-module/plugins/log4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j/README.md)","agent-module/plugins/ktor/README.md":"# ktor Documentation\n\nPath: `agent-module/plugins/ktor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ktor/README.md)","agent-module/plugins/kotlin-coroutines/README.md":"# kotlin-coroutines Documentation\n\nPath: `agent-module/plugins/kotlin-coroutines/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kotlin-coroutines/README.md)","agent-module/plugins/kafka/README.md":"# kafka Documentation\n\nPath: `agent-module/plugins/kafka/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kafka/README.md)","agent-module/plugins/jtds/README.md":"# jtds Documentation\n\nPath: `agent-module/plugins/jtds/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jtds/README.md)","agent-module/plugins/json-lib/README.md":"# json-lib Documentation\n\nPath: `agent-module/plugins/json-lib/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/json-lib/README.md)","agent-module/plugins/jetty/README.md":"# jetty Documentation\n\nPath: `agent-module/plugins/jetty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jetty/README.md)","agent-module/plugins/jdk-httpclient/README.md":"# jdk-httpclient Documentation\n\nPath: `agent-module/plugins/jdk-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-httpclient/README.md)","agent-module/plugins/jdk-http/README.md":"# jdk-http Documentation\n\nPath: `agent-module/plugins/jdk-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-http/README.md)","agent-module/plugins/jboss/README.md":"# jboss Documentation\n\nPath: `agent-module/plugins/jboss/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jboss/README.md)","agent-module/plugins/jackson/README.md":"# jackson Documentation\n\nPath: `agent-module/plugins/jackson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jackson/README.md)","agent-module/plugins/informix-jdbc/README.md":"# informix-jdbc Documentation\n\nPath: `agent-module/plugins/informix-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/informix-jdbc/README.md)","agent-module/plugins/ibatis/README.md":"# ibatis Documentation\n\nPath: `agent-module/plugins/ibatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ibatis/README.md)","agent-module/plugins/hystrix/README.md":"# hystrix Documentation\n\nPath: `agent-module/plugins/hystrix/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hystrix/README.md)","agent-module/plugins/httpclient5/README.md":"# httpclient5 Documentation\n\nPath: `agent-module/plugins/httpclient5/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient5/README.md)","agent-module/plugins/httpclient4/README.md":"# httpclient4 Documentation\n\nPath: `agent-module/plugins/httpclient4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient4/README.md)","agent-module/plugins/httpclient3/README.md":"# httpclient3 Documentation\n\nPath: `agent-module/plugins/httpclient3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient3/README.md)","agent-module/plugins/hikaricp/README.md":"# hikaricp Documentation\n\nPath: `agent-module/plugins/hikaricp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hikaricp/README.md)","agent-module/plugins/hbase/README.md":"# hbase Documentation\n\nPath: `agent-module/plugins/hbase/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hbase/README.md)","agent-module/plugins/gson/README.md":"# gson Documentation\n\nPath: `agent-module/plugins/gson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/gson/README.md)","agent-module/plugins/grpc/README.md":"# grpc Documentation\n\nPath: `agent-module/plugins/grpc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/grpc/README.md)","agent-module/plugins/google-httpclient/README.md":"# google-httpclient Documentation\n\nPath: `agent-module/plugins/google-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/google-httpclient/README.md)","agent-module/plugins/fastjson/README.md":"# fastjson Documentation\n\nPath: `agent-module/plugins/fastjson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/fastjson/README.md)","agent-module/plugins/elasticsearch8/README.md":"# elasticsearch8 Documentation\n\nPath: `agent-module/plugins/elasticsearch8/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch8/README.md)","agent-module/plugins/elasticsearch/README.md":"# elasticsearch Documentation\n\nPath: `agent-module/plugins/elasticsearch/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch/README.md)","agent-module/plugins/druid/README.md":"# druid Documentation\n\nPath: `agent-module/plugins/druid/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/druid/README.md)","agent-module/plugins/dbcp2/README.md":"# dbcp2 Documentation\n\nPath: `agent-module/plugins/dbcp2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp2/README.md)","agent-module/plugins/dbcp/README.md":"# dbcp Documentation\n\nPath: `agent-module/plugins/dbcp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp/README.md)","agent-module/plugins/db2-jdbc/README.md":"# db2-jdbc Documentation\n\nPath: `agent-module/plugins/db2-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/db2-jdbc/README.md)","agent-module/plugins/dameng-jdbc/README.md":"# dameng-jdbc Documentation\n\nPath: `agent-module/plugins/dameng-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dameng-jdbc/README.md)","agent-module/plugins/cxf/README.md":"# cxf Documentation\n\nPath: `agent-module/plugins/cxf/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cxf/README.md)","agent-module/plugins/cubrid-jdbc/README.md":"# cubrid-jdbc Documentation\n\nPath: `agent-module/plugins/cubrid-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cubrid-jdbc/README.md)","agent-module/plugins/cassandra4/README.md":"# cassandra4 Documentation\n\nPath: `agent-module/plugins/cassandra4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra4/README.md)","agent-module/plugins/cassandra/README.md":"# cassandra Documentation\n\nPath: `agent-module/plugins/cassandra/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra/README.md)","agent-module/plugins/aws-sdk-s3/README.md":"# aws-sdk-s3 Documentation\n\nPath: `agent-module/plugins/aws-sdk-s3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/aws-sdk-s3/README.md)","agent-module/plugins/arcus/README.md":"# arcus Documentation\n\nPath: `agent-module/plugins/arcus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/arcus/README.md)","agent-module/plugins/apache-dubbo/README.md":"# apache-dubbo Documentation\n\nPath: `agent-module/plugins/apache-dubbo/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/apache-dubbo/README.md)","agent-module/plugins/akka-http/README.md":"# akka-http Documentation\n\nPath: `agent-module/plugins/akka-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/akka-http/README.md)","agent-module/plugins/activemq-client/README.md":"# activemq-client Documentation\n\nPath: `agent-module/plugins/activemq-client/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/activemq-client/README.md)","agent-module/plugins/postgresql-jdbc/README.md":"# postgresql-jdbc Documentation\n\nPath: `agent-module/plugins/postgresql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/postgresql-jdbc/README.md)","agent-module/plugins/process/README.md":"# process Documentation\n\nPath: `agent-module/plugins/process/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/process/README.md)","agent-module/plugins/pulsar/README.md":"# pulsar Documentation\n\nPath: `agent-module/plugins/pulsar/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pulsar/README.md)","agent-module/plugins/rabbitmq/README.md":"# rabbitmq Documentation\n\nPath: `agent-module/plugins/rabbitmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rabbitmq/README.md)","agent-module/plugins/reactor/README.md":"# reactor Documentation\n\nPath: `agent-module/plugins/reactor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor/README.md)","agent-module/plugins/reactor-netty/README.md":"# reactor-netty Documentation\n\nPath: `agent-module/plugins/reactor-netty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor-netty/README.md)","agent-module/plugins/redis/README.md":"# redis Documentation\n\nPath: `agent-module/plugins/redis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis/README.md)","agent-module/plugins/redis-lettuce/README.md":"# redis-lettuce Documentation\n\nPath: `agent-module/plugins/redis-lettuce/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-lettuce/README.md)","agent-module/plugins/redis-redisson/README.md":"# redis-redisson Documentation\n\nPath: `agent-module/plugins/redis-redisson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-redisson/README.md)","agent-module/plugins/resilience4j/README.md":"# resilience4j Documentation\n\nPath: `agent-module/plugins/resilience4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/resilience4j/README.md)","agent-module/plugins/rocketmq/README.md":"# rocketmq Documentation\n\nPath: `agent-module/plugins/rocketmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rocketmq/README.md)","agent-module/plugins/rxjava/README.md":"# rxjava Documentation\n\nPath: `agent-module/plugins/rxjava/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rxjava/README.md)","agent-module/plugins/spring/README.md":"# spring Documentation\n\nPath: `agent-module/plugins/spring/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring/README.md)","agent-module/plugins/spring-boot/README.md":"# spring-boot Documentation\n\nPath: `agent-module/plugins/spring-boot/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-boot/README.md)","agent-module/plugins/spring-cloud-sleuth/README.md":"# spring-cloud-sleuth Documentation\n\nPath: `agent-module/plugins/spring-cloud-sleuth/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-cloud-sleuth/README.md)","agent-module/plugins/spring-data-r2dbc/README.md":"# spring-data-r2dbc Documentation\n\nPath: `agent-module/plugins/spring-data-r2dbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-data-r2dbc/README.md)","agent-module/plugins/spring-tx/README.md":"# spring-tx Documentation\n\nPath: `agent-module/plugins/spring-tx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-tx/README.md)","agent-module/plugins/spring-webflux/README.md":"# spring-webflux Documentation\n\nPath: `agent-module/plugins/spring-webflux/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-webflux/README.md)","agent-module/plugins/thread/README.md":"# thread Documentation\n\nPath: `agent-module/plugins/thread/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thread/README.md)","agent-module/plugins/thrift/README.md":"# thrift Documentation\n\nPath: `agent-module/plugins/thrift/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thrift/README.md)","agent-module/plugins/tomcat/README.md":"# tomcat Documentation\n\nPath: `agent-module/plugins/tomcat/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/tomcat/README.md)","agent-module/plugins/undertow/README.md":"# undertow Documentation\n\nPath: `agent-module/plugins/undertow/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow/README.md)","agent-module/plugins/undertow-servlet/README.md":"# undertow-servlet Documentation\n\nPath: `agent-module/plugins/undertow-servlet/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow-servlet/README.md)","agent-module/plugins/user/README.md":"# user Documentation\n\nPath: `agent-module/plugins/user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/user/README.md)","agent-module/plugins/vertx/README.md":"# vertx Documentation\n\nPath: `agent-module/plugins/vertx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/vertx/README.md)","agent-module/plugins/weblogic/README.md":"# weblogic Documentation\n\nPath: `agent-module/plugins/weblogic/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/weblogic/README.md)","agent-module/plugins/websphere/README.md":"# websphere Documentation\n\nPath: `agent-module/plugins/websphere/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/websphere/README.md)","agent-module/agent-plugins/proxy-apache/README.md":"# proxy-apache Documentation\n\nPath: `agent-module/agent-plugins/proxy-apache/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-apache/README.md)","agent-module/agent-plugins/proxy-app/README.md":"# proxy-app Documentation\n\nPath: `agent-module/agent-plugins/proxy-app/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-app/README.md)","agent-module/agent-plugins/proxy-nginx/README.md":"# proxy-nginx Documentation\n\nPath: `agent-module/agent-plugins/proxy-nginx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-nginx/README.md)","agent-module/agent-plugins/proxy-user/README.md":"# proxy-user Documentation\n\nPath: `agent-module/agent-plugins/proxy-user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-user/README.md)","web-frontend/src/main/v3/.claude/rules/api-hooks.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/api-hooks.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/api-hooks.md)","web-frontend/src/main/v3/.claude/rules/code-review-policy.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-review-policy.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-review-policy.md)","web-frontend/src/main/v3/.claude/rules/code-style.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-style.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-style.md)","web-frontend/src/main/v3/.claude/rules/components.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/components.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/components.md)","web-frontend/src/main/v3/.claude/rules/git-workflow.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/git-workflow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/git-workflow.md)","web-frontend/src/main/v3/.claude/rules/i18n.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/i18n.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/i18n.md)","web-frontend/src/main/v3/.claude/rules/monorepo.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/monorepo.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/monorepo.md)","web-frontend/src/main/v3/.claude/rules/routing.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/routing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/routing.md)","web-frontend/src/main/v3/.claude/rules/service-map.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/service-map.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/service-map.md)","web-frontend/src/main/v3/.claude/rules/state-management.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/state-management.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/state-management.md)","web-frontend/src/main/v3/.claude/rules/testing.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/testing.md)","web-frontend/src/main/v3/.claude/rules/tool-usage.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/tool-usage.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/tool-usage.md)","web-frontend/src/main/v3/packages/ui/components.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/components.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/components.json)","web-frontend/src/main/v3/packages/ui/package.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/package.json)","web-frontend/src/main/v3/packages/ui/README.md":"# ui Documentation\n\nPath: `web-frontend/src/main/v3/packages/ui/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/README.md)","web-frontend/src/main/v3/packages/ui/tsconfig.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.json)","web-frontend/src/main/v3/packages/ui/tsconfig.node.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.node.json)","web-frontend/src/main/v3/packages/server-map/package.json":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/package.json)","web-frontend/src/main/v3/packages/server-map/README.md":"# server-map Documentation\n\nPath: `web-frontend/src/main/v3/packages/server-map/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/README.md)","web-frontend/src/main/v3/packages/server-map/tsconfig.json":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/tsconfig.json)","web-frontend/src/main/v3/packages/scatter-chart/package.json":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/package.json)","web-frontend/src/main/v3/packages/scatter-chart/README.md":"# scatter-chart Documentation\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/README.md)","web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json)","web-frontend/src/main/v3/packages/datetime-picker/package.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/package.json)","web-frontend/src/main/v3/packages/datetime-picker/README.md":"# datetime-picker Documentation\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/README.md)","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json)","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json)","web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md":"# Subagent: qa-engineer\n\nPath: `web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md)","web-frontend/src/main/v3/.claude/agents/explorer/explorer.md":"# Subagent: explorer\n\nPath: `web-frontend/src/main/v3/.claude/agents/explorer/explorer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/explorer/explorer.md)","web-frontend/src/main/v3/.claude/agents/debugger/debugger.md":"# Subagent: debugger\n\nPath: `web-frontend/src/main/v3/.claude/agents/debugger/debugger.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/debugger/debugger.md)","web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md":"# Subagent: code-reviewer\n\nPath: `web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md)","web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md":"# Prompts Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md)","web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json":"# .storybook Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json)","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json)","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json)","web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json)","web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json)"},"files":{"web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md":"---\nname: write-test\ndescription: 변경되었거나 테스트가 없는 Pinpoint 프론트엔드 코드에 대한 Jest 테스트를 작성합니다. 훅, 아톰, 유틸리티, 컴포넌트에 테스트가 필요하거나 커버리지를 높여야 할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 테스트 작성\n\n`$ARGUMENTS`의 코드에 대한 Jest 테스트를 작성합니다 (경로가 없으면 최근 변경된 파일 대상).\n\n## 1단계: 테스트가 필요한 파일 탐색\n\n인자가 없는 경우:\n\n```bash\ngit diff upstream/master --name-only\n```\n\n변경된 각 `.ts` / `.tsx` 파일에 대해 해당하는 `.test.ts` / `.test.tsx` 파일이 있는지 확인합니다.\n테스트가 **없는** 파일 목록 — 이것이 우선 타겟입니다.\n\n## 2단계: 코드 분석\n\n각 타겟 파일을 완전히 읽고 파악합니다:\n\n- **수행하는 것** (구현이 아닌 동작)\n- **받는 입력** (props, 인자, 아톰 값, URL 파라미터)\n- **생성하는 출력** (반환 값, 렌더링 출력, 사이드 이펙트, 아톰 업데이트)\n- **의존성** (fetch 호출, 아톰, 다른 훅)\n\n## 3단계: 테스트 작성\n\n`.claude/rules/testing.md`의 프로젝트 테스트 패턴을 따릅니다.\n\n> **규칙: 테스트 이름(`describe` / `test` / `it` 문자열)은 반드시 영어로 작성합니다.**\n\n### 유틸리티 함수 테스트\n\n```typescript\nimport { theUtil } from \"./theUtil\";\n\ndescribe(\"theUtil\", () => {\n  test(\"should return [expected behavior] given [normal input]\", () => {\n    expect(theUtil(normalInput)).toBe(expected);\n  });\n\n  test(\"should handle null/undefined input gracefully\", () => {\n    expect(theUtil(null)).toBe(fallback);\n  });\n\n  test(\"should handle edge cases\", () => {\n    expect(theUtil(edgeCase)).toBe(edgeExpected);\n  });\n});\n```\n\n### Jotai 아톰 테스트\n\n```typescript\nimport { renderHook, act } from \"@testing-library/react\";\nimport { useAtom } from \"jotai\";\nimport { theAtom } from \"./theAtom\";\n\ndescribe(\"theAtom\", () => {\n  test(\"should initialize with default value\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    expect(result.current[0]).toEqual(defaultValue);\n  });\n\n  test(\"should update when setter is called\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    act(() => {\n      result.current[1](newValue);\n    });\n    expect(result.current[0]).toEqual(newValue);\n  });\n});\n```\n\n### API 훅 테스트 (useGetXxx)\n\n```typescript\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { createWrapper } from \"../testUtils\"; // QueryClient wrapper\nimport { useGetXxx } from \"./useGetXxx\";\n\ndescribe(\"useGetXxx\", () => {\n  beforeEach(() => {\n    global.fetch = jest.fn();\n  });\n\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n\n  test(\"should fetch data with correct endpoint and params\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: true,\n      json: async () => ({ data: mockData }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isSuccess).toBe(true));\n\n    expect(global.fetch).toHaveBeenCalledWith(\n      expect.stringContaining(\"/api/expected-endpoint\"),\n      expect.any(Object),\n    );\n    expect(result.current.data).toEqual(expectedData);\n  });\n\n  test(\"should not fetch when required params are missing\", () => {\n    const { result } = renderHook(() => useGetXxx(null), {\n      wrapper: createWrapper(),\n    });\n    expect(result.current.isFetching).toBe(false);\n    expect(global.fetch).not.toHaveBeenCalled();\n  });\n\n  test(\"should handle API error response\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: false,\n      status: 500,\n      json: async () => ({ title: \"Internal Server Error\" }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isError).toBe(true));\n  });\n});\n```\n\n### 라우트 로더 테스트\n\n```typescript\nimport { loader } from \"./loader\";\n\ndescribe(\"loader\", () => {\n  test(\"should redirect with correct date format when from/to are invalid\", async () => {\n    const request = new Request(\n      \"http://localhost/page?from=invalid&to=invalid\",\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeInstanceOf(Response); // redirect\n  });\n\n  test(\"should return null for valid date params\", async () => {\n    const now = Date.now();\n    const request = new Request(\n      `http://localhost/page?from=${now - 3600000}&to=${now}`,\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeNull();\n  });\n});\n```\n\n## 4단계: 커버리지 목표\n\n각 파일에 대해 다음을 커버하는 것을 목표로 합니다:\n\n- [ ] 정상 / 해피 패스\n- [ ] 빈 / null / undefined 입력\n- [ ] 오류 상태 (API 실패, 잘못된 데이터)\n- [ ] 경계값 (빈 배열, 최대값)\n- [ ] 훅의 `enabled` 조건 (파라미터 없을 때 페칭 안 함)\n\n## 5단계: 배치 및 등록\n\n- 테스트 파일은 소스와 함께 위치: `myHook.ts` → `myHook.test.ts`\n- 테스트 통과 확인을 위해 실행: `yarn workspace @pinpoint-fe/ui jest path/to/file.test.ts`\n\n작성된 테스트와 통과/실패 여부를 보고합니다.\n","web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md":"---\nname: review-code\ndescription: Pinpoint 프로젝트 규약에 따라 코드 변경을 리뷰합니다. 커밋 전, PR 리뷰, 또는 코드 품질을 점검할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰\n\n> **이 스킬은 다음 두 에이전트를 사용하여 실행합니다:**\n> 1. `.claude/agents/explorer/explorer.md` — 코드베이스 탐색 및 변경 사항 파악\n> 2. `.claude/agents/code-reviewer/code-reviewer.md` — 실제 코드 리뷰 수행\n>\n> 리뷰 시 두 에이전트의 사고방식과 체크리스트를 따르세요.\n\n**인자 형식**: `/review-code [파일경로 또는 경로 목록]`\n- `$ARGUMENTS`에 파일 경로를 전달하면 해당 파일을 리뷰합니다. 예: `/review-code packages/ui/src/hooks/api/useGetServerMap.ts`\n- 경로 없이 실행하면 `git diff upstream/master --name-only`로 변경된 파일을 자동 감지합니다.\n\n`$ARGUMENTS`의 코드를 리뷰합니다 (경로가 없으면 최근 git 변경 사항 리뷰).\n\n## 리뷰 체크리스트\n\n### 1. 아키텍처\n- [ ] 올바른 패키지에 코드 위치 (라우팅은 apps/web, 나머지는 packages/ui)\n- [ ] 페이지가 올바른 중첩 레이아웃 outlet에 배치 (InitialFetchOutlet / ConfigurationOutlet)\n- [ ] API 훅이 reactQueryHelper의 공유 queryFn 사용\n- [ ] 상태 관리가 올바른 계층 사용 (URL → Jotai → React Query)\n\n### 2. 코드 스타일\n- [ ] Prettier 포맷팅 (100자, 작은따옴표, 후행 쉼표, 세미콜론)\n- [ ] TypeScript strict 준수 (`any` 금지, 적절한 타입 좁히기)\n- [ ] 임포트 순서: external → @pinpoint-fe/* → relative\n- [ ] 딥 임포트: `@pinpoint-fe/ui` 대신 `@pinpoint-fe/ui/src/constants`\n\n### 3. 컴포넌트\n- [ ] UI 프리미티브가 shadcn/ui 패턴 준수 (Radix + CVA + Tailwind)\n- [ ] 도메인 컴포넌트가 UI 프리미티브를 조합하여 구성\n- [ ] className 병합에 `cn()` 사용\n- [ ] 인라인 스타일이나 CSS 모듈 없음\n\n### 4. 데이터 페칭\n- [ ] 엔드포인트가 EndPoints.ts에 정의됨\n- [ ] 타입이 네임스페이스 패턴으로 정의됨\n- [ ] `enabled` 옵션으로 조기 쿼리 실행 방지\n- [ ] ProblemDetail 패턴을 통한 오류 처리\n\n### 5. i18n\n- [ ] 모든 사용자 노출 문자열에 `t()` 함수 사용\n- [ ] 키가 en.json과 ko.json 모두에 추가됨\n- [ ] 키 네이밍이 SECTION.KEY_NAME 규칙을 따름\n\n### 6. 일반적인 함정\n- [ ] React 훅 의존성 누락 없음\n- [ ] 메모리 누수 없음 (useEffect에 클린업)\n- [ ] 새 페이지에 지연 로딩 사용\n- [ ] 하드코딩된 API 경로 없음 (END_POINTS 상수 사용)\n\n결과를 심각도 순으로 정리: Critical > Warning > Suggestion\n","web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md":"---\nname: mvn-web\ndescription: web-frontend, web, web-starter Maven 모듈을 skipTests 옵션으로 순차 빌드합니다.\n---\n\n# Maven Web 빌드\n\n## 0단계: Pinpoint 루트 디렉토리 탐색\n\n현재 작업 디렉토리부터 상위 디렉토리로 올라가며 `web-frontend`, `web`, `web-starter` 서브디렉토리를 포함하는 `pinpoint`라는 이름의 가장 가까운 상위 디렉토리를 찾습니다. 이 경로를 `PINPOINT_ROOT`로 저장합니다.\n\n```bash\nPINPOINT_ROOT=$(d=\"$PWD\"; while [ \"$d\" != \"/\" ]; do if [ \"$(basename \"$d\")\" = \"pinpoint\" ] && [ -d \"$d/web-frontend\" ] && [ -d \"$d/web\" ] && [ -d \"$d/web-starter\" ]; then echo \"$d\"; break; fi; d=\"$(dirname \"$d\")\"; done)\n```\n\n`PINPOINT_ROOT`가 비어 있으면 즉시 중단하고 pinpoint 루트 디렉토리를 찾을 수 없다고 보고합니다.\n\n## 1~3단계: 모듈 순차 빌드\n\n아래 모듈에 대해 정해진 순서대로 `mvn clean install -DskipTests=true`를 순차 실행합니다. 각 단계는 반드시 성공해야 다음 단계로 진행할 수 있습니다. 실패 시 즉시 중단하고 오류를 보고합니다.\n\n1. `cd $PINPOINT_ROOT/web-frontend && mvn clean install -DskipTests=true`\n2. `cd $PINPOINT_ROOT/web && mvn clean install -DskipTests=true`\n3. `cd $PINPOINT_ROOT/web-starter && mvn clean install -DskipTests=true`\n","web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md":"---\nname: create-component\ndescription: 프로젝트의 shadcn/ui + Tailwind 패턴에 따라 새 React 컴포넌트를 생성합니다. UI 프리미티브(버튼, 다이얼로그 등) 또는 도메인 컴포넌트(ServerMap, Inspector 등)를 새로 만들 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 컴포넌트 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 컴포넌트를 생성합니다.\n\n## 1. 컴포넌트 유형 결정\n\n### UI 프리미티브 (packages/ui/src/components/ui/)\n재사용 가능한 일반 UI 컴포넌트(버튼 변형, 다이얼로그, 입력 등):\n- shadcn/ui 패턴 준수: Radix UI + CVA + Tailwind\n- `@pinpoint-fe/ui/src/lib/utils`의 `cn()` 사용\n- 적절한 경우 Radix Slot을 통한 `asChild` 지원\n- ref 전달을 위한 `React.forwardRef` 사용\n- CVA(class-variance-authority)로 variants 정의\n\n### 도메인 컴포넌트 (packages/ui/src/components/{DomainName}/)\n기능별 컴포넌트(ServerMap, ErrorAnalysis 등):\n- `packages/ui/src/components/` 아래 서브디렉토리 생성\n- UI 프리미티브를 조합하여 구성\n- 데이터 페칭에 React Query 훅 사용\n- 공유 상태에 Jotai 아톰 사용\n- 비동기 콘텐츠를 Suspense + ErrorBoundary로 감싸기\n\n## 2. 기존 예시 읽기\n- UI 프리미티브: `packages/ui/src/components/ui/button.tsx` 또는 `dialog.tsx` 읽기\n- 도메인 컴포넌트: 타겟과 유사한 기존 도메인 컴포넌트 읽기\n\n## 3. 컴포넌트 생성\n\n### UI 프리미티브 템플릿\n```tsx\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\n\nconst componentVariants = cva('base-classes', {\n  variants: { variant: { default: '...', outline: '...' }, size: { default: '...', sm: '...' } },\n  defaultVariants: { variant: 'default', size: 'default' },\n});\n\nexport interface ComponentProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof componentVariants> {}\n\nconst Component = React.forwardRef<HTMLDivElement, ComponentProps>(\n  ({ className, variant, size, ...props }, ref) => (\n    <div ref={ref} className={cn(componentVariants({ variant, size, className }))} {...props} />\n  ),\n);\nComponent.displayName = 'Component';\nexport { Component, componentVariants };\n```\n\n### 도메인 컴포넌트 템플릿\n```tsx\nimport React, { Suspense } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { useTranslation } from 'react-i18next';\nimport { useAtomValue } from 'jotai';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\nimport { someSearchParamAtom } from '@pinpoint-fe/ui/src/atoms';\nimport { useGetMyData } from '@pinpoint-fe/ui/src/hooks/api';\n\nexport interface MyComponentProps {\n  className?: string;\n}\n\nconst MyComponentContent = ({ className }: MyComponentProps) => {\n  const { t } = useTranslation();\n  const searchParam = useAtomValue(someSearchParamAtom);\n  const { data } = useGetMyData({ param: searchParam });\n\n  if (!data) return null;\n\n  return <div className={cn('...', className)}>{/* 렌더링 */}</div>;\n};\n\nexport const MyComponent = ({ className }: MyComponentProps) => (\n  <ErrorBoundary fallback={<div>Error</div>}>\n    <Suspense fallback={<div>Loading...</div>}>\n      <MyComponentContent className={className} />\n    </Suspense>\n  </ErrorBoundary>\n);\n```\n\n## 4. 스타일링 규칙\n- Tailwind CSS만 사용 — 인라인 스타일, CSS 모듈 금지\n- 테마에는 CSS 변수 사용: `var(--ui-primary)`, `var(--ui-border)`\n- 모든 className 합성에 `cn()` 사용\n- Tailwind 브레이크포인트로 반응형 디자인\n\n## 5. 완료\n- `packages/ui/src/components/index.ts` (또는 해당 서브디렉토리의 `index.ts`)에서 컴포넌트 익스포트\n- `yarn build`로 TypeScript 오류 없음 확인\n","web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md":"---\nname: qa-pr\ndescription: Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요.\n---\n\n# PR 전 QA 게이트\n\n> **이 스킬은 `.claude/agents/qa-engineer/qa-engineer.md`에 정의된 `qa-engineer` 에이전트를 사용하여 실행합니다.**\n> QA 수행 시 해당 에이전트의 사고방식, 체크리스트, 출력 형식을 따르세요.\n\n**실행 시점: 커밋하거나 푸시하기 전에 반드시 실행하세요. QA 판정이 FAIL이면 문제를 해결하기 전까지 커밋하지 마세요.**\n\nPR 제출 전에 현재 변경 사항에 대한 전체 QA를 수행합니다.\n\n## 1단계: 변경 사항 파악\n\n```bash\ngit diff upstream/master --name-only\ngit diff upstream/master --stat\n```\n\n변경된 모든 파일을 나열하고 수정된 내용을 요약합니다.\n\n## 2단계: 빌드 및 테스트\n\n순서대로 실행하세요. **실패 시 즉시 중단하고 보고하세요. 빌드나 테스트 실패 상태에서는 커밋하지 마세요.**\n\n```bash\nyarn build\nyarn test\n```\n\n각각의 통과/실패 여부와 오류 출력을 보고합니다.\n\n## 3단계: 동작 QA\n\n변경된 각 컴포넌트, 훅, 페이지에 대해 기능 분석을 수행합니다:\n\n### 3a. 해피 패스\n- 정상 데이터로 기대되는 동작은 무엇인가?\n- 구현이 그 기대에 부합하는가?\n- 사용자 액션 → 상태 변경 → UI 업데이트 추적\n\n### 3b. 엣지 케이스\n변경된 UI 컴포넌트에 대해 다음을 각각 확인:\n- [ ] 빈/null 데이터 상태 — API가 빈 배열이나 null을 반환할 때 무엇이 렌더링되나?\n- [ ] 로딩 상태 — 스켈레톤/스피너가 표시되나? 빠른 로드에서 깜빡이지 않나?\n- [ ] 오류 상태 — API 실패 / 네트워크 오류. 사용자에게 오류가 표시되나?\n- [ ] 경계값 — 날짜 범위, 페이지 제한, 대용량 데이터셋\n- [ ] 동시 요청 — 빠른 클릭, 여러 탭 전환\n\n### 3c. 상태 무결성\n- [ ] URL 파라미터가 UI 상태를 올바르게 반영 (from/to, application)\n- [ ] 페이지 새로고침이 상태를 유지 (URL이 진실의 원천)\n- [ ] 아톰 상태가 내비게이션 간에 누출되지 않음 (클린업 확인)\n- [ ] React Query 캐시가 뮤테이션 후 오래된 데이터를 표시하지 않음\n\n### 3d. 컴포넌트 상호작용\n- [ ] 변경된 props가 모든 부모 컴포넌트 호출 위치를 만족함\n- [ ] 이벤트 핸들러가 올바르게 발생하고 중복 액션을 생성하지 않음\n- [ ] 무한 리렌더 루프 없음 (아톰 의존성 변경, 불안정한 참조)\n\n## 4단계: Pinpoint 특화 확인\n\n- [ ] application/from/to가 변경될 때 ServerMap이 여전히 렌더링됨\n- [ ] 변경된 코드 근처의 스캐터 차트 상호작용(드래그 선택, 클릭)이 여전히 작동\n- [ ] 트랜잭션 목록 / Inspector 내비게이션이 손상되지 않음\n- [ ] 설정 기반 기능이 여전히 설정을 올바르게 확인함\n\n## 5단계: 회귀 요약\n\n다음을 나열합니다:\n1. **변경된 파일**: (개수와 목록)\n2. **실행된 테스트**: 통과/실패\n3. **빌드**: 통과/실패\n4. **발견된 동작 이슈**: (심각도와 함께 목록)\n5. **QA 판정**: ✅ PASS / ❌ FAIL / ⚠️ PASS WITH WARNINGS\n\nFAIL 또는 PASS WITH WARNINGS인 경우, 머지 전에 필요한 구체적인 조치 사항을 나열합니다.\n","web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md":"---\nname: create-page\ndescription: Pinpoint 프로젝트 패턴에 따라 새 페이지를 생성합니다. 애플리케이션에 새 라우트/페이지를 추가하거나, 새 화면을 만들거나, 기존 라우팅 구조에 페이지를 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 페이지 생성\n\n**인자 형식**: `/create-page <PageName> [설명]`\n- `$0` — 생성할 페이지 이름 (PascalCase, 예: `RealTimeDashboard`)\n- `$ARGUMENTS` — 페이지 목적 설명 (선택 사항, 예: `실시간 메트릭 대시보드`)\n- 인자 없이 실행하면 사용자에게 페이지 이름과 목적을 먼저 질문합니다.\n\n`$ARGUMENTS` 설명을 가진 `$0` 페이지를 생성합니다.\n\n다음 단계를 엄격히 따르세요:\n\n## 1. 기존 페이지 분석\n- `packages/ui/src/constants/path.ts`를 읽어 APP_PATH 패턴 파악\n- `apps/web/src/routes/index.tsx`를 읽어 라우팅 구조 확인\n- `packages/ui/src/pages/`의 유사한 기존 페이지와 `apps/web/src/pages/`의 래퍼 읽기\n\n## 2. 파일 생성 (순서대로)\n\n### 2a. 라우트 경로 추가\n`packages/ui/src/constants/path.ts`의 `APP_PATH`에 새 경로 상수 추가.\n\n### 2b. 페이지 컴포넌트 생성\n`packages/ui/src/pages/{PageName}.tsx` 생성:\n- `@pinpoint-fe/ui`에서 훅과 컴포넌트 임포트\n- `configuration` prop 받기 (페이지 래퍼의 `configurationAtom`에서 읽음)\n- 적절한 검색 파라미터 훅 사용\n- 데이터 페칭에 React Query 훅 사용\n\n### 2c. 페이지 컴포넌트 익스포트\n`packages/ui/src/pages/index.ts`에서 페이지 익스포트 (없으면 생성).\n\n### 2d. 라우트 로더 생성 (날짜 파라미터가 필요한 경우)\n기존 로더의 패턴을 따라 `packages/ui/src/loader/{pageName}.ts` 생성:\n- URL 파라미터에서 application 파싱\n- `periodMax` 설정에 대해 날짜 범위 검증\n- 유효하지 않으면 올바른 날짜로 리다이렉트\n\n### 2e. 페이지 래퍼 생성\n`apps/web/src/pages/<PageName>.tsx` 생성:\n```tsx\n// <PageName>을 실제 페이지 이름으로 교체 (예: Inspector, ErrorAnalysis)\nimport { useAtomValue } from 'jotai';\nimport { <PageName>Page } from '@pinpoint-fe/ui';\nimport { configurationAtom } from '@pinpoint-fe/ui/src/atoms';\n\nexport default function <PageName>() {\n  const configuration = useAtomValue(configurationAtom);\n  return <<PageName>Page configuration={configuration} />;\n}\n```\n\n### 2f. 라우트 추가\n`apps/web/src/routes/index.tsx`에 라우트 추가:\n- 상단에 lazy 임포트 추가\n- `InitialFetchOutlet` children에 라우트 항목 추가 (설정 페이지는 `ConfigurationOutlet`)\n- 로더와 엘리먼트 포함\n\n## 3. i18n 키 추가\n사용자 노출 문자열을 `packages/ui/src/constants/locales/`의 `en.json`과 `ko.json` 모두에 추가.\n\n## 4. 검증\n- 라우트 경로가 고유한지 확인\n- 모든 임포트가 올바른지 확인\n- 라우트 트리에서 페이지가 올바른 레이아웃 outlet 내에 배치되었는지 확인\n","web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md":"---\nname: merge-check\ndescription: PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. \"머지해도 되나\", \"머지 전에 봐줘\", \"이 PR 리뷰해줘\", \"PR 괜찮은지 확인\", \"approve해도 되나\", \"머지 전에 뭘 확인해야 하나\" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다.\n---\n\n# 머지 전 최종 리뷰 (merge-check)\n\n**이 스킬의 목적은 \"머지 버튼을 눌러도 안전한가\"에 답하는 것입니다.**\n\n가장 중요한 판단 기준은 하나입니다: **기존에 잘 동작하던 기능이 그대로 동작하는가.**\n새 기능이 조금 부족한 건 다음 PR에서 고칠 수 있지만, 잘 쓰던 기능이 깨지면 사용자가 바로 피해를 봅니다.\n그래서 이 스킬은 \"새로 추가된 코드가 예쁜가\"보다 **\"이 변경이 무엇을 건드렸고, 그것을 쓰던 곳들이 아직 멀쩡한가\"**에 시간을 더 씁니다.\n\n## 절대 하지 않는 것\n\n- **머지하지 않습니다.** `gh pr merge`는 어떤 경우에도 실행하지 않습니다. 이 스킬은 판단만 하고, 머지는 사용자가 합니다.\n- **코드를 고치지 않습니다.** 문제를 찾으면 보고합니다. 고치는 건 별개 작업(`/apply-review`)입니다.\n- **GitHub에 아무것도 쓰지 않습니다.** 결과는 대화창에만 한국어로 보고합니다. PR 코멘트나 Approve는 사용자가 명시적으로 요청할 때만, 확인을 받고 남깁니다.\n- **확인하지 않은 것을 확인한 척하지 않습니다.** 못 본 건 \"확인 못 함\"으로 적습니다. 근거 없는 ✅ 는 이 스킬을 쓰는 의미를 지웁니다.\n\n## 0단계: 어떤 PR인지 확정 + 작업 중인 내용 보호\n\n```bash\ngit branch --show-current\ngit status --porcelain          # 커밋 안 된 작업이 있는지 먼저 확인\ngit rev-parse HEAD              # 로컬이 보고 있는 코드\ngh pr view --json number,title,url,headRefName,headRefOid,baseRefName,state,mergeable,author\n```\n\n**대상 PR 정하기**\n\n- `gh pr view`가 PR을 찾으면 → 그 PR이 대상입니다. 링크를 따로 받지 않습니다.\n- 못 찾거나 현재 브랜치가 `master`이면 → **멈추고 PR 링크를 요청**합니다. 추측하지 않습니다.\n  예: \"현재 브랜치에 연결된 PR을 찾지 못했어요. 리뷰할 PR 링크를 알려주세요.\"\n- 사용자가 링크를 줬으면 항상 그 링크가 우선입니다. 링크에서 `{owner}/{repo}`와 PR 번호를 파싱합니다.\n\n**내가 읽는 코드가 정말 그 PR의 코드인가 (놓치기 쉬움)**\n\n`git rev-parse HEAD`와 PR의 `headRefOid`가 다르면, **로컬에서 보고 있는 코드가 PR에 올라간 코드가\n아닙니다.** 리베이스했지만 아직 푸시하지 않은 경우가 흔합니다. 이때 그냥 리뷰하면 \"PR을 검증했다\"고\n말할 수 없습니다. 두 커밋의 코드가 실제로 같은지 확인하세요:\n\n```bash\ngit diff --stat {headRefOid} HEAD    # 비어 있으면 코드는 동일하고 베이스만 다르다\n```\n\n- **차이가 없거나 무관한 파일뿐이면** → 그대로 진행하고, 보고에 \"로컬이 리베이스로 앞서 있으나 코드는\n  동일\"이라고 한 줄 적습니다.\n- **차이가 있으면** → 어느 쪽을 리뷰할지 사용자에게 확인합니다. 로컬만 있는 수정은 PR에 없으므로,\n  그것까지 통과 판정에 넣으면 실제 머지될 코드와 어긋납니다.\n\n**사용자의 작업 보호**\n\n검증을 위해 브랜치를 옮겨야 할 수도 있습니다. 다만 항상 위험한 건 아니니 구분하세요:\n\n- **이미 그 PR의 브랜치에 있으면** 체크아웃이 필요 없습니다. 그냥 진행합니다.\n- **untracked 파일(`??`)만 있으면** 체크아웃·머지가 그 파일을 건드리지 않으므로 그대로 진행합니다.\n  (보고에 한 줄 언급만)\n- **수정·스테이징된 변경(`M`, `A` 등)이 있으면** 체크아웃하지 말고 사용자에게 먼저 묻습니다:\n  \"커밋되지 않은 변경이 있어요. ① 코드 읽기만으로 리뷰 ② stash 후 진행 — 어느 쪽으로 할까요?\"\n\n브랜치를 옮겼다면 **리뷰가 끝나고 반드시 원래 브랜치로 돌려놓고**, 그 사실을 보고에 적습니다.\n\n## 1단계: 이 PR이 무엇을 했는지 먼저 요약한다\n\n판정보다 요약이 먼저입니다. **무엇을 하려던 PR인지 모르면 \"제대로 했는지\"도 판단할 수 없습니다.**\n\n```bash\ngh pr view {number} --repo {owner}/{repo} --json title,body,commits,files,additions,deletions\n\n# 변경 규모는 git으로 봅니다. (`gh pr diff`에는 --stat이 없는 버전이 있어 그대로 쓰면 실패합니다.)\ngit fetch upstream master\ngit diff --stat upstream/master...HEAD          # 세 점: 공통 조상부터 이 브랜치까지\n```\n\n읽을 것:\n\n- **PR 제목·본문·연결된 이슈** — 이 PR이 풀려던 문제가 무엇인가\n- **커밋 메시지들** — 어떤 순서로 무엇을 했는가\n- **변경 파일 목록과 규모** — 어디를 건드렸는가\n\n여기서 나오는 요약은 사용자에게 보여주는 첫 항목이며, **의도(PR 본문)와 실제(diff)가 어긋나는지**를 보는 기준이기도 합니다.\n\"본문에는 A만 고쳤다고 썼는데 diff에는 B도 바뀌어 있다\" — 이건 그 자체로 리뷰 대상입니다.\n의도하지 않은 파일이 섞여 들어온 것일 수 있고, 그게 회귀의 흔한 원인입니다.\n\n## 2단계: 실제로 빌드·테스트를 돌린다\n\n기본 동작은 **실제 실행**입니다. 코드를 읽어서 \"괜찮아 보인다\"와 빌드가 통과하는 것은 다른 증거입니다.\n(사용자가 \"빠르게 봐줘\"라고 했다면 이 단계를 건너뛰고 CI 결과 조회로 대체하되, **보고에 \"직접 실행하지 않음\"을 명시**합니다.)\n\n검증은 **머지된 뒤의 코드**에 대해 해야 의미가 있습니다. PR 브랜치 단독으로 통과해도,\n그 사이 master에 들어간 다른 변경과 부딪히면 머지 직후에 깨집니다. 그래서 합쳐 놓고 돌립니다.\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\ngit fetch upstream master\ngit merge --no-commit --no-ff upstream/master   # 커밋하지 않고 합친 상태만 만든다\n```\n\n- **충돌이 나면** → `git merge --abort` 후, 충돌 파일을 보고 항목으로 올립니다(조건부 또는 머지 불가 사유).\n  이후 리뷰는 PR 브랜치 상태로 코드 읽기 중심으로 이어갑니다.\n- **깨끗하게 합쳐지면** → 그 상태(= 머지 후 master의 모습)에서 검증을 돌립니다.\n\n```bash\n# web-frontend/src/main/v3 에서\nyarn build      # TypeScript 검사 + 프로덕션 빌드\nyarn test       # 전체 워크스페이스 테스트\nyarn lint\n```\n\n검증이 끝나면 `git merge --abort`로 합친 상태를 되돌립니다. (머지 결과를 남기지 않습니다.)\n\n- **빌드 실패 → 무조건 머지 불가.** 더 볼 것 없습니다.\n- **테스트 실패 → 실패한 테스트가 이 PR 때문인지 확인.** upstream/master에서도 같은 테스트가 실패하면 기존 문제입니다.\n  그 구분을 하지 않고 \"테스트 실패\"라고만 보고하면 사용자가 헛수고합니다.\n- **CI 결과도 함께 봅니다.** `gh pr checks`는 실패 여부만 알려주고 이유를 말해주지 않으니,\n  실패한 것이 있으면 반드시 내용까지 읽습니다. (품질 게이트 실패는 저장소 자체의 머지 기준입니다.)\n\n```bash\ngh pr checks {number} --repo {owner}/{repo}\n\n# 실패한 검사의 실제 사유 (예: SonarCloud 품질 게이트가 무엇을 걸었는지)\ngh api repos/{owner}/{repo}/commits/{headRefOid}/check-runs \\\n  --jq '.check_runs[] | select(.conclusion==\"failure\") | \"\\(.name) | \\(.output.title) | \\(.output.summary)\"'\n```\n\n## 3단계: 기존 기능 회귀 점검 — 이 스킬의 핵심\n\n여기에 가장 많은 시간을 씁니다. 방법이 중요합니다. diff를 위에서 아래로 훑어 읽는 것은\n**추가된 코드**를 보게 만들 뿐이고, 회귀는 거의 항상 **추가가 아니라 변경과 삭제**에서 나옵니다.\n\n### 3a. PR을 만든 뒤 master가 얻은 변경과 부딪히는지 본다\n\n**이건 이 PR의 diff만 봐서는 절대 보이지 않습니다.** PR 브랜치 안에서는 완벽한 코드가, 그사이 master에\n들어온 다른 변경과 만나 깨질 수 있습니다. 머지 리뷰가 일반 코드 리뷰와 다른 지점이 바로 여기입니다.\n\n```bash\n# 이 PR의 베이스 이후 master가 새로 얻은 커밋\ngit log --oneline $(git merge-base HEAD upstream/master)..upstream/master\n```\n\n커밋 목록을 **읽고**, 이 PR이 건드린 영역과 겹치는 것이 있으면 그 커밋의 diff를 직접 확인합니다.\n특히 백엔드 변경은 프론트와 계약으로 연결돼 있어 겹치기 쉽습니다:\n\n- **API 응답·상태 코드가 바뀌었나** — 프론트가 특정 상태 코드(404 등)나 필드를 보고 분기한다면,\n  그 규칙이 아직 유효한지 확인합니다. (실제로 \"없는 이름은 404\" 프론트 + \"400을 반환\" 백엔드가\n  같은 시점에 올라온 적이 있습니다.)\n- **필수 파라미터가 늘었나** — 프론트가 그 값 없이 보내는 경로가 있으면 머지 직후 400이 됩니다.\n- **조용히 넘어가던 것이 예외가 되었나** — 기본값으로 대체되던 동작이 오류로 바뀌면, 그에 의존한\n  화면이 깨집니다.\n\n겹치는 것이 없으면 \"master의 새 커밋 N개, 이 PR과 겹치는 영역 없음\"이라고 적고 넘어갑니다.\n\n### 3b. \"위험한 변경\"만 골라낸다\n\ndiff에서 다음을 뽑아 목록으로 만듭니다. 추가만 된 코드는 회귀 위험이 낮으니 뒤로 미룹니다.\n\n```bash\ngit diff upstream/master...HEAD          # 전체 diff를 실제로 읽습니다\n```\n\n| 위험 신호 | 왜 위험한가 |\n|---|---|\n| 지워진 줄 / 삭제된 파일 · export | 쓰던 곳이 남아 있으면 그대로 깨집니다 |\n| 함수 시그니처 · props · 반환 타입 변경 | 호출자가 옛 계약을 기대합니다 |\n| 기본값 변경, optional ↔ required 변경 | 인자를 안 넘기던 호출자의 동작이 조용히 바뀝니다 |\n| 조건문(`if`, 삼항, `&&`) 수정 | 기존 경로가 새 조건에 걸려 빠질 수 있습니다 |\n| 이름 변경 (rename) | 참조를 하나라도 놓치면 깨집니다 |\n| 공용 파일 수정 (hooks/api, atoms, constants, utils) | 소비자가 많아 파급이 큽니다 |\n\n### 3c. 목록의 항목마다 \"쓰던 곳 전부\"를 찾아 확인한다\n\n**이게 핵심 작업입니다.** 변경된 심볼 하나하나에 대해:\n\n```bash\ngit grep -n \"심볼이름\" -- '*.ts' '*.tsx'      # 사용처 전부. 개수를 셉니다\n```\n\n그리고 **사용처를 샘플링하지 말고 전부 확인합니다.** 3곳뿐이면 3곳 다, 20곳이면 20곳 다.\n너무 많아 전부 못 봤으면 **몇 곳 중 몇 곳을 봤는지 숫자로 보고**합니다 (\"18곳 중 12곳 확인\").\n\"대충 괜찮아 보인다\"는 이 스킬에서 가장 위험한 문장입니다.\n\n각 사용처에서 확인할 것: **이번 변경 후에도 이 호출이 예전과 같은 결과를 내는가.**\n타입 체크만 통과하는 것으로는 부족합니다 — 타입은 맞는데 동작만 달라지는 변경이 제일 잡기 어렵습니다\n(기본값 변경, 조건 뒤집힘, 정렬 순서 변경, 캐시 키 변경 등).\n\n`.claude/rules/code-review-policy.md`의 영향 분석 절차를 그대로 따릅니다.\n\n### 3d. Pinpoint에서 실제로 회귀가 났던 자리들\n\n이 프로젝트에서 조용히 깨지기 쉬운 지점입니다. 해당하는 변경이 있으면 반드시 확인합니다.\n\n- **설정 플래그 분기** — `experimental.enableServiceMap` 같은 플래그. **플래그가 꺼진 기존 사용자의 경로가\n  그대로인가**를 별도로 확인합니다. 켠 쪽만 확인하고 넘어가는 실수가 흔합니다. 그 기능에 대한 규칙\n  문서가 `.claude/rules/`에 있으면 함께 읽습니다.\n- **Jotai 아톰** — 아톰은 화면 remount로 지워지지 않습니다. 아톰을 추가·수정했으면 **읽는 모든 컴포넌트**와\n  **초기화 시점**을 확인합니다. 안 지워진 옛 값으로 조회가 나가 400을 받는 사고가 실제로 있었습니다.\n- **React Query 쿼리 키** — 키가 바뀌면 캐시 무효화가 깨지거나, 다른 데이터가 같은 키에 섞입니다.\n- **라우트 경로 / URL 파라미터** — 경로 형태가 바뀌면 기존 링크·북마크가 죽습니다. 로더의 검증·리다이렉트가\n  옛 형태도 받아주는지 확인합니다.\n- **i18n 키** — 제거·이름 변경된 키를 다른 화면이 아직 쓰고 있지 않은지 `git grep`으로 확인합니다.\n- **컴포넌트 props** — 렌더하는 모든 부모가 유효한 props를 넘기는지 확인합니다.\n- **API 엔드포인트 · 응답 타입** — Java 쪽이 함께 바뀌었으면, 프론트가 기대하는 필드·형태와 맞는지 대조합니다.\n  (백엔드 코드는 이 계약 부분만 봅니다. 그 외 Java 내부 로직은 이 스킬의 범위가 아니라고 밝히세요.)\n\n### 3e. 판단이 안 서면 \"모르겠다\"가 정답이다\n\n코드만으로 확신이 안 서면 **추측으로 ✅ 하지 말고** 그 항목을 \"확인 필요\"로 남기고,\n사용자가 무엇을 어떻게 확인하면 되는지 알려줍니다 (예: \"dev 서버에서 A 화면 → B 클릭 순서로 확인\").\n머지 여부를 잘못 통과시키는 비용이, 한 번 더 확인하는 비용보다 훨씬 큽니다.\n\n## 4단계: PR이 의도한 동작을 정확히 하는가\n\n1단계 요약에서 정리한 \"이 PR이 풀려던 문제\"를 다시 꺼내 대조합니다.\n\n- 이슈에 적힌 증상이 이 변경으로 **실제로** 해소되는가 (코드를 따라가며 확인)\n- 해피 패스뿐 아니라 **빈 데이터 · 로딩 · 오류 · 경계값**에서도 의도대로 동작하는가\n- 문제를 근본에서 고쳤는가, 증상만 가렸는가\n- 놓친 케이스가 있는가 (예: 한 화면만 고치고 같은 문제를 가진 다른 화면은 그대로)\n\n깊은 동작 QA가 필요하면 `/qa-pr` 의 체크리스트(엣지 케이스, 상태 무결성, 컴포넌트 상호작용)를 활용합니다.\n\n## 5단계: 그 밖에 머지 전에 봐야 하는 것들\n\n- **코드 스타일 일관성** — `.claude/rules/code-style.md`, `/review-code` 체크리스트 기준.\n  포맷팅뿐 아니라 **주변 코드와 같은 방식으로 쓰였는가**를 봅니다 (같은 일을 다른 패턴으로 하는 코드가\n  섞이면 다음 사람이 어느 쪽을 따라야 할지 모르게 됩니다).\n- **아키텍처 위치** — 라우팅은 `apps/web`, 나머지는 `packages/ui`. 훅·아톰·상수가 제자리에 있는가.\n- **남아 있는 디버그 코드** — `console.log`, 주석 처리된 코드, `TODO`, 임시 하드코딩:\n  ```bash\n  git diff upstream/master...HEAD -- '*.ts' '*.tsx' | grep -nE '^\\+.*(console\\.(log|debug)|debugger|FIXME|XXX)'\n  ```\n- **커밋 메시지 규약** — `[#issue_number] Description`, 영어 (`.claude/rules/git-workflow.md`)\n- **PR 범위** — 이슈와 무관한 변경이 섞여 있지 않은가\n- **테스트** — 아톰·유틸·API 훅·라우트 로더가 바뀌었는데 테스트가 없으면 지적합니다 (핵심 경로)\n- **타입 안전성** — 새로 들어온 `any`, 위험한 단언(`as`), 무시된 null 체크\n- **성능** — 불필요한 리렌더, 누락된 `useEffect` 클린업, 큰 목록의 비효율 처리\n\n## 6단계: 직접 눈으로 확인할 화면 목록을 만든다 (필수)\n\n코드 추적·빌드·테스트로는 **실제로 화면에 무엇이 그려지는지**를 알 수 없습니다. 그래서 이 스킬은\n\"확인 못 했다\"로 끝내지 않고, **사용자가 `yarn dev`로 무엇을 열어 무엇을 봐야 하는지**를 항상\n목록으로 내놓습니다. 목록이 없으면 사용자는 어디서부터 봐야 할지 몰라 결국 아무것도 확인하지 않습니다.\n\n```bash\nyarn dev     # 포트 3000. /api/*는 localhost:8080(백엔드)로 프록시되므로 백엔드가 떠 있어야 데이터가 보인다\n```\n\n### 화면 목록을 뽑는 방법\n\n변경된 파일에서 **화면까지 거슬러 올라갑니다.** 컴포넌트·훅은 그 자체로 화면이 아니므로, 사용처를\n따라 `pages/`와 라우트까지 올라가야 어떤 주소를 열어야 할지 나옵니다.\n\n```bash\n# 변경된 컴포넌트/훅을 누가 쓰는지 → 그 사용처를 또 누가 쓰는지 (pages/ 까지)\ngit grep -n \"변경된컴포넌트\\|변경된훅\" -- '*.tsx' '*.ts'\n```\n\n주소는 `packages/ui/src/constants/path.ts`의 `APP_PATH`에서 확인합니다.\n\n### 목록에 반드시 들어가야 하는 것\n\n1. **기존 화면 (회귀 확인)** — 이번에 바뀐 공용 코드를 쓰는 **모든** 기존 화면. 새 기능 화면보다\n   **먼저** 적습니다. 사용자가 제일 걱정하는 건 \"잘 쓰던 게 깨졌나\"입니다.\n   공용 코드(`hooks/api`, `atoms`, `utils`, 공유 컴포넌트)를 건드렸다면 소비 화면이 여러 개일 테니\n   샘플링하지 말고 다 적습니다.\n2. **새 기능 화면 (의도 확인)** — 이 PR이 만든 동작. PR 본문의 테스트 계획에 있으면 그것을 재사용합니다.\n3. **설정 플래그가 있으면 양쪽 다** — 켠 상태와 **끈 상태**. 끈 쪽이 기존 사용자의 화면이므로 더 중요합니다.\n4. **코드로 확신이 안 섰던 항목** (3e에서 남긴 것) — 그게 바로 눈으로 봐야 하는 것입니다.\n\n각 항목은 **\"무엇을 보면 정상인지\"**까지 적습니다. \"servermap 확인\" 같은 문장은 도움이 안 됩니다.\n\"노드를 클릭하면 오른쪽 패널에 그 노드 이름과 차트가 뜨는지\" 처럼 판정 가능한 문장으로 씁니다.\n브라우저 개발자도구 네트워크 탭에서 볼 것이 있으면(400 응답, 중복 요청 등) 그것도 적습니다.\n\n## 7단계: 보고 (대화창, 한국어)\n\n**항상 이 구조로** 보고합니다. 요약이 판정보다 먼저 오는 순서를 지킵니다 —\n사용자는 \"무엇을 한 PR인지\" 이해한 뒤에 판정을 봐야 그 판정을 신뢰할 수 있습니다.\n\n```markdown\n## 1. 이 PR이 한 일\n- **목적**: (이슈/PR 본문 기준, 한두 문장)\n- **바꾼 것**: (파일 N개 / +A −B 줄, 핵심 변경 3~5개를 쉬운 말로)\n- **의도와 diff의 차이**: (없으면 \"없음\")\n\n## 2. 검증 결과\n| 항목 | 결과 |\n|---|---|\n| upstream/master 병합 | 충돌 없음 / 충돌 (파일) |\n| yarn build | 통과 / 실패 |\n| yarn test | 통과 / 실패 (N건, 이 PR 때문인지 여부) |\n| yarn lint | 통과 / 실패 |\n| CI | 상태 |\n\n## 3. 기존 기능 회귀 점검 (가장 중요)\n**master의 새 변경과의 충돌**: 새 커밋 N개 → 겹치는 것마다 판단 + 근거 (없으면 \"겹침 없음\")\n**위험 변경마다**: (항목) — 사용처 N곳 중 M곳 확인 → 판단 + 근거 (`파일:라인`)\n**확인하지 못한 것**: (항목) — 왜 확인 못 했는지 (→ 6번 목록으로 넘긴다)\n\n## 4. 동작 정확성\n- 의도한 문제가 해소되는가: 판단 + 근거\n- 엣지 케이스: 확인 결과\n\n## 5. 그 외 (스타일 · 구조 · 기타)\n심각도 순으로: Critical / Warning / Suggestion\n\n## 6. 직접 확인할 화면 (`yarn dev`)\n기존 화면 — 회귀 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n| (화면 이름) | `/경로/...` | (판정 가능한 문장) |\n\n새 기능 — 의도 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n\n## 7. 판정\n**✅ 머지 가능** / **⚠️ 조건부** / **❌ 머지 불가**\n- 이유: (한두 문장)\n- 머지 전에 해야 할 일: (있으면 목록)\n```\n\n### 판정 기준\n\n- **❌ 머지 불가** — 빌드·테스트 실패, 기존 기능이 깨진 것을 **확인**했음, 머지 충돌 미해결\n- **⚠️ 조건부** — 회귀 위험이 있는데 코드만으로는 확정할 수 없음, CI 검사(품질 게이트 등)가 빨간불,\n  또는 고쳐야 할 문제가 남았지만 치명적이지 않음.\n  **무엇을 확인·수정하면 ✅ 가 되는지 반드시 적습니다.**\n- **✅ 머지 가능** — 검증·CI 통과 + 위험 변경의 사용처를 확인했고 문제 없음\n\n> 6번의 화면 목록은 판정과 무관하게 **항상** 내놓습니다. ✅ 라도 \"코드로는 문제를 못 찾았다\"는\n> 뜻이지 \"화면을 봤다\"는 뜻은 아니고, 그 차이를 사용자가 알아야 스스로 판단할 수 있습니다.\n\n> 애매하면 ✅ 를 주지 마세요. ⚠️ 는 사용자가 5분 더 확인하게 만들지만, 잘못된 ✅ 는 깨진 코드를 배포합니다.\n> 다만 근거 없이 ⚠️ 를 남발하는 것도 도움이 되지 않습니다 — ⚠️ 에는 항상 \"무엇을 확인해야 하는지\"가 붙어야 합니다.\n\n### 마지막 정리\n\n- 브랜치를 옮겼다면 원래 브랜치로 복귀했는지 확인하고 보고에 한 줄 적습니다.\n- `git merge --abort`, stash 복원 등 임시 상태가 남지 않았는지 확인합니다.\n- 사용자가 PR 코멘트나 Approve를 원하면 그때 확인을 받고 남깁니다. 본문은 **영어**입니다\n  (`.claude/rules/git-workflow.md`).\n","web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md":"---\nname: create-api-hook\ndescription: useGetXxx 패턴에 따라 새 React Query API 훅을 생성합니다. 새 백엔드 API를 연동하거나, 엔드포인트에 대한 훅이 필요하거나, 데이터 페칭 로직을 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 API 훅 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 엔드포인트에 대한 새 API 훅을 생성합니다.\n\n다음 단계를 따르세요:\n\n## 1. 기존 패턴 분석\n- `packages/ui/src/hooks/api/reactQueryHelper.ts`를 읽어 queryFn과 queryClient 이해\n- `packages/ui/src/constants/EndPoints.ts`에서 엔드포인트 네이밍 확인\n- `packages/ui/src/hooks/api/`의 유사한 기존 훅에서 패턴 파악\n\n## 2. 엔드포인트 정의\n`packages/ui/src/constants/EndPoints.ts`에 엔드포인트 상수 추가:\n```typescript\nexport const NEW_ENDPOINT = `/api/path/to/endpoint`;\n```\n\n## 3. 타입 정의\n`packages/ui/src/constants/types/`에 타입 생성 또는 확장:\n```typescript\nexport namespace GetNewData {\n  export interface Parameters {\n    applicationName: string;\n    from: number;\n    to: number;\n    // ... 기타 파라미터\n  }\n  export interface Response {\n    // ... 응답 형태\n  }\n}\n```\n`packages/ui/src/constants/types/index.ts`에서 익스포트.\n\n## 4. 훅 생성\n`packages/ui/src/hooks/api/useGetNewData.ts` 생성:\n```typescript\nimport { useQuery } from '@tanstack/react-query';\nimport { END_POINTS, GetNewData } from '@pinpoint-fe/ui/src/constants';\nimport { convertParamsToQueryString } from '@pinpoint-fe/ui/src/utils';\nimport { queryFn } from './reactQueryHelper';\n\nexport const useGetNewData = (params: GetNewData.Parameters) => {\n  const queryString = convertParamsToQueryString(params);\n\n  return useQuery<GetNewData.Response>({\n    queryKey: [END_POINTS.NEW_ENDPOINT, queryString],\n    queryFn: queryFn(`${END_POINTS.NEW_ENDPOINT}?${queryString}`),\n    enabled: !!params.applicationName,\n    gcTime: 30000,\n  });\n};\n```\n\n## 5. 훅 익스포트\n`packages/ui/src/hooks/api/index.ts` (또는 해당하는 배럴 파일)에서 익스포트.\n\n## 6. 핵심 가이드라인\n- 필수 파라미터 없이 쿼리가 실행되지 않도록 `enabled` 사용\n- `reactQueryHelper.ts`의 `queryFn` 사용 — 직접 fetch를 구현하지 마세요\n- 쿼리 키에는 응답에 영향을 미치는 엔드포인트와 모든 파라미터 포함\n- POST 뮤테이션은 `useQuery` 대신 `useMutation` 사용\n- 폴링의 경우 `gcTime: 0` 설정, 부드러운 전환을 위해 `placeholderData: (prev) => prev` 사용\n","web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md":"---\nname: add-translation\ndescription: 영어와 한국어 로케일 파일 모두에 i18n 번역 키를 추가합니다. 사용자 노출 문자열을 추가하거나, 번역 키가 누락되었거나, 새 UI 텍스트를 국제화할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 번역 키 추가\n\n영어 텍스트 `$1`과 한국어 텍스트 `$2`를 가진 번역 키 `$0`을 추가합니다.\n\n## 단계\n\n1. `packages/ui/src/constants/locales/en.json` 읽기\n2. `packages/ui/src/constants/locales/ko.json` 읽기\n3. 키 접두사를 기반으로 올바른 섹션 결정 (COMMON, SERVER_MAP, TRANSACTION 등)\n4. 올바른 섹션의 **두 파일 모두**에 키 추가, 섹션 내 알파벳 순서 유지\n5. 한국어 텍스트가 제공되지 않은 경우, 나중에 쉽게 찾아 바꿀 수 있도록 `[TODO]` 접두사를 붙인 영어 텍스트를 플레이스홀더로 추가 (예: `\"[TODO] English text\"`)\n\n## 키 네이밍\n- 점으로 구분된 섹션을 사용하는 SCREAMING_SNAKE_CASE\n- 예시: `COMMON.SAVE`, `SERVER_MAP.NODE_COUNT`, `ERROR_ANALYSIS.CHART_TITLE`\n\n## 가이드라인\n- 항상 en.json과 ko.json을 동시에 업데이트\n- 한국어 번역은 직역 금지, 자연스러운 한국어로 작성\n- 동적 값은 이중 중괄호로 보간: `\"Hello, {{name}}!\"` / `\"안녕하세요, {{name}}님!\"`\n- 복수형에는 i18next 복수 접미사 사용: `_one`, `_other`\n",".claude/rules/build.md":"---\ndescription: Maven build commands for multi-module project, frontend build\nglobs:\n---\n\n## Build Commands\n\nMaven wrapper (`./mvnw`) is the build tool. This is a multi-module Maven project with 30+ top-level modules.\n\n```bash\n# Build everything (skip tests)\n./mvnw install -Dmaven.test.skip=true\n\n# Build specific modules with dependencies\n./mvnw install -pl agent -am -Dmaven.test.skip=true\n./mvnw install -pl collector -am -Dmaven.test.skip=true\n./mvnw install -pl web -am -Dmaven.test.skip=true\n\n# Build web without frontend\n./mvnw install -pl web -am -Dbuild.frontend.skip=true -Dmaven.test.skip=true\n```\n\n## Frontend\n\nLocated at `web-frontend/src/main/v3/`. Built via Maven frontend plugin using Yarn. Can be skipped with `-Dbuild.frontend.skip=true`.","web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md":"---\nname: apply-review\ndescription: 현재 작업 중인 PR에 달린 코드 리뷰를 확인하고, 타당한 리뷰는 코드를 고쳐 반영(커밋·푸시·PR 갱신)하고, 부당한 리뷰는 이유를 설명하며 무시합니다. PR 리뷰 코멘트를 반영하거나, 리뷰 피드백에 대응하거나, \"리뷰 반영\", \"리뷰 적용\", \"코드리뷰 처리\"를 요청할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰 반영 (apply-review)\n\n현재 작업의 PR에 달린 코드 리뷰를 가져와 **하나씩 평가**하고, 타당하면 코드에 반영하고 부당하면 무시합니다.\n모든 판단은 **대화창에 설명**하고 **PR 코멘트로도 남깁니다** (적용한 것·무시한 것 모두).\n\n## 핵심 원칙\n\n- **모든 설명은 개발자가 아니어도 이해할 수 있게, 짧고 쉽게.** 전문 용어 대신 \"무엇을 왜 바꿨는지/안 바꿨는지\"를 한두 문장으로.\n- **언어 규칙**: 사용자 대화창 설명은 **한국어**, PR 코멘트·커밋 메시지·PR 본문은 **영어** (`.claude/rules/git-workflow.md`).\n- **리뷰를 맹목적으로 따르지 않습니다.** 각 리뷰가 정말 맞는지, 우리 코드 맥락에서 타당한지 직접 판단합니다. 틀리거나 불필요하면 정중히 무시하고 이유를 댑니다.\n- **되돌리기 어려운 작업(커밋·푸시·PR 갱신) 전에는 반드시 `/qa-pr`을 통과해야 합니다.**\n\n## 0단계: PR 컨텍스트 확정\n\n먼저 지금 어떤 PR을 다루는지 정합니다.\n\n```bash\ngit branch --show-current\ngh pr view --json number,title,url\n```\n\n다음 두 경우에는 **작업을 멈추고 사용자에게 PR 링크를 요청하세요.** 추측해서 진행하지 않습니다.\n\n- 현재 브랜치가 `master`인 경우 (master에서는 직접 작업하지 않습니다 — `.claude/rules/git-workflow.md`)\n- `gh pr view`가 실패하는 등 **현재 컨텍스트로 PR을 알 수 없는 경우**\n\n요청 예시: \"현재 브랜치가 master라(또는 연결된 PR을 찾지 못해) 어떤 PR의 리뷰를 반영할지 알 수 없어요. PR 링크를 알려주세요.\"\n\n링크를 받으면 거기서 `{owner}/{repo}`와 PR 번호를 파싱하고, 해당 PR 브랜치로 이동해 작업합니다:\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\n```\n\n체크아웃 후 다시 `git branch --show-current`로 master가 아님을 확인합니다.\n리모트: `origin`=내 포크(jihea-park/pinpoint), `upstream`=pinpoint-apm/pinpoint.\n\n## 1단계: 리뷰 수집\n\n확정된 PR의 리뷰 전부(요약 리뷰 + 인라인 코멘트, Copilot·사람 모두)를 가져옵니다.\n\n```bash\n# PR 번호와 저장소가 아직 없으면 다시 확인\ngh pr view --json number,title,url\n\n# 리뷰 요약(승인/변경요청/총평) — 리뷰어와 본문\ngh api repos/{owner}/{repo}/pulls/{number}/reviews \\\n  --jq '.[] | {id, user: .user.login, state, body}'\n\n# 인라인 코드 코멘트 — 파일·라인·내용·comment id (반영 대상의 핵심)\ngh api repos/{owner}/{repo}/pulls/{number}/comments \\\n  --jq '.[] | {id, user: .user.login, path, line, body}'\n```\n\n`{owner}/{repo}`는 PR이 올라간 저장소(보통 `pinpoint-apm/pinpoint`). 위 `gh pr view`의 `url`(예: `https://github.com/pinpoint-apm/pinpoint/pull/13913`)에서 파싱해 채웁니다.\n이미 답글이 달려 처리된 코멘트는 중복 대응하지 않도록 `in_reply_to_id`가 없는(최상위) 코멘트 위주로 봅니다.\n\n## 2단계: 각 리뷰를 하나씩 평가\n\n리뷰 코멘트마다 다음을 따집니다. **추측하지 말고 실제 코드를 열어 확인하세요.**\n\n1. **무엇을 지적하는가** — 코멘트가 가리키는 파일·라인을 직접 읽습니다.\n2. **타당한가** — 우리 코드 맥락에서 실제 문제인지, 프로젝트 규약(`.claude/rules/`)에 비춰 맞는지 판단합니다.\n3. **부수효과는 없는가** — 고쳤을 때 다른 동작이 깨지지 않는지 봅니다.\n\n판단은 두 갈래입니다:\n\n- **타당함 → 반영** (3단계로)\n- **부당하거나 불필요함 → 무시**: 왜 적용하지 않는지 쉬운 말로 설명합니다. 예) 리뷰가 가정한 상황이 실제로는 생기지 않음 / 이미 다른 곳에서 처리됨 / 이슈 범위 밖 / 제안대로면 오히려 기존 동작이 깨짐.\n\n> 부당해 보여도 단정하기 전에 한 번 더 코드로 확인하세요. 반대로 \"리뷰어가 그렇게 말했으니까\"는 적용의 이유가 될 수 없습니다.\n\n## 3단계: 타당한 리뷰 반영 — 영향 분석 후 수정\n\n코드를 고치기 전에 `.claude/rules/code-review-policy.md`의 회귀 방지 절차를 따릅니다:\n\n- 고칠 파일의 **모든 호출자·소비자**를 먼저 파악합니다 (타입/훅/아톰/props/엔드포인트 변경 시 사용처 전부 Grep).\n- 수정이 **이번 PR이 해결하려던 이슈와 충돌하지 않는지** 확인합니다. (PR 제목·본문·연결 이슈의 의도를 다시 읽기)\n- 수정 후, 영향받은 파일을 다시 읽어 기존 시그니처·반환 타입·props·import 경로가 깨지지 않았는지 검증합니다.\n\n여러 리뷰를 반영할 경우 관련 수정을 모아 **하나의 커밋**으로 묶습니다(성격이 전혀 다르면 분리 가능).\n\n## 4단계: 리베이스로 최종 코드 만든 뒤 `/qa-pr` 필수 (게이트)\n\nQA는 **커밋·푸시될 최종 코드**에 대해 해야 의미가 있습니다. 리베이스로 충돌을 해결하면 코드가 바뀌므로, **리베이스를 먼저 끝내고 그 결과에 `/qa-pr`을 실행**합니다. (QA 뒤에 리베이스를 하면 변경된 코드가 검증되지 않은 채 커밋될 수 있습니다.)\n\n```bash\n# 1) 먼저 upstream 최신화 리베이스 — 충돌이 있으면 해결까지 완료 (git-workflow.md)\ngit fetch upstream master\ngit rebase upstream/master\n```\n\n```text\n# 2) 그 다음 /qa-pr 실행 — 빌드(yarn build)·테스트(yarn test)·동작 QA·회귀 점검\n```\n\n판정이 **FAIL이면 절대 커밋하지 말고** 문제를 먼저 해결합니다. (`.claude/rules/git-workflow.md`의 QA 게이트)\n`/qa-pr` 통과 후 셀프 체크: 디버그 코드(`console.log` 등) 없음, 코드 스타일 준수, 기존 기능 정상.\n\n## 5단계: 커밋 · 푸시 · PR 갱신\n\n리베이스와 QA가 모두 끝나고 PASS일 때만 진행합니다.\n\n```bash\ngit add <변경 파일>\ngit commit -m \"[#issue_number] Description\"   # 영어로. 같은 플랫폼이면 #issue_number, 다른 플랫폼이면 #noissue (git-workflow.md)\ngit push origin <branch-name>                 # 기존 PR 갱신이므로 -u 불필요 (이미 origin 추적 중)\n```\n\n커밋·PR 메시지는 **항상 영어**. 기존 PR이 같은 브랜치를 추적하므로 push만으로 PR이 갱신됩니다.\n\n## 6단계: 판단을 PR 코멘트로 남기기 (적용·무시 모두)\n\n각 리뷰 코멘트에 **답글**로 결론을 남깁니다. 답글 본문은 **영어**로, 짧고 명확하게.\n\n```bash\n# 특정 인라인 리뷰 코멘트에 답글 (본문은 영어로 — 플레이스홀더도 영어)\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Applied. <one-line reason in English>\"\n# 또는 무시한 경우\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Not applied. <one-line reason in English>\"\n```\n\n요약 리뷰(인라인이 아닌 총평)에 대응할 때는 PR 본문 코멘트를 사용:\n\n```bash\ngh pr comment {number} --body \"<summary of applied/ignored items in English>\"\n```\n\n## 7단계: 대화창 보고\n\n마지막으로 사용자에게 쉬운 말로 정리해 보여줍니다:\n\n1. **적용한 리뷰**: 무엇을, 왜 타당해서, 어떻게 고쳤는지 (각 한두 문장)\n2. **무시한 리뷰**: 무엇을, 왜 적용하지 않았는지 (각 한두 문장)\n3. **QA 결과**: PASS / FAIL\n4. **반영 결과**: 커밋 해시, 푸시·PR 갱신 여부, 남긴 PR 코멘트\n\n> 적용/무시 어느 쪽이든 \"왜\"가 가장 중요합니다. 비개발자도 납득할 수 있게 설명하세요.\n",".claude/rules/testing.md":"# Rules Skill\n\nPath: `.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/testing.md)","agent-module/plugins/README.md":"# plugins Documentation\n\nPath: `agent-module/plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/README.md)","agent-module/plugins/type-provider-schema.json":"# Plugins Skill\n\nPath: `agent-module/plugins/type-provider-schema.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/type-provider-schema.json)","agent-module/agent-tools/README.md":"# agent-tools Documentation\n\nPath: `agent-module/agent-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-tools/README.md)","agent-module/agent-plugins/README.md":"# agent-plugins Documentation\n\nPath: `agent-module/agent-plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/README.md)","agent-module/plugins/pekko-http/README.md":"# pekko-http Documentation\n\nPath: `agent-module/plugins/pekko-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pekko-http/README.md)","agent-module/plugins/paho-mqtt/README.md":"# paho-mqtt Documentation\n\nPath: `agent-module/plugins/paho-mqtt/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/paho-mqtt/README.md)","agent-module/plugins/oracle-jdbc/README.md":"# oracle-jdbc Documentation\n\nPath: `agent-module/plugins/oracle-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/oracle-jdbc/README.md)","agent-module/plugins/openwhisk/README.md":"# openwhisk Documentation\n\nPath: `agent-module/plugins/openwhisk/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/openwhisk/README.md)","agent-module/plugins/okhttp/README.md":"# okhttp Documentation\n\nPath: `agent-module/plugins/okhttp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/okhttp/README.md)","agent-module/plugins/ning-asynchttpclient/README.md":"# ning-asynchttpclient Documentation\n\nPath: `agent-module/plugins/ning-asynchttpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ning-asynchttpclient/README.md)","agent-module/plugins/mysql-jdbc/README.md":"# mysql-jdbc Documentation\n\nPath: `agent-module/plugins/mysql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mysql-jdbc/README.md)","agent-module/plugins/mybatis/README.md":"# mybatis Documentation\n\nPath: `agent-module/plugins/mybatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mybatis/README.md)","agent-module/plugins/mssql-jdbc/README.md":"# mssql-jdbc Documentation\n\nPath: `agent-module/plugins/mssql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mssql-jdbc/README.md)","agent-module/plugins/mongodb/README.md":"# mongodb Documentation\n\nPath: `agent-module/plugins/mongodb/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mongodb/README.md)","agent-module/plugins/mariadb-jdbc/README.md":"# mariadb-jdbc Documentation\n\nPath: `agent-module/plugins/mariadb-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mariadb-jdbc/README.md)","agent-module/plugins/logback/README.md":"# logback Documentation\n\nPath: `agent-module/plugins/logback/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/logback/README.md)","agent-module/plugins/log4j2/README.md":"# log4j2 Documentation\n\nPath: `agent-module/plugins/log4j2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j2/README.md)","agent-module/plugins/log4j/README.md":"# log4j Documentation\n\nPath: `agent-module/plugins/log4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j/README.md)","agent-module/plugins/ktor/README.md":"# ktor Documentation\n\nPath: `agent-module/plugins/ktor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ktor/README.md)","agent-module/plugins/kotlin-coroutines/README.md":"# kotlin-coroutines Documentation\n\nPath: `agent-module/plugins/kotlin-coroutines/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kotlin-coroutines/README.md)","agent-module/plugins/kafka/README.md":"# kafka Documentation\n\nPath: `agent-module/plugins/kafka/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kafka/README.md)","agent-module/plugins/jtds/README.md":"# jtds Documentation\n\nPath: `agent-module/plugins/jtds/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jtds/README.md)","agent-module/plugins/json-lib/README.md":"# json-lib Documentation\n\nPath: `agent-module/plugins/json-lib/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/json-lib/README.md)","agent-module/plugins/jetty/README.md":"# jetty Documentation\n\nPath: `agent-module/plugins/jetty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jetty/README.md)","agent-module/plugins/jdk-httpclient/README.md":"# jdk-httpclient Documentation\n\nPath: `agent-module/plugins/jdk-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-httpclient/README.md)","agent-module/plugins/jdk-http/README.md":"# jdk-http Documentation\n\nPath: `agent-module/plugins/jdk-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-http/README.md)","agent-module/plugins/jboss/README.md":"# jboss Documentation\n\nPath: `agent-module/plugins/jboss/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jboss/README.md)","agent-module/plugins/jackson/README.md":"# jackson Documentation\n\nPath: `agent-module/plugins/jackson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jackson/README.md)","agent-module/plugins/informix-jdbc/README.md":"# informix-jdbc Documentation\n\nPath: `agent-module/plugins/informix-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/informix-jdbc/README.md)","agent-module/plugins/ibatis/README.md":"# ibatis Documentation\n\nPath: `agent-module/plugins/ibatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ibatis/README.md)","agent-module/plugins/hystrix/README.md":"# hystrix Documentation\n\nPath: `agent-module/plugins/hystrix/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hystrix/README.md)","agent-module/plugins/httpclient5/README.md":"# httpclient5 Documentation\n\nPath: `agent-module/plugins/httpclient5/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient5/README.md)","agent-module/plugins/httpclient4/README.md":"# httpclient4 Documentation\n\nPath: `agent-module/plugins/httpclient4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient4/README.md)","agent-module/plugins/httpclient3/README.md":"# httpclient3 Documentation\n\nPath: `agent-module/plugins/httpclient3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient3/README.md)","agent-module/plugins/hikaricp/README.md":"# hikaricp Documentation\n\nPath: `agent-module/plugins/hikaricp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hikaricp/README.md)","agent-module/plugins/hbase/README.md":"# hbase Documentation\n\nPath: `agent-module/plugins/hbase/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hbase/README.md)","agent-module/plugins/gson/README.md":"# gson Documentation\n\nPath: `agent-module/plugins/gson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/gson/README.md)","agent-module/plugins/grpc/README.md":"# grpc Documentation\n\nPath: `agent-module/plugins/grpc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/grpc/README.md)","agent-module/plugins/google-httpclient/README.md":"# google-httpclient Documentation\n\nPath: `agent-module/plugins/google-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/google-httpclient/README.md)","agent-module/plugins/fastjson/README.md":"# fastjson Documentation\n\nPath: `agent-module/plugins/fastjson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/fastjson/README.md)","agent-module/plugins/elasticsearch8/README.md":"# elasticsearch8 Documentation\n\nPath: `agent-module/plugins/elasticsearch8/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch8/README.md)","agent-module/plugins/elasticsearch/README.md":"# elasticsearch Documentation\n\nPath: `agent-module/plugins/elasticsearch/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch/README.md)","agent-module/plugins/druid/README.md":"# druid Documentation\n\nPath: `agent-module/plugins/druid/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/druid/README.md)","agent-module/plugins/dbcp2/README.md":"# dbcp2 Documentation\n\nPath: `agent-module/plugins/dbcp2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp2/README.md)","agent-module/plugins/dbcp/README.md":"# dbcp Documentation\n\nPath: `agent-module/plugins/dbcp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp/README.md)","agent-module/plugins/db2-jdbc/README.md":"# db2-jdbc Documentation\n\nPath: `agent-module/plugins/db2-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/db2-jdbc/README.md)","agent-module/plugins/dameng-jdbc/README.md":"# dameng-jdbc Documentation\n\nPath: `agent-module/plugins/dameng-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dameng-jdbc/README.md)","agent-module/plugins/cxf/README.md":"# cxf Documentation\n\nPath: `agent-module/plugins/cxf/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cxf/README.md)","agent-module/plugins/cubrid-jdbc/README.md":"# cubrid-jdbc Documentation\n\nPath: `agent-module/plugins/cubrid-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cubrid-jdbc/README.md)","agent-module/plugins/cassandra4/README.md":"# cassandra4 Documentation\n\nPath: `agent-module/plugins/cassandra4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra4/README.md)","agent-module/plugins/cassandra/README.md":"# cassandra Documentation\n\nPath: `agent-module/plugins/cassandra/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra/README.md)","agent-module/plugins/aws-sdk-s3/README.md":"# aws-sdk-s3 Documentation\n\nPath: `agent-module/plugins/aws-sdk-s3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/aws-sdk-s3/README.md)","agent-module/plugins/arcus/README.md":"# arcus Documentation\n\nPath: `agent-module/plugins/arcus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/arcus/README.md)","agent-module/plugins/apache-dubbo/README.md":"# apache-dubbo Documentation\n\nPath: `agent-module/plugins/apache-dubbo/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/apache-dubbo/README.md)","agent-module/plugins/akka-http/README.md":"# akka-http Documentation\n\nPath: `agent-module/plugins/akka-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/akka-http/README.md)","agent-module/plugins/activemq-client/README.md":"# activemq-client Documentation\n\nPath: `agent-module/plugins/activemq-client/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/activemq-client/README.md)","agent-module/plugins/postgresql-jdbc/README.md":"# postgresql-jdbc Documentation\n\nPath: `agent-module/plugins/postgresql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/postgresql-jdbc/README.md)","agent-module/plugins/process/README.md":"# process Documentation\n\nPath: `agent-module/plugins/process/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/process/README.md)","agent-module/plugins/pulsar/README.md":"# pulsar Documentation\n\nPath: `agent-module/plugins/pulsar/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pulsar/README.md)","agent-module/plugins/rabbitmq/README.md":"# rabbitmq Documentation\n\nPath: `agent-module/plugins/rabbitmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rabbitmq/README.md)","agent-module/plugins/reactor/README.md":"# reactor Documentation\n\nPath: `agent-module/plugins/reactor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor/README.md)","agent-module/plugins/reactor-netty/README.md":"# reactor-netty Documentation\n\nPath: `agent-module/plugins/reactor-netty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor-netty/README.md)","agent-module/plugins/redis/README.md":"# redis Documentation\n\nPath: `agent-module/plugins/redis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis/README.md)","agent-module/plugins/redis-lettuce/README.md":"# redis-lettuce Documentation\n\nPath: `agent-module/plugins/redis-lettuce/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-lettuce/README.md)","agent-module/plugins/redis-redisson/README.md":"# redis-redisson Documentation\n\nPath: `agent-module/plugins/redis-redisson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-redisson/README.md)","agent-module/plugins/resilience4j/README.md":"# resilience4j Documentation\n\nPath: `agent-module/plugins/resilience4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/resilience4j/README.md)","agent-module/plugins/rocketmq/README.md":"# rocketmq Documentation\n\nPath: `agent-module/plugins/rocketmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rocketmq/README.md)","agent-module/plugins/rxjava/README.md":"# rxjava Documentation\n\nPath: `agent-module/plugins/rxjava/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rxjava/README.md)","agent-module/plugins/spring/README.md":"# spring Documentation\n\nPath: `agent-module/plugins/spring/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring/README.md)","agent-module/plugins/spring-boot/README.md":"# spring-boot Documentation\n\nPath: `agent-module/plugins/spring-boot/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-boot/README.md)","agent-module/plugins/spring-cloud-sleuth/README.md":"# spring-cloud-sleuth Documentation\n\nPath: `agent-module/plugins/spring-cloud-sleuth/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-cloud-sleuth/README.md)","agent-module/plugins/spring-data-r2dbc/README.md":"# spring-data-r2dbc Documentation\n\nPath: `agent-module/plugins/spring-data-r2dbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-data-r2dbc/README.md)","agent-module/plugins/spring-tx/README.md":"# spring-tx Documentation\n\nPath: `agent-module/plugins/spring-tx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-tx/README.md)","agent-module/plugins/spring-webflux/README.md":"# spring-webflux Documentation\n\nPath: `agent-module/plugins/spring-webflux/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-webflux/README.md)","agent-module/plugins/thread/README.md":"# thread Documentation\n\nPath: `agent-module/plugins/thread/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thread/README.md)","agent-module/plugins/thrift/README.md":"# thrift Documentation\n\nPath: `agent-module/plugins/thrift/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thrift/README.md)","agent-module/plugins/tomcat/README.md":"# tomcat Documentation\n\nPath: `agent-module/plugins/tomcat/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/tomcat/README.md)","agent-module/plugins/undertow/README.md":"# undertow Documentation\n\nPath: `agent-module/plugins/undertow/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow/README.md)","agent-module/plugins/undertow-servlet/README.md":"# undertow-servlet Documentation\n\nPath: `agent-module/plugins/undertow-servlet/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow-servlet/README.md)","agent-module/plugins/user/README.md":"# user Documentation\n\nPath: `agent-module/plugins/user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/user/README.md)","agent-module/plugins/vertx/README.md":"# vertx Documentation\n\nPath: `agent-module/plugins/vertx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/vertx/README.md)","agent-module/plugins/weblogic/README.md":"# weblogic Documentation\n\nPath: `agent-module/plugins/weblogic/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/weblogic/README.md)","agent-module/plugins/websphere/README.md":"# websphere Documentation\n\nPath: `agent-module/plugins/websphere/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/websphere/README.md)","agent-module/agent-plugins/proxy-apache/README.md":"# proxy-apache Documentation\n\nPath: `agent-module/agent-plugins/proxy-apache/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-apache/README.md)","agent-module/agent-plugins/proxy-app/README.md":"# proxy-app Documentation\n\nPath: `agent-module/agent-plugins/proxy-app/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-app/README.md)","agent-module/agent-plugins/proxy-nginx/README.md":"# proxy-nginx Documentation\n\nPath: `agent-module/agent-plugins/proxy-nginx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-nginx/README.md)","agent-module/agent-plugins/proxy-user/README.md":"# proxy-user Documentation\n\nPath: `agent-module/agent-plugins/proxy-user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-user/README.md)","web-frontend/src/main/v3/.claude/rules/api-hooks.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/api-hooks.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/api-hooks.md)","web-frontend/src/main/v3/.claude/rules/code-review-policy.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-review-policy.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-review-policy.md)","web-frontend/src/main/v3/.claude/rules/code-style.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-style.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-style.md)","web-frontend/src/main/v3/.claude/rules/components.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/components.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/components.md)","web-frontend/src/main/v3/.claude/rules/git-workflow.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/git-workflow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/git-workflow.md)","web-frontend/src/main/v3/.claude/rules/i18n.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/i18n.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/i18n.md)","web-frontend/src/main/v3/.claude/rules/monorepo.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/monorepo.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/monorepo.md)","web-frontend/src/main/v3/.claude/rules/routing.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/routing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/routing.md)","web-frontend/src/main/v3/.claude/rules/service-map.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/service-map.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/service-map.md)","web-frontend/src/main/v3/.claude/rules/state-management.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/state-management.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/state-management.md)","web-frontend/src/main/v3/.claude/rules/testing.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/testing.md)","web-frontend/src/main/v3/.claude/rules/tool-usage.md":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/tool-usage.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/tool-usage.md)","web-frontend/src/main/v3/packages/ui/components.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/components.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/components.json)","web-frontend/src/main/v3/packages/ui/package.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/package.json)","web-frontend/src/main/v3/packages/ui/README.md":"# ui Documentation\n\nPath: `web-frontend/src/main/v3/packages/ui/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/README.md)","web-frontend/src/main/v3/packages/ui/tsconfig.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.json)","web-frontend/src/main/v3/packages/ui/tsconfig.node.json":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.node.json)","web-frontend/src/main/v3/packages/server-map/package.json":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/package.json)","web-frontend/src/main/v3/packages/server-map/README.md":"# server-map Documentation\n\nPath: `web-frontend/src/main/v3/packages/server-map/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/README.md)","web-frontend/src/main/v3/packages/server-map/tsconfig.json":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/tsconfig.json)","web-frontend/src/main/v3/packages/scatter-chart/package.json":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/package.json)","web-frontend/src/main/v3/packages/scatter-chart/README.md":"# scatter-chart Documentation\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/README.md)","web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json)","web-frontend/src/main/v3/packages/datetime-picker/package.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/package.json)","web-frontend/src/main/v3/packages/datetime-picker/README.md":"# datetime-picker Documentation\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/README.md)","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json)","web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json)","web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md":"# Subagent: qa-engineer\n\nPath: `web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md)","web-frontend/src/main/v3/.claude/agents/explorer/explorer.md":"# Subagent: explorer\n\nPath: `web-frontend/src/main/v3/.claude/agents/explorer/explorer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/explorer/explorer.md)","web-frontend/src/main/v3/.claude/agents/debugger/debugger.md":"# Subagent: debugger\n\nPath: `web-frontend/src/main/v3/.claude/agents/debugger/debugger.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/debugger/debugger.md)","web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md":"# Subagent: code-reviewer\n\nPath: `web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md)","web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md":"# Prompts Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md)","web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json":"# .storybook Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json)","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json)","web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json)","web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json)","web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json)","web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json)","web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json)"},"items":[{"name":"build.md","path":".claude/rules/build.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/build.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"---\ndescription: Maven build commands for multi-module project, frontend build\nglobs:\n---\n\n## Build Commands\n\nMaven wrapper (`./mvnw`) is the build tool. This is a multi-module Maven project with 30+ top-level modules.\n\n```bash\n# Build everything (skip tests)\n./mvnw install -Dmaven.test.skip=true\n\n# Build specific modules with dependencies\n./mvnw install -pl agent -am -Dmaven.test.skip=true\n./mvnw install -pl collector -am -Dmaven.test.skip=true\n./mvnw install -pl web -am -Dmaven.test.skip=true\n\n# Build web without frontend\n./mvnw install -pl web -am -Dbuild.frontend.skip=true -Dmaven.test.skip=true\n```\n\n## Frontend\n\nLocated at `web-frontend/src/main/v3/`. Built via Maven frontend plugin using Yarn. Can be skipped with `-Dbuild.frontend.skip=true`.","frontmatter":{"description":"Maven build commands for multi-module project, frontend build","globs":null},"isInternal":false,"tokens":199,"sizeBytes":758},{"name":"testing.md","path":".claude/rules/testing.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/testing.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/testing.md)","tokens":300,"sizeBytes":164},{"name":"type-provider-schema.json","path":"agent-module/plugins/type-provider-schema.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/type-provider-schema.json","title":"Plugins Skill","category":"anthropic-skill","format":"json","content":"# Plugins Skill\n\nPath: `agent-module/plugins/type-provider-schema.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/type-provider-schema.json)","tokens":300,"sizeBytes":210},{"name":"api-hooks.md","path":"web-frontend/src/main/v3/.claude/rules/api-hooks.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/api-hooks.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/api-hooks.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/api-hooks.md)","tokens":300,"sizeBytes":218},{"name":"code-review-policy.md","path":"web-frontend/src/main/v3/.claude/rules/code-review-policy.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-review-policy.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-review-policy.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-review-policy.md)","tokens":300,"sizeBytes":236},{"name":"code-style.md","path":"web-frontend/src/main/v3/.claude/rules/code-style.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-style.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-style.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-style.md)","tokens":300,"sizeBytes":220},{"name":"components.md","path":"web-frontend/src/main/v3/.claude/rules/components.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/components.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/components.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/components.md)","tokens":300,"sizeBytes":220},{"name":"git-workflow.md","path":"web-frontend/src/main/v3/.claude/rules/git-workflow.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/git-workflow.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/git-workflow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/git-workflow.md)","tokens":300,"sizeBytes":224},{"name":"i18n.md","path":"web-frontend/src/main/v3/.claude/rules/i18n.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/i18n.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/i18n.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/i18n.md)","tokens":300,"sizeBytes":208},{"name":"monorepo.md","path":"web-frontend/src/main/v3/.claude/rules/monorepo.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/monorepo.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/monorepo.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/monorepo.md)","tokens":300,"sizeBytes":216},{"name":"routing.md","path":"web-frontend/src/main/v3/.claude/rules/routing.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/routing.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/routing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/routing.md)","tokens":300,"sizeBytes":214},{"name":"service-map.md","path":"web-frontend/src/main/v3/.claude/rules/service-map.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/service-map.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/service-map.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/service-map.md)","tokens":300,"sizeBytes":222},{"name":"state-management.md","path":"web-frontend/src/main/v3/.claude/rules/state-management.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/state-management.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/state-management.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/state-management.md)","tokens":300,"sizeBytes":232},{"name":"testing.md","path":"web-frontend/src/main/v3/.claude/rules/testing.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/testing.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/testing.md)","tokens":300,"sizeBytes":214},{"name":"tool-usage.md","path":"web-frontend/src/main/v3/.claude/rules/tool-usage.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/tool-usage.md","title":"Rules Skill","category":"anthropic-skill","format":"markdown","content":"# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/tool-usage.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/tool-usage.md)","tokens":300,"sizeBytes":220},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md","title":"add-translation","category":"anthropic-skill","format":"markdown","content":"---\nname: add-translation\ndescription: 영어와 한국어 로케일 파일 모두에 i18n 번역 키를 추가합니다. 사용자 노출 문자열을 추가하거나, 번역 키가 누락되었거나, 새 UI 텍스트를 국제화할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 번역 키 추가\n\n영어 텍스트 `$1`과 한국어 텍스트 `$2`를 가진 번역 키 `$0`을 추가합니다.\n\n## 단계\n\n1. `packages/ui/src/constants/locales/en.json` 읽기\n2. `packages/ui/src/constants/locales/ko.json` 읽기\n3. 키 접두사를 기반으로 올바른 섹션 결정 (COMMON, SERVER_MAP, TRANSACTION 등)\n4. 올바른 섹션의 **두 파일 모두**에 키 추가, 섹션 내 알파벳 순서 유지\n5. 한국어 텍스트가 제공되지 않은 경우, 나중에 쉽게 찾아 바꿀 수 있도록 `[TODO]` 접두사를 붙인 영어 텍스트를 플레이스홀더로 추가 (예: `\"[TODO] English text\"`)\n\n## 키 네이밍\n- 점으로 구분된 섹션을 사용하는 SCREAMING_SNAKE_CASE\n- 예시: `COMMON.SAVE`, `SERVER_MAP.NODE_COUNT`, `ERROR_ANALYSIS.CHART_TITLE`\n\n## 가이드라인\n- 항상 en.json과 ko.json을 동시에 업데이트\n- 한국어 번역은 직역 금지, 자연스러운 한국어로 작성\n- 동적 값은 이중 중괄호로 보간: `\"Hello, {{name}}!\"` / `\"안녕하세요, {{name}}님!\"`\n- 복수형에는 i18next 복수 접미사 사용: `_one`, `_other`\n","frontmatter":{"name":"add-translation","description":"영어와 한국어 로케일 파일 모두에 i18n 번역 키를 추가합니다. 사용자 노출 문자열을 추가하거나, 번역 키가 누락되었거나, 새 UI 텍스트를 국제화할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":514,"sizeBytes":1400},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md","title":"apply-review","category":"anthropic-skill","format":"markdown","content":"---\nname: apply-review\ndescription: 현재 작업 중인 PR에 달린 코드 리뷰를 확인하고, 타당한 리뷰는 코드를 고쳐 반영(커밋·푸시·PR 갱신)하고, 부당한 리뷰는 이유를 설명하며 무시합니다. PR 리뷰 코멘트를 반영하거나, 리뷰 피드백에 대응하거나, \"리뷰 반영\", \"리뷰 적용\", \"코드리뷰 처리\"를 요청할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰 반영 (apply-review)\n\n현재 작업의 PR에 달린 코드 리뷰를 가져와 **하나씩 평가**하고, 타당하면 코드에 반영하고 부당하면 무시합니다.\n모든 판단은 **대화창에 설명**하고 **PR 코멘트로도 남깁니다** (적용한 것·무시한 것 모두).\n\n## 핵심 원칙\n\n- **모든 설명은 개발자가 아니어도 이해할 수 있게, 짧고 쉽게.** 전문 용어 대신 \"무엇을 왜 바꿨는지/안 바꿨는지\"를 한두 문장으로.\n- **언어 규칙**: 사용자 대화창 설명은 **한국어**, PR 코멘트·커밋 메시지·PR 본문은 **영어** (`.claude/rules/git-workflow.md`).\n- **리뷰를 맹목적으로 따르지 않습니다.** 각 리뷰가 정말 맞는지, 우리 코드 맥락에서 타당한지 직접 판단합니다. 틀리거나 불필요하면 정중히 무시하고 이유를 댑니다.\n- **되돌리기 어려운 작업(커밋·푸시·PR 갱신) 전에는 반드시 `/qa-pr`을 통과해야 합니다.**\n\n## 0단계: PR 컨텍스트 확정\n\n먼저 지금 어떤 PR을 다루는지 정합니다.\n\n```bash\ngit branch --show-current\ngh pr view --json number,title,url\n```\n\n다음 두 경우에는 **작업을 멈추고 사용자에게 PR 링크를 요청하세요.** 추측해서 진행하지 않습니다.\n\n- 현재 브랜치가 `master`인 경우 (master에서는 직접 작업하지 않습니다 — `.claude/rules/git-workflow.md`)\n- `gh pr view`가 실패하는 등 **현재 컨텍스트로 PR을 알 수 없는 경우**\n\n요청 예시: \"현재 브랜치가 master라(또는 연결된 PR을 찾지 못해) 어떤 PR의 리뷰를 반영할지 알 수 없어요. PR 링크를 알려주세요.\"\n\n링크를 받으면 거기서 `{owner}/{repo}`와 PR 번호를 파싱하고, 해당 PR 브랜치로 이동해 작업합니다:\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\n```\n\n체크아웃 후 다시 `git branch --show-current`로 master가 아님을 확인합니다.\n리모트: `origin`=내 포크(jihea-park/pinpoint), `upstream`=pinpoint-apm/pinpoint.\n\n## 1단계: 리뷰 수집\n\n확정된 PR의 리뷰 전부(요약 리뷰 + 인라인 코멘트, Copilot·사람 모두)를 가져옵니다.\n\n```bash\n# PR 번호와 저장소가 아직 없으면 다시 확인\ngh pr view --json number,title,url\n\n# 리뷰 요약(승인/변경요청/총평) — 리뷰어와 본문\ngh api repos/{owner}/{repo}/pulls/{number}/reviews \\\n  --jq '.[] | {id, user: .user.login, state, body}'\n\n# 인라인 코드 코멘트 — 파일·라인·내용·comment id (반영 대상의 핵심)\ngh api repos/{owner}/{repo}/pulls/{number}/comments \\\n  --jq '.[] | {id, user: .user.login, path, line, body}'\n```\n\n`{owner}/{repo}`는 PR이 올라간 저장소(보통 `pinpoint-apm/pinpoint`). 위 `gh pr view`의 `url`(예: `https://github.com/pinpoint-apm/pinpoint/pull/13913`)에서 파싱해 채웁니다.\n이미 답글이 달려 처리된 코멘트는 중복 대응하지 않도록 `in_reply_to_id`가 없는(최상위) 코멘트 위주로 봅니다.\n\n## 2단계: 각 리뷰를 하나씩 평가\n\n리뷰 코멘트마다 다음을 따집니다. **추측하지 말고 실제 코드를 열어 확인하세요.**\n\n1. **무엇을 지적하는가** — 코멘트가 가리키는 파일·라인을 직접 읽습니다.\n2. **타당한가** — 우리 코드 맥락에서 실제 문제인지, 프로젝트 규약(`.claude/rules/`)에 비춰 맞는지 판단합니다.\n3. **부수효과는 없는가** — 고쳤을 때 다른 동작이 깨지지 않는지 봅니다.\n\n판단은 두 갈래입니다:\n\n- **타당함 → 반영** (3단계로)\n- **부당하거나 불필요함 → 무시**: 왜 적용하지 않는지 쉬운 말로 설명합니다. 예) 리뷰가 가정한 상황이 실제로는 생기지 않음 / 이미 다른 곳에서 처리됨 / 이슈 범위 밖 / 제안대로면 오히려 기존 동작이 깨짐.\n\n> 부당해 보여도 단정하기 전에 한 번 더 코드로 확인하세요. 반대로 \"리뷰어가 그렇게 말했으니까\"는 적용의 이유가 될 수 없습니다.\n\n## 3단계: 타당한 리뷰 반영 — 영향 분석 후 수정\n\n코드를 고치기 전에 `.claude/rules/code-review-policy.md`의 회귀 방지 절차를 따릅니다:\n\n- 고칠 파일의 **모든 호출자·소비자**를 먼저 파악합니다 (타입/훅/아톰/props/엔드포인트 변경 시 사용처 전부 Grep).\n- 수정이 **이번 PR이 해결하려던 이슈와 충돌하지 않는지** 확인합니다. (PR 제목·본문·연결 이슈의 의도를 다시 읽기)\n- 수정 후, 영향받은 파일을 다시 읽어 기존 시그니처·반환 타입·props·import 경로가 깨지지 않았는지 검증합니다.\n\n여러 리뷰를 반영할 경우 관련 수정을 모아 **하나의 커밋**으로 묶습니다(성격이 전혀 다르면 분리 가능).\n\n## 4단계: 리베이스로 최종 코드 만든 뒤 `/qa-pr` 필수 (게이트)\n\nQA는 **커밋·푸시될 최종 코드**에 대해 해야 의미가 있습니다. 리베이스로 충돌을 해결하면 코드가 바뀌므로, **리베이스를 먼저 끝내고 그 결과에 `/qa-pr`을 실행**합니다. (QA 뒤에 리베이스를 하면 변경된 코드가 검증되지 않은 채 커밋될 수 있습니다.)\n\n```bash\n# 1) 먼저 upstream 최신화 리베이스 — 충돌이 있으면 해결까지 완료 (git-workflow.md)\ngit fetch upstream master\ngit rebase upstream/master\n```\n\n```text\n# 2) 그 다음 /qa-pr 실행 — 빌드(yarn build)·테스트(yarn test)·동작 QA·회귀 점검\n```\n\n판정이 **FAIL이면 절대 커밋하지 말고** 문제를 먼저 해결합니다. (`.claude/rules/git-workflow.md`의 QA 게이트)\n`/qa-pr` 통과 후 셀프 체크: 디버그 코드(`console.log` 등) 없음, 코드 스타일 준수, 기존 기능 정상.\n\n## 5단계: 커밋 · 푸시 · PR 갱신\n\n리베이스와 QA가 모두 끝나고 PASS일 때만 진행합니다.\n\n```bash\ngit add <변경 파일>\ngit commit -m \"[#issue_number] Description\"   # 영어로. 같은 플랫폼이면 #issue_number, 다른 플랫폼이면 #noissue (git-workflow.md)\ngit push origin <branch-name>                 # 기존 PR 갱신이므로 -u 불필요 (이미 origin 추적 중)\n```\n\n커밋·PR 메시지는 **항상 영어**. 기존 PR이 같은 브랜치를 추적하므로 push만으로 PR이 갱신됩니다.\n\n## 6단계: 판단을 PR 코멘트로 남기기 (적용·무시 모두)\n\n각 리뷰 코멘트에 **답글**로 결론을 남깁니다. 답글 본문은 **영어**로, 짧고 명확하게.\n\n```bash\n# 특정 인라인 리뷰 코멘트에 답글 (본문은 영어로 — 플레이스홀더도 영어)\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Applied. <one-line reason in English>\"\n# 또는 무시한 경우\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Not applied. <one-line reason in English>\"\n```\n\n요약 리뷰(인라인이 아닌 총평)에 대응할 때는 PR 본문 코멘트를 사용:\n\n```bash\ngh pr comment {number} --body \"<summary of applied/ignored items in English>\"\n```\n\n## 7단계: 대화창 보고\n\n마지막으로 사용자에게 쉬운 말로 정리해 보여줍니다:\n\n1. **적용한 리뷰**: 무엇을, 왜 타당해서, 어떻게 고쳤는지 (각 한두 문장)\n2. **무시한 리뷰**: 무엇을, 왜 적용하지 않았는지 (각 한두 문장)\n3. **QA 결과**: PASS / FAIL\n4. **반영 결과**: 커밋 해시, 푸시·PR 갱신 여부, 남긴 PR 코멘트\n\n> 적용/무시 어느 쪽이든 \"왜\"가 가장 중요합니다. 비개발자도 납득할 수 있게 설명하세요.\n","frontmatter":{"name":"apply-review","description":"현재 작업 중인 PR에 달린 코드 리뷰를 확인하고, 타당한 리뷰는 코드를 고쳐 반영(커밋·푸시·PR 갱신)하고, 부당한 리뷰는 이유를 설명하며 무시합니다. PR 리뷰 코멘트를 반영하거나, 리뷰 피드백에 대응하거나, \"리뷰 반영\", \"리뷰 적용\", \"코드리뷰 처리\"를 요청할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":3075,"sizeBytes":8108},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md","title":"create-api-hook","category":"anthropic-skill","format":"markdown","content":"---\nname: create-api-hook\ndescription: useGetXxx 패턴에 따라 새 React Query API 훅을 생성합니다. 새 백엔드 API를 연동하거나, 엔드포인트에 대한 훅이 필요하거나, 데이터 페칭 로직을 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 API 훅 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 엔드포인트에 대한 새 API 훅을 생성합니다.\n\n다음 단계를 따르세요:\n\n## 1. 기존 패턴 분석\n- `packages/ui/src/hooks/api/reactQueryHelper.ts`를 읽어 queryFn과 queryClient 이해\n- `packages/ui/src/constants/EndPoints.ts`에서 엔드포인트 네이밍 확인\n- `packages/ui/src/hooks/api/`의 유사한 기존 훅에서 패턴 파악\n\n## 2. 엔드포인트 정의\n`packages/ui/src/constants/EndPoints.ts`에 엔드포인트 상수 추가:\n```typescript\nexport const NEW_ENDPOINT = `/api/path/to/endpoint`;\n```\n\n## 3. 타입 정의\n`packages/ui/src/constants/types/`에 타입 생성 또는 확장:\n```typescript\nexport namespace GetNewData {\n  export interface Parameters {\n    applicationName: string;\n    from: number;\n    to: number;\n    // ... 기타 파라미터\n  }\n  export interface Response {\n    // ... 응답 형태\n  }\n}\n```\n`packages/ui/src/constants/types/index.ts`에서 익스포트.\n\n## 4. 훅 생성\n`packages/ui/src/hooks/api/useGetNewData.ts` 생성:\n```typescript\nimport { useQuery } from '@tanstack/react-query';\nimport { END_POINTS, GetNewData } from '@pinpoint-fe/ui/src/constants';\nimport { convertParamsToQueryString } from '@pinpoint-fe/ui/src/utils';\nimport { queryFn } from './reactQueryHelper';\n\nexport const useGetNewData = (params: GetNewData.Parameters) => {\n  const queryString = convertParamsToQueryString(params);\n\n  return useQuery<GetNewData.Response>({\n    queryKey: [END_POINTS.NEW_ENDPOINT, queryString],\n    queryFn: queryFn(`${END_POINTS.NEW_ENDPOINT}?${queryString}`),\n    enabled: !!params.applicationName,\n    gcTime: 30000,\n  });\n};\n```\n\n## 5. 훅 익스포트\n`packages/ui/src/hooks/api/index.ts` (또는 해당하는 배럴 파일)에서 익스포트.\n\n## 6. 핵심 가이드라인\n- 필수 파라미터 없이 쿼리가 실행되지 않도록 `enabled` 사용\n- `reactQueryHelper.ts`의 `queryFn` 사용 — 직접 fetch를 구현하지 마세요\n- 쿼리 키에는 응답에 영향을 미치는 엔드포인트와 모든 파라미터 포함\n- POST 뮤테이션은 `useQuery` 대신 `useMutation` 사용\n- 폴링의 경우 `gcTime: 0` 설정, 부드러운 전환을 위해 `placeholderData: (prev) => prev` 사용\n","frontmatter":{"name":"create-api-hook","description":"useGetXxx 패턴에 따라 새 React Query API 훅을 생성합니다. 새 백엔드 API를 연동하거나, 엔드포인트에 대한 훅이 필요하거나, 데이터 페칭 로직을 추가할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":796,"sizeBytes":2537},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md","title":"create-component","category":"anthropic-skill","format":"markdown","content":"---\nname: create-component\ndescription: 프로젝트의 shadcn/ui + Tailwind 패턴에 따라 새 React 컴포넌트를 생성합니다. UI 프리미티브(버튼, 다이얼로그 등) 또는 도메인 컴포넌트(ServerMap, Inspector 등)를 새로 만들 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 컴포넌트 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 컴포넌트를 생성합니다.\n\n## 1. 컴포넌트 유형 결정\n\n### UI 프리미티브 (packages/ui/src/components/ui/)\n재사용 가능한 일반 UI 컴포넌트(버튼 변형, 다이얼로그, 입력 등):\n- shadcn/ui 패턴 준수: Radix UI + CVA + Tailwind\n- `@pinpoint-fe/ui/src/lib/utils`의 `cn()` 사용\n- 적절한 경우 Radix Slot을 통한 `asChild` 지원\n- ref 전달을 위한 `React.forwardRef` 사용\n- CVA(class-variance-authority)로 variants 정의\n\n### 도메인 컴포넌트 (packages/ui/src/components/{DomainName}/)\n기능별 컴포넌트(ServerMap, ErrorAnalysis 등):\n- `packages/ui/src/components/` 아래 서브디렉토리 생성\n- UI 프리미티브를 조합하여 구성\n- 데이터 페칭에 React Query 훅 사용\n- 공유 상태에 Jotai 아톰 사용\n- 비동기 콘텐츠를 Suspense + ErrorBoundary로 감싸기\n\n## 2. 기존 예시 읽기\n- UI 프리미티브: `packages/ui/src/components/ui/button.tsx` 또는 `dialog.tsx` 읽기\n- 도메인 컴포넌트: 타겟과 유사한 기존 도메인 컴포넌트 읽기\n\n## 3. 컴포넌트 생성\n\n### UI 프리미티브 템플릿\n```tsx\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\n\nconst componentVariants = cva('base-classes', {\n  variants: { variant: { default: '...', outline: '...' }, size: { default: '...', sm: '...' } },\n  defaultVariants: { variant: 'default', size: 'default' },\n});\n\nexport interface ComponentProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof componentVariants> {}\n\nconst Component = React.forwardRef<HTMLDivElement, ComponentProps>(\n  ({ className, variant, size, ...props }, ref) => (\n    <div ref={ref} className={cn(componentVariants({ variant, size, className }))} {...props} />\n  ),\n);\nComponent.displayName = 'Component';\nexport { Component, componentVariants };\n```\n\n### 도메인 컴포넌트 템플릿\n```tsx\nimport React, { Suspense } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { useTranslation } from 'react-i18next';\nimport { useAtomValue } from 'jotai';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\nimport { someSearchParamAtom } from '@pinpoint-fe/ui/src/atoms';\nimport { useGetMyData } from '@pinpoint-fe/ui/src/hooks/api';\n\nexport interface MyComponentProps {\n  className?: string;\n}\n\nconst MyComponentContent = ({ className }: MyComponentProps) => {\n  const { t } = useTranslation();\n  const searchParam = useAtomValue(someSearchParamAtom);\n  const { data } = useGetMyData({ param: searchParam });\n\n  if (!data) return null;\n\n  return <div className={cn('...', className)}>{/* 렌더링 */}</div>;\n};\n\nexport const MyComponent = ({ className }: MyComponentProps) => (\n  <ErrorBoundary fallback={<div>Error</div>}>\n    <Suspense fallback={<div>Loading...</div>}>\n      <MyComponentContent className={className} />\n    </Suspense>\n  </ErrorBoundary>\n);\n```\n\n## 4. 스타일링 규칙\n- Tailwind CSS만 사용 — 인라인 스타일, CSS 모듈 금지\n- 테마에는 CSS 변수 사용: `var(--ui-primary)`, `var(--ui-border)`\n- 모든 className 합성에 `cn()` 사용\n- Tailwind 브레이크포인트로 반응형 디자인\n\n## 5. 완료\n- `packages/ui/src/components/index.ts` (또는 해당 서브디렉토리의 `index.ts`)에서 컴포넌트 익스포트\n- `yarn build`로 TypeScript 오류 없음 확인\n","frontmatter":{"name":"create-component","description":"프로젝트의 shadcn/ui + Tailwind 패턴에 따라 새 React 컴포넌트를 생성합니다. UI 프리미티브(버튼, 다이얼로그 등) 또는 도메인 컴포넌트(ServerMap, Inspector 등)를 새로 만들 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":1213,"sizeBytes":3784},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md","title":"create-page","category":"anthropic-skill","format":"markdown","content":"---\nname: create-page\ndescription: Pinpoint 프로젝트 패턴에 따라 새 페이지를 생성합니다. 애플리케이션에 새 라우트/페이지를 추가하거나, 새 화면을 만들거나, 기존 라우팅 구조에 페이지를 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 페이지 생성\n\n**인자 형식**: `/create-page <PageName> [설명]`\n- `$0` — 생성할 페이지 이름 (PascalCase, 예: `RealTimeDashboard`)\n- `$ARGUMENTS` — 페이지 목적 설명 (선택 사항, 예: `실시간 메트릭 대시보드`)\n- 인자 없이 실행하면 사용자에게 페이지 이름과 목적을 먼저 질문합니다.\n\n`$ARGUMENTS` 설명을 가진 `$0` 페이지를 생성합니다.\n\n다음 단계를 엄격히 따르세요:\n\n## 1. 기존 페이지 분석\n- `packages/ui/src/constants/path.ts`를 읽어 APP_PATH 패턴 파악\n- `apps/web/src/routes/index.tsx`를 읽어 라우팅 구조 확인\n- `packages/ui/src/pages/`의 유사한 기존 페이지와 `apps/web/src/pages/`의 래퍼 읽기\n\n## 2. 파일 생성 (순서대로)\n\n### 2a. 라우트 경로 추가\n`packages/ui/src/constants/path.ts`의 `APP_PATH`에 새 경로 상수 추가.\n\n### 2b. 페이지 컴포넌트 생성\n`packages/ui/src/pages/{PageName}.tsx` 생성:\n- `@pinpoint-fe/ui`에서 훅과 컴포넌트 임포트\n- `configuration` prop 받기 (페이지 래퍼의 `configurationAtom`에서 읽음)\n- 적절한 검색 파라미터 훅 사용\n- 데이터 페칭에 React Query 훅 사용\n\n### 2c. 페이지 컴포넌트 익스포트\n`packages/ui/src/pages/index.ts`에서 페이지 익스포트 (없으면 생성).\n\n### 2d. 라우트 로더 생성 (날짜 파라미터가 필요한 경우)\n기존 로더의 패턴을 따라 `packages/ui/src/loader/{pageName}.ts` 생성:\n- URL 파라미터에서 application 파싱\n- `periodMax` 설정에 대해 날짜 범위 검증\n- 유효하지 않으면 올바른 날짜로 리다이렉트\n\n### 2e. 페이지 래퍼 생성\n`apps/web/src/pages/<PageName>.tsx` 생성:\n```tsx\n// <PageName>을 실제 페이지 이름으로 교체 (예: Inspector, ErrorAnalysis)\nimport { useAtomValue } from 'jotai';\nimport { <PageName>Page } from '@pinpoint-fe/ui';\nimport { configurationAtom } from '@pinpoint-fe/ui/src/atoms';\n\nexport default function <PageName>() {\n  const configuration = useAtomValue(configurationAtom);\n  return <<PageName>Page configuration={configuration} />;\n}\n```\n\n### 2f. 라우트 추가\n`apps/web/src/routes/index.tsx`에 라우트 추가:\n- 상단에 lazy 임포트 추가\n- `InitialFetchOutlet` children에 라우트 항목 추가 (설정 페이지는 `ConfigurationOutlet`)\n- 로더와 엘리먼트 포함\n\n## 3. i18n 키 추가\n사용자 노출 문자열을 `packages/ui/src/constants/locales/`의 `en.json`과 `ko.json` 모두에 추가.\n\n## 4. 검증\n- 라우트 경로가 고유한지 확인\n- 모든 임포트가 올바른지 확인\n- 라우트 트리에서 페이지가 올바른 레이아웃 outlet 내에 배치되었는지 확인\n","frontmatter":{"name":"create-page","description":"Pinpoint 프로젝트 패턴에 따라 새 페이지를 생성합니다. 애플리케이션에 새 라우트/페이지를 추가하거나, 새 화면을 만들거나, 기존 라우팅 구조에 페이지를 추가할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":1001,"sizeBytes":3000},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md","title":"merge-check","category":"anthropic-skill","format":"markdown","content":"---\nname: merge-check\ndescription: PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. \"머지해도 되나\", \"머지 전에 봐줘\", \"이 PR 리뷰해줘\", \"PR 괜찮은지 확인\", \"approve해도 되나\", \"머지 전에 뭘 확인해야 하나\" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다.\n---\n\n# 머지 전 최종 리뷰 (merge-check)\n\n**이 스킬의 목적은 \"머지 버튼을 눌러도 안전한가\"에 답하는 것입니다.**\n\n가장 중요한 판단 기준은 하나입니다: **기존에 잘 동작하던 기능이 그대로 동작하는가.**\n새 기능이 조금 부족한 건 다음 PR에서 고칠 수 있지만, 잘 쓰던 기능이 깨지면 사용자가 바로 피해를 봅니다.\n그래서 이 스킬은 \"새로 추가된 코드가 예쁜가\"보다 **\"이 변경이 무엇을 건드렸고, 그것을 쓰던 곳들이 아직 멀쩡한가\"**에 시간을 더 씁니다.\n\n## 절대 하지 않는 것\n\n- **머지하지 않습니다.** `gh pr merge`는 어떤 경우에도 실행하지 않습니다. 이 스킬은 판단만 하고, 머지는 사용자가 합니다.\n- **코드를 고치지 않습니다.** 문제를 찾으면 보고합니다. 고치는 건 별개 작업(`/apply-review`)입니다.\n- **GitHub에 아무것도 쓰지 않습니다.** 결과는 대화창에만 한국어로 보고합니다. PR 코멘트나 Approve는 사용자가 명시적으로 요청할 때만, 확인을 받고 남깁니다.\n- **확인하지 않은 것을 확인한 척하지 않습니다.** 못 본 건 \"확인 못 함\"으로 적습니다. 근거 없는 ✅ 는 이 스킬을 쓰는 의미를 지웁니다.\n\n## 0단계: 어떤 PR인지 확정 + 작업 중인 내용 보호\n\n```bash\ngit branch --show-current\ngit status --porcelain          # 커밋 안 된 작업이 있는지 먼저 확인\ngit rev-parse HEAD              # 로컬이 보고 있는 코드\ngh pr view --json number,title,url,headRefName,headRefOid,baseRefName,state,mergeable,author\n```\n\n**대상 PR 정하기**\n\n- `gh pr view`가 PR을 찾으면 → 그 PR이 대상입니다. 링크를 따로 받지 않습니다.\n- 못 찾거나 현재 브랜치가 `master`이면 → **멈추고 PR 링크를 요청**합니다. 추측하지 않습니다.\n  예: \"현재 브랜치에 연결된 PR을 찾지 못했어요. 리뷰할 PR 링크를 알려주세요.\"\n- 사용자가 링크를 줬으면 항상 그 링크가 우선입니다. 링크에서 `{owner}/{repo}`와 PR 번호를 파싱합니다.\n\n**내가 읽는 코드가 정말 그 PR의 코드인가 (놓치기 쉬움)**\n\n`git rev-parse HEAD`와 PR의 `headRefOid`가 다르면, **로컬에서 보고 있는 코드가 PR에 올라간 코드가\n아닙니다.** 리베이스했지만 아직 푸시하지 않은 경우가 흔합니다. 이때 그냥 리뷰하면 \"PR을 검증했다\"고\n말할 수 없습니다. 두 커밋의 코드가 실제로 같은지 확인하세요:\n\n```bash\ngit diff --stat {headRefOid} HEAD    # 비어 있으면 코드는 동일하고 베이스만 다르다\n```\n\n- **차이가 없거나 무관한 파일뿐이면** → 그대로 진행하고, 보고에 \"로컬이 리베이스로 앞서 있으나 코드는\n  동일\"이라고 한 줄 적습니다.\n- **차이가 있으면** → 어느 쪽을 리뷰할지 사용자에게 확인합니다. 로컬만 있는 수정은 PR에 없으므로,\n  그것까지 통과 판정에 넣으면 실제 머지될 코드와 어긋납니다.\n\n**사용자의 작업 보호**\n\n검증을 위해 브랜치를 옮겨야 할 수도 있습니다. 다만 항상 위험한 건 아니니 구분하세요:\n\n- **이미 그 PR의 브랜치에 있으면** 체크아웃이 필요 없습니다. 그냥 진행합니다.\n- **untracked 파일(`??`)만 있으면** 체크아웃·머지가 그 파일을 건드리지 않으므로 그대로 진행합니다.\n  (보고에 한 줄 언급만)\n- **수정·스테이징된 변경(`M`, `A` 등)이 있으면** 체크아웃하지 말고 사용자에게 먼저 묻습니다:\n  \"커밋되지 않은 변경이 있어요. ① 코드 읽기만으로 리뷰 ② stash 후 진행 — 어느 쪽으로 할까요?\"\n\n브랜치를 옮겼다면 **리뷰가 끝나고 반드시 원래 브랜치로 돌려놓고**, 그 사실을 보고에 적습니다.\n\n## 1단계: 이 PR이 무엇을 했는지 먼저 요약한다\n\n판정보다 요약이 먼저입니다. **무엇을 하려던 PR인지 모르면 \"제대로 했는지\"도 판단할 수 없습니다.**\n\n```bash\ngh pr view {number} --repo {owner}/{repo} --json title,body,commits,files,additions,deletions\n\n# 변경 규모는 git으로 봅니다. (`gh pr diff`에는 --stat이 없는 버전이 있어 그대로 쓰면 실패합니다.)\ngit fetch upstream master\ngit diff --stat upstream/master...HEAD          # 세 점: 공통 조상부터 이 브랜치까지\n```\n\n읽을 것:\n\n- **PR 제목·본문·연결된 이슈** — 이 PR이 풀려던 문제가 무엇인가\n- **커밋 메시지들** — 어떤 순서로 무엇을 했는가\n- **변경 파일 목록과 규모** — 어디를 건드렸는가\n\n여기서 나오는 요약은 사용자에게 보여주는 첫 항목이며, **의도(PR 본문)와 실제(diff)가 어긋나는지**를 보는 기준이기도 합니다.\n\"본문에는 A만 고쳤다고 썼는데 diff에는 B도 바뀌어 있다\" — 이건 그 자체로 리뷰 대상입니다.\n의도하지 않은 파일이 섞여 들어온 것일 수 있고, 그게 회귀의 흔한 원인입니다.\n\n## 2단계: 실제로 빌드·테스트를 돌린다\n\n기본 동작은 **실제 실행**입니다. 코드를 읽어서 \"괜찮아 보인다\"와 빌드가 통과하는 것은 다른 증거입니다.\n(사용자가 \"빠르게 봐줘\"라고 했다면 이 단계를 건너뛰고 CI 결과 조회로 대체하되, **보고에 \"직접 실행하지 않음\"을 명시**합니다.)\n\n검증은 **머지된 뒤의 코드**에 대해 해야 의미가 있습니다. PR 브랜치 단독으로 통과해도,\n그 사이 master에 들어간 다른 변경과 부딪히면 머지 직후에 깨집니다. 그래서 합쳐 놓고 돌립니다.\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\ngit fetch upstream master\ngit merge --no-commit --no-ff upstream/master   # 커밋하지 않고 합친 상태만 만든다\n```\n\n- **충돌이 나면** → `git merge --abort` 후, 충돌 파일을 보고 항목으로 올립니다(조건부 또는 머지 불가 사유).\n  이후 리뷰는 PR 브랜치 상태로 코드 읽기 중심으로 이어갑니다.\n- **깨끗하게 합쳐지면** → 그 상태(= 머지 후 master의 모습)에서 검증을 돌립니다.\n\n```bash\n# web-frontend/src/main/v3 에서\nyarn build      # TypeScript 검사 + 프로덕션 빌드\nyarn test       # 전체 워크스페이스 테스트\nyarn lint\n```\n\n검증이 끝나면 `git merge --abort`로 합친 상태를 되돌립니다. (머지 결과를 남기지 않습니다.)\n\n- **빌드 실패 → 무조건 머지 불가.** 더 볼 것 없습니다.\n- **테스트 실패 → 실패한 테스트가 이 PR 때문인지 확인.** upstream/master에서도 같은 테스트가 실패하면 기존 문제입니다.\n  그 구분을 하지 않고 \"테스트 실패\"라고만 보고하면 사용자가 헛수고합니다.\n- **CI 결과도 함께 봅니다.** `gh pr checks`는 실패 여부만 알려주고 이유를 말해주지 않으니,\n  실패한 것이 있으면 반드시 내용까지 읽습니다. (품질 게이트 실패는 저장소 자체의 머지 기준입니다.)\n\n```bash\ngh pr checks {number} --repo {owner}/{repo}\n\n# 실패한 검사의 실제 사유 (예: SonarCloud 품질 게이트가 무엇을 걸었는지)\ngh api repos/{owner}/{repo}/commits/{headRefOid}/check-runs \\\n  --jq '.check_runs[] | select(.conclusion==\"failure\") | \"\\(.name) | \\(.output.title) | \\(.output.summary)\"'\n```\n\n## 3단계: 기존 기능 회귀 점검 — 이 스킬의 핵심\n\n여기에 가장 많은 시간을 씁니다. 방법이 중요합니다. diff를 위에서 아래로 훑어 읽는 것은\n**추가된 코드**를 보게 만들 뿐이고, 회귀는 거의 항상 **추가가 아니라 변경과 삭제**에서 나옵니다.\n\n### 3a. PR을 만든 뒤 master가 얻은 변경과 부딪히는지 본다\n\n**이건 이 PR의 diff만 봐서는 절대 보이지 않습니다.** PR 브랜치 안에서는 완벽한 코드가, 그사이 master에\n들어온 다른 변경과 만나 깨질 수 있습니다. 머지 리뷰가 일반 코드 리뷰와 다른 지점이 바로 여기입니다.\n\n```bash\n# 이 PR의 베이스 이후 master가 새로 얻은 커밋\ngit log --oneline $(git merge-base HEAD upstream/master)..upstream/master\n```\n\n커밋 목록을 **읽고**, 이 PR이 건드린 영역과 겹치는 것이 있으면 그 커밋의 diff를 직접 확인합니다.\n특히 백엔드 변경은 프론트와 계약으로 연결돼 있어 겹치기 쉽습니다:\n\n- **API 응답·상태 코드가 바뀌었나** — 프론트가 특정 상태 코드(404 등)나 필드를 보고 분기한다면,\n  그 규칙이 아직 유효한지 확인합니다. (실제로 \"없는 이름은 404\" 프론트 + \"400을 반환\" 백엔드가\n  같은 시점에 올라온 적이 있습니다.)\n- **필수 파라미터가 늘었나** — 프론트가 그 값 없이 보내는 경로가 있으면 머지 직후 400이 됩니다.\n- **조용히 넘어가던 것이 예외가 되었나** — 기본값으로 대체되던 동작이 오류로 바뀌면, 그에 의존한\n  화면이 깨집니다.\n\n겹치는 것이 없으면 \"master의 새 커밋 N개, 이 PR과 겹치는 영역 없음\"이라고 적고 넘어갑니다.\n\n### 3b. \"위험한 변경\"만 골라낸다\n\ndiff에서 다음을 뽑아 목록으로 만듭니다. 추가만 된 코드는 회귀 위험이 낮으니 뒤로 미룹니다.\n\n```bash\ngit diff upstream/master...HEAD          # 전체 diff를 실제로 읽습니다\n```\n\n| 위험 신호 | 왜 위험한가 |\n|---|---|\n| 지워진 줄 / 삭제된 파일 · export | 쓰던 곳이 남아 있으면 그대로 깨집니다 |\n| 함수 시그니처 · props · 반환 타입 변경 | 호출자가 옛 계약을 기대합니다 |\n| 기본값 변경, optional ↔ required 변경 | 인자를 안 넘기던 호출자의 동작이 조용히 바뀝니다 |\n| 조건문(`if`, 삼항, `&&`) 수정 | 기존 경로가 새 조건에 걸려 빠질 수 있습니다 |\n| 이름 변경 (rename) | 참조를 하나라도 놓치면 깨집니다 |\n| 공용 파일 수정 (hooks/api, atoms, constants, utils) | 소비자가 많아 파급이 큽니다 |\n\n### 3c. 목록의 항목마다 \"쓰던 곳 전부\"를 찾아 확인한다\n\n**이게 핵심 작업입니다.** 변경된 심볼 하나하나에 대해:\n\n```bash\ngit grep -n \"심볼이름\" -- '*.ts' '*.tsx'      # 사용처 전부. 개수를 셉니다\n```\n\n그리고 **사용처를 샘플링하지 말고 전부 확인합니다.** 3곳뿐이면 3곳 다, 20곳이면 20곳 다.\n너무 많아 전부 못 봤으면 **몇 곳 중 몇 곳을 봤는지 숫자로 보고**합니다 (\"18곳 중 12곳 확인\").\n\"대충 괜찮아 보인다\"는 이 스킬에서 가장 위험한 문장입니다.\n\n각 사용처에서 확인할 것: **이번 변경 후에도 이 호출이 예전과 같은 결과를 내는가.**\n타입 체크만 통과하는 것으로는 부족합니다 — 타입은 맞는데 동작만 달라지는 변경이 제일 잡기 어렵습니다\n(기본값 변경, 조건 뒤집힘, 정렬 순서 변경, 캐시 키 변경 등).\n\n`.claude/rules/code-review-policy.md`의 영향 분석 절차를 그대로 따릅니다.\n\n### 3d. Pinpoint에서 실제로 회귀가 났던 자리들\n\n이 프로젝트에서 조용히 깨지기 쉬운 지점입니다. 해당하는 변경이 있으면 반드시 확인합니다.\n\n- **설정 플래그 분기** — `experimental.enableServiceMap` 같은 플래그. **플래그가 꺼진 기존 사용자의 경로가\n  그대로인가**를 별도로 확인합니다. 켠 쪽만 확인하고 넘어가는 실수가 흔합니다. 그 기능에 대한 규칙\n  문서가 `.claude/rules/`에 있으면 함께 읽습니다.\n- **Jotai 아톰** — 아톰은 화면 remount로 지워지지 않습니다. 아톰을 추가·수정했으면 **읽는 모든 컴포넌트**와\n  **초기화 시점**을 확인합니다. 안 지워진 옛 값으로 조회가 나가 400을 받는 사고가 실제로 있었습니다.\n- **React Query 쿼리 키** — 키가 바뀌면 캐시 무효화가 깨지거나, 다른 데이터가 같은 키에 섞입니다.\n- **라우트 경로 / URL 파라미터** — 경로 형태가 바뀌면 기존 링크·북마크가 죽습니다. 로더의 검증·리다이렉트가\n  옛 형태도 받아주는지 확인합니다.\n- **i18n 키** — 제거·이름 변경된 키를 다른 화면이 아직 쓰고 있지 않은지 `git grep`으로 확인합니다.\n- **컴포넌트 props** — 렌더하는 모든 부모가 유효한 props를 넘기는지 확인합니다.\n- **API 엔드포인트 · 응답 타입** — Java 쪽이 함께 바뀌었으면, 프론트가 기대하는 필드·형태와 맞는지 대조합니다.\n  (백엔드 코드는 이 계약 부분만 봅니다. 그 외 Java 내부 로직은 이 스킬의 범위가 아니라고 밝히세요.)\n\n### 3e. 판단이 안 서면 \"모르겠다\"가 정답이다\n\n코드만으로 확신이 안 서면 **추측으로 ✅ 하지 말고** 그 항목을 \"확인 필요\"로 남기고,\n사용자가 무엇을 어떻게 확인하면 되는지 알려줍니다 (예: \"dev 서버에서 A 화면 → B 클릭 순서로 확인\").\n머지 여부를 잘못 통과시키는 비용이, 한 번 더 확인하는 비용보다 훨씬 큽니다.\n\n## 4단계: PR이 의도한 동작을 정확히 하는가\n\n1단계 요약에서 정리한 \"이 PR이 풀려던 문제\"를 다시 꺼내 대조합니다.\n\n- 이슈에 적힌 증상이 이 변경으로 **실제로** 해소되는가 (코드를 따라가며 확인)\n- 해피 패스뿐 아니라 **빈 데이터 · 로딩 · 오류 · 경계값**에서도 의도대로 동작하는가\n- 문제를 근본에서 고쳤는가, 증상만 가렸는가\n- 놓친 케이스가 있는가 (예: 한 화면만 고치고 같은 문제를 가진 다른 화면은 그대로)\n\n깊은 동작 QA가 필요하면 `/qa-pr` 의 체크리스트(엣지 케이스, 상태 무결성, 컴포넌트 상호작용)를 활용합니다.\n\n## 5단계: 그 밖에 머지 전에 봐야 하는 것들\n\n- **코드 스타일 일관성** — `.claude/rules/code-style.md`, `/review-code` 체크리스트 기준.\n  포맷팅뿐 아니라 **주변 코드와 같은 방식으로 쓰였는가**를 봅니다 (같은 일을 다른 패턴으로 하는 코드가\n  섞이면 다음 사람이 어느 쪽을 따라야 할지 모르게 됩니다).\n- **아키텍처 위치** — 라우팅은 `apps/web`, 나머지는 `packages/ui`. 훅·아톰·상수가 제자리에 있는가.\n- **남아 있는 디버그 코드** — `console.log`, 주석 처리된 코드, `TODO`, 임시 하드코딩:\n  ```bash\n  git diff upstream/master...HEAD -- '*.ts' '*.tsx' | grep -nE '^\\+.*(console\\.(log|debug)|debugger|FIXME|XXX)'\n  ```\n- **커밋 메시지 규약** — `[#issue_number] Description`, 영어 (`.claude/rules/git-workflow.md`)\n- **PR 범위** — 이슈와 무관한 변경이 섞여 있지 않은가\n- **테스트** — 아톰·유틸·API 훅·라우트 로더가 바뀌었는데 테스트가 없으면 지적합니다 (핵심 경로)\n- **타입 안전성** — 새로 들어온 `any`, 위험한 단언(`as`), 무시된 null 체크\n- **성능** — 불필요한 리렌더, 누락된 `useEffect` 클린업, 큰 목록의 비효율 처리\n\n## 6단계: 직접 눈으로 확인할 화면 목록을 만든다 (필수)\n\n코드 추적·빌드·테스트로는 **실제로 화면에 무엇이 그려지는지**를 알 수 없습니다. 그래서 이 스킬은\n\"확인 못 했다\"로 끝내지 않고, **사용자가 `yarn dev`로 무엇을 열어 무엇을 봐야 하는지**를 항상\n목록으로 내놓습니다. 목록이 없으면 사용자는 어디서부터 봐야 할지 몰라 결국 아무것도 확인하지 않습니다.\n\n```bash\nyarn dev     # 포트 3000. /api/*는 localhost:8080(백엔드)로 프록시되므로 백엔드가 떠 있어야 데이터가 보인다\n```\n\n### 화면 목록을 뽑는 방법\n\n변경된 파일에서 **화면까지 거슬러 올라갑니다.** 컴포넌트·훅은 그 자체로 화면이 아니므로, 사용처를\n따라 `pages/`와 라우트까지 올라가야 어떤 주소를 열어야 할지 나옵니다.\n\n```bash\n# 변경된 컴포넌트/훅을 누가 쓰는지 → 그 사용처를 또 누가 쓰는지 (pages/ 까지)\ngit grep -n \"변경된컴포넌트\\|변경된훅\" -- '*.tsx' '*.ts'\n```\n\n주소는 `packages/ui/src/constants/path.ts`의 `APP_PATH`에서 확인합니다.\n\n### 목록에 반드시 들어가야 하는 것\n\n1. **기존 화면 (회귀 확인)** — 이번에 바뀐 공용 코드를 쓰는 **모든** 기존 화면. 새 기능 화면보다\n   **먼저** 적습니다. 사용자가 제일 걱정하는 건 \"잘 쓰던 게 깨졌나\"입니다.\n   공용 코드(`hooks/api`, `atoms`, `utils`, 공유 컴포넌트)를 건드렸다면 소비 화면이 여러 개일 테니\n   샘플링하지 말고 다 적습니다.\n2. **새 기능 화면 (의도 확인)** — 이 PR이 만든 동작. PR 본문의 테스트 계획에 있으면 그것을 재사용합니다.\n3. **설정 플래그가 있으면 양쪽 다** — 켠 상태와 **끈 상태**. 끈 쪽이 기존 사용자의 화면이므로 더 중요합니다.\n4. **코드로 확신이 안 섰던 항목** (3e에서 남긴 것) — 그게 바로 눈으로 봐야 하는 것입니다.\n\n각 항목은 **\"무엇을 보면 정상인지\"**까지 적습니다. \"servermap 확인\" 같은 문장은 도움이 안 됩니다.\n\"노드를 클릭하면 오른쪽 패널에 그 노드 이름과 차트가 뜨는지\" 처럼 판정 가능한 문장으로 씁니다.\n브라우저 개발자도구 네트워크 탭에서 볼 것이 있으면(400 응답, 중복 요청 등) 그것도 적습니다.\n\n## 7단계: 보고 (대화창, 한국어)\n\n**항상 이 구조로** 보고합니다. 요약이 판정보다 먼저 오는 순서를 지킵니다 —\n사용자는 \"무엇을 한 PR인지\" 이해한 뒤에 판정을 봐야 그 판정을 신뢰할 수 있습니다.\n\n```markdown\n## 1. 이 PR이 한 일\n- **목적**: (이슈/PR 본문 기준, 한두 문장)\n- **바꾼 것**: (파일 N개 / +A −B 줄, 핵심 변경 3~5개를 쉬운 말로)\n- **의도와 diff의 차이**: (없으면 \"없음\")\n\n## 2. 검증 결과\n| 항목 | 결과 |\n|---|---|\n| upstream/master 병합 | 충돌 없음 / 충돌 (파일) |\n| yarn build | 통과 / 실패 |\n| yarn test | 통과 / 실패 (N건, 이 PR 때문인지 여부) |\n| yarn lint | 통과 / 실패 |\n| CI | 상태 |\n\n## 3. 기존 기능 회귀 점검 (가장 중요)\n**master의 새 변경과의 충돌**: 새 커밋 N개 → 겹치는 것마다 판단 + 근거 (없으면 \"겹침 없음\")\n**위험 변경마다**: (항목) — 사용처 N곳 중 M곳 확인 → 판단 + 근거 (`파일:라인`)\n**확인하지 못한 것**: (항목) — 왜 확인 못 했는지 (→ 6번 목록으로 넘긴다)\n\n## 4. 동작 정확성\n- 의도한 문제가 해소되는가: 판단 + 근거\n- 엣지 케이스: 확인 결과\n\n## 5. 그 외 (스타일 · 구조 · 기타)\n심각도 순으로: Critical / Warning / Suggestion\n\n## 6. 직접 확인할 화면 (`yarn dev`)\n기존 화면 — 회귀 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n| (화면 이름) | `/경로/...` | (판정 가능한 문장) |\n\n새 기능 — 의도 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n\n## 7. 판정\n**✅ 머지 가능** / **⚠️ 조건부** / **❌ 머지 불가**\n- 이유: (한두 문장)\n- 머지 전에 해야 할 일: (있으면 목록)\n```\n\n### 판정 기준\n\n- **❌ 머지 불가** — 빌드·테스트 실패, 기존 기능이 깨진 것을 **확인**했음, 머지 충돌 미해결\n- **⚠️ 조건부** — 회귀 위험이 있는데 코드만으로는 확정할 수 없음, CI 검사(품질 게이트 등)가 빨간불,\n  또는 고쳐야 할 문제가 남았지만 치명적이지 않음.\n  **무엇을 확인·수정하면 ✅ 가 되는지 반드시 적습니다.**\n- **✅ 머지 가능** — 검증·CI 통과 + 위험 변경의 사용처를 확인했고 문제 없음\n\n> 6번의 화면 목록은 판정과 무관하게 **항상** 내놓습니다. ✅ 라도 \"코드로는 문제를 못 찾았다\"는\n> 뜻이지 \"화면을 봤다\"는 뜻은 아니고, 그 차이를 사용자가 알아야 스스로 판단할 수 있습니다.\n\n> 애매하면 ✅ 를 주지 마세요. ⚠️ 는 사용자가 5분 더 확인하게 만들지만, 잘못된 ✅ 는 깨진 코드를 배포합니다.\n> 다만 근거 없이 ⚠️ 를 남발하는 것도 도움이 되지 않습니다 — ⚠️ 에는 항상 \"무엇을 확인해야 하는지\"가 붙어야 합니다.\n\n### 마지막 정리\n\n- 브랜치를 옮겼다면 원래 브랜치로 복귀했는지 확인하고 보고에 한 줄 적습니다.\n- `git merge --abort`, stash 복원 등 임시 상태가 남지 않았는지 확인합니다.\n- 사용자가 PR 코멘트나 Approve를 원하면 그때 확인을 받고 남깁니다. 본문은 **영어**입니다\n  (`.claude/rules/git-workflow.md`).\n","frontmatter":{"name":"merge-check","description":"PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. \"머지해도 되나\", \"머지 전에 봐줘\", \"이 PR 리뷰해줘\", \"PR 괜찮은지 확인\", \"approve해도 되나\", \"머지 전에 뭘 확인해야 하나\" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다."},"isInternal":false,"tokens":8254,"sizeBytes":21831},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md","title":"mvn-web","category":"anthropic-skill","format":"markdown","content":"---\nname: mvn-web\ndescription: web-frontend, web, web-starter Maven 모듈을 skipTests 옵션으로 순차 빌드합니다.\n---\n\n# Maven Web 빌드\n\n## 0단계: Pinpoint 루트 디렉토리 탐색\n\n현재 작업 디렉토리부터 상위 디렉토리로 올라가며 `web-frontend`, `web`, `web-starter` 서브디렉토리를 포함하는 `pinpoint`라는 이름의 가장 가까운 상위 디렉토리를 찾습니다. 이 경로를 `PINPOINT_ROOT`로 저장합니다.\n\n```bash\nPINPOINT_ROOT=$(d=\"$PWD\"; while [ \"$d\" != \"/\" ]; do if [ \"$(basename \"$d\")\" = \"pinpoint\" ] && [ -d \"$d/web-frontend\" ] && [ -d \"$d/web\" ] && [ -d \"$d/web-starter\" ]; then echo \"$d\"; break; fi; d=\"$(dirname \"$d\")\"; done)\n```\n\n`PINPOINT_ROOT`가 비어 있으면 즉시 중단하고 pinpoint 루트 디렉토리를 찾을 수 없다고 보고합니다.\n\n## 1~3단계: 모듈 순차 빌드\n\n아래 모듈에 대해 정해진 순서대로 `mvn clean install -DskipTests=true`를 순차 실행합니다. 각 단계는 반드시 성공해야 다음 단계로 진행할 수 있습니다. 실패 시 즉시 중단하고 오류를 보고합니다.\n\n1. `cd $PINPOINT_ROOT/web-frontend && mvn clean install -DskipTests=true`\n2. `cd $PINPOINT_ROOT/web && mvn clean install -DskipTests=true`\n3. `cd $PINPOINT_ROOT/web-starter && mvn clean install -DskipTests=true`\n","frontmatter":{"name":"mvn-web","description":"web-frontend, web, web-starter Maven 모듈을 skipTests 옵션으로 순차 빌드합니다."},"isInternal":false,"tokens":475,"sizeBytes":1332},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md","title":"qa-pr","category":"anthropic-skill","format":"markdown","content":"---\nname: qa-pr\ndescription: Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요.\n---\n\n# PR 전 QA 게이트\n\n> **이 스킬은 `.claude/agents/qa-engineer/qa-engineer.md`에 정의된 `qa-engineer` 에이전트를 사용하여 실행합니다.**\n> QA 수행 시 해당 에이전트의 사고방식, 체크리스트, 출력 형식을 따르세요.\n\n**실행 시점: 커밋하거나 푸시하기 전에 반드시 실행하세요. QA 판정이 FAIL이면 문제를 해결하기 전까지 커밋하지 마세요.**\n\nPR 제출 전에 현재 변경 사항에 대한 전체 QA를 수행합니다.\n\n## 1단계: 변경 사항 파악\n\n```bash\ngit diff upstream/master --name-only\ngit diff upstream/master --stat\n```\n\n변경된 모든 파일을 나열하고 수정된 내용을 요약합니다.\n\n## 2단계: 빌드 및 테스트\n\n순서대로 실행하세요. **실패 시 즉시 중단하고 보고하세요. 빌드나 테스트 실패 상태에서는 커밋하지 마세요.**\n\n```bash\nyarn build\nyarn test\n```\n\n각각의 통과/실패 여부와 오류 출력을 보고합니다.\n\n## 3단계: 동작 QA\n\n변경된 각 컴포넌트, 훅, 페이지에 대해 기능 분석을 수행합니다:\n\n### 3a. 해피 패스\n- 정상 데이터로 기대되는 동작은 무엇인가?\n- 구현이 그 기대에 부합하는가?\n- 사용자 액션 → 상태 변경 → UI 업데이트 추적\n\n### 3b. 엣지 케이스\n변경된 UI 컴포넌트에 대해 다음을 각각 확인:\n- [ ] 빈/null 데이터 상태 — API가 빈 배열이나 null을 반환할 때 무엇이 렌더링되나?\n- [ ] 로딩 상태 — 스켈레톤/스피너가 표시되나? 빠른 로드에서 깜빡이지 않나?\n- [ ] 오류 상태 — API 실패 / 네트워크 오류. 사용자에게 오류가 표시되나?\n- [ ] 경계값 — 날짜 범위, 페이지 제한, 대용량 데이터셋\n- [ ] 동시 요청 — 빠른 클릭, 여러 탭 전환\n\n### 3c. 상태 무결성\n- [ ] URL 파라미터가 UI 상태를 올바르게 반영 (from/to, application)\n- [ ] 페이지 새로고침이 상태를 유지 (URL이 진실의 원천)\n- [ ] 아톰 상태가 내비게이션 간에 누출되지 않음 (클린업 확인)\n- [ ] React Query 캐시가 뮤테이션 후 오래된 데이터를 표시하지 않음\n\n### 3d. 컴포넌트 상호작용\n- [ ] 변경된 props가 모든 부모 컴포넌트 호출 위치를 만족함\n- [ ] 이벤트 핸들러가 올바르게 발생하고 중복 액션을 생성하지 않음\n- [ ] 무한 리렌더 루프 없음 (아톰 의존성 변경, 불안정한 참조)\n\n## 4단계: Pinpoint 특화 확인\n\n- [ ] application/from/to가 변경될 때 ServerMap이 여전히 렌더링됨\n- [ ] 변경된 코드 근처의 스캐터 차트 상호작용(드래그 선택, 클릭)이 여전히 작동\n- [ ] 트랜잭션 목록 / Inspector 내비게이션이 손상되지 않음\n- [ ] 설정 기반 기능이 여전히 설정을 올바르게 확인함\n\n## 5단계: 회귀 요약\n\n다음을 나열합니다:\n1. **변경된 파일**: (개수와 목록)\n2. **실행된 테스트**: 통과/실패\n3. **빌드**: 통과/실패\n4. **발견된 동작 이슈**: (심각도와 함께 목록)\n5. **QA 판정**: ✅ PASS / ❌ FAIL / ⚠️ PASS WITH WARNINGS\n\nFAIL 또는 PASS WITH WARNINGS인 경우, 머지 전에 필요한 구체적인 조치 사항을 나열합니다.\n","frontmatter":{"name":"qa-pr","description":"Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요."},"isInternal":false,"tokens":1308,"sizeBytes":3506},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md","title":"review-code","category":"anthropic-skill","format":"markdown","content":"---\nname: review-code\ndescription: Pinpoint 프로젝트 규약에 따라 코드 변경을 리뷰합니다. 커밋 전, PR 리뷰, 또는 코드 품질을 점검할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰\n\n> **이 스킬은 다음 두 에이전트를 사용하여 실행합니다:**\n> 1. `.claude/agents/explorer/explorer.md` — 코드베이스 탐색 및 변경 사항 파악\n> 2. `.claude/agents/code-reviewer/code-reviewer.md` — 실제 코드 리뷰 수행\n>\n> 리뷰 시 두 에이전트의 사고방식과 체크리스트를 따르세요.\n\n**인자 형식**: `/review-code [파일경로 또는 경로 목록]`\n- `$ARGUMENTS`에 파일 경로를 전달하면 해당 파일을 리뷰합니다. 예: `/review-code packages/ui/src/hooks/api/useGetServerMap.ts`\n- 경로 없이 실행하면 `git diff upstream/master --name-only`로 변경된 파일을 자동 감지합니다.\n\n`$ARGUMENTS`의 코드를 리뷰합니다 (경로가 없으면 최근 git 변경 사항 리뷰).\n\n## 리뷰 체크리스트\n\n### 1. 아키텍처\n- [ ] 올바른 패키지에 코드 위치 (라우팅은 apps/web, 나머지는 packages/ui)\n- [ ] 페이지가 올바른 중첩 레이아웃 outlet에 배치 (InitialFetchOutlet / ConfigurationOutlet)\n- [ ] API 훅이 reactQueryHelper의 공유 queryFn 사용\n- [ ] 상태 관리가 올바른 계층 사용 (URL → Jotai → React Query)\n\n### 2. 코드 스타일\n- [ ] Prettier 포맷팅 (100자, 작은따옴표, 후행 쉼표, 세미콜론)\n- [ ] TypeScript strict 준수 (`any` 금지, 적절한 타입 좁히기)\n- [ ] 임포트 순서: external → @pinpoint-fe/* → relative\n- [ ] 딥 임포트: `@pinpoint-fe/ui` 대신 `@pinpoint-fe/ui/src/constants`\n\n### 3. 컴포넌트\n- [ ] UI 프리미티브가 shadcn/ui 패턴 준수 (Radix + CVA + Tailwind)\n- [ ] 도메인 컴포넌트가 UI 프리미티브를 조합하여 구성\n- [ ] className 병합에 `cn()` 사용\n- [ ] 인라인 스타일이나 CSS 모듈 없음\n\n### 4. 데이터 페칭\n- [ ] 엔드포인트가 EndPoints.ts에 정의됨\n- [ ] 타입이 네임스페이스 패턴으로 정의됨\n- [ ] `enabled` 옵션으로 조기 쿼리 실행 방지\n- [ ] ProblemDetail 패턴을 통한 오류 처리\n\n### 5. i18n\n- [ ] 모든 사용자 노출 문자열에 `t()` 함수 사용\n- [ ] 키가 en.json과 ko.json 모두에 추가됨\n- [ ] 키 네이밍이 SECTION.KEY_NAME 규칙을 따름\n\n### 6. 일반적인 함정\n- [ ] React 훅 의존성 누락 없음\n- [ ] 메모리 누수 없음 (useEffect에 클린업)\n- [ ] 새 페이지에 지연 로딩 사용\n- [ ] 하드코딩된 API 경로 없음 (END_POINTS 상수 사용)\n\n결과를 심각도 순으로 정리: Critical > Warning > Suggestion\n","frontmatter":{"name":"review-code","description":"Pinpoint 프로젝트 규약에 따라 코드 변경을 리뷰합니다. 커밋 전, PR 리뷰, 또는 코드 품질을 점검할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":992,"sizeBytes":2708},{"name":"SKILL.md","path":"web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md","title":"write-test","category":"anthropic-skill","format":"markdown","content":"---\nname: write-test\ndescription: 변경되었거나 테스트가 없는 Pinpoint 프론트엔드 코드에 대한 Jest 테스트를 작성합니다. 훅, 아톰, 유틸리티, 컴포넌트에 테스트가 필요하거나 커버리지를 높여야 할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 테스트 작성\n\n`$ARGUMENTS`의 코드에 대한 Jest 테스트를 작성합니다 (경로가 없으면 최근 변경된 파일 대상).\n\n## 1단계: 테스트가 필요한 파일 탐색\n\n인자가 없는 경우:\n\n```bash\ngit diff upstream/master --name-only\n```\n\n변경된 각 `.ts` / `.tsx` 파일에 대해 해당하는 `.test.ts` / `.test.tsx` 파일이 있는지 확인합니다.\n테스트가 **없는** 파일 목록 — 이것이 우선 타겟입니다.\n\n## 2단계: 코드 분석\n\n각 타겟 파일을 완전히 읽고 파악합니다:\n\n- **수행하는 것** (구현이 아닌 동작)\n- **받는 입력** (props, 인자, 아톰 값, URL 파라미터)\n- **생성하는 출력** (반환 값, 렌더링 출력, 사이드 이펙트, 아톰 업데이트)\n- **의존성** (fetch 호출, 아톰, 다른 훅)\n\n## 3단계: 테스트 작성\n\n`.claude/rules/testing.md`의 프로젝트 테스트 패턴을 따릅니다.\n\n> **규칙: 테스트 이름(`describe` / `test` / `it` 문자열)은 반드시 영어로 작성합니다.**\n\n### 유틸리티 함수 테스트\n\n```typescript\nimport { theUtil } from \"./theUtil\";\n\ndescribe(\"theUtil\", () => {\n  test(\"should return [expected behavior] given [normal input]\", () => {\n    expect(theUtil(normalInput)).toBe(expected);\n  });\n\n  test(\"should handle null/undefined input gracefully\", () => {\n    expect(theUtil(null)).toBe(fallback);\n  });\n\n  test(\"should handle edge cases\", () => {\n    expect(theUtil(edgeCase)).toBe(edgeExpected);\n  });\n});\n```\n\n### Jotai 아톰 테스트\n\n```typescript\nimport { renderHook, act } from \"@testing-library/react\";\nimport { useAtom } from \"jotai\";\nimport { theAtom } from \"./theAtom\";\n\ndescribe(\"theAtom\", () => {\n  test(\"should initialize with default value\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    expect(result.current[0]).toEqual(defaultValue);\n  });\n\n  test(\"should update when setter is called\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    act(() => {\n      result.current[1](newValue);\n    });\n    expect(result.current[0]).toEqual(newValue);\n  });\n});\n```\n\n### API 훅 테스트 (useGetXxx)\n\n```typescript\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { createWrapper } from \"../testUtils\"; // QueryClient wrapper\nimport { useGetXxx } from \"./useGetXxx\";\n\ndescribe(\"useGetXxx\", () => {\n  beforeEach(() => {\n    global.fetch = jest.fn();\n  });\n\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n\n  test(\"should fetch data with correct endpoint and params\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: true,\n      json: async () => ({ data: mockData }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isSuccess).toBe(true));\n\n    expect(global.fetch).toHaveBeenCalledWith(\n      expect.stringContaining(\"/api/expected-endpoint\"),\n      expect.any(Object),\n    );\n    expect(result.current.data).toEqual(expectedData);\n  });\n\n  test(\"should not fetch when required params are missing\", () => {\n    const { result } = renderHook(() => useGetXxx(null), {\n      wrapper: createWrapper(),\n    });\n    expect(result.current.isFetching).toBe(false);\n    expect(global.fetch).not.toHaveBeenCalled();\n  });\n\n  test(\"should handle API error response\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: false,\n      status: 500,\n      json: async () => ({ title: \"Internal Server Error\" }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isError).toBe(true));\n  });\n});\n```\n\n### 라우트 로더 테스트\n\n```typescript\nimport { loader } from \"./loader\";\n\ndescribe(\"loader\", () => {\n  test(\"should redirect with correct date format when from/to are invalid\", async () => {\n    const request = new Request(\n      \"http://localhost/page?from=invalid&to=invalid\",\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeInstanceOf(Response); // redirect\n  });\n\n  test(\"should return null for valid date params\", async () => {\n    const now = Date.now();\n    const request = new Request(\n      `http://localhost/page?from=${now - 3600000}&to=${now}`,\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeNull();\n  });\n});\n```\n\n## 4단계: 커버리지 목표\n\n각 파일에 대해 다음을 커버하는 것을 목표로 합니다:\n\n- [ ] 정상 / 해피 패스\n- [ ] 빈 / null / undefined 입력\n- [ ] 오류 상태 (API 실패, 잘못된 데이터)\n- [ ] 경계값 (빈 배열, 최대값)\n- [ ] 훅의 `enabled` 조건 (파라미터 없을 때 페칭 안 함)\n\n## 5단계: 배치 및 등록\n\n- 테스트 파일은 소스와 함께 위치: `myHook.ts` → `myHook.test.ts`\n- 테스트 통과 확인을 위해 실행: `yarn workspace @pinpoint-fe/ui jest path/to/file.test.ts`\n\n작성된 테스트와 통과/실패 여부를 보고합니다.\n","frontmatter":{"name":"write-test","description":"변경되었거나 테스트가 없는 Pinpoint 프론트엔드 코드에 대한 Jest 테스트를 작성합니다. 훅, 아톰, 유틸리티, 컴포넌트에 테스트가 필요하거나 커버리지를 높여야 할 때 반드시 이 스킬을 사용하세요."},"isInternal":false,"tokens":1515,"sizeBytes":5363},{"name":"package.json","path":"web-frontend/src/main/v3/packages/datetime-picker/package.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/package.json","title":"Datetime-picker Skill","category":"anthropic-skill","format":"json","content":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/package.json)","tokens":300,"sizeBytes":250},{"name":"tsconfig.json","path":"web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json","title":"Datetime-picker Skill","category":"anthropic-skill","format":"json","content":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json)","tokens":300,"sizeBytes":252},{"name":"tsconfig.node.json","path":"web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json","title":"Datetime-picker Skill","category":"anthropic-skill","format":"json","content":"# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json)","tokens":300,"sizeBytes":262},{"name":"package.json","path":"web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json","title":".storybook Skill","category":"anthropic-skill","format":"json","content":"# .storybook Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json)","tokens":300,"sizeBytes":263},{"name":"package.json","path":"web-frontend/src/main/v3/packages/scatter-chart/package.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/package.json","title":"Scatter-chart Skill","category":"anthropic-skill","format":"json","content":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/package.json)","tokens":300,"sizeBytes":244},{"name":"data1.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data1.json)","tokens":300,"sizeBytes":265},{"name":"data2.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data2.json)","tokens":300,"sizeBytes":265},{"name":"data3.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data3.json)","tokens":300,"sizeBytes":265},{"name":"data4.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data4.json)","tokens":300,"sizeBytes":265},{"name":"data5.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/data5.json)","tokens":300,"sizeBytes":265},{"name":"realtimeData.json","path":"web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/src/stories/mock/realtimeData.json)","tokens":300,"sizeBytes":279},{"name":"data1.json","path":"web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data1.json)","tokens":300,"sizeBytes":251},{"name":"data2.json","path":"web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/test/mock/data2.json)","tokens":300,"sizeBytes":251},{"name":"tsconfig.json","path":"web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json","title":"Scatter-chart Skill","category":"anthropic-skill","format":"json","content":"# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/tsconfig.json)","tokens":300,"sizeBytes":246},{"name":"package.json","path":"web-frontend/src/main/v3/packages/server-map/package.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/package.json","title":"Server-map Skill","category":"anthropic-skill","format":"json","content":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/package.json)","tokens":300,"sizeBytes":235},{"name":"data1.json","path":"web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data1.json)","tokens":300,"sizeBytes":263},{"name":"data2.json","path":"web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data2.json)","tokens":300,"sizeBytes":263},{"name":"data3.json","path":"web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data3.json)","tokens":300,"sizeBytes":263},{"name":"data4.json","path":"web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data4.json)","tokens":300,"sizeBytes":263},{"name":"data5.json","path":"web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json","title":"Mock Skill","category":"anthropic-skill","format":"json","content":"# Mock Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/src/storybook/mock/data5.json)","tokens":300,"sizeBytes":263},{"name":"tsconfig.json","path":"web-frontend/src/main/v3/packages/server-map/tsconfig.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/tsconfig.json","title":"Server-map Skill","category":"anthropic-skill","format":"json","content":"# Server-map Skill\n\nPath: `web-frontend/src/main/v3/packages/server-map/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/tsconfig.json)","tokens":300,"sizeBytes":237},{"name":"components.json","path":"web-frontend/src/main/v3/packages/ui/components.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/components.json","title":"Ui Skill","category":"anthropic-skill","format":"json","content":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/components.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/components.json)","tokens":300,"sizeBytes":217},{"name":"package.json","path":"web-frontend/src/main/v3/packages/ui/package.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/package.json","title":"Ui Skill","category":"anthropic-skill","format":"json","content":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/package.json)","tokens":300,"sizeBytes":211},{"name":"billboard-to-echarts-migration-prompt.md","path":"web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md","title":"Prompts Skill","category":"anthropic-skill","format":"markdown","content":"# Prompts Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/prompts/billboard-to-echarts-migration-prompt.md)","tokens":300,"sizeBytes":288},{"name":"en.json","path":"web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json","title":"Locales Skill","category":"anthropic-skill","format":"json","content":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/en.json)","tokens":300,"sizeBytes":250},{"name":"ko.json","path":"web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json","title":"Locales Skill","category":"anthropic-skill","format":"json","content":"# Locales Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/src/constants/locales/ko.json)","tokens":300,"sizeBytes":250},{"name":"tsconfig.json","path":"web-frontend/src/main/v3/packages/ui/tsconfig.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.json","title":"Ui Skill","category":"anthropic-skill","format":"json","content":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.json)","tokens":300,"sizeBytes":213},{"name":"tsconfig.node.json","path":"web-frontend/src/main/v3/packages/ui/tsconfig.node.json","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.node.json","title":"Ui Skill","category":"anthropic-skill","format":"json","content":"# Ui Skill\n\nPath: `web-frontend/src/main/v3/packages/ui/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/tsconfig.node.json)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/agent-plugins/proxy-apache/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-apache/README.md","title":"proxy-apache Documentation","category":"plugin-manifest","format":"markdown","content":"# proxy-apache Documentation\n\nPath: `agent-module/agent-plugins/proxy-apache/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-apache/README.md)","tokens":300,"sizeBytes":229},{"name":"README.md","path":"agent-module/agent-plugins/proxy-app/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-app/README.md","title":"proxy-app Documentation","category":"plugin-manifest","format":"markdown","content":"# proxy-app Documentation\n\nPath: `agent-module/agent-plugins/proxy-app/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-app/README.md)","tokens":300,"sizeBytes":220},{"name":"README.md","path":"agent-module/agent-plugins/proxy-nginx/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-nginx/README.md","title":"proxy-nginx Documentation","category":"plugin-manifest","format":"markdown","content":"# proxy-nginx Documentation\n\nPath: `agent-module/agent-plugins/proxy-nginx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-nginx/README.md)","tokens":300,"sizeBytes":226},{"name":"README.md","path":"agent-module/agent-plugins/proxy-user/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-user/README.md","title":"proxy-user Documentation","category":"plugin-manifest","format":"markdown","content":"# proxy-user Documentation\n\nPath: `agent-module/agent-plugins/proxy-user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/proxy-user/README.md)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/agent-plugins/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/README.md","title":"agent-plugins Documentation","category":"plugin-manifest","format":"markdown","content":"# agent-plugins Documentation\n\nPath: `agent-module/agent-plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-plugins/README.md)","tokens":300,"sizeBytes":204},{"name":"README.md","path":"agent-module/agent-tools/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-tools/README.md","title":"agent-tools Documentation","category":"plugin-manifest","format":"markdown","content":"# agent-tools Documentation\n\nPath: `agent-module/agent-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/agent-tools/README.md)","tokens":300,"sizeBytes":198},{"name":"README.md","path":"agent-module/plugins/activemq-client/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/activemq-client/README.md","title":"activemq-client Documentation","category":"plugin-manifest","format":"markdown","content":"# activemq-client Documentation\n\nPath: `agent-module/plugins/activemq-client/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/activemq-client/README.md)","tokens":300,"sizeBytes":226},{"name":"README.md","path":"agent-module/plugins/akka-http/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/akka-http/README.md","title":"akka-http Documentation","category":"plugin-manifest","format":"markdown","content":"# akka-http Documentation\n\nPath: `agent-module/plugins/akka-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/akka-http/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"agent-module/plugins/apache-dubbo/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/apache-dubbo/README.md","title":"apache-dubbo Documentation","category":"plugin-manifest","format":"markdown","content":"# apache-dubbo Documentation\n\nPath: `agent-module/plugins/apache-dubbo/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/apache-dubbo/README.md)","tokens":300,"sizeBytes":217},{"name":"README.md","path":"agent-module/plugins/arcus/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/arcus/README.md","title":"arcus Documentation","category":"plugin-manifest","format":"markdown","content":"# arcus Documentation\n\nPath: `agent-module/plugins/arcus/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/arcus/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/aws-sdk-s3/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/aws-sdk-s3/README.md","title":"aws-sdk-s3 Documentation","category":"plugin-manifest","format":"markdown","content":"# aws-sdk-s3 Documentation\n\nPath: `agent-module/plugins/aws-sdk-s3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/aws-sdk-s3/README.md)","tokens":300,"sizeBytes":211},{"name":"README.md","path":"agent-module/plugins/cassandra/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra/README.md","title":"cassandra Documentation","category":"plugin-manifest","format":"markdown","content":"# cassandra Documentation\n\nPath: `agent-module/plugins/cassandra/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"agent-module/plugins/cassandra4/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra4/README.md","title":"cassandra4 Documentation","category":"plugin-manifest","format":"markdown","content":"# cassandra4 Documentation\n\nPath: `agent-module/plugins/cassandra4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cassandra4/README.md)","tokens":300,"sizeBytes":211},{"name":"README.md","path":"agent-module/plugins/cubrid-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cubrid-jdbc/README.md","title":"cubrid-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# cubrid-jdbc Documentation\n\nPath: `agent-module/plugins/cubrid-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cubrid-jdbc/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/cxf/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cxf/README.md","title":"cxf Documentation","category":"plugin-manifest","format":"markdown","content":"# cxf Documentation\n\nPath: `agent-module/plugins/cxf/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/cxf/README.md)","tokens":300,"sizeBytes":190},{"name":"README.md","path":"agent-module/plugins/dameng-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dameng-jdbc/README.md","title":"dameng-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# dameng-jdbc Documentation\n\nPath: `agent-module/plugins/dameng-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dameng-jdbc/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/db2-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/db2-jdbc/README.md","title":"db2-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# db2-jdbc Documentation\n\nPath: `agent-module/plugins/db2-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/db2-jdbc/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/dbcp/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp/README.md","title":"dbcp Documentation","category":"plugin-manifest","format":"markdown","content":"# dbcp Documentation\n\nPath: `agent-module/plugins/dbcp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/dbcp2/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp2/README.md","title":"dbcp2 Documentation","category":"plugin-manifest","format":"markdown","content":"# dbcp2 Documentation\n\nPath: `agent-module/plugins/dbcp2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/dbcp2/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/druid/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/druid/README.md","title":"druid Documentation","category":"plugin-manifest","format":"markdown","content":"# druid Documentation\n\nPath: `agent-module/plugins/druid/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/druid/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/elasticsearch/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch/README.md","title":"elasticsearch Documentation","category":"plugin-manifest","format":"markdown","content":"# elasticsearch Documentation\n\nPath: `agent-module/plugins/elasticsearch/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch/README.md)","tokens":300,"sizeBytes":220},{"name":"README.md","path":"agent-module/plugins/elasticsearch8/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch8/README.md","title":"elasticsearch8 Documentation","category":"plugin-manifest","format":"markdown","content":"# elasticsearch8 Documentation\n\nPath: `agent-module/plugins/elasticsearch8/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/elasticsearch8/README.md)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/plugins/fastjson/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/fastjson/README.md","title":"fastjson Documentation","category":"plugin-manifest","format":"markdown","content":"# fastjson Documentation\n\nPath: `agent-module/plugins/fastjson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/fastjson/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/google-httpclient/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/google-httpclient/README.md","title":"google-httpclient Documentation","category":"plugin-manifest","format":"markdown","content":"# google-httpclient Documentation\n\nPath: `agent-module/plugins/google-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/google-httpclient/README.md)","tokens":300,"sizeBytes":232},{"name":"README.md","path":"agent-module/plugins/grpc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/grpc/README.md","title":"grpc Documentation","category":"plugin-manifest","format":"markdown","content":"# grpc Documentation\n\nPath: `agent-module/plugins/grpc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/grpc/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/gson/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/gson/README.md","title":"gson Documentation","category":"plugin-manifest","format":"markdown","content":"# gson Documentation\n\nPath: `agent-module/plugins/gson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/gson/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/hbase/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hbase/README.md","title":"hbase Documentation","category":"plugin-manifest","format":"markdown","content":"# hbase Documentation\n\nPath: `agent-module/plugins/hbase/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hbase/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/hikaricp/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hikaricp/README.md","title":"hikaricp Documentation","category":"plugin-manifest","format":"markdown","content":"# hikaricp Documentation\n\nPath: `agent-module/plugins/hikaricp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hikaricp/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/httpclient3/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient3/README.md","title":"httpclient3 Documentation","category":"plugin-manifest","format":"markdown","content":"# httpclient3 Documentation\n\nPath: `agent-module/plugins/httpclient3/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient3/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/httpclient4/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient4/README.md","title":"httpclient4 Documentation","category":"plugin-manifest","format":"markdown","content":"# httpclient4 Documentation\n\nPath: `agent-module/plugins/httpclient4/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient4/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/httpclient5/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient5/README.md","title":"httpclient5 Documentation","category":"plugin-manifest","format":"markdown","content":"# httpclient5 Documentation\n\nPath: `agent-module/plugins/httpclient5/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/httpclient5/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/hystrix/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hystrix/README.md","title":"hystrix Documentation","category":"plugin-manifest","format":"markdown","content":"# hystrix Documentation\n\nPath: `agent-module/plugins/hystrix/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/hystrix/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/ibatis/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ibatis/README.md","title":"ibatis Documentation","category":"plugin-manifest","format":"markdown","content":"# ibatis Documentation\n\nPath: `agent-module/plugins/ibatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ibatis/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/informix-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/informix-jdbc/README.md","title":"informix-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# informix-jdbc Documentation\n\nPath: `agent-module/plugins/informix-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/informix-jdbc/README.md)","tokens":300,"sizeBytes":220},{"name":"README.md","path":"agent-module/plugins/jackson/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jackson/README.md","title":"jackson Documentation","category":"plugin-manifest","format":"markdown","content":"# jackson Documentation\n\nPath: `agent-module/plugins/jackson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jackson/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/jboss/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jboss/README.md","title":"jboss Documentation","category":"plugin-manifest","format":"markdown","content":"# jboss Documentation\n\nPath: `agent-module/plugins/jboss/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jboss/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/jdk-http/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-http/README.md","title":"jdk-http Documentation","category":"plugin-manifest","format":"markdown","content":"# jdk-http Documentation\n\nPath: `agent-module/plugins/jdk-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-http/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/jdk-httpclient/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-httpclient/README.md","title":"jdk-httpclient Documentation","category":"plugin-manifest","format":"markdown","content":"# jdk-httpclient Documentation\n\nPath: `agent-module/plugins/jdk-httpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jdk-httpclient/README.md)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/plugins/jetty/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jetty/README.md","title":"jetty Documentation","category":"plugin-manifest","format":"markdown","content":"# jetty Documentation\n\nPath: `agent-module/plugins/jetty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jetty/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/json-lib/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/json-lib/README.md","title":"json-lib Documentation","category":"plugin-manifest","format":"markdown","content":"# json-lib Documentation\n\nPath: `agent-module/plugins/json-lib/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/json-lib/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/jtds/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jtds/README.md","title":"jtds Documentation","category":"plugin-manifest","format":"markdown","content":"# jtds Documentation\n\nPath: `agent-module/plugins/jtds/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/jtds/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/kafka/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kafka/README.md","title":"kafka Documentation","category":"plugin-manifest","format":"markdown","content":"# kafka Documentation\n\nPath: `agent-module/plugins/kafka/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kafka/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/kotlin-coroutines/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kotlin-coroutines/README.md","title":"kotlin-coroutines Documentation","category":"plugin-manifest","format":"markdown","content":"# kotlin-coroutines Documentation\n\nPath: `agent-module/plugins/kotlin-coroutines/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/kotlin-coroutines/README.md)","tokens":300,"sizeBytes":232},{"name":"README.md","path":"agent-module/plugins/ktor/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ktor/README.md","title":"ktor Documentation","category":"plugin-manifest","format":"markdown","content":"# ktor Documentation\n\nPath: `agent-module/plugins/ktor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ktor/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/log4j/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j/README.md","title":"log4j Documentation","category":"plugin-manifest","format":"markdown","content":"# log4j Documentation\n\nPath: `agent-module/plugins/log4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/log4j2/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j2/README.md","title":"log4j2 Documentation","category":"plugin-manifest","format":"markdown","content":"# log4j2 Documentation\n\nPath: `agent-module/plugins/log4j2/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/log4j2/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/logback/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/logback/README.md","title":"logback Documentation","category":"plugin-manifest","format":"markdown","content":"# logback Documentation\n\nPath: `agent-module/plugins/logback/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/logback/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/mariadb-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mariadb-jdbc/README.md","title":"mariadb-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# mariadb-jdbc Documentation\n\nPath: `agent-module/plugins/mariadb-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mariadb-jdbc/README.md)","tokens":300,"sizeBytes":217},{"name":"README.md","path":"agent-module/plugins/mongodb/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mongodb/README.md","title":"mongodb Documentation","category":"plugin-manifest","format":"markdown","content":"# mongodb Documentation\n\nPath: `agent-module/plugins/mongodb/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mongodb/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/mssql-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mssql-jdbc/README.md","title":"mssql-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# mssql-jdbc Documentation\n\nPath: `agent-module/plugins/mssql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mssql-jdbc/README.md)","tokens":300,"sizeBytes":211},{"name":"README.md","path":"agent-module/plugins/mybatis/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mybatis/README.md","title":"mybatis Documentation","category":"plugin-manifest","format":"markdown","content":"# mybatis Documentation\n\nPath: `agent-module/plugins/mybatis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mybatis/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/mysql-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mysql-jdbc/README.md","title":"mysql-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# mysql-jdbc Documentation\n\nPath: `agent-module/plugins/mysql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/mysql-jdbc/README.md)","tokens":300,"sizeBytes":211},{"name":"README.md","path":"agent-module/plugins/ning-asynchttpclient/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ning-asynchttpclient/README.md","title":"ning-asynchttpclient Documentation","category":"plugin-manifest","format":"markdown","content":"# ning-asynchttpclient Documentation\n\nPath: `agent-module/plugins/ning-asynchttpclient/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/ning-asynchttpclient/README.md)","tokens":300,"sizeBytes":241},{"name":"README.md","path":"agent-module/plugins/okhttp/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/okhttp/README.md","title":"okhttp Documentation","category":"plugin-manifest","format":"markdown","content":"# okhttp Documentation\n\nPath: `agent-module/plugins/okhttp/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/okhttp/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/openwhisk/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/openwhisk/README.md","title":"openwhisk Documentation","category":"plugin-manifest","format":"markdown","content":"# openwhisk Documentation\n\nPath: `agent-module/plugins/openwhisk/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/openwhisk/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"agent-module/plugins/oracle-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/oracle-jdbc/README.md","title":"oracle-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# oracle-jdbc Documentation\n\nPath: `agent-module/plugins/oracle-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/oracle-jdbc/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/paho-mqtt/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/paho-mqtt/README.md","title":"paho-mqtt Documentation","category":"plugin-manifest","format":"markdown","content":"# paho-mqtt Documentation\n\nPath: `agent-module/plugins/paho-mqtt/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/paho-mqtt/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"agent-module/plugins/pekko-http/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pekko-http/README.md","title":"pekko-http Documentation","category":"plugin-manifest","format":"markdown","content":"# pekko-http Documentation\n\nPath: `agent-module/plugins/pekko-http/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pekko-http/README.md)","tokens":300,"sizeBytes":211},{"name":"README.md","path":"agent-module/plugins/postgresql-jdbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/postgresql-jdbc/README.md","title":"postgresql-jdbc Documentation","category":"plugin-manifest","format":"markdown","content":"# postgresql-jdbc Documentation\n\nPath: `agent-module/plugins/postgresql-jdbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/postgresql-jdbc/README.md)","tokens":300,"sizeBytes":226},{"name":"README.md","path":"agent-module/plugins/process/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/process/README.md","title":"process Documentation","category":"plugin-manifest","format":"markdown","content":"# process Documentation\n\nPath: `agent-module/plugins/process/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/process/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/pulsar/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pulsar/README.md","title":"pulsar Documentation","category":"plugin-manifest","format":"markdown","content":"# pulsar Documentation\n\nPath: `agent-module/plugins/pulsar/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/pulsar/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/rabbitmq/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rabbitmq/README.md","title":"rabbitmq Documentation","category":"plugin-manifest","format":"markdown","content":"# rabbitmq Documentation\n\nPath: `agent-module/plugins/rabbitmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rabbitmq/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/reactor-netty/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor-netty/README.md","title":"reactor-netty Documentation","category":"plugin-manifest","format":"markdown","content":"# reactor-netty Documentation\n\nPath: `agent-module/plugins/reactor-netty/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor-netty/README.md)","tokens":300,"sizeBytes":220},{"name":"README.md","path":"agent-module/plugins/reactor/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor/README.md","title":"reactor Documentation","category":"plugin-manifest","format":"markdown","content":"# reactor Documentation\n\nPath: `agent-module/plugins/reactor/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/reactor/README.md)","tokens":300,"sizeBytes":202},{"name":"README.md","path":"agent-module/plugins/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/README.md","title":"plugins Documentation","category":"plugin-manifest","format":"markdown","content":"# plugins Documentation\n\nPath: `agent-module/plugins/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/README.md)","tokens":300,"sizeBytes":186},{"name":"README.md","path":"agent-module/plugins/redis-lettuce/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-lettuce/README.md","title":"redis-lettuce Documentation","category":"plugin-manifest","format":"markdown","content":"# redis-lettuce Documentation\n\nPath: `agent-module/plugins/redis-lettuce/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-lettuce/README.md)","tokens":300,"sizeBytes":220},{"name":"README.md","path":"agent-module/plugins/redis-redisson/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-redisson/README.md","title":"redis-redisson Documentation","category":"plugin-manifest","format":"markdown","content":"# redis-redisson Documentation\n\nPath: `agent-module/plugins/redis-redisson/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis-redisson/README.md)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/plugins/redis/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis/README.md","title":"redis Documentation","category":"plugin-manifest","format":"markdown","content":"# redis Documentation\n\nPath: `agent-module/plugins/redis/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/redis/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/resilience4j/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/resilience4j/README.md","title":"resilience4j Documentation","category":"plugin-manifest","format":"markdown","content":"# resilience4j Documentation\n\nPath: `agent-module/plugins/resilience4j/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/resilience4j/README.md)","tokens":300,"sizeBytes":217},{"name":"README.md","path":"agent-module/plugins/rocketmq/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rocketmq/README.md","title":"rocketmq Documentation","category":"plugin-manifest","format":"markdown","content":"# rocketmq Documentation\n\nPath: `agent-module/plugins/rocketmq/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rocketmq/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/rxjava/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rxjava/README.md","title":"rxjava Documentation","category":"plugin-manifest","format":"markdown","content":"# rxjava Documentation\n\nPath: `agent-module/plugins/rxjava/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/rxjava/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/spring-boot/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-boot/README.md","title":"spring-boot Documentation","category":"plugin-manifest","format":"markdown","content":"# spring-boot Documentation\n\nPath: `agent-module/plugins/spring-boot/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-boot/README.md)","tokens":300,"sizeBytes":214},{"name":"README.md","path":"agent-module/plugins/spring-cloud-sleuth/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-cloud-sleuth/README.md","title":"spring-cloud-sleuth Documentation","category":"plugin-manifest","format":"markdown","content":"# spring-cloud-sleuth Documentation\n\nPath: `agent-module/plugins/spring-cloud-sleuth/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-cloud-sleuth/README.md)","tokens":300,"sizeBytes":238},{"name":"README.md","path":"agent-module/plugins/spring-data-r2dbc/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-data-r2dbc/README.md","title":"spring-data-r2dbc Documentation","category":"plugin-manifest","format":"markdown","content":"# spring-data-r2dbc Documentation\n\nPath: `agent-module/plugins/spring-data-r2dbc/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-data-r2dbc/README.md)","tokens":300,"sizeBytes":232},{"name":"README.md","path":"agent-module/plugins/spring-tx/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-tx/README.md","title":"spring-tx Documentation","category":"plugin-manifest","format":"markdown","content":"# spring-tx Documentation\n\nPath: `agent-module/plugins/spring-tx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-tx/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"agent-module/plugins/spring-webflux/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-webflux/README.md","title":"spring-webflux Documentation","category":"plugin-manifest","format":"markdown","content":"# spring-webflux Documentation\n\nPath: `agent-module/plugins/spring-webflux/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring-webflux/README.md)","tokens":300,"sizeBytes":223},{"name":"README.md","path":"agent-module/plugins/spring/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring/README.md","title":"spring Documentation","category":"plugin-manifest","format":"markdown","content":"# spring Documentation\n\nPath: `agent-module/plugins/spring/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/spring/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/thread/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thread/README.md","title":"thread Documentation","category":"plugin-manifest","format":"markdown","content":"# thread Documentation\n\nPath: `agent-module/plugins/thread/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thread/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/thrift/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thrift/README.md","title":"thrift Documentation","category":"plugin-manifest","format":"markdown","content":"# thrift Documentation\n\nPath: `agent-module/plugins/thrift/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/thrift/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/tomcat/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/tomcat/README.md","title":"tomcat Documentation","category":"plugin-manifest","format":"markdown","content":"# tomcat Documentation\n\nPath: `agent-module/plugins/tomcat/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/tomcat/README.md)","tokens":300,"sizeBytes":199},{"name":"README.md","path":"agent-module/plugins/undertow-servlet/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow-servlet/README.md","title":"undertow-servlet Documentation","category":"plugin-manifest","format":"markdown","content":"# undertow-servlet Documentation\n\nPath: `agent-module/plugins/undertow-servlet/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow-servlet/README.md)","tokens":300,"sizeBytes":229},{"name":"README.md","path":"agent-module/plugins/undertow/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow/README.md","title":"undertow Documentation","category":"plugin-manifest","format":"markdown","content":"# undertow Documentation\n\nPath: `agent-module/plugins/undertow/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/undertow/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/user/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/user/README.md","title":"user Documentation","category":"plugin-manifest","format":"markdown","content":"# user Documentation\n\nPath: `agent-module/plugins/user/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/user/README.md)","tokens":300,"sizeBytes":193},{"name":"README.md","path":"agent-module/plugins/vertx/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/vertx/README.md","title":"vertx Documentation","category":"plugin-manifest","format":"markdown","content":"# vertx Documentation\n\nPath: `agent-module/plugins/vertx/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/vertx/README.md)","tokens":300,"sizeBytes":196},{"name":"README.md","path":"agent-module/plugins/weblogic/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/weblogic/README.md","title":"weblogic Documentation","category":"plugin-manifest","format":"markdown","content":"# weblogic Documentation\n\nPath: `agent-module/plugins/weblogic/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/weblogic/README.md)","tokens":300,"sizeBytes":205},{"name":"README.md","path":"agent-module/plugins/websphere/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/websphere/README.md","title":"websphere Documentation","category":"plugin-manifest","format":"markdown","content":"# websphere Documentation\n\nPath: `agent-module/plugins/websphere/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/websphere/README.md)","tokens":300,"sizeBytes":208},{"name":"README.md","path":"web-frontend/src/main/v3/packages/datetime-picker/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/README.md","title":"datetime-picker Documentation","category":"plugin-manifest","format":"markdown","content":"# datetime-picker Documentation\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/README.md)","tokens":300,"sizeBytes":252},{"name":"README.md","path":"web-frontend/src/main/v3/packages/scatter-chart/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/README.md","title":"scatter-chart Documentation","category":"plugin-manifest","format":"markdown","content":"# scatter-chart Documentation\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/README.md)","tokens":300,"sizeBytes":246},{"name":"README.md","path":"web-frontend/src/main/v3/packages/server-map/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/README.md","title":"server-map Documentation","category":"plugin-manifest","format":"markdown","content":"# server-map Documentation\n\nPath: `web-frontend/src/main/v3/packages/server-map/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/server-map/README.md)","tokens":300,"sizeBytes":237},{"name":"README.md","path":"web-frontend/src/main/v3/packages/ui/README.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/README.md","title":"ui Documentation","category":"plugin-manifest","format":"markdown","content":"# ui Documentation\n\nPath: `web-frontend/src/main/v3/packages/ui/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/ui/README.md)","tokens":300,"sizeBytes":213},{"name":"code-reviewer.md","path":"web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md","title":"Subagent: code-reviewer","category":"subagent-persona","format":"markdown","content":"# Subagent: code-reviewer\n\nPath: `web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/code-reviewer/code-reviewer.md)","tokens":300,"sizeBytes":268},{"name":"debugger.md","path":"web-frontend/src/main/v3/.claude/agents/debugger/debugger.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/debugger/debugger.md","title":"Subagent: debugger","category":"subagent-persona","format":"markdown","content":"# Subagent: debugger\n\nPath: `web-frontend/src/main/v3/.claude/agents/debugger/debugger.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/debugger/debugger.md)","tokens":300,"sizeBytes":243},{"name":"explorer.md","path":"web-frontend/src/main/v3/.claude/agents/explorer/explorer.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/explorer/explorer.md","title":"Subagent: explorer","category":"subagent-persona","format":"markdown","content":"# Subagent: explorer\n\nPath: `web-frontend/src/main/v3/.claude/agents/explorer/explorer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/explorer/explorer.md)","tokens":300,"sizeBytes":243},{"name":"qa-engineer.md","path":"web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md","rawUrl":"https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md","title":"Subagent: qa-engineer","category":"subagent-persona","format":"markdown","content":"# Subagent: qa-engineer\n\nPath: `web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md)","tokens":300,"sizeBytes":258}],"systemPromptSnippet":"<yakaai_skills repo=\"pinpoint-apm/pinpoint\">\n<!-- File: .claude/rules/build.md (Tokens: ~199 | Category: anthropic-skill) -->\n---\ndescription: Maven build commands for multi-module project, frontend build\nglobs:\n---\n\n## Build Commands\n\nMaven wrapper (`./mvnw`) is the build tool. This is a multi-module Maven project with 30+ top-level modules.\n\n```bash\n# Build everything (skip tests)\n./mvnw install -Dmaven.test.skip=true\n\n# Build specific modules with dependencies\n./mvnw install -pl agent -am -Dmaven.test.skip=true\n./mvnw install -pl collector -am -Dmaven.test.skip=true\n./mvnw install -pl web -am -Dmaven.test.skip=true\n\n# Build web without frontend\n./mvnw install -pl web -am -Dbuild.frontend.skip=true -Dmaven.test.skip=true\n```\n\n## Frontend\n\nLocated at `web-frontend/src/main/v3/`. Built via Maven frontend plugin using Yarn. Can be skipped with `-Dbuild.frontend.skip=true`.\n\n<!-- File: .claude/rules/testing.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/.claude/rules/testing.md)\n\n<!-- File: agent-module/plugins/type-provider-schema.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Plugins Skill\n\nPath: `agent-module/plugins/type-provider-schema.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/agent-module/plugins/type-provider-schema.json)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/api-hooks.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/api-hooks.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/api-hooks.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/code-review-policy.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-review-policy.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-review-policy.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/code-style.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/code-style.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/code-style.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/components.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/components.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/components.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/git-workflow.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/git-workflow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/git-workflow.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/i18n.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/i18n.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/i18n.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/monorepo.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/monorepo.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/monorepo.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/routing.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/routing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/routing.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/service-map.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/service-map.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/service-map.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/state-management.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/state-management.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/state-management.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/testing.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/testing.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/testing.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/rules/tool-usage.md (Tokens: ~300 | Category: anthropic-skill) -->\n# Rules Skill\n\nPath: `web-frontend/src/main/v3/.claude/rules/tool-usage.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/.claude/rules/tool-usage.md)\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/add-translation/SKILL.md (Tokens: ~514 | Category: anthropic-skill) -->\n---\nname: add-translation\ndescription: 영어와 한국어 로케일 파일 모두에 i18n 번역 키를 추가합니다. 사용자 노출 문자열을 추가하거나, 번역 키가 누락되었거나, 새 UI 텍스트를 국제화할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 번역 키 추가\n\n영어 텍스트 `$1`과 한국어 텍스트 `$2`를 가진 번역 키 `$0`을 추가합니다.\n\n## 단계\n\n1. `packages/ui/src/constants/locales/en.json` 읽기\n2. `packages/ui/src/constants/locales/ko.json` 읽기\n3. 키 접두사를 기반으로 올바른 섹션 결정 (COMMON, SERVER_MAP, TRANSACTION 등)\n4. 올바른 섹션의 **두 파일 모두**에 키 추가, 섹션 내 알파벳 순서 유지\n5. 한국어 텍스트가 제공되지 않은 경우, 나중에 쉽게 찾아 바꿀 수 있도록 `[TODO]` 접두사를 붙인 영어 텍스트를 플레이스홀더로 추가 (예: `\"[TODO] English text\"`)\n\n## 키 네이밍\n- 점으로 구분된 섹션을 사용하는 SCREAMING_SNAKE_CASE\n- 예시: `COMMON.SAVE`, `SERVER_MAP.NODE_COUNT`, `ERROR_ANALYSIS.CHART_TITLE`\n\n## 가이드라인\n- 항상 en.json과 ko.json을 동시에 업데이트\n- 한국어 번역은 직역 금지, 자연스러운 한국어로 작성\n- 동적 값은 이중 중괄호로 보간: `\"Hello, {{name}}!\"` / `\"안녕하세요, {{name}}님!\"`\n- 복수형에는 i18next 복수 접미사 사용: `_one`, `_other`\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/apply-review/SKILL.md (Tokens: ~3075 | Category: anthropic-skill) -->\n---\nname: apply-review\ndescription: 현재 작업 중인 PR에 달린 코드 리뷰를 확인하고, 타당한 리뷰는 코드를 고쳐 반영(커밋·푸시·PR 갱신)하고, 부당한 리뷰는 이유를 설명하며 무시합니다. PR 리뷰 코멘트를 반영하거나, 리뷰 피드백에 대응하거나, \"리뷰 반영\", \"리뷰 적용\", \"코드리뷰 처리\"를 요청할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰 반영 (apply-review)\n\n현재 작업의 PR에 달린 코드 리뷰를 가져와 **하나씩 평가**하고, 타당하면 코드에 반영하고 부당하면 무시합니다.\n모든 판단은 **대화창에 설명**하고 **PR 코멘트로도 남깁니다** (적용한 것·무시한 것 모두).\n\n## 핵심 원칙\n\n- **모든 설명은 개발자가 아니어도 이해할 수 있게, 짧고 쉽게.** 전문 용어 대신 \"무엇을 왜 바꿨는지/안 바꿨는지\"를 한두 문장으로.\n- **언어 규칙**: 사용자 대화창 설명은 **한국어**, PR 코멘트·커밋 메시지·PR 본문은 **영어** (`.claude/rules/git-workflow.md`).\n- **리뷰를 맹목적으로 따르지 않습니다.** 각 리뷰가 정말 맞는지, 우리 코드 맥락에서 타당한지 직접 판단합니다. 틀리거나 불필요하면 정중히 무시하고 이유를 댑니다.\n- **되돌리기 어려운 작업(커밋·푸시·PR 갱신) 전에는 반드시 `/qa-pr`을 통과해야 합니다.**\n\n## 0단계: PR 컨텍스트 확정\n\n먼저 지금 어떤 PR을 다루는지 정합니다.\n\n```bash\ngit branch --show-current\ngh pr view --json number,title,url\n```\n\n다음 두 경우에는 **작업을 멈추고 사용자에게 PR 링크를 요청하세요.** 추측해서 진행하지 않습니다.\n\n- 현재 브랜치가 `master`인 경우 (master에서는 직접 작업하지 않습니다 — `.claude/rules/git-workflow.md`)\n- `gh pr view`가 실패하는 등 **현재 컨텍스트로 PR을 알 수 없는 경우**\n\n요청 예시: \"현재 브랜치가 master라(또는 연결된 PR을 찾지 못해) 어떤 PR의 리뷰를 반영할지 알 수 없어요. PR 링크를 알려주세요.\"\n\n링크를 받으면 거기서 `{owner}/{repo}`와 PR 번호를 파싱하고, 해당 PR 브랜치로 이동해 작업합니다:\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\n```\n\n체크아웃 후 다시 `git branch --show-current`로 master가 아님을 확인합니다.\n리모트: `origin`=내 포크(jihea-park/pinpoint), `upstream`=pinpoint-apm/pinpoint.\n\n## 1단계: 리뷰 수집\n\n확정된 PR의 리뷰 전부(요약 리뷰 + 인라인 코멘트, Copilot·사람 모두)를 가져옵니다.\n\n```bash\n# PR 번호와 저장소가 아직 없으면 다시 확인\ngh pr view --json number,title,url\n\n# 리뷰 요약(승인/변경요청/총평) — 리뷰어와 본문\ngh api repos/{owner}/{repo}/pulls/{number}/reviews \\\n  --jq '.[] | {id, user: .user.login, state, body}'\n\n# 인라인 코드 코멘트 — 파일·라인·내용·comment id (반영 대상의 핵심)\ngh api repos/{owner}/{repo}/pulls/{number}/comments \\\n  --jq '.[] | {id, user: .user.login, path, line, body}'\n```\n\n`{owner}/{repo}`는 PR이 올라간 저장소(보통 `pinpoint-apm/pinpoint`). 위 `gh pr view`의 `url`(예: `https://github.com/pinpoint-apm/pinpoint/pull/13913`)에서 파싱해 채웁니다.\n이미 답글이 달려 처리된 코멘트는 중복 대응하지 않도록 `in_reply_to_id`가 없는(최상위) 코멘트 위주로 봅니다.\n\n## 2단계: 각 리뷰를 하나씩 평가\n\n리뷰 코멘트마다 다음을 따집니다. **추측하지 말고 실제 코드를 열어 확인하세요.**\n\n1. **무엇을 지적하는가** — 코멘트가 가리키는 파일·라인을 직접 읽습니다.\n2. **타당한가** — 우리 코드 맥락에서 실제 문제인지, 프로젝트 규약(`.claude/rules/`)에 비춰 맞는지 판단합니다.\n3. **부수효과는 없는가** — 고쳤을 때 다른 동작이 깨지지 않는지 봅니다.\n\n판단은 두 갈래입니다:\n\n- **타당함 → 반영** (3단계로)\n- **부당하거나 불필요함 → 무시**: 왜 적용하지 않는지 쉬운 말로 설명합니다. 예) 리뷰가 가정한 상황이 실제로는 생기지 않음 / 이미 다른 곳에서 처리됨 / 이슈 범위 밖 / 제안대로면 오히려 기존 동작이 깨짐.\n\n> 부당해 보여도 단정하기 전에 한 번 더 코드로 확인하세요. 반대로 \"리뷰어가 그렇게 말했으니까\"는 적용의 이유가 될 수 없습니다.\n\n## 3단계: 타당한 리뷰 반영 — 영향 분석 후 수정\n\n코드를 고치기 전에 `.claude/rules/code-review-policy.md`의 회귀 방지 절차를 따릅니다:\n\n- 고칠 파일의 **모든 호출자·소비자**를 먼저 파악합니다 (타입/훅/아톰/props/엔드포인트 변경 시 사용처 전부 Grep).\n- 수정이 **이번 PR이 해결하려던 이슈와 충돌하지 않는지** 확인합니다. (PR 제목·본문·연결 이슈의 의도를 다시 읽기)\n- 수정 후, 영향받은 파일을 다시 읽어 기존 시그니처·반환 타입·props·import 경로가 깨지지 않았는지 검증합니다.\n\n여러 리뷰를 반영할 경우 관련 수정을 모아 **하나의 커밋**으로 묶습니다(성격이 전혀 다르면 분리 가능).\n\n## 4단계: 리베이스로 최종 코드 만든 뒤 `/qa-pr` 필수 (게이트)\n\nQA는 **커밋·푸시될 최종 코드**에 대해 해야 의미가 있습니다. 리베이스로 충돌을 해결하면 코드가 바뀌므로, **리베이스를 먼저 끝내고 그 결과에 `/qa-pr`을 실행**합니다. (QA 뒤에 리베이스를 하면 변경된 코드가 검증되지 않은 채 커밋될 수 있습니다.)\n\n```bash\n# 1) 먼저 upstream 최신화 리베이스 — 충돌이 있으면 해결까지 완료 (git-workflow.md)\ngit fetch upstream master\ngit rebase upstream/master\n```\n\n```text\n# 2) 그 다음 /qa-pr 실행 — 빌드(yarn build)·테스트(yarn test)·동작 QA·회귀 점검\n```\n\n판정이 **FAIL이면 절대 커밋하지 말고** 문제를 먼저 해결합니다. (`.claude/rules/git-workflow.md`의 QA 게이트)\n`/qa-pr` 통과 후 셀프 체크: 디버그 코드(`console.log` 등) 없음, 코드 스타일 준수, 기존 기능 정상.\n\n## 5단계: 커밋 · 푸시 · PR 갱신\n\n리베이스와 QA가 모두 끝나고 PASS일 때만 진행합니다.\n\n```bash\ngit add <변경 파일>\ngit commit -m \"[#issue_number] Description\"   # 영어로. 같은 플랫폼이면 #issue_number, 다른 플랫폼이면 #noissue (git-workflow.md)\ngit push origin <branch-name>                 # 기존 PR 갱신이므로 -u 불필요 (이미 origin 추적 중)\n```\n\n커밋·PR 메시지는 **항상 영어**. 기존 PR이 같은 브랜치를 추적하므로 push만으로 PR이 갱신됩니다.\n\n## 6단계: 판단을 PR 코멘트로 남기기 (적용·무시 모두)\n\n각 리뷰 코멘트에 **답글**로 결론을 남깁니다. 답글 본문은 **영어**로, 짧고 명확하게.\n\n```bash\n# 특정 인라인 리뷰 코멘트에 답글 (본문은 영어로 — 플레이스홀더도 영어)\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Applied. <one-line reason in English>\"\n# 또는 무시한 경우\ngh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \\\n  --method POST -f body=\"Not applied. <one-line reason in English>\"\n```\n\n요약 리뷰(인라인이 아닌 총평)에 대응할 때는 PR 본문 코멘트를 사용:\n\n```bash\ngh pr comment {number} --body \"<summary of applied/ignored items in English>\"\n```\n\n## 7단계: 대화창 보고\n\n마지막으로 사용자에게 쉬운 말로 정리해 보여줍니다:\n\n1. **적용한 리뷰**: 무엇을, 왜 타당해서, 어떻게 고쳤는지 (각 한두 문장)\n2. **무시한 리뷰**: 무엇을, 왜 적용하지 않았는지 (각 한두 문장)\n3. **QA 결과**: PASS / FAIL\n4. **반영 결과**: 커밋 해시, 푸시·PR 갱신 여부, 남긴 PR 코멘트\n\n> 적용/무시 어느 쪽이든 \"왜\"가 가장 중요합니다. 비개발자도 납득할 수 있게 설명하세요.\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/create-api-hook/SKILL.md (Tokens: ~796 | Category: anthropic-skill) -->\n---\nname: create-api-hook\ndescription: useGetXxx 패턴에 따라 새 React Query API 훅을 생성합니다. 새 백엔드 API를 연동하거나, 엔드포인트에 대한 훅이 필요하거나, 데이터 페칭 로직을 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 API 훅 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 엔드포인트에 대한 새 API 훅을 생성합니다.\n\n다음 단계를 따르세요:\n\n## 1. 기존 패턴 분석\n- `packages/ui/src/hooks/api/reactQueryHelper.ts`를 읽어 queryFn과 queryClient 이해\n- `packages/ui/src/constants/EndPoints.ts`에서 엔드포인트 네이밍 확인\n- `packages/ui/src/hooks/api/`의 유사한 기존 훅에서 패턴 파악\n\n## 2. 엔드포인트 정의\n`packages/ui/src/constants/EndPoints.ts`에 엔드포인트 상수 추가:\n```typescript\nexport const NEW_ENDPOINT = `/api/path/to/endpoint`;\n```\n\n## 3. 타입 정의\n`packages/ui/src/constants/types/`에 타입 생성 또는 확장:\n```typescript\nexport namespace GetNewData {\n  export interface Parameters {\n    applicationName: string;\n    from: number;\n    to: number;\n    // ... 기타 파라미터\n  }\n  export interface Response {\n    // ... 응답 형태\n  }\n}\n```\n`packages/ui/src/constants/types/index.ts`에서 익스포트.\n\n## 4. 훅 생성\n`packages/ui/src/hooks/api/useGetNewData.ts` 생성:\n```typescript\nimport { useQuery } from '@tanstack/react-query';\nimport { END_POINTS, GetNewData } from '@pinpoint-fe/ui/src/constants';\nimport { convertParamsToQueryString } from '@pinpoint-fe/ui/src/utils';\nimport { queryFn } from './reactQueryHelper';\n\nexport const useGetNewData = (params: GetNewData.Parameters) => {\n  const queryString = convertParamsToQueryString(params);\n\n  return useQuery<GetNewData.Response>({\n    queryKey: [END_POINTS.NEW_ENDPOINT, queryString],\n    queryFn: queryFn(`${END_POINTS.NEW_ENDPOINT}?${queryString}`),\n    enabled: !!params.applicationName,\n    gcTime: 30000,\n  });\n};\n```\n\n## 5. 훅 익스포트\n`packages/ui/src/hooks/api/index.ts` (또는 해당하는 배럴 파일)에서 익스포트.\n\n## 6. 핵심 가이드라인\n- 필수 파라미터 없이 쿼리가 실행되지 않도록 `enabled` 사용\n- `reactQueryHelper.ts`의 `queryFn` 사용 — 직접 fetch를 구현하지 마세요\n- 쿼리 키에는 응답에 영향을 미치는 엔드포인트와 모든 파라미터 포함\n- POST 뮤테이션은 `useQuery` 대신 `useMutation` 사용\n- 폴링의 경우 `gcTime: 0` 설정, 부드러운 전환을 위해 `placeholderData: (prev) => prev` 사용\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/create-component/SKILL.md (Tokens: ~1213 | Category: anthropic-skill) -->\n---\nname: create-component\ndescription: 프로젝트의 shadcn/ui + Tailwind 패턴에 따라 새 React 컴포넌트를 생성합니다. UI 프리미티브(버튼, 다이얼로그 등) 또는 도메인 컴포넌트(ServerMap, Inspector 등)를 새로 만들 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 컴포넌트 생성\n\n`$ARGUMENTS` 설명을 가진 `$0` 컴포넌트를 생성합니다.\n\n## 1. 컴포넌트 유형 결정\n\n### UI 프리미티브 (packages/ui/src/components/ui/)\n재사용 가능한 일반 UI 컴포넌트(버튼 변형, 다이얼로그, 입력 등):\n- shadcn/ui 패턴 준수: Radix UI + CVA + Tailwind\n- `@pinpoint-fe/ui/src/lib/utils`의 `cn()` 사용\n- 적절한 경우 Radix Slot을 통한 `asChild` 지원\n- ref 전달을 위한 `React.forwardRef` 사용\n- CVA(class-variance-authority)로 variants 정의\n\n### 도메인 컴포넌트 (packages/ui/src/components/{DomainName}/)\n기능별 컴포넌트(ServerMap, ErrorAnalysis 등):\n- `packages/ui/src/components/` 아래 서브디렉토리 생성\n- UI 프리미티브를 조합하여 구성\n- 데이터 페칭에 React Query 훅 사용\n- 공유 상태에 Jotai 아톰 사용\n- 비동기 콘텐츠를 Suspense + ErrorBoundary로 감싸기\n\n## 2. 기존 예시 읽기\n- UI 프리미티브: `packages/ui/src/components/ui/button.tsx` 또는 `dialog.tsx` 읽기\n- 도메인 컴포넌트: 타겟과 유사한 기존 도메인 컴포넌트 읽기\n\n## 3. 컴포넌트 생성\n\n### UI 프리미티브 템플릿\n```tsx\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\n\nconst componentVariants = cva('base-classes', {\n  variants: { variant: { default: '...', outline: '...' }, size: { default: '...', sm: '...' } },\n  defaultVariants: { variant: 'default', size: 'default' },\n});\n\nexport interface ComponentProps\n  extends React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof componentVariants> {}\n\nconst Component = React.forwardRef<HTMLDivElement, ComponentProps>(\n  ({ className, variant, size, ...props }, ref) => (\n    <div ref={ref} className={cn(componentVariants({ variant, size, className }))} {...props} />\n  ),\n);\nComponent.displayName = 'Component';\nexport { Component, componentVariants };\n```\n\n### 도메인 컴포넌트 템플릿\n```tsx\nimport React, { Suspense } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { useTranslation } from 'react-i18next';\nimport { useAtomValue } from 'jotai';\nimport { cn } from '@pinpoint-fe/ui/src/lib/utils';\nimport { someSearchParamAtom } from '@pinpoint-fe/ui/src/atoms';\nimport { useGetMyData } from '@pinpoint-fe/ui/src/hooks/api';\n\nexport interface MyComponentProps {\n  className?: string;\n}\n\nconst MyComponentContent = ({ className }: MyComponentProps) => {\n  const { t } = useTranslation();\n  const searchParam = useAtomValue(someSearchParamAtom);\n  const { data } = useGetMyData({ param: searchParam });\n\n  if (!data) return null;\n\n  return <div className={cn('...', className)}>{/* 렌더링 */}</div>;\n};\n\nexport const MyComponent = ({ className }: MyComponentProps) => (\n  <ErrorBoundary fallback={<div>Error</div>}>\n    <Suspense fallback={<div>Loading...</div>}>\n      <MyComponentContent className={className} />\n    </Suspense>\n  </ErrorBoundary>\n);\n```\n\n## 4. 스타일링 규칙\n- Tailwind CSS만 사용 — 인라인 스타일, CSS 모듈 금지\n- 테마에는 CSS 변수 사용: `var(--ui-primary)`, `var(--ui-border)`\n- 모든 className 합성에 `cn()` 사용\n- Tailwind 브레이크포인트로 반응형 디자인\n\n## 5. 완료\n- `packages/ui/src/components/index.ts` (또는 해당 서브디렉토리의 `index.ts`)에서 컴포넌트 익스포트\n- `yarn build`로 TypeScript 오류 없음 확인\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/create-page/SKILL.md (Tokens: ~1001 | Category: anthropic-skill) -->\n---\nname: create-page\ndescription: Pinpoint 프로젝트 패턴에 따라 새 페이지를 생성합니다. 애플리케이션에 새 라우트/페이지를 추가하거나, 새 화면을 만들거나, 기존 라우팅 구조에 페이지를 추가할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 새 페이지 생성\n\n**인자 형식**: `/create-page <PageName> [설명]`\n- `$0` — 생성할 페이지 이름 (PascalCase, 예: `RealTimeDashboard`)\n- `$ARGUMENTS` — 페이지 목적 설명 (선택 사항, 예: `실시간 메트릭 대시보드`)\n- 인자 없이 실행하면 사용자에게 페이지 이름과 목적을 먼저 질문합니다.\n\n`$ARGUMENTS` 설명을 가진 `$0` 페이지를 생성합니다.\n\n다음 단계를 엄격히 따르세요:\n\n## 1. 기존 페이지 분석\n- `packages/ui/src/constants/path.ts`를 읽어 APP_PATH 패턴 파악\n- `apps/web/src/routes/index.tsx`를 읽어 라우팅 구조 확인\n- `packages/ui/src/pages/`의 유사한 기존 페이지와 `apps/web/src/pages/`의 래퍼 읽기\n\n## 2. 파일 생성 (순서대로)\n\n### 2a. 라우트 경로 추가\n`packages/ui/src/constants/path.ts`의 `APP_PATH`에 새 경로 상수 추가.\n\n### 2b. 페이지 컴포넌트 생성\n`packages/ui/src/pages/{PageName}.tsx` 생성:\n- `@pinpoint-fe/ui`에서 훅과 컴포넌트 임포트\n- `configuration` prop 받기 (페이지 래퍼의 `configurationAtom`에서 읽음)\n- 적절한 검색 파라미터 훅 사용\n- 데이터 페칭에 React Query 훅 사용\n\n### 2c. 페이지 컴포넌트 익스포트\n`packages/ui/src/pages/index.ts`에서 페이지 익스포트 (없으면 생성).\n\n### 2d. 라우트 로더 생성 (날짜 파라미터가 필요한 경우)\n기존 로더의 패턴을 따라 `packages/ui/src/loader/{pageName}.ts` 생성:\n- URL 파라미터에서 application 파싱\n- `periodMax` 설정에 대해 날짜 범위 검증\n- 유효하지 않으면 올바른 날짜로 리다이렉트\n\n### 2e. 페이지 래퍼 생성\n`apps/web/src/pages/<PageName>.tsx` 생성:\n```tsx\n// <PageName>을 실제 페이지 이름으로 교체 (예: Inspector, ErrorAnalysis)\nimport { useAtomValue } from 'jotai';\nimport { <PageName>Page } from '@pinpoint-fe/ui';\nimport { configurationAtom } from '@pinpoint-fe/ui/src/atoms';\n\nexport default function <PageName>() {\n  const configuration = useAtomValue(configurationAtom);\n  return <<PageName>Page configuration={configuration} />;\n}\n```\n\n### 2f. 라우트 추가\n`apps/web/src/routes/index.tsx`에 라우트 추가:\n- 상단에 lazy 임포트 추가\n- `InitialFetchOutlet` children에 라우트 항목 추가 (설정 페이지는 `ConfigurationOutlet`)\n- 로더와 엘리먼트 포함\n\n## 3. i18n 키 추가\n사용자 노출 문자열을 `packages/ui/src/constants/locales/`의 `en.json`과 `ko.json` 모두에 추가.\n\n## 4. 검증\n- 라우트 경로가 고유한지 확인\n- 모든 임포트가 올바른지 확인\n- 라우트 트리에서 페이지가 올바른 레이아웃 outlet 내에 배치되었는지 확인\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/merge-check/SKILL.md (Tokens: ~8254 | Category: anthropic-skill) -->\n---\nname: merge-check\ndescription: PR을 머지해도 되는지 판단하는 머지 전 최종 리뷰. PR이 무엇을 했는지 먼저 요약하고, 기존에 잘 동작하던 기능이 깨지지 않았는지(회귀)를 가장 꼼꼼히 검증한 뒤, 동작 정확성·코드 스타일·CI까지 점검해 머지 가능/불가를 판정하고, `yarn dev`로 직접 열어봐야 할 화면 목록까지 알려줍니다. \"머지해도 되나\", \"머지 전에 봐줘\", \"이 PR 리뷰해줘\", \"PR 괜찮은지 확인\", \"approve해도 되나\", \"머지 전에 뭘 확인해야 하나\" 같은 요청이나, 사용자가 PR 링크만 던져줄 때 반드시 이 스킬을 사용하세요. 현재 브랜치에 연결된 PR이 있으면 링크 없이도 동작합니다.\n---\n\n# 머지 전 최종 리뷰 (merge-check)\n\n**이 스킬의 목적은 \"머지 버튼을 눌러도 안전한가\"에 답하는 것입니다.**\n\n가장 중요한 판단 기준은 하나입니다: **기존에 잘 동작하던 기능이 그대로 동작하는가.**\n새 기능이 조금 부족한 건 다음 PR에서 고칠 수 있지만, 잘 쓰던 기능이 깨지면 사용자가 바로 피해를 봅니다.\n그래서 이 스킬은 \"새로 추가된 코드가 예쁜가\"보다 **\"이 변경이 무엇을 건드렸고, 그것을 쓰던 곳들이 아직 멀쩡한가\"**에 시간을 더 씁니다.\n\n## 절대 하지 않는 것\n\n- **머지하지 않습니다.** `gh pr merge`는 어떤 경우에도 실행하지 않습니다. 이 스킬은 판단만 하고, 머지는 사용자가 합니다.\n- **코드를 고치지 않습니다.** 문제를 찾으면 보고합니다. 고치는 건 별개 작업(`/apply-review`)입니다.\n- **GitHub에 아무것도 쓰지 않습니다.** 결과는 대화창에만 한국어로 보고합니다. PR 코멘트나 Approve는 사용자가 명시적으로 요청할 때만, 확인을 받고 남깁니다.\n- **확인하지 않은 것을 확인한 척하지 않습니다.** 못 본 건 \"확인 못 함\"으로 적습니다. 근거 없는 ✅ 는 이 스킬을 쓰는 의미를 지웁니다.\n\n## 0단계: 어떤 PR인지 확정 + 작업 중인 내용 보호\n\n```bash\ngit branch --show-current\ngit status --porcelain          # 커밋 안 된 작업이 있는지 먼저 확인\ngit rev-parse HEAD              # 로컬이 보고 있는 코드\ngh pr view --json number,title,url,headRefName,headRefOid,baseRefName,state,mergeable,author\n```\n\n**대상 PR 정하기**\n\n- `gh pr view`가 PR을 찾으면 → 그 PR이 대상입니다. 링크를 따로 받지 않습니다.\n- 못 찾거나 현재 브랜치가 `master`이면 → **멈추고 PR 링크를 요청**합니다. 추측하지 않습니다.\n  예: \"현재 브랜치에 연결된 PR을 찾지 못했어요. 리뷰할 PR 링크를 알려주세요.\"\n- 사용자가 링크를 줬으면 항상 그 링크가 우선입니다. 링크에서 `{owner}/{repo}`와 PR 번호를 파싱합니다.\n\n**내가 읽는 코드가 정말 그 PR의 코드인가 (놓치기 쉬움)**\n\n`git rev-parse HEAD`와 PR의 `headRefOid`가 다르면, **로컬에서 보고 있는 코드가 PR에 올라간 코드가\n아닙니다.** 리베이스했지만 아직 푸시하지 않은 경우가 흔합니다. 이때 그냥 리뷰하면 \"PR을 검증했다\"고\n말할 수 없습니다. 두 커밋의 코드가 실제로 같은지 확인하세요:\n\n```bash\ngit diff --stat {headRefOid} HEAD    # 비어 있으면 코드는 동일하고 베이스만 다르다\n```\n\n- **차이가 없거나 무관한 파일뿐이면** → 그대로 진행하고, 보고에 \"로컬이 리베이스로 앞서 있으나 코드는\n  동일\"이라고 한 줄 적습니다.\n- **차이가 있으면** → 어느 쪽을 리뷰할지 사용자에게 확인합니다. 로컬만 있는 수정은 PR에 없으므로,\n  그것까지 통과 판정에 넣으면 실제 머지될 코드와 어긋납니다.\n\n**사용자의 작업 보호**\n\n검증을 위해 브랜치를 옮겨야 할 수도 있습니다. 다만 항상 위험한 건 아니니 구분하세요:\n\n- **이미 그 PR의 브랜치에 있으면** 체크아웃이 필요 없습니다. 그냥 진행합니다.\n- **untracked 파일(`??`)만 있으면** 체크아웃·머지가 그 파일을 건드리지 않으므로 그대로 진행합니다.\n  (보고에 한 줄 언급만)\n- **수정·스테이징된 변경(`M`, `A` 등)이 있으면** 체크아웃하지 말고 사용자에게 먼저 묻습니다:\n  \"커밋되지 않은 변경이 있어요. ① 코드 읽기만으로 리뷰 ② stash 후 진행 — 어느 쪽으로 할까요?\"\n\n브랜치를 옮겼다면 **리뷰가 끝나고 반드시 원래 브랜치로 돌려놓고**, 그 사실을 보고에 적습니다.\n\n## 1단계: 이 PR이 무엇을 했는지 먼저 요약한다\n\n판정보다 요약이 먼저입니다. **무엇을 하려던 PR인지 모르면 \"제대로 했는지\"도 판단할 수 없습니다.**\n\n```bash\ngh pr view {number} --repo {owner}/{repo} --json title,body,commits,files,additions,deletions\n\n# 변경 규모는 git으로 봅니다. (`gh pr diff`에는 --stat이 없는 버전이 있어 그대로 쓰면 실패합니다.)\ngit fetch upstream master\ngit diff --stat upstream/master...HEAD          # 세 점: 공통 조상부터 이 브랜치까지\n```\n\n읽을 것:\n\n- **PR 제목·본문·연결된 이슈** — 이 PR이 풀려던 문제가 무엇인가\n- **커밋 메시지들** — 어떤 순서로 무엇을 했는가\n- **변경 파일 목록과 규모** — 어디를 건드렸는가\n\n여기서 나오는 요약은 사용자에게 보여주는 첫 항목이며, **의도(PR 본문)와 실제(diff)가 어긋나는지**를 보는 기준이기도 합니다.\n\"본문에는 A만 고쳤다고 썼는데 diff에는 B도 바뀌어 있다\" — 이건 그 자체로 리뷰 대상입니다.\n의도하지 않은 파일이 섞여 들어온 것일 수 있고, 그게 회귀의 흔한 원인입니다.\n\n## 2단계: 실제로 빌드·테스트를 돌린다\n\n기본 동작은 **실제 실행**입니다. 코드를 읽어서 \"괜찮아 보인다\"와 빌드가 통과하는 것은 다른 증거입니다.\n(사용자가 \"빠르게 봐줘\"라고 했다면 이 단계를 건너뛰고 CI 결과 조회로 대체하되, **보고에 \"직접 실행하지 않음\"을 명시**합니다.)\n\n검증은 **머지된 뒤의 코드**에 대해 해야 의미가 있습니다. PR 브랜치 단독으로 통과해도,\n그 사이 master에 들어간 다른 변경과 부딪히면 머지 직후에 깨집니다. 그래서 합쳐 놓고 돌립니다.\n\n```bash\ngh pr checkout {number} --repo {owner}/{repo}\ngit fetch upstream master\ngit merge --no-commit --no-ff upstream/master   # 커밋하지 않고 합친 상태만 만든다\n```\n\n- **충돌이 나면** → `git merge --abort` 후, 충돌 파일을 보고 항목으로 올립니다(조건부 또는 머지 불가 사유).\n  이후 리뷰는 PR 브랜치 상태로 코드 읽기 중심으로 이어갑니다.\n- **깨끗하게 합쳐지면** → 그 상태(= 머지 후 master의 모습)에서 검증을 돌립니다.\n\n```bash\n# web-frontend/src/main/v3 에서\nyarn build      # TypeScript 검사 + 프로덕션 빌드\nyarn test       # 전체 워크스페이스 테스트\nyarn lint\n```\n\n검증이 끝나면 `git merge --abort`로 합친 상태를 되돌립니다. (머지 결과를 남기지 않습니다.)\n\n- **빌드 실패 → 무조건 머지 불가.** 더 볼 것 없습니다.\n- **테스트 실패 → 실패한 테스트가 이 PR 때문인지 확인.** upstream/master에서도 같은 테스트가 실패하면 기존 문제입니다.\n  그 구분을 하지 않고 \"테스트 실패\"라고만 보고하면 사용자가 헛수고합니다.\n- **CI 결과도 함께 봅니다.** `gh pr checks`는 실패 여부만 알려주고 이유를 말해주지 않으니,\n  실패한 것이 있으면 반드시 내용까지 읽습니다. (품질 게이트 실패는 저장소 자체의 머지 기준입니다.)\n\n```bash\ngh pr checks {number} --repo {owner}/{repo}\n\n# 실패한 검사의 실제 사유 (예: SonarCloud 품질 게이트가 무엇을 걸었는지)\ngh api repos/{owner}/{repo}/commits/{headRefOid}/check-runs \\\n  --jq '.check_runs[] | select(.conclusion==\"failure\") | \"\\(.name) | \\(.output.title) | \\(.output.summary)\"'\n```\n\n## 3단계: 기존 기능 회귀 점검 — 이 스킬의 핵심\n\n여기에 가장 많은 시간을 씁니다. 방법이 중요합니다. diff를 위에서 아래로 훑어 읽는 것은\n**추가된 코드**를 보게 만들 뿐이고, 회귀는 거의 항상 **추가가 아니라 변경과 삭제**에서 나옵니다.\n\n### 3a. PR을 만든 뒤 master가 얻은 변경과 부딪히는지 본다\n\n**이건 이 PR의 diff만 봐서는 절대 보이지 않습니다.** PR 브랜치 안에서는 완벽한 코드가, 그사이 master에\n들어온 다른 변경과 만나 깨질 수 있습니다. 머지 리뷰가 일반 코드 리뷰와 다른 지점이 바로 여기입니다.\n\n```bash\n# 이 PR의 베이스 이후 master가 새로 얻은 커밋\ngit log --oneline $(git merge-base HEAD upstream/master)..upstream/master\n```\n\n커밋 목록을 **읽고**, 이 PR이 건드린 영역과 겹치는 것이 있으면 그 커밋의 diff를 직접 확인합니다.\n특히 백엔드 변경은 프론트와 계약으로 연결돼 있어 겹치기 쉽습니다:\n\n- **API 응답·상태 코드가 바뀌었나** — 프론트가 특정 상태 코드(404 등)나 필드를 보고 분기한다면,\n  그 규칙이 아직 유효한지 확인합니다. (실제로 \"없는 이름은 404\" 프론트 + \"400을 반환\" 백엔드가\n  같은 시점에 올라온 적이 있습니다.)\n- **필수 파라미터가 늘었나** — 프론트가 그 값 없이 보내는 경로가 있으면 머지 직후 400이 됩니다.\n- **조용히 넘어가던 것이 예외가 되었나** — 기본값으로 대체되던 동작이 오류로 바뀌면, 그에 의존한\n  화면이 깨집니다.\n\n겹치는 것이 없으면 \"master의 새 커밋 N개, 이 PR과 겹치는 영역 없음\"이라고 적고 넘어갑니다.\n\n### 3b. \"위험한 변경\"만 골라낸다\n\ndiff에서 다음을 뽑아 목록으로 만듭니다. 추가만 된 코드는 회귀 위험이 낮으니 뒤로 미룹니다.\n\n```bash\ngit diff upstream/master...HEAD          # 전체 diff를 실제로 읽습니다\n```\n\n| 위험 신호 | 왜 위험한가 |\n|---|---|\n| 지워진 줄 / 삭제된 파일 · export | 쓰던 곳이 남아 있으면 그대로 깨집니다 |\n| 함수 시그니처 · props · 반환 타입 변경 | 호출자가 옛 계약을 기대합니다 |\n| 기본값 변경, optional ↔ required 변경 | 인자를 안 넘기던 호출자의 동작이 조용히 바뀝니다 |\n| 조건문(`if`, 삼항, `&&`) 수정 | 기존 경로가 새 조건에 걸려 빠질 수 있습니다 |\n| 이름 변경 (rename) | 참조를 하나라도 놓치면 깨집니다 |\n| 공용 파일 수정 (hooks/api, atoms, constants, utils) | 소비자가 많아 파급이 큽니다 |\n\n### 3c. 목록의 항목마다 \"쓰던 곳 전부\"를 찾아 확인한다\n\n**이게 핵심 작업입니다.** 변경된 심볼 하나하나에 대해:\n\n```bash\ngit grep -n \"심볼이름\" -- '*.ts' '*.tsx'      # 사용처 전부. 개수를 셉니다\n```\n\n그리고 **사용처를 샘플링하지 말고 전부 확인합니다.** 3곳뿐이면 3곳 다, 20곳이면 20곳 다.\n너무 많아 전부 못 봤으면 **몇 곳 중 몇 곳을 봤는지 숫자로 보고**합니다 (\"18곳 중 12곳 확인\").\n\"대충 괜찮아 보인다\"는 이 스킬에서 가장 위험한 문장입니다.\n\n각 사용처에서 확인할 것: **이번 변경 후에도 이 호출이 예전과 같은 결과를 내는가.**\n타입 체크만 통과하는 것으로는 부족합니다 — 타입은 맞는데 동작만 달라지는 변경이 제일 잡기 어렵습니다\n(기본값 변경, 조건 뒤집힘, 정렬 순서 변경, 캐시 키 변경 등).\n\n`.claude/rules/code-review-policy.md`의 영향 분석 절차를 그대로 따릅니다.\n\n### 3d. Pinpoint에서 실제로 회귀가 났던 자리들\n\n이 프로젝트에서 조용히 깨지기 쉬운 지점입니다. 해당하는 변경이 있으면 반드시 확인합니다.\n\n- **설정 플래그 분기** — `experimental.enableServiceMap` 같은 플래그. **플래그가 꺼진 기존 사용자의 경로가\n  그대로인가**를 별도로 확인합니다. 켠 쪽만 확인하고 넘어가는 실수가 흔합니다. 그 기능에 대한 규칙\n  문서가 `.claude/rules/`에 있으면 함께 읽습니다.\n- **Jotai 아톰** — 아톰은 화면 remount로 지워지지 않습니다. 아톰을 추가·수정했으면 **읽는 모든 컴포넌트**와\n  **초기화 시점**을 확인합니다. 안 지워진 옛 값으로 조회가 나가 400을 받는 사고가 실제로 있었습니다.\n- **React Query 쿼리 키** — 키가 바뀌면 캐시 무효화가 깨지거나, 다른 데이터가 같은 키에 섞입니다.\n- **라우트 경로 / URL 파라미터** — 경로 형태가 바뀌면 기존 링크·북마크가 죽습니다. 로더의 검증·리다이렉트가\n  옛 형태도 받아주는지 확인합니다.\n- **i18n 키** — 제거·이름 변경된 키를 다른 화면이 아직 쓰고 있지 않은지 `git grep`으로 확인합니다.\n- **컴포넌트 props** — 렌더하는 모든 부모가 유효한 props를 넘기는지 확인합니다.\n- **API 엔드포인트 · 응답 타입** — Java 쪽이 함께 바뀌었으면, 프론트가 기대하는 필드·형태와 맞는지 대조합니다.\n  (백엔드 코드는 이 계약 부분만 봅니다. 그 외 Java 내부 로직은 이 스킬의 범위가 아니라고 밝히세요.)\n\n### 3e. 판단이 안 서면 \"모르겠다\"가 정답이다\n\n코드만으로 확신이 안 서면 **추측으로 ✅ 하지 말고** 그 항목을 \"확인 필요\"로 남기고,\n사용자가 무엇을 어떻게 확인하면 되는지 알려줍니다 (예: \"dev 서버에서 A 화면 → B 클릭 순서로 확인\").\n머지 여부를 잘못 통과시키는 비용이, 한 번 더 확인하는 비용보다 훨씬 큽니다.\n\n## 4단계: PR이 의도한 동작을 정확히 하는가\n\n1단계 요약에서 정리한 \"이 PR이 풀려던 문제\"를 다시 꺼내 대조합니다.\n\n- 이슈에 적힌 증상이 이 변경으로 **실제로** 해소되는가 (코드를 따라가며 확인)\n- 해피 패스뿐 아니라 **빈 데이터 · 로딩 · 오류 · 경계값**에서도 의도대로 동작하는가\n- 문제를 근본에서 고쳤는가, 증상만 가렸는가\n- 놓친 케이스가 있는가 (예: 한 화면만 고치고 같은 문제를 가진 다른 화면은 그대로)\n\n깊은 동작 QA가 필요하면 `/qa-pr` 의 체크리스트(엣지 케이스, 상태 무결성, 컴포넌트 상호작용)를 활용합니다.\n\n## 5단계: 그 밖에 머지 전에 봐야 하는 것들\n\n- **코드 스타일 일관성** — `.claude/rules/code-style.md`, `/review-code` 체크리스트 기준.\n  포맷팅뿐 아니라 **주변 코드와 같은 방식으로 쓰였는가**를 봅니다 (같은 일을 다른 패턴으로 하는 코드가\n  섞이면 다음 사람이 어느 쪽을 따라야 할지 모르게 됩니다).\n- **아키텍처 위치** — 라우팅은 `apps/web`, 나머지는 `packages/ui`. 훅·아톰·상수가 제자리에 있는가.\n- **남아 있는 디버그 코드** — `console.log`, 주석 처리된 코드, `TODO`, 임시 하드코딩:\n  ```bash\n  git diff upstream/master...HEAD -- '*.ts' '*.tsx' | grep -nE '^\\+.*(console\\.(log|debug)|debugger|FIXME|XXX)'\n  ```\n- **커밋 메시지 규약** — `[#issue_number] Description`, 영어 (`.claude/rules/git-workflow.md`)\n- **PR 범위** — 이슈와 무관한 변경이 섞여 있지 않은가\n- **테스트** — 아톰·유틸·API 훅·라우트 로더가 바뀌었는데 테스트가 없으면 지적합니다 (핵심 경로)\n- **타입 안전성** — 새로 들어온 `any`, 위험한 단언(`as`), 무시된 null 체크\n- **성능** — 불필요한 리렌더, 누락된 `useEffect` 클린업, 큰 목록의 비효율 처리\n\n## 6단계: 직접 눈으로 확인할 화면 목록을 만든다 (필수)\n\n코드 추적·빌드·테스트로는 **실제로 화면에 무엇이 그려지는지**를 알 수 없습니다. 그래서 이 스킬은\n\"확인 못 했다\"로 끝내지 않고, **사용자가 `yarn dev`로 무엇을 열어 무엇을 봐야 하는지**를 항상\n목록으로 내놓습니다. 목록이 없으면 사용자는 어디서부터 봐야 할지 몰라 결국 아무것도 확인하지 않습니다.\n\n```bash\nyarn dev     # 포트 3000. /api/*는 localhost:8080(백엔드)로 프록시되므로 백엔드가 떠 있어야 데이터가 보인다\n```\n\n### 화면 목록을 뽑는 방법\n\n변경된 파일에서 **화면까지 거슬러 올라갑니다.** 컴포넌트·훅은 그 자체로 화면이 아니므로, 사용처를\n따라 `pages/`와 라우트까지 올라가야 어떤 주소를 열어야 할지 나옵니다.\n\n```bash\n# 변경된 컴포넌트/훅을 누가 쓰는지 → 그 사용처를 또 누가 쓰는지 (pages/ 까지)\ngit grep -n \"변경된컴포넌트\\|변경된훅\" -- '*.tsx' '*.ts'\n```\n\n주소는 `packages/ui/src/constants/path.ts`의 `APP_PATH`에서 확인합니다.\n\n### 목록에 반드시 들어가야 하는 것\n\n1. **기존 화면 (회귀 확인)** — 이번에 바뀐 공용 코드를 쓰는 **모든** 기존 화면. 새 기능 화면보다\n   **먼저** 적습니다. 사용자가 제일 걱정하는 건 \"잘 쓰던 게 깨졌나\"입니다.\n   공용 코드(`hooks/api`, `atoms`, `utils`, 공유 컴포넌트)를 건드렸다면 소비 화면이 여러 개일 테니\n   샘플링하지 말고 다 적습니다.\n2. **새 기능 화면 (의도 확인)** — 이 PR이 만든 동작. PR 본문의 테스트 계획에 있으면 그것을 재사용합니다.\n3. **설정 플래그가 있으면 양쪽 다** — 켠 상태와 **끈 상태**. 끈 쪽이 기존 사용자의 화면이므로 더 중요합니다.\n4. **코드로 확신이 안 섰던 항목** (3e에서 남긴 것) — 그게 바로 눈으로 봐야 하는 것입니다.\n\n각 항목은 **\"무엇을 보면 정상인지\"**까지 적습니다. \"servermap 확인\" 같은 문장은 도움이 안 됩니다.\n\"노드를 클릭하면 오른쪽 패널에 그 노드 이름과 차트가 뜨는지\" 처럼 판정 가능한 문장으로 씁니다.\n브라우저 개발자도구 네트워크 탭에서 볼 것이 있으면(400 응답, 중복 요청 등) 그것도 적습니다.\n\n## 7단계: 보고 (대화창, 한국어)\n\n**항상 이 구조로** 보고합니다. 요약이 판정보다 먼저 오는 순서를 지킵니다 —\n사용자는 \"무엇을 한 PR인지\" 이해한 뒤에 판정을 봐야 그 판정을 신뢰할 수 있습니다.\n\n```markdown\n## 1. 이 PR이 한 일\n- **목적**: (이슈/PR 본문 기준, 한두 문장)\n- **바꾼 것**: (파일 N개 / +A −B 줄, 핵심 변경 3~5개를 쉬운 말로)\n- **의도와 diff의 차이**: (없으면 \"없음\")\n\n## 2. 검증 결과\n| 항목 | 결과 |\n|---|---|\n| upstream/master 병합 | 충돌 없음 / 충돌 (파일) |\n| yarn build | 통과 / 실패 |\n| yarn test | 통과 / 실패 (N건, 이 PR 때문인지 여부) |\n| yarn lint | 통과 / 실패 |\n| CI | 상태 |\n\n## 3. 기존 기능 회귀 점검 (가장 중요)\n**master의 새 변경과의 충돌**: 새 커밋 N개 → 겹치는 것마다 판단 + 근거 (없으면 \"겹침 없음\")\n**위험 변경마다**: (항목) — 사용처 N곳 중 M곳 확인 → 판단 + 근거 (`파일:라인`)\n**확인하지 못한 것**: (항목) — 왜 확인 못 했는지 (→ 6번 목록으로 넘긴다)\n\n## 4. 동작 정확성\n- 의도한 문제가 해소되는가: 판단 + 근거\n- 엣지 케이스: 확인 결과\n\n## 5. 그 외 (스타일 · 구조 · 기타)\n심각도 순으로: Critical / Warning / Suggestion\n\n## 6. 직접 확인할 화면 (`yarn dev`)\n기존 화면 — 회귀 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n| (화면 이름) | `/경로/...` | (판정 가능한 문장) |\n\n새 기능 — 의도 확인:\n| 화면 | 주소 | 무엇을 보면 정상인지 |\n|---|---|---|\n\n## 7. 판정\n**✅ 머지 가능** / **⚠️ 조건부** / **❌ 머지 불가**\n- 이유: (한두 문장)\n- 머지 전에 해야 할 일: (있으면 목록)\n```\n\n### 판정 기준\n\n- **❌ 머지 불가** — 빌드·테스트 실패, 기존 기능이 깨진 것을 **확인**했음, 머지 충돌 미해결\n- **⚠️ 조건부** — 회귀 위험이 있는데 코드만으로는 확정할 수 없음, CI 검사(품질 게이트 등)가 빨간불,\n  또는 고쳐야 할 문제가 남았지만 치명적이지 않음.\n  **무엇을 확인·수정하면 ✅ 가 되는지 반드시 적습니다.**\n- **✅ 머지 가능** — 검증·CI 통과 + 위험 변경의 사용처를 확인했고 문제 없음\n\n> 6번의 화면 목록은 판정과 무관하게 **항상** 내놓습니다. ✅ 라도 \"코드로는 문제를 못 찾았다\"는\n> 뜻이지 \"화면을 봤다\"는 뜻은 아니고, 그 차이를 사용자가 알아야 스스로 판단할 수 있습니다.\n\n> 애매하면 ✅ 를 주지 마세요. ⚠️ 는 사용자가 5분 더 확인하게 만들지만, 잘못된 ✅ 는 깨진 코드를 배포합니다.\n> 다만 근거 없이 ⚠️ 를 남발하는 것도 도움이 되지 않습니다 — ⚠️ 에는 항상 \"무엇을 확인해야 하는지\"가 붙어야 합니다.\n\n### 마지막 정리\n\n- 브랜치를 옮겼다면 원래 브랜치로 복귀했는지 확인하고 보고에 한 줄 적습니다.\n- `git merge --abort`, stash 복원 등 임시 상태가 남지 않았는지 확인합니다.\n- 사용자가 PR 코멘트나 Approve를 원하면 그때 확인을 받고 남깁니다. 본문은 **영어**입니다\n  (`.claude/rules/git-workflow.md`).\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/mvn-web/SKILL.md (Tokens: ~475 | Category: anthropic-skill) -->\n---\nname: mvn-web\ndescription: web-frontend, web, web-starter Maven 모듈을 skipTests 옵션으로 순차 빌드합니다.\n---\n\n# Maven Web 빌드\n\n## 0단계: Pinpoint 루트 디렉토리 탐색\n\n현재 작업 디렉토리부터 상위 디렉토리로 올라가며 `web-frontend`, `web`, `web-starter` 서브디렉토리를 포함하는 `pinpoint`라는 이름의 가장 가까운 상위 디렉토리를 찾습니다. 이 경로를 `PINPOINT_ROOT`로 저장합니다.\n\n```bash\nPINPOINT_ROOT=$(d=\"$PWD\"; while [ \"$d\" != \"/\" ]; do if [ \"$(basename \"$d\")\" = \"pinpoint\" ] && [ -d \"$d/web-frontend\" ] && [ -d \"$d/web\" ] && [ -d \"$d/web-starter\" ]; then echo \"$d\"; break; fi; d=\"$(dirname \"$d\")\"; done)\n```\n\n`PINPOINT_ROOT`가 비어 있으면 즉시 중단하고 pinpoint 루트 디렉토리를 찾을 수 없다고 보고합니다.\n\n## 1~3단계: 모듈 순차 빌드\n\n아래 모듈에 대해 정해진 순서대로 `mvn clean install -DskipTests=true`를 순차 실행합니다. 각 단계는 반드시 성공해야 다음 단계로 진행할 수 있습니다. 실패 시 즉시 중단하고 오류를 보고합니다.\n\n1. `cd $PINPOINT_ROOT/web-frontend && mvn clean install -DskipTests=true`\n2. `cd $PINPOINT_ROOT/web && mvn clean install -DskipTests=true`\n3. `cd $PINPOINT_ROOT/web-starter && mvn clean install -DskipTests=true`\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md (Tokens: ~1308 | Category: anthropic-skill) -->\n---\nname: qa-pr\ndescription: Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요.\n---\n\n# PR 전 QA 게이트\n\n> **이 스킬은 `.claude/agents/qa-engineer/qa-engineer.md`에 정의된 `qa-engineer` 에이전트를 사용하여 실행합니다.**\n> QA 수행 시 해당 에이전트의 사고방식, 체크리스트, 출력 형식을 따르세요.\n\n**실행 시점: 커밋하거나 푸시하기 전에 반드시 실행하세요. QA 판정이 FAIL이면 문제를 해결하기 전까지 커밋하지 마세요.**\n\nPR 제출 전에 현재 변경 사항에 대한 전체 QA를 수행합니다.\n\n## 1단계: 변경 사항 파악\n\n```bash\ngit diff upstream/master --name-only\ngit diff upstream/master --stat\n```\n\n변경된 모든 파일을 나열하고 수정된 내용을 요약합니다.\n\n## 2단계: 빌드 및 테스트\n\n순서대로 실행하세요. **실패 시 즉시 중단하고 보고하세요. 빌드나 테스트 실패 상태에서는 커밋하지 마세요.**\n\n```bash\nyarn build\nyarn test\n```\n\n각각의 통과/실패 여부와 오류 출력을 보고합니다.\n\n## 3단계: 동작 QA\n\n변경된 각 컴포넌트, 훅, 페이지에 대해 기능 분석을 수행합니다:\n\n### 3a. 해피 패스\n- 정상 데이터로 기대되는 동작은 무엇인가?\n- 구현이 그 기대에 부합하는가?\n- 사용자 액션 → 상태 변경 → UI 업데이트 추적\n\n### 3b. 엣지 케이스\n변경된 UI 컴포넌트에 대해 다음을 각각 확인:\n- [ ] 빈/null 데이터 상태 — API가 빈 배열이나 null을 반환할 때 무엇이 렌더링되나?\n- [ ] 로딩 상태 — 스켈레톤/스피너가 표시되나? 빠른 로드에서 깜빡이지 않나?\n- [ ] 오류 상태 — API 실패 / 네트워크 오류. 사용자에게 오류가 표시되나?\n- [ ] 경계값 — 날짜 범위, 페이지 제한, 대용량 데이터셋\n- [ ] 동시 요청 — 빠른 클릭, 여러 탭 전환\n\n### 3c. 상태 무결성\n- [ ] URL 파라미터가 UI 상태를 올바르게 반영 (from/to, application)\n- [ ] 페이지 새로고침이 상태를 유지 (URL이 진실의 원천)\n- [ ] 아톰 상태가 내비게이션 간에 누출되지 않음 (클린업 확인)\n- [ ] React Query 캐시가 뮤테이션 후 오래된 데이터를 표시하지 않음\n\n### 3d. 컴포넌트 상호작용\n- [ ] 변경된 props가 모든 부모 컴포넌트 호출 위치를 만족함\n- [ ] 이벤트 핸들러가 올바르게 발생하고 중복 액션을 생성하지 않음\n- [ ] 무한 리렌더 루프 없음 (아톰 의존성 변경, 불안정한 참조)\n\n## 4단계: Pinpoint 특화 확인\n\n- [ ] application/from/to가 변경될 때 ServerMap이 여전히 렌더링됨\n- [ ] 변경된 코드 근처의 스캐터 차트 상호작용(드래그 선택, 클릭)이 여전히 작동\n- [ ] 트랜잭션 목록 / Inspector 내비게이션이 손상되지 않음\n- [ ] 설정 기반 기능이 여전히 설정을 올바르게 확인함\n\n## 5단계: 회귀 요약\n\n다음을 나열합니다:\n1. **변경된 파일**: (개수와 목록)\n2. **실행된 테스트**: 통과/실패\n3. **빌드**: 통과/실패\n4. **발견된 동작 이슈**: (심각도와 함께 목록)\n5. **QA 판정**: ✅ PASS / ❌ FAIL / ⚠️ PASS WITH WARNINGS\n\nFAIL 또는 PASS WITH WARNINGS인 경우, 머지 전에 필요한 구체적인 조치 사항을 나열합니다.\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/review-code/SKILL.md (Tokens: ~992 | Category: anthropic-skill) -->\n---\nname: review-code\ndescription: Pinpoint 프로젝트 규약에 따라 코드 변경을 리뷰합니다. 커밋 전, PR 리뷰, 또는 코드 품질을 점검할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 코드 리뷰\n\n> **이 스킬은 다음 두 에이전트를 사용하여 실행합니다:**\n> 1. `.claude/agents/explorer/explorer.md` — 코드베이스 탐색 및 변경 사항 파악\n> 2. `.claude/agents/code-reviewer/code-reviewer.md` — 실제 코드 리뷰 수행\n>\n> 리뷰 시 두 에이전트의 사고방식과 체크리스트를 따르세요.\n\n**인자 형식**: `/review-code [파일경로 또는 경로 목록]`\n- `$ARGUMENTS`에 파일 경로를 전달하면 해당 파일을 리뷰합니다. 예: `/review-code packages/ui/src/hooks/api/useGetServerMap.ts`\n- 경로 없이 실행하면 `git diff upstream/master --name-only`로 변경된 파일을 자동 감지합니다.\n\n`$ARGUMENTS`의 코드를 리뷰합니다 (경로가 없으면 최근 git 변경 사항 리뷰).\n\n## 리뷰 체크리스트\n\n### 1. 아키텍처\n- [ ] 올바른 패키지에 코드 위치 (라우팅은 apps/web, 나머지는 packages/ui)\n- [ ] 페이지가 올바른 중첩 레이아웃 outlet에 배치 (InitialFetchOutlet / ConfigurationOutlet)\n- [ ] API 훅이 reactQueryHelper의 공유 queryFn 사용\n- [ ] 상태 관리가 올바른 계층 사용 (URL → Jotai → React Query)\n\n### 2. 코드 스타일\n- [ ] Prettier 포맷팅 (100자, 작은따옴표, 후행 쉼표, 세미콜론)\n- [ ] TypeScript strict 준수 (`any` 금지, 적절한 타입 좁히기)\n- [ ] 임포트 순서: external → @pinpoint-fe/* → relative\n- [ ] 딥 임포트: `@pinpoint-fe/ui` 대신 `@pinpoint-fe/ui/src/constants`\n\n### 3. 컴포넌트\n- [ ] UI 프리미티브가 shadcn/ui 패턴 준수 (Radix + CVA + Tailwind)\n- [ ] 도메인 컴포넌트가 UI 프리미티브를 조합하여 구성\n- [ ] className 병합에 `cn()` 사용\n- [ ] 인라인 스타일이나 CSS 모듈 없음\n\n### 4. 데이터 페칭\n- [ ] 엔드포인트가 EndPoints.ts에 정의됨\n- [ ] 타입이 네임스페이스 패턴으로 정의됨\n- [ ] `enabled` 옵션으로 조기 쿼리 실행 방지\n- [ ] ProblemDetail 패턴을 통한 오류 처리\n\n### 5. i18n\n- [ ] 모든 사용자 노출 문자열에 `t()` 함수 사용\n- [ ] 키가 en.json과 ko.json 모두에 추가됨\n- [ ] 키 네이밍이 SECTION.KEY_NAME 규칙을 따름\n\n### 6. 일반적인 함정\n- [ ] React 훅 의존성 누락 없음\n- [ ] 메모리 누수 없음 (useEffect에 클린업)\n- [ ] 새 페이지에 지연 로딩 사용\n- [ ] 하드코딩된 API 경로 없음 (END_POINTS 상수 사용)\n\n결과를 심각도 순으로 정리: Critical > Warning > Suggestion\n\n<!-- File: web-frontend/src/main/v3/.claude/skills/write-test/SKILL.md (Tokens: ~1515 | Category: anthropic-skill) -->\n---\nname: write-test\ndescription: 변경되었거나 테스트가 없는 Pinpoint 프론트엔드 코드에 대한 Jest 테스트를 작성합니다. 훅, 아톰, 유틸리티, 컴포넌트에 테스트가 필요하거나 커버리지를 높여야 할 때 반드시 이 스킬을 사용하세요.\n---\n\n# 테스트 작성\n\n`$ARGUMENTS`의 코드에 대한 Jest 테스트를 작성합니다 (경로가 없으면 최근 변경된 파일 대상).\n\n## 1단계: 테스트가 필요한 파일 탐색\n\n인자가 없는 경우:\n\n```bash\ngit diff upstream/master --name-only\n```\n\n변경된 각 `.ts` / `.tsx` 파일에 대해 해당하는 `.test.ts` / `.test.tsx` 파일이 있는지 확인합니다.\n테스트가 **없는** 파일 목록 — 이것이 우선 타겟입니다.\n\n## 2단계: 코드 분석\n\n각 타겟 파일을 완전히 읽고 파악합니다:\n\n- **수행하는 것** (구현이 아닌 동작)\n- **받는 입력** (props, 인자, 아톰 값, URL 파라미터)\n- **생성하는 출력** (반환 값, 렌더링 출력, 사이드 이펙트, 아톰 업데이트)\n- **의존성** (fetch 호출, 아톰, 다른 훅)\n\n## 3단계: 테스트 작성\n\n`.claude/rules/testing.md`의 프로젝트 테스트 패턴을 따릅니다.\n\n> **규칙: 테스트 이름(`describe` / `test` / `it` 문자열)은 반드시 영어로 작성합니다.**\n\n### 유틸리티 함수 테스트\n\n```typescript\nimport { theUtil } from \"./theUtil\";\n\ndescribe(\"theUtil\", () => {\n  test(\"should return [expected behavior] given [normal input]\", () => {\n    expect(theUtil(normalInput)).toBe(expected);\n  });\n\n  test(\"should handle null/undefined input gracefully\", () => {\n    expect(theUtil(null)).toBe(fallback);\n  });\n\n  test(\"should handle edge cases\", () => {\n    expect(theUtil(edgeCase)).toBe(edgeExpected);\n  });\n});\n```\n\n### Jotai 아톰 테스트\n\n```typescript\nimport { renderHook, act } from \"@testing-library/react\";\nimport { useAtom } from \"jotai\";\nimport { theAtom } from \"./theAtom\";\n\ndescribe(\"theAtom\", () => {\n  test(\"should initialize with default value\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    expect(result.current[0]).toEqual(defaultValue);\n  });\n\n  test(\"should update when setter is called\", () => {\n    const { result } = renderHook(() => useAtom(theAtom));\n    act(() => {\n      result.current[1](newValue);\n    });\n    expect(result.current[0]).toEqual(newValue);\n  });\n});\n```\n\n### API 훅 테스트 (useGetXxx)\n\n```typescript\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { createWrapper } from \"../testUtils\"; // QueryClient wrapper\nimport { useGetXxx } from \"./useGetXxx\";\n\ndescribe(\"useGetXxx\", () => {\n  beforeEach(() => {\n    global.fetch = jest.fn();\n  });\n\n  afterEach(() => {\n    jest.resetAllMocks();\n  });\n\n  test(\"should fetch data with correct endpoint and params\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: true,\n      json: async () => ({ data: mockData }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isSuccess).toBe(true));\n\n    expect(global.fetch).toHaveBeenCalledWith(\n      expect.stringContaining(\"/api/expected-endpoint\"),\n      expect.any(Object),\n    );\n    expect(result.current.data).toEqual(expectedData);\n  });\n\n  test(\"should not fetch when required params are missing\", () => {\n    const { result } = renderHook(() => useGetXxx(null), {\n      wrapper: createWrapper(),\n    });\n    expect(result.current.isFetching).toBe(false);\n    expect(global.fetch).not.toHaveBeenCalled();\n  });\n\n  test(\"should handle API error response\", async () => {\n    (global.fetch as jest.Mock).mockResolvedValueOnce({\n      ok: false,\n      status: 500,\n      json: async () => ({ title: \"Internal Server Error\" }),\n    });\n\n    const { result } = renderHook(() => useGetXxx(params), {\n      wrapper: createWrapper(),\n    });\n    await waitFor(() => expect(result.current.isError).toBe(true));\n  });\n});\n```\n\n### 라우트 로더 테스트\n\n```typescript\nimport { loader } from \"./loader\";\n\ndescribe(\"loader\", () => {\n  test(\"should redirect with correct date format when from/to are invalid\", async () => {\n    const request = new Request(\n      \"http://localhost/page?from=invalid&to=invalid\",\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeInstanceOf(Response); // redirect\n  });\n\n  test(\"should return null for valid date params\", async () => {\n    const now = Date.now();\n    const request = new Request(\n      `http://localhost/page?from=${now - 3600000}&to=${now}`,\n    );\n    const response = await loader({ request, params: {} });\n    expect(response).toBeNull();\n  });\n});\n```\n\n## 4단계: 커버리지 목표\n\n각 파일에 대해 다음을 커버하는 것을 목표로 합니다:\n\n- [ ] 정상 / 해피 패스\n- [ ] 빈 / null / undefined 입력\n- [ ] 오류 상태 (API 실패, 잘못된 데이터)\n- [ ] 경계값 (빈 배열, 최대값)\n- [ ] 훅의 `enabled` 조건 (파라미터 없을 때 페칭 안 함)\n\n## 5단계: 배치 및 등록\n\n- 테스트 파일은 소스와 함께 위치: `myHook.ts` → `myHook.test.ts`\n- 테스트 통과 확인을 위해 실행: `yarn workspace @pinpoint-fe/ui jest path/to/file.test.ts`\n\n작성된 테스트와 통과/실패 여부를 보고합니다.\n\n<!-- File: web-frontend/src/main/v3/packages/datetime-picker/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/package.json)\n\n<!-- File: web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.json)\n\n<!-- File: web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Datetime-picker Skill\n\nPath: `web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/datetime-picker/tsconfig.node.json)\n\n<!-- File: web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# .storybook Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/.storybook/package.json)\n\n<!-- File: web-frontend/src/main/v3/packages/scatter-chart/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Scatter-chart Skill\n\nPath: `web-frontend/src/main/v3/packages/scatter-chart/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/pinpoint-apm/pinpoint/HEAD/web-frontend/src/main/v3/packages/scatter-chart/package.json)\n\n<!-- ... +117 more modular skills available via /api/skills/pinpoint-apm/pinpoint?path={path} -->\n</yakaai_skills>"}