fix(agent-help): refresh trails availability · Entire
fix(agent-help): refresh trails availability
e77cd56→main·
dipree·2d ago·2 files·+56 added/-2 removed
Sessions
01KXJX4ZP5K7K9FFCJ7RDX2X3BView transcript
[?
Fix Agent Help Trail AvailabilityPi·GPT-5.6-sol·1 step](/content/gh/entireio/cli/session/019f65cc-0712-7af1-9340-2ded310ed0f4#timeline-01KXJX4ZP5K7K9FFCJ7RDX2X3B/index.html)
Changes
2
cmd/entire/cli
Magent_help_cmd.go+18/-2
Magent_help_cmd_test.go+38
67 unmodified lines
68
69
70
71
72
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
1 unmodified line
88
89
90
91
92
93
94
95
96
97
98
99
67 unmodified lines
// agentHelpRepoContext resolves the origin remote ONCE and derives both the repo
// line (forge/owner/repo, or "" when it can't be determined — no origin /
// detached HEAD — so the renderer degrades gracefully) and whether trails are
// enabled for that scope. Previously the repo line and the trails check resolved
// origin independently, costing two git subprocesses per `entire agent-help` run.
// enabled for that scope. Unlike the prompt-path gate, agent-help is an explicit
// command and can afford to refresh an absent or stale enablement decision rather
// than incorrectly treating an unknown cache entry as "trails unavailable".
func agentHelpRepoContext(ctx context.Context) (repoLine string, trailsEnabled bool) {
return agentHelpRepoContextWithRefresh(ctx, refreshTrailsEnabledCacheIfStaleForScope)
}
// agentHelpRepoContextWithRefresh keeps the refresh dependency explicit so the
// cache-miss behavior can be tested without authenticating against a real API.
func agentHelpRepoContextWithRefresh(
ctx context.Context,
refresh func(context.Context, trailEnablementScope) error,
) (repoLine string, trailsEnabled bool) {
scope, err := currentTrailEnablementScope(ctx)
if err != nil {
return "", false
1 unmodified line
if scope.Forge != "" && scope.Owner != "" && scope.Repo != "" {
repoLine = scope.RepoKey
}
refreshCtx, cancel := context.WithTimeout(ctx, trailEnablementRefreshTimeout)
defer cancel()
if err := refresh(refreshCtx, scope); err != nil {
return repoLine, false
}
return repoLine, cachedTrailsEnablementForScope(ctx, scope, time.Now()) == trailEnablementCacheEnabled
}
Mcmd/entire/cli/agent_help_cmd.go+18/-2
1 unmodified line
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
78 unmodified lines
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
1 unmodified line
import (
"bytes"
"context"
"encoding/json"
"io"
"os/exec"
"strings"
"testing"
"time"
"github.com/entireio/cli/cmd/entire/cli/testutil"
"github.com/spf13/cobra"
)
78 unmodified lines
}
// agent-help is invoked explicitly, so an absent cache entry must trigger the
// repo-scoped trails availability check instead of being treated as disabled.
// Not parallel: changes the process working directory.
func TestAgentHelpRepoContext_RefreshesUnknownTrailsEnablement(t *testing.T) {
repoDir := t.TempDir()
testutil.InitRepo(t, repoDir)
cmd := exec.CommandContext(t.Context(), "git", "remote", "add", "origin", "git@github.com:acme/app.git")
cmd.Dir = repoDir
cmd.Env = testutil.GitIsolatedEnv()
if err := cmd.Run(); err != nil {
t.Fatalf("git remote add: %v", err)
}
t.Chdir(repoDir)
refreshCalls := 0
repoLine, enabled := agentHelpRepoContextWithRefresh(t.Context(), func(ctx context.Context, scope trailEnablementScope) error {
refreshCalls++
if scope.RepoKey != "gh/acme/app" {
t.Fatalf("refresh scope repo = %q, want gh/acme/app", scope.RepoKey)
}
return saveTrailsEnabledForScope(ctx, scope, true, time.Now())
})
if refreshCalls != 1 {
t.Fatalf("refresh calls = %d, want 1", refreshCalls)
}
if repoLine != "gh/acme/app" {
t.Errorf("repo line = %q, want gh/acme/app", repoLine)
}
if !enabled {
t.Fatal("trails should be enabled after the availability refresh succeeds")
}
}
// Drilling into a trail-gated command is blocked when trails are disabled.
func TestRunAgentHelp_TrailDrillGatedOnTrailsEnabled(t *testing.T) {
t.Parallel()