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
91 lines
3.1 KiB
Go
91 lines
3.1 KiB
Go
// Package continuedev implements the Gortex init integration for
|
|
// Continue.dev. Today we write .continue/mcpServers/gortex.json
|
|
// (the legacy split-file layout); the Step 3 audit revisits whether
|
|
// Continue's current canonical form is an inline block inside
|
|
// config.yaml.
|
|
package continuedev
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/zzet/gortex/internal/agents"
|
|
"github.com/zzet/gortex/internal/agents/internalutil"
|
|
)
|
|
|
|
const Name = "continue"
|
|
const DocsURL = "https://docs.continue.dev/customize/deep-dives/mcp"
|
|
|
|
type Adapter struct{}
|
|
|
|
func New() *Adapter { return &Adapter{} }
|
|
func (a *Adapter) Name() string { return Name }
|
|
func (a *Adapter) DocsURL() string { return DocsURL }
|
|
|
|
func (a *Adapter) Detect(env agents.Env) (bool, error) {
|
|
if _, err := os.Stat(filepath.Join(env.Root, ".continue")); err == nil {
|
|
return true, nil
|
|
}
|
|
if env.Home != "" {
|
|
if _, err := os.Stat(filepath.Join(env.Home, ".continue")); err == nil {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func (a *Adapter) Plan(env agents.Env) (*agents.Plan, error) {
|
|
p := &agents.Plan{Files: []agents.FileAction{
|
|
{Path: filepath.Join(env.Root, ".continue", "mcpServers", "gortex.json"), Action: agents.ActionWouldMerge, Keys: []string{"mcpServers"}},
|
|
}}
|
|
if env.Mode != agents.ModeGlobal && env.SkillsRouting != "" {
|
|
p.Files = append(p.Files, agents.FileAction{
|
|
Path: filepath.Join(env.Root, ".continue", "rules", "gortex-communities.md"), Action: agents.ActionWouldCreate,
|
|
Keys: []string{"communities-rule"},
|
|
})
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
func (a *Adapter) Apply(env agents.Env, opts agents.ApplyOpts) (*agents.Result, error) {
|
|
res := &agents.Result{Name: Name, DocsURL: DocsURL}
|
|
// Global mode: Continue.dev's MCP config is project-scoped only;
|
|
// nothing to install user-wide today.
|
|
if env.Mode == agents.ModeGlobal {
|
|
return res, nil
|
|
}
|
|
detected, _ := a.Detect(env)
|
|
res.Detected = detected
|
|
if !detected && !opts.ForceDetect {
|
|
internalutil.Logf(env.Stderr, "[gortex init] skip Continue.dev setup (Continue not detected)")
|
|
return res, nil
|
|
}
|
|
internalutil.Logf(env.Stderr, "[gortex init] setting up Continue.dev integration...")
|
|
|
|
path := filepath.Join(env.Root, ".continue", "mcpServers", "gortex.json")
|
|
action, err := agents.MergeJSON(env.Stderr, path, func(root map[string]any, _ bool) (bool, error) {
|
|
return agents.UpsertMCPServer(root, "gortex", agents.DefaultGortexMCPEntry(), opts), nil
|
|
}, opts)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
res.Files = append(res.Files, action)
|
|
|
|
// Continue reads .continue/rules/*.md on every chat turn. The
|
|
// community-routing file is ours end-to-end — regenerated each
|
|
// `gortex init` run so the listing tracks the current graph.
|
|
// Skipped when --no-skills / no communities qualify.
|
|
if env.SkillsRouting != "" {
|
|
rulesPath := filepath.Join(env.Root, ".continue", "rules", "gortex-communities.md")
|
|
body := agents.CommunitiesStartMarker + "\n" + env.SkillsRouting + "\n" + agents.CommunitiesEndMarker + "\n"
|
|
ruleAction, err := agents.WriteOwnedFile(env.Stderr, rulesPath, body, opts)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
res.Files = append(res.Files, ruleAction)
|
|
}
|
|
|
|
res.Configured = true
|
|
return res, nil
|
|
}
|