feat(trail): add `entire trail tune` to tailor runner prompts to the repo · Entire
feat(trail): add entire trail tune to tailor runner prompts to the repo
7752487·Soph·3w ago·7 files·+1,212 added/-0 removed
entire trail tune [<runner>] gathers signal about the current repo across four best-effort, gracefully-degrading tiers — repo docs/structure, merged PRs and issues (via gh), checkpoint churn hotspots, and past trail findings — and produces a prompt that rewrites the .entire/runners/*.json templates so their dimensions and score bands fit this repo instead of the generic defaults.
By default it prints the prompt for pasting into an agent. With --run it executes the prompt headlessly through the configured summary provider and surgically rewrites only each runner's prompt.template via byte-level replacement, leaving all other fields and formatting byte-for-byte intact (minimal git diff; files are git-tracked so the user reviews via git diff).
The CLI has no runner struct/loader (the backend consumes these files and substitutes {{placeholders}}), so runners are treated as opaque text.
Unit tests cover output parsing, surgical template replacement, runner loading/filtering, source-flag parsing, and prompt assembly.
Sessions
Changes
7
cmd/entire/cli
Mtrail_cmd.go+1
Atrail_tune_apply.go+156
Atrail_tune_apply_test.go+175
Atrail_tune_cmd.go+180
Atrail_tune_gather.go+390
Atrail_tune_prompt.go+159
Cmd/entire/cli/trail_cmd.go+1
// parseTuneOutput extracts the runner-id -> new-template map the tuning model
// is instructed to emit as a single JSON object.
// ...
func parseTuneOutput(text string) (map[string]string, error) {
//...
}
package cli
import (
"encoding/json"
"testing"
)
const sampleRunner = `{ "id": "trail-risk", "display_name": "Risk Eval", "enabled": true, ... }
`
func TestReplaceRunnerTemplate_SurgicalPreservesOtherFields(t *testing.T) {
//...
}
// validateNewTemplate rejects a rewritten template...
func validateNewTemplate(oldTemplate, newTemplate string) error {
//...
}
// extractJSONObject returns the outermost {...} span in text,
// after stripping any surrounding markdown code fences. Returns "" when none is found.
func extractJSONObject(text string) string {
//...
}
// replaceRunnerTemplate swaps only the prompt.template value inside a runner
// JSON document...
func replaceRunnerTemplate(raw []byte, newTemplate string) ([]byte, error) {
//...
}
// encodeJSONString encodes s as a JSON string without HTML escaping,
// so characters like <, >, and & stay literal...
func encodeJSONString(s string) ([]byte, error) {
//...
}
package cli
import (
"testing"
)
const sampleRunner = `...
`
func TestReplaceRunnerTemplate_Errors(t *testing.T) {
//...
}
// gatherTuningContext builds the markdown "tuning brief" from the selected
// tiers. Every tier is best-effort: a tier that is unavailable (no gh,...
func gatherTuningContext(ctx context.Context, errW io.Writer, repoRoot string, src tuneSources, limit int, insecureHTTP bool) string {
//...
}
// buildTunePrompt assembles the full instruction prompt...
func buildTunePrompt(brief string, runners []tuneRunner) string {
//...
}
package cli
import (
"io"
"os"
)
func applyTuneWithAgent(ctx context.Context, w, errW io.Writer, runners []tuneRunner, prompt string) error {
//...
}
Additional Information
- The README.md file contains instructions for setting up the repository, and details about the CLI commands that can be executed related to trail tuning.
- Make sure to handle exceptions and edge cases when implementing the
entire trail tunefunctionality.