Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ This repo contains the CLI for Entire.

### Command Layout

The CLI is organized around five noun groups plus a small set of top-level
verbs. The groups are the canonical home for each verb; legacy top-level
shortcuts remain functional but hidden, and emit a deprecation hint pointing
at the canonical group form.

- `session` (alias: `sessions`): `list`, `info`, `stop`, `attach`, `resume`, `current`.
The visible CLI is organized around five noun groups plus a small set of
top-level verbs. The groups are the canonical home for each verb; legacy
top-level shortcuts remain functional but hidden, and emit a deprecation hint
pointing at the canonical group form. Newer experimental command families are
discoverable through `entire labs` and may remain hidden from root help while
their canonical paths are still runnable.

- `session` (alias: `sessions`): `list`, `info`, `tokens`, `stop`, `attach`, `resume`, `current`.
`resume` with a branch arg switches to it and resumes its session; with no arg
it opens an interactive picker of stopped sessions (across all worktrees),
resolving each to its branch and pointing at the owning worktree when the
branch is checked out elsewhere. Resume keeps an existing local session log
as-is by default (`--force` overwrites it from the checkpoint).
- `checkpoint` (aliases: `cp`, `checkpoints`): `list`, `explain`, `search`, plus
- `checkpoint` (aliases: `cp`, `checkpoints`): `list`, `explain`, `tokens`, `search`, plus
the deprecated `rewind` (functional, prints a cobra deprecation message, will
be removed in a future release)
- `agent`: bare opens the interactive agent selector, plus `list`, `add`, `remove`
Expand All @@ -45,6 +47,10 @@ at the canonical group form.
current one) and `--all-contexts` (log out of every saved login)
- `doctor`: bare runs the scan-and-fix flow, plus `trace`, `logs`, `bundle`

Experimental command families advertised through `entire labs`:

- `tokens`: `profile` (hidden from root help while token diagnostics mature)

Top-level lifecycle and standalone commands: `enable`, `disable`, `status`,
`login`, `logout`, `clean`, `version`, `dispatch`, `activity`, `help`,
`configure`.
Expand Down
135 changes: 125 additions & 10 deletions cmd/entire/cli/checkpoint_tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"strconv"
Expand Down Expand Up @@ -37,7 +38,10 @@ type checkpointTokensComparison struct {
TargetCheckpointID string `json:"target_checkpoint_id"`
Status string `json:"status"`
Total *checkpointTokensMetricDelta `json:"total,omitempty"`
Input *checkpointTokensMetricDelta `json:"input,omitempty"`
CacheRead *checkpointTokensMetricDelta `json:"cache_read,omitempty"`
CacheWrite *checkpointTokensMetricDelta `json:"cache_write,omitempty"`
Output *checkpointTokensMetricDelta `json:"output,omitempty"`
APICalls *checkpointTokensMetricDelta `json:"api_calls,omitempty"`
Qualification string `json:"qualification"`
Limitations []string `json:"limitations,omitempty"`
Expand All @@ -56,11 +60,16 @@ const (
checkpointComparisonStatusObservedReduction = "observed_reduction"
checkpointComparisonStatusObservedIncrease = "observed_increase"
checkpointComparisonStatusObservedNoChange = "observed_no_change"

checkpointDeltaDirectionDown = "down"
checkpointDeltaDirectionUp = "up"
checkpointDeltaDirectionUnchanged = "unchanged"
)

func newCheckpointTokensCmd() *cobra.Command {
var jsonFlag bool
var compareFlag string
var agentBriefFlag bool

cmd := &cobra.Command{
Use: "tokens <checkpoint-id>",
Expand All @@ -77,16 +86,20 @@ Use --compare <checkpoint-id> to compare this checkpoint against a previous
checkpoint and qualify observed token reduction or increase.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runCheckpointTokens(cmd.Context(), cmd, args[0], jsonFlag, compareFlag)
if jsonFlag && agentBriefFlag {
return errors.New("--json and --agent-brief are mutually exclusive")
}
return runCheckpointTokens(cmd.Context(), cmd, args[0], jsonFlag, compareFlag, agentBriefFlag)
},
}

cmd.Flags().BoolVar(&jsonFlag, "json", false, "Output as JSON")
cmd.Flags().StringVar(&compareFlag, "compare", "", "Compare against a baseline checkpoint ID")
cmd.Flags().BoolVar(&agentBriefFlag, "agent-brief", false, "Output compact next-step guidance for agents")
return cmd
}

