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


// 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