cli

package
v0.0.0-...-86b21bc Latest Latest
Warning

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

Go to latest
Published: May 8, 2026 License: MIT Imports: 76 Imported by: 0

Documentation

Overview

Package cli builds the Cobra command tree for the gemba binary. The cmd/gemba entry point delegates to Execute so subcommand wiring stays out of package main and can be tested directly.

Index

Constants

View Source
const DefaultDaemonTickPeriod = 10 * time.Second

DefaultDaemonTickPeriod is the period the autodispatch daemon's loop runs at when no per-pool override is set. Spec §6 doesn't pin a number; 10s matches `work-planning.md`'s "loop runs every few seconds" prose without thrashing on a quiet rig.

Variables

View Source
var ErrConformanceFailed = fmt.Errorf("gemba adaptor test: one or more conformance probes failed")

ErrConformanceFailed signals one or more probes failed. Execute() returns a non-zero exit code on this sentinel without re-printing cobra's usage block — the text summary already tells the operator exactly what went wrong.

Functions

func Execute

func Execute(b BuildInfo) int

Execute builds the root command and runs it. Returns the process exit code.

Types

type AffinityOut

type AffinityOut struct {
	Rows []AffinityRow `json:"rows"`
}

type AffinityRow

type AffinityRow struct {
	BeadID    core.WorkItemID        `json:"bead_id"`
	SessionID string                 `json:"session_id"`
	AgentID   core.AgentID           `json:"agent_id,omitempty"`
	Scores    planner.AffinityScores `json:"scores"`
}

type BuildInfo

type BuildInfo struct {
	Version string
	Commit  string
	Date    string
}

BuildInfo carries -ldflags-injected build metadata from cmd/gemba.

type ConflictsOut

type ConflictsOut struct {
	Edges               []conflicts.Edge             `json:"edges"`
	Batches             []conflicts.Batch            `json:"batches"`
	WorkspaceCollisions []planner.WorkspaceCollision `json:"workspace_collisions"`
	SemanticConflicts   []planner.SemanticConflict   `json:"semantic_conflicts"`
	Notices             []string                     `json:"notices,omitempty"`
}

type OperationalContextInput

type OperationalContextInput struct {
	Sessions   []*core.Session                    `json:"sessions"`
	Agents     []*core.AgentRef                   `json:"agents,omitempty"`
	Workspaces []*core.Workspace                  `json:"workspaces,omitempty"`
	Profiles   map[string]*planner.SessionProfile `json:"profiles,omitempty"` // key = session id
	// Optional: explicit clock for deterministic test runs (RFC3339).
	Now string `json:"now,omitempty"`
}

OperationalContextInput is the offline-mode envelope. Operators supply the session/agent/workspace/profile pieces they have and the CLI runs ReadOperationalContext against in-memory readers.

Populating only Sessions still produces a useful result — TimeOnTask is meaningful from a Session alone (see gm-s47n.5.1). Populate Profiles too for ContextPressure + ConceptDrift.

type PlannerInput

type PlannerInput struct {
	// Beads are the candidate WorkItems the planner is reasoning
	// about. Each entry is the planner's projection — id + tags
	// + targets + repo affinity — derived from a real WorkItem
	// upstream.
	Beads []PlannerInputBead `json:"beads"`
	// SessionContexts are the live agent sessions the planner can
	// dispatch against. Pass them along even when only running
	// conflicts: workspace-collision detection cross-references
	// these so a ready bead routed to a worktree another session
	// is already writing in is flagged.
	SessionContexts []planner.OperationalContext `json:"session_contexts,omitempty"`
}

PlannerInput is the wire shape both commands accept on stdin. Fields are optional so an operator can prepare just-conflicts input (no SessionContexts) or just-affinity input (no targets on the beads). The CLI only reads what each command needs.

type PlannerInputBead

type PlannerInputBead struct {
	ID           core.WorkItemID         `json:"id"`
	Concepts     []planner.ConceptTag    `json:"concepts,omitempty"`
	Targets      []string                `json:"targets,omitempty"`
	Repositories []string                `json:"repositories,omitempty"`
	Branch       string                  `json:"branch,omitempty"`
	WorktreePath string                  `json:"worktree_path,omitempty"`
	GlobPatterns []targets.Pattern       `json:"glob_patterns,omitempty"`
	SemanticHits []sourceanalysis.Target `json:"semantic_hits,omitempty"`
}

PlannerInputBead captures every per-bead field the two CLI commands need. Targets are file paths (already glob-expanded by the caller); BeadTarget is the routing-collision input for workspace conflict.

type PlannerJSONOut

type PlannerJSONOut struct {
	Conflicts *ConflictsOut `json:"conflicts,omitempty"`
	Affinity  *AffinityOut  `json:"affinity,omitempty"`
}

PlannerJSONOut is the stable shape for both --json modes. The command sets exactly one of Conflicts or Affinity per call.

type RetroListInput

type RetroListInput struct {
	Grades []retro.Grade `json:"grades"`
}

RetroListInput is the offline-mode wire shape for `gemba retro list`. Grades is the input set; ListFilter narrows it the same way the dolt-mode SQL filter would.

