Gitmoot treats Codex, Claude Code, Kimi Code, and shell commands as runtime adapters behind one interface. Workflow, daemon, and GitHub code should stay runtime-neutral.
An adapter implements runtime.Adapter:
type Adapter interface {
Name() string
Start(ctx context.Context, request StartRequest) (StartResult, error)
Validate(ctx context.Context, agent Agent) error
Deliver(ctx context.Context, agent Agent, job Job) (Result, error)
Health(ctx context.Context, agent Agent) error
Capabilities(ctx context.Context) ([]string, error)
}Responsibilities:
Namereturns the runtime key used bygitmoot agent startandgitmoot agent subscribe.Startcreates a new runtime session forgitmoot agent startand returns the runtime reference Gitmoot should store.Validatechecks the agent record without doing unnecessary work.Deliverresumes or invokes the runtime with the rendered job prompt and returns raw output.Healthperforms a small operational check that proves the runtime can accept a job.Capabilitiesadvertises actions such asreview,implement, andask.
Adapters receive a normalized runtime.Agent:
type Agent struct {
Name string
Role string
Runtime string
RuntimeRef string
RepoScope string
TemplateID string
Capabilities []string
AutonomyPolicy string
HealthStatus string
}RuntimeRef is runtime-specific. Codex accepts a session UUID, thread name, or
last. Claude accepts a UUID or last. Kimi accepts a Kimi session id of the
form session_<uuid> or empty. Shell uses the configured command.
TemplateID is Gitmoot-owned metadata. Adapters do not fetch or interpret template
content; Gitmoot snapshots cached template instructions into the rendered prompt
before delivery.
gitmoot agent start uses the adapter Start method to create a new session
without leaving an interactive terminal open. The startup prompt tells the
runtime to initialize only, make no file edits, and reply with a short readiness
acknowledgment.
Codex startup runs in the repo checkout path:
codex exec --json -- '<startup-prompt>'The adapter parses JSONL stdout and stores the first
thread.started.thread_id. Future jobs resume that session with:
codex exec resume <session-id> -- '<job-prompt>'Claude startup generates a UUID before invocation, then runs:
claude --session-id <uuid> -p --output-format json -- '<startup-prompt>'The UUID is stored only after the command succeeds. Future jobs use the Claude
adapter's resume path. This depends on the installed Claude Code CLI supporting
the documented --session-id, -p, --output-format json, and --resume
contract.
Kimi startup runs in the repo checkout path:
kimi -p '<startup-prompt>' --output-format stream-jsonThe adapter parses the stream-json output and stores the reported session id. Future jobs resume that session with:
kimi -S <session-id> -p '<job-prompt>' --output-format stream-jsonKimi runs against a logged-in Kimi CLI. Run kimi login, then restart the
Gitmoot daemon so it inherits the session.
Shell adapters do not support agent start; register shell commands with
agent subscribe.
Gitmoot sends adapters a runtime.Job:
type Job struct {
ID string
AgentName string
Action string
Prompt string
Repository string
PullRequest int
}The prompt already includes repo, branch, PR number, task label, sender,
requested action, cached template instructions when present, constraints, and the
required gitmoot_result JSON shape. Adapters should pass the prompt through
without rewriting workflow semantics.
Deliver should return raw runtime output. Gitmoot parses the
gitmoot_result object after delivery. If the runtime returns structured JSON
with a nested text result, the adapter may also fill Result.Summary, but raw
output must be preserved for parsing and diagnostics.
- Add a runtime constant in
internal/runtime/adapter.go. - Implement an adapter type in
internal/runtime. - Register it in
runtime.Factory.Adapter. - Extend
ValidateAgentonly for runtime-specific reference rules. - Implement startup semantics or return a clear unsupported error from
Start. - Add tests for startup command arguments, validation, delivery command arguments, error handling, health checks, and capability reporting.
- Add or update docs for the runtime-specific
--sessionand startup values.
Keep runtime-specific command names, flags, JSON modes, session lookup, and fallback behavior inside the adapter package. Do not leak Codex or Claude assumptions into workflow, daemon, GitHub, database, or merge-gate code.
Agent Templates are prompt/profile bundles layered above runtimes. They are not runtime adapters and should not create adapter-specific behavior. Gitmoot snapshots cached template content into startup and job prompts before invoking an adapter.
The built-in thermo-nuclear-code-quality-review template is fetched explicitly
with:
gitmoot agent template update thermo-nuclear-code-quality-reviewAfter it is cached, bind it to a normal runtime-backed agent:
gitmoot agent start thermo-review \
--runtime codex \
--repo owner/repo \
--template thermo-nuclear-code-quality-reviewThe thermo template is non-mutating. It supplies reviewer defaults and allows
ask,review, but it cannot grant implement.
Local custom agent templates are installed from files:
gitmoot agent template validate agents/frontend-reviewer.md
gitmoot agent template add frontend-reviewer --file agents/frontend-reviewer.mdThey store local@file:<absolute-path> metadata and a sha256:<hash> resolved
identifier. Adapters should not read those files or decide how agent templates behave;
workflow code passes only the rendered prompt. After a template file changes, the
user must run gitmoot agent template update <custom-id> before new jobs use the new
content.
The shell adapter is useful for experiments and contract tests. It invokes:
sh -c '<configured command>' gitmoot '<job prompt>'Health checks invoke:
sh -c '<configured command>' gitmoot-health 'Gitmoot health check. Reply OK only.'The command must print a valid gitmoot_result object for normal jobs.