## Context

### Current Implementation
The plugin uses a simple `opencodePath: string` setting that defaults to "opencode". The `ServerManager` spawns this directly with default arguments:
```typescript
this.process = this.processImpl.start(
  this.settings.opencodePath,
  ["serve", "--port", this.settings.port.toString(), ...],
  options
);
```

Platform-specific process implementations (`PosixProcess`, `WindowsProcess`) handle spawning and verification. The `verifyCommand` method checks if the executable exists.

### New Requirements
1. One-time autodetect for new users (empty path on first run)
2. Support custom shell commands with full user control
3. Maintain backward compatibility with existing path-based configuration

## Goals / Non-Goals

**Goals:**
- Provide zero-configuration setup for new users via autodetect
- Enable power users to use custom commands with full flexibility
- Maintain backward compatibility for existing users
- Clear UI distinction between path mode and custom command mode
- Platform-aware executable detection (PATH + common locations)

**Non-Goals:**
- Complex command builder UI (simple text input for custom commands)
- Automatic installation of opencode
- Validation of custom commands before execution

## Decisions

### 1. Settings Schema Extension
**Decision:** Extend existing settings rather than replace.

**Rationale:**
- Maintains backward compatibility - existing configs continue working
- Simple migration - just add new fields with sensible defaults
- Minimal code changes to existing path-based logic

**Alternatives considered:**
- Replace with structured command object - rejected due to breaking change
- Separate settings sections - rejected as overkill for this feature

**Implementation:**
```typescript
interface OpenCodeSettings {
  // ... existing fields ...
  opencodePath: string;           // Still used as primary path
  customCommand: string;          // New: shell command
  useCustomCommand: boolean;     // New: toggle mode
}
```

### 2. Autodetect Trigger Strategy
**Decision:** Autodetect runs on every plugin startup when path is empty.

**Rationale:**
- Reminds user to configure or disable the plugin if opencode is missing
- Simpler implementation - no state tracking needed
- If user installs opencode later, it will be detected automatically

**Alternatives considered:**
- Run once and remember with flag - rejected as hides the problem
- Run only manually - rejected as adds friction for new users
- Explicit "first setup" wizard - rejected as overkill

**Implementation:**
```typescript
// In main.ts onload()
if (!this.settings.opencodePath && !this.settings.useCustomCommand) {
  await this.attemptAutodetect();
}
```

### 3. Custom Command Spawning Strategy
**Decision:** Use `shell: true` for custom commands, user controls ALL arguments.

**Rationale:**
- Maximum flexibility - env vars, pipes, complex invocations all work
- Simple mental model - "what you type is what runs"
- No ambiguity about argument concatenation

**Alternatives considered:**
- Parse and split custom command - rejected as fragile
- Merge plugin args with custom args - rejected as confusing
- Separate args array - rejected as limiting

**Implementation:**
```typescript
// Path mode
this.process = spawn(opencodePath, ["serve", "--port", port, ...], options);

// Custom mode
this.process = spawn(customCommand, [], { ...options, shell: true });
```

### 4. Executable Detection Order
**Decision:** Check PATH first, then platform-specific common locations.

**Rationale:**
- Respects user's environment setup
- Common locations cover most package manager installs (homebrew, cargo, npm -g, etc.)

**Search algorithm:**
1. If configured path is absolute and exists, return it directly
2. Extract basename from configured path (e.g., "opencode" from "/path/to/opencode" or just "opencode")
3. Search platform-specific locations for that basename:
   - **Linux:** `~/.local/bin/`, `~/.opencode/bin/`, `~/.bun/bin/`, `~/.npm-global/bin/`, `~/.nvm/versions/node/*/bin/`, `/usr/local/bin/`, `/usr/bin/`
   - **macOS:** `~/.local/bin/`, `/opt/homebrew/bin/`, `/usr/local/bin/`
   - **Windows:** `%LOCALAPPDATA%\opencode\bin\`, `%USERPROFILE%\.bun\bin\`, `%USERPROFILE%\.local\bin\`
4. If found, return full path; if not found, return configured path as fallback

**nvm wildcard handling:** For `~/.nvm/versions/node/*/bin/`, expand the wildcard to find actual Node version directories.

### 5. UI Layout
**Decision:** Toggle switch to select mode, conditional display of relevant input.

**Rationale:**
- Clear mental model - one or the other, not both
- Reduces visual clutter
- Toggle state directly maps to `useCustomCommand` boolean

**Layout:**
```
Command Mode:
[  Use custom command  ●─────○  ]

[Path Mode - shown when toggle off]
OpenCode path: [____________] [Autodetect]

[Custom Mode - shown when toggle on]
Custom command:
[______________________________]
(Full shell command with all arguments)
```

## Risks / Trade-offs

**[Risk]** Custom command mode is powerful but dangerous - users can break their setup.
→ **Mitigation:** This is intentional flexibility. Users opting into "custom command" are advanced users. No validation performed - natural failure on spawn.

**[Risk]** Autodetect could find wrong executable (different binary with same name).
→ **Mitigation:** Low probability - "opencode" is unique. Could add version check in future if needed.

**[Risk]** Users may not understand difference between path and custom command modes.
→ **Mitigation:** Clear UI labels and descriptions. Path mode is default, custom mode opt-in.

**[Risk]** Toast notification on every startup might be annoying if user intentionally leaves path empty.
→ **Mitigation:** User can switch to custom command mode (even with empty command) to suppress autodetect, or configure a path.

## Migration Plan

1. **No breaking changes** - existing configs with `opencodePath` set continue working
2. **New fields** default to empty/false
3. **Autodetect** triggers on every startup when path is empty and custom command mode is disabled
4. **Settings UI** adapts to existing data - if `opencodePath` is set, starts in path mode

## Open Questions

None - design is complete based on user requirements.
