Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 12 additions & 12 deletions .github/workflows/regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,24 @@ jobs:
['ASTVersion']
['Modules']['a.b/c']['Dependencies']['a.b/c']
['Modules']['a.b/c/cmdx']['Dependencies']['a.b/c/cmdx']
['NameToFile']
['NameToLocations']
steps:
- name: Checkout pull request code
uses: actions/checkout@v4
with:
path: 'pr_repo'
path: "pr_repo"

- name: Checkout main branch code
uses: actions/checkout@v4
with:
ref: 'main'
path: 'main_repo'
ref: "main"
path: "main_repo"

- name: Setup Go environment
uses: actions/setup-go@v5
with:
go-version: '1.22'
go-version: "1.22"
cache-dependency-path: |
main_repo/go.sum
pr_repo/go.sum
Expand All @@ -51,18 +53,18 @@ jobs:
- name: Setup Python environment
uses: actions/setup-python@v5
with:
python-version: '3.11'
python-version: "3.11"

- name: Setup JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
java-version: "21"
distribution: "temurin"

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
node-version: "22"

- name: Compile both binaries
run: |
Expand All @@ -82,8 +84,7 @@ jobs:
echo "JDTLS_ROOT_PATH=$(realpath ./main_repo/lang/java/lsp/jdtls/jdt-language-server-*)" >> $GITHUB_ENV

- name: Run OLD abcoder
run:
OUTDIR=out_old ABCEXE=./abcoder_old ./main_repo/script/run_testdata.sh all
run: OUTDIR=out_old ABCEXE=./abcoder_old ./main_repo/script/run_testdata.sh all

- name: Reset dependencies
run: |
Expand All @@ -95,8 +96,7 @@ jobs:
OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_testdata.sh first

- name: Run NEW abcoder
run:
OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_testdata.sh all
run: OUTDIR=out_new ABCEXE=./abcoder_new ./pr_repo/script/run_testdata.sh all

- name: Upload output directories
uses: actions/upload-artifact@v4
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@ tools

