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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ jobs:
run: go build ./...

- name: Lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v9
with:
install-mode: goinstall
version: v1.64.8
version: v2.8.0
args: --timeout=5m

- name: Test
Expand Down
118 changes: 64 additions & 54 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,65 +1,75 @@
version: "2"
run:
timeout: 5m
tests: true

issues:
exclude-dirs:
- vendor
exclude-files:
- ".*\\.pb\\.go"
- ".*\\.gen\\.go"
exclude-use-default: false
max-issues-per-linter: 0
max-same-issues: 0
exclude-rules:
- path: _test\.go
linters:
- goconst
- errorlint
- errcheck
- linters:
- goconst
source: "case \".*\":|return \".*\"|== \".*\""
- linters:
- staticcheck
text: "SA1019.*deprecated"
path: "custom/.*/.*\\.go"

linters:
disable-all: true
default: none
enable:
- bodyclose
- errcheck
- gosimple
- errorlint
- goconst
- gosec
- govet
- ineffassign
- misspell
- noctx
- staticcheck
- typecheck
- unconvert
- unused
settings:
goconst:
min-len: 5
min-occurrences: 5
gosec:
excludes:
- G104
- G204
- G304
- G115
- G301
- G101
- G306
exclusions:
generated: lax
rules:
- linters:
- errcheck
- errorlint
- goconst
path: _test\.go
- linters:
- goconst
source: case ".*":|return ".*"|== ".*"
- linters:
- staticcheck
path: custom/.*/.*\.go
text: SA1019.*deprecated
paths:
- .*\.pb\.go
- .*\.gen\.go
- vendor
- third_party$
- builtin$
- examples$
issues:
max-issues-per-linter: 0
max-same-issues: 0
formatters:
enable:
- gofmt
- goimports
- misspell
- errorlint
- unconvert
- goconst
# Security linters
- gosec
- bodyclose
- noctx

