Files
kandev/apps/backend/internal/agent/agents/detect.go
T
João Salavisa cab7b28ed9 chore: round 4 dead-code cleanup (transport helpers, detect, orphan methods) (#1156)
* chore(agentctl): delete duplicate procattr files in adapter package

setProcGroup and killProcessGroup are defined in both
agentctl/server/adapter/ and agentctl/server/process/. The process/
copies are the live ones (called by process/runner.go, manager.go,
vscode.go); the adapter/ copies have zero callers and are removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(agentctl): remove orphan helpers from transport/shared

Left over from the ACP refactor. All had zero callers:
- DebugEnabled(): internal debugMode var is checked directly by
  LogRawEvent/LogNormalizedEvent — the exported wrapper was unused.
- GetBool, GetMap, GetSlice: only GetString/GetInt are called in acp/normalize.go.
- NormalizeShellResult, NormalizeReadResult, NormalizeCodeSearchResult,
  NormalizeModifyResult: normalization moved to acp/normalize.go.
- TruncateIfNeeded, MaxContentLength, MaxFileCount: only used by the
  four Normalize* helpers above; removed transitively.
- TraceControlMessage: zero callers in the adapter transport layer.

GenerateUnifiedDiff, SplitLines, DetectLanguage, Tracer, ShutdownTracing,
TraceProtocolEvent, TraceProtocolRequest are alive and kept.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(agentctl): remove unused tool_payload constructors

NewHttpRequest, NewCreateTask, NewSubagentTask, NewShowPlan,
NewManageTodos, and NewMisc have zero callers — ACP normalization
builds NormalizedPayload via struct literals and JSON unmarshaling,
not these factory functions. NewReadFile, NewModifyFile, NewShellExec,
NewCodeSearch, and NewGeneric are kept (live callers in acp/normalize.go).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(agents/detect): remove dead fluent options and OSPaths type

WithFileExists, WithCommandOutput, WithEnvVar, expandHomePath (their
transitive helper), and OSPaths (struct + Resolve + Expanded) have
zero callers. Only WithCommand and WithNpxRunnable are used by agent
IsInstalled implementations. Imports trimmed to context and os/exec.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(office): remove dead channel methods superseded by service/

ListComments, DeleteComment, and UpdateChannelStatus on ChannelService
have zero callers — the live implementations live in
internal/office/service/comments.go and service/channels.go.
CreateComment is kept: it is called by HandleChannelInbound.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: remove scattered orphan helpers

Remove dead single-symbol exports verified to have zero callers:
- ParseCronExpression (office/shared/cron.go): NextCronTime covers
  all live usages; the validator wrapper was unused.
- IsValidPathComponent, MustJSON (office/shared/helpers.go): zero
  callers; GenerateSlug is kept.
- DiscoverUserSkillsAt (office/skills/userhome_discovery.go): exported
  wrapper over the private discoverUserSkillsAt; only the internal
  DiscoverUserSkills method is wired up.
- Manager.Get (agent/loginpty/manager.go): zero callers; GetByID and
  Stop are kept (Stop is tested in manager_test.go).
- DetachedWithValues (common/appctx/appctx.go): zero callers; Detached
  is kept.
- Repository.Close no-ops (task/share, terminal/repository): both are
  documented no-ops with zero callers.
- TaskBranchName (worktree/config.go): zero callers; the deterministic
  TaskBranchNameWithSuffix is kept.

Note: dialect.Now was initially targeted but is tested in
dialect_test.go (same-package call — missed by package-qualified grep).
It remains unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(share): remove stale Close reference from provider.go comment

Repository.Close() was removed as a no-op in the round-4 cleanup.
The comment in provider.go still referenced it by name; updated to
reflect that the repo simply doesn't own its DB connections.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(office/shared): delete helpers.go — GenerateSlug had zero callers

The triage step mistakenly identified skills/service.go as a caller,
but that package defines its own local GenerateSlug (different regex,
adds TrimSpace and a 'skill' fallback default). shared.GenerateSlug
was never called anywhere. helpers.go is now empty; delete the file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(worktree): fix stale TaskBranchName reference in TaskBranchNameWithSuffix doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:18:10 +01:00

68 lines
2.3 KiB
Go

package agents
import (
"context"
"os/exec"
)
// DetectOption is a detection strategy. Returns (found, matchedPath, err).
type DetectOption func(ctx context.Context) (bool, string, error)
// WithCommand checks if a command is in PATH (exec.LookPath).
func WithCommand(name string) DetectOption {
return func(ctx context.Context) (bool, string, error) {
path, err := exec.LookPath(name)
if err != nil {
return false, "", nil
}
return true, path, nil
}
}
// WithNpxRunnable reports the agent as runnable via `npx -y <pkg>` whenever
// npx is on PATH. MatchedPath is tagged "npx <pkg>" so the settings page
// renders "Detected at npx <pkg>", giving users an honest hint that the
// package isn't globally installed but will be fetched on launch.
//
// Only `npx` is checked, not `node`: every npm-distributed agent's launch
// command is `npx -y <pkg>`, so a node-only setup would pass detection but
// fail at session start with "exec: npx: executable file not found in PATH".
//
// Use this AFTER a WithCommand check for the global binary — Detect is
// first-match-wins, so the global install (if present) is preferred and
// reports its real path.
//
// NOTE: not currently wired into any agent's IsInstalled. The host-utility
// manager treats Available=true as a green light to spawn and probe the
// agent at boot, so claiming availability via npx alone caused unwanted
// downloads and misleading auth_required/failed states for agents the user
// never installed. The helper is parked here until the host-utility manager
// gains a "skip probe for npx-fallback detections" path; at that point this
// can be re-wired into the npm-distributed agents' IsInstalled.
func WithNpxRunnable(pkg string) DetectOption {
return func(ctx context.Context) (bool, string, error) {
if _, err := exec.LookPath("npx"); err == nil {
return true, "npx " + pkg, nil
}
return false, "", nil
}
}
// Detect runs options in order, returns first match.
// If none match, returns DiscoveryResult{Available: false}.
func Detect(ctx context.Context, opts ...DetectOption) (*DiscoveryResult, error) {
for _, opt := range opts {
found, matched, err := opt(ctx)
if err != nil {
return &DiscoveryResult{Available: false}, err
}
if found {
return &DiscoveryResult{
Available: true,
MatchedPath: matched,
}, nil
}
}
return &DiscoveryResult{Available: false}, nil
}