Documentation
¶
Overview ¶
Package agents (this file): the sidecar manifest written next to SKILL.md at install time (D-03, D-04). The manifest records which binary version wrote the installed skill package and a content hash for every artifact codegraph wrote, so "which version is installed" is observable from the installed files rather than inferred from whatever binary happens to be on $PATH, and so codegraph upgrade has something to discover (AGENT-03).
The manifest's hash is a drift signal only — it is NOT a tamper-detection or authenticity control. It protects a file any local process can freely rewrite, and carries no signature: a hash mismatch means "codegraph's own content was hand-edited since the last write," nothing more. D-05 fixes the response to a mismatch as a silent overwrite, deliberately with no prompt, no warning, and no new flag. No code in this package may treat a hash mismatch as a security event.
Package agents implements the codegraph install/uninstall subsystem: the AgentTarget interface, one implementation per roster agent (Claude Code, Cursor, Codex CLI, opencode, Hermes, Gemini CLI, Antigravity, Kiro), and the shared surgical-write helpers every target uses to edit external agent config files in place. Install/uninstall logic lives here — never in internal/cli, which only resolves flags/paths and delegates (D-02).
This package writes external tool config files; it never reads or mutates the project's own graph store, indexer, or query engine packages (phase 6 boundary discipline) — install/uninstall never touch the graph.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DetectAll ¶
func DetectAll(loc Location) map[TargetID]DetectionResult
DetectAll runs Detect(loc) for every registered target, keyed by TargetID — the source data behind --target auto's detected-only default and the interactive multi-select's prefilled selection (D-03).
Types ¶
type AgentTarget ¶
type AgentTarget interface {
// ID returns this target's stable registry key.
ID() TargetID
// DisplayName returns the agent's human-readable name for CLI output
// and the interactive multi-select (D-03).
DisplayName() string
// SupportsLocation reports whether this target accepts loc. Codex,
// Antigravity, and Hermes are global-only and return false for
// LocationLocal (D-03, D-05).
SupportsLocation(loc Location) bool
// Detect reports whether the agent is installed and whether
// codegraph is already configured for it at loc, driving --target
// auto's detected-only default (D-03).
Detect(loc Location) DetectionResult
// Install writes (or updates, idempotently) this agent's MCP config
// entry and, for the 4 agents that get one, its marker-fenced
// instructions file (D-01a, D-07).
Install(loc Location, opts InstallOptions) WriteResult
// Uninstall reverses everything Install wrote for this target/loc,
// preserving every unrelated key/section in every file it touches
// (D-02, D-07, D-08). Never errors on a target that was never
// installed.
Uninstall(loc Location) WriteResult
// DescribePaths returns every config/instructions file path this
// target reads or writes at loc, for --print-config-style reporting
// and test assertions.
DescribePaths(loc Location) []string
}
AgentTarget is the interface every roster agent implements; the registry (registry.go) iterates it so install/uninstall never branch on agent identity outside a target's own file (D-02).
func AllTargets ¶
func AllTargets() []AgentTarget
AllTargets returns every registered AgentTarget, in the same sorted order as AllTargetIDs.
func GetTarget ¶
func GetTarget(id TargetID) (AgentTarget, bool)
GetTarget returns the registered AgentTarget for id, if any.
func ResolveTargetFlag ¶
func ResolveTargetFlag(spec string, loc Location) ([]AgentTarget, error)
ResolveTargetFlag resolves the --target flag's value at loc into a concrete, TargetID-sorted list of AgentTarget (D-03):
- "all": every registered target
- "none": no targets
- "auto": only targets whose Detect(loc).Installed is true; if that detects zero targets, falls back to just the Claude target rather than installing nothing — least-surprise for a clean environment (RESEARCH.md recommendation, not a hard requirement)
- anything else: a comma-separated list of TargetIDs, resolved to exactly those targets; an unknown id in the list is an error
type DetectionResult ¶
type DetectionResult struct {
// Installed is true when the agent's own config dir/primary file
// exists, independent of whether codegraph has been configured for it.
Installed bool
// AlreadyConfigured is true when the codegraph MCP entry (and/or
// marker block) is already present for this target/location.
AlreadyConfigured bool
// ConfigPath is the primary config file path this detection checked,
// surfaced for install/uninstall status reporting.
ConfigPath string
}
DetectionResult reports whether an agent is installed on this machine and whether codegraph is already configured for it, used by --target auto (D-03) to decide which targets to configure without prompting.
type FileAction ¶
type FileAction string
FileAction records what happened to one file during Install/Uninstall, using the same per-file action enum the marker contract defines (D-07, D-08).
const ( // ActionCreated: the file did not exist before this write. ActionCreated FileAction = "created" // ActionUpdated: the file existed and its content changed. ActionUpdated FileAction = "updated" // ActionUnchanged: the file existed and already matched the desired // content — no write performed (D-07 idempotency: re-running install // twice is a byte-level no-op). ActionUnchanged FileAction = "unchanged" // ActionRemoved: uninstall deleted the codegraph entry/section, and // the file was rewritten (or removed entirely) to reflect that. ActionRemoved FileAction = "removed" // ActionNotFound: uninstall found nothing to remove — the file didn't // exist or had no codegraph entry (D-08: never errors in this case). ActionNotFound FileAction = "not-found" // ActionKept: a file was left untouched on purpose (e.g. a marker // block target that had no markers present). ActionKept FileAction = "kept" )
type FileResult ¶
type FileResult struct {
// Path is the file that was read/written (or would have been).
Path string
// Action is what happened to Path (D-07/D-08).
Action FileAction
}
FileResult is one file's outcome from an Install/Uninstall call.
type InstallOptions ¶
type InstallOptions struct {
// AutoAllow, when true, additionally writes
// permissions.allow += ["mcp__codegraph__*"] to Claude Code's
// settings.json (Claude-only; a no-op for every other target, D-05).
AutoAllow bool
// ExecPath is the absolute path to the running codegraph binary,
// resolved once by the CLI via os.Executable() and passed down so
// every agent's MCP command entry launches the exact binary the user
// ran `install` from, not a PATH guess (D-04).
ExecPath string
}
InstallOptions carries per-run install configuration threaded down from the CLI to every AgentTarget.Install call.
type Location ¶
type Location string
Location is the install/uninstall scope: a per-user (global) config or a per-project (local) config. Not every agent supports both — Codex, Antigravity, and Hermes are global-only (D-03, D-05).
func ConfiguredSkillLocations ¶ added in v0.10.0
ConfiguredSkillLocations reports every location that carries evidence of a prior codegraph install for id — a readable manifest, OR one that exists but failed to parse — by probing the two fixed candidate manifest paths, never by walking the filesystem. A present-but-corrupted manifest is proof the location was configured before, exactly as much proof as a readable one; excluding it would let a corrupted manifest silently drop that location from every future `codegraph upgrade` refresh with no warning anywhere (code review WR-04), even though writeManifest self-heals a corrupted manifest the moment Install() next runs there. Only a genuinely absent manifest (no error, not present) means "never configured" and is excluded. Exported because Plan 04's CLI-layer upgrade refresh needs it. Returns nil for any target id other than Claude, since this phase is Claude-only by scope: discovery is two stat calls for a phase deliberately narrowed to one agent, and anything more general is unneeded generality here.
type TargetID ¶
type TargetID string
TargetID is the stable registry key for one roster agent (D-02). Used by --target csv parsing, the registry map, and the interactive multi-select — never derived from DisplayName, which may change wording over time.
func AllTargetIDs ¶
func AllTargetIDs() []TargetID
AllTargetIDs returns every registered TargetID, sorted ascending. Map iteration order is non-deterministic in Go, so this sort is load-bearing — not cosmetic — for --target all and the interactive multi-select's display order (D-03).
type WriteResult ¶
type WriteResult struct {
// Files lists every file this call touched, in the order they were
// written.
Files []FileResult
// Notes carries agent-specific advisory text surfaced to the user
// (e.g. Kiro's "enable MCP in Settings" reminder); empty for most
// targets.
Notes []string
// Errors carries every I/O error encountered while writing/removing a
// file this call attempted to touch — path context is included in
// each error's message. A non-empty Errors means the corresponding
// file's Install/Uninstall step did NOT complete, so the caller (the
// CLI's install/uninstall commands) MUST surface these and report a
// non-zero exit rather than a silent "unchanged"/"not-configured"
// (CR-01: a swallowed write error must never look like a no-op).
Errors []error
}
WriteResult is the full outcome of one AgentTarget.Install/Uninstall call — every file touched, plus any human-readable notes (e.g. D-08's "MCP support is disabled by default in Kiro IDE" install-time note).