zzet/gortex. 저장소 하나를 통째로 읽어 모든 파일·심볼·호출·import·타입 관계를 '지식 그래프(knowledge graph)' 하나에 담고, 그것을 CLI · MCP 서버 · 웹 UI 세 가지 창구로 노출하는 코드 인텔리전스 엔진이다. Claude Code·Cursor·Codex 같은 AI 코딩 에이전트가 파일을 5~10번 읽던 일을 get_editing_context 한 번의 호출로 끝내 토큰을 약 94% 줄인다. 전부 메모리에서(in-memory), 외부 서비스 없이(100% 로컬), 단일 바이너리로 돈다. (저장소: zzet/gortex · 언어 Go 97.5% · tree-sitter 기반 25개 언어 파싱 · MCP 툴 40개 + 리소스 6개 · 라이선스/CI 포함 · ★ 급상승 중 — TrendShift 라이브 멘션)
"AI가 코드를 '한 파일씩 읽는' 대신, 미리 그려 둔 '지하철 노선도'를 보고 필요한 칸만 콕 집게 한다."
보통 AI 에이전트는 코드를 이해하려고 파일을 열고·읽고·grep하고를 수십 번 반복합니다. 매번 토큰(=돈)이 들고, 그래도 "이 함수를 누가 부르는지, 이 타입이 무슨 인터페이스를 구현하는지" 같은 관계는 잘 못 봅니다. Gortex는 미리 레포를 통째로 분석해 모든 심볼을 점(노드), 모든 관계를 선(엣지)으로 잇는 그래프를 메모리에 만들어 둡니다. 그러면 에이전트는 "함수 X 고치려는데 필요한 맥락 줘"라고 한 번만 물어보고, 딱 필요한 심볼·시그니처·호출자·피호출자만 받습니다. 파일 10개를 통째로 읽던 일이 1번의 정밀 질의로 바뀝니다.
좀 더 구체적으로, Gortex는 Go로 만든 명령줄 도구(CLI)이자 서버입니다. gortex init으로 한 프로젝트에 설정을 깔고, gortex serve로 켜 두면 ① 터미널에서 직접 질의(CLI), ② AI 에이전트가 표준 규격으로 호출(MCP 서버), ③ 브라우저에서 그래프 시각화(웹 UI) 세 가지를 동시에 쓸 수 있습니다. 핵심 자랑거리는 "한 번의 get_editing_context 호출이 파일 5~10개 읽기를 대체해 토큰을 약 94% 절감"한다는 것 — 즉 속도가 아니라 '토큰 경제'가 이 프로젝트의 진짜 상품입니다.
이 문서가 파고드는 건 사용법만이 아니라 그 안의 설계입니다 — "25개 언어를 어떻게 한 가지 그래프 모양으로 통일하나(tree-sitter)", "파일이 바뀔 때 전체를 다시 읽지 않고 어떻게 그래프만 살짝 고치나(증분 업데이트)", "왜 데이터베이스 없이 메모리에만 두는가". 코드 분석·그래프·에이전트 도구를 처음 공부하는 사람에게 실전 교본입니다.
"에이전트 코딩의 진짜 비용은 속도가 아니라 토큰이다. Gortex는 그 청구서를 공격한다."
Claude Code·Cursor·Codex 같은 에이전트는 코드베이스를 이해하려고 Read(파일 읽기)와 Grep(문자열 검색)을 끝없이 호출합니다. 함수 하나를 고치려 해도 "이게 어디 정의됐지 → 누가 부르지 → 이 타입은 뭐지"를 알아내려고 파일을 통째로 5~10개씩 맥락 창에 퍼 담습니다. 그 파일의 99%는 지금 작업과 무관한데도요. 토큰은 곧 비용이고, 맥락 창은 유한합니다. 쓸데없는 코드로 창이 차면 정작 중요한 정보가 밀려납니다.
파일 단위로 읽으면 필요한 함수 한 개를 위해 주변 수백 줄을 함께 싣습니다. 게다가 "이 함수를 누가 호출하는가" 같은 역방향 관계는 한 파일만 봐서는 절대 알 수 없어, 에이전트가 레포 전체를 grep하며 헤맵니다. 큰 리팩터링에서는 이 비용이 폭발합니다.
Gortex는 인덱싱 단계에서 레포 전체를 한 번 그래프로 만들어 둡니다. 이후 에이전트의 질문에는 심볼 단위로 답합니다 — get_symbol_source는 함수 한 개의 소스만(파일 통째 대비 80% 적은 토큰), smart_context는 "작업에 정말 필요한" 심볼·시그니처·호출 관계만 골라 한 번에 줍니다. 역방향 관계(누가 부르는가)도 그래프엔 화살표로 이미 들어 있어 즉답합니다.
"코드 그래프로 토큰 줄이기"는 2026년 들어 가장 붐비는 카테고리입니다(codebase-memory-mcp, codegraph, Understand-Anything 등). 그 속에서 Gortex가 내세우는 포인트는 분명합니다.
| 관점 | Gortex | 전형적인 "파일 읽기" 방식 (맨몸 에이전트) |
|---|---|---|
| 코드 이해 단위 | 심볼·관계(그래프) | 파일·텍스트 |
| 토큰 비용 | 질의당 최소 (≈ -94%) | 읽을 때마다 누적 |
| 역방향 질의 (누가 부르나) | 그래프 엣지로 즉답 | 레포 전체 grep |
| 저장 위치 | 메모리(in-memory), 외부 DB 없음 | 해당 없음 |
| 의존성 | 제로 — 단일 바이너리, 외부 서비스 0 | 해당 없음 |
| 언어 범위 | tree-sitter로 25개 언어 통일 | 모델의 일반 독해력에 의존 |
| 최신성 | watch 모드로 파일 변경 시 즉시 동기화 | 매번 새로 읽음 |
요약하면 Gortex의 셀링 포인트는 네 가지입니다. ① 메모리·제로 의존성(설치=바이너리 1개, DB·도커 불필요), ② 40개 MCP 툴로 단순 검색을 넘어 블래스트 반경(blast radius)·죽은 코드·순환 의존·커뮤니티 탐지까지 제공, ③ git 인식(변경 영향 분석, co-change 가드 규칙), ④ Claude Code/Kiro에 자동 통합(gortex init 한 번에 슬래시 명령·스킬·PreToolUse 훅까지 설치)입니다.
맨몸 에이전트 = 처음 온 도시에서 길마다 직접 걸어 보는 관광객. 매번 골목을 헤매고(grep), 막다른 길을 만나고, 같은 곳을 또 갑니다.
Gortex = 그 도시의 지하철 노선도를 손에 쥔 사람. "여기서 저기 가려면 2호선 → 환승 → 3호선"을 걷기 전에 압니다. 노선도(그래프)는 미리 한 번만 그리면 되고, 역이 새로 생기면(파일 변경) 그 부분만 노선도에 덧그립니다(watch 모드).
주의할 점도 짚겠습니다. README의 "≈94% 절감"은 개발자가 제시한 수치이고, 작업 종류·레포 크기에 따라 편차가 큽니다. 또 그래프 자체가 메모리를 먹고(큰 레포일수록 RAM 사용↑), 처음 인덱싱에는 시간이 듭니다. 그래도 방향성은 설득력 있습니다 — "파일을 통째로 싣는 대신 관계를 미리 계산해 둔다"는 발상은 에이전트 코딩이 커질수록 더 중요해지는 정공법이기 때문입니다.
"코드의 97.5%가 Go다. 하지만 진짜 재미는 'Go가 C(tree-sitter)와 손잡는 지점'에 있다."
Gortex는 화면에 보이는 웹 UI는 작고, 무게중심이 백엔드 코어에 쏠린 프로젝트입니다. GitHub 언어 통계도 Go 97.5% / JavaScript 1.7%로, 시각화는 곁가지이고 핵심은 "파싱 → 그래프 → 질의"의 엔진임을 보여 줍니다.
| 기술 | 역할 | 한 줄 설명 |
|---|---|---|
| Go 1.21+ | 전체 언어 | 단일 바이너리·동시성(고루틴)·빠른 시작. 인덱싱을 병렬로 돌리기 좋다. |
| tree-sitter (CGO) | 소스 파싱 | 25개 언어를 같은 방식으로 AST(구문 트리)로 만든다. C 라이브러리라 CGO(=Go에서 C 호출)가 필요 → 빌드에 C 컴파일러가 든다. |
| cobra | CLI 프레임워크 | gortex init/serve/index/query… 같은 하위 명령·플래그 체계를 만든다(kubectl·gh와 같은 계열). |
| fsnotify | 파일 감시 | OS의 파일 변경 이벤트를 받아 watch 모드를 구동. 바뀐 파일만 다시 파싱한다. |
| 자체 그래프 | 지식 저장소 | 노드/엣지 + 빠른 조회용 인접 인덱스를 메모리에 둔 자료구조. 외부 그래프 DB(Neo4j 등) 미사용. |
| 창구 | 대상 | 설명 |
|---|---|---|
| MCP 서버 | AI 에이전트 | 핵심 상품. 40개 툴 + 6개 리소스를 표준 규격(MCP)으로 노출. 보통 stdio(JSON-RPC)로 Claude Code·Kiro에 물린다. |
| CLI | 사람(터미널) | gortex query symbol … 처럼 사람이 직접 그래프를 질의. --format text|json|dot 지원(DOT은 Graphviz 그림용). |
| 웹 서버 + SSE | 브라우저 | localhost:8765에 그래프 시각화. SSE(서버 보냄 이벤트)로 watch 중 실시간 갱신. |
| TUI | 터미널 UI | 터미널 안에서 대화형으로 탐색하는 화면(internal/tui). |
| 기술 | 역할 |
|---|---|
| Sigma.js | WebGL로 대형 그래프를 부드럽게 그리는 라이브러리. 노드 수천 개도 60fps로 렌더. |
| ForceAtlas2 | 힘 기반 배치 알고리즘 — 연결 많은 노드는 끌어당기고 먼 건 밀어내 자연스러운 군집 모양을 만든다. |
| 노드 크기 = 중요도 | 연결 수(degree)에 비례해 노드를 키워, 한눈에 '핵심 코드'가 도드라진다. |
| SSE 수신 | watch 모드일 때 그래프가 바뀌면 새로고침 없이 화면이 갱신. |
| 항목 | 내용 |
|---|---|
| 배포 형태 | 단일 정적 바이너리 — 런타임 의존성 0, 외부 서비스 0. |
| goreleaser | git 태그에서 크로스 플랫폼(여러 OS/CPU) 바이너리를 자동 빌드·릴리스. |
| Makefile | make build/test/bench/lint/fmt/install 한 줄 명령 모음. 테스트는 -race(경쟁 상태 탐지) 포함. |
| 품질 | golangci-lint, gofmt, GitHub Actions CI, Go Report Card 배지 — 오픈소스 위생이 잘 갖춰짐. |
| 에이전트 자동설정 | gortex init이 .mcp.json(Claude Code)·.kiro/(Kiro)·~/.claude/skills/·CLAUDE.md 블록·PreToolUse 훅을 한 번에 깐다. |
"걷는 길은 다섯 정거장 — 파일을 걷고(walk) → 뜯고(extract) → 잇고(resolve) → 질문받고(query) → 바뀌면 덧댄다(watch)."
README의 표현을 빌리면 데이터 흐름은 다섯 단계입니다. ① Indexer가 디렉터리를 걸으며 파일을 언어별 추출기로 분배 → ② tree-sitter 추출기가 파일에서 노드(파일·함수·타입 등)와 엣지(호출·import·정의 등)를 뽑음 → ③ Resolver가 파일을 넘나드는 참조를 연결하고 인터페이스 구현 관계를 추론 → ④ Query Engine이 살아 있는 그래프 위에서 traversal(따라가기) 질의에 답 → ⑤ Watcher가 변경을 감지해 바뀐 파일만 골라 그래프를 외과수술하듯 패치(파일별 디바운스).
가장 핵심적인 발상입니다. 코드의 참조는 한 파일만 봐서는 못 풉니다. foo()를 호출하는 줄을 봐도, 그 foo가 어느 파일·어느 패키지의 것인지는 레포 전체를 봐야 알죠. 그래서 Gortex는 일을 둘로 나눕니다.
| 단계 | 하는 일 | 비유 |
|---|---|---|
| Extract (추출) | 파일 하나만 보고 "여기 함수 foo 정의됨", "여기서 bar 호출함" 같은 국소 사실만 기록. 빠르고 병렬 가능. | 책마다 색인 카드를 따로 만든다 |
| Resolve (해석) | 모든 카드를 모아 "이 bar 호출 = 3번 파일의 bar 정의"로 화살표를 잇고, 인터페이스 구현을 추론. | 카드들을 한 책상에 펴고 상호참조를 연결한다 |
퍼즐 1000조각을 맞출 때, 먼저 조각마다 색·모서리를 분류(추출)하고 그다음 서로 맞는 조각을 잇는(해석) 것과 같습니다. 처음부터 아무 두 조각이나 비교하면 느리지만, 분류를 마친 뒤 연결하면 훨씬 빠릅니다. 추출은 파일별로 병렬이 되고(고루틴), 해석은 한 번에 모아 처리합니다.
Indexer는 파일 확장자를 보고 해당 언어 추출기에 일을 넘깁니다(Go면 Go 추출기, Python이면 Python 추출기…). 추출기는 언어마다 다르지만 출력 모양은 똑같습니다 — 전부 같은 노드/엣지 스키마로 떨어집니다. 그래서 다운스트림(그래프·질의·시각화)은 언어를 신경 쓸 필요가 없습니다. 새 언어를 추가하려면 그 언어용 추출기 하나만 끼워 넣으면 됩니다(플러그인 같은 구조).
file, function, method, type, interface, variable, import, package.calls(호출), imports, defines(정의), implements(구현), extends(상속), references(참조), member_of(소속), instantiates(인스턴스화). 모든 언어가 이 통일된 어휘로 환원됩니다.Go·TypeScript·Rust 등은 구조적 타이핑을 씁니다. 즉 타입이 "나 이 인터페이스 구현해요"라고 선언하지 않아도, 인터페이스가 요구하는 메서드를 전부 갖췄으면 자동으로 구현체로 인정됩니다. Gortex의 Resolver는 이 관계를 직접 계산해 implements 엣지를 만들어 줍니다. 덕분에 "이 인터페이스를 실제로 구현하는 타입이 누구냐(find_implementations)"를 즉답할 수 있습니다.
오리(Duck) 타이핑: "꽥꽥 울고 뒤뚱뒤뚱 걸으면 오리로 친다." 어떤 타입이 인터페이스가 시킨 메서드를 다 갖췄으면, 도장 안 받아도 "구현했네"라고 그래프에 화살표를 그어 줍니다.
코드를 한 줄 고칠 때마다 레포 전체를 다시 읽으면 너무 느립니다. Watcher는 fsnotify로 어떤 파일이 바뀌었는지만 받아, 그 파일을 다시 파싱하고 관련된 노드·엣지만 떼었다 붙입니다. 여러 변경이 몰리면 디바운스(debounce)로 묶어 한 번에 처리합니다. 그래서 watch 모드에서 그래프는 항상 코드와 거의 실시간으로 일치합니다 — 에이전트가 늘 최신 지도를 봅니다.
한 파일을 고치면 그 파일만 바뀌는 게 아닙니다. 그 파일의 함수를 다른 파일이 호출하고 있었다면 그 엣지들도 손봐야 하죠. "어디까지 다시 계산할지"를 잘못 잡으면 그래프가 코드와 어긋납니다(stale). Gortex가 index_health로 parse 실패·stale 파일을 점검하는 툴을 따로 둔 이유입니다.
마지막 통찰은 출력의 모양입니다. 같은 그래프라도 사람에겐 표·그림이 좋지만, 에이전트에겐 토큰이 적은 게 최선입니다. 그래서 Gortex의 MCP 툴은 "딱 필요한 것만" 돌려주도록 설계됐습니다 — get_symbol_signature(본문 빼고 시그니처만), get_symbol_source(함수 1개 소스만), smart_context(작업에 필요한 최소 묶음). 거기에 PreToolUse 훅으로 에이전트가 Read/Grep을 부르기 직전 그래프 맥락을 자동 주입해, 사람이 따로 시키지 않아도 토큰을 아낍니다.
dependents(나에게 의존하는 것들) 엣지를 역방향으로 따라가 구합니다. Gortex는 여기에 위험도 등급과 "영향받는 실행 흐름(process)"까지 붙여(explain_change_impact) 리팩터링 전에 위험을 미리 보여 줍니다.여기에 메모리 최적화도 곁들여집니다. 큰 레포는 같은 경로·심볼 문자열이 수백만 번 반복되는데, internal/intern(문자열 인터닝)으로 같은 문자열을 하나만 저장해 공유하여 RAM을 아낍니다. "메모리에 다 올린다"는 과감한 선택을 떠받치는 디테일입니다.
"전형적인 Go 레이아웃(cmd · internal · pkg) 위에, internal/이 70여 개 패키지로 잘게 쪼개져 있다."
main 진입점, internal/은 이 모듈 안에서만 쓸 수 있는 비공개 코드(Go 컴파일러가 외부 import를 막아 줌), pkg/는 남이 가져다 써도 되는 공개 API입니다. Gortex가 무게를 internal/에 둔 건 "엔진 내부는 자유롭게 바꾸되, 외부 약속(pkg/gortex)은 작게 유지"하려는 의도입니다.패키지가 많아 보이지만, 역할로 묶으면 "엔진의 부품 목록"이 또렷해집니다. (대표적인 것만 추렸습니다.)
| 묶음 | 대표 패키지 | 하는 일 |
|---|---|---|
| 파싱·인덱싱 | indexer, parser, resolver, intern, pathkey, excludes | 파일을 걷고 → tree-sitter로 뜯고 → 참조를 잇고, 문자열 인터닝으로 메모리 절약 |
| 그래프·질의 | graph, query, search, callpath, dataflow, reach, astquery, cfg, semantic | 그래프 본체 + 검색·호출경로·데이터흐름·도달성·제어흐름(CFG) 질의 |
| 코드 분석 | analysis, analyzer, churn, clones, cochange, contracts, entrypoints, coverage, todos | 커뮤니티·핫스팟·순환·죽은코드·복제·변경빈도·계약·진입점·커버리지·TODO 추출 |
| 인터페이스 | mcp, server, serverstack, daemon, tui | 에이전트(MCP)·브라우저(웹)·터미널(TUI)·상주 데몬 등 바깥과 만나는 창구 |
| 에이전트 통합 | hooks, skills, claudemd, modelhint, llm, agents, elide, tokens, savings | PreToolUse 훅·스킬 설치·CLAUDE.md 생성·토큰 계산/절감 추적·LLM 연동 |
| git 인식 | gitcmd, githooks, blame, codeowners | git 명령·훅·blame(작성자)·CODEOWNERS 연동으로 변경/소유 정보 결합 |
| 부가·운영 | config, persistence, telemetry, version, platform, releases, wiki, docs, licenses | 설정·저장·텔레메트리·버전·플랫폼 추상화·릴리스/위키/문서 생성 |
자동차 공장으로 보면, 파싱·인덱싱은 원자재를 부품으로 가공하는 라인, 그래프·질의는 부품 창고와 검색대, 분석은 품질검사실, 인터페이스는 출고 도크(에이전트/브라우저/터미널로 내보냄)입니다. internal/이 잘게 쪼개진 건 부품마다 따로 테스트·교체하기 위해서입니다(internal/fixtures에 테스트용 표본 코드가 있는 이유).
pkg/gortex/api.go(약 3KB)는 공개 API입니다. 즉 Gortex를 CLI/서버로만이 아니라 다른 Go 프로그램이 import해서 코드 인텔리전스 기능을 내장할 수 있게 얇은 진입 함수를 제공합니다. 옆에 api_test.go가 있어 공개 약속이 테스트로 고정돼 있습니다. "도구이자 라이브러리"라는 두 정체성을 동시에 노리는 설계입니다.
"Gortex 한 레포 안에 컴파일러 이론·그래프 알고리즘·시스템 프로그래밍·에이전트 도구설계가 다 들어 있다."
배울 것: 소스 코드를 텍스트가 아니라 구문 트리로 다루는 법. tree-sitter 문법이 어떻게 함수·타입 노드를 잡아내는지, 그리고 Go에서 C 라이브러리를 부르는 CGO의 빌드 제약(C 컴파일러 필요).
실습: Go에서 go-tree-sitter로 작은 소스 파일을 파싱해 함수 이름만 전부 출력해 보기. 그다음 "함수 호출"을 잡는 쿼리를 추가해 호출 목록을 뽑아 보기.
배울 것: 노드/엣지 스키마를 안정적인 ID로 설계하는 법(경로+심볼명 등), 그리고 빠른 조회를 위한 인접 인덱스(누가 누구를 호출하는지 양방향 맵). 정방향(calls)과 역방향(called by)을 둘 다 인덱싱하는 게 핵심.
실습: map[심볼ID][]엣지 두 개(정방향·역방향)로 미니 호출 그래프를 만들고, "함수 A를 바꾸면 영향받는 함수"를 역방향 BFS로 구해 보기(= 블래스트 반경의 축소판).
배울 것: Gortex가 실제로 쓰는 고전 알고리즘들 — Louvain(연결이 촘촘한 묶음=커뮤니티 찾기), Tarjan SCC(강한 연결 요소로 순환 의존 탐지), fan-in/fan-out으로 핫스팟(많이 얽힌 코드) 랭킹.
실습: 작은 의존 그래프에서 Tarjan 알고리즘으로 순환(cycle)을 찾아 보기. 그다음 각 노드의 들어오는/나가는 엣지 수를 세어 '핫스팟 Top 5'를 출력.
배울 것: 에이전트가 부를 툴을 어떻게 설계하면 토큰이 줄어드는가. "파일 전체" 대신 "심볼 1개", "전부" 대신 "작업에 필요한 최소"를 돌려주는 응답 설계. Gortex의 smart_context가 좋은 본보기.
실습: MCP SDK로 툴 1개짜리 서버를 만들어, "심볼 이름을 받으면 그 함수 소스만 돌려주는" get_symbol_source의 미니 버전을 구현하고 Claude Code에 물려 토큰 차이를 비교.
배울 것: fsnotify로 OS 파일 이벤트를 받고, 디바운스로 변경을 묶어, 바뀐 부분만 다시 계산하는 패턴. 캐시 무효화("어디까지 다시 만들까")가 왜 어려운지 체감.
실습: fsnotify로 폴더를 감시하다가 파일이 바뀌면 그 파일만 다시 파싱해 노드 수를 갱신하는 작은 데몬 만들기. 300ms 디바운스를 넣어 연속 저장을 한 번으로 묶기.
배울 것: cmd/internal/pkg 레이아웃, cobra로 하위 명령 만들기, -race 테스트, goreleaser로 크로스 플랫폼 단일 바이너리 배포까지 — "혼자서도 배포 가능한 도구"의 전형.
실습: cobra로 mytool index/query 두 명령을 만들고, goreleaser 설정을 추가해 깃 태그 한 번으로 Linux/macOS 바이너리가 나오게 해 보기.
배울 것: 이 레포 전체를 관통하는 사상. "모델에게 무엇을, 얼마나 보여 줄지가 성능과 비용을 좌우한다"는 관점. internal/elide(불필요한 부분 잘라내기)·tokens·savings가 그 실천입니다.
실습: 같은 작업을 (a) 파일 통째 읽기 (b) Gortex smart_context 두 방식으로 시키고, 입력 토큰 수와 결과 품질을 표로 비교해 보기.
"GPU·클라우드·DB 전부 필요 없다. 대신 '빌드에 C 컴파일러'와 '레포 크기만큼의 RAM'이 든다."
| 항목 | 요구사항 / 메모 |
|---|---|
| 언어/런타임 | Go 1.21+. 빌드만 하면 단일 바이너리라 런타임 의존성은 없음. |
| CGO (중요) | CGO 활성화 + C 컴파일러(gcc/clang) 필요. tree-sitter가 C 라이브러리라 빌드에 꼭 든다 — 순수 Go 크로스 컴파일이 까다로운 지점. |
| 외부 서비스 | 없음. 데이터베이스·벡터DB·클라우드 API 불필요. 그래프는 전부 메모리. |
| GPU | 불필요. 임베딩/LLM 호출은 선택적 통합이며 코어 동작엔 안 듦. |
| 메모리(RAM) | 레포 크기에 비례. 모든 노드/엣지를 메모리에 두므로 거대 모노레포는 RAM을 많이 쓴다(문자열 인터닝으로 완화). |
| 포트 | 웹 UI: localhost:8765. MCP 서버: 보통 stdio(JSON-RPC)로 에이전트와 직결. |
| OS | 크로스 플랫폼(goreleaser가 여러 OS/CPU 바이너리 생성). CGO 때문에 각 OS에 맞는 빌드 환경이 필요. |
CGO가 꺼져 있거나(CGO_ENABLED=0) C 컴파일러가 없으면 빌드가 실패합니다. README도 "requires CGO for tree-sitter C bindings"를 명시합니다. 도커 등 최소 이미지에서 빌드할 때 build-essential(또는 clang)을 먼저 깔아야 합니다.
"빌드해서 켜 보기 → 질의해 보기 → 에이전트에 물리기 → 엔진을 확장하기, 단계별로."
go build -o gortex ./cmd/gortex/로 빌드(C 컴파일러 준비) → gortex status --index /내/프로젝트로 통계 확인 → gortex serve --index /내/프로젝트 --watch로 띄우고 localhost:8765에서 그래프를 눈으로 본다.
목표: "내 코드가 점·선으로 어떻게 보이나"를 체감. 가장 큰(연결 많은) 노드가 무엇인지 찾아보기 = 핫스팟 직관.
gortex query symbol 함수이름으로 심볼을 찾고, gortex query callers/dependents로 호출자·블래스트 반경을 본다. --format dot으로 DOT을 뽑아 Graphviz로 PNG 렌더링.
목표: "이 함수를 누가 부르나", "이걸 바꾸면 어디가 영향받나"를 명령 한 줄로 답하는 경험. 정방향(calls)과 역방향(callers)의 차이를 몸으로 익히기.
gortex init으로 .mcp.json·CLAUDE.md·훅을 깐 뒤, 같은 리팩터링 작업을 (a) 맨몸과 (b) Gortex 연결 두 번 시켜 입력 토큰을 비교한다.
목표: smart_context/get_editing_context가 실제로 파일 읽기를 줄이는지 수치로 확인. README의 "≈94%" 주장을 내 레포에서 검증해 보기(편차가 클 수 있음).
internal/parser·추출기 구조를 읽고, 아주 단순한 언어(예: 간단한 DSL이나 설정 파일)용 추출기를 추가해 노드/엣지를 만들어 본다. internal/fixtures의 표본을 참고.
목표: "언어가 달라도 같은 그래프 스키마로 환원"하는 디스패치 구조를 손으로 체득. tree-sitter 문법 → 노드/엣지 매핑이 핵심.
내 미니 그래프 위에 Tarjan SCC로 순환 의존을 찾는 함수를, 또는 역방향 BFS로 블래스트 반경을 구하는 MCP 툴을 직접 작성한다. Gortex의 find_cycles·explain_change_impact가 정답지.
목표: 코드 인텔리전스의 "분석" 기능이 결국 고전 그래프 알고리즘임을 깨닫기. 위험도 등급까지 붙이면 실전급.
"Go 기초에서 출발해 컴파일러·그래프·에이전트 도구까지, Gortex를 길잡이 삼아."
| 주차 | 주제 | 핵심 학습 + Gortex 연결점 |
|---|---|---|
| 1주 | Go 기초 + 프로젝트 레이아웃 | 문법·고루틴·에러처리, cmd/internal/pkg 구조, cobra로 CLI 만들기 → cmd/gortex 읽기 |
| 2주 | 파싱 · AST · tree-sitter · CGO | 구문 트리 개념, tree-sitter로 함수/호출 추출, CGO 빌드 → internal/parser |
| 3주 | 그래프 모델링 + 순회 | 노드/엣지 스키마, 인접 인덱스, BFS/DFS로 호출 체인·도달성 → internal/graph·query·callpath·reach |
| 4주 | 그래프 알고리즘 | Louvain 커뮤니티, Tarjan SCC 순환, fan-in/out 핫스팟, 죽은 코드 → internal/analysis·clones·contracts |
| 5주 | MCP 서버 + 토큰 설계 | MCP 규격, 툴 응답을 '토큰 모양'으로, PreToolUse 훅 → internal/mcp·hooks·elide·tokens |
| 6주 | watch + 시각화 + 배포 | fsnotify 증분 업데이트, Sigma.js/SSE, goreleaser 단일 바이너리 → internal/daemon·server + .goreleaser.yml |
이 로드맵은 "컴파일러 프런트엔드(파싱) → 그래프 자료구조 → 그래프 알고리즘 → 시스템/도구화"를 한 줄로 꿴 코스입니다. 대학의 자료구조·알고리즘·컴파일러 과목을 하나의 실전 레포로 복습하는 셈이라, 이론과 현업 코드를 동시에 잡을 수 있습니다.
"이 문서와 저장소에서 반복되는 용어를 한곳에 모았다."
| 용어 | 의미 |
|---|---|
| 코드 인텔리전스 엔진 | 소스를 구조 데이터로 바꿔 '정의·참조·호출' 같은 코드 내비게이션을 API로 제공하는 도구 |
| 지식 그래프 | 심볼=노드, 관계=엣지로 코드 전체를 표현한 그물망. Gortex의 본체 |
| 노드 / 엣지 | 노드: file·function·method·type·interface·variable·import·package / 엣지: calls·imports·defines·implements·extends·references·member_of·instantiates |
| tree-sitter | 25개 언어를 같은 방식으로 AST로 파싱하는 파서. C 라이브러리(→CGO 필요), 증분 파싱이 빠름 |
| AST (구문 트리) | 소스 코드를 문법 구조에 따라 트리로 표현한 것. 함수·타입·호출이 가지로 보임 |
| MCP | 에이전트와 도구를 잇는 표준 규격. Gortex는 40개 툴을 가진 MCP 서버 |
| get_editing_context / smart_context | 편집 전 필요한 심볼·시그니처·호출관계를 한 번에 주는 핵심 툴(파일 5~10개 읽기 대체) |
| 블래스트 반경 (blast radius) | 한 심볼을 바꿨을 때 영향받는 범위. 역방향 dependents 엣지로 계산 |
| 호출 체인 (call chain) | A→B→C처럼 함수 호출이 이어지는 경로. 정방향/역방향 모두 추적 |
| IMPLEMENTS 추론 | "인터페이스가 요구한 메서드를 다 갖춘 타입"을 자동으로 구현체로 인정(구조적 타이핑) |
| Louvain | 연결이 촘촘한 묶음(커뮤니티)을 찾는 알고리즘 — 기능 단위 군집 탐지에 사용 |
| Tarjan SCC | 강한 연결 요소를 찾아 순환 의존(circular dependency)을 탐지하는 알고리즘 |
| 핫스팟 / fan-in·fan-out | 들어오고 나가는 엣지가 많아 가장 얽힌(위험한) 심볼. 들어옴=fan-in, 나감=fan-out |
| 죽은 코드 (dead code) | 들어오는 엣지가 0인 심볼(진입점·테스트·export 제외) — 안 쓰이는 코드 후보 |
| watch 모드 / fsnotify | 파일 변경을 OS 이벤트로 받아 바뀐 파일만 다시 인덱싱하는 실시간 동기화 |
| 디바운스 (debounce) | 짧은 시간에 몰린 변경을 한 번으로 묶어 처리해 과도한 재계산을 막는 기법 |
| 증분 업데이트 | 전체 재인덱싱 대신 영향받은 노드/엣지만 떼었다 붙이는 갱신 방식 |
| 문자열 인터닝 (interning) | 같은 문자열을 하나만 저장·공유해 메모리를 아끼는 최적화(internal/intern) |
| CGO | Go에서 C 코드를 호출하는 다리. tree-sitter(C) 사용 때문에 C 컴파일러가 빌드에 필요 |
| cobra | Go용 CLI 프레임워크 — 하위 명령·플래그 체계를 만든다(kubectl·gh 계열) |
| SSE (Server-Sent Events) | 서버가 브라우저로 실시간 이벤트를 밀어 주는 단방향 채널 — 웹 UI 실시간 갱신용 |
| Sigma.js / ForceAtlas2 | 대형 그래프를 WebGL로 그리는 라이브러리 / 힘 기반 자동 배치 알고리즘 |
| 가드 규칙 (.gortex.yaml) | co-change·boundary 같은 프로젝트 제약을 정의해 변경을 점검(check_guards) |
| cmd / internal / pkg | Go 표준 폴더 규칙 — 진입점 / 비공개 코어 / 공개 API |