sources

package
v0.22.122 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package sources — concrete IdeaSource implementations.

adr_questions: parses every ADR markdown under wiki/decisions/ for a "## Open questions" section and emits one Idea per numbered or bulleted item. Wiki is gitignored on this repo per operator policy, so a missing wiki/ directory is a silent no-op rather than an error — the source returns an empty slice and lets the orchestrator move on.

Package sources — bench_regression source.

Reads /tmp/clawtool-toolsearch-bench.tsv (the toolsearch BM25 rank-1 hit-rate fixture the autodev cron writes after each manifest tweak) and compares the latest run against a stored baseline at $XDG_CONFIG_HOME/clawtool/ideator/bench-baseline.json. A drop greater than DefaultRegressionThreshold (5pp) emits one Idea so the operator decides whether to chase the regression or roll the baseline forward.

Missing TSV → silent no-op (CI hasn't written one yet). Missing baseline → silent no-op (operator hasn't run `clawtool ideate --baseline-set` yet).

Package sources — ci_failures source.

Calls `gh run list --branch main --status failure --limit 10 --json databaseId,name,headSha,conclusion,event,createdAt` and emits one Idea per failed run. Falls back to a quiet no-op when the gh CLI isn't installed or unauthenticated — the spec calls this a cheap-on-fail signal, not a hard requirement.

Superseded-run filter: a failed run is dropped from the result set when EITHER (a) its head sha is more than MaxCommitsBehind commits behind the current branch tip, OR (b) the same workflow has had a later successful run on the same branch. Both probes use `gh` so they share the same auth + cheap-on-fail story as the main query.

Package sources — manifest_drift source.

Compares the manifest's hardcoded ToolSpec.Description against the *live* description each tool's Register fn emits via `mcp.WithDescription(...)`. Drift here is the v0.22.110 bug class: a hand-edit to one side leaves the search index ranking on stale prose. SyncDescriptionsFromRegistration auto-mirrors at boot, but this source guards against the inverse — someone removing the sync call or accidentally re-introducing the two hand-maintained copies.

Cycle note: this package can't import internal/tools/core (core registers IdeateRun / IdeateApply, which would import sources). The CLI / MCP edge injects the manifest builder via SetManifestBuilder before the orchestrator runs; when nothing is injected the source is a quiet no-op.

Package sources — todos source.

Walks repoRoot for *.go files (using a Go-native walker — no shell-out, no rg dependency) and emits one Idea per TODO / FIXME / XXX comment. DedupeKey is sha1(path + line + comment text) so the same comment surfaces the same id across runs even when other comments above it shift line numbers.

Index

Constants

View Source
const DefaultBenchTSV = "/tmp/clawtool-toolsearch-bench.tsv"

DefaultBenchTSV is the canonical TSV path the autodev cron writes. Columns: query, expected_top1, observed_top1, score.

View Source
const DefaultRegressionThreshold = 0.05

DefaultRegressionThreshold is the rank-1 hit-rate drop that promotes a TSV row into an Idea. 5pp is loud enough that the operator wants to know, quiet enough that single-test variance (one query per ideate cycle) doesn't trip it constantly.

Variables

This section is empty.

Functions

func DefaultBenchBaselinePath

func DefaultBenchBaselinePath() string

DefaultBenchBaselinePath returns $XDG_CONFIG_HOME/clawtool/ideator/bench-baseline.json.

func SetDefaultManifestProvider

func SetDefaultManifestProvider(p ManifestProvider)

SetDefaultManifestProvider lets the CLI / MCP edge inject a manifest builder. internal/cli/ideate.go calls this at init so every freshly-constructed ManifestDrift picks up the canonical builder; the function is safe to call multiple times.

Types

type ADRQuestions

type ADRQuestions struct{}

ADRQuestions implements IdeaSource. Construct via NewADRQuestions.

func NewADRQuestions

func NewADRQuestions() *ADRQuestions

NewADRQuestions returns a ready-to-use ADR question miner.

func (ADRQuestions) Name

func (ADRQuestions) Name() string

Name returns the canonical source name used by --source filters.

func (ADRQuestions) Scan

func (a ADRQuestions) Scan(ctx context.Context, repoRoot string) ([]ideator.Idea, error)

