Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions .claude/skills/ccg-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,6 @@ User: "RAG 인덱스 만들어줘"
→ Creates searchable document tree from docs + communities
```

### Build RAG index from namespace docs
```
User: "my-service namespace 문서로 RAG 인덱스 만들어줘"
→ upload_file(namespace: "my-service", file_path: "docs/handler.go.md", content: "<base64>")
→ build_rag_index(namespace: "my-service")
→ search_docs(query: "handler")
→ get_doc_content(namespace: "my-service", file_path: "docs/handler.go.md")
```

### Check documentation quality
```
User: "문서 상태 체크해줘"
Expand Down
104 changes: 0 additions & 104 deletions .claude/skills/ccg-workspace/SKILL.md

This file was deleted.

1 change: 0 additions & 1 deletion .claude/skills/ccg/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ Related skills:
/ccg-analyze — Code analysis & architecture
/ccg-annotate — Annotation system & AI workflow
/ccg-docs — Documentation & RAG indexing
/ccg-workspace — Namespace file management
```

## MCP Tools (7)
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ The ccg MCP server registered in `.mcp.json` provides 33 tools:

- `parse_project`, `build_or_update_graph`, `run_postprocess`
- `get_postprocess_policy`, `reset_postprocess_policy`
- `get_node`, `search`, `query_graph`, `list_graph_stats`, `get_minimal_context`
- `get_node`, `search`, `query_graph`, `list_graph_stats`, `list_namespaces`, `get_minimal_context`
- `get_impact_radius`, `trace_flow`
- `find_large_functions`, `find_dead_code`
- `detect_changes`, `get_affected_flows`, `list_flows`
- `list_communities`, `get_community`, `get_architecture_overview`
- `get_annotation`
- `build_rag_index`, `get_rag_tree`, `get_doc_content`, `search_docs`, `retrieve_docs`
- `upload_file`, `upload_files`, `list_namespaces`, `list_files`, `delete_file`, `delete_namespace`

`ccg serve` is the local stdio MCP entry point. Self-hosted HTTP mode is provided by
the separate `ccg-server` binary, which serves `/mcp`, `/health`, `/ready`, `/status`,
Expand Down
20 changes: 9 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ Follow the global prompt rules first. This file adds project-specific skill rout

## MCP 서버

`.mcp.json`에 등록된 ccg MCP 서버가 26개 도구를 제공합니다:
`.mcp.json`에 등록된 ccg MCP 서버가 21개 도구를 제공합니다:

- `parse_project`, `build_or_update_graph`, `run_postprocess`
- `get_postprocess_policy`, `reset_postprocess_policy`
- `get_node`, `search`, `query_graph`, `list_graph_stats`, `get_minimal_context`
- `get_node`, `search`, `query_graph`, `list_graph_stats`, `list_namespaces`, `get_minimal_context`
- `get_impact_radius`, `trace_flow`, `find_suspect_fallback_edges`
- `detect_changes`, `get_affected_flows`, `list_flows`
- `get_annotation`
- `get_doc_content`, `search_docs`, `retrieve_docs`
- `upload_file`, `upload_files`, `list_files`, `delete_file`, `list_namespaces`, `delete_namespace`

HTTP 모드 (`--transport streamable-http`)에서는 `/health` 및 `/webhook` 엔드포인트도 제공합니다.
Webhook은 `--allow-repo` 플래그로 허용 리포지토리를 설정하면 활성화됩니다.
Expand All @@ -24,15 +23,14 @@ GitHub (`X-Hub-Signature-256`) 및 Gitea (`X-Gitea-Signature`, `X-Gitea-Event`)
Push 이벤트 수신 → 자동 clone/pull → 그래프 빌드 → DB 저장 파이프라인.
Graceful shutdown: SIGINT/SIGTERM 시 진행 중인 clone/build에 context cancel 전파.

## CLI Skills (5개)
## CLI Skills (4개)

| Skill | 설명 |
| ---------------- | ----------------------------------------------------------- |
| `/ccg` | 코어 빌드 & 검색 — 파싱, 그래프 빌드, 쿼리, 검색 |
| `/ccg-analyze` | 코드 분석 — 영향 반경, 플로우 추적, 데드코드, 아키텍처 |
| `/ccg-annotate` | 어노테이션 시스템 — AI 어노테이션 워크플로우, 태그 레퍼런스 |
| `/ccg-docs` | 문서 — 문서 생성, RAG 인덱싱, lint |
| `/ccg-workspace` | 파일 워크스페이스 — 파일/워크스페이스 업로드, 목록, 삭제 |
| Skill | 설명 |
| --------------- | ----------------------------------------------------------- |
| `/ccg` | 코어 빌드 & 검색 — 파싱, 그래프 빌드, 쿼리, 검색 |
| `/ccg-analyze` | 코드 분석 — 영향 반경, 플로우 추적, 데드코드, 아키텍처 |
| `/ccg-annotate` | 어노테이션 시스템 — AI 어노테이션 워크플로우, 태그 레퍼런스 |
| `/ccg-docs` | 문서 — 문서 생성, RAG 인덱싱, lint |

주요 커맨드:

Expand Down
19 changes: 5 additions & 14 deletions guide/ko/mcp-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,37 +139,28 @@ RAG 인덱스 품질은 생성 문서와 비어 있지 않은 community postproc
`run_postprocess`를 `communities=true`, `flows=false`, `fts=false`로
호출하십시오.

### 네임스페이스 파일 관리 (Namespace File Management)
### 네임스페이스 탐색 (Namespace Discovery)

업로드 파일, 서비스별 그래프 데이터, 네임스페이스별 RAG 인덱스의 격리 단위는
`namespace`입니다.
서비스별 그래프 데이터와 네임스페이스별 RAG 인덱스의 격리 단위는 `namespace`입니다.

| 도구 | 설명 |
|------|-------------|
| `upload_file` | 네임스페이스에 파일 업로드 (base64) |
| `upload_files` | 단일 호출로 여러 네임스페이스에 다수 파일 업로드 |
| `list_namespaces` | 모든 네임스페이스 목록 출력 |
| `list_files` | 네임스페이스 내 파일 목록 출력 |
| `delete_file` | 네임스페이스에서 파일 삭제 |
| `delete_namespace` | 네임스페이스 전체 및 관련 파일 모두 삭제 |
| `list_namespaces` | 그래프 데이터를 가진 네임스페이스를 네임스페이스별 노드 수와 함께 출력 |

정식 예시:

```
upload_file(namespace: "payment-svc", file_path: "handler.go", content: "<base64>")
list_files(namespace: "payment-svc")
delete_namespace(namespace: "payment-svc")
list_namespaces() // -> [{namespace: "payment-svc", node_count: 128}, ...]
```

## Agent Skills (5개)
## Agent Skills (4개)

| 스킬 | 설명 |
|-------|-------------|
| `/ccg` | 핵심 빌드 및 검색 — 파싱, 그래프 빌드, 쿼리, 검색 |
| `/ccg-analyze` | 코드 분석 — 영향 범위, 흐름 추적, 데드 코드, 아키텍처 |
| `/ccg-annotate` | 어노테이션 시스템 — AI 기반 어노테이션 워크플로우, 태그 레퍼런스 |
| `/ccg-docs` | 문서화 — 문서 생성, RAG 인덱싱, 린트 |
| `/ccg-namespace` | 네임스페이스 파일 관리 — 네임스페이스 파일 업로드, 목록 출력, 삭제 |

이 스킬 파일들은 `skills/`에 있으며 slash-command 스타일의 에이전트
워크플로우를 위해 작성되었습니다. 일반적인 코딩 에이전트 작업을 적절한
Expand Down
22 changes: 7 additions & 15 deletions guide/mcp-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,37 +144,29 @@ when it is configured. In MCP-only workflows, run `run_postprocess` with
`communities=true`, `flows=false`, and `fts=false` before `build_rag_index` when
communities may be missing.

### Namespace File Management
### Namespace Discovery

Use `namespace` as the isolation term for uploaded files, per-service graph data,
and namespace-specific RAG indexes.
`namespace` is the isolation term for per-service graph data and namespace-specific
RAG indexes.

| Tool | Description |
|------|-------------|
| `upload_file` | Upload file to namespace (base64) |
| `upload_files` | Upload multiple files to namespaces in a single call |
| `list_namespaces` | List all namespaces |
| `list_files` | List files in a namespace |
| `delete_file` | Delete file from namespace |
| `delete_namespace` | Delete an entire namespace and all its files |
| `list_namespaces` | List namespaces that hold graph data, with per-namespace node counts |

Canonical examples:
Canonical example:

```
upload_file(namespace: "payment-svc", file_path: "handler.go", content: "<base64>")
list_files(namespace: "payment-svc")
delete_namespace(namespace: "payment-svc")
list_namespaces() // -> [{namespace: "payment-svc", node_count: 128}, ...]
```

## Agent Skills (5)
## Agent Skills (4)

| Skill | Description |
|-------|-------------|
| `/ccg` | Core build & search — parse, build graph, query, search |
| `/ccg-analyze` | Code analysis — impact radius, flow tracing, dead code, architecture |
| `/ccg-annotate` | Annotation system — AI-driven annotation workflow, tag reference |
| `/ccg-docs` | Documentation — generate docs, RAG indexing, lint |
| `/ccg-namespace` | Namespace file management — upload, list, and delete namespace files |

These skill files live in `skills/` and are written for slash-command style
agent workflows. They route common coding-agent tasks to the right CLI and MCP
Expand Down
99 changes: 0 additions & 99 deletions internal/mcp/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package mcp

import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -524,101 +523,3 @@ func Gamma() {}
t.Errorf("expected at least 3 nodes, got %v", resp["total_nodes"])
}
}

func TestE2E_UploadBuildSearch(t *testing.T) {
deps := setupE2EDeps(t)

wsRoot := t.TempDir()
deps.NamespaceRoot = wsRoot

// Step 1: Upload Go source into the namespace with upload_file.
goSrc := `package payment

