Compare commits

..

26 Commits

Author SHA1 Message Date
이정수 ad8b47d4ec feat: add console output to logger and remove redundant deferReply in autorole command 2026-04-10 10:25:55 +09:00
이정수 1e31f83ff3 fix(i18n): restore missing channelLocked translation key in ko.ts 2026-04-10 09:40:26 +09:00
이정수 bbc4bed551 Merge branch 'origin/main' into feature/invite-role and resolve conflicts 2026-04-10 09:38:39 +09:00
이정수 dcaa14091f chore: update graphify analysis and configuration files 2026-04-09 17:43:01 +09:00
이정수 7beed8f69e docs: update project configuration and add Graphify setup documentation 2026-04-09 17:38:58 +09:00
이정수 e196017bb8 feat: generate graph visualization and cache files for project structure analysis 2026-04-09 17:36:44 +09:00
이정수 aa59e47a62 feat: add graphify tool support with documentation and agent rules 2026-04-09 17:21:54 +09:00
안명현 9afaaf9a2e Merge pull request 'fix(fishing): clear stale sessions for deleted threads' (#10) from myong_dev into main
Reviewed-on: #10
2026-04-09 04:49:53 +00:00
안명현 b9d509a9e8 fix(fishing): clear stale sessions for deleted threads 2026-04-09 13:48:33 +09:00
안명현 d9f3e160aa Merge pull request 'fix(fishing): avoid stale no-session response on session end' (#9) from myong_dev into main
Reviewed-on: #9
2026-04-09 04:14:39 +00:00
안명현 55fc7b46fc fix(fishing): avoid stale no-session response on session end 2026-04-09 13:12:24 +09:00
안명현 53027ac21f Merge pull request 'myong_dev' (#8) from myong_dev into main
Reviewed-on: #8
2026-04-09 03:54:13 +00:00
안명현 7022900eff fix(fishing): use editReply for deferred slash responses 2026-04-09 12:52:29 +09:00
안명현 233615e6d0 Merge branch 'main' into myong_dev 2026-04-09 12:46:45 +09:00
안명현 9f903f676f chore: remove BOM from fishing-related files 2026-04-09 12:39:07 +09:00
안명현 1432e0d090 fix(commands): re-sync global commands when definitions change 2026-04-09 12:25:04 +09:00
안명현 c80bcffb08 Implement fishing progression features 2026-04-09 12:02:54 +09:00
mineseo-kim dbadd936ca feat(logging): wire LOG_DIR through env and align systemd helper
- logger uses config/env for LOG_DIR and LOG_LEVEL (single source of truth)
- Document absolute LOG_DIR for wipe/redeploy (Jenkins) in env and .env.example
- setup-kord-user-log-file.sh reads LOG_DIR from KORD_HOME/.env and syncs
  StandardOutput/StandardError/ExecStartPre mkdir to the same path

Made-with: Cursor
2026-04-09 10:00:58 +09:00
mineseo-kim 5280f1987b chore(scripts): add systemd ExecStartPre for kord log directory
When StandardOutput=append points under ~/kord/logs, systemd opens the
file before ExecStart; a missing directory causes status 209/STDOUT.
Inject mkdir -p via ExecStartPre so restarts survive a deleted logs folder.

Made-with: Cursor
2026-04-09 09:56:46 +09:00
mineseo-kim ca9413e665 fix(db): honor DATABASE_URL schema for pg Pool and PrismaPg
node-postgres ignores Prisma's ?schema= query param, so connections
defaulted to public. Parse the schema from the URL, set search_path on
the pool, and pass schema to PrismaPg (see prisma/prisma#28611).

Made-with: Cursor
2026-04-09 09:45:10 +09:00
mineseo-kim f317be9eab fix(logging): clarify LOG_DIR creation and bootstrap errors
- Wrap mkdir in ensureLogDir with stderr message on failure.

- Trim LOG_DIR; note in .env.example that the directory is created at startup.

Made-with: Cursor
2026-04-09 09:38:59 +09:00
mineseo-kim f2ffdb64a8 feat(logging): switch to log4js with file output and env-driven level
- Replace console logger with log4js dateFile under LOG_DIR (default logs).

- No console appender; daily rotation with 7-day retention (numBackups).

- Add LOG_LEVEL and LOG_DIR to env and .env.example; document in env.ts.

Made-with: Cursor
2026-04-09 09:34:15 +09:00
mineseo-kim f5f597d73d fix(i18n): restore ko locale and remove UTF-8 BOM
- Replace mojibake in ko.ts with proper Korean aligned to en.ts.

- Strip UTF-8 BOM from the 9 other text files (docs, commands, services, tests, en.ts).

Made-with: Cursor
2026-04-09 09:23:14 +09:00
mineseo-kim 586f516d4a Respect DOTENV_CONFIG_PATH for dotenv load path
Matches systemd Environment=DOTENV_CONFIG_PATH=/home/psa/.env so keys are not reported as 0 when only ~/.env exists.

Made-with: Cursor
2026-04-09 09:14:57 +09:00
mineseo-kim 1a4652c185 Fix slash command timeouts: defer before locale DB reads
- interactionCreate: deferReply(ephemeral) immediately for chat commands, then getInteractionLocale.

- All slash handlers use editReply; remove redundant deferReply in audit/fishing/music.

- localeHelper: parallelize user/guild Prisma lookups for getInteractionLocale and getContextLocale.

Note: deferred replies are ephemeral; public-only responses (e.g. music queue) are now user-visible only.
Made-with: Cursor
2026-04-09 09:09:32 +09:00
mineseo-kim a2e755b708 Remove Redis and replace with in-memory caches
- Drop ioredis, docker-compose redis service, and REDIS_* env vars.

- Remove src/cache; use Map-based invite and webhook caching in services.

- Run global command registration and voice boot sync without distributed locks.

- Update README, agent rules, and docs to match the new stack.

Made-with: Cursor
2026-04-09 08:50:53 +09:00
142 changed files with 12061 additions and 590 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

11
.agents/rules/graphify.md Normal file
View File

@ -0,0 +1,11 @@
---
trigger: model_decision
description: Graphify
---
# Graphify (Knowledge Graph)
- This project uses `graphify` to build and maintain a knowledge graph in `graphify-out/`.
- When the user triggers `/graphify`, refer to `SKILL.md` in the project root for execution steps.
- Always check `graphify-out/GRAPH_REPORT.md` before answering architecture or codebase-wide questions.
- If you see `graphify-out/graph.json` missing or outdated, suggest running `/graphify .`.

View File

@ -9,7 +9,7 @@ description: work routine
## 기본 원칙 (Work Rules)
1. **인프라 자율 사용**: 에이전트는 프로젝트에 설정된 Docker 기반 인프라(PostgreSQL, Redis 등)를 사용자의 추가 승인 없이 자유롭게 구동(`docker-compose up -d`) 및 활용할 수 있습니다.
1. **인프라 자율 사용**: 에이전트는 프로젝트에 설정된 Docker 기반 인프라(PostgreSQL 등)를 사용자의 추가 승인 없이 자유롭게 구동(`docker-compose up -d`) 및 활용할 수 있습니다.
2. **협력적 기획, 독립적 실행**: 기능 기획과 설계(Architecture, Schema 등)는 사용자와 함께 논리적인 완결성을 갖출 때까지 충분히 논의합니다. 기획이 "완료 및 승인"된 후에는 후속 구현, 에러 디버깅, 자체 테스트를 추가적인 중간 확인 없이 에이전트가 주도를 가지고 끝마친 뒤 최종 결과를 보고합니다.
## 단계별 작업 루틴

View File

@ -15,3 +15,9 @@
- 유저에게 노출되는 모든 기능(메시지, 임베드, 상태 메시지 등)을 구성할 때는 별도의 요청이 없더라도 **반드시 다국어 지원(i18n) 적용을 검토하고 구현**해야 합니다. (자세한 내용은 `Docs/Rules/i18n_guidelines.md` 참조)
- 단순 문법 검증에 그치지 말고, `yarn dev` 등의 명령어로 봇을 백그라운드에서 직접 구동(Boot)시켜 DB/캐시 커넥트 및 이벤트 리스너 초기화 중 런타임 에러(예: Intents 권한 거부 등)가 발생하지 않는지 스스로 눈으로 확인하고 완벽히 디버깅해야 합니다.
- 봇이 성공적으로 온라인 상태(`Ready`)에 진입한 것을 확인한 뒤에만 사용자에게 작업 완료를 보고합니다.
## Graphify Rules
- 사용자가 `/graphify` 혹은 지식 그래프 관련 질의를 할 경우, 프로젝트 루트의 `SKILL.md` 및 `Docs/Features/Graphify_Setup_Guide.md` 지침을 준수하여 실행합니다.
- 대규모 리팩토링이나 구조 파악이 필요할 때는 `graphify-out/GRAPH_REPORT.md`를 우선적으로 참조하여 의존 관계를 파악합니다.
- 로컬 Ollama 환경이 감지되면 (`http://localhost:11434`), 대량의 데이터 처리에 대해 `--ollama` 옵션 사용을 우선적으로 검토합니다.
- 개발 및 잦은 코드 수정 시 항상 `python3 -m graphify.watch .` 를 백그라운드에 구동시켜 지식 그래프의 최신화를 자동화하는 것을 검토하십시오.

View File

@ -6,5 +6,10 @@ DISCORD_CLIENT_ID=your_client_id_here
# User/pass from docker-compose.yml
DATABASE_URL="postgresql://kord:password@localhost:5432/kord_db?schema=public"
## NOTE
## This project does not use Redis.
# Logging (log4js — file only under LOG_DIR, no console appender)
# Levels: trace, debug, info, warn, error, fatal
LOG_LEVEL=info
# Log directory (kord.log + dated rotations). Relative = from process cwd; use an absolute path on servers
# if the deploy directory is wiped (e.g. Jenkins): LOG_DIR=/var/lib/kord/logs
LOG_DIR=logs

1
.graphify_cached.json Normal file

File diff suppressed because one or more lines are too long

1
.graphify_python Normal file
View File

@ -0,0 +1 @@
/Users/wemadeplay/workspace/graphify/venv/bin/python

View File

@ -16,3 +16,8 @@
- 유저에게 노출되는 모든 기능(메시지, 임베드, 상태 메시지 등)을 구성할 때는 별도의 요청이 없더라도 **반드시 다국어 지원(i18n) 적용을 검토하고 구현**해야 합니다. (자세한 내용은 `Docs/Rules/i18n_guidelines.md` 참조)
- 단순 문법 검증에 그치지 말고, `yarn dev` 등의 명령어로 봇을 백그라운드에서 직접 구동(Boot)시켜 DB/캐시 커넥트 및 이벤트 리스너 초기화 중 런타임 에러(예: Intents 권한 거부 등)가 발생하지 않는지 스스로 눈으로 확인하고 완벽히 디버깅해야 합니다.
- 봇이 성공적으로 온라인 상태(`Ready`)에 진입한 것을 확인한 뒤에만 사용자에게 작업 완료를 보고합니다.
## Graphify Rules
- 사용자가 `/graphify` 혹은 지식 그래프 관련 질의를 할 경우, `SKILL.md`와 `Docs/Features/Graphify_Setup_Guide.md`의 워크플로우를 참조합니다.
- 대규모 리팩토링이나 구조 파악이 필요할 때는 `graphify-out/GRAPH_REPORT.md`를 우선적으로 참조하여 의존 관계를 파악합니다.
- 로컬 모델을 위한 시맨틱 추출이 필요한 경우 `--ollama` 옵션의 활용을 검토하며, 코드 기반 갱신은 `python3 -m graphify.watch .` 를 이용합니다.

5
CLAUDE.md Normal file
View File

@ -0,0 +1,5 @@
# graphify
- **graphify** (`SKILL.md`) - any input to knowledge graph. Trigger: `/graphify`
When the user types `/graphify`, invoke the Skill tool with `skill: "graphify"` before doing anything else.
- 프로젝트의 구조 변경이나 문서 갱신시 실시간 업데이트를 원한다면 `python3 -m graphify.watch .` 실행을 추천하세요.
- Ollama 연동 및 트러블슈팅 설정 등은 `Docs/Features/Graphify_Setup_Guide.md` 문서를 참고하세요.

View File

@ -0,0 +1,62 @@
# Graphify Setup & Guide
이 문서는 프로젝트 내 코드 및 문서의 지식 그래프(Knowledge Graph)를 생성하고 유지관리하기 위한 `graphify` 도구의 설치부터 Ollama 모델 연동, 그리고 실시간 자동 갱신(Watch Mode)을 적용하는 과정을 다른 환경에서도 쉽게 따라 할 수 있도록 정리한 가이드입니다.
## 1. Graphify 설치 및 기본 환경 설정
`graphify`는 코드베이스, 문서 등을 분석하여 구조적/시맨틱(의미론적) 연결망을 만들어주는 지식 그래프 도구입니다.
### Python 인터프리터 구성
- 시스템 전역 파이썬 대신 `venv` 등의 가상 환경에 구성된 파이썬을 이용하는 것을 권장합니다.
- `graphify` 설치 명령어:
```bash
python3 -m pip install graphifyy -q --break-system-packages
```
- 에이전트(Claude 등)가 일관된 파이썬을 사용할 수 있게 프로젝트 루트에 `.graphify_python` 파일을 생성해 파이썬 경로를 저장합니다.
```bash
python3 -c "import sys; open('.graphify_python', 'w').write(sys.executable)"
```
## 2. 로컬 LLM (Ollama) 연동 및 시맨틱 분석
`graphify`는 문서나 코드의 주석 등을 기반으로 추론된 엣지(INFERRED)를 찾을 때 LLM을 사용합니다. 외부 API 대신 로컬 Ollama 모델을 활용하면 토큰 비용을 아낄 수 있습니다.
### Ollama 연결 확인 및 모델 설정
- 로컬의 `11434` 포트에서 Ollama 데몬이 실행 중인지 확인합니다.
```bash
curl -s http://localhost:11434/api/tags > .ollama_tags.json
```
- 로드된 언어 모델(예: `gemma4:e4b-it-q4_K_M`, `llama3` 등)을 `.ollama_models.json` 캐시로 저장합니다.
- 이후 그래프 생성 명령 시 `--ollama` 플래그를 붙여 로컬 연동을 지시합니다.
```bash
/graphify . --ollama --model gemma4:e4b-it-q4_K_M
```
### 트러블슈팅: f-string 및 패키지 오류 (semantic_llm.py)
파이썬 버전 또는 패키지 업데이트 상태에 따라 Ollama API를 호출하는 `semantic_llm.py` 내부 로직에서 몇 가지 오류가 발생할 수 있습니다. (에이전트가 실행 시 자동 수정하거나, 수동으로 수정해야 합니다.)
1. **f-string `{}` 파싱 오류**: `extract_semantic` 프롬프트 내 JSON 예시의 괄호(`{`, `}`)가 f-string의 변수로 인식되어 `ValueError`가 발생할 수 있습니다. JSON 중괄호를 모두 `{{`, `}}`로 더블 이스케이프해야 합니다.
2. **urllib Request 오류**: `urllib.request.Request` 호출 시 `content_type="application/json"` 인자가 거부될 경우, `headers={"Content-Type": "application/json"}` 형태로 교체해야 합니다.
## 3. 지식 그래프 자동 갱신 설정 (Watch Mode)
개발 과정 중 코드나 문서가 빈번하게수정될 때, 그래프를 백그라운드에서 실시간으로 최신화하는 `watch` 모드를 설정할 수 있습니다. (문서 수정은 수동 업데이트 필요, 코드는 자동 재구성)
### 의존성 설치
watch 모드는 `watchdog` 라이브러리를 요구합니다.
```bash
python3 -m pip install watchdog
```
### 상태 감시 실행
터미널을 열어 아래 명령어를 유지합니다:
```bash
python3 -m graphify.watch .
```
- **코드 파일**이 변경된 경우: 백그라운드에서 즉각적으로 AST 추출이 다시 실행되고 `graph.json`과 리포트가 갱신됩니다.
- **문서 파일**이 변경된 경우: LLM 추론이 필요하므로 `need_update` 플래그만 기록합니다. 이후 에이전트나 사용자가 명시적으로 `/graphify . --update` 를 실행하여 최신화합니다.
## 4. 에이전트 설정(IDE Rules) 연계
- **CLAUDE.md 및 .cursorrules**: AI 에이전트가 `graphify` 관련 요청을 받을 경우 `SKILL.md`를 우선 확인하도록 규칙이 지정되어 있습니다.
- 백그라운드에서 감지될 수 있도록 에이전트는 "대규모 리팩토링이나 구조 파악 전 `GRAPH_REPORT.md` 검토", "코드 작성 중 `watchdog`에 의한 자동 갱신 확인" 등을 수행합니다.

View File

@ -39,7 +39,7 @@
|----------|-------------|------|------------------|
| `USER_INPUT` | `E1xxx` | 잘못된 입력값 (범위 초과, 형식 오류 등) | 올바른 입력 예시 안내, 재입력 유도 |
| `PERMISSION` | `E2xxx` | 봇 또는 사용자 권한 부족 | 필요 권한 안내, 서버 관리자 문의 유도 |
| `BOT_INTERNAL` | `E3xxx` | 봇 내부 오류 (DB, Redis, 로직 오류) | 잠시 후 재시도 안내, 지속 시 관리자 문의 |
| `BOT_INTERNAL` | `E3xxx` | 봇 내부 오류 (DB, 로직 오류) | 잠시 후 재시도 안내, 지속 시 관리자 문의 |
| `DISCORD_API` | `E4xxx` | Discord API 오류 (Rate Limit, 서비스 장애 등) | 잠시 후 재시도, Discord 상태 확인 안내 |
### 주요 에러 코드 예시
@ -51,7 +51,7 @@ E2001 봇에 Manage Channels 권한 없음
E2002 사용자에게 관리자 권한 없음
E2003 채널 소유자만 사용 가능
E3001 데이터베이스 연결/쿼리 실패
E3002 캐시(Redis) 연결 실패
E3002 내부 캐시/상태 계층 오류
E4001 Discord API Rate Limit
E4002 Discord API 50013 (Missing Permissions)
E4003 Discord API 일시적 오류

View File

@ -173,11 +173,10 @@ enum EventStatus {
### 중복 방지
- 전송 직후 `remindedOneHour`, `remindedTenMinutes` 업데이트
- 다중 인스턴스 환경에서는 Redis lock 또는 `INSTANCE_ID` 기반 단일 실행 제어 고려
- 다중 인스턴스 환경에서는 DB advisory lock 또는 `INSTANCE_ID` 기반 단일 실행 제어 고려
> [!NOTE]
> 현재 프로젝트는 글로벌 커맨드 동기화 시 Redis lock을 사용하므로,
> 이벤트 리마인더도 같은 방식으로 확장하기 좋습니다.
> 글로벌 커맨드 등록 등은 애플리케이션 레벨에서 처리하며, 이벤트 리마인더도 유사한 단일 실행 패턴으로 확장할 수 있습니다.
---

View File

@ -1,4 +1,4 @@
# 낚시 미니게임 구현 기획안
# 낚시 미니게임 구현 기획안
이 문서는 Kord의 `낚시(Fishing)` 미니게임 시스템에 대한 설계 방향과 구현 범위를 정리한 기획서입니다.
@ -182,7 +182,9 @@
후속 버전에서는 아래 요소를 추가할 수 있습니다.
- 물고기 희귀도
- 물고기 크기(cm) 시스템
- 개별 물고기 인벤토리
- 물고기 도감 / 컬렉션
- 미끼 종류
- 낚싯대 및 업그레이드
- 물고기 판매 시스템
@ -253,6 +255,41 @@ Phase 1에서는 직접 `gold`를 주는 방식이 가장 단순하고 호환성
이 정도면 초반 통계 추적에 충분하고, 너무 이르게 인벤토리를 과설계하지 않을 수 있습니다.
도감/크기 확장 시에는 아래 모델을 추가합니다.
- `FishingCollectionEntry`
- `userId`
- `guildId`
- `fishId`
- `catchCount`
- `bestRarity`
- `bestSizeCm`
- `lastCaughtAt`
- `createdAt`
- `updatedAt`
이 모델은 유저가 어떤 물고기를 몇 번 잡았는지, 최고 레어도와 최고 크기가 무엇인지 추적하는 데 사용합니다.
### 물고기 크기 시스템
- 낚시 성공 시 물고기마다 `cm` 단위의 크기를 부여합니다.
- 기본 크기 범위는 물고기별 데이터에서 관리합니다.
- 최종 크기는 `물고기 기본 크기 범위 × 레어도 보정치`로 계산합니다.
- 즉, 같은 물고기라도 레어도가 높을수록 더 큰 개체가 등장할 수 있습니다.
- 성공 결과 메시지에는 잡은 물고기의 크기를 함께 표시합니다.
- 도감에는 해당 물고기의 최고 크기를 기록합니다.
### 도감 (Dex / Collection)
- `/fishing dex` 명령을 통해 개인 도감을 조회할 수 있어야 합니다.
- 도감에는 아래 정보를 보여줍니다.
- 잡아본 물고기 목록
- 각 물고기의 포획 횟수
- 최고 레어도
- 최고 크기(cm)
- 마지막 포획 시각
- 아직 잡지 못한 물고기는 후속 버전에서 실루엣/잠금 상태로 표시할 수 있습니다.
### 세션 모델
낚시 플레이 자체는 즉각적인 반응을 위해 메모리 세션 기반이 적합합니다.
@ -318,17 +355,23 @@ Phase 1에서는 직접 `gold`를 주는 방식이 가장 단순하고 호환성
### Phase 2
- `/fishing status` 추가
- `/fishing ranking` 추가
- 사용자별 낚시 통계 추가
- 낚시 프로필 영속화
- 물고기 이동 패턴 개선
- 보상 밸런스 조정
- `/fishing dex` 추가
- 물고기 크기(cm) 시스템 추가
- 도감용 포획 기록 저장
- 길드 내 최고 크기 기준 Top 10 랭킹 표시
### Phase 3
- 희귀도 체계 추가
- 인벤토리 / 도감 추가
- 인벤토리 / 도감 고도화
- 미끼 / 낚싯대 보정치 추가
- 리더보드 지원
- 미포획 물고기 잠금/실루엣 UI 추가
## 검증 / 테스트

View File

@ -71,7 +71,7 @@
- **State Management (상태 관리)**:
- 마법사는 ephemeral 메시지로 띄워지며, 세션 식별은 `customId` 릴레이 방식을 권장합니다.
- 예시: `setup_action_next_2` (현재 Step 2, 다음으로 이동) 등 Stateless하게 관리하거나,
- 사용자/서버별 임시 Map/Redis`SetupSession` (진행 단계 등) 보관. (구현 편의상 `customId` payload에 스텝 인덱스를 담는 Stateless 방식 채택)
- 사용자/서버별 임시 Map`SetupSession` (진행 단계 등) 보관. (구현 편의상 `customId` payload에 스텝 인덱스를 담는 Stateless 방식 채택)
- **i18n 통합**:
- 버튼 레이블 및 Embed 내용은 모두 `t()` 함수를 거쳐야 합니다.
- Step 1에서 언어가 변경되면, 즉시 그 언어 기준의 `t()`를 이용해 현재 뷰(View)를 갱신합니다.

View File

@ -13,7 +13,7 @@
#### 절대 금지 대상 예시:
- 디스코드 봇 토큰 (Discord Bot Tokens)
- 데이터베이스 비밀번호 및 접속 주소 (e.g. `postgresql://user:password@host/db`)
- Redis 비밀번호, API 인증 키(Keys), 비밀 암호 해시, 사내용 중요 자격증명 리스트
- 외부 서비스 비밀번호, API 인증 키(Keys), 비밀 암호 해시, 사내용 중요 자격증명 리스트
#### 올바른 해결 방법
1. **환경 변수 파일 (`.env`) 사용**:

View File

@ -7,7 +7,7 @@
### 1. 기술 스택 확정 및 초기화
- **언어 및 런타임**: Node.js, TypeScript
- **프레임워크**: discord.js (v14+)
- **데이터베이스**: Prisma (PostgreSQL) + Redis (캐싱 및 동기화)
- **데이터베이스**: Prisma (PostgreSQL)
- **빌드 도구**: ts-node, tsx, tsc
### 2. 프로젝트 기본 구조 설계

View File

@ -38,6 +38,6 @@
- **퇴장 시 채널 미삭제 및 유령 방 버그**:
- *문제*: 채널 내에 음악봇 등 봇만 남았을 때 삭제 조건이 작동하지 않고, 권한 문제로 삭제가 실패했을 때 DB 무결성이 깨지는 버그.
- *해결*: 휴먼 카운트(`humanCount`) 도입 및 삭제 롤백 검증 처리. 자세한 사항은 [handleLeave_ghost_channel.md](../Troubleshooting/handleLeave_ghost_channel.md) 참조.
- **멀티 인스턴스 대응 및 봇 재부팅 복구 (Boot Recovery)**:
- *사유*: 봇 재시작, 크래시, 혹은 다중 노드(Multi-Instance) 환경에서 DB와 디스코드 실제 채널 상태가 어긋나게 될 경우를 방지.
- *해결*: `ioredis` 분산 락(Distributed Lock)과 결합된 `VoiceService.syncChannels` 메서드를 구현하여, 부팅 시 딱 하나의 인스턴스만 DB를 훑으며 삭제되어야 할 유령 방들을 크로스체크 및 안전하게 청소(Garbage Collection)하도록 반영.
- **봇 재부팅 복구 (Boot Recovery)**:
- *사유*: 봇 재시작·크래시 등으로 DB와 디스코드 실제 채널 상태가 어긋나게 될 경우를 방지.
- *해결*: `VoiceService.syncChannels`로 부팅 시 DB를 기준으로 유령 방을 크로스체크 및 청소(Garbage Collection)하도록 반영. (다중 인스턴스 동시 실행 시 동일 작업이 겹칠 수 있으나 작업은 멱등에 가깝게 설계됨.)

View File

@ -1,4 +1,4 @@
# 2026-03-31 낚시 미니게임 Phase 1 구현
# 2026-03-31 낚시 미니게임 Phase 1 구현
## 개요

View File

@ -0,0 +1,29 @@
# 2026-04-07 Fishing Dex and Size Implementation
## 요약
낚시 미니게임에 물고기 크기(`cm`) 시스템과 도감(`/fishing dex`) 기능을 추가했다.
## 구현 내용
- 물고기별 기본 크기 범위를 `fish_catalog.json`에 추가
- 레어도별 크기 보정치를 `fish_rarities.json`에 추가
- 낚시 성공 시 최종 물고기 크기를 계산하여 결과 메시지에 표시
- `FishingCollectionEntry` 모델 추가
- 물고기별 포획 수
- 최고 레어도
- 최고 크기
- 마지막 포획 시각
- `/fishing dex` 서브커맨드 추가
- 유저별 물고기 도감 조회
- 포획 수, 최고 레어도, 최고 크기 표시
- 성공 결과 메시지에 크기 필드 추가
## 검증
- `yarn prisma generate`
- `yarn build`
- `yarn test --runInBand`
- `yarn prisma migrate deploy`
모든 단계가 정상 통과했다.

View File

@ -0,0 +1,39 @@
# 2026-04-07 Fishing Mini-Game Phase 2 Implementation
## 요약
낚시 미니게임의 Phase 2로 `FishingProfile` 기반 통계 영속화와 `/fishing status` 조회 기능을 추가했다.
## 구현 내용
- `FishingProfile` Prisma 모델 추가
- `userId`, `guildId` 복합 키
- 총 시도 수, 성공/실패 수
- 누적 획득 골드
- 최고 보상
- 레어도별 포획 수
- 마지막 낚시 시각
- `FishingService`에 프로필 저장 로직 추가
- 성공 시 보상과 레어도별 포획 수 누적
- 실패 시 실패 횟수 누적
- 모든 세션 종료 시 총 시도 수와 마지막 낚시 시각 갱신
- `/fishing status` 서브커맨드 추가
- 본인 또는 지정 유저의 낚시 통계 조회
- 총 시도, 성공률, 누적 골드, 최고 보상, 마지막 낚시 시각 표시
- 레어도별 포획 수를 별도 필드로 표시
- 낚시 i18n 문자열 추가
- 통계 Embed 제목/필드명/빈 기록 메시지
## 검증
- `yarn prisma generate`
- `yarn prisma migrate deploy`
- `yarn build`
- `yarn test --runInBand`
모든 단계가 정상 통과했다.
## 비고
- `FishingProfile`은 현재 낚시 진행 통계 전용 모델이다.
- 이후 랭킹, 도감, 업적, 장비 시스템은 이 프로필을 기반으로 확장할 수 있다.

View File

@ -0,0 +1,26 @@
# 2026-04-07: 낚시 크기 랭킹 구현
## 개요
낚시 시스템에 `/fishing ranking` 명령을 추가해, 서버 내 최고 물고기 크기 기록 상위 10개를 조회할 수 있도록 구현했습니다.
랭킹은 `FishingCollectionEntry`에 저장된 각 유저의 물고기별 최고 크기 기록을 기준으로 정렬하며, 각 항목에는 아래 정보가 포함됩니다.
- 유저
- 물고기 종류
- 최고 레어도
- 최고 크기(cm)
## 구현 내용
- `/fishing ranking` 서브커맨드 추가
- 길드 기준 최고 크기 기록 Top 10 조회 서비스 추가
- 같은 크기일 경우 최고 레어도, 포획 횟수 순으로 정렬
- 랭킹이 비어 있을 때의 안내 메시지 추가
- 낚시 기획서에 랭킹 항목 반영
## 사용자 확인 포인트
- `/fishing ranking` 실행 시 서버 기준 상위 10개 기록이 표시되는지
- 각 항목에 유저, 물고기, 레어도, 크기가 함께 보이는지
- 기록이 없는 서버에서는 빈 상태 안내가 표시되는지

View File

@ -15,6 +15,7 @@
## 기능 명세 (Features)
- [임시 음성 채널 자동화 (Temp Voice Channels)](Features/temp_voice_channels.md)
- [Graphify 설정 및 연동 가이드 (Graphify Setup Guide)](Features/Graphify_Setup_Guide.md)
## 기획서 (Plans)
@ -63,3 +64,6 @@
- [2026-03-30: 미니게임 시스템 및 재련 게임 구현 (Mini-Game System & Refinement Implementation)](WorkDone/2026-03-30_RefinementImplementation.md)
- [2026-03-31: 낚시 미니게임 Phase 1 구현 (Fishing Mini-Game Phase 1 Implementation)](WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md)
- [2026-03-31: 낚시 미니게임 Phase 1 완료 (Fishing Mini-Game Phase 1 Completion)](WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Completion.md)
- [2026-04-07: 낚시 미니게임 Phase 2 구현 (Fishing Mini-Game Phase 2 Implementation)](WorkDone/2026-04-07_Fishing_MiniGame_Phase2_Implementation.md)
- [2026-04-07: 낚시 도감 및 크기 시스템 구현 (Fishing Dex and Size Implementation)](WorkDone/2026-04-07_Fishing_Dex_And_Size_Implementation.md)
- [2026-04-07: 낚시 크기 랭킹 구현 (Fishing Size Ranking Implementation)](WorkDone/2026-04-07_Fishing_Size_Ranking_Implementation.md)

View File

@ -58,7 +58,8 @@ Kord는 Discord 서버 관리를 돕는 강력하고 유연한 다기능 봇입
1. **빌드**: `yarn build`
2. **실행**: `yarn start`
3. **Docker**: `docker-compose up -d`를 통해 전체 스택(Bot, DB)을 실행할 수 있습니다.
3. **Docker**: `docker-compose up -d`를 통해 PostgreSQL 등 로컬 인프라를 실행할 수 있습니다.
## 5. 기능 목록 (Feature List)

855
SKILL.md Normal file
View File

@ -0,0 +1,855 @@
---
name: graphify
description: any input (code, docs, papers, images) → knowledge graph → clustered communities → HTML + JSON + audit report
trigger: /graphify
---
# /graphify
Turn any folder of files into a navigable knowledge graph with community detection, an honest audit trail, and three outputs: interactive HTML, GraphRAG-ready JSON, and a plain-language GRAPH_REPORT.md.
## Usage
```
/graphify # full pipeline on current directory → Obsidian vault
/graphify <path> # full pipeline on specific path
/graphify <path> --mode deep # thorough extraction, richer INFERRED edges
/graphify <path> --update # incremental - re-extract only new/changed files
/graphify <path> --cluster-only # rerun clustering on existing graph
/graphify <path> --no-viz # skip visualization, just report + JSON
/graphify <path> --html # (HTML is generated by default - this flag is a no-op)
/graphify <path> --svg # also export graph.svg (embeds in Notion, GitHub)
/graphify <path> --graphml # export graph.graphml (Gephi, yEd)
/graphify <path> --neo4j # generate graphify-out/cypher.txt for Neo4j
/graphify <path> --neo4j-push bolt://localhost:7687 # push directly to Neo4j
/graphify <path> --mcp # start MCP stdio server for agent access
/graphify <path> --watch # watch folder, auto-rebuild on code changes (no LLM needed)
/graphify <path> --wiki # build agent-crawlable wiki (index.md + one article per community)
/graphify <path> --obsidian --obsidian-dir ~/vaults/my-project # write vault to custom path (e.g. existing vault)
/graphify add <url> # fetch URL, save to ./raw, update graph
/graphify add <url> --author "Name" # tag who wrote it
/graphify add <url> --contributor "Name" # tag who added it to the corpus
/graphify query "<question>" # BFS traversal - broad context
/graphify query "<question>" --dfs # DFS - trace a specific path
/graphify query "<question>" --budget 1500 # cap answer at N tokens
/graphify path "AuthModule" "Database" # shortest path between two concepts
/graphify explain "SwinTransformer" # plain-language explanation of a node
/graphify <path> --ollama # use local Ollama for semantic extraction
/graphify <path> --ollama --model gemma4 # use specific Ollama model (default: llama3)
```
## What graphify is for
graphify is built around Andrej Karpathy's /raw folder workflow: drop anything into a folder - papers, tweets, screenshots, code, notes - and get a structured knowledge graph that shows you what you didn't know was connected.
Three things it does that Claude alone cannot:
1. **Persistent graph** - relationships are stored in `graphify-out/graph.json` and survive across sessions. Ask questions weeks later without re-reading everything.
2. **Honest audit trail** - every edge is tagged EXTRACTED, INFERRED, or AMBIGUOUS. You know what was found vs invented.
3. **Cross-document surprise** - community detection finds connections between concepts in different files that you would never think to ask about directly.
Use it for:
- A codebase you're new to (understand architecture before touching anything)
- A reading list (papers + tweets + notes → one navigable graph)
- A research corpus (citation graph + concept graph in one)
- Your personal /raw folder (drop everything in, let it grow, query it)
## What You Must Do When Invoked
If no path was given, use `.` (current directory). Do not ask the user for a path.
Follow these steps in order. Do not skip steps.
### Step 1 - Ensure graphify is installed
```bash
# Detect the correct Python interpreter (handles pipx, venv, system installs)
GRAPHIFY_BIN=$(which graphify 2>/dev/null)
if [ -n "$GRAPHIFY_BIN" ]; then
PYTHON=$(head -1 "$GRAPHIFY_BIN" | tr -d '#!')
else
PYTHON="python3"
fi
$PYTHON -c "import graphify" 2>/dev/null || pip install graphifyy -q --break-system-packages 2>&1 | tail -3
# Write interpreter path for all subsequent steps
$PYTHON -c "import sys; open('.graphify_python', 'w').write(sys.executable)"
# Check Ollama connectivity
OLLAMA_UP=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:11434/api/tags 2>/dev/null)
if [ "$OLLAMA_UP" = "200" ]; then
echo "Ollama: CONNECTED"
$PYTHON -c "import json; print(json.dumps([m['name'] for m in json.loads(open('.ollama_tags.json').read()).get('models', [])]))" > .ollama_models.json 2>/dev/null || (curl -s http://localhost:11434/api/tags > .ollama_tags.json && $PYTHON -c "import json; print(json.dumps([m['name'] for m in json.loads(open('.ollama_tags.json').read()).get('models', [])]))" > .ollama_models.json && rm .ollama_tags.json)
else
echo "Ollama: DISCONNECTED"
rm -f .ollama_models.json
fi
```
If the import succeeds, print nothing and move straight to Step 2.
**In every subsequent bash block, replace `python3` with `$(cat .graphify_python)` to use the correct interpreter.**
### Step 2 - Detect files
```bash
$(cat .graphify_python) -c "
import json
from graphify.detect import detect
from pathlib import Path
result = detect(Path('INPUT_PATH'))
print(json.dumps(result))
" > .graphify_detect.json
```
Replace INPUT_PATH with the actual path the user provided. Do NOT cat or print the JSON - read it silently and present a clean summary instead:
```
Corpus: X files · ~Y words
code: N files (.py .ts .go ...)
docs: N files (.md .txt ...)
papers: N files (.pdf ...)
images: N files
```
Then act on it:
- If `total_files` is 0: stop with "No supported files found in [path]."
- If `skipped_sensitive` is non-empty: mention file count skipped, not the file names.
- If `total_words` > 2,000,000 OR `total_files` > 200: show the warning and the top 5 subdirectories by file count, then ask which subfolder to run on. Wait for the user's answer before proceeding.
- Otherwise: proceed directly to Step 3 - no need to ask anything.
### Step 3 - Extract entities and relationships
**Before starting:** note whether `--mode deep` was given. You must pass `DEEP_MODE=true` to every subagent in Step B2 if it was. Track this from the original invocation - do not lose it.
This step has two parts: **structural extraction** (deterministic, free) and **semantic extraction** (Claude, costs tokens).
**Run Part A (AST) and Part B (semantic) in parallel. Dispatch all semantic subagents AND start AST extraction in the same message. Both can run simultaneously since they operate on different file types. Merge results in Part C as before.**
Note: Parallelizing AST + semantic saves 5-15s on large corpora. AST is deterministic and fast; start it while subagents are processing docs/papers.
#### Part A - Structural extraction for code files
For any code files detected, run AST extraction in parallel with Part B subagents:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.extract import collect_files, extract
from pathlib import Path
import json
code_files = []
detect = json.loads(Path('.graphify_detect.json').read_text())
for f in detect.get('files', {}).get('code', []):
code_files.extend(collect_files(Path(f)) if Path(f).is_dir() else [Path(f)])
if code_files:
result = extract(code_files)
Path('.graphify_ast.json').write_text(json.dumps(result, indent=2))
print(f'AST: {len(result[\"nodes\"])} nodes, {len(result[\"edges\"])} edges')
else:
Path('.graphify_ast.json').write_text(json.dumps({'nodes':[],'edges':[],'input_tokens':0,'output_tokens':0}))
print('No code files - skipping AST extraction')
"
```
#### Part B - Semantic extraction (parallel subagents or local LLM)
**Fast path:** If detection found zero docs, papers, and images (code-only corpus), skip Part B entirely and go straight to Part C. AST handles code - there is nothing for semantic subagents to do.
**Ollama Choice:** If Ollama is CONNECTED (check `.ollama_models.json`) AND `--ollama` was given:
Run semantic extraction locally for each chunk of files.
```bash
$(cat .graphify_python) -c "
import json
from graphify.semantic_llm import extract_semantic
from pathlib import Path
uncached = Path('.graphify_uncached.txt').read_text().splitlines()
# Split into chunks of 15 files (local models are slower)
chunks = [uncached[i:i + 15] for i in range(0, len(uncached), 15)]
all_results = {'nodes': [], 'edges': [], 'hyperedges': [], 'input_tokens': 0, 'output_tokens': 0}
model = 'MODEL_NAME' # Use --model value or 'llama3' or first found in .ollama_models.json
deep = DEEP_MODE_VAR # True if --mode deep
for i, chunk in enumerate(chunks):
print(f'Local Extraction: chunk {i+1}/{len(chunks)} ({len(chunk)} files)...')
res = extract_semantic(chunk, model=model, deep_mode=deep)
all_results['nodes'].extend(res.get('nodes', []))
all_results['edges'].extend(res.get('edges', []))
all_results['hyperedges'].extend(res.get('hyperedges', []))
Path('.graphify_semantic_new.json').write_text(json.dumps(all_results, indent=2))
"
```
**Otherwise (Cloud Model - DEFAULT):**
**MANDATORY: You MUST use the Agent tool here. Reading files yourself one-by-one is forbidden - it is 5-10x slower. If you do not use the Agent tool you are doing this wrong.**
Before dispatching subagents, print a timing estimate:
- Load `total_words` and file counts from `.graphify_detect.json`
- Estimate agents needed: `ceil(uncached_non_code_files / 22)` (chunk size is 20-25)
- Estimate time: ~45s per agent batch (they run in parallel, so total ≈ 45s × ceil(agents/parallel_limit))
- Print: "Semantic extraction: ~N files → X agents, estimated ~Ys"
**Step B0 - Check extraction cache first**
Before dispatching any subagents, check which files already have cached extraction results:
```bash
$(cat .graphify_python) -c "
import json
from graphify.cache import check_semantic_cache
from pathlib import Path
detect = json.loads(Path('.graphify_detect.json').read_text())
all_files = [f for files in detect['files'].values() for f in files]
cached_nodes, cached_edges, cached_hyperedges, uncached = check_semantic_cache(all_files)
if cached_nodes or cached_edges or cached_hyperedges:
Path('.graphify_cached.json').write_text(json.dumps({'nodes': cached_nodes, 'edges': cached_edges, 'hyperedges': cached_hyperedges}))
Path('.graphify_uncached.txt').write_text('\n'.join(uncached))
print(f'Cache: {len(all_files)-len(uncached)} files hit, {len(uncached)} files need extraction')
"
```
Only dispatch subagents for files listed in `.graphify_uncached.txt`. If all files are cached, skip to Part C directly.
**Step B1 - Split into chunks**
Load files from `.graphify_uncached.txt`. Split into chunks of 20-25 files each. Each image gets its own chunk (vision needs separate context).
**Step B2 - Dispatch ALL subagents in a single message**
Call the Agent tool multiple times IN THE SAME RESPONSE - one call per chunk. This is the only way they run in parallel. If you make one Agent call, wait, then make another, you are doing it sequentially and defeating the purpose.
Concrete example for 3 chunks:
```
[Agent tool call 1: files 1-15]
[Agent tool call 2: files 16-30]
[Agent tool call 3: files 31-45]
```
All three in one message. Not three separate messages.
Each subagent receives this exact prompt (substitute FILE_LIST, CHUNK_NUM, TOTAL_CHUNKS, and DEEP_MODE):
```
You are a graphify extraction subagent. Read the files listed and extract a knowledge graph fragment.
Output ONLY valid JSON matching the schema below - no explanation, no markdown fences, no preamble.
Files (chunk CHUNK_NUM of TOTAL_CHUNKS):
FILE_LIST
Rules:
- EXTRACTED: relationship explicit in source (import, call, citation, "see §3.2")
- INFERRED: reasonable inference (shared data structure, implied dependency)
- AMBIGUOUS: uncertain - flag for review, do not omit
Code files: focus on semantic edges AST cannot find (call relationships, shared data, arch patterns).
Do not re-extract imports - AST already has those.
Doc/paper files: extract named concepts, entities, citations. Also extract rationale — sections that explain WHY a decision was made, trade-offs chosen, or design intent. These become nodes with `rationale_for` edges pointing to the concept they explain.
Image files: use vision to understand what the image IS - do not just OCR.
UI screenshot: layout patterns, design decisions, key elements, purpose.
Chart: metric, trend/insight, data source.
Tweet/post: claim as node, author, concepts mentioned.
Diagram: components and connections.
Research figure: what it demonstrates, method, result.
Handwritten/whiteboard: ideas and arrows, mark uncertain readings AMBIGUOUS.
DEEP_MODE (if --mode deep was given): be aggressive with INFERRED edges - indirect deps,
shared assumptions, latent couplings. Mark uncertain ones AMBIGUOUS instead of omitting.
Semantic similarity: if two concepts in this chunk solve the same problem or represent the same idea without any structural link (no import, no call, no citation), add a `semantically_similar_to` edge marked INFERRED with a confidence_score reflecting how similar they are (0.6-0.95). Examples:
- Two functions that both validate user input but never call each other
- A class in code and a concept in a paper that describe the same algorithm
- Two error types that handle the same failure mode differently
Only add these when the similarity is genuinely non-obvious and cross-cutting. Do not add them for trivially similar things.
Hyperedges: if 3 or more nodes clearly participate together in a shared concept, flow, or pattern that is not captured by pairwise edges alone, add a hyperedge to a top-level `hyperedges` array. Examples:
- All classes that implement a common protocol or interface
- All functions in an authentication flow (even if they don't all call each other)
- All concepts from a paper section that form one coherent idea
Use sparingly — only when the group relationship adds information beyond the pairwise edges. Maximum 3 hyperedges per chunk.
If a file has YAML frontmatter (--- ... ---), copy source_url, captured_at, author,
contributor onto every node from that file.
confidence_score is REQUIRED on every edge - never omit it, never use 0.5 as a default:
- EXTRACTED edges: confidence_score = 1.0 always
- INFERRED edges: reason about each edge individually.
Direct structural evidence (shared data structure, clear dependency): 0.8-0.9.
Reasonable inference with some uncertainty: 0.6-0.7.
Weak or speculative: 0.4-0.5. Most edges should be 0.6-0.9, not 0.5.
- AMBIGUOUS edges: 0.1-0.3
Output exactly this JSON (no other text):
{"nodes":[{"id":"filestem_entityname","label":"Human Readable Name","file_type":"code|document|paper|image","source_file":"relative/path","source_location":null,"source_url":null,"captured_at":null,"author":null,"contributor":null}],"edges":[{"source":"node_id","target":"node_id","relation":"calls|implements|references|cites|conceptually_related_to|shares_data_with|semantically_similar_to|rationale_for","confidence":"EXTRACTED|INFERRED|AMBIGUOUS","confidence_score":1.0,"source_file":"relative/path","source_location":null,"weight":1.0}],"hyperedges":[{"id":"snake_case_id","label":"Human Readable Label","nodes":["node_id1","node_id2","node_id3"],"relation":"participate_in|implement|form","confidence":"EXTRACTED|INFERRED","confidence_score":0.75,"source_file":"relative/path"}],"input_tokens":0,"output_tokens":0}
```
**Step B3 - Collect, cache, and merge**
Wait for all subagents. For each result:
- If a subagent returned valid JSON with `nodes` and `edges`, include it and save each file's nodes/edges to the cache
- If a subagent failed or returned invalid JSON, print a warning and skip that chunk - do not abort
If more than half the chunks failed, stop and tell the user.
Save new results to cache:
```bash
$(cat .graphify_python) -c "
import json
from graphify.cache import save_semantic_cache
from pathlib import Path
new = json.loads(Path('.graphify_semantic_new.json').read_text()) if Path('.graphify_semantic_new.json').exists() else {'nodes':[],'edges':[],'hyperedges':[]}
saved = save_semantic_cache(new.get('nodes', []), new.get('edges', []), new.get('hyperedges', []))
print(f'Cached {saved} files')
"
```
Merge cached + new results into `.graphify_semantic.json`:
```bash
$(cat .graphify_python) -c "
import json
from pathlib import Path
cached = json.loads(Path('.graphify_cached.json').read_text()) if Path('.graphify_cached.json').exists() else {'nodes':[],'edges':[],'hyperedges':[]}
new = json.loads(Path('.graphify_semantic_new.json').read_text()) if Path('.graphify_semantic_new.json').exists() else {'nodes':[],'edges':[],'hyperedges':[]}
all_nodes = cached['nodes'] + new.get('nodes', [])
all_edges = cached['edges'] + new.get('edges', [])
all_hyperedges = cached.get('hyperedges', []) + new.get('hyperedges', [])
seen = set()
deduped = []
for n in all_nodes:
if n['id'] not in seen:
seen.add(n['id'])
deduped.append(n)
merged = {
'nodes': deduped,
'edges': all_edges,
'hyperedges': all_hyperedges,
'input_tokens': new.get('input_tokens', 0),
'output_tokens': new.get('output_tokens', 0),
}
Path('.graphify_semantic.json').write_text(json.dumps(merged, indent=2))
print(f'Extraction complete - {len(deduped)} nodes, {len(all_edges)} edges ({len(cached[\"nodes\"])} from cache, {len(new.get(\"nodes\",[]))} new)')
"
```
Clean up temp files: `rm -f .graphify_cached.json .graphify_uncached.txt .graphify_semantic_new.json`
#### Part C - Merge AST + semantic into final extraction
```bash
$(cat .graphify_python) -c "
import sys, json
from pathlib import Path
ast = json.loads(Path('.graphify_ast.json').read_text())
sem = json.loads(Path('.graphify_semantic.json').read_text())
# Merge: AST nodes first, semantic nodes deduplicated by id
seen = {n['id'] for n in ast['nodes']}
merged_nodes = list(ast['nodes'])
for n in sem['nodes']:
if n['id'] not in seen:
merged_nodes.append(n)
seen.add(n['id'])
merged_edges = ast['edges'] + sem['edges']
merged_hyperedges = sem.get('hyperedges', [])
merged = {
'nodes': merged_nodes,
'edges': merged_edges,
'hyperedges': merged_hyperedges,
'input_tokens': sem.get('input_tokens', 0),
'output_tokens': sem.get('output_tokens', 0),
}
Path('.graphify_extract.json').write_text(json.dumps(merged, indent=2))
total = len(merged_nodes)
edges = len(merged_edges)
print(f'Merged: {total} nodes, {edges} edges ({len(ast[\"nodes\"])} AST + {len(sem[\"nodes\"])} semantic)')
"
```
### Step 4 - Build graph, cluster, analyze, generate outputs
```bash
mkdir -p graphify-out
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.cluster import cluster, score_all
from graphify.analyze import god_nodes, surprising_connections, suggest_questions
from graphify.report import generate
from graphify.export import to_json
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
detection = json.loads(Path('.graphify_detect.json').read_text())
G = build_from_json(extraction)
communities = cluster(G)
cohesion = score_all(G, communities)
tokens = {'input': extraction.get('input_tokens', 0), 'output': extraction.get('output_tokens', 0)}
gods = god_nodes(G)
surprises = surprising_connections(G, communities)
labels = {cid: 'Community ' + str(cid) for cid in communities}
# Placeholder questions - regenerated with real labels in Step 5
questions = suggest_questions(G, communities, labels)
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, 'INPUT_PATH', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report)
to_json(G, communities, 'graphify-out/graph.json')
analysis = {
'communities': {str(k): v for k, v in communities.items()},
'cohesion': {str(k): v for k, v in cohesion.items()},
'gods': gods,
'surprises': surprises,
'questions': questions,
}
Path('.graphify_analysis.json').write_text(json.dumps(analysis, indent=2))
if G.number_of_nodes() == 0:
print('ERROR: Graph is empty - extraction produced no nodes.')
print('Possible causes: all files were skipped, binary-only corpus, or extraction failed.')
raise SystemExit(1)
print(f'Graph: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges, {len(communities)} communities')
"
```
If this step prints `ERROR: Graph is empty`, stop and tell the user what happened - do not proceed to labeling or visualization.
Replace INPUT_PATH with the actual path.
### Step 5 - Label communities
Read `.graphify_analysis.json`. For each community key, look at its node labels and write a 2-5 word plain-language name (e.g. "Attention Mechanism", "Training Pipeline", "Data Loading").
Then regenerate the report and save the labels for the visualizer:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.cluster import score_all
from graphify.analyze import god_nodes, surprising_connections, suggest_questions
from graphify.report import generate
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
detection = json.loads(Path('.graphify_detect.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
cohesion = {int(k): v for k, v in analysis['cohesion'].items()}
tokens = {'input': extraction.get('input_tokens', 0), 'output': extraction.get('output_tokens', 0)}
# LABELS - replace these with the names you chose above
labels = LABELS_DICT
# Regenerate questions with real community labels (labels affect question phrasing)
questions = suggest_questions(G, communities, labels)
report = generate(G, communities, cohesion, labels, analysis['gods'], analysis['surprises'], detection, tokens, 'INPUT_PATH', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report)
Path('.graphify_labels.json').write_text(json.dumps({str(k): v for k, v in labels.items()}))
print('Report updated with community labels')
"
```
Replace `LABELS_DICT` with the actual dict you constructed (e.g. `{0: "Attention Mechanism", 1: "Training Pipeline"}`).
Replace INPUT_PATH with the actual path.
### Step 6 - Generate Obsidian vault (opt-in) + HTML
**Generate HTML always** (unless `--no-viz`). **Obsidian vault only if `--obsidian` was explicitly given** — skip it otherwise, it generates one file per node.
If `--obsidian` was given:
- If `--obsidian-dir <path>` was also given, use that path as the vault directory. Otherwise default to `graphify-out/obsidian`.
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.export import to_obsidian, to_canvas
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
labels_raw = json.loads(Path('.graphify_labels.json').read_text()) if Path('.graphify_labels.json').exists() else {}
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
cohesion = {int(k): v for k, v in analysis['cohesion'].items()}
labels = {int(k): v for k, v in labels_raw.items()}
obsidian_dir = 'OBSIDIAN_DIR' # replace with --obsidian-dir value, or 'graphify-out/obsidian' if not given
n = to_obsidian(G, communities, obsidian_dir, community_labels=labels or None, cohesion=cohesion)
print(f'Obsidian vault: {n} notes in {obsidian_dir}/')
to_canvas(G, communities, f'{obsidian_dir}/graph.canvas', community_labels=labels or None)
print(f'Canvas: {obsidian_dir}/graph.canvas - open in Obsidian for structured community layout')
print()
print(f'Open {obsidian_dir}/ as a vault in Obsidian.')
print(' Graph view - nodes colored by community (set automatically)')
print(' graph.canvas - structured layout with communities as groups')
print(' _COMMUNITY_* - overview notes with cohesion scores and dataview queries')
"
```
Generate the HTML graph (always, unless `--no-viz`):
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.export import to_html
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
labels_raw = json.loads(Path('.graphify_labels.json').read_text()) if Path('.graphify_labels.json').exists() else {}
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
labels = {int(k): v for k, v in labels_raw.items()}
if G.number_of_nodes() > 5000:
print(f'Graph has {G.number_of_nodes()} nodes - too large for HTML viz. Use Obsidian vault instead.')
else:
to_html(G, communities, 'graphify-out/graph.html', community_labels=labels or None)
print('graph.html written - open in any browser, no server needed')
"
```
### Step 7 - Neo4j export (only if --neo4j or --neo4j-push flag)
**If `--neo4j`** - generate a Cypher file for manual import:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.export import to_cypher
from pathlib import Path
G = build_from_json(json.loads(Path('.graphify_extract.json').read_text()))
to_cypher(G, 'graphify-out/cypher.txt')
print('cypher.txt written - import with: cypher-shell < graphify-out/cypher.txt')
"
```
**If `--neo4j-push <uri>`** - push directly to a running Neo4j instance. Ask the user for credentials if not provided:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.cluster import cluster
from graphify.export import push_to_neo4j
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
result = push_to_neo4j(G, uri='NEO4J_URI', user='NEO4J_USER', password='NEO4J_PASSWORD', communities=communities)
print(f'Pushed to Neo4j: {result[\"nodes\"]} nodes, {result[\"edges\"]} edges')
"
```
Replace `NEO4J_URI`, `NEO4J_USER`, `NEO4J_PASSWORD` with actual values. Default URI is `bolt://localhost:7687`, default user is `neo4j`. Uses MERGE - safe to re-run without creating duplicates.
### Step 7b - SVG export (only if --svg flag)
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.export import to_svg
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
labels_raw = json.loads(Path('.graphify_labels.json').read_text()) if Path('.graphify_labels.json').exists() else {}
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
labels = {int(k): v for k, v in labels_raw.items()}
to_svg(G, communities, 'graphify-out/graph.svg', community_labels=labels or None)
print('graph.svg written - embeds in Obsidian, Notion, GitHub READMEs')
"
```
### Step 7c - GraphML export (only if --graphml flag)
```bash
$(cat .graphify_python) -c "
import json
from graphify.build import build_from_json
from graphify.export import to_graphml
from pathlib import Path
extraction = json.loads(Path('.graphify_extract.json').read_text())
analysis = json.loads(Path('.graphify_analysis.json').read_text())
G = build_from_json(extraction)
communities = {int(k): v for k, v in analysis['communities'].items()}
to_graphml(G, communities, 'graphify-out/graph.graphml')
print('graph.graphml written - open in Gephi, yEd, or any GraphML tool')
"
```
### Step 7d - MCP server (only if --mcp flag)
```bash
python3 -m graphify.serve graphify-out/graph.json
```
This starts a stdio MCP server that exposes tools: `query_graph`, `get_node`, `get_neighbors`, `get_community`, `god_nodes`, `graph_stats`, `shortest_path`. Add to Claude Desktop or any MCP-compatible agent orchestrator so other agents can query the graph live.
To configure in Claude Desktop, add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"graphify": {
"command": "python3",
"args": ["-m", "graphify.serve", "/absolute/path/to/graphify-out/graph.json"]
}
}
}
```
### Step 8 - Token reduction benchmark (only if total_words > 5000)
If `total_words` from `.graphify_detect.json` is greater than 5,000, run:
```bash
$(cat .graphify_python) -c "
import json
from graphify.benchmark import run_benchmark, print_benchmark
from pathlib import Path
detection = json.loads(Path('.graphify_detect.json').read_text())
result = run_benchmark('graphify-out/graph.json', corpus_words=detection['total_words'])
print_benchmark(result)
"
```
Print the output directly in chat. If `total_words <= 5000`, skip silently - the graph value is structural clarity, not token compression, for small corpora.
---
### Step 9 - Save manifest, update cost tracker, clean up, and report
```bash
$(cat .graphify_python) -c "
import json
from pathlib import Path
from datetime import datetime, timezone
from graphify.detect import save_manifest
# Save manifest for --update
detect = json.loads(Path('.graphify_detect.json').read_text())
save_manifest(detect['files'])
# Update cumulative cost tracker
extract = json.loads(Path('.graphify_extract.json').read_text())
input_tok = extract.get('input_tokens', 0)
output_tok = extract.get('output_tokens', 0)
cost_path = Path('graphify-out/cost.json')
if cost_path.exists():
cost = json.loads(cost_path.read_text())
else:
cost = {'runs': [], 'total_input_tokens': 0, 'total_output_tokens': 0}
cost['runs'].append({
'date': datetime.now(timezone.utc).isoformat(),
'input_tokens': input_tok,
'output_tokens': output_tok,
'files': detect.get('total_files', 0),
})
cost['total_input_tokens'] += input_tok
cost['total_output_tokens'] += output_tok
cost_path.write_text(json.dumps(cost, indent=2))
print(f'This run: {input_tok:,} input tokens, {output_tok:,} output tokens')
print(f'All time: {cost[\"total_input_tokens\"]:,} input, {cost[\"total_output_tokens\"]:,} output ({len(cost[\"runs\"])} runs)')
"
rm -f .graphify_detect.json .graphify_extract.json .graphify_ast.json .graphify_semantic.json .graphify_analysis.json .graphify_labels.json .graphify_python
rm -f graphify-out/.needs_update 2>/dev/null || true
```
Tell the user (omit the obsidian line unless --obsidian was given):
```
Graph complete. Outputs in PATH_TO_DIR/graphify-out/
graph.html - interactive graph, open in browser
GRAPH_REPORT.md - audit report
graph.json - raw graph data
obsidian/ - Obsidian vault (only if --obsidian was given)
```
Replace PATH_TO_DIR with the actual absolute path of the directory that was processed.
Then paste these sections from GRAPH_REPORT.md directly into the chat:
- God Nodes
- Surprising Connections
- Suggested Questions
Do NOT paste the full report - just those three sections. Keep it concise.
Then immediately offer to explore. Pick the single most interesting suggested question from the report - the one that crosses the most community boundaries or has the most surprising bridge node - and ask:
> "The most interesting question this graph can answer: **[question]**. Want me to trace it?"
If the user says yes, run `/graphify query "[question]"` on the graph and walk them through the answer using the graph structure - which nodes connect, which community boundaries get crossed, what the path reveals. Keep going as long as they want to explore. Each answer should end with a natural follow-up ("this connects to X - want to go deeper?") so the session feels like navigation, not a one-shot report.
The graph is the map. Your job after the pipeline is to be the guide.
---
## For --update (incremental re-extraction)
Use when you've added or modified files since the last run. Only re-extracts changed files - saves tokens and time.
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.detect import detect_incremental, save_manifest
from pathlib import Path
result = detect_incremental(Path('INPUT_PATH'))
new_total = result.get('new_total', 0)
print(json.dumps(result, indent=2))
Path('.graphify_incremental.json').write_text(json.dumps(result))
if new_total == 0:
print('No files changed since last run. Nothing to update.')
raise SystemExit(0)
print(f'{new_total} new/changed file(s) to re-extract.')
"
```
If new files exist, first check whether all changed files are code files:
```bash
$(cat .graphify_python) -c "
import json
from pathlib import Path
result = json.loads(open('.graphify_incremental.json').read()) if Path('.graphify_incremental.json').exists() else {}
code_exts = {'.py','.ts','.js','.go','.rs','.java','.cpp','.c','.rb','.swift','.kt','.cs','.scala','.php','.cc','.cxx','.hpp','.h','.kts','.lua','.toc'}
new_files = result.get('new_files', {})
all_changed = [f for files in new_files.values() for f in files]
code_only = all(Path(f).suffix.lower() in code_exts for f in all_changed)
print('code_only:', code_only)
"
```
If `code_only` is True: print `[graphify update] Code-only changes detected - skipping semantic extraction (no LLM needed)`, run only Step 3A (AST) on the changed files, skip Step 3B entirely (no subagents), then go straight to merge and Steps 48.
If `code_only` is False (any changed file is a doc/paper/image): run the full Steps 3A3C pipeline as normal.
Then:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.build import build_from_json
from graphify.export import to_json
from networkx.readwrite import json_graph
import networkx as nx
from pathlib import Path
# Load existing graph
existing_data = json.loads(Path('graphify-out/graph.json').read_text())
G_existing = json_graph.node_link_graph(existing_data, edges='links')
# Load new extraction
new_extraction = json.loads(Path('.graphify_extract.json').read_text())
G_new = build_from_json(new_extraction)
# Merge: new nodes/edges into existing graph
G_existing.update(G_new)
print(f'Merged: {G_existing.number_of_nodes()} nodes, {G_existing.number_of_edges()} edges')
"
```
Then run Steps 48 on the merged graph as normal.
After Step 4, show the graph diff:
```bash
$(cat .graphify_python) -c "
import json
from graphify.analyze import graph_diff
from graphify.build import build_from_json
from networkx.readwrite import json_graph
import networkx as nx
from pathlib import Path
# Load old graph (before update) from backup written before merge
old_data = json.loads(Path('.graphify_old.json').read_text()) if Path('.graphify_old.json').exists() else None
new_extract = json.loads(Path('.graphify_extract.json').read_text())
G_new = build_from_json(new_extract)
if old_data:
G_old = json_graph.node_link_graph(old_data, edges='links')
diff = graph_diff(G_old, G_new)
print(diff['summary'])
if diff['new_nodes']:
print('New nodes:', ', '.join(n['label'] for n in diff['new_nodes'][:5]))
if diff['new_edges']:
print('New edges:', len(diff['new_edges']))
"
```
Before the merge step, save the old graph: `cp graphify-out/graph.json .graphify_old.json`
Clean up after: `rm -f .graphify_old.json`
---
## For --cluster-only
Skip Steps 13. Load the existing graph from `graphify-out/graph.json` and re-run clustering:
```bash
$(cat .graphify_python) -c "
import sys, json
from graphify.cluster import cluster, score_all
from graphify.analyze import god_nodes, surprising_connections
from graphify.report import generate
from graphify.export import to_json
from networkx.readwrite import json_graph
import networkx as nx
from pathlib import Path
data = json.loads(Path('graphify-out/graph.json').read_text())
G = json_graph.node_link_graph(data, edges='links')
detection = {'total_files': 0, 'total_words': 99999, 'needs_graph': True, 'warning': None, 'files': {}}
communities = cluster(G)
cohesion = score_all(G, communities)
gods = god_nodes(G)
surprises = surprising_connections(G, communities)
labels = {cid: 'Community ' + str(cid) for cid in communities}
report = generate(G, communities, cohesion, labels, gods, surprises, detection, {'input':0,'output':0}, 'INPUT_PATH')
Path('graphify-out/GRAPH_REPORT.md').write_text(report)
to_json(G, communities, 'graphify-out/graph.json')
print(f'Re-clustered: {len(communities)} communities')
"
```
Then proceed to Step 5 (Labeling) as normal.

View File

@ -0,0 +1,181 @@
# Graph Report - . (2026-04-09)
## Corpus Check
- 124 files · ~92,302 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 316 nodes · 549 edges · 29 communities detected
- Extraction: 64% EXTRACTED · 36% INFERRED · 0% AMBIGUOUS · INFERRED: 197 edges (avg confidence: 0.5)
- Token cost: 0 input · 0 output
## God Nodes (most connected - your core abstractions)
1. `FishingService` - 55 edges
2. `MusicService` - 38 edges
3. `RefinementService` - 13 edges
4. `VoiceService` - 8 edges
5. `PermissionAuditService` - 7 edges
6. `execute()` - 6 edges
7. `InviteService` - 6 edges
8. `AuditLogService` - 6 edges
9. `EventService` - 6 edges
10. `buildEventEmbed()` - 5 edges
## Surprising Connections (you probably didn't know these)
- None detected - all connections are within the same source files.
## Communities
### Community 0 - "Community 0"
Cohesion: 0.05
Nodes (6): ActivityTrackerService, buildEventEmbed(), EventService, resolveAnnouncementChannel(), toDiscordTimestamps(), KordClient
### Community 1 - "Community 1"
Cohesion: 0.08
Nodes (1): FishingService
### Community 2 - "Community 2"
Cohesion: 0.11
Nodes (6): extractYouTubeVideoId(), formatDuration(), isYouTubePlaylistUrl(), MusicService, parseDurationSeconds(), parseDurationTextToSeconds()
### Community 3 - "Community 3"
Cohesion: 0.14
Nodes (5): getNestedValue(), normalizeDiscordLocale(), resolveLocale(), StaticI18nProvider, t()
### Community 4 - "Community 4"
Cohesion: 0.15
Nodes (3): BotError, ErrorReporter, withErrorHandler()
### Community 5 - "Community 5"
Cohesion: 0.16
Nodes (4): execute(), getOverallColor(), PermissionAuditService, SetupWizardRenderer
### Community 6 - "Community 6"
Cohesion: 0.37
Nodes (1): RefinementService
### Community 7 - "Community 7"
Cohesion: 0.18
Nodes (3): BigEmojiService, MimicService, WebhookService
### Community 8 - "Community 8"
Cohesion: 0.36
Nodes (9): Fishing Game Backend Logic, Authentication/Authorization Layer, Database Schema Design (User/Item), Frontend Game Client (React/Unity), Payment Gateway Integration (Stripe/PayPal), Real-time Communication (WebSockets), Game State Management (Session/Persistence), Analytics/Telemetry Tracking (+1 more)
### Community 9 - "Community 9"
Cohesion: 0.46
Nodes (1): VoiceService
### Community 10 - "Community 10"
Cohesion: 0.52
Nodes (6): buildStatusLabel(), execute(), formatReminderOffsets(), parseReminderOffsets(), parseSeoulDateTime(), toDiscordTimestamps()
### Community 11 - "Community 11"
Cohesion: 0.33
Nodes (2): buildFishingGauge(), buildFishingLane()
### Community 12 - "Community 12"
Cohesion: 0.6
Nodes (1): InviteService
### Community 13 - "Community 13"
Cohesion: 0.47
Nodes (1): AuditLogService
### Community 14 - "Community 14"
Cohesion: 0.4
Nodes (0):
### Community 15 - "Community 15"
Cohesion: 0.4
Nodes (0):
### Community 16 - "Community 16"
Cohesion: 0.83
Nodes (3): buildErrorMessage(), execute(), respond()
### Community 17 - "Community 17"
Cohesion: 0.5
Nodes (1): FeverService
### Community 18 - "Community 18"
Cohesion: 0.67
Nodes (1): PresenceService
### Community 19 - "Community 19"
Cohesion: 1.0
Nodes (0):
### Community 20 - "Community 20"
Cohesion: 1.0
Nodes (2): main.ts, config.ts
### Community 21 - "Community 21"
Cohesion: 1.0
Nodes (1): FishingGameConcept
### Community 22 - "Community 22"
Cohesion: 1.0
Nodes (0):
### Community 23 - "Community 23"
Cohesion: 1.0
Nodes (0):
### Community 24 - "Community 24"
Cohesion: 1.0
Nodes (1): Gemma 4 Response
### Community 25 - "Community 25"
Cohesion: 1.0
Nodes (1): Tool Use Concept
### Community 26 - "Community 26"
Cohesion: 1.0
Nodes (1): Capability Summary
### Community 27 - "Community 27"
Cohesion: 1.0
Nodes (1): db.ts
### Community 28 - "Community 28"
Cohesion: 1.0
Nodes (1): logger.ts
## Knowledge Gaps
- **Thin community `Community 19`** (2 nodes): `language.ts`, `execute()`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 20`** (2 nodes): `main.ts`, `config.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 21`** (1 nodes): `FishingGameConcept`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 22`** (1 nodes): `jest.config.js`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 23`** (1 nodes): `i18n.test.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 24`** (1 nodes): `Gemma 4 Response`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 25`** (1 nodes): `Tool Use Concept`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 26`** (1 nodes): `Capability Summary`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 27`** (1 nodes): `db.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
- **Thin community `Community 28`** (1 nodes): `logger.ts`
Too small to be a meaningful cluster - may be noise or needs more connections extracted.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `FishingService` connect `Community 1` to `Community 11`?**
_High betweenness centrality (0.272) - this node is a cross-community bridge._
- **Why does `RefinementService` connect `Community 6` to `Community 0`?**
_High betweenness centrality (0.067) - this node is a cross-community bridge._
- **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05 - nodes in this community are weakly interconnected._
- **Should `Community 1` be split into smaller, more focused modules?**
_Cohesion score 0.08 - nodes in this community are weakly interconnected._
- **Should `Community 2` be split into smaller, more focused modules?**
_Cohesion score 0.11 - nodes in this community are weakly interconnected._
- **Should `Community 3` be split into smaller, more focused modules?**
_Cohesion score 0.14 - nodes in this community are weakly interconnected._

View File

@ -0,0 +1 @@
{"nodes": [{"id": "invitedelete", "label": "inviteDelete.ts", "file_type": "code", "source_file": "src/events/inviteDelete.ts", "source_location": "L1"}, {"id": "invitedelete_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/inviteDelete.ts", "source_location": "L7"}], "edges": [{"source": "invitedelete", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/inviteDelete.ts", "source_location": "L1", "weight": 1.0}, {"source": "invitedelete", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/inviteDelete.ts", "source_location": "L2", "weight": 1.0}, {"source": "invitedelete", "target": "invitedelete_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/inviteDelete.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "kordclient", "label": "KordClient.ts", "file_type": "code", "source_file": "src/client/KordClient.ts", "source_location": "L1"}, {"id": "kordclient_kordclient", "label": "KordClient", "file_type": "code", "source_file": "src/client/KordClient.ts", "source_location": "L10"}, {"id": "kordclient_kordclient_constructor", "label": ".constructor()", "file_type": "code", "source_file": "src/client/KordClient.ts", "source_location": "L13"}, {"id": "kordclient_kordclient_start", "label": ".start()", "file_type": "code", "source_file": "src/client/KordClient.ts", "source_location": "L26"}], "edges": [{"source": "kordclient", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L1", "weight": 1.0}, {"source": "kordclient", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L2", "weight": 1.0}, {"source": "kordclient", "target": "env", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L3", "weight": 1.0}, {"source": "kordclient", "target": "commandloader", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L4", "weight": 1.0}, {"source": "kordclient", "target": "eventloader", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L5", "weight": 1.0}, {"source": "kordclient", "target": "errorhandler", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L6", "weight": 1.0}, {"source": "kordclient", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L7", "weight": 1.0}, {"source": "kordclient", "target": "feverservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L8", "weight": 1.0}, {"source": "kordclient", "target": "kordclient_kordclient", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L10", "weight": 1.0}, {"source": "kordclient_kordclient", "target": "kordclient_kordclient_constructor", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L13", "weight": 1.0}, {"source": "kordclient_kordclient", "target": "kordclient_kordclient_start", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/client/KordClient.ts", "source_location": "L26", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "error_guidance_ux", "label": "\uc5d0\ub7ec \uc548\ub0b4 UX \uac1c\uc120", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Error_Guidance_UX_Implementation.md"}, {"id": "BotError class", "label": "BotError \ud074\ub798\uc2a4", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Error_Guidance_UX_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "AuditChannel", "label": "Audit Channel Model", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Audit_Log_Channel_Implementation.md"}, {"id": "AuditLogService", "label": "Audit Log Service", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Audit_Log_Channel_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "Discord Bot Tokens", "label": "\ub514\uc2a4\ucf54\ub4dc \ubd07 \ud1a0\ud070", "file_type": "secret", "source_file": "Docs/Rules/security_guidelines.md"}, {"id": "Database Credentials", "label": "\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ube44\ubc00\ubc88\ud638 \ubc0f \uc811\uc18d \uc8fc\uc18c", "file_type": "secret", "source_file": "Docs/Rules/security_guidelines.md"}, {"id": "Environment Variables", "label": "\ud658\uacbd \ubcc0\uc218", "file_type": "concept", "source_file": "Docs/Rules/security_guidelines.md"}], "edges": [{"source": "Environment Variables", "target": "Discord Bot Tokens", "relation": "is_preferred_storage_for", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Rules/security_guidelines.md"}, {"source": "Environment Variables", "target": "Database Credentials", "relation": "is_preferred_storage_for", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Rules/security_guidelines.md"}], "hyperedges": []}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "event", "label": "event.ts", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L1"}, {"id": "event_parseseouldatetime", "label": "parseSeoulDateTime()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L18"}, {"id": "event_todiscordtimestamps", "label": "toDiscordTimestamps()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L51"}, {"id": "event_parsereminderoffsets", "label": "parseReminderOffsets()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L59"}, {"id": "event_formatreminderoffsets", "label": "formatReminderOffsets()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L77"}, {"id": "event_buildstatuslabel", "label": "buildStatusLabel()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L85"}, {"id": "event_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/event.ts", "source_location": "L189"}], "edges": [{"source": "event", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L1", "weight": 1.0}, {"source": "event", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L10", "weight": 1.0}, {"source": "event", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L11", "weight": 1.0}, {"source": "event", "target": "eventservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L12", "weight": 1.0}, {"source": "event", "target": "event_parseseouldatetime", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L18", "weight": 1.0}, {"source": "event", "target": "event_todiscordtimestamps", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L51", "weight": 1.0}, {"source": "event", "target": "event_parsereminderoffsets", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L59", "weight": 1.0}, {"source": "event", "target": "event_formatreminderoffsets", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L77", "weight": 1.0}, {"source": "event", "target": "event_buildstatuslabel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L85", "weight": 1.0}, {"source": "event", "target": "event_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/event.ts", "source_location": "L189", "weight": 1.0}, {"source": "event_execute", "target": "event_parseseouldatetime", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/event.ts", "source_location": "L202", "weight": 0.8}, {"source": "event_execute", "target": "event_parsereminderoffsets", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/event.ts", "source_location": "L217", "weight": 0.8}, {"source": "event_execute", "target": "event_todiscordtimestamps", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/event.ts", "source_location": "L239", "weight": 0.8}, {"source": "event_execute", "target": "event_formatreminderoffsets", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/event.ts", "source_location": "L247", "weight": 0.8}, {"source": "event_execute", "target": "event_buildstatuslabel", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/event.ts", "source_location": "L286", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "minigameregistry", "label": "MiniGameRegistry.ts", "file_type": "code", "source_file": "src/services/MiniGameRegistry.ts", "source_location": "L1"}, {"id": "minigameregistry_getminigame", "label": "getMiniGame()", "file_type": "code", "source_file": "src/services/MiniGameRegistry.ts", "source_location": "L20"}, {"id": "minigameregistry_getallminigames", "label": "getAllMiniGames()", "file_type": "code", "source_file": "src/services/MiniGameRegistry.ts", "source_location": "L24"}], "edges": [{"source": "minigameregistry", "target": "minigameregistry_getminigame", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/MiniGameRegistry.ts", "source_location": "L20", "weight": 1.0}, {"source": "minigameregistry", "target": "minigameregistry_getallminigames", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/MiniGameRegistry.ts", "source_location": "L24", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "interactioncreate", "label": "interactionCreate.ts", "file_type": "code", "source_file": "src/events/interactionCreate.ts", "source_location": "L1"}, {"id": "interactioncreate_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/interactionCreate.ts", "source_location": "L16"}], "edges": [{"source": "interactioncreate", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L1", "weight": 1.0}, {"source": "interactioncreate", "target": "kordclient", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L2", "weight": 1.0}, {"source": "interactioncreate", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L3", "weight": 1.0}, {"source": "interactioncreate", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L4", "weight": 1.0}, {"source": "interactioncreate", "target": "boterror", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L5", "weight": 1.0}, {"source": "interactioncreate", "target": "errorcodes", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L6", "weight": 1.0}, {"source": "interactioncreate", "target": "errorreporter", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L7", "weight": 1.0}, {"source": "interactioncreate", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L8", "weight": 1.0}, {"source": "interactioncreate", "target": "localehelper", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L9", "weight": 1.0}, {"source": "interactioncreate", "target": "setupwizardhandler", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L10", "weight": 1.0}, {"source": "interactioncreate", "target": "musicservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L11", "weight": 1.0}, {"source": "interactioncreate", "target": "interactioncreate_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/interactionCreate.ts", "source_location": "L16", "weight": 1.0}]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "boterror", "label": "BotError.ts", "file_type": "code", "source_file": "src/errors/BotError.ts", "source_location": "L1"}, {"id": "boterror_boterror", "label": "BotError", "file_type": "code", "source_file": "src/errors/BotError.ts", "source_location": "L16"}, {"id": "boterror_boterror_constructor", "label": ".constructor()", "file_type": "code", "source_file": "src/errors/BotError.ts", "source_location": "L29"}], "edges": [{"source": "boterror", "target": "boterror_boterror", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/errors/BotError.ts", "source_location": "L16", "weight": 1.0}, {"source": "boterror_boterror", "target": "boterror_boterror_constructor", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/errors/BotError.ts", "source_location": "L29", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "i18n_test", "label": "i18n.test.ts", "file_type": "code", "source_file": "tests/i18n/i18n.test.ts", "source_location": "L1"}], "edges": [{"source": "i18n_test", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/i18n/i18n.test.ts", "source_location": "L1", "weight": 1.0}, {"source": "i18n_test", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/i18n/i18n.test.ts", "source_location": "L2", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "GuildEvent", "label": "\uc774\ubca4\ud2b8 \uc774\ubca4\ud2b8", "file_type": "model", "source_file": "Docs/WorkDone/2026-03-30_Event_Reminder_Offsets_Implementation.md"}, {"id": "reminderOffsets", "label": "\uc774\ubca4\ud2b8 \ub9ac\ub9c8\uc778\ub354 \uc624\ud504\uc14b \ubaa9\ub85d", "file_type": "data_field", "source_file": "Docs/WorkDone/2026-03-30_Event_Reminder_Offsets_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "ko", "label": "ko.ts", "file_type": "code", "source_file": "src/i18n/locales/ko.ts", "source_location": "L1"}], "edges": [{"source": "ko", "target": "types", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/locales/ko.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "errorcodes", "label": "ErrorCodes.ts", "file_type": "code", "source_file": "src/errors/ErrorCodes.ts", "source_location": "L1"}, {"id": "errorcodes_createboterror", "label": "createBotError()", "file_type": "code", "source_file": "src/errors/ErrorCodes.ts", "source_location": "L123"}], "edges": [{"source": "errorcodes", "target": "boterror", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorCodes.ts", "source_location": "L1", "weight": 1.0}, {"source": "errorcodes", "target": "errorcodes_createboterror", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorCodes.ts", "source_location": "L123", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "voiceservice_test", "label": "VoiceService.test.ts", "file_type": "code", "source_file": "tests/services/VoiceService.test.ts", "source_location": "L1"}], "edges": [{"source": "voiceservice_test", "target": "voiceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/VoiceService.test.ts", "source_location": "L1", "weight": 1.0}, {"source": "voiceservice_test", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/VoiceService.test.ts", "source_location": "L2", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "subscription_tier_system", "label": "\uad6c\ub3c5 \ud2f0\uc5b4 \uc2dc\uc2a4\ud15c", "file_type": "document", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "User", "label": "\uc0ac\uc6a9\uc790", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "Guild", "label": "\uc11c\ubc84", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "Free", "label": "FREE (\ud504\ub9ac)", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "Standard", "label": "STANDARD (\uc2a4\ud0e0\ub2e4\ub4dc)", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "Pro", "label": "PRO (\ud504\ub85c)", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "Premium", "label": "PREMIUM (\ud504\ub9ac\ubbf8\uc5c4)", "file_type": "concept", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "UserSubscription", "label": "UserSubscription", "file_type": "model", "source_file": "Docs/Decisions/subscription_tiers.md"}, {"id": "GuildOwnership", "label": "GuildOwnership", "file_type": "model", "source_file": "Docs/Decisions/subscription_tiers.md"}], "edges": [{"source": "User", "target": "subscription_tier_system", "relation": "is_holder_of_tier", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "Guild", "target": "subscription_tier_system", "relation": "is_controlled_by", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "Free", "target": "subscription_tier_system", "relation": "defines_limit", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "Standard", "target": "subscription_tier_system", "relation": "defines_limit", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "Pro", "target": "subscription_tier_system", "relation": "defines_limit", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "Premium", "target": "subscription_tier_system", "relation": "defines_limit", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "GuildOwnership", "target": "subscription_tier_system", "relation": "manages_association", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}, {"source": "UserSubscription", "target": "subscription_tier_system", "relation": "is_used_for_validation", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "Docs/Decisions/subscription_tiers.md"}], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "inviteservice", "label": "InviteService.ts", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L1"}, {"id": "inviteservice_inviteservice", "label": "InviteService", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L5"}, {"id": "inviteservice_inviteservice_cacheallinvites", "label": ".cacheAllInvites()", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L9"}, {"id": "inviteservice_inviteservice_cacheguildinvites", "label": ".cacheGuildInvites()", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L16"}, {"id": "inviteservice_inviteservice_handleinvitecreate", "label": ".handleInviteCreate()", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L29"}, {"id": "inviteservice_inviteservice_handleinvitedelete", "label": ".handleInviteDelete()", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L35"}, {"id": "inviteservice_inviteservice_handlememberadd", "label": ".handleMemberAdd()", "file_type": "code", "source_file": "src/services/InviteService.ts", "source_location": "L41"}], "edges": [{"source": "inviteservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L1", "weight": 1.0}, {"source": "inviteservice", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L2", "weight": 1.0}, {"source": "inviteservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L3", "weight": 1.0}, {"source": "inviteservice", "target": "inviteservice_inviteservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L5", "weight": 1.0}, {"source": "inviteservice_inviteservice", "target": "inviteservice_inviteservice_cacheallinvites", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L9", "weight": 1.0}, {"source": "inviteservice_inviteservice", "target": "inviteservice_inviteservice_cacheguildinvites", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L16", "weight": 1.0}, {"source": "inviteservice_inviteservice", "target": "inviteservice_inviteservice_handleinvitecreate", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L29", "weight": 1.0}, {"source": "inviteservice_inviteservice", "target": "inviteservice_inviteservice_handleinvitedelete", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L35", "weight": 1.0}, {"source": "inviteservice_inviteservice", "target": "inviteservice_inviteservice_handlememberadd", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/InviteService.ts", "source_location": "L41", "weight": 1.0}, {"source": "inviteservice_inviteservice_cacheallinvites", "target": "inviteservice_inviteservice_cacheguildinvites", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/InviteService.ts", "source_location": "L11", "weight": 0.8}, {"source": "inviteservice_inviteservice_handleinvitecreate", "target": "inviteservice_inviteservice_cacheguildinvites", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/InviteService.ts", "source_location": "L32", "weight": 0.8}, {"source": "inviteservice_inviteservice_handleinvitedelete", "target": "inviteservice_inviteservice_cacheguildinvites", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/InviteService.ts", "source_location": "L38", "weight": 0.8}, {"source": "inviteservice_inviteservice_handlememberadd", "target": "inviteservice_inviteservice_cacheguildinvites", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/InviteService.ts", "source_location": "L61", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "refinementhandler", "label": "refinementHandler.ts", "file_type": "code", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L1"}, {"id": "refinementhandler_handlerefinementinteraction", "label": "handleRefinementInteraction()", "file_type": "code", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L7"}], "edges": [{"source": "refinementhandler", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L1", "weight": 1.0}, {"source": "refinementhandler", "target": "refinementservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L2", "weight": 1.0}, {"source": "refinementhandler", "target": "feverservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L3", "weight": 1.0}, {"source": "refinementhandler", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L4", "weight": 1.0}, {"source": "refinementhandler", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L5", "weight": 1.0}, {"source": "refinementhandler", "target": "refinementhandler_handlerefinementinteraction", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/refinementHandler.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "minigame", "label": "minigame.ts", "file_type": "code", "source_file": "src/commands/minigame.ts", "source_location": "L1"}, {"id": "minigame_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/minigame.ts", "source_location": "L62"}], "edges": [{"source": "minigame", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/minigame.ts", "source_location": "L1", "weight": 1.0}, {"source": "minigame", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/minigame.ts", "source_location": "L9", "weight": 1.0}, {"source": "minigame", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/minigame.ts", "source_location": "L10", "weight": 1.0}, {"source": "minigame", "target": "minigameregistry", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/minigame.ts", "source_location": "L11", "weight": 1.0}, {"source": "minigame", "target": "minigame_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/minigame.ts", "source_location": "L62", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "types", "label": "types.ts", "file_type": "code", "source_file": "src/i18n/types.ts", "source_location": "L1"}], "edges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "jest_config", "label": "jest.config.js", "file_type": "code", "source_file": "jest.config.js", "source_location": "L1"}], "edges": []}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "mimicservice_test", "label": "MimicService.test.ts", "file_type": "code", "source_file": "tests/services/MimicService.test.ts", "source_location": "L1"}], "edges": [{"source": "mimicservice_test", "target": "mimicservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/MimicService.test.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "musicservice_test", "label": "MusicService.test.ts", "file_type": "code", "source_file": "tests/services/MusicService.test.ts", "source_location": "L1"}], "edges": [{"source": "musicservice_test", "target": "musicservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/MusicService.test.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "boterror_test", "label": "BotError.test.ts", "file_type": "code", "source_file": "tests/errors/BotError.test.ts", "source_location": "L1"}], "edges": [{"source": "boterror_test", "target": "boterror", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/errors/BotError.test.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "audit", "label": "audit.ts", "file_type": "code", "source_file": "src/commands/audit.ts", "source_location": "L1"}, {"id": "audit_getoverallcolor", "label": "getOverallColor()", "file_type": "code", "source_file": "src/commands/audit.ts", "source_location": "L20"}, {"id": "audit_buildresultline", "label": "buildResultLine()", "file_type": "code", "source_file": "src/commands/audit.ts", "source_location": "L26"}, {"id": "audit_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/audit.ts", "source_location": "L110"}], "edges": [{"source": "audit", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L1", "weight": 1.0}, {"source": "audit", "target": "auditlogservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L10", "weight": 1.0}, {"source": "audit", "target": "permissionauditservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L11", "weight": 1.0}, {"source": "audit", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L12", "weight": 1.0}, {"source": "audit", "target": "audit_getoverallcolor", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L20", "weight": 1.0}, {"source": "audit", "target": "audit_buildresultline", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L26", "weight": 1.0}, {"source": "audit", "target": "audit_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/audit.ts", "source_location": "L110", "weight": 1.0}, {"source": "audit_execute", "target": "audit_getoverallcolor", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/audit.ts", "source_location": "L202", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "bigemojiservice", "label": "BigEmojiService.ts", "file_type": "code", "source_file": "src/services/BigEmojiService.ts", "source_location": "L1"}, {"id": "bigemojiservice_bigemojiservice", "label": "BigEmojiService", "file_type": "code", "source_file": "src/services/BigEmojiService.ts", "source_location": "L5"}, {"id": "bigemojiservice_bigemojiservice_handlemessage", "label": ".handleMessage()", "file_type": "code", "source_file": "src/services/BigEmojiService.ts", "source_location": "L6"}], "edges": [{"source": "bigemojiservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/BigEmojiService.ts", "source_location": "L1", "weight": 1.0}, {"source": "bigemojiservice", "target": "webhookservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/BigEmojiService.ts", "source_location": "L2", "weight": 1.0}, {"source": "bigemojiservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/BigEmojiService.ts", "source_location": "L3", "weight": 1.0}, {"source": "bigemojiservice", "target": "bigemojiservice_bigemojiservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/BigEmojiService.ts", "source_location": "L5", "weight": 1.0}, {"source": "bigemojiservice_bigemojiservice", "target": "bigemojiservice_bigemojiservice_handlemessage", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/BigEmojiService.ts", "source_location": "L6", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "index", "label": "index.ts", "file_type": "code", "source_file": "src/index.ts", "source_location": "L1"}], "edges": [{"source": "index", "target": "kordclient", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/index.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "fishing_mini_game", "label": "\ub09a\uc2dc \ubbf8\ub2c8\uac8c\uc784", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "fishing_mini_game_registry", "label": "\uacf5\uc6a9 \ubbf8\ub2c8\uac8c\uc784 \ub808\uc9c0\uc2a4\ud2b8\ub9ac", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "/fishing cast command", "label": "/fishing cast \uba85\ub839\uc5b4", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "/fishing end command", "label": "/fishing end \uba85\ub839\uc5b4", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": " \uc804\uc6a9 \uc2a4\ub808\ub4dc \uae30\ubc18 \uc138\uc158", "label": "\uc804\uc6a9 \uc2a4\ub808\ub4dc \uae30\ubc18 \uc138\uc158", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "\uba54\ubaa8\ub9ac \uae30\ubc18 \uc138\uc158 \uad00\ub9ac", "label": "\uba54\ubaa8\ub9ac \uae30\ubc18 \uc138\uc158 \uad00\ub9ac", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "\uac70\ub9ac/\ub04a\uc5b4\uc9d0 \uac8c\uc774\uc9c0", "label": "\uac70\ub9ac/\ub04a\uc5b4\uc9d0 \uac8c\uc774\uc9c0", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "\uace8\ub4dc \uc9c0\uae09", "label": "\uace8\ub4dc \uc9c0\uae09", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "RefinementProfile.gold", "label": "RefinementProfile.gold", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/commands/fishing.ts", "label": "src/commands/fishing.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/services/FishingService.ts", "label": "src/services/FishingService.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/events/interactionCreate.ts", "label": "src/events/interactionCreate.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/services/MiniGameRegistry.ts", "label": "src/services/MiniGameRegistry.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/services/RefinementService.ts", "label": "src/services/RefinementService.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/i18n/types.ts", "label": "src/i18n/types.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/i18n/locales/en.ts", "label": "src/i18n/locales/en.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "src/i18n/locales/ko.ts", "label": "src/i18n/locales/ko.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}, {"id": "tests/services/FishingService.test.ts", "label": "tests/services/FishingService.test.ts", "file_type": "code", "source_file": "Docs/WorkDone/2026-03-31_Fishing_MiniGame_Phase1_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "activitytrackerservice", "label": "ActivityTrackerService.ts", "file_type": "code", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L1"}, {"id": "activitytrackerservice_activitytrackerservice", "label": "ActivityTrackerService", "file_type": "code", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L4"}, {"id": "activitytrackerservice_activitytrackerservice_recordactivity", "label": ".recordActivity()", "file_type": "code", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L9"}, {"id": "activitytrackerservice_activitytrackerservice_getpeakhour", "label": ".getPeakHour()", "file_type": "code", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L48"}], "edges": [{"source": "activitytrackerservice", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L1", "weight": 1.0}, {"source": "activitytrackerservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L2", "weight": 1.0}, {"source": "activitytrackerservice", "target": "activitytrackerservice_activitytrackerservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L4", "weight": 1.0}, {"source": "activitytrackerservice_activitytrackerservice", "target": "activitytrackerservice_activitytrackerservice_recordactivity", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L9", "weight": 1.0}, {"source": "activitytrackerservice_activitytrackerservice", "target": "activitytrackerservice_activitytrackerservice_getpeakhour", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/ActivityTrackerService.ts", "source_location": "L48", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "feverservice", "label": "FeverService.ts", "file_type": "code", "source_file": "src/services/FeverService.ts", "source_location": "L1"}, {"id": "feverservice_feverservice", "label": "FeverService", "file_type": "code", "source_file": "src/services/FeverService.ts", "source_location": "L5"}, {"id": "feverservice_feverservice_startscheduler", "label": ".startScheduler()", "file_type": "code", "source_file": "src/services/FeverService.ts", "source_location": "L11"}, {"id": "feverservice_feverservice_updatefeverstate", "label": ".updateFeverState()", "file_type": "code", "source_file": "src/services/FeverService.ts", "source_location": "L28"}, {"id": "feverservice_feverservice_getfeverbonus", "label": ".getFeverBonus()", "file_type": "code", "source_file": "src/services/FeverService.ts", "source_location": "L64"}], "edges": [{"source": "feverservice", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L1", "weight": 1.0}, {"source": "feverservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L2", "weight": 1.0}, {"source": "feverservice", "target": "activitytrackerservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L3", "weight": 1.0}, {"source": "feverservice", "target": "feverservice_feverservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L5", "weight": 1.0}, {"source": "feverservice_feverservice", "target": "feverservice_feverservice_startscheduler", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L11", "weight": 1.0}, {"source": "feverservice_feverservice", "target": "feverservice_feverservice_updatefeverstate", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L28", "weight": 1.0}, {"source": "feverservice_feverservice", "target": "feverservice_feverservice_getfeverbonus", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/FeverService.ts", "source_location": "L64", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "index", "label": "index.ts", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L1"}, {"id": "index_statici18nprovider", "label": "StaticI18nProvider", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L28"}, {"id": "index_statici18nprovider_get", "label": ".get()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L29"}, {"id": "index_statici18nprovider_issupported", "label": ".isSupported()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L33"}, {"id": "index_statici18nprovider_getsupportedlocales", "label": ".getSupportedLocales()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L37"}, {"id": "index_seti18nprovider", "label": "setI18nProvider()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L50"}, {"id": "index_geti18nprovider", "label": "getI18nProvider()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L55"}, {"id": "index_resolvelocale", "label": "resolveLocale()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L68"}, {"id": "index_normalizediscordlocale", "label": "normalizeDiscordLocale()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L88"}, {"id": "index_t", "label": "t()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L109"}, {"id": "index_getnestedvalue", "label": "getNestedValue()", "file_type": "code", "source_file": "src/i18n/index.ts", "source_location": "L134"}], "edges": [{"source": "index", "target": "types", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L9", "weight": 1.0}, {"source": "index", "target": "en", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L17", "weight": 1.0}, {"source": "index", "target": "ko", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L18", "weight": 1.0}, {"source": "index", "target": "index_statici18nprovider", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L28", "weight": 1.0}, {"source": "index_statici18nprovider", "target": "index_statici18nprovider_get", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L29", "weight": 1.0}, {"source": "index_statici18nprovider", "target": "index_statici18nprovider_issupported", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L33", "weight": 1.0}, {"source": "index_statici18nprovider", "target": "index_statici18nprovider_getsupportedlocales", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L37", "weight": 1.0}, {"source": "index", "target": "index_seti18nprovider", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L50", "weight": 1.0}, {"source": "index", "target": "index_geti18nprovider", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L55", "weight": 1.0}, {"source": "index", "target": "index_resolvelocale", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L68", "weight": 1.0}, {"source": "index", "target": "index_normalizediscordlocale", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L88", "weight": 1.0}, {"source": "index", "target": "index_t", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L109", "weight": 1.0}, {"source": "index", "target": "index_getnestedvalue", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/index.ts", "source_location": "L134", "weight": 1.0}, {"source": "index_statici18nprovider_get", "target": "index_getnestedvalue", "relation": "calls", "confidence": "INFERRED", "source_file": "src/i18n/index.ts", "source_location": "L30", "weight": 0.8}, {"source": "index_resolvelocale", "target": "index_normalizediscordlocale", "relation": "calls", "confidence": "INFERRED", "source_file": "src/i18n/index.ts", "source_location": "L72", "weight": 0.8}, {"source": "index_resolvelocale", "target": "index_statici18nprovider_issupported", "relation": "calls", "confidence": "INFERRED", "source_file": "src/i18n/index.ts", "source_location": "L76", "weight": 0.8}, {"source": "index_t", "target": "index_statici18nprovider_get", "relation": "calls", "confidence": "INFERRED", "source_file": "src/i18n/index.ts", "source_location": "L115", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "env", "label": "env.ts", "file_type": "code", "source_file": "src/config/env.ts", "source_location": "L1"}, {"id": "env_generateinstanceid", "label": "generateInstanceId()", "file_type": "code", "source_file": "src/config/env.ts", "source_location": "L8"}], "edges": [{"source": "env", "target": "dotenv", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/config/env.ts", "source_location": "L1", "weight": 1.0}, {"source": "env", "target": "os", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/config/env.ts", "source_location": "L2", "weight": 1.0}, {"source": "env", "target": "path", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/config/env.ts", "source_location": "L3", "weight": 1.0}, {"source": "env", "target": "env_generateinstanceid", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/config/env.ts", "source_location": "L8", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "config", "label": "config.ts", "file_type": "code", "source_file": "src/commands/config.ts", "source_location": "L1"}, {"id": "config_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/config.ts", "source_location": "L66"}], "edges": [{"source": "config", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/config.ts", "source_location": "L1", "weight": 1.0}, {"source": "config", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/config.ts", "source_location": "L8", "weight": 1.0}, {"source": "config", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/config.ts", "source_location": "L9", "weight": 1.0}, {"source": "config", "target": "config_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/config.ts", "source_location": "L66", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "inviteservice_test", "label": "InviteService.test.ts", "file_type": "code", "source_file": "tests/services/InviteService.test.ts", "source_location": "L1"}], "edges": [{"source": "inviteservice_test", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/InviteService.test.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "i18n System", "label": "i18n \uc2dc\uc2a4\ud15c", "file_type": "concept", "source_file": "Docs/Rules/i18n_guidelines.md"}, {"id": "TranslationSchema", "label": "TranslationSchema", "file_type": "interface", "source_file": "Docs/Rules/i18n_guidelines.md"}, {"id": "src/i18n/locales/en.ts", "label": "\uc601\uc5b4 \ubc88\uc5ed \ub370\uc774\ud130", "file_type": "module", "source_file": "Docs/Rules/i18n_guidelines.md"}, {"id": "src/i18n/locales/ko.ts", "label": "\ud55c\uad6d\uc5b4 \ubc88\uc5ed \ub370\uc774\ud130", "file_type": "module", "source_file": "Docs/Rules/i18n_guidelines.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "mimicservice", "label": "MimicService.ts", "file_type": "code", "source_file": "src/services/MimicService.ts", "source_location": "L1"}, {"id": "mimicservice_mimicservice", "label": "MimicService", "file_type": "code", "source_file": "src/services/MimicService.ts", "source_location": "L5"}, {"id": "mimicservice_mimicservice_handlemessage", "label": ".handleMessage()", "file_type": "code", "source_file": "src/services/MimicService.ts", "source_location": "L6"}], "edges": [{"source": "mimicservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/MimicService.ts", "source_location": "L1", "weight": 1.0}, {"source": "mimicservice", "target": "webhookservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/MimicService.ts", "source_location": "L2", "weight": 1.0}, {"source": "mimicservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/MimicService.ts", "source_location": "L3", "weight": 1.0}, {"source": "mimicservice", "target": "mimicservice_mimicservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/MimicService.ts", "source_location": "L5", "weight": 1.0}, {"source": "mimicservice_mimicservice", "target": "mimicservice_mimicservice_handlemessage", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/MimicService.ts", "source_location": "L6", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "ready", "label": "ready.ts", "file_type": "code", "source_file": "src/events/ready.ts", "source_location": "L1"}, {"id": "ready_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/ready.ts", "source_location": "L14"}], "edges": [{"source": "ready", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L1", "weight": 1.0}, {"source": "ready", "target": "kordclient", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L2", "weight": 1.0}, {"source": "ready", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L3", "weight": 1.0}, {"source": "ready", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L4", "weight": 1.0}, {"source": "ready", "target": "voiceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L5", "weight": 1.0}, {"source": "ready", "target": "presenceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L6", "weight": 1.0}, {"source": "ready", "target": "eventservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L7", "weight": 1.0}, {"source": "ready", "target": "auditlogservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L8", "weight": 1.0}, {"source": "ready", "target": "env", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L9", "weight": 1.0}, {"source": "ready", "target": "ready_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/ready.ts", "source_location": "L14", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "voice", "label": "voice.ts", "file_type": "code", "source_file": "src/commands/voice.ts", "source_location": "L1"}, {"id": "voice_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/voice.ts", "source_location": "L79"}], "edges": [{"source": "voice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/voice.ts", "source_location": "L1", "weight": 1.0}, {"source": "voice", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/voice.ts", "source_location": "L9", "weight": 1.0}, {"source": "voice", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/voice.ts", "source_location": "L10", "weight": 1.0}, {"source": "voice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/voice.ts", "source_location": "L11", "weight": 1.0}, {"source": "voice", "target": "voice_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/voice.ts", "source_location": "L79", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "presenceservice", "label": "PresenceService.ts", "file_type": "code", "source_file": "src/services/PresenceService.ts", "source_location": "L1"}, {"id": "presenceservice_presenceservice", "label": "PresenceService", "file_type": "code", "source_file": "src/services/PresenceService.ts", "source_location": "L9"}, {"id": "presenceservice_presenceservice_startactivepresence", "label": ".startActivePresence()", "file_type": "code", "source_file": "src/services/PresenceService.ts", "source_location": "L28"}, {"id": "presenceservice_presenceservice_updatepresence", "label": ".updatePresence()", "file_type": "code", "source_file": "src/services/PresenceService.ts", "source_location": "L54"}, {"id": "presenceservice_presenceservice_stoprotation", "label": ".stopRotation()", "file_type": "code", "source_file": "src/services/PresenceService.ts", "source_location": "L74"}], "edges": [{"source": "presenceservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L1", "weight": 1.0}, {"source": "presenceservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L2", "weight": 1.0}, {"source": "presenceservice", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L3", "weight": 1.0}, {"source": "presenceservice", "target": "presenceservice_presenceservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L9", "weight": 1.0}, {"source": "presenceservice_presenceservice", "target": "presenceservice_presenceservice_startactivepresence", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L28", "weight": 1.0}, {"source": "presenceservice_presenceservice", "target": "presenceservice_presenceservice_updatepresence", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L54", "weight": 1.0}, {"source": "presenceservice_presenceservice", "target": "presenceservice_presenceservice_stoprotation", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/PresenceService.ts", "source_location": "L74", "weight": 1.0}, {"source": "presenceservice_presenceservice_startactivepresence", "target": "presenceservice_presenceservice_updatepresence", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/PresenceService.ts", "source_location": "L34", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "commandloader", "label": "CommandLoader.ts", "file_type": "code", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L1"}, {"id": "commandloader_loadcommands", "label": "loadCommands()", "file_type": "code", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L6"}], "edges": [{"source": "commandloader", "target": "kordclient", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L1", "weight": 1.0}, {"source": "commandloader", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L2", "weight": 1.0}, {"source": "commandloader", "target": "fs", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L3", "weight": 1.0}, {"source": "commandloader", "target": "path", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L4", "weight": 1.0}, {"source": "commandloader", "target": "commandloader_loadcommands", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/handlers/CommandLoader.ts", "source_location": "L6", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "setup", "label": "setup.ts", "file_type": "code", "source_file": "src/commands/setup.ts", "source_location": "L1"}, {"id": "setup_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/setup.ts", "source_location": "L18"}], "edges": [{"source": "setup", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/setup.ts", "source_location": "L1", "weight": 1.0}, {"source": "setup", "target": "setupwizardrenderer", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/setup.ts", "source_location": "L6", "weight": 1.0}, {"source": "setup", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/setup.ts", "source_location": "L7", "weight": 1.0}, {"source": "setup", "target": "setup_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/setup.ts", "source_location": "L18", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "localehelper", "label": "localeHelper.ts", "file_type": "code", "source_file": "src/i18n/localeHelper.ts", "source_location": "L1"}, {"id": "localehelper_getinteractionlocale", "label": "getInteractionLocale()", "file_type": "code", "source_file": "src/i18n/localeHelper.ts", "source_location": "L21"}, {"id": "localehelper_getcontextlocale", "label": "getContextLocale()", "file_type": "code", "source_file": "src/i18n/localeHelper.ts", "source_location": "L55"}], "edges": [{"source": "localehelper", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/localeHelper.ts", "source_location": "L8", "weight": 1.0}, {"source": "localehelper", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/localeHelper.ts", "source_location": "L9", "weight": 1.0}, {"source": "localehelper", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/localeHelper.ts", "source_location": "L10", "weight": 1.0}, {"source": "localehelper", "target": "localehelper_getinteractionlocale", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/localeHelper.ts", "source_location": "L21", "weight": 1.0}, {"source": "localehelper", "target": "localehelper_getcontextlocale", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/i18n/localeHelper.ts", "source_location": "L55", "weight": 1.0}]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "errorhandler", "label": "errorHandler.ts", "file_type": "code", "source_file": "src/utils/errorHandler.ts", "source_location": "L1"}, {"id": "errorhandler_handleglobalexceptions", "label": "handleGlobalExceptions()", "file_type": "code", "source_file": "src/utils/errorHandler.ts", "source_location": "L3"}], "edges": [{"source": "errorhandler", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/utils/errorHandler.ts", "source_location": "L1", "weight": 1.0}, {"source": "errorhandler", "target": "errorhandler_handleglobalexceptions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/utils/errorHandler.ts", "source_location": "L3", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "music", "label": "music.ts", "file_type": "code", "source_file": "src/commands/music.ts", "source_location": "L1"}, {"id": "music_builderrormessage", "label": "buildErrorMessage()", "file_type": "code", "source_file": "src/commands/music.ts", "source_location": "L6"}, {"id": "music_respond", "label": "respond()", "file_type": "code", "source_file": "src/commands/music.ts", "source_location": "L14"}, {"id": "music_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/music.ts", "source_location": "L130"}], "edges": [{"source": "music", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L1", "weight": 1.0}, {"source": "music", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L2", "weight": 1.0}, {"source": "music", "target": "musicservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L3", "weight": 1.0}, {"source": "music", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L4", "weight": 1.0}, {"source": "music", "target": "music_builderrormessage", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L6", "weight": 1.0}, {"source": "music", "target": "music_respond", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L14", "weight": 1.0}, {"source": "music", "target": "music_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/music.ts", "source_location": "L130", "weight": 1.0}, {"source": "music_execute", "target": "music_builderrormessage", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/music.ts", "source_location": "L140", "weight": 0.8}, {"source": "music_execute", "target": "music_respond", "relation": "calls", "confidence": "INFERRED", "source_file": "src/commands/music.ts", "source_location": "L377", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "messagecreate", "label": "messageCreate.ts", "file_type": "code", "source_file": "src/events/messageCreate.ts", "source_location": "L1"}, {"id": "messagecreate_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/messageCreate.ts", "source_location": "L10"}], "edges": [{"source": "messagecreate", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L1", "weight": 1.0}, {"source": "messagecreate", "target": "mimicservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L2", "weight": 1.0}, {"source": "messagecreate", "target": "bigemojiservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L3", "weight": 1.0}, {"source": "messagecreate", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L4", "weight": 1.0}, {"source": "messagecreate", "target": "activitytrackerservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L5", "weight": 1.0}, {"source": "messagecreate", "target": "messagecreate_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/messageCreate.ts", "source_location": "L10", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "webhookservice", "label": "WebhookService.ts", "file_type": "code", "source_file": "src/services/WebhookService.ts", "source_location": "L1"}, {"id": "webhookservice_webhookservice", "label": "WebhookService", "file_type": "code", "source_file": "src/services/WebhookService.ts", "source_location": "L4"}, {"id": "webhookservice_webhookservice_getwebhookclient", "label": ".getWebhookClient()", "file_type": "code", "source_file": "src/services/WebhookService.ts", "source_location": "L13"}], "edges": [{"source": "webhookservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/WebhookService.ts", "source_location": "L1", "weight": 1.0}, {"source": "webhookservice", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/WebhookService.ts", "source_location": "L2", "weight": 1.0}, {"source": "webhookservice", "target": "webhookservice_webhookservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/WebhookService.ts", "source_location": "L4", "weight": 1.0}, {"source": "webhookservice_webhookservice", "target": "webhookservice_webhookservice_getwebhookclient", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/WebhookService.ts", "source_location": "L13", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "en", "label": "en.ts", "file_type": "code", "source_file": "src/i18n/locales/en.ts", "source_location": "L1"}], "edges": [{"source": "en", "target": "types", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/i18n/locales/en.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "errorreporter", "label": "ErrorReporter.ts", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L1"}, {"id": "errorreporter_errorreporter", "label": "ErrorReporter", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L38"}, {"id": "errorreporter_errorreporter_report", "label": ".report()", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L43"}, {"id": "errorreporter_errorreporter_wrap", "label": ".wrap()", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L73"}, {"id": "errorreporter_errorreporter_buildembed", "label": ".buildEmbed()", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L107"}, {"id": "errorreporter_witherrorhandler", "label": "withErrorHandler()", "file_type": "code", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L136"}], "edges": [{"source": "errorreporter", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L1", "weight": 1.0}, {"source": "errorreporter", "target": "boterror", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L8", "weight": 1.0}, {"source": "errorreporter", "target": "errorcodes", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L9", "weight": 1.0}, {"source": "errorreporter", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L10", "weight": 1.0}, {"source": "errorreporter", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L11", "weight": 1.0}, {"source": "errorreporter", "target": "errorreporter_errorreporter", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L38", "weight": 1.0}, {"source": "errorreporter_errorreporter", "target": "errorreporter_errorreporter_report", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L43", "weight": 1.0}, {"source": "errorreporter_errorreporter", "target": "errorreporter_errorreporter_wrap", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L73", "weight": 1.0}, {"source": "errorreporter_errorreporter", "target": "errorreporter_errorreporter_buildembed", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L107", "weight": 1.0}, {"source": "errorreporter", "target": "errorreporter_witherrorhandler", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L136", "weight": 1.0}, {"source": "errorreporter_errorreporter_report", "target": "errorreporter_errorreporter_buildembed", "relation": "calls", "confidence": "INFERRED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L55", "weight": 0.8}, {"source": "errorreporter_witherrorhandler", "target": "errorreporter_errorreporter_wrap", "relation": "calls", "confidence": "INFERRED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L144", "weight": 0.8}, {"source": "errorreporter_witherrorhandler", "target": "errorreporter_errorreporter_report", "relation": "calls", "confidence": "INFERRED", "source_file": "src/errors/ErrorReporter.ts", "source_location": "L145", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "fishing", "label": "fishing.ts", "file_type": "code", "source_file": "src/commands/fishing.ts", "source_location": "L1"}, {"id": "fishing_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/fishing.ts", "source_location": "L83"}], "edges": [{"source": "fishing", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/fishing.ts", "source_location": "L1", "weight": 1.0}, {"source": "fishing", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/fishing.ts", "source_location": "L7", "weight": 1.0}, {"source": "fishing", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/fishing.ts", "source_location": "L8", "weight": 1.0}, {"source": "fishing", "target": "fishingservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/fishing.ts", "source_location": "L9", "weight": 1.0}, {"source": "fishing", "target": "fishing_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/fishing.ts", "source_location": "L83", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "setupwizardhandler", "label": "setupWizardHandler.ts", "file_type": "code", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L1"}, {"id": "setupwizardhandler_handlesetupwizardinteraction", "label": "handleSetupWizardInteraction()", "file_type": "code", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L7"}], "edges": [{"source": "setupwizardhandler", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L1", "weight": 1.0}, {"source": "setupwizardhandler", "target": "setupwizardrenderer", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L2", "weight": 1.0}, {"source": "setupwizardhandler", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L3", "weight": 1.0}, {"source": "setupwizardhandler", "target": "errorcodes", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L4", "weight": 1.0}, {"source": "setupwizardhandler", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L5", "weight": 1.0}, {"source": "setupwizardhandler", "target": "setupwizardhandler_handlesetupwizardinteraction", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/interactions/handlers/setupWizardHandler.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "eventloader", "label": "EventLoader.ts", "file_type": "code", "source_file": "src/handlers/EventLoader.ts", "source_location": "L1"}, {"id": "eventloader_loadevents", "label": "loadEvents()", "file_type": "code", "source_file": "src/handlers/EventLoader.ts", "source_location": "L6"}], "edges": [{"source": "eventloader", "target": "kordclient", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/EventLoader.ts", "source_location": "L1", "weight": 1.0}, {"source": "eventloader", "target": "logger", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/EventLoader.ts", "source_location": "L2", "weight": 1.0}, {"source": "eventloader", "target": "fs", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/EventLoader.ts", "source_location": "L3", "weight": 1.0}, {"source": "eventloader", "target": "path", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/handlers/EventLoader.ts", "source_location": "L4", "weight": 1.0}, {"source": "eventloader", "target": "eventloader_loadevents", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/handlers/EventLoader.ts", "source_location": "L6", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "setupwizardrenderer", "label": "SetupWizardRenderer.ts", "file_type": "code", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L1"}, {"id": "setupwizardrenderer_setupwizardrenderer", "label": "SetupWizardRenderer", "file_type": "code", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L17"}, {"id": "setupwizardrenderer_setupwizardrenderer_renderstep", "label": ".renderStep()", "file_type": "code", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L18"}], "edges": [{"source": "setupwizardrenderer", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L1", "weight": 1.0}, {"source": "setupwizardrenderer", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L13", "weight": 1.0}, {"source": "setupwizardrenderer", "target": "permissionauditservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L14", "weight": 1.0}, {"source": "setupwizardrenderer", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L15", "weight": 1.0}, {"source": "setupwizardrenderer", "target": "setupwizardrenderer_setupwizardrenderer", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L17", "weight": 1.0}, {"source": "setupwizardrenderer_setupwizardrenderer", "target": "setupwizardrenderer_setupwizardrenderer_renderstep", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/SetupWizardRenderer.ts", "source_location": "L18", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "fishingservice_test", "label": "FishingService.test.ts", "file_type": "code", "source_file": "tests/services/FishingService.test.ts", "source_location": "L1"}], "edges": [{"source": "fishingservice_test", "target": "fishingservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/services/FishingService.test.ts", "source_location": "L1", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "FishingCollectionEntry", "label": "Fishing Collection Entry", "file_type": "document", "source_file": "Docs/WorkDone/2026-04-07_Fishing_Size_Ranking_Implementation.md"}, {"id": "/fishing ranking", "label": "/fishing ranking command", "file_type": "document", "source_file": "Docs/WorkDone/2026-04-07_Fishing_Size_Ranking_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "PermissionAuditService", "label": "Permission Audit Service", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Permission_Audit_Implementation.md"}, {"id": "/audit-permissions", "label": "/audit-permissions command", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Permission_Audit_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "guildmemberadd", "label": "guildMemberAdd.ts", "file_type": "code", "source_file": "src/events/guildMemberAdd.ts", "source_location": "L1"}, {"id": "guildmemberadd_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/guildMemberAdd.ts", "source_location": "L7"}], "edges": [{"source": "guildmemberadd", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildMemberAdd.ts", "source_location": "L1", "weight": 1.0}, {"source": "guildmemberadd", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildMemberAdd.ts", "source_location": "L2", "weight": 1.0}, {"source": "guildmemberadd", "target": "guildmemberadd_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/guildMemberAdd.ts", "source_location": "L7", "weight": 1.0}]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "errorreporter_test", "label": "ErrorReporter.test.ts", "file_type": "code", "source_file": "tests/errors/ErrorReporter.test.ts", "source_location": "L1"}], "edges": [{"source": "errorreporter_test", "target": "boterror", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/errors/ErrorReporter.test.ts", "source_location": "L1", "weight": 1.0}, {"source": "errorreporter_test", "target": "errorcodes", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/errors/ErrorReporter.test.ts", "source_location": "L2", "weight": 1.0}, {"source": "errorreporter_test", "target": "errorreporter", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "tests/errors/ErrorReporter.test.ts", "source_location": "L3", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "guildcreate", "label": "guildCreate.ts", "file_type": "code", "source_file": "src/events/guildCreate.ts", "source_location": "L1"}, {"id": "guildcreate_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/guildCreate.ts", "source_location": "L8"}], "edges": [{"source": "guildcreate", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildCreate.ts", "source_location": "L1", "weight": 1.0}, {"source": "guildcreate", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildCreate.ts", "source_location": "L2", "weight": 1.0}, {"source": "guildcreate", "target": "presenceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildCreate.ts", "source_location": "L3", "weight": 1.0}, {"source": "guildcreate", "target": "guildcreate_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/guildCreate.ts", "source_location": "L8", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "voicestateupdate", "label": "voiceStateUpdate.ts", "file_type": "code", "source_file": "src/events/voiceStateUpdate.ts", "source_location": "L1"}, {"id": "voicestateupdate_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/voiceStateUpdate.ts", "source_location": "L7"}], "edges": [{"source": "voicestateupdate", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/voiceStateUpdate.ts", "source_location": "L1", "weight": 1.0}, {"source": "voicestateupdate", "target": "voiceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/voiceStateUpdate.ts", "source_location": "L2", "weight": 1.0}, {"source": "voicestateupdate", "target": "voicestateupdate_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/voiceStateUpdate.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "check_i18n_tests", "label": "check-i18n-tests.ts", "file_type": "code", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L1"}, {"id": "check_i18n_tests_walk", "label": "walk()", "file_type": "code", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L19"}, {"id": "check_i18n_tests_getfiles", "label": "getFiles()", "file_type": "code", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L43"}, {"id": "check_i18n_tests_checkfile", "label": "checkFile()", "file_type": "code", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L64"}], "edges": [{"source": "check_i18n_tests", "target": "fs", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L1", "weight": 1.0}, {"source": "check_i18n_tests", "target": "path", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L2", "weight": 1.0}, {"source": "check_i18n_tests", "target": "ko", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L3", "weight": 1.0}, {"source": "check_i18n_tests", "target": "en", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L4", "weight": 1.0}, {"source": "check_i18n_tests", "target": "check_i18n_tests_walk", "relation": "contains", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L19", "weight": 1.0}, {"source": "check_i18n_tests", "target": "check_i18n_tests_getfiles", "relation": "contains", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L43", "weight": 1.0}, {"source": "check_i18n_tests", "target": "check_i18n_tests_checkfile", "relation": "contains", "confidence": "EXTRACTED", "source_file": "scripts/check-i18n-tests.ts", "source_location": "L64", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "invitecreate", "label": "inviteCreate.ts", "file_type": "code", "source_file": "src/events/inviteCreate.ts", "source_location": "L1"}, {"id": "invitecreate_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/inviteCreate.ts", "source_location": "L7"}], "edges": [{"source": "invitecreate", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/inviteCreate.ts", "source_location": "L1", "weight": 1.0}, {"source": "invitecreate", "target": "inviteservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/inviteCreate.ts", "source_location": "L2", "weight": 1.0}, {"source": "invitecreate", "target": "invitecreate_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/inviteCreate.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "PresenceService", "label": "Presence Service", "file_type": "document", "source_file": "Docs/WorkDone/2026-03-27_Presence_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "prisma_config", "label": "prisma.config.ts", "file_type": "code", "source_file": "prisma.config.ts", "source_location": "L1"}], "edges": [{"source": "prisma_config", "target": "node_path", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma.config.ts", "source_location": "L1", "weight": 1.0}, {"source": "prisma_config", "target": "config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma.config.ts", "source_location": "L2", "weight": 1.0}, {"source": "prisma_config", "target": "config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma.config.ts", "source_location": "L3", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "FishingProfile", "label": "Fishing Profile (User Stats)", "file_type": "document", "source_file": "Docs/WorkDone/2026-04-07_Fishing_MiniGame_Phase2_Implementation.md"}, {"id": "FishingService", "label": "Fishing Service", "file_type": "document", "source_file": "Docs/WorkDone/2026-04-07_Fishing_MiniGame_Phase2_Implementation.md"}, {"id": "/fishing status", "label": "/fishing status command", "file_type": "document", "source_file": "Docs/WorkDone/2026-04-07_Fishing_MiniGame_Phase2_Implementation.md"}], "edges": [], "hyperedges": []}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "guilddelete", "label": "guildDelete.ts", "file_type": "code", "source_file": "src/events/guildDelete.ts", "source_location": "L1"}, {"id": "guilddelete_execute", "label": "execute()", "file_type": "code", "source_file": "src/events/guildDelete.ts", "source_location": "L7"}], "edges": [{"source": "guilddelete", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildDelete.ts", "source_location": "L1", "weight": 1.0}, {"source": "guilddelete", "target": "presenceservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/events/guildDelete.ts", "source_location": "L2", "weight": 1.0}, {"source": "guilddelete", "target": "guilddelete_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/events/guildDelete.ts", "source_location": "L7", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "refine", "label": "refine.ts", "file_type": "code", "source_file": "src/commands/refine.ts", "source_location": "L1"}, {"id": "refine_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/refine.ts", "source_location": "L91"}], "edges": [{"source": "refine", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L1", "weight": 1.0}, {"source": "refine", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L11", "weight": 1.0}, {"source": "refine", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L12", "weight": 1.0}, {"source": "refine", "target": "refinementservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L13", "weight": 1.0}, {"source": "refine", "target": "feverservice", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L14", "weight": 1.0}, {"source": "refine", "target": "refine_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/refine.ts", "source_location": "L91", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "auditlogservice", "label": "AuditLogService.ts", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L1"}, {"id": "auditlogservice_auditlogservice", "label": "AuditLogService", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L23"}, {"id": "auditlogservice_auditlogservice_log", "label": ".log()", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L29"}, {"id": "auditlogservice_auditlogservice_setchannel", "label": ".setChannel()", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L71"}, {"id": "auditlogservice_auditlogservice_clearchannel", "label": ".clearChannel()", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L87"}, {"id": "auditlogservice_auditlogservice_getchannel", "label": ".getChannel()", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L96"}, {"id": "auditlogservice_auditlogservice_setfilter", "label": ".setFilter()", "file_type": "code", "source_file": "src/services/AuditLogService.ts", "source_location": "L107"}], "edges": [{"source": "auditlogservice", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L1", "weight": 1.0}, {"source": "auditlogservice", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L2", "weight": 1.0}, {"source": "auditlogservice", "target": "env", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L3", "weight": 1.0}, {"source": "auditlogservice", "target": "auditlogservice_auditlogservice", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L23", "weight": 1.0}, {"source": "auditlogservice_auditlogservice", "target": "auditlogservice_auditlogservice_log", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L29", "weight": 1.0}, {"source": "auditlogservice_auditlogservice", "target": "auditlogservice_auditlogservice_setchannel", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L71", "weight": 1.0}, {"source": "auditlogservice_auditlogservice", "target": "auditlogservice_auditlogservice_clearchannel", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L87", "weight": 1.0}, {"source": "auditlogservice_auditlogservice", "target": "auditlogservice_auditlogservice_getchannel", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L96", "weight": 1.0}, {"source": "auditlogservice_auditlogservice", "target": "auditlogservice_auditlogservice_setfilter", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/services/AuditLogService.ts", "source_location": "L107", "weight": 1.0}, {"source": "auditlogservice_auditlogservice_log", "target": "auditlogservice_auditlogservice_getchannel", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/AuditLogService.ts", "source_location": "L31", "weight": 0.8}, {"source": "auditlogservice_auditlogservice_setfilter", "target": "auditlogservice_auditlogservice_getchannel", "relation": "calls", "confidence": "INFERRED", "source_file": "src/services/AuditLogService.ts", "source_location": "L108", "weight": 0.8}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "language", "label": "language.ts", "file_type": "code", "source_file": "src/commands/language.ts", "source_location": "L1"}, {"id": "language_execute", "label": "execute()", "file_type": "code", "source_file": "src/commands/language.ts", "source_location": "L25"}], "edges": [{"source": "language", "target": "discord_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/language.ts", "source_location": "L1", "weight": 1.0}, {"source": "language", "target": "database", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/language.ts", "source_location": "L2", "weight": 1.0}, {"source": "language", "target": "i18n", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "src/commands/language.ts", "source_location": "L3", "weight": 1.0}, {"source": "language", "target": "language_execute", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/commands/language.ts", "source_location": "L25", "weight": 1.0}]}

View File

@ -0,0 +1 @@
{"nodes": [{"id": "YouTube Music Playback", "label": "YouTube \uc74c\uc545 \uc7ac\uc0dd \uae30\ub2a5", "file_type": "feature", "source_file": "Docs/WorkDone/2026-03-31_YouTube_Music_Playback_Phase2_Implementation.md"}, {"id": "MusicService", "label": "MusicService", "file_type": "service", "source_file": "Docs/WorkDone/2026-03-31_YouTube_Music_Playback_Phase2_Implementation.md"}, {"id": "Slash Command", "label": "Slash Command", "file_type": "feature", "source_file": "Docs/WorkDone/2026-03-31_YouTube_Music_Playback_Phase2_Implementation.md"}], "edges": [], "hyperedges": []}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"nodes": [{"id": "seed", "label": "seed.ts", "file_type": "code", "source_file": "prisma/seed.ts", "source_location": "L1"}, {"id": "seed_main", "label": "main()", "file_type": "code", "source_file": "prisma/seed.ts", "source_location": "L10"}], "edges": [{"source": "seed", "target": "pg", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma/seed.ts", "source_location": "L1", "weight": 1.0}, {"source": "seed", "target": "adapter_pg", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma/seed.ts", "source_location": "L2", "weight": 1.0}, {"source": "seed", "target": "client", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma/seed.ts", "source_location": "L3", "weight": 1.0}, {"source": "seed", "target": "config", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "prisma/seed.ts", "source_location": "L4", "weight": 1.0}, {"source": "seed", "target": "seed_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "prisma/seed.ts", "source_location": "L10", "weight": 1.0}]}

Some files were not shown because too many files have changed in this diff Show More