linters-settings:
goimports:
local-prefixes: github.com/clawscli/claws
gofmt:
simplify: true
goconst:
min-len: 5
min-occurrences: 5
gosec:
excludes:
- G104 # Audit errors not checked (covered by errcheck)
- G204 # Subprocess with variable - intentional for CLI actions
- G304 # File path from variable - intentional for log/config
- G115 # int->int32 conversion - pageSize always < 1000
- G301 # Directory permissions - test only
- G101 # Hardcoded credentials - test examples only
- G306 # WriteFile permissions 0644 - standard for generated Go source
settings:
gofmt:
simplify: true
goimports:
local-prefixes:
- github.com/clawscli/claws
exclusions:
generated: lax
paths:
- .*\.pb\.go
- .*\.gen\.go
- vendor
- third_party$
- builtin$
- examples$
5 changes: 3 additions & 2 deletions custom/apprunner/services/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,12 @@ func (r *ServiceRenderer) RenderDetail(resource dao.Resource) string {
if sourceType := svc.SourceType(); sourceType != "" {
d.Section("Source Configuration")
d.Field("Source Type", sourceType)
if sourceType == "IMAGE_REPOSITORY" {
switch sourceType {
case "IMAGE_REPOSITORY":
if img := svc.ImageIdentifier(); img != "" {
d.Field("Image", img)
}
} else if sourceType == "CODE_REPOSITORY" {
case "CODE_REPOSITORY":
if repo := svc.RepositoryUrl(); repo != "" {
d.Field("Repository URL", repo)
}
Expand Down
2 changes: 1 addition & 1 deletion custom/s3/buckets/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (d *BucketDAO) fetchTags(ctx context.Context, client *s3.Client, bucket str
tags[*tag.Key] = *tag.Value
}
}
r.BaseResource.Tags = tags
r.Tags = tags
}

func (d *BucketDAO) Delete(ctx context.Context, id string) error {
Expand Down
5 changes: 3 additions & 2 deletions internal/action/exec_with_header.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package action

import (
"cmp"
"context"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -66,7 +67,7 @@ func (e *SimpleExec) Run() error {
stderr = os.Stderr
}

cmd := exec.Command("/bin/sh", "-c", e.Command)
cmd := exec.CommandContext(context.Background(), "/bin/sh", "-c", e.Command)
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
Expand Down Expand Up @@ -164,7 +165,7 @@ func (e *ExecWithHeader) Run() error {
return ErrEmptyCommand
}

cmd := exec.Command("/bin/sh", "-c", e.Command)
cmd := exec.CommandContext(context.Background(), "/bin/sh", "-c", e.Command)
cmd.Stdin = stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
Expand Down
5 changes: 3 additions & 2 deletions internal/app/pty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app

import (
"bytes"
"context"
"os"
"os/exec"
"strings"
Expand All @@ -14,14 +15,14 @@ import (
// TestPTYEscHandling runs the actual app in a PTY and tests esc handling
func TestPTYEscHandling(t *testing.T) {
// Build the app first
buildCmd := exec.Command("go", "build", "-o", "/tmp/claws-test", "../../cmd/claws")
buildCmd := exec.CommandContext(context.Background(), "go", "build", "-o", "/tmp/claws-test", "../../cmd/claws")
if out, err := buildCmd.CombinedOutput(); err != nil {
t.Fatalf("Failed to build: %v\n%s", err, out)
}
defer func() { _ = os.Remove("/tmp/claws-test") }()

// Run the app in a PTY
cmd := exec.Command("/tmp/claws-test")
cmd := exec.CommandContext(context.Background(), "/tmp/claws-test")
ptmx, err := pty.Start(cmd)
if err != nil {
t.Fatalf("Failed to start PTY: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion internal/view/chat_overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ func (c *ChatOverlay) handleToolExecute(msg chatToolExecuteMsg) (tea.Model, tea.
for _, tu := range msg.toolUses {
// Check tool call limit before executing each tool
if c.toolCallCount >= maxCalls {
c.err = fmt.Errorf("Tool call limit reached (%d calls). Start new query to continue.", maxCalls)
c.err = fmt.Errorf("tool call limit reached (%d calls), start new query to continue", maxCalls)
c.isStreaming = false
c.updateViewport()
return c, nil
Expand Down
9 changes: 5 additions & 4 deletions internal/view/dashboard_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,14 @@ func (d *DashboardView) ViewString() string {
opsFocusRow := -1
secFocusRow := -1
optFocusRow := -1
if d.focusedPanel == panelCost {
switch d.focusedPanel {
case panelCost:
costFocusRow = d.focusedRow
} else if d.focusedPanel == panelOperations {
case panelOperations:
opsFocusRow = d.focusedRow
} else if d.focusedPanel == panelSecurity {
case panelSecurity:
secFocusRow = d.focusedRow
} else if d.focusedPanel == panelOptimization {
case panelOptimization:
optFocusRow = d.focusedRow
}

Expand Down
5 changes: 3 additions & 2 deletions internal/view/dashboard_view_panels.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,10 @@ func (d *DashboardView) renderSecurityContent(contentWidth, contentHeight int, f
} else if len(d.secItems) > 0 {
var critical, high int
for _, item := range d.secItems {
if item.severity == "CRITICAL" {
switch item.severity {
case "CRITICAL":
critical++
} else if item.severity == "HIGH" {
case "HIGH":
high++
}
}
Expand Down
3 changes: 2 additions & 1 deletion internal/view/profile_selector.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package view

import (
"context"
"fmt"
"io"
"os/exec"
Expand Down Expand Up @@ -231,7 +232,7 @@ type ssoLoginCmd struct {
}

func (s *ssoLoginCmd) Run() error {
cmd := exec.Command("aws", "sso", "login", "--profile", s.profileName)
cmd := exec.CommandContext(context.Background(), "aws", "sso", "login", "--profile", s.profileName)
cmd.Stdin = s.stdin
cmd.Stdout = s.stdout
cmd.Stderr = s.stderr
Expand Down
6 changes: 3 additions & 3 deletions internal/view/table_style.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ func NewTableStyleFunc(widths []int, cursor int) func(row, col int) lipgloss.Sty
if col >= numCols {
return ui.NoStyle()
}
switch {
case row == table.HeaderRow:
switch row {
case table.HeaderRow:
return headerStyles[col]
case row == cursor:
case cursor:
return selectedStyles[col]
default:
return normalStyles[col]
Expand Down
3 changes: 2 additions & 1 deletion scripts/gen-imports/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bytes"
"context"
"fmt"
"go/format"
"os"
Expand Down Expand Up @@ -63,7 +64,7 @@ func main() {
}

func verifyBuild(projectRoot string) error {
cmd := exec.Command("go", "build", "./cmd/claws")
cmd := exec.CommandContext(context.Background(), "go", "build", "./cmd/claws")
cmd.Dir = projectRoot
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand Down