func ProcessPayment(amount int) error {
return nil
}

func RefundPayment(txID string) error {
return nil
}
`
encoded := base64.StdEncoding.EncodeToString([]byte(goSrc))

uploadResult := callTool(t, deps, "upload_file", map[string]any{
"namespace": "payment-svc",
"file_path": "payment.go",
"content": encoded,
})
if uploadResult.IsError {
t.Fatalf("upload_file error: %s", getTextContent(uploadResult))
}

// Step 2: Build the namespace path with build_or_update_graph.
wsPath := filepath.Join(wsRoot, "payment-svc")
buildResult := callTool(t, deps, "build_or_update_graph", map[string]any{
"path": wsPath,
"full_rebuild": true,
"postprocess": "none",
})
if buildResult.IsError {
t.Fatalf("build_or_update_graph error: %s", getTextContent(buildResult))
}

// Step 3: Build the search index.
ctx := context.Background()
nodesInFile, err := deps.Store.GetNodesByFile(ctx, "payment.go")
if err != nil {
t.Fatal(err)
}
if len(nodesInFile) == 0 {
t.Fatal("expected at least 1 node after build")
}
for _, n := range nodesInFile {
if n.Kind == model.NodeKindFunction {
deps.DB.Create(&model.SearchDocument{
NodeID: n.ID,
Content: n.Name + " " + n.QualifiedName,
Language: n.Language,
})
}
}
deps.SearchBackend.Rebuild(ctx, deps.DB)

// Step 4: Verify with search.
searchResult := callTool(t, deps, "search", map[string]any{"query": "ProcessPayment", "limit": 10})
if searchResult.IsError {
t.Fatalf("search error: %s", getTextContent(searchResult))
}
searchText := getTextContent(searchResult)
var results []map[string]any
if err := json.Unmarshal([]byte(searchText), &results); err != nil {
t.Fatalf("search result not JSON array: %s", searchText)
}
if len(results) == 0 {
t.Fatal("expected at least 1 search result for 'ProcessPayment'")
}

found := false
for _, r := range results {
if name, ok := r["name"].(string); ok && name == "ProcessPayment" {
found = true
}
}
if !found {
t.Error("expected ProcessPayment in search results")
}

// Step 5: Confirm Refund is searchable too.
refundResult := callTool(t, deps, "search", map[string]any{"query": "RefundPayment", "limit": 10})
if refundResult.IsError {
t.Fatalf("search error: %s", getTextContent(refundResult))
}
refundText := getTextContent(refundResult)
var refundResults []map[string]any
if err := json.Unmarshal([]byte(refundText), &refundResults); err != nil {
t.Fatalf("search result not JSON array: %s", refundText)
}
if len(refundResults) == 0 {
t.Fatal("expected at least 1 search result for 'RefundPayment'")
}
}
Loading
Loading