!testdata/asts/*.json

.claude/
.claude/
!internal/cmd/assets/.claude/
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,45 @@ Start coding(sub-agent) ─────────→ Execute Implementation

> Watch the demo video [here](https://github.com/cloudwego/abcoder/pull/141)

## Use ABCoder as a Skill

The **Skill** interface provides native Claude Code integration without MCP protocol overhead. It uses Claude Code's built-in skill system for a more streamlined workflow.

### Setup

The Skill is automatically configured when you run `abcoder init-spec`. The skill definitions are located in `internal/cmd/assets/.claude/skills/`.

### Available Tools

| Tool | Description |
|------|-------------|
| `list_repos` | List all available repositories |
| `tree_repo` | Get repository file structure |
| `get_file_structure` | Get all symbols in a file |
| `get_file_symbol` | Get symbol details with dependencies and references |
| `search_symbol` | Search symbols by name pattern |

### Usage Example

```bash
# List all repositories
abcoder cli list_repos

# Get repository file tree
abcoder cli tree_repo 'repo_name'

# Get file structure
abcoder cli get_file_structure 'repo_name' 'path/to/file.go'

# Get symbol details
abcoder cli get_file_symbol 'repo_name' 'path/to/file.go' 'SymbolName'

# Search symbols
abcoder cli search_symbol 'repo_name' 'Pattern*'
```

For Claude Code integration, the skill tools are invoked directly via slash commands like `/abcoder:schedule`.

## Use ABCoder as a MCP server

1. Install ABCoder:
Expand Down Expand Up @@ -177,6 +216,44 @@ Start coding(sub-agent) ─────────→ Execute Implementation

- Try to use [the recommended prompt](llm/prompt/analyzer.md) and combine planning/memory tools like [sequential-thinking](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking) in your AI agent.

### Skill vs MCP

ABCoder provides two integration methods with Claude Code:

| Feature | MCP (mcp__abcoder) | Skill (skill__abcoder) |
|---------|-------------------|----------------------|
| **Invocation** | `mcp__abcoder__tool_name` | `skill__abcoder__tool_name` |
| **Definition** | MCP protocol | .claude/skills/ |
| **Use Case** | General AI agents | Claude Code workflow |
| **Auto Detection** | - | Auto-detect `current_repo` from cwd |
| **Memory Efficient** | - | Sonic lazy-load, on-demand parsing |
| **Pipeline Support** | - | `rg` filter, `jq` extract |
| **Symbol Search** | - | Regex pattern support |
| **Example** | `mcp__abcoder__get_file_symbol` | `skill__abcoder__get_file_symbol` |

The **Skill** interface is the recommended approach for Claude Code users, providing a more streamlined workflow:

- **Auto-detect current repo**: `list_repos` automatically detects repos that match current working directory
- **Memory efficient**: Uses Sonic for lazy JSON parsing, only loads needed data
- **Pipeline friendly**: Output can be piped to `rg` for filtering or `jq` for extraction
- **Regex search**: `search_symbol` supports regex patterns to precisely locate symbols

**Pipeline Examples:**
```bash
# Filter current repo(s) only
abcoder cli list_repos | jq '.current_repo'

# Search with regex
abcoder cli search_symbol myrepo "^Get.*User$"

# Filter related file
abcoder cli tree_repo myrepo | rg 'related-file'

# Filter dependencies only
abcoder cli get_file_symbol myrepo src/main.go MyFunc | jq '.node.dependencies'
```

For detailed usage, see [Skill Definitions](internal/cmd/assets/.claude/skills/).

## Use ABCoder as an Agent (WIP)

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.10.0
github.com/vifraa/gopom v1.0.0
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa
golang.org/x/mod v0.24.0
golang.org/x/tools v0.32.0
)
Expand Down Expand Up @@ -89,7 +90,6 @@ require (
github.com/yargevad/filepathx v1.0.0 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
golang.org/x/arch v0.14.0 // indirect
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.33.0 // indirect
Expand Down
52 changes: 52 additions & 0 deletions idl/get_file_structure.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// get_file_structure IDL
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这仨 pb 是给谁用的?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

主要给AI用,让他理解输出schema;目前代码里没有使用


syntax = "proto3";

package abcoder;

// Request
message GetFileStructReq {
string repo_name = 1; // the name of the repository (output of list_repos tool)
string file_path = 2; // relative file path (output of get_repo_structure tool, e.g., 'src/main.go')
}

// Response
message GetFileStructResp {
FileStruct file_struct = 1;
string error = 2; // optional
}

message FileStruct {
string file_path = 1; // the path of the file
string mod_path = 2; // optional, the module path
string pkg_path = 3; // optional, the package path
repeated Import imports = 4; // optional, the imports of the file
repeated NodeStruct nodes = 5; // optional, the node structs of the file
}

message Import {
string path = 1; // import path
string alias = 2; // optional, import alias
}

message NodeStruct {
string mod_path = 1; // optional, the module path
string pkg_path = 2; // optional, the package path
string name = 3; // the name of the node
string type = 4; // optional, the type of the node
string signature = 5; // optional, the func signature of the node (omitted when nodes > 500)
string file = 6; // optional, the file path of the node
int32 line = 7; // optional, the line of the node
string codes = 8; // optional, the codes of the node
repeated NodeID dependencies = 9; // optional, the dependencies of the node
repeated NodeID references = 10; // optional, the references of the node
repeated NodeID implements = 11; // optional, the implements of the node
repeated NodeID groups = 12; // optional, the groups of the node
repeated NodeID inherits = 13; // optional, the inherits of the node
}

message NodeID {
string mod_path = 1; // module path of the node (from get_repo_structure)
string pkg_path = 2; // package path of the node (from get_repo_structure)
string name = 3; // name of the node (from get_package_structure or get_file_structure)
}
39 changes: 39 additions & 0 deletions idl/get_file_symbol.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// get_file_symbol IDL

syntax = "proto3";

package abcoder;

// Request
message GetFileSymbolReq {
string repo_name = 1; // the name of the repository (output of list_repos tool)
string file_path = 2; // the file path (output of get_repo_structure tool)
string name = 3; // the name of the symbol (function, type, or variable) to query
}

// Response
message GetFileSymbolResp {
FileNodeStruct node = 1; // the ast node
string error = 2; // optional, the error message
}

// FileNodeStruct 文件节点结构(使用 FileNodeID)
message FileNodeStruct {
string name = 1; // the name of the node
string type = 2; // optional, the type of the node
string signature = 3; // optional, the func signature of the node
string file = 4; // optional, the file path of the node
int32 line = 5; // optional, the line of the node
string codes = 6; // optional, the codes of the node
repeated FileNodeID dependencies = 7; // optional, the dependencies of the node
repeated FileNodeID references = 8; // optional, the references of the node
repeated FileNodeID implements = 9; // optional, the implements of the node
repeated FileNodeID groups = 10; // optional, the groups of the node
repeated FileNodeID inherits = 11; // optional, the inherits of the node
}

// FileNodeID 文件节点标识(用于 get_file_symbol 输出)
message FileNodeID {
string file_path = 1; // file path relative to repo root
string name = 2; // symbol name in the file
}
Loading
Loading