func runCheckpointTokens(ctx context.Context, cmd *cobra.Command, checkpointIDPrefix string, jsonOutput bool, comparePrefix string) error {
func runCheckpointTokens(ctx context.Context, cmd *cobra.Command, checkpointIDPrefix string, jsonOutput bool, comparePrefix string, agentBrief bool) error {
report, lookup, err := loadCheckpointTokensReport(ctx, cmd, checkpointIDPrefix)
if lookup != nil {
defer lookup.Close()
Expand All @@ -103,12 +116,20 @@ func runCheckpointTokens(ctx context.Context, cmd *cobra.Command, checkpointIDPr
if err != nil {
return tokenCommandError(err)
}
if baselineReport.CheckpointID == report.CheckpointID {
cmd.SilenceUsage = true
return fmt.Errorf("cannot compare checkpoint %s to itself", report.CheckpointID)
}
report.Comparison = buildCheckpointTokensComparison(report, baselineReport)
}

if jsonOutput {
return writeCheckpointTokensJSON(cmd.OutOrStdout(), report)
}
if agentBrief {
writeCheckpointTokensAgentBrief(cmd.OutOrStdout(), report)
return nil
}
writeCheckpointTokensText(cmd.OutOrStdout(), report)
return nil
}
Expand Down Expand Up @@ -374,19 +395,53 @@ func buildCheckpointTokensComparison(target, baseline checkpointTokensReport) *c
}

comparison.Total = buildCheckpointMetricDelta(baseline.Tokens.Total, target.Tokens.Total)
comparison.Input = buildCheckpointMetricDelta(baseline.Tokens.Input, target.Tokens.Input)
comparison.CacheRead = buildCheckpointMetricDelta(baseline.Tokens.CacheRead, target.Tokens.CacheRead)
comparison.CacheWrite = buildCheckpointMetricDelta(baseline.Tokens.CacheWrite, target.Tokens.CacheWrite)
comparison.Output = buildCheckpointMetricDelta(baseline.Tokens.Output, target.Tokens.Output)
comparison.APICalls = buildCheckpointMetricDelta(baseline.Tokens.APICalls, target.Tokens.APICalls)
comparison.Status = checkpointComparisonStatus(comparison.Total)
comparison.Qualification = checkpointComparisonQualification(comparison.Status)
if classes := checkpointCostProxyPressureIncreased(comparison); len(classes) > 0 {
comparison.Qualification += fmt.Sprintf(" Cost-proxy pressure increased for %s even though total tokens decreased.", formatTokenClassList(classes))
}
return comparison
}

func checkpointCostProxyPressureIncreased(comparison *checkpointTokensComparison) []string {
if comparison == nil || comparison.Total == nil || comparison.Total.Change >= 0 {
return nil
}
var classes []string
if comparison.CacheWrite != nil && comparison.CacheWrite.Change > 0 {
classes = append(classes, "cache write")
}
if comparison.Output != nil && comparison.Output.Change > 0 {
classes = append(classes, "output")
}
return classes
}

func formatTokenClassList(classes []string) string {
switch len(classes) {
case 0:
return ""
case 1:
return classes[0]
case 2:
return classes[0] + " and " + classes[1]
default:
return strings.Join(classes[:len(classes)-1], ", ") + ", and " + classes[len(classes)-1]
}
}

