Documentation
¶
Overview ¶
Package decisionlog captures the decisions of the coding-agent sessions on this machine and keeps them in a private local store. See README.md.
Index ¶
- Constants
- Variables
- func DefaultDecisionModel(backend string) string
- func LocalClones(registry TimelineRegistry) func(context.Context, string) TimelineClone
- type API
- type AssignReport
- type Attempt
- type BuildEstimate
- type BuildOptions
- type BuildProgress
- type BuildReport
- type Capturer
- type ConsolidateReport
- type Decision
- type DecisionView
- type DiscoverReport
- type Effective
- type Extraction
- type FeatureOptions
- type FeatureRegistry
- type FeatureWorker
- func (w *FeatureWorker) Assign(ctx context.Context, repository, dir string, o FeatureOptions) (AssignReport, error)
- func (w *FeatureWorker) Build(ctx context.Context, repository, dir string, o BuildOptions) (BuildReport, error)
- func (w *FeatureWorker) Consolidate(ctx context.Context, repository, dir string, o FeatureOptions) (ConsolidateReport, error)
- func (w *FeatureWorker) Discover(ctx context.Context, repository, dir string) (DiscoverReport, error)
- func (w *FeatureWorker) EstimateBuild(ctx context.Context, repository, dir string, o BuildOptions) (BuildEstimate, error)
- func (w *FeatureWorker) Index(ctx context.Context, repository, dir string, fresh []gitlocal.Commit, ...) (IndexReport, error)
- func (w *FeatureWorker) ListHistory(ctx context.Context, repository string) (HistoryReport, error)
- func (w *FeatureWorker) PlanBuild(ctx context.Context, repository, dir string, o BuildOptions) (backend, model, reason string, err error)
- func (w *FeatureWorker) Run(ctx context.Context)
- func (w *FeatureWorker) RunOnce(ctx context.Context)
- func (w *FeatureWorker) Summarize(ctx context.Context, repository, dir string, o FeatureOptions) (SummaryReport, error)
- func (w *FeatureWorker) Sync(ctx context.Context, repository, dir string) (SyncReport, error)
- func (w *FeatureWorker) Wake()
- type FlowPull
- type HistoryReport
- type IndexReport
- type LedgerEntry
- type LinkedSessions
- type Meta
- type OpenOptions
- type Options
- type Person
- type PlacedItem
- type PullCommit
- type PullRequestDecisions
- type PullRequestSession
- type PullSync
- type Registry
- type Report
- type ResolvedFeature
- type SampleDecisionRef
- type SampleFeature
- type Scheduler
- type Session
- type SessionCommit
- type SessionDecisions
- type SessionKey
- type Source
- type Stats
- type Store
- func (s *Store) Activate(ctx context.Context, repository string) (PullSync, error)
- func (s *Store) Begin(ctx context.Context, a Attempt) (int64, error)
- func (s *Store) Close() error
- func (s *Store) Coverage(ctx context.Context, sessions ...SessionKey) (map[SessionKey][2]string, error)
- func (s *Store) Covered(ctx context.Context, m Meta) error
- func (s *Store) Current(ctx context.Context, sessions ...SessionKey) ([]Decision, error)
- func (s *Store) Failed(ctx context.Context, m Meta) (int, error)
- func (s *Store) Ledger(ctx context.Context, since time.Time) ([]LedgerEntry, error)
- func (s *Store) LiveVersion(ctx context.Context, repository string) (int64, error)
- func (s *Store) PathsFailed(ctx context.Context, repository string, number int, head string) (bool, error)
- func (s *Store) PullFlow(ctx context.Context, repository string, since time.Time) ([]FlowPull, bool, error)
- func (s *Store) PullsWithCommitsSince(ctx context.Context, repository string, since time.Time) ([]StoredPull, error)
- func (s *Store) PullsWithoutPaths(ctx context.Context, repository string) ([]StoredPull, error)
- func (s *Store) ReplaceSessionCommits(ctx context.Context, repository string, shas []string, links []SessionCommit, ...) error
- func (s *Store) ResolveFeature(ctx context.Context, id string) (ResolvedFeature, error)
- func (s *Store) RetryUnknownPaths(ctx context.Context, repository string) error
- func (s *Store) Save(ctx context.Context, e Extraction) error
- func (s *Store) SaveHistoryPulls(ctx context.Context, repository string, pulls []github.ListedPull) error
- func (s *Store) SavePulls(ctx context.Context, repository string, pulls []github.ListedPull, etag string, ...) error
- func (s *Store) SeedSample(ctx context.Context, repository string, pulls []github.ListedPull, ...) error
- func (s *Store) Session(ctx context.Context, agent, id string) (Session, bool, error)
- func (s *Store) SessionLinks(ctx context.Context, repository, agent, sessionID string) (features.SessionLinks, error)
- func (s *Store) Sessions(ctx context.Context, keys ...SessionKey) ([]SessionDecisions, error)
- func (s *Store) SetPath(ctx context.Context, agent, id, path string) error
- func (s *Store) SetPullPaths(ctx context.Context, repository string, number int, head string, ...) error
- func (s *Store) Settle(ctx context.Context, id int64, state, reason string, cost *float64, ...) error
- func (s *Store) Skip(ctx context.Context, m Meta, reason string) error
- func (s *Store) Stats(ctx context.Context, agent, id string, day time.Time) (Stats, error)
- func (s *Store) Taxonomy(ctx context.Context, repository, ref string) (int64, discover.FeatureTaxonomy, error)
- type StoredPull
- type SummarizedFeature
- type SummaryReport
- type SyncReport
- type Target
- type Timeline
- type TimelineClone
- type TimelineRegistry
- type Tracker
- type Worker
Constants ¶
const ( // CaptureOffPaused is the automatic master switch off (the tray's pause). CaptureOffPaused = "paused" // CaptureOffSwitch is the decisions switch off. CaptureOffSwitch = "off" // CaptureOffRepository is the session's repository turning it off. CaptureOffRepository = "repository_off" // CaptureOffNotPicked is a repository that is not picked, or none. CaptureOffNotPicked = "not_picked" )
Why capture does not run for a session (SessionDecisions.CaptureOff).
const ( ReasonTooLarge = "too_large" ReasonUnreadable = "unreadable" ReasonMismatch = "session_mismatch" ReasonGenerationRun = "generation_run" ReasonOverTokenCap = "over_token_cap" ReasonFailed = "extraction_failed" // Transient. ReasonUnsupported = "backend_unsupported" )
Skip reasons. The transient ones are tried again the next day, or when the transcript changes; the others only when it changes.
const ( OutcomeDisabled = "disabled" OutcomeThrottled = "throttled" OutcomeUnchanged = "unchanged" OutcomeSkipped = "skipped" OutcomeHit = "hit" OutcomeDryRun = "dry_run" OutcomeExtracted = "extracted" OutcomeFailed = "failed" // OutcomeAbandoned is a capture the daemon stopping cut short; its // attempt is abandoned and nothing else is recorded. OutcomeAbandoned = "abandoned" )
Outcomes of a capture.
const ( MinInterval = 5 * time.Minute FailureDelay = 10 * time.Minute MaxPerDay = 12 MaxFailures = 3 )
Throttle bounds.
const ( TriggerOpened = "opened" TriggerMerged = "merged" TriggerUpdated = "updated" TriggerQuiet = "quiet" )
Triggers of a placement.
const ( FeatureAssigned = "assigned" FeatureCreated = "created" FeatureSkipped = "skipped" FeatureDeferred = "deferred" FeatureGivenUp = "given_up" FeatureDryRun = "dry_run" )
Outcomes of an item placed or a feature's text.
const ( StageAssign = "feature_assign" StageSummary = "feature_summary" StagePullSummary = "pr_summary" )
Ledger stages of the feature log's calls.
const ( BuildReading = "reading" BuildDiscovering = "discovering" BuildPlacing = "placing" BuildSummarizing = "summarizing" BuildSwitching = "switching" )
Phases of a build.
const ( TaxonomyAuto = "auto" TaxonomyNone = "none" )
Taxonomy choices of a build besides LatestTaxonomy and an id.
const ( // AssignVersion, SummaryVersion and ConsolidateVersion are the published // prompts the feature log calls. AssignVersion = assign.PublicVersion SummaryVersion = summary.PublicVersion ConsolidateVersion = consolidate.PublicVersion // FeatureTick is how often the feature worker runs its stages. FeatureTick = time.Minute // FeatureCandidates is how many candidate features an assignment offers // (K); FeaturePathSlots and FeatureRecentSlots split them between the // candidates ranked by shared paths and the most recent. FeatureCandidates = 16 FeaturePathSlots = FeatureCandidates * 5 / 8 FeatureRecentSlots = FeatureCandidates - FeaturePathSlots // FeatureCandidateWindow is how recently a candidate feature must have // changed. FeatureCandidateWindow = 90 * 24 * time.Hour // FeatureLookback is how far back commits are linked to sessions, and // pull requests and sessions are picked up for assignment. Hosted looks // back a day; a laptop may be off for days, so locally it is a week. FeatureLookback = 7 * 24 * time.Hour // FeatureQuiet is how long a session must have been unchanged before it // is placed, how long a pull request without known paths waits for them // and how long a feature's members must have been unchanged before its // text is written; it is also the debounce of the session window's // re-link. FeatureQuiet = 15 * time.Minute // FeaturePathTries is how many failed reads of a pull request's commits // at one head leave its paths unknown until the daily re-link. FeaturePathTries = 3 // FeatureRelinkEvery is how often every commit of the lookback is linked // again. FeatureRelinkEvery = 24 * time.Hour // FeatureReassignShare and FeatureReassignPaths are the large-update rule // (features.LargeUpdate) for assigning a pull request again. FeatureReassignPaths = 3 // FeatureAssignRunLimit and FeatureSummaryRunLimit bound the items one // run of placement and the features one run of the text stage take. FeatureAssignRunLimit = 100 FeatureSummaryRunLimit = 50 // FeatureSummaryConcurrency is how many features the text stage writes // at once: each feature's text and pull request summaries are calls of // their own. Fewer than a hosted rebuild's, as each local call may be a // CLI process on the user's machine and plan. FeatureSummaryConcurrency = 4 // FeatureBackoff is how long an item or feature whose call failed // waits; after FeatureMaxFailures counted failures for one trigger it // waits for the next. FeatureBackoff = 10 * time.Minute FeatureMaxFailures = 3 // FeatureBatch is how many items one batch assignment holds. FeatureBatch = 25 // FeatureConsolidateEvery is how often a repository's features are // consolidated, when they changed. FeatureConsolidateEvery = 7 * 24 * time.Hour // FeatureSplitPulls and FeatureSplitAge make a feature a split // candidate: more pull requests than that, or pull requests opened // further apart. A pass offers at most FeatureMaxSplits features. FeatureSplitPulls = 30 FeatureSplitAge = 8 * 7 * 24 * time.Hour FeatureMaxSplits = 3 // FeatureConsolidateOutputTokens bounds a merge or split reply. Hosted // uses consolidate.MaxOutputTokens; locally Claude Code's models think // within the reply's bound whatever thinking is set to, and a merge over a // first build's features ran out of it, so local calls get more room. FeatureConsolidateOutputTokens = 4 * consolidate.MaxOutputTokens // FeatureSplitHold is how long after a split a merge undoing it is not // applied. FeatureSplitHold = 4 * 7 * 24 * time.Hour // FeatureFirstSyncWindow is how far back the first sync lists a // repository's pull requests; a first build lists its whole history // (FeatureWorker.ListHistory). FeatureFirstSyncWindow = 180 * 24 * time.Hour // FeatureBuildTries is how many times a first build makes a failed batch // call before splitting it; FeatureBuildCandidates is the most // candidates a batch call offers; FeatureBuildSummarizeEvery is how many // batches go between its text passes. FeatureBuildTries = 2 FeatureBuildCandidates = 40 FeatureBuildSummarizeEvery = 3 )
The feature log's choices, all in one place (README.md, "Feature log"). They follow the hosted feature log's unless a comment says otherwise.
const ( FeatureEstimatePullsPerFeature = 3 FeatureEstimateTextPasses = 2 )
What a build's estimate assumes of what it cannot know beforehand (local only; hosted builds have no estimate): the pull requests a new feature gathers, and how many times a new feature's text is written.
const ( ConsolidationDone = "consolidated" ConsolidationNotDue = "not_due" ConsolidationUnchanged = "unchanged" ConsolidationWaiting = "waiting" )
Outcomes of a consolidation pass besides those of placement.
const ( ReasonNoDefaultBranch = "no_default_branch" // ReasonDiscoveryFailed is followed by the failure's category. ReasonDiscoveryFailed = "discovery_failed" )
Reasons discovery was not run or gave no taxonomy, besides the backend reasons.
const ( VersionBuilding = "building" VersionCurrent = "current" VersionRetired = "retired" )
Feature version states.
const ( FeatureSummarized = "summarized" FeatureReused = "reused" FeatureStale = "stale" FeatureEmpty = "empty" )
Outcomes of a feature's text besides those of placement.
const ( // MaxInputTokens caps a transcript's estimated prompt. MaxInputTokens = 272_000 // MaxOutputTokens caps the reply, and is reserved in full. MaxOutputTokens = 16_384 // MaxTranscriptBytes caps the session's own files. MaxTranscriptBytes = 64 << 20 )
Limits of one capture.
const ( ReasonDisabled = "disabled" ReasonPreferences = "preferences_unreadable" )
Reasons a feature stage call was not made, besides the skip reasons.
const ( ReasonGitAuthSSH = "git_auth_ssh" ReasonGitAuthHTTPS = "git_auth_https" )
Reasons a build stopped because a fetch could not sign in to the remote (see gitlocal.AuthError).
const ( // SettleAfter is how long a session that is not running must have been // quiet: its turn ended, it waits on its user, or it went silent. SettleAfter = 2 * time.Minute // RunningEvery captures a session that keeps running. RunningEvery = 20 * time.Minute // BackstopEvery looks again at every settled session. BackstopEvery = 5 * time.Minute // TickEvery is how often the triggers are evaluated. TickEvery = 30 * time.Second )
Trigger timings (README.md, "When a session is captured").
const ( CoverageExtracted = "extracted" CoverageSkipped = "skipped" )
Coverage of a session.
const ( AttemptPending = "pending" AttemptSucceeded = "succeeded" AttemptFailed = "failed" AttemptAbandoned = "abandoned" )
Attempt states.
const ( TimelinePageSize = 50 TimelineMaxPage = 500 // TimelineFilePage and TimelineMaxFilePage bound /files, as hosted. TimelineFilePage = 20 TimelineMaxFilePage = 50 )
TimelinePageSize is how many rows a list answers with unless asked for more; TimelineMaxPage is the most it answers with.
const CallTimeout = 10 * time.Minute
CallTimeout bounds one model call, as review generation's default pass_timeout bounds one pass: a backend that hangs releases the worker and the attempt fails.
const LatestTaxonomy = "latest"
LatestTaxonomy names a repository's newest taxonomy.
const MaxCachedPrompts = 16
MaxCachedPrompts is how many sessions' prompts the Timeline keeps, the least recently read making room.
const ReasonVersionRetired = "version_retired"
ReasonVersionRetired stops a live run whose version a build's switch retired; the next run uses the new current version.
const StageCapture = "capture"
StageCapture is the ledger stage of a decision capture's call.
const StageConsolidate = "feature_consolidate"
StageConsolidate is the ledger stage of consolidation's calls.
const StageDiscovery = "feature_discovery"
StageDiscovery is the ledger stage of a discovery task.
Variables ¶
var ErrMergeChain = errors.New("merged too many times over")
ErrMergeChain is a feature merged into others too many times over to follow: a broken chain.
Functions ¶
func DefaultDecisionModel ¶
DefaultDecisionModel is the model decision capture uses with backend when the preferences name none: a small, cheap one of the backend's provider.
func LocalClones ¶
func LocalClones(registry TimelineRegistry) func(context.Context, string) TimelineClone
LocalClones is a Timeline's Clone: the first available clone of the picked repository, whose git user.email names this machine's sessions and whose review store holds its saved reviews.
Types ¶
type API ¶
type API struct {
Store *Store
// Registry, when set, says whether capture runs for a session's
// repository, as the capture gate reads it.
Registry Registry
// Live lists the tracked sessions; nil is none.
Live func() []livesessions.Session
// Linked is nil to link none.
Linked LinkedSessions
// Log is nil for slog.Default.
Log *slog.Logger
}
API serves GET /api/decisions: what the app shows of the captured decisions. Like the other local APIs it does not authenticate; mount it only behind the daemon's authenticated, Host/Origin-checked middleware.
func (*API) Handler ¶
Handler serves GET /api/decisions?agent=&session= (one session) and GET /api/decisions?repository=&pr= (the sessions of a pull request: those the tracker links to it, ended ones included, and those its saved review links). Decisions dated after that review was generated are provisional.
type AssignReport ¶
type AssignReport struct {
Repository string `json:"repository"`
// SmallUpdates are the heads judged too small a change to place again.
SmallUpdates int `json:"small_updates"`
Items []PlacedItem `json:"items"`
// Stopped is the reason no further call was made (a backend or price
// reason).
Stopped string `json:"stopped,omitempty"`
Spent float64 `json:"spent_usd"`
}
AssignReport says what Assign did.
type Attempt ¶
type Attempt struct {
Agent, ID, Repository string
Backend, Model string
// Mode is "full" or "extend".
Mode string
Reserved float64
// Stage is the call's stage, "" for capture; Item names what a feature
// stage's call was about.
Stage, Item string
}
Attempt is one model call in the ledger.
type BuildEstimate ¶
type BuildEstimate struct {
Repository string `json:"repository"`
// Version is the building version a build resumes, 0 for a new one.
Version int64 `json:"version,omitempty"`
// PullRequests are those left to place, in Batches calls.
PullRequests int `json:"pull_requests"`
Batches int `json:"batches"`
// Calls are the model calls left, besides discovery's.
Calls int `json:"calls"`
Backend string `json:"backend,omitempty"`
Model string `json:"model,omitempty"`
// Reason is why no call could be made (a backend reason).
Reason string `json:"reason,omitempty"`
// HistoryTruncated says the history listing stopped at its bound: the
// least recently updated pull requests are missing, and the listing is
// not retried.
HistoryTruncated bool `json:"history_truncated,omitempty"`
// Discovery says the build runs feature discovery first, with a review
// run's budgets.
Discovery bool `json:"discovery,omitempty"`
}
BuildEstimate is what a build of the repository would do: how many pull requests it places and calls it makes. It has no cost: prices only report.
type BuildOptions ¶
type BuildOptions struct {
// DryRun estimates and writes nothing.
DryRun bool
// Backend and Model, when set, replace the configured ones.
Backend, Model string
// Gated refuses a repository whose decisions are not captured (the
// gate), with Reason ReasonDisabled.
Gated bool
// Progress, when set, is told after every batch and stage.
Progress func(BuildProgress)
// Taxonomy chooses what a new version is seeded with: TaxonomyAuto
// (empty) a taxonomy made after the version, else a new discovery;
// TaxonomyNone nothing; LatestTaxonomy or an id a stored taxonomy.
Taxonomy string
}
BuildOptions change a first build.
type BuildProgress ¶
type BuildProgress struct {
Phase string `json:"phase"`
// Placed counts the pull requests placed or skipped of Total.
Placed, Total int
Calls int
SpentUSD float64
// Unpriced counts the run's calls whose cost is unknown: SpentUSD is
// then a lower bound.
Unpriced int
}
BuildProgress is a build's progress.
type BuildReport ¶
type BuildReport struct {
Repository string `json:"repository"`
Version int64 `json:"version"`
// PullRequests are those this run listed to place.
PullRequests int `json:"pull_requests"`
Placed int `json:"placed"`
Created int `json:"created"`
Skipped int `json:"skipped"`
// Failed counts the pull requests whose batch failed down to them alone,
// LeftOut those that failed once more and were left out.
Failed int `json:"failed"`
LeftOut int `json:"left_out"`
Calls int `json:"calls"`
Features int `json:"features"`
// Current says the version became current; otherwise Stopped says why
// not (a backend reason, or "failed").
Current bool `json:"current"`
Stopped string `json:"stopped,omitempty"`
SpentUSD float64 `json:"spent_usd"`
VersionSpentUSD float64 `json:"version_spent_usd"`
// UnpricedCalls are the version's calls whose cost is unknown: its spend
// is then at least VersionSpentUSD.
UnpricedCalls int `json:"unpriced_calls,omitempty"`
HistoryTruncated bool `json:"history_truncated,omitempty"`
// Taxonomy is the taxonomy the version was seeded with, 0 for none, and
// Seeds its features; SeedsJoined are those a pull request joined in
// this run and SeedsDeleted those deleted before the switch, still
// empty.
Taxonomy int64 `json:"taxonomy,omitempty"`
Seeds int `json:"seeds,omitempty"`
SeedsJoined int `json:"seeds_joined,omitempty"`
SeedsDeleted int `json:"seeds_deleted,omitempty"`
// Discovery is this run's discovery, nil for none; Unseeded says why a
// new version is built without seeds.
Discovery *DiscoverReport `json:"discovery,omitempty"`
Unseeded string `json:"unseeded,omitempty"`
}
BuildReport says what Build did; no pull request, feature or reply text.
type Capturer ¶
type Capturer struct {
Store *Store
Registry Registry
// Config is the config file's; the preferences and the repository's
// settings are layered on it for every capture.
Config config.Config
// Backends builds the backends; zero is generate.DefaultBackendsFor.
Backends generate.Backends
// Home holds the agents' session stores; empty is the user's home.
Home string
// CursorStore is Cursor's database; empty is its default.
CursorStore string
// Extractor is nil for the published prompt's.
Extractor *decisions.Extractor
// Prices is nil for pricing.Active.
Prices func() *pricing.List
Now func() time.Time
// Changed is called once a capture's call is recorded as pending.
Changed func()
Log *slog.Logger
// CallTimeout is zero for the package's CallTimeout.
CallTimeout time.Duration
// contains filtered or unexported fields
}
Capturer captures one session at a time (README.md, "Capture").
type ConsolidateReport ¶
type ConsolidateReport struct {
Repository string `json:"repository"`
Outcome string `json:"outcome"`
// Stopped is the reason a call was not made (a backend or price
// reason); what was called is still written.
Stopped string `json:"stopped,omitempty"`
Features int `json:"features"`
// Merged counts the features merged into another, HeldMerges those the
// split hold kept apart and InvalidMerges the reply's groups dropped or
// cut.
Merged int `json:"merged"`
HeldMerges int `json:"held_merges"`
InvalidMerges int `json:"invalid_merges"`
// Split counts the features split, NewFeatures the parts they made,
// KeptWhole those the reply kept whole or too large to offer and
// InvalidSplits those whose reply was invalid or whose call failed.
Split int `json:"split"`
NewFeatures int `json:"new_features"`
KeptWhole int `json:"kept_whole"`
InvalidSplits int `json:"invalid_splits"`
// DiscardedMerges counts the merge reply's groups not written because a
// split call failed or was refused.
DiscardedMerges int `json:"discarded_merges,omitempty"`
// Changed counts the merges and splits not written because their
// features changed after they were read.
Changed int `json:"changed"`
Spent float64 `json:"spent_usd"`
Error string `json:"error,omitempty"`
}
ConsolidateReport says what a consolidation pass did; no feature or reply text.
type Decision ¶
type Decision struct {
decisions.Decision
Agent string `json:"agent"`
SessionID string `json:"session_id"`
Repository string `json:"repository"`
Branch string `json:"branch,omitempty"`
DecidedAt time.Time `json:"decided_at"`
}
Decision is a current decision as the log keeps it.
type DecisionView ¶
type DecisionView struct {
ID string `json:"decision_id"`
Title string `json:"title,omitempty"`
Summary string `json:"summary"`
Category decisions.Category `json:"category"`
Who decisions.Who `json:"who"`
Rationale string `json:"rationale,omitempty"`
RejectedAlternative string `json:"rejected_alternative,omitempty"`
Superseded bool `json:"superseded"`
Files []string `json:"files"`
// DecidedAt is when the decision was first raised (Decision.DecidedAt).
DecidedAt time.Time `json:"decided_at"`
// Provisional marks, for a pull request, a decision dated after its
// saved review was generated: the review has not seen it.
Provisional bool `json:"provisional,omitempty"`
}
DecisionView is what the app is told of a current decision: no evidence quote, turns or branch.
type DiscoverReport ¶
type DiscoverReport struct {
Repository string `json:"repository"`
// TaxonomyID is the stored taxonomy, 0 when none was made.
TaxonomyID int64 `json:"taxonomy_id,omitempty"`
Revision string `json:"revision,omitempty"`
Features int `json:"features"`
Backend string `json:"backend,omitempty"`
Model string `json:"model,omitempty"`
// MaxTokens and MaxCalls are the run's budgets; zero is no limit.
MaxTokens int `json:"max_tokens,omitempty"`
MaxCalls int `json:"max_calls,omitempty"`
Calls int `json:"calls"`
// SpentUSD is nil when the run's spend cannot be priced.
SpentUSD *float64 `json:"spent_usd"`
// Stopped is why no taxonomy was made.
Stopped string `json:"stopped,omitempty"`
}
DiscoverReport says what Discover did; no taxonomy text.
type Effective ¶
type Effective struct {
// Backend is the data extraction backend, resolved as a review's for
// auto, empty when none passes its check.
Backend string `json:"backend"`
// Undetermined is a backend whose checks did not answer in time, apart
// from none being usable.
Undetermined bool `json:"backend_undetermined"`
// Model is the decision model; empty without a backend.
Model string `json:"effective_model"`
// Ignored is a chosen model (preferences.decisions.model) that capture
// does not use with Backend.
Ignored bool `json:"model_ignored"`
}
Effective is the backend and model decision capture uses.
func EffectiveModel ¶
func EffectiveModel(ctx context.Context, file config.Config, prefs repos.Preferences, backends generate.Backends, list *pricing.List) Effective
EffectiveModel resolves the backend and decision model as a capture does (resolveModel), from the config file with the app's preferences over it. Backends zero builds them from the configuration and list nil is pricing.Active. With auto it runs the backends' checks, for at most effectiveTimeout. No usable backend leaves the Effective empty; checks that do not answer in time leave it empty but Undetermined. Either way the model is unknown and nothing is ignored.
type Extraction ¶
type Extraction struct {
Meta
ContentHash, PrefixHash string
PromptVersion string
Backend, Model string
// Decisions all have IDs (decisions.Identified).
Decisions []decisions.Decision
Dropped []decisions.Dropped
Usage decisions.Usage
// Cost is nil when unknown.
Cost *float64
// TurnTimes are the times of the root session's turns, by ordinal.
TurnTimes map[int]time.Time
}
Extraction is one extraction to save as the session's head.
type FeatureOptions ¶
type FeatureOptions struct {
// DryRun renders placement's calls without making them, and writes
// nothing.
DryRun bool
// Limit bounds the items or features taken; zero is the stage's limit.
Limit int
// Manual ignores the activation and the text stage's debounce.
Manual bool
// Backend and Model, when set, replace the configured ones.
Backend, Model string
// contains filtered or unexported fields
}
FeatureOptions change one run of placement or the text stage, for testing by hand.
type FeatureRegistry ¶
type FeatureRegistry interface {
Preferences(context.Context) (repos.Preferences, error)
Repositories(context.Context) ([]repos.Repository, error)
RepositorySettings(ctx context.Context, repository string) (repos.Settings, bool, error)
}
FeatureRegistry is what the feature worker reads of the repository registry; *repos.Registry is one.
type FeatureWorker ¶
type FeatureWorker struct {
Store *Store
Registry FeatureRegistry
// GitHub opens a REST reader for a repository.
GitHub func(context.Context, github.Repository) (github.Reader, error)
// Sessions narrows the session stores linked; zero reads the defaults.
Sessions sessions.Options
// Config, Backends and Prices make the placement and text calls as
// capture's (Capturer).
Config config.Config
Backends generate.Backends
Prices func() *pricing.List
Now func() time.Time
// Tick is how often the stages run; zero is FeatureTick.
Tick time.Duration
// Window is how far back the first sync lists pull requests; zero is
// FeatureFirstSyncWindow.
Window time.Duration
// Changed is called after a repository's pass that may have changed
// its pull requests, their sessions or its features.
Changed func()
Log *slog.Logger
// contains filtered or unexported fields
}
FeatureWorker runs the feature log's stages for every repository whose decisions are captured (README.md, "Feature log"). Run it once in the daemon, beside the capture scheduler and on the same Store.
func (*FeatureWorker) Assign ¶
func (w *FeatureWorker) Assign(ctx context.Context, repository, dir string, o FeatureOptions) (AssignReport, error)
Assign places the repository's pending pull requests and sessions, oldest trigger first, at most FeatureAssignRunLimit (or o.Limit) of them. A backend reason stops it until the next run.
func (*FeatureWorker) Build ¶
func (w *FeatureWorker) Build(ctx context.Context, repository, dir string, o BuildOptions) (BuildReport, error)
Build builds the repository's features from its pull request history in its building version, made or resumed, and makes that version current (README.md, "First build"). It stops, leaving the version building, when a call cannot be made or on a store error; running it again resumes the version. A dry run reports the estimate in Stopped's place and writes nothing.
func (*FeatureWorker) Consolidate ¶
func (w *FeatureWorker) Consolidate(ctx context.Context, repository, dir string, o FeatureOptions) (ConsolidateReport, error)
Consolidate makes a consolidation pass over the repository's features when one is due: at most every FeatureConsolidateEvery, and only when the features changed since the last pass (any time with o.Manual).
func (*FeatureWorker) Discover ¶
func (w *FeatureWorker) Discover(ctx context.Context, repository, dir string) (DiscoverReport, error)
Discover runs feature discovery of the repository once, from the clone in dir, and stores the taxonomy it replies with. It runs on the data extraction backend and model, after listing the whole history and reading its paths as a first build does.
func (*FeatureWorker) EstimateBuild ¶
func (w *FeatureWorker) EstimateBuild(ctx context.Context, repository, dir string, o BuildOptions) (BuildEstimate, error)
EstimateBuild estimates a build of the repository: what is left of its building version, or a new one.
func (*FeatureWorker) Index ¶
func (w *FeatureWorker) Index(ctx context.Context, repository, dir string, fresh []gitlocal.Commit, full bool) (IndexReport, error)
Index links commits to the sessions on this machine and replaces their links: the fresh commits Sync recorded within FeatureLookback; every FeatureQuiet, the commits within the session window of now, which sessions still running may yet link to; and every FeatureRelinkEvery, or with full, every commit within FeatureLookback.
func (*FeatureWorker) ListHistory ¶
func (w *FeatureWorker) ListHistory(ctx context.Context, repository string) (HistoryReport, error)
ListHistory lists every pull request of the repository once, for its first build, and saves them without moving the sync's ETag or cursor. A repository whose history was listed before is not listed again.
func (*FeatureWorker) PlanBuild ¶
func (w *FeatureWorker) PlanBuild(ctx context.Context, repository, dir string, o BuildOptions) (backend, model, reason string, err error)
PlanBuild resolves the backend and model a build of the repository would call, without listing its history, or the reason it cannot run now (the gate, or a backend reason). Nothing about the price stops a build.
func (*FeatureWorker) Run ¶
func (w *FeatureWorker) Run(ctx context.Context)
Run runs the stages every Tick and when woken, until ctx ends. It returns once the stage in progress has.
func (*FeatureWorker) RunOnce ¶
func (w *FeatureWorker) RunOnce(ctx context.Context)
RunOnce runs the stages (sync, index, placement, text and consolidation) for every repository whose decisions are captured and that has a clone. A repository turned off is not read and makes no GitHub call.
func (*FeatureWorker) Summarize ¶
func (w *FeatureWorker) Summarize(ctx context.Context, repository, dir string, o FeatureOptions) (SummaryReport, error)
Summarize writes the text of the repository's features whose members changed and have been unchanged for FeatureQuiet (not with o.Manual), longest behind first, at most FeatureSummaryRunLimit (or o.Limit). A backend reason stops it until the next run.
func (*FeatureWorker) Sync ¶
func (w *FeatureWorker) Sync(ctx context.Context, repository, dir string) (SyncReport, error)
Sync lists the repository's pull requests updated since the last sync (the first lists those of Window) and reads the paths and commits of each whose head changed from the clone in dir, fetching missing heads.
func (*FeatureWorker) Wake ¶
func (w *FeatureWorker) Wake()
Wake runs the stages soon, for a settings change. A nil worker ignores it.
type FlowPull ¶
FlowPull is one pull request for Analytics' pull request flow: who opened it, when, and when it merged.
type HistoryReport ¶
type HistoryReport struct {
Repository string `json:"repository"`
// Listed is false when the history was listed before.
Listed bool `json:"listed"`
Calls int `json:"github_calls"`
PullRequests int `json:"pull_requests_listed"`
// Truncated is a listing that stopped at its bound: the least recently
// updated pull requests are missing. The listing is not retried.
Truncated bool `json:"truncated,omitempty"`
}
HistoryReport says what ListHistory did.
type IndexReport ¶
type IndexReport struct {
Repository string `json:"repository"`
Full bool `json:"full"`
Commits int `json:"commits_linked"`
Links int `json:"links"`
Sessions int `json:"sessions"`
}
IndexReport says what Index did.
type LedgerEntry ¶
type LedgerEntry struct {
Repository, Backend string
State, Reason string
StartedAt time.Time
// Cost is nil when unknown or, for a pending attempt, not known yet.
Cost *float64
}
LedgerEntry is one attempt of the ledger, as analytics counts it.
type LinkedSessions ¶
type LinkedSessions func(ctx context.Context, repository string, number int) ([]locallink.Session, time.Time, error)
LinkedSessions lists the sessions the pull request's latest saved review links on this machine (as its PR page's sessions list does), and when that review was generated, zero without one.
type OpenOptions ¶
type OpenOptions struct {
// AbandonPending settles the attempts a previous run left pending as
// abandoned. Only the daemon, the one writer that makes calls unattended,
// sets it.
AbandonPending bool
// ReadOnly opens an existing store without writing to it, and an empty
// in-memory one when there is none, for a dry run.
ReadOnly bool
}
OpenOptions choose how Open opens the store.
type Options ¶
type Options struct {
// DryRun stops before the call and writes nothing.
DryRun bool
// Force skips the gate, the throttle and the unchanged check.
Force bool
// Backend and Model, when set, replace the configured ones.
Backend, Model string
// DebugDir, when set, receives the rendered transcript (transcript.txt),
// the user message sent (user.txt) and the raw reply (reply.json), for
// testing by hand. Each capture first removes the previous capture's
// files. The daemon never sets it.
DebugDir string
}
Options change one capture.
type Person ¶
type Person struct {
Email string `json:"email"`
Name *string `json:"name"`
Login *string `json:"login"`
AvatarURL *string `json:"avatar_url"`
// contains filtered or unexported fields
}
Person is who a session or pull request belongs to. The avatar is never read: the app draws initials.
type PlacedItem ¶
type PlacedItem struct {
Kind string `json:"kind"`
Trigger string `json:"trigger"`
Number int `json:"number,omitempty"`
Title string `json:"title,omitempty"`
Session string `json:"session,omitempty"`
Outcome string `json:"outcome"`
Reason string `json:"reason,omitempty"`
Feature string `json:"feature,omitempty"`
// FeatureTitle is a new feature's provisional title.
FeatureTitle string `json:"feature_title,omitempty"`
// Candidates are the candidate features' titles, in the order offered.
Candidates []string `json:"candidates"`
InputBytes int `json:"input_bytes"`
Cost *float64 `json:"cost_usd,omitempty"`
Error string `json:"error,omitempty"`
}
PlacedItem is one item Assign took.
type PullCommit ¶
PullCommit is one commit of a pull request.
type PullRequestDecisions ¶
type PullRequestDecisions struct {
Sessions []PullRequestSession `json:"sessions"`
// ReviewGeneratedAt is when the saved review the provisional marks are
// relative to was generated; null without one.
ReviewGeneratedAt *time.Time `json:"review_generated_at"`
}
PullRequestDecisions is the answer for a pull request.
type PullRequestSession ¶
type PullRequestSession struct {
SessionDecisions
// Title is the linked session's; a live one's is in the live list.
Title string `json:"title,omitempty"`
// Live is a session the tracker follows that is not over yet.
Live bool `json:"live"`
}
PullRequestSession is a session of a pull request with its decisions.
type PullSync ¶
type PullSync struct {
ETag string
// Cursor is the latest updated_at listed, zero before the first sync.
Cursor time.Time
// ActivatedAt is when the feature log first ran for the repository;
// earlier work is not assigned.
ActivatedAt time.Time
// RelinkedAt is the last full re-link, zero for none.
RelinkedAt time.Time
// HistoryListedAt is when a first build listed the whole history, zero
// before.
HistoryListedAt time.Time
}
PullSync is a repository's pull request sync state.
type Registry ¶
type Registry interface {
Preferences(context.Context) (repos.Preferences, error)
RepositorySettings(ctx context.Context, repository string) (repos.Settings, bool, error)
}
Registry is what capture reads of the repository registry.
type Report ¶
type Report struct {
Outcome string `json:"outcome"`
Reason string `json:"reason,omitempty"`
// Mode is "full" or "extend".
Mode string `json:"mode,omitempty"`
Backend string `json:"backend,omitempty"`
Model string `json:"model,omitempty"`
Turns int `json:"turns"`
// Tokens is the estimated prompt, MaxTokens the bound reserved for.
Tokens int64 `json:"estimated_tokens"`
MaxTokens int64 `json:"max_tokens"`
Reserved float64 `json:"reserved_usd"`
Cost *float64 `json:"cost_usd,omitempty"`
Decisions int `json:"decisions"`
}
Report is what a capture did.
type ResolvedFeature ¶
type ResolvedFeature struct {
// ID is the feature, followed to the one it was merged into.
ID string `json:"id"`
Repository string `json:"repository"`
// Archived is a feature of a retired version.
Archived bool `json:"archived,omitempty"`
}
ResolvedFeature is what a link to a feature shows.
type SampleDecisionRef ¶
SampleDecisionRef addresses one saved decision of a session's turn.
type SampleFeature ¶
type SampleFeature struct {
ID, Title, Description, Digest string
// KeyDecisions name the decisions the text cites, which Save stored.
KeyDecisions []SampleDecisionRef
Pulls []int
// Sessions are Claude Code sessions placed on the feature on their own.
Sessions []string
Updated time.Time
}
SampleFeature is a feature of the tour's sample project as the feature log would leave it: its text written, its pull requests and the sessions placed on it.
type Scheduler ¶
type Scheduler struct {
Tracker Tracker
Source Source
Worker Worker
Now func() time.Time
// Tick is how often the triggers are evaluated; zero is TickEvery.
Tick time.Duration
// Changed is called after a capture that saved decisions, recorded a
// skip or settled an attempt.
Changed func()
Log *slog.Logger
// contains filtered or unexported fields
}
Scheduler decides when the tracked sessions are captured and hands them, one at a time, to the worker. Run it once in the daemon.
type Session ¶
type Session struct {
Agent, ID string
Repository, Branch, Path string
Fingerprint string
ContentHash, PrefixHash string
PromptVersion string
Backend, Model string
// Decisions are the head extraction's, with IDs; nil when none was made.
Decisions []decisions.Decision
Coverage string
SkipReason string
Failures int
UpdatedAt time.Time
}
Session is a captured session's row: its coverage and head extraction.
type SessionCommit ¶
SessionCommit is one session linked to a commit.
type SessionDecisions ¶
type SessionDecisions struct {
Agent string `json:"agent"`
SessionID string `json:"session_id"`
// Repository is the session's, as last captured; empty for a session
// never captured. The gate reads it; the app is not told.
Repository string `json:"-"`
// CaptureOff says why capture does not run for the session now
// (API.Registry; CaptureOff* values), empty when it does or is not known.
CaptureOff string `json:"capture_off,omitempty"`
// Coverage is CoverageExtracted, CoverageSkipped, or empty for a session
// never captured.
Coverage string `json:"coverage"`
SkipReason string `json:"skip_reason,omitempty"`
UpdatedAt *time.Time `json:"updated_at"`
// Capturing is a model call for the session that has not settled.
Capturing bool `json:"capturing"`
Decisions []DecisionView `json:"decisions"`
}
SessionDecisions is what the app shows of one session's capture: its current decisions, its coverage and why it was skipped, when its row last changed and whether a call for it is in flight.
type Source ¶
type Source interface {
SubscribeCounted(buffer int, match func(hookevents.Event) bool) (events <-chan hookevents.Record, cancel func(), dropped func() uint64)
}
Source delivers hook events; *hookevents.Store is one.
type Stats ¶
type Stats struct {
// Count is the session's attempts since the day's start; LastStart is its
// latest attempt and LastFail its latest failed one, zero for none.
Count int
LastStart time.Time
LastFail time.Time
}
Stats are what the throttle reads from the ledger.
type Store ¶
type Store struct {
// Changed, when set, is called after each write that changes what the
// app shows: a session's coverage or decisions, or an attempt beginning
// or settling. The daemon publishes the app's decisions event with it.
Changed func()
// contains filtered or unexported fields
}
Store keeps the sessions' coverage and head extraction, the decision log and the ledger of model calls.
func Open ¶
func Open(path string, o OpenOptions) (*Store, error)
Open creates or opens the private store at path, in a 0700 directory.
func (*Store) Activate ¶
Activate reads the repository's sync state, activating the repository the first time.
func (*Store) Coverage ¶
func (s *Store) Coverage(ctx context.Context, sessions ...SessionKey) (map[SessionKey][2]string, error)
Coverage reads each session's coverage and skip reason; a session without a row is left out.
func (*Store) Covered ¶
Covered records that the head extraction still covers the session as fingerprinted (a cache hit): its rendered transcript did not change.
func (*Store) Current ¶
Current reads the current decisions of the sessions, in session and extraction order, with their files.
func (*Store) Failed ¶
Failed counts a failed extraction of the session and returns how many followed its last success.
func (*Store) LiveVersion ¶
LiveVersion is the repository's feature version in use, created when it has none.
func (*Store) PathsFailed ¶
func (s *Store) PathsFailed(ctx context.Context, repository string, number int, head string) (bool, error)
PathsFailed counts a failed read of the pull request's commits at head (a new head or base starts the count again, SavePulls). It is tried again after FeatureQuiet; after FeaturePathTries failures its paths are unknown at that head, and true is returned.
func (*Store) PullFlow ¶
func (s *Store) PullFlow(ctx context.Context, repository string, since time.Time) ([]FlowPull, bool, error)
PullFlow lists the repository's pull requests not opened by a bot that were opened or merged at or after since, and whether the feature log has listed the repository yet: one it never listed has none to give. The repository is named as the feature log stores it, so the primary key finds its rows.
func (*Store) PullsWithCommitsSince ¶
func (s *Store) PullsWithCommitsSince(ctx context.Context, repository string, since time.Time) ([]StoredPull, error)
PullsWithCommitsSince lists the pull requests holding a recorded commit made at or after since, at the head their commits were recorded at, so they are linked again while a newer head cannot be read. The base is the current one. A new base with the same head has the pull request read again (SavePulls); with a new head too, the recorded head is kept until the new one is read.
func (*Store) PullsWithoutPaths ¶
PullsWithoutPaths lists the repository's pull requests that may be placed in a feature, open or merged and not opened by a bot, whose paths were not read at their head and are due to be, newest first.
func (*Store) ReplaceSessionCommits ¶
func (s *Store) ReplaceSessionCommits(ctx context.Context, repository string, shas []string, links []SessionCommit, relinked time.Time) error
ReplaceSessionCommits makes links the sessions linked to the commits shas: every earlier link of those commits goes. relinked, when not zero, records a full re-link. A commit whose sessions changed marks the features holding a pull request with it and the features of its old and new sessions.
func (*Store) ResolveFeature ¶
ResolveFeature is the feature a link to id shows: followed to the feature it was merged into, archived when its version was retired. sql.ErrNoRows for an unknown feature or one of a version being built.
func (*Store) RetryUnknownPaths ¶
RetryUnknownPaths has every pull request whose commits failed to be read read again now, those with unknown paths FeaturePathTries more times.
func (*Store) Save ¶
func (s *Store) Save(ctx context.Context, e Extraction) error
Save makes the extraction the session's head and its decisions the session's current ones, as the hosted decision log does: a decision is upserted by its ID, so it keeps the row and creation time it had; the session's current decisions missing from the new set become obsolete and are never deleted. A decision is dated by its first cited turn's time, else the date its ID had, else the time of the extraction.
func (*Store) SaveHistoryPulls ¶
func (s *Store) SaveHistoryPulls(ctx context.Context, repository string, pulls []github.ListedPull) error
SaveHistoryPulls upserts a listing of the repository's whole history as SavePulls does, leaving the sync's ETag and cursor as they are, and records that the history was listed. A pull request stored with a later update, as a sync during the listing saves it, is kept as it is.
func (*Store) SavePulls ¶
func (s *Store) SavePulls(ctx context.Context, repository string, pulls []github.ListedPull, etag string, cursor time.Time) error
SavePulls upserts the listed pull requests, marking the feature of one whose title, description or state changed, and, for a non-zero cursor, moves the sync state to etag and the cursor; the cursor never goes back. A new head or base starts the count of failed reads again, and a new base has the pull request's commits read again.
func (*Store) SeedSample ¶
func (s *Store) SeedSample(ctx context.Context, repository string, pulls []github.ListedPull, summaries map[int]string, features []SampleFeature) error
SeedSample writes the sample project's pull requests, their summaries and its features into a store no feature build has run on. Nothing else writes features without a model; this is for the sample project alone.
func (*Store) SessionLinks ¶
func (s *Store) SessionLinks(ctx context.Context, repository, agent, sessionID string) (features.SessionLinks, error)
SessionLinks reads what attributes a captured session's decisions in the repository's live version: the feature pull requests its linked commits are in, and the feature it is in on its own. A session without a capture row has none.
func (*Store) Sessions ¶
func (s *Store) Sessions(ctx context.Context, keys ...SessionKey) ([]SessionDecisions, error)
Sessions reads what the app shows of each session, in the given order.
func (*Store) SetPullPaths ¶
func (s *Store) SetPullPaths(ctx context.Context, repository string, number int, head string, paths []string, commits []PullCommit) error
SetPullPaths records what the pull request touches at head: its paths, nil when they cannot be read, and its commits, which replace those it had.
func (*Store) Settle ¶
func (s *Store) Settle(ctx context.Context, id int64, state, reason string, cost *float64, usage decisions.Usage) error
Settle records how an attempt ended. A nil cost is unknown.
func (*Store) Skip ¶
Skip records that the session, as fingerprinted, was not extracted and why. Its head extraction and decisions stay as they were.
type StoredPull ¶
StoredPull is a pull request whose paths are to be read.
type SummarizedFeature ¶
type SummarizedFeature struct {
Feature string `json:"feature"`
Title string `json:"title"`
Outcome string `json:"outcome"`
Reason string `json:"reason,omitempty"`
// PullRequests are its pull requests' numbers, earliest opened first.
PullRequests []int `json:"pull_requests"`
// PullSummaries counts the generated pull request summaries made by a
// call, PullSummariesReused those kept.
PullSummaries int `json:"pull_request_summaries"`
PullSummariesReused int `json:"pull_request_summaries_reused"`
Decisions int `json:"decisions"`
KeyDecisions int `json:"key_decisions"`
InputBytes int `json:"input_bytes"`
Cost *float64 `json:"cost_usd,omitempty"`
Error string `json:"error,omitempty"`
}
SummarizedFeature is one feature Summarize took.
type SummaryReport ¶
type SummaryReport struct {
Repository string `json:"repository"`
Features []SummarizedFeature `json:"features"`
// Stopped is the reason no further call was made (a backend or price
// reason).
Stopped string `json:"stopped,omitempty"`
Spent float64 `json:"spent_usd"`
}
SummaryReport says what Summarize did.
type SyncReport ¶
type SyncReport struct {
Repository string `json:"repository"`
Calls int `json:"github_calls"`
NotModified bool `json:"not_modified"`
Listed int `json:"pull_requests_listed"`
// Truncated is a listing that stopped at its bound: older pull requests
// still due were skipped.
Truncated bool `json:"truncated,omitempty"`
PathsRead int `json:"paths_read"`
// PathsFailed are pull requests whose commits failed to be read, to be
// tried again; PathsUnknown those of them that failed FeaturePathTries
// times at their head and now have unknown paths.
PathsFailed int `json:"paths_failed"`
PathsUnknown int `json:"paths_unknown"`
// Stopped is set when the repository was turned off during the sync.
Stopped bool `json:"stopped,omitempty"`
Commits int `json:"commits_recorded"`
// contains filtered or unexported fields
}
SyncReport says what Sync did.
type Target ¶
type Target struct {
Agent, ID string
// Path is the transcript path the session's hooks named, if any.
Path string
Repository, Branch string
// Ended is a session that sent its end event: the daily attempt limit
// does not hold it back.
Ended bool
}
Target is a session to capture.
type Timeline ¶
type Timeline struct {
Store *Store
Registry TimelineRegistry
// Clone opens the repository's clone for a request; nil, or a nil
// answer, reads nobody and no review.
Clone func(ctx context.Context, repository string) TimelineClone
// Login is the user's GitHub login, "" when unknown; it folds the pull
// requests they opened into them.
Login func(ctx context.Context) string
// Home holds the agents' session stores, whose transcripts a decision's
// cited prompts are read from; empty is the user's home.
Home string
// CursorStore is Cursor's database; empty is its default.
CursorStore string
// Transcripts serves a captured session's transcript, tracked or ended;
// nil serves none.
Transcripts *livesessions.Transcripts
// contains filtered or unexported fields
}
Timeline serves /api/timeline/.
type TimelineClone ¶
type TimelineClone interface {
// Person is who sessions in this clone belong to, by its git
// user.email and user.name; nil when it has no address.
Person(ctx context.Context) *Person
// Review is the summary of the pull request's latest saved review and
// its state against head ("current" or "outdated"), "" and "none"
// without one.
Review(ctx context.Context, number int, head string) (summary, state string)
}
TimelineClone is what one request reads of a repository's clone; it reads each once.
type TimelineRegistry ¶
type TimelineRegistry interface {
Preferences(context.Context) (repos.Preferences, error)
Repositories(context.Context) ([]repos.Repository, error)
}
TimelineRegistry is what the Timeline reads of the repository registry; *repos.Registry is one.
type Tracker ¶
type Tracker interface {
Sessions() []livesessions.Session
Lookup(agent, id string) (livesessions.Session, string, bool)
}
Tracker is what the scheduler reads of the live sessions; *livesessions.Tracker is one.