type RetroListOut

type RetroListOut struct {
	Rows []retro.Grade `json:"rows"`
}

RetroListOut is the stable --json envelope.

type SessionHealthEntry

type SessionHealthEntry struct {
	Session *core.Session           `json:"session"`
	Profile *planner.SessionProfile `json:"profile,omitempty"`
}

SessionHealthEntry is one (Session, Profile) pair. Profile is optional: a session that's still booting may have no profile row yet — TimeOnTask is meaningful from the session alone.

type SessionHealthInput

type SessionHealthInput struct {
	Sessions     []SessionHealthEntry                               `json:"sessions"`
	BeadConcepts map[core.WorkItemID]map[planner.ConceptTag]float64 `json:"bead_concepts,omitempty"`
	// Now overrides time.Now for deterministic test runs. RFC3339
	// string. Empty → live wall clock.
	Now string `json:"now,omitempty"`
}

SessionHealthInput is the wire shape `gemba session-health` consumes. One entry per session under inspection. Optional bead_concepts seeds the drift-vector lookup — when omitted, the computation falls through to ConceptDrift=0 (treat as "no recent drift signal"), still useful for the other two numbers.

type SessionHealthOut

type SessionHealthOut struct {
	Rows []SessionHealthRow `json:"rows"`
}

SessionHealthOut is the stable --json envelope. One row per input session, in the same order, with thresholds rendered as strings so consumers don't reimplement the rule table.

type SessionHealthRow

type SessionHealthRow struct {
	SessionID         string  `json:"session_id"`
	AgentID           string  `json:"agent_id,omitempty"`
	ContextPressure   float64 `json:"context_pressure"`
	ConceptDrift      float64 `json:"concept_drift"`
	TimeOnTaskSeconds float64 `json:"time_on_task_seconds"`
	// PressureLevel and DriftLevel are "ok" | "warn" | "recycle"
	// per spec §4 Layer 4. The CLI carries the labels so a future
	// machine consumer doesn't need to duplicate the threshold
	// table.
	PressureLevel string `json:"pressure_level"`
	DriftLevel    string `json:"drift_level"`
}

type SessionStatusEntry

type SessionStatusEntry struct {
	Session     *core.Session           `json:"session"`
	Profile     *planner.SessionProfile `json:"profile,omitempty"`
	Calibration float64                 `json:"calibration,omitempty"`
}

SessionStatusEntry is one (Session, Profile, Calibration) tuple. Calibration is optional; zero falls through to runway's default.

type SessionStatusInput

type SessionStatusInput struct {
	Sessions     []SessionStatusEntry                               `json:"sessions"`
	BeadConcepts map[core.WorkItemID]map[planner.ConceptTag]float64 `json:"bead_concepts,omitempty"`
	// Now overrides time.Now for deterministic test runs.
	Now string `json:"now,omitempty"`
}

SessionStatusInput is the wire shape `gemba session-status` consumes. Mirrors SessionHealthInput plus a per-session calibration override so the operator can replay promised-vs-actual data without rebuilding the input from scratch.

type SessionStatusOut

type SessionStatusOut struct {
	Rows []SessionStatusRow `json:"rows"`
}

SessionStatusOut is the stable --json envelope. One row per input session in the same order.

type SessionStatusRow

type SessionStatusRow struct {
	SessionID         string        `json:"session_id"`
	AgentID           string        `json:"agent_id,omitempty"`
	ContextPressure   float64       `json:"context_pressure"`
	ConceptDrift      float64       `json:"concept_drift"`
	TimeOnTaskSeconds float64       `json:"time_on_task_seconds"`
	PressureLevel     string        `json:"pressure_level"`
	DriftLevel        string        `json:"drift_level"`
	Runway            runway.Runway `json:"runway"`
}

type SizeCalibrationInput

type SizeCalibrationInput struct {
	Samples []SizeCalibrationSample `json:"samples"`
	// Targets is optional — when omitted the aggregator uses
	// sizecalibration.DefaultBucketTargets.
	Targets *SizeCalibrationTargets `json:"targets,omitempty"`
	// CurrentThresholds is optional — when omitted the aggregator
	// uses enrichment.DefaultSizeThresholds.
	CurrentThresholds *enrichment.SizeHeuristicThresholds `json:"current_thresholds,omitempty"`
}

SizeCalibrationInput is the wire shape `gemba size-calibration` accepts on stdin. Samples carry actual_seconds rather than a time.Duration so JSON is unambiguous; the CLI converts at the boundary.

type SizeCalibrationSample

type SizeCalibrationSample struct {
	BeadID        core.WorkItemID          `json:"bead_id,omitempty"`
	Predicted     enrichment.EstimatedSize `json:"predicted"`
	ActualSeconds float64                  `json:"actual_seconds"`
	Author        string                   `json:"author,omitempty"`
}

type SizeCalibrationTargets

type SizeCalibrationTargets struct {
	SmallSeconds  float64 `json:"small_seconds"`
	MediumSeconds float64 `json:"medium_seconds"`
	LargeSeconds  float64 `json:"large_seconds"`
}

Jump to

Keyboard shortcuts

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