diff --git a/.agents/skills/ccg/SKILL.md b/.agents/skills/ccg/SKILL.md new file mode 100644 index 00000000..65092b55 --- /dev/null +++ b/.agents/skills/ccg/SKILL.md @@ -0,0 +1,11 @@ +--- +name: ccg +description: "Build, update, inspect, and search code-context-graph graphs and route to specialized CCG workflows. Use when a task needs CCG setup, graph freshness, algorithm or feature-pipeline understanding, exact symbol or relationship lookup, annotation-aware full-text search, safe full or scoped synchronization, MCP graph queries, combining direct source lookup with CCG before an absence or completeness claim, or selection among CCG analysis, docs, annotation, and namespace skills. Do not use for a simple file or string lookup when grep/read is sufficient." +--- + +# CCG Runtime Adapter + +Read the [canonical CCG skill](../../../skills/ccg/SKILL.md) completely before +acting. Resolve its linked resources relative to the canonical skill directory +and follow its routing, safety, search, and completion instructions for the +current task. diff --git a/.claude/skills/ccg/SKILL.md b/.claude/skills/ccg/SKILL.md index 52abaf6e..65092b55 100644 --- a/.claude/skills/ccg/SKILL.md +++ b/.claude/skills/ccg/SKILL.md @@ -1,111 +1,11 @@ --- name: ccg -description: code-context-graph — build code knowledge graphs and search. Core entry point for parsing, building, and querying code graphs. +description: "Build, update, inspect, and search code-context-graph graphs and route to specialized CCG workflows. Use when a task needs CCG setup, graph freshness, algorithm or feature-pipeline understanding, exact symbol or relationship lookup, annotation-aware full-text search, safe full or scoped synchronization, MCP graph queries, combining direct source lookup with CCG before an absence or completeness claim, or selection among CCG analysis, docs, annotation, and namespace skills. Do not use for a simple file or string lookup when grep/read is sufficient." --- -# code-context-graph — Core Build & Search +# CCG Runtime Adapter -Local code analysis tool that parses codebases via Tree-sitter into a knowledge graph with 12 language support and annotation-powered search. - -## Subcommands - -| Command | Description | Example | -| ----------------------------------- | ------------------------------------------- | ----------------------------------------- | -| `build [dir]` | Parse directory, build graph + search index | `ccg build .` | -| `build --exclude ` | Exclude files/paths (repeatable) | `ccg build --exclude vendor` | -| `build --no-recursive [dir]` | Only parse top-level directory | `ccg build --no-recursive .` | -| `update [dir]` | Incremental sync (changed files only) | `ccg update .` | -| `status` | Show graph statistics (nodes/edges/files) | `ccg status` | -| `search ` | FTS keyword search (includes @annotations) | `ccg search "authentication"` | -| `search --path ` | Scoped search by path prefix | `ccg search --path internal/auth "login"` | -| `languages` | List supported languages and extensions | `ccg languages` | -| `example [language]` | Show annotation writing example | `ccg example go` | -| `tags` | Show all annotation tag reference | `ccg tags` | -| `serve` | Start MCP server (stdio by default) | `ccg serve` | -| `serve --transport streamable-http` | Start MCP server over HTTP | `ccg serve --transport streamable-http` | -| `serve --http-addr :9090` | Custom HTTP listen address | `ccg serve --http-addr :9090` | -| `serve --stateless` | Stateless session mode | `ccg serve --stateless` | -| `serve --allow-repo ` | Allowed repos for webhook sync (repeatable) | `ccg serve --allow-repo "org/*"` | -| `serve --webhook-secret ` | HMAC secret for webhook verification | `ccg serve --webhook-secret mysecret` | -| `serve --repo-root ` | Root dir for cloned repos | `ccg serve --repo-root /data/repos` | - -## Execution - -Parse the user's input after `ccg` and run via Bash: - -```bash -ccg {subcommand} {args} -``` - -If the binary doesn't exist, build it first: - -```bash -CGO_ENABLED=1 go build -tags "fts5" -o ccg ./cmd/ccg/ -``` - -## When no arguments provided - -Show available commands: - -``` -Available ccg commands: - ccg build [dir] — Build code knowledge graph - ccg update [dir] — Incremental update - ccg status — Graph statistics - ccg search — Full-text search (annotations included) - ccg languages — List supported languages - ccg serve — Start MCP server - -Related skills: - /ccg-analyze — Code analysis & architecture - /ccg-annotate — Annotation system & AI workflow - /ccg-docs — Documentation & RAG indexing -``` - -## MCP Tools (7) - -| Tool | Description | -| ----------------------- | ---------------------------------------------------------- | -| `parse_project` | Parse source files | -| `build_or_update_graph` | Full/incremental build with postprocessing | -| `run_postprocess` | Run flows/communities/search rebuild | -| `get_node` | Get node by qualified name | -| `search` | Full-text search | -| `query_graph` | Predefined graph queries (callers, callees, imports, etc.) | -| `list_graph_stats` | Node/edge/file counts | - -## Smart Behaviors - -### Auto-rebuild when stale - -If `ccg.db` doesn't exist or the user asks to analyze the project, run `ccg build .` first. - -### Annotation-aware search - -When the user asks about business concepts, use FTS search which includes annotation content: - -- `@intent` — function purpose/goal -- `@domainRule` — business rules -- `@sideEffect` — side effects -- `@mutates` — state changes -- `@index` — file/package level description - -Example: user asks "결제 관련 코드" → `ccg search "결제"` finds functions annotated with payment-related @intent/@domainRule. - -## Graph Schema - -Node kinds: `function`, `class`, `type`, `test`, `file` - -Edge kinds: `calls`, `imports_from`, `inherits`, `implements`, `contains`, `tested_by`, `depends_on`, `references` - -## Supported Languages (12) - -Go, Python, TypeScript, Java, Ruby, JavaScript, C, C++, Rust, Kotlin, PHP, Lua - -## HTTP Endpoints (Streamable HTTP mode) - -| Endpoint | Method | Description | -| ---------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| `/mcp` | POST/GET/DELETE | MCP protocol endpoint (session-based) | -| `/health` | GET | Health check — returns `{"status":"ok"}` | -| `/webhook` | POST | GitHub / Gitea webhook receiver (when `--allow-repo` configured). Supports `X-Hub-Signature-256` and `X-Gitea-Signature` HMAC verification. | +Read the [canonical CCG skill](../../../skills/ccg/SKILL.md) completely before +acting. Resolve its linked resources relative to the canonical skill directory +and follow its routing, safety, search, and completion instructions for the +current task. diff --git a/internal/adapters/inbound/cli/skills_contract_test.go b/internal/adapters/inbound/cli/skills_contract_test.go index 083f2f28..d00ce045 100644 --- a/internal/adapters/inbound/cli/skills_contract_test.go +++ b/internal/adapters/inbound/cli/skills_contract_test.go @@ -109,6 +109,43 @@ func TestProjectSkillsDeclareRuntimeContract(t *testing.T) { } } +func TestCoreSkillHasClaudeAndAntigravityProjectAdapters(t *testing.T) { + repoRoot := filepath.Join("..", "..", "..", "..") + canonicalPath := filepath.Join(repoRoot, "skills", "ccg", "SKILL.md") + canonicalRaw, err := os.ReadFile(canonicalPath) + if err != nil { + t.Fatalf("read canonical skill: %v", err) + } + canonical := parseSkillContract(t, canonicalRaw) + + adapters := map[string]string{ + "claude": filepath.Join(repoRoot, ".claude", "skills", "ccg", "SKILL.md"), + "antigravity": filepath.Join(repoRoot, ".agents", "skills", "ccg", "SKILL.md"), + } + for runtime, path := range adapters { + t.Run(runtime, func(t *testing.T) { + raw, err := os.ReadFile(path) + if err != nil { + t.Fatalf("read runtime adapter: %v", err) + } + adapter := parseSkillContract(t, raw) + if adapter.Name != canonical.Name { + t.Errorf("name = %q, want canonical name %q", adapter.Name, canonical.Name) + } + if adapter.Description != canonical.Description { + t.Errorf("description differs from canonical discovery contract") + } + if !strings.Contains(string(raw), "[canonical CCG skill](../../../skills/ccg/SKILL.md)") { + t.Error("adapter does not route to the canonical CCG skill") + } + linkedPath := filepath.Clean(filepath.Join(filepath.Dir(path), "..", "..", "..", "skills", "ccg", "SKILL.md")) + if linkedPath != filepath.Clean(canonicalPath) { + t.Errorf("canonical link resolves to %q, want %q", linkedPath, canonicalPath) + } + }) + } +} + func TestProjectSkillsDoNotAdvertiseRemovedCommands(t *testing.T) { for _, command := range []string{"ccg index", "ccg languages", "ccg example", "ccg tags"} { matches, err := filepath.Glob(filepath.Join("..", "..", "..", "..", "skills", "*", "SKILL.md")) diff --git a/skills/ccg/SKILL.md b/skills/ccg/SKILL.md index cf7efd4a..4a108794 100644 --- a/skills/ccg/SKILL.md +++ b/skills/ccg/SKILL.md @@ -1,8 +1,8 @@ --- name: ccg -description: "Build, update, inspect, and search code-context-graph graphs and route to specialized CCG workflows. Use when a task needs CCG setup, graph freshness, algorithm or feature-pipeline understanding, exact symbol or relationship lookup, annotation-aware full-text search, safe full or scoped synchronization, MCP graph queries, or selection among CCG analysis, docs, annotation, and namespace skills. Do not use for a simple file or string lookup when grep/read is sufficient." +description: "Build, update, inspect, and search code-context-graph graphs and route to specialized CCG workflows. Use when a task needs CCG setup, graph freshness, algorithm or feature-pipeline understanding, exact symbol or relationship lookup, annotation-aware full-text search, safe full or scoped synchronization, MCP graph queries, combining direct source lookup with CCG before an absence or completeness claim, or selection among CCG analysis, docs, annotation, and namespace skills. Do not use for a simple file or string lookup when grep/read is sufficient." metadata: - version: 1.4.0 + version: 1.4.1 openclaw: category: "code-intelligence" domain: "core" @@ -166,17 +166,45 @@ Every hit carries a `node_id`. Hand that ID straight to `get_node`, `query_graph`, `get_impact_radius`, or `trace_flow` — the answer exists to start a graph walk, not to finish the investigation. -**When a question comes back empty or weak, the search is not broken — the -reasons were never written down.** A question mostly made of words nobody -recorded gets no intent hits by design. Hand off to the `ccg-annotate` skill: -annotate the area under investigation, rebuild the graph, then re-ask the same -question. That loop, not query rephrasing, is what makes questions answerable. +**When coverage says the reasons were never written, fix the evidence rather +than rephrasing the query.** If `annotation_coverage.with_reason` is zero or +`next` names `ccg-annotate`, hand off to the `ccg-annotate` skill: annotate the +area under investigation, rebuild the graph, then re-ask the same question. An +empty or weak answer without that evidence is not enough to blame annotations; +follow the hybrid workflow below and inspect freshness and truncation first. **Difference from Grep**: Grep scans source text directly. CCG full-text search queries indexed symbol fields and annotations together. Searching "결제" can find a `payment` function when its annotation contains "결제 처리"; search does not infer translations or arbitrary synonyms that are absent from the index. +## Hybrid Search Workflow + +Do not treat grep/read and CCG search as mutually exclusive. Prefer `rg` when +it is available for repository text searches. The two approaches answer +different parts of the same investigation: + +1. When the question names an exact identifier, path, literal, or error text, + use grep/read for the current source. Also use CCG when the task asks why the + code exists, how it relates to other code, or what a change affects. +2. When the question cannot name a symbol yet, start with `ccg search`. Feed the + returned qualified names, paths, and distinctive reason terms into grep/read + to verify the candidate against source. +3. Before concluding that code or behavior does not exist, verify graph + freshness and check both CCG and grep/read. A miss in either one alone is not + proof of absence: CCG can be stale or rank a candidate off the first page, + while grep cannot find intent or relationships that are not written as the + query's exact text. +4. Merge corroborating results by file path and symbol instead of presenting + duplicate lists. Preserve why each result was found (`exact text`, + `identifier`, `recorded reason`, or `graph relationship`). Treat source as + authority for current text and location; treat CCG as candidate evidence for + intent and relationships, then verify those claims with the relevant graph + query or source read. + +Run the two searches in parallel when the request contains both an exact clue +and an intent/relationship question, or when a completeness claim matters. + ## Reading a Path You Already Have `search` ranks; it can be wrong about what matters. @@ -243,7 +271,10 @@ a narrow question before expanding through graph queries. ## Boundary -- Use grep/read for a known filename, exact string, or one obvious location. +- Follow the hybrid workflow when both direct source evidence and indexed + intent or relationship evidence can materially change the answer. +- Use grep/read alone only for a known filename, exact string, or one obvious + location with no intent, relationship, or completeness claim. - Treat algorithm, feature-flow, and pipeline questions as relationship analysis rather than simple location lookup. - Use `ccg search` for intent and annotation candidates, not exact graph proof. - Use specialized CCG skills for analysis, docs, annotations, or namespaces. @@ -255,5 +286,6 @@ a narrow question before expanding through graph queries. Before finishing, state the namespace and freshness evidence used (or say it was not verified), name the evidence-producing tools or commands, report result limits and truncation, record the chosen `replace` behavior for scoped updates, -and list any failed/skipped postprocess step, source fallback, or verification -that was not run. +say whether grep/read corroborated CCG whenever absence or completeness was +claimed, and list any failed/skipped postprocess step, source fallback, or +verification that was not run.