func buildCheckpointMetricDelta(baseline, current int) *checkpointTokensMetricDelta {
change := saturatingIntSub(current, baseline)
delta := &checkpointTokensMetricDelta{
Baseline: baseline,
Current: current,
Change: current - baseline,
Direction: checkpointDeltaDirection(current - baseline),
Change: change,
Direction: checkpointDeltaDirection(change),
}
if baseline != 0 {
percent := float64(delta.Change) * 100 / float64(baseline)
Expand All @@ -395,14 +450,32 @@ func buildCheckpointMetricDelta(baseline, current int) *checkpointTokensMetricDe
return delta
}

func saturatingIntSub(a, b int) int {
if b < 0 && a > maxInt()+b {
return maxInt()
}
if b > 0 && a < minInt()+b {
return minInt()
}
return a - b
}

func maxInt() int {
return int(^uint(0) >> 1)
}

func minInt() int {
return -maxInt() - 1
}

func checkpointDeltaDirection(change int) string {
switch {
case change < 0:
return "down"
return checkpointDeltaDirectionDown
case change > 0:
return "up"
return checkpointDeltaDirectionUp
default:
return "unchanged"
return checkpointDeltaDirectionUnchanged
}
}

Expand All @@ -411,9 +484,9 @@ func checkpointComparisonStatus(total *checkpointTokensMetricDelta) string {
return checkpointComparisonStatusUnavailable
}
switch total.Direction {
case "down":
case checkpointDeltaDirectionDown:
return checkpointComparisonStatusObservedReduction
case "up":
case checkpointDeltaDirectionUp:
return checkpointComparisonStatusObservedIncrease
default:
return checkpointComparisonStatusObservedNoChange
Expand Down Expand Up @@ -479,6 +552,45 @@ func writeCheckpointTokensText(w io.Writer, report checkpointTokensReport) {
writeTokenLimitations(w, report.Limitations)
}

func writeCheckpointTokensAgentBrief(w io.Writer, report checkpointTokensReport) {
fmt.Fprintln(w, "Checkpoint token brief")
fmt.Fprintf(w, "Checkpoint: %s\n", report.CheckpointID)
fmt.Fprintln(w)
fmt.Fprintln(w, agentBriefUsageLine(report.Tokens))
fmt.Fprintln(w)
fmt.Fprintln(w, "Next best action:")
fmt.Fprintln(w, checkpointAgentBriefNextAction(report))

signals := agentBriefSignals(checkpointAgentBriefSessionReport(report))
if len(signals) > 0 {
fmt.Fprintln(w)
fmt.Fprintln(w, "Signals:")
for _, signal := range signals {
fmt.Fprintf(w, "- %s\n", signal)
}
}
}

func checkpointAgentBriefNextAction(report checkpointTokensReport) string {
sessionReport := checkpointAgentBriefSessionReport(report)
if hasTokenRecommendation(sessionReport, "no-token-data") {
return "Do not spend extra commands on token optimization for this checkpoint. Continue with the task and capture a newer checkpoint before rechecking tokens."
}
if action, ok := agentBriefOptimizationAction(sessionReport); ok {
return action
}
return "Continue normally; no high-signal token optimization is available from this checkpoint."
}

func checkpointAgentBriefSessionReport(report checkpointTokensReport) sessionTokensReport {
return sessionTokensReport{
Tokens: report.Tokens,
Context: report.Context,
Recommendations: report.Recommendations,
Limitations: report.Limitations,
}
}

func writeCheckpointTokenComparison(w io.Writer, comparison *checkpointTokensComparison) {
if comparison == nil {
return
Expand All @@ -489,7 +601,10 @@ func writeCheckpointTokenComparison(w io.Writer, comparison *checkpointTokensCom
fmt.Fprintf(w, "Baseline: %s\n", comparison.BaselineCheckpointID)
if comparison.Status != checkpointComparisonStatusUnavailable {
fmt.Fprintf(w, "Total tokens: %s\n", formatCheckpointMetricDelta(comparison.Total, formatTokenCount))
fmt.Fprintf(w, "Input: %s\n", formatCheckpointMetricDelta(comparison.Input, formatTokenCount))
fmt.Fprintf(w, "Cache/context replay: %s\n", formatCheckpointMetricDelta(comparison.CacheRead, formatTokenCount))
fmt.Fprintf(w, "Cache write: %s\n", formatCheckpointMetricDelta(comparison.CacheWrite, formatTokenCount))
fmt.Fprintf(w, "Output: %s\n", formatCheckpointMetricDelta(comparison.Output, formatTokenCount))
fmt.Fprintf(w, "API calls: %s\n", formatCheckpointMetricDelta(comparison.APICalls, formatPlainCount))
}
fmt.Fprintln(w)
Expand All @@ -503,7 +618,7 @@ func formatCheckpointMetricDelta(delta *checkpointTokensMetricDelta, formatValue
}
from := formatValue(delta.Baseline)
to := formatValue(delta.Current)
if delta.Direction == "unchanged" {
if delta.Direction == checkpointDeltaDirectionUnchanged {
return fmt.Sprintf("unchanged (%s -> %s)", from, to)
}
if delta.ChangePercent == nil {
Expand Down
66 changes: 39 additions & 27 deletions cmd/entire/cli/labs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,61 @@ import (
)

type experimentalCommandInfo struct {
Name string
Invocation string
Summary string
CommandPath []string
Invocation string
Summary string
}

var experimentalCommands = []experimentalCommandInfo{
{
Name: "review",
Invocation: "entire review",
Summary: "Run configured review skills against the current branch",
CommandPath: []string{"review"},
Invocation: "entire review",
Summary: "Run configured review skills against the current branch",
},
{
Name: "investigate",
Invocation: "entire investigate",
Summary: "Run a multi-agent investigation against a topic, issue, or seed doc",
CommandPath: []string{"investigate"},
Invocation: "entire investigate",
Summary: "Run a multi-agent investigation against a topic, issue, or seed doc",
},
{
Name: "org",
Invocation: "entire org",
Summary: "Manage Entire organizations (create, list)",
CommandPath: []string{"tokens"},
Invocation: "entire tokens",
Summary: "Analyze experimental token usage diagnostics",
},
{
Name: "project",
Invocation: "entire project",
Summary: "Manage Entire projects (create, list)",
CommandPath: []string{"tokens", "profile"},
Invocation: "entire tokens profile",
Summary: "Aggregate token usage across committed checkpoints",
},
{
Name: "repo",
Invocation: "entire repo",
Summary: "Manage Entire repositories (create, list, get, delete)",
CommandPath: []string{"org"},
Invocation: "entire org",
Summary: "Manage Entire organizations (create, list)",
},
{
Name: "grant",
Invocation: "entire grant",
Summary: "Manage access grants and org membership (org, project, repo)",
CommandPath: []string{"project"},
Invocation: "entire project",
Summary: "Manage Entire projects (create, list)",
},
{
Name: "blame",
Invocation: "entire blame",
Summary: "Show which lines came from Entire checkpoints",
CommandPath: []string{"repo"},
Invocation: "entire repo",
Summary: "Manage Entire repositories (create, list, get, delete)",
},
{
Name: "why",
Invocation: "entire why",
Summary: "Show why a line exists (commit, checkpoint, prompt, session)",
CommandPath: []string{"grant"},
Invocation: "entire grant",
Summary: "Manage access grants and org membership (org, project, repo)",
},
{
CommandPath: []string{"blame"},
Invocation: "entire blame",
Summary: "Show which lines came from Entire checkpoints",
},
{
CommandPath: []string{"why"},
Invocation: "entire why",
Summary: "Show why a line exists (commit, checkpoint, prompt, session)",
},
}

Expand Down Expand Up @@ -97,6 +107,8 @@ Available experimental commands:
Try:
entire review --help
entire investigate --help
entire tokens --help
entire tokens profile --help
entire org --help
entire project --help
entire repo --help
Expand Down
Loading
Loading