mirror of
https://github.com/lukaszraczylo/harness-sync.git
synced 2026-10-12 00:45:22 +00:00
Add Rule as a first-class canonical kind (rules/<name>.md, loaded like agents) and propagate it the way each harness actually loads it: - claude-code: native ~/.claude/rules directory symlink (preserves rule path-scoping frontmatter); rules NOT folded into CLAUDE.md. - opencode/kilo/zed/crush: fold rule bodies into the global AGENTS.md always-on instructions file (frontmatter stripped). crush has no global instructions file, so register the absolute AGENTS.md path in options.context_paths (defaults are re-prepended at load, so nothing is clobbered). - goose: fold into ~/.config/goose/.goosehints. - cagent: fold into the per-agent instruction. Also: - Wire markdown agents to opencode (~/.config/opencode/agents) and fix the kilo agents symlink: plural ~/.config/kilo/agents (singular "agent" is a silent no-op on current Kilo CLI). - Add ManagesAgents/ManagesRules to HarnessCapabilities + ImportResult.Rules; claude-code/opencode import rules/agents round-trip. - Centralize instruction selection in Bundle.InstructionText / InstructionTextWithRules (replaces per-adapter override duplication). - init scaffolds + imports rules; README capability matrix gains Agents/Rules columns with native-vs-folded footnotes. Grounded each harness's sink against official docs + config source this session. Gate: gofmt, go vet, go test -race ./..., golangci-lint (0), govulncheck (clean).
102 lines
2.4 KiB
Go
102 lines
2.4 KiB
Go
// Package canonical defines the source-of-truth domain types for harness-sync.
|
|
package canonical
|
|
|
|
type Config struct {
|
|
Paths Paths `yaml:"paths,omitempty"`
|
|
ActiveProfile string `yaml:"active_profile"`
|
|
EnabledHarnesses []string `yaml:"enabled_harnesses"`
|
|
}
|
|
|
|
type Paths struct {
|
|
Skills string `yaml:"skills,omitempty"`
|
|
Agents string `yaml:"agents,omitempty"`
|
|
Instructions string `yaml:"instructions,omitempty"`
|
|
}
|
|
|
|
type Profile struct {
|
|
Name string `yaml:"name"`
|
|
Gateway Gateway `yaml:"gateway"`
|
|
Upstreams []Upstream `yaml:"upstreams,omitempty"`
|
|
Models []Model `yaml:"models"`
|
|
}
|
|
|
|
type Gateway struct {
|
|
URL string `yaml:"url"`
|
|
Token string `yaml:"token"`
|
|
DefaultModel string `yaml:"default_model"`
|
|
}
|
|
|
|
type Upstream struct {
|
|
Name string `yaml:"name"`
|
|
APIKey string `yaml:"api_key,omitempty"`
|
|
BaseURL string `yaml:"base_url,omitempty"`
|
|
}
|
|
|
|
type Model struct {
|
|
ID string `yaml:"id"`
|
|
Alias string `yaml:"alias,omitempty"`
|
|
}
|
|
|
|
type MCPRegistry struct {
|
|
Servers []MCPServer `yaml:"servers"`
|
|
}
|
|
|
|
type MCPServer struct {
|
|
Env map[string]string `yaml:"env,omitempty"`
|
|
Headers map[string]string `yaml:"headers,omitempty"`
|
|
Name string `yaml:"name"`
|
|
Command string `yaml:"command,omitempty"`
|
|
URL string `yaml:"url,omitempty"`
|
|
Transport string `yaml:"transport,omitempty"`
|
|
Args []string `yaml:"args,omitempty"`
|
|
}
|
|
|
|
type Skill struct {
|
|
Name string
|
|
Description string
|
|
Body string
|
|
Path string
|
|
}
|
|
|
|
type Agent struct {
|
|
Name string
|
|
Description string
|
|
Body string
|
|
Path string
|
|
}
|
|
|
|
// Rule is a topic-scoped instruction fragment (e.g. ~/.claude/rules/go.md).
|
|
// Claude Code auto-loads a directory of these; harnesses without a native rules
|
|
// directory receive the bodies folded into their global instructions file.
|
|
type Rule struct {
|
|
Name string
|
|
Description string
|
|
Body string
|
|
Path string
|
|
}
|
|
|
|
type Instructions struct {
|
|
PerHarness map[string]string
|
|
Global string
|
|
}
|
|
|
|
type Bundle struct {
|
|
Config Config
|
|
Instructions Instructions
|
|
Root string
|
|
Profile Profile
|
|
Skills []Skill
|
|
Agents []Agent
|
|
Rules []Rule
|
|
MCP MCPRegistry
|
|
}
|
|
|
|
func (p *Profile) LookupModel(alias string) (Model, bool) {
|
|
for _, m := range p.Models {
|
|
if m.Alias == alias || m.ID == alias {
|
|
return m, true
|
|
}
|
|
}
|
|
return Model{}, false
|
|
}
|