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
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
- name: Set up Go
uses: useblacksmith/setup-go@v6
with:
go-version: '1.24'
go-version: '1.25'

- name: Generate Error Codes
run: go generate ./...
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/upgrade-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ jobs:
uses: actions/setup-go@v5
if: ${{ matrix.os != 'blacksmith-4vcpu-ubuntu-2204' }}
with:
go-version: '1.24'
go-version: '1.25'
cache: true

- name: Set up Go
uses: useblacksmith/setup-go@v6
if: ${{ matrix.os == 'blacksmith-4vcpu-ubuntu-2204' }}
with:
go-version: '1.24'
go-version: '1.25'
cache: true

- name: Build current version
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module github.com/agentuity/cli

go 1.24.4
go 1.25

require (
github.com/Masterminds/semver v1.5.0
github.com/agentuity/go-common v1.0.67
github.com/agentuity/go-common v1.0.71
github.com/agentuity/mcp-golang/v2 v2.0.2
github.com/bmatcuk/doublestar/v4 v4.8.1
github.com/charmbracelet/bubbles v0.20.0
Expand All @@ -29,6 +29,7 @@ require (

require (
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.5 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
Expand All @@ -9,8 +11,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
github.com/agentuity/go-common v1.0.67 h1:Pw6Lv/2eJ+F4kZZgnZhYy3JyTzA3VEa64h/BPSfayxw=
github.com/agentuity/go-common v1.0.67/go.mod h1:cy1EPYpZUkp3JSMgTb+Sa3sLnS7vQQupj/RwO4An6L4=
github.com/agentuity/go-common v1.0.71 h1:W8ynuxcXKfrDNcCWNAoAzqhfMt8oTBR4ALVJJelE0Yw=
github.com/agentuity/go-common v1.0.71/go.mod h1:qMuSKhvnSAyje6MB1XLSp6xC4d17Hy6FiE3NDYFr9pk=
github.com/agentuity/mcp-golang/v2 v2.0.2 h1:wZqS/aHWZsQoU/nd1E1/iMsVY2dywWT9+PFlf+3YJxo=
github.com/agentuity/mcp-golang/v2 v2.0.2/go.mod h1:U105tZXyTatxxOBlcObRgLb/ULvGgT2DJ1nq/8++P6Q=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
Expand Down
36 changes: 28 additions & 8 deletions internal/templates/steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,47 @@ type CommandStep struct {

var _ Step = (*CommandStep)(nil)

const commandExecTimeout = time.Minute * 2

func (s *CommandStep) Run(ctx TemplateContext) error {
ctx.Logger.Debug("Running command: %s with args: %s", s.Command, strings.Join(s.Args, " "))

timeoutCtx, cancel := context.WithTimeout(ctx.Context, 1*time.Minute)
started := time.Now()
timeoutCtx, cancel := context.WithTimeout(ctx.Context, commandExecTimeout)
defer cancel()
cmd := exec.CommandContext(timeoutCtx, s.Command, s.Args...)
cmd.Dir = ctx.ProjectDir
cmd.Stdin = nil

out, err := cmd.CombinedOutput()

buf := strings.TrimSpace(string(out))
if buf != "" {
ctx.Logger.Debug("Command output: %s", buf)
}

if cmd.ProcessState != nil {
ctx.Logger.Debug("command exit code %d (took %v)", cmd.ProcessState.ExitCode(), time.Since(started))
}

if timeoutCtx.Err() == context.DeadlineExceeded {
ctx.Logger.Error("command: %s %s timed out after %v", s.Command, strings.Join(s.Args, " "), time.Since(started))
}

if err != nil {
ctx.Logger.Debug("command failed with error: %s (%T)", err, err)
if s.Command == "uv" && len(s.Args) >= 3 && s.Args[0] == "add" {
exitErr, ok := err.(*exec.ExitError)
if ok && exitErr.ExitCode() == 130 {
packages := s.Args[2:]
ctx.Logger.Debug("Command interrupted with SIGINT (130), trying alternative installation methods for: %v", packages)

altCmd := exec.CommandContext(ctx.Context, "uv", "pip", "install")
fallbackCtx1, fallbackCancel1 := context.WithTimeout(ctx.Context, commandExecTimeout)
defer fallbackCancel1()
altCmd := exec.CommandContext(fallbackCtx1, "uv", "pip", "install")
altCmd.Args = append(altCmd.Args, packages...)
altCmd.Dir = ctx.ProjectDir
altCmd.Stdin = nil
altOut, altErr := altCmd.CombinedOutput()

if altErr == nil {
Expand All @@ -68,9 +89,12 @@ func (s *CommandStep) Run(ctx TemplateContext) error {
}

ctx.Logger.Debug("Failed to install with uv pip, trying with pip: %v", altErr)
pipCmd := exec.CommandContext(ctx.Context, "pip", "install")
fallbackCtx2, fallbackCancel2 := context.WithTimeout(ctx.Context, commandExecTimeout)
defer fallbackCancel2()
pipCmd := exec.CommandContext(fallbackCtx2, "pip", "install")
pipCmd.Args = append(pipCmd.Args, packages...)
pipCmd.Dir = ctx.ProjectDir
pipCmd.Stdin = nil
pipOut, pipErr := pipCmd.CombinedOutput()

if pipErr == nil {
Expand All @@ -83,13 +107,9 @@ func (s *CommandStep) Run(ctx TemplateContext) error {
}
}

return fmt.Errorf("failed to run command: %s with args: %s: %w (%s)", s.Command, strings.Join(s.Args, " "), err, string(out))
return fmt.Errorf("failed to run command: %s with args: %s: %w (%s)", s.Command, strings.Join(s.Args, " "), err, buf)
}

buf := strings.TrimSpace(string(out))
if buf != "" {
ctx.Logger.Debug("Command output: %s", buf)
}
return nil
}

Expand Down
Loading