Skip to content

Saved agent config loses to project-marker detection in autoResolveAgent #89

Description

@mrrobertkent

The precedence documented on autoResolveAgent does not match the code, and one of its branches is unreachable.

Documented

 *   1. Explicit `--agent` flag.
 *   2. Env-detected target (`CLAUDE_CODE`, `CURSOR_SESSION`, etc).
 *   3. Saved config default.
 *   4. Project marker dirs (`.claude/skills`, `.cursor/`, …) when exactly one
 *      agent matches the cwd.
 *   5. Installed agents on the machine when exactly one is found.

Actual

export function resolveAgent(agentFlag?: string): AgentType | 'none' | null {
  if (process.env.SKILLD_NO_AGENT)
    return null
  return (agentFlag as AgentType | undefined)
    ?? detectTargetAgent()
    ?? (readConfig().agent as AgentType | undefined)
    ?? null
}

detectTargetAgent() is env and project markers:

export function detectTargetAgent(): AgentType | null {
  for (const [type, target] of Object.entries(agents)) {
    if (target.detectEnv())
      return type as AgentType
  }
  const projectMatches: AgentType[] = []
  // …
  return projectMatches.length === 1 ? projectMatches[0]! : null
}

So project markers are consulted at step 2, before the saved config. A user who sets agent: claude-code via skilld config gets a different agent in any project whose only marker directory belongs to another agent.

Unreachable branch

const projectMatches = detectProjectAgents()
if (projectMatches.length === 1)
  return projectMatches[0]!

autoResolveAgent only reaches this after resolveAgent returned null, which for the project-marker path means detectTargetAgent() saw a count other than 1. detectProjectAgents() returns the same set, so the length can never be 1 here. Confirmed on a project with three marker dirs:

detectProjectAgents(): ["claude-code","codex","github-copilot"]
detectTargetAgent()  : null

Suggested resolution

Split env detection from project detection so the saved config can sit between them, matching the documentation:

return (agentFlag as AgentType | undefined)
  ?? detectEnvAgent()
  ?? (readConfig().agent as AgentType | undefined)
  ?? detectProjectAgent()
  ?? null

That also makes the detectProjectAgents() branch in autoResolveAgent redundant and removable.

Happy to send a PR, but the ordering is a product decision: if project markers are meant to win over the saved config, the fix is to correct the comment instead. Let me know which you prefer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions