This document describes how to contribute code to VibeCoding.
- Go 1.24+
- Git
- Make (optional)
- bubblewrap (optional, for sandbox testing)
git clone https://github.com/startvibecoding/vibecoding.git
cd vibecodinggo mod download# Build
make build
# Install to $GOPATH/bin
make install# Run all tests
make test
# Run tests for specific package
go test ./internal/tools/
# Run specific test
go test -run TestReadTool ./internal/tools/vibecoding/
├── cmd/vibecoding/ # CLI entry point
│ └── main.go
├── internal/
│ ├── agent/ # Core Agent loop
│ │ ├── agent.go # Agent main logic
│ │ ├── events.go # Event type definitions
│ │ ├── provider.go # Provider adapter
│ │ └── system_prompt.go # System prompt generation
│ ├── config/ # Configuration management
│ ├── contextfiles/ # Context file loading
│ ├── provider/ # LLM Provider abstraction
│ │ ├── provider.go # Provider interface
│ │ ├── anthropic/ # Anthropic implementation
│ │ └── openai/ # OpenAI implementation
│ ├── sandbox/ # Sandbox implementation
│ ├── session/ # Session management
│ ├── skills/ # Skills system
│ ├── tools/ # Tool implementations
│ │ ├── tool.go # Tool interface and registration
│ │ ├── bash.go # Bash command
│ │ ├── read.go # File reading
│ │ ├── write.go # File writing
│ │ ├── edit.go # File editing
│ │ ├── grep.go # Content search
│ │ ├── find.go # File finding
│ │ └── ls.go # Directory listing
│ ├── tui/ # Terminal UI
│ └── util/ # Utility functions
└── pkg/sdk/ # Public SDK (future)
type Provider interface {
Name() string
Models() []*Model
GetModel(id string) *Model
Chat(ctx context.Context, params ChatParams) <-chan StreamEvent
}type Tool interface {
Name() string
Description() string
Parameters() json.RawMessage
Execute(ctx context.Context, params json.RawMessage) (string, error)
}// internal/tools/mytool.go
package tools
import (
"context"
"encoding/json"
)
type MyTool struct {
workdir string
}
func NewMyTool(workdir string) *MyTool {
return &MyTool{workdir: workdir}
}
func (t *MyTool) Name() string {
return "mytool"
}
func (t *MyTool) Description() string {
return "Description of my tool"
}
func (t *MyTool) Parameters() json.RawMessage {
return json.RawMessage(`{
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "First parameter"
}
},
"required": ["param1"]
}`)
}
func (t *MyTool) Execute(ctx context.Context, params json.RawMessage) (string, error) {
var p struct {
Param1 string `json:"param1"`
}
if err := json.Unmarshal(params, &p); err != nil {
return "", err
}
// Implement tool logic
return "result", nil
}In internal/tools/tool.go's RegisterDefaults() method:
func (r *Registry) RegisterDefaults() {
r.Register(&ReadTool{workdir: r.workdir})
r.Register(&WriteTool{workdir: r.workdir})
r.Register(&EditTool{workdir: r.workdir})
r.Register(&BashTool{workdir: r.workdir, sandbox: r.sandbox})
r.Register(&GrepTool{workdir: r.workdir})
r.Register(&FindTool{workdir: r.workdir})
r.Register(&LsTool{workdir: r.workdir})
r.Register(&MyTool{workdir: r.workdir}) // Add new tool
}Add tool description in internal/agent/system_prompt.go.
// internal/tools/mytool_test.go
package tools
import (
"context"
"testing"
)
func TestMyTool_Execute(t *testing.T) {
tool := NewMyTool("/tmp")
params := `{"param1": "value"}`
result, err := tool.Execute(context.Background(), json.RawMessage(params))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result != "expected" {
t.Errorf("expected 'expected', got '%s'", result)
}
}Most new services should be added as vendor adapters, not new protocol
providers. If the service speaks OpenAI Chat Completions or Anthropic Messages,
reuse the generic provider and register vendor defaults in internal/provider.
- Create
internal/provider/vendor_myvendor.go. - Register URL detection and defaults with
RegisterVendorAdapter. - Add model
compatflags only for behavior that differs from the generic protocol. - Add focused tests in
internal/providerand, if request formatting changes, ininternal/provider/openaiorinternal/provider/anthropic.
package provider
func init() {
RegisterVendorAdapter(simpleVendorAdapter{
name: "myvendor",
domains: []string{"api.myvendor.example"},
thinkingFormat: "deepseek", // optional
defaultAPI: "openai-chat",
})
}Provider creation for CLI and ACP goes through internal/provider/factory, so
do not add vendor-specific creation code to cmd/vibecoding/main.go or
internal/acp/acp.go.
Only add a new provider package when the service has a native protocol that is not covered by OpenAI Chat Completions or Anthropic Messages.
- Create
internal/provider/myprotocol. - Implement
provider.Provider. - Add construction support in
internal/provider/factory. - Keep settings JSON compatibility stable.
- Add provider and factory tests.
make testgo test ./internal/agent/
go test ./internal/tools/go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.outmake fmtOr manually:
gofmt -w .
goimports -w .make lint- Package names: lowercase words, e.g.,
tools,agent - Interface names: verbs or nouns, e.g.,
Provider,Tool - Struct names: PascalCase, e.g.,
ReadTool,AgentConfig - Function names: PascalCase, e.g.,
NewAgent,Execute - Variable names: camelCase, e.g.,
workdir,maxTokens
// Good practice
result, err := doSomething()
if err != nil {
return fmt.Errorf("do something: %w", err)
}
// Bad practice
result, _ := doSomething()Use Conventional Commits:
<type>(<scope>): <subject>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentationrefactor: Refactoringtest: Testschore: Miscellaneous
Examples:
feat(tools): add new search tool
fix(agent): fix streaming issue
docs(readme): update installation guide
- Fork project
- Create feature branch
- Commit changes
- Run tests
- Create Pull Request
vibecoding --debug# Install dlv
go install github.com/go-delve/delve/cmd/dlv@latest
# Debug
dlv debug ./cmd/vibecoding -- --debugUse Semantic Versioning:
MAJOR.MINOR.PATCH
Example: 1.0.0, 1.1.0, 1.0.1
# Update version number
git tag -a v1.0.0 -m "Release v1.0.0"
# Push tags
git push --tags
# Build release packages
make build-all# Publish release version
make npm-publish
# Publish pre-release version
make npm-publish-preUsers can install via npm:
npm install -g vibecoding-installerA: See Adding New Tools section.
A: See Adding New Providers section.
A:
- Check Go version
- Run
go mod tidy - Check error logs
A:
- Use
--debugflag - Check if bwrap is installed:
bwrap --version - Check system logs