Scan walks repoRoot/wiki/decisions/*.md. Missing directory is a silent no-op (wiki/ is gitignored on this repo). Each line under "## Open questions" that begins with `-`, `*`, or a numbered list marker becomes one Idea. The DedupeKey is sha1(adr-path + question text) so an unedited file produces stable IDs across runs.

type Baseline

type Baseline struct {
	HitRate    float64 `json:"hit_rate"`
	NumQueries int     `json:"num_queries"`
	WrittenAt  string  `json:"written_at"`
}

Baseline is the on-disk JSON shape the operator writes via `clawtool ideate --baseline-set`. HitRate is rank-1 (top-1 correct count / total queries).

func SaveBaseline

func SaveBaseline(tsvPath, baselinePath string) (Baseline, error)

SaveBaseline writes the current TSV's hit rate to the baseline path. CLI's `--baseline-set` calls this. Exposed at package level so the orchestrator + CLI share one writer.

type BenchRegression

type BenchRegression struct {
	// TSVPath overrides DefaultBenchTSV (tests inject tmpdir).
	TSVPath string
	// BaselinePath overrides the default baseline location.
	BaselinePath string
	// Threshold is the hit-rate drop (0..1) at which an Idea fires.
	Threshold float64
}

BenchRegression implements IdeaSource for the BM25 baseline diff.

func NewBenchRegression

func NewBenchRegression() *BenchRegression

NewBenchRegression returns a ready-to-use BM25 baseline-diff source with default paths and threshold.

func (BenchRegression) Name

func (BenchRegression) Name() string

Name returns the canonical source name.

func (BenchRegression) Scan

func (b BenchRegression) Scan(ctx context.Context, repoRoot string) ([]ideator.Idea, error)

Scan loads the latest TSV results, computes the rank-1 hit rate, compares against the baseline, and emits one Idea when the drop exceeds Threshold.

type CIFailures

type CIFailures struct {
	// Branch is the branch to inspect (default "main").
	Branch string
	// Limit caps how many failed runs gh returns (default 10).
	Limit int
	// GHBinary lets tests inject a stub binary; defaults to "gh".
	GHBinary string
	// Timeout caps the gh subprocess (default 10s).
	Timeout time.Duration
	// MaxCommitsBehind drops failures whose head sha is more than
	// this many commits behind the current branch tip (default 20).
	// Set to 0 to disable the distance probe.
	MaxCommitsBehind int
	// GitBinary lets tests inject a stub `git`; defaults to "git".
	// Used by the distance probe (`git rev-list --count A..HEAD`).
	GitBinary string
	// SkipSupersededByGreen toggles the per-workflow "later green
	// run" probe. Default true. Tests that don't want to stub gh's
	// success query can disable it.
	SkipSupersededByGreen bool
}

CIFailures implements IdeaSource. Construct via NewCIFailures.

func NewCIFailures

func NewCIFailures() *CIFailures

NewCIFailures returns a ready-to-use ci_failures miner.

func (CIFailures) Name

func (CIFailures) Name() string

Name returns the canonical source name.

func (CIFailures) Scan

func (c CIFailures) Scan(ctx context.Context, repoRoot string) ([]ideator.Idea, error)

Scan calls gh, parses JSON, returns one Idea per failed run. Missing gh / network failure / auth failure → empty + nil error.

Superseded runs (head sha far behind tip, OR a newer green run on the same workflow) are dropped before any Idea is emitted.

type ManifestDrift

type ManifestDrift struct {
	// Provider returns the manifest to inspect. nil → silent no-op.
	Provider ManifestProvider
}

ManifestDrift implements IdeaSource by diffing the manifest spec descriptions against what each Register fn registers live.

func NewManifestDrift

func NewManifestDrift() *ManifestDrift

NewManifestDrift returns a ready-to-use manifest-drift detector. Provider must be wired separately via SetProvider or by direct field assignment; the CLI / MCP edge does this in internal/cli/ideate.go and internal/tools/core/ideator_tool.go (those layers can import core without creating a cycle).

func (ManifestDrift) Name

func (ManifestDrift) Name() string

Name returns the canonical source name.

func (ManifestDrift) Scan

func (m ManifestDrift) Scan(ctx context.Context, repoRoot string) ([]ideator.Idea, error)

Scan compares each registered spec description against the live `mcp.WithDescription` value. Mismatches surface as Ideas pointing the operator at SyncDescriptionsFromRegistration.

func (*ManifestDrift) SetProvider

func (m *ManifestDrift) SetProvider(p ManifestProvider)

SetProvider lets a caller swap the manifest builder (tests use this to feed a hand-built manifest with deliberately drifted descriptions).

type ManifestProvider

type ManifestProvider func() *registry.Manifest

ManifestProvider returns the live MCP tool manifest. The CLI / MCP edge wraps core.BuildManifest into this shape so this package stays free of an import cycle.

type TODOs

type TODOs struct {
	// MaxIdeas caps the source's emit count so a repo with hundreds
	// of TODOs doesn't drown the orchestrator's top-K. Default 50.
	MaxIdeas int
	// SkipDirs are directory names skipped during the walk
	// (default: vendor, node_modules, .git, .clawtool, dist, bin).
	SkipDirs []string
	// SkipPathFragments are forward-slash substrings; any path that
	// contains one (case-insensitive) is dropped before parsing.
	// Default value covers Go module cache, Claude Code plugin
	// install/cache dirs, Obsidian wiki, vendor / node_modules,
	// and .git in case the walker misses them via a symlink.
	SkipPathFragments []string
}

TODOs implements IdeaSource by mining TODO/FIXME/XXX comments from *.go files.

func NewTODOs

func NewTODOs() *TODOs

NewTODOs returns a ready-to-use TODO/FIXME/XXX miner with sane skip defaults.

func (TODOs) Name

func (TODOs) Name() string

Name returns the canonical source name.

func (TODOs) Scan

func (t TODOs) Scan(ctx context.Context, repoRoot string) ([]ideator.Idea, error)

Scan walks repoRoot in-process. Cheap-on-fail: read errors on individual files become silent skips so one weird file doesn't hide every other TODO.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL