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 VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0
0.1.3
4 changes: 3 additions & 1 deletion cli/agent/claudecode/claude.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ func (c *ClaudeCodeAgent) GetTranscriptPosition(path string) (int, error) {
return 0, nil
}

// #nosec G304 -- path comes from Claude Code transcript location, not remote/untrusted input
file, err := os.Open(path) //nolint:gosec // Path comes from Claude Code transcript location
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -319,6 +320,7 @@ func (c *ClaudeCodeAgent) ExtractModifiedFilesFromOffset(path string, startOffse
return nil, 0, nil
}

// #nosec G304 -- path comes from Claude Code transcript location, not remote/untrusted input
file, openErr := os.Open(path) //nolint:gosec // Path comes from Claude Code transcript location
if openErr != nil {
return nil, 0, fmt.Errorf("failed to open transcript file: %w", openErr)
Expand Down Expand Up @@ -381,7 +383,7 @@ func (c *ClaudeCodeAgent) LaunchCmd(ctx context.Context, initialPrompt string) (
if err != nil {
return nil, fmt.Errorf("claude binary not on PATH: %w", err)
}
cmd := exec.CommandContext(ctx, bin, initialPrompt)
cmd := exec.CommandContext(ctx, bin, initialPrompt) // #nosec G204 -- bin is resolved via exec.LookPath("claude"); initialPrompt is passed as a single argument, not shell-interpreted
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand Down
2 changes: 2 additions & 0 deletions cli/agent/claudecode/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func readSkillsDir(ctx context.Context, dir, pluginName string) []agent.Discover
}
skillDir := filepath.Join(dir, skillEntry.Name())
skillFile := filepath.Join(skillDir, "SKILL.md")
// #nosec G304 -- skillFile is constructed from a ReadDir walk under HOME, not user input
data, err := os.ReadFile(skillFile) //nolint:gosec // G304: skillFile is constructed from a ReadDir walk under HOME, not user input
if err != nil {
continue
Expand Down Expand Up @@ -232,6 +233,7 @@ func scanFlatMarkdownDir(ctx context.Context, dir, pluginName string) []agent.Di
continue
}
filePath := filepath.Join(dir, entry.Name())
// #nosec G304 -- filePath is constructed from a ReadDir walk under HOME, not user input
data, err := os.ReadFile(filePath) //nolint:gosec // G304: filePath is constructed from a ReadDir walk under HOME, not user input
if err != nil {
continue
Expand Down
5 changes: 4 additions & 1 deletion cli/agent/claudecode/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func (c *ClaudeCodeAgent) InstallHooks(ctx context.Context, localDev bool, force
// rawPermissions preserves unknown permission fields (e.g., "ask")
var rawPermissions map[string]json.RawMessage

// #nosec G304 -- path is constructed from repo root + settings file name, not external input
existingData, readErr := os.ReadFile(settingsPath) //nolint:gosec // path is constructed from repo root + settings file name
if readErr == nil {
if err := json.Unmarshal(existingData, &rawSettings); err != nil {
Expand Down Expand Up @@ -233,7 +234,7 @@ func (c *ClaudeCodeAgent) InstallHooks(ctx context.Context, localDev bool, force
func parseHookType(rawHooks map[string]json.RawMessage, hookType string, target *[]ClaudeHookMatcher) {
if data, ok := rawHooks[hookType]; ok {
//nolint:errcheck,gosec // Intentionally ignoring parse errors - leave target as nil/empty
json.Unmarshal(data, target)
json.Unmarshal(data, target) // #nosec G104 -- intentionally ignoring parse errors, leave target as nil/empty
}
}

Expand All @@ -259,6 +260,7 @@ func (c *ClaudeCodeAgent) UninstallHooks(ctx context.Context) error {
repoRoot = "." // Fallback to CWD if not in a git repo
}
settingsPath := filepath.Join(repoRoot, ".claude", ClaudeSettingsFileName)
// #nosec G304 -- path is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(settingsPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
return nil //nolint:nilerr // No settings file means nothing to uninstall
Expand Down Expand Up @@ -378,6 +380,7 @@ func (c *ClaudeCodeAgent) AreHooksInstalled(ctx context.Context) bool {
repoRoot = "." // Fallback to CWD if not in a git repo
}
settingsPath := filepath.Join(repoRoot, ".claude", ClaudeSettingsFileName)
// #nosec G304 -- path is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(settingsPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
return false
Expand Down
2 changes: 2 additions & 0 deletions cli/agent/claudecode/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func (c *ClaudeCodeAgent) ParseHookEvent(_ context.Context, hookName string, std

// ReadTranscript reads the raw JSONL transcript bytes for a session.
func (c *ClaudeCodeAgent) ReadTranscript(sessionRef string) ([]byte, error) {
// #nosec G304 -- path comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return nil, fmt.Errorf("failed to read transcript: %w", err)
Expand Down Expand Up @@ -244,6 +245,7 @@ func waitForTranscriptFlush(ctx context.Context, transcriptPath string, hookStar

// checkStopSentinel reads the tail of the transcript file and looks for the sentinel.
func checkStopSentinel(path string, tailBytes int64, hookStartTime time.Time, maxSkew time.Duration) bool {
// #nosec G304 -- path comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
f, err := os.Open(path) //nolint:gosec // path comes from agent hook input
if err != nil {
return false
Expand Down
2 changes: 1 addition & 1 deletion cli/agent/claudecode/reviewer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func NewReviewer() *reviewtypes.ReviewerTemplate {
// Exposed at package level for test inspection of argv and env.
func buildReviewCmd(ctx context.Context, cfg reviewtypes.RunConfig) *exec.Cmd {
prompt := review.ComposeReviewPrompt(cfg)
cmd := exec.CommandContext(ctx, "claude", "-p", prompt)
cmd := exec.CommandContext(ctx, "claude", "-p", prompt) // #nosec G204 -- fixed "claude" binary; prompt is passed as a single argument, not shell-interpreted
cmd.Env = review.AppendReviewEnv(os.Environ(), "claude-code", cfg, prompt)
return cmd
}
Expand Down
1 change: 1 addition & 0 deletions cli/agent/claudecode/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const (
ToolWrite = "Write"
ToolEdit = "Edit"
ToolNotebookEdit = "NotebookEdit"
// #nosec G101 -- not a credential: this is an MCP tool name constant
ToolMCPWrite = "mcp__acp__Write" //nolint:gosec // G101: This is a tool name, not a credential
ToolMCPEdit = "mcp__acp__Edit"
)
Expand Down
3 changes: 2 additions & 1 deletion cli/agent/codex/codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func (c *CodexAgent) FormatResumeCommand(sessionID string) string {

// ReadTranscript reads the raw JSONL transcript bytes for a session.
func (c *CodexAgent) ReadTranscript(sessionRef string) ([]byte, error) {
// #nosec G304 -- path comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return nil, fmt.Errorf("failed to read transcript: %w", err)
Expand Down Expand Up @@ -256,7 +257,7 @@ func (c *CodexAgent) LaunchCmd(ctx context.Context, initialPrompt string) (*exec
if err != nil {
return nil, fmt.Errorf("codex binary not on PATH: %w", err)
}
cmd := exec.CommandContext(ctx, bin, initialPrompt)
cmd := exec.CommandContext(ctx, bin, initialPrompt) // #nosec G204 -- bin is resolved via exec.LookPath("codex"); initialPrompt is passed as a single argument, not shell-interpreted
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand Down
4 changes: 4 additions & 0 deletions cli/agent/codex/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (c *CodexAgent) InstallHooks(ctx context.Context, localDev bool, force bool

// Read existing hooks.json if present
var rawHooks map[string]json.RawMessage
// #nosec G304 -- hooksPath is constructed from repo root + fixed subpath, not external input
existingData, readErr := os.ReadFile(hooksPath) //nolint:gosec // path constructed from repo root
if readErr == nil {
var hooksFile map[string]json.RawMessage
Expand Down Expand Up @@ -163,6 +164,7 @@ func (c *CodexAgent) UninstallHooks(ctx context.Context) error {
}

hooksPath := filepath.Join(repoRoot, ".codex", HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed subpath, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path constructed from repo root
if err != nil {
return nil //nolint:nilerr // No hooks.json means nothing to uninstall
Expand Down Expand Up @@ -230,6 +232,7 @@ func (c *CodexAgent) AreHooksInstalled(ctx context.Context) bool {
}

hooksPath := filepath.Join(repoRoot, ".codex", HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed subpath, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path constructed from repo root
if err != nil {
return false
Expand Down Expand Up @@ -342,6 +345,7 @@ const featureLine = "codex_hooks = true"
func ensureProjectFeatureEnabled(repoRoot string) error {
configPath := filepath.Join(repoRoot, ".codex", configFileName)

// #nosec G304 -- configPath is constructed from repo root + fixed subpath, not external input
data, err := os.ReadFile(configPath) //nolint:gosec // path constructed from repo root
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to read config.toml: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion cli/agent/codex/spawner.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewSpawner() spawn.Spawner { //nolint:ireturn // factory returns interface
func (codexSpawner) Name() string { return string(agent.AgentNameCodex) }

func (codexSpawner) BuildCmd(ctx context.Context, env []string, prompt string) *exec.Cmd {
cmd := exec.CommandContext(
cmd := exec.CommandContext( // #nosec G204 -- fixed "codex" binary name and fixed argv flags; prompt is piped via stdin, not an argument
ctx, string(agent.AgentNameCodex),
codexExecCommand,
"--skip-git-repo-check",
Expand Down
3 changes: 3 additions & 0 deletions cli/agent/codex/transcript.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (c *CodexAgent) GetTranscriptPosition(path string) (int, error) {
return 0, nil
}

// #nosec G304 -- path comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
file, err := os.Open(path) //nolint:gosec // Path comes from agent hook input
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -116,6 +117,7 @@ func (c *CodexAgent) ExtractModifiedFilesFromOffset(path string, startOffset int
return nil, 0, nil
}

// #nosec G304 -- path comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
file, openErr := os.Open(path) //nolint:gosec // Path comes from agent hook input
if openErr != nil {
return nil, 0, fmt.Errorf("failed to open transcript: %w", openErr)
Expand Down Expand Up @@ -262,6 +264,7 @@ func (c *CodexAgent) CalculateTokenUsage(transcriptData []byte, fromOffset int)

// ExtractPrompts returns user prompts from the transcript starting at the given offset.
func (c *CodexAgent) ExtractPrompts(sessionRef string, fromOffset int) ([]string, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
if os.IsNotExist(err) {
Expand Down
3 changes: 3 additions & 0 deletions cli/agent/codex/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func codexConfigPath() string {
// whether the read+parse succeeded — false on missing/malformed file so
// callers can stay silent rather than mid-flow noise.
func declaredCodexEvents(hooksJSONPath string) ([]string, bool) {
// #nosec G304 -- hooksJSONPath constructed from caller-controlled repo root, not remote/untrusted input
data, err := os.ReadFile(hooksJSONPath) //nolint:gosec // path constructed from caller-controlled repo root
if err != nil {
return nil, false
Expand Down Expand Up @@ -103,6 +104,7 @@ func declaredCodexEvents(hooksJSONPath string) ([]string, bool) {
// are "Codex isn't enabled here", which is a different problem.
func MissingEntireHooks(repoRoot string) []string {
hooksJSONPath := filepath.Join(repoRoot, ".codex", "hooks.json")
// #nosec G304 -- hooksJSONPath constructed from caller-controlled repo root, not remote/untrusted input
data, err := os.ReadFile(hooksJSONPath) //nolint:gosec // path constructed from caller-controlled repo root
if err != nil {
return nil
Expand Down Expand Up @@ -131,6 +133,7 @@ func MissingEntireHooks(repoRoot string) []string {
var codexTrustStateHeaderRegex = regexp.MustCompile(`(?m)^\[hooks\.state\."([^"]+)"\]`)

func readCodexTrustedKeys(configPath string) (map[string]struct{}, bool) {
// #nosec G304 -- configPath resolved from CODEX_HOME env var or user home dir, a standard trusted config location
data, err := os.ReadFile(configPath) //nolint:gosec // path resolved from CODEX_HOME or HOME
if err != nil {
return nil, false
Expand Down
1 change: 1 addition & 0 deletions cli/agent/copilotcli/copilotcli.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func (c *CopilotCLIAgent) FormatResumeCommand(sessionID string) string {

// ReadTranscript reads the raw JSONL transcript bytes for a session.
func (c *CopilotCLIAgent) ReadTranscript(sessionRef string) ([]byte, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return nil, fmt.Errorf("failed to read transcript: %w", err)
Expand Down
3 changes: 3 additions & 0 deletions cli/agent/copilotcli/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (c *CopilotCLIAgent) InstallHooks(ctx context.Context, localDev bool, force
var rawFile map[string]json.RawMessage
var rawHooks map[string]json.RawMessage

// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
existingData, readErr := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
switch {
case readErr == nil:
Expand Down Expand Up @@ -172,6 +173,7 @@ func (c *CopilotCLIAgent) UninstallHooks(ctx context.Context) error {
worktreeRoot = "."
}
hooksPath := filepath.Join(worktreeRoot, hooksDir, HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
if errors.Is(err, os.ErrNotExist) {
Expand Down Expand Up @@ -238,6 +240,7 @@ func (c *CopilotCLIAgent) AreHooksInstalled(ctx context.Context) bool {
worktreeRoot = "."
}
hooksPath := filepath.Join(worktreeRoot, hooksDir, HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
Expand Down
5 changes: 5 additions & 0 deletions cli/agent/copilotcli/transcript.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ func ExtractModelFromTranscript(ctx context.Context, transcriptPath string) stri
return ""
}

// #nosec G304 -- transcriptPath derived from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(transcriptPath) //nolint:gosec // Path derived from agent hook input
if err != nil {
logging.Debug(ctx, "copilot-cli: failed to read transcript for model extraction",
Expand Down Expand Up @@ -374,6 +375,7 @@ func (c *CopilotCLIAgent) GetTranscriptPosition(path string) (int, error) {
return 0, nil
}

// #nosec G304 -- path comes from Copilot CLI transcript location, not remote/untrusted input
file, err := os.Open(path) //nolint:gosec // Path comes from Copilot CLI transcript location
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -415,6 +417,7 @@ func (c *CopilotCLIAgent) ExtractModifiedFilesFromOffset(path string, startOffse
return nil, 0, nil
}

// #nosec G304 -- path comes from Copilot CLI transcript location, not remote/untrusted input
file, openErr := os.Open(path) //nolint:gosec // Path comes from Copilot CLI transcript location
if openErr != nil {
return nil, 0, fmt.Errorf("failed to open transcript file: %w", openErr)
Expand Down Expand Up @@ -452,6 +455,7 @@ func (c *CopilotCLIAgent) ExtractModifiedFilesFromOffset(path string, startOffse

// ExtractPrompts extracts user prompts from the transcript starting at the given offset.
func (c *CopilotCLIAgent) ExtractPrompts(sessionRef string, fromOffset int) ([]string, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return nil, fmt.Errorf("failed to read transcript: %w", err)
Expand All @@ -466,6 +470,7 @@ func (c *CopilotCLIAgent) ExtractPrompts(sessionRef string, fromOffset int) ([]s

// ExtractSummary extracts the last assistant message as a session summary.
func (c *CopilotCLIAgent) ExtractSummary(sessionRef string) (string, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return "", fmt.Errorf("failed to read transcript: %w", err)
Expand Down
5 changes: 4 additions & 1 deletion cli/agent/cursor/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func (c *CursorAgent) InstallHooks(ctx context.Context, localDev bool, force boo
var rawFile map[string]json.RawMessage
var rawHooks map[string]json.RawMessage

// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
existingData, readErr := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
if readErr == nil {
if err := json.Unmarshal(existingData, &rawFile); err != nil {
Expand Down Expand Up @@ -218,6 +219,7 @@ func (c *CursorAgent) UninstallHooks(ctx context.Context) error {
worktreeRoot = "."
}
hooksPath := filepath.Join(worktreeRoot, ".cursor", HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
return nil //nolint:nilerr // No hooks file means nothing to uninstall
Expand Down Expand Up @@ -297,6 +299,7 @@ func (c *CursorAgent) AreHooksInstalled(ctx context.Context) bool {
worktreeRoot = "."
}
hooksPath := filepath.Join(worktreeRoot, ".cursor", HooksFileName)
// #nosec G304 -- hooksPath is constructed from repo root + fixed path, not external input
data, err := os.ReadFile(hooksPath) //nolint:gosec // path is constructed from repo root + fixed path
if err != nil {
return false
Expand Down Expand Up @@ -333,7 +336,7 @@ func (c *CursorAgent) GetSupportedHooks() []agent.HookType {
func parseCursorHookType(rawHooks map[string]json.RawMessage, hookType string, target *[]CursorHookEntry) {
if data, ok := rawHooks[hookType]; ok {
//nolint:errcheck,gosec // Intentionally ignoring parse errors - leave target as nil/empty
json.Unmarshal(data, target)
json.Unmarshal(data, target) // #nosec G104 -- intentionally ignoring parse errors, leave target as nil/empty
}
}

Expand Down
1 change: 1 addition & 0 deletions cli/agent/cursor/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func (c *CursorAgent) ParseHookEvent(ctx context.Context, hookName string, stdin

// ReadTranscript reads the raw JSONL transcript bytes for a session.
func (c *CursorAgent) ReadTranscript(sessionRef string) ([]byte, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return nil, fmt.Errorf("failed to read transcript: %w", err)
Expand Down
2 changes: 2 additions & 0 deletions cli/agent/cursor/transcript.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func (c *CursorAgent) GetTranscriptPosition(path string) (int, error) {
return 0, nil
}

// #nosec G304 -- path comes from Cursor transcript location, not remote/untrusted input
file, err := os.Open(path) //nolint:gosec // Path comes from Cursor transcript location
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -77,6 +78,7 @@ func (c *CursorAgent) ExtractPrompts(sessionRef string, fromOffset int) ([]strin

// ExtractSummary extracts the last assistant message as a session summary.
func (c *CursorAgent) ExtractSummary(sessionRef string) (string, error) {
// #nosec G304 -- sessionRef comes from agent hook input (trusted lifecycle payload), not remote/untrusted input
data, err := os.ReadFile(sessionRef) //nolint:gosec // Path comes from agent hook input
if err != nil {
return "", fmt.Errorf("failed to read transcript: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion cli/agent/external/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func (e *Agent) run(ctx context.Context, stdin []byte, args ...string) ([]byte,
ctx, cancel = context.WithTimeout(ctx, defaultRunTimeout)
defer cancel()
}
cmd := exec.CommandContext(ctx, e.binaryPath, args...)
cmd := exec.CommandContext(ctx, e.binaryPath, args...) // #nosec G204 -- e.binaryPath is the user-configured external agent binary, a trusted operator-provided path; args are internally constructed
// Ensure I/O goroutines are released shortly after the process is killed,
// so cmd.Run() doesn't block waiting for pipe reads.
cmd.WaitDelay = 3 * time.Second
Expand Down
Loading
Loading