Skip to content
Merged
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
28 changes: 0 additions & 28 deletions ae-cli/cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package cmd
import (
"context"
"os"
"time"

"github.com/ai-efficiency/ae-cli/internal/attributionlocal"
"github.com/ai-efficiency/ae-cli/internal/hooks"
"github.com/ai-efficiency/ae-cli/internal/proxy"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -49,30 +47,6 @@ var hookPostRewriteCmd = &cobra.Command{
},
}

var hookSessionEventCmd = &cobra.Command{
Use: "session-event",
Short: "Forward tool hook events to the local proxy (hidden)",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
tool, err := cmd.Flags().GetString("tool")
if err != nil {
return err
}
err = proxy.ForwardHookEvent(context.Background(), os.Stdin, proxy.HookForwardRequest{
Tool: tool,
LocalProxyURL: os.Getenv("AE_LOCAL_PROXY_URL"),
LocalProxyToken: os.Getenv("AE_LOCAL_PROXY_TOKEN"),
SessionID: os.Getenv("AE_SESSION_ID"),
WorkspaceID: os.Getenv("AE_WORKSPACE_ID"),
CapturedAt: time.Now().UTC(),
})
if err != nil {
return nil
}
return nil
},
}

var hookAttributionSyncCmd = &cobra.Command{
Use: "attribution-sync",
Short: "Run local attribution sync (hidden)",
Expand All @@ -87,8 +61,6 @@ var hookAttributionSyncCmd = &cobra.Command{
func init() {
hookCmd.AddCommand(hookPostCommitCmd)
hookCmd.AddCommand(hookPostRewriteCmd)
hookSessionEventCmd.Flags().String("tool", "", "originating tool name")
hookCmd.AddCommand(hookSessionEventCmd)
hookCmd.AddCommand(hookAttributionSyncCmd)
rootCmd.AddCommand(hookCmd)
}
15 changes: 0 additions & 15 deletions ae-cli/cmd/hook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,6 @@ func TestHookCommandHasPostRewriteSubcommand(t *testing.T) {
}
}

func TestHookCommandHasSessionEventSubcommand(t *testing.T) {
var found bool
for _, c := range hookCmd.Commands() {
if c.Name() == "session-event" {
found = true
if !c.Hidden {
t.Fatalf("expected hook session-event to be hidden")
}
}
}
if !found {
t.Fatalf("expected hidden subcommand 'ae-cli hook session-event' to exist")
}
}

func TestHookPostCommitCommandQueuesWhenUploaderUnsupported(t *testing.T) {
repo := initRepoWithCommitForCmdTests(t)

Expand Down
108 changes: 1 addition & 107 deletions ae-cli/cmd/shell.go
Original file line number Diff line number Diff line change
@@ -1,112 +1,6 @@
package cmd

import (
"context"
"os"
"strings"
"syscall"
"time"

"github.com/ai-efficiency/ae-cli/config"
"github.com/ai-efficiency/ae-cli/internal/session"
"github.com/ai-efficiency/ae-cli/internal/shell"
"github.com/ai-efficiency/ae-cli/internal/tmux"
"github.com/ai-efficiency/ae-cli/internal/toolconfig"
"github.com/spf13/cobra"
)

type shellRunner interface {
Run() error
ShouldKillTmux() bool
}

type ticker interface {
Chan() <-chan time.Time
Stop()
}

type realTicker struct{ *time.Ticker }

func (t realTicker) Chan() <-chan time.Time { return t.C }

// newShellRunner is an injection point for cmd tests. Production uses the real
// interactive shell implementation.
var newShellRunner = func(cfg *config.Config, state *session.State) shellRunner {
return shell.New(cfg, state)
}

var (
shellSignalSet = []os.Signal{syscall.SIGTERM, syscall.SIGHUP}
newHeartbeatTicker = func(d time.Duration) ticker { return realTicker{time.NewTicker(d)} }
shellHeartbeatInterval = 30 * time.Second
)

func shellToolNames(cfg *config.Config) string {
if cfg == nil {
return ""
}
var names []string
for name := range cfg.Tools {
names = append(names, name)
}
return strings.Join(names, ", ")
}

func applyRuntimeEnvironment(tmuxSession string, rt *session.RuntimeBundle) {
if rt == nil {
return
}

env := map[string]string{}
for k, v := range rt.EnvBundle {
env[k] = v
}

if rt.Proxy != nil {
env = toolconfig.ApplyClaudeProxyEnv(env, toolconfig.ClaudeEnv{
BaseURL: "http://" + rt.Proxy.ListenAddr + "/anthropic",
Token: rt.Proxy.AuthToken,
})
_ = os.Unsetenv("ANTHROPIC_API_KEY")
}

for k, v := range env {
_ = os.Setenv(k, v)
}
if tmuxSession != "" {
_ = tmux.SetEnvironment(tmuxSession, env)
if rt.Proxy != nil {
_ = tmux.UnsetEnvironment(tmuxSession, []string{"ANTHROPIC_API_KEY"})
}
}
}

func startHeartbeatLoop(mgr *session.Manager, state *session.State) func() {
if mgr == nil || state == nil || strings.TrimSpace(state.ID) == "" {
return func() {}
}
t := newHeartbeatTicker(shellHeartbeatInterval)
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
defer close(done)
for {
select {
case <-ctx.Done():
return
case <-t.Chan():
hbCtx, hbCancel := context.WithTimeout(context.Background(), 5*time.Second)
_ = mgr.Heartbeat(hbCtx, state.ID)
hbCancel()
}
}
}()
return func() {
cancel()
t.Stop()
<-done
}
}
import "github.com/spf13/cobra"

var shellCmd = &cobra.Command{
Use: "shell",
Expand Down
21 changes: 0 additions & 21 deletions ae-cli/cmd/start.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package cmd

import (
"fmt"
"strings"

"github.com/ai-efficiency/ae-cli/internal/proxy"
"github.com/spf13/cobra"
)

Expand All @@ -17,23 +13,6 @@ var startCmd = &cobra.Command{
},
}

var proxyServeInternalCmd = &cobra.Command{
Use: "proxy-serve-internal",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
configPath, err := cmd.Flags().GetString("config")
if err != nil {
return err
}
if strings.TrimSpace(configPath) == "" {
return fmt.Errorf("--config is required")
}
return proxy.ServeFromConfigFile(configPath)
},
}

func init() {
rootCmd.AddCommand(startCmd)
proxyServeInternalCmd.Flags().String("config", "", "internal proxy runtime config path")
rootCmd.AddCommand(proxyServeInternalCmd)
}
Loading