a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
151 lines
4.3 KiB
Go
151 lines
4.3 KiB
Go
// Package zed implements the Gortex init integration for the Zed
|
|
// editor. Zed calls its MCP registry `context_servers` (not
|
|
// `mcpServers`) and stores it in a platform-specific settings.json:
|
|
//
|
|
// macOS: ~/Library/Application Support/Zed/settings.json
|
|
// Linux: ~/.config/zed/settings.json
|
|
// Windows: %APPDATA%\Zed\settings.json
|
|
//
|
|
// The server entry shape:
|
|
//
|
|
// {
|
|
// "context_servers": {
|
|
// "gortex": {
|
|
// "source": "custom",
|
|
// "command": "gortex",
|
|
// "args": ["mcp", "--index", ".", "--watch"],
|
|
// "env": {"GORTEX_INDEX_WORKERS": "8"}
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// Docs: https://zed.dev/docs/ai/mcp
|
|
package zed
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"github.com/zzet/gortex/internal/agents"
|
|
"github.com/zzet/gortex/internal/agents/internalutil"
|
|
)
|
|
|
|
const Name = "zed"
|
|
const DocsURL = "https://zed.dev/docs/ai/mcp"
|
|
|
|
type Adapter struct{}
|
|
|
|
func New() *Adapter { return &Adapter{} }
|
|
func (a *Adapter) Name() string { return Name }
|
|
func (a *Adapter) DocsURL() string { return DocsURL }
|
|
|
|
// userSettingsPath returns the platform-specific Zed settings file.
|
|
// Returns "" when Home is unset or the OS is unsupported.
|
|
func userSettingsPath(home string) string {
|
|
if home == "" {
|
|
return ""
|
|
}
|
|
switch runtime.GOOS {
|
|
case "darwin":
|
|
return filepath.Join(home, "Library", "Application Support", "Zed", "settings.json")
|
|
case "linux":
|
|
return filepath.Join(home, ".config", "zed", "settings.json")
|
|
case "windows":
|
|
// %APPDATA% is usually ~\AppData\Roaming on Windows.
|
|
return filepath.Join(home, "AppData", "Roaming", "Zed", "settings.json")
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// Detect checks for the zed CLI on PATH or the platform-specific
|
|
// settings.json directory.
|
|
func (a *Adapter) Detect(env agents.Env) (bool, error) {
|
|
if p, err := exec.LookPath("zed"); err == nil && p != "" {
|
|
return true, nil
|
|
}
|
|
path := userSettingsPath(env.Home)
|
|
if path == "" {
|
|
return false, nil
|
|
}
|
|
if _, err := os.Stat(filepath.Dir(path)); err == nil {
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (a *Adapter) Plan(env agents.Env) (*agents.Plan, error) {
|
|
p := &agents.Plan{}
|
|
if settings := userSettingsPath(env.Home); settings != "" {
|
|
p.Files = append(p.Files, agents.FileAction{
|
|
Path: settings,
|
|
Action: agents.ActionWouldMerge,
|
|
Keys: []string{"context_servers"},
|
|
})
|
|
}
|
|
if env.Mode != agents.ModeGlobal && env.SkillsRouting != "" {
|
|
p.Files = append(p.Files, agents.FileAction{
|
|
Path: filepath.Join(env.Root, ".rules"), Action: agents.ActionWouldMerge,
|
|
Keys: []string{"communities-block"},
|
|
})
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
func (a *Adapter) Apply(env agents.Env, opts agents.ApplyOpts) (*agents.Result, error) {
|
|
res := &agents.Result{Name: Name, DocsURL: DocsURL}
|
|
detected, _ := a.Detect(env)
|
|
res.Detected = detected
|
|
if !detected && !opts.ForceDetect {
|
|
internalutil.Logf(env.Stderr, "[gortex init] skip Zed setup (zed not detected)")
|
|
return res, nil
|
|
}
|
|
path := userSettingsPath(env.Home)
|
|
if path == "" {
|
|
return res, fmt.Errorf("zed: no user settings path known for %s", runtime.GOOS)
|
|
}
|
|
internalutil.Logf(env.Stderr, "[gortex init] setting up Zed integration...")
|
|
|
|
action, err := agents.MergeJSON(env.Stderr, path, func(root map[string]any, _ bool) (bool, error) {
|
|
servers, ok := root["context_servers"].(map[string]any)
|
|
if !ok {
|
|
servers = make(map[string]any)
|
|
}
|
|
if _, exists := servers["gortex"]; exists && !opts.Force {
|
|
return false, nil
|
|
}
|
|
servers["gortex"] = map[string]any{
|
|
"source": "custom",
|
|
"command": "gortex",
|
|
"args": []string{"mcp"},
|
|
"env": map[string]string{"GORTEX_INDEX_WORKERS": "8"},
|
|
}
|
|
root["context_servers"] = servers
|
|
return true, nil
|
|
}, opts)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
res.Files = append(res.Files, action)
|
|
|
|
// Zed's Agent panel reads `.rules` at the project root on every
|
|
// turn. Write a marker-guarded community-routing block there
|
|
// when skills were generated. Skipped in global mode (the file
|
|
// is per-repo).
|
|
if env.Mode != agents.ModeGlobal && env.SkillsRouting != "" {
|
|
rulesPath := filepath.Join(env.Root, ".rules")
|
|
routingAction, err := agents.UpsertMarkedBlock(env.Stderr, rulesPath, env.SkillsRouting,
|
|
agents.CommunitiesStartMarker, agents.CommunitiesEndMarker, opts)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
res.Files = append(res.Files, routingAction)
|
|
}
|
|
|
|
res.Configured = true
|
|
return res, nil
|
|
}
|