mirror of
https://github.com/rait-09/obsidian-agent-client.git
synced 2026-07-22 06:43:37 +00:00
Add guides for Codex and Gemini CLI
This commit is contained in:
parent
ec840c69a5
commit
1108d973bd
2 changed files with 452 additions and 0 deletions
226
AGENTS.md
Normal file
226
AGENTS.md
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
# Agent Client Plugin - LLM Developer Guide
|
||||
|
||||
## Overview
|
||||
Obsidian plugin for AI agent interaction (Claude Code, Gemini CLI, custom agents). **Clean Architecture** (5 layers): Presentation → Adapters → Use Cases → Domain ← Infrastructure.
|
||||
|
||||
**Tech**: React 19, TypeScript, Obsidian API, Agent Client Protocol (ACP)
|
||||
|
||||
## Architecture
|
||||
|
||||
**Dependency Flow**: Inward only. Core domain has zero external dependencies.
|
||||
|
||||
```
|
||||
src/
|
||||
├── core/domain/ # Pure domain models + ports (interfaces)
|
||||
│ ├── models/ # agent-config, agent-error, chat-message, chat-session
|
||||
│ └── ports/ # IAgentClient, ISettingsAccess, IVaultAccess
|
||||
├── core/use-cases/ # Business logic
|
||||
│ ├── handle-permission.use-case.ts
|
||||
│ ├── manage-session.use-case.ts
|
||||
│ ├── send-message.use-case.ts
|
||||
│ └── switch-agent.use-case.ts
|
||||
├── adapters/ # Interface implementations
|
||||
│ ├── acp/ # ACP protocol (acp.adapter.ts, acp-type-converter.ts)
|
||||
│ ├── obsidian/ # Platform adapters (vault, settings, mention-service)
|
||||
│ └── view-models/ # chat.view-model.ts (MVVM)
|
||||
├── infrastructure/ # External frameworks
|
||||
│ ├── obsidian-plugin/ # plugin.ts (lifecycle, persistence)
|
||||
│ └── terminal/ # terminal-manager.ts
|
||||
├── presentation/ # UI layer
|
||||
│ ├── views/chat/ # ChatView.tsx (DI container + rendering)
|
||||
│ └── components/ # chat/, settings/, shared/
|
||||
└── shared/ # Utilities (logger, exporter, mention-utils, settings-utils)
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### ChatView (`presentation/views/chat/ChatView.tsx`)
|
||||
- **DI Container**: Instantiates Use Cases, Adapters, ViewModel via useMemo
|
||||
- **Rendering**: Uses useSyncExternalStore for ViewModel state
|
||||
- **No Business Logic**: Pure UI component
|
||||
|
||||
### ChatViewModel (`adapters/view-models/chat.view-model.ts`)
|
||||
- **State**: messages, session, errorInfo, isSending, mention dropdown, slash command dropdown
|
||||
- **Methods** (27): Session mgmt, messaging, permissions, agent switching, mentions, slash commands
|
||||
- **Delegates**: All logic to Use Cases
|
||||
- **Callbacks**: addMessage, updateLastMessage, updateMessage, updateAvailableCommands (from AcpAdapter)
|
||||
|
||||
### Use Cases (`core/use-cases/`)
|
||||
|
||||
**SendMessageUseCase**:
|
||||
- `prepareMessage()`: Sync - auto-mention, convert @[[note]] → paths
|
||||
- `sendPreparedMessage()`: Async - send via IAgentClient, auth retry
|
||||
- Error handling: Ignore "empty response text", auto-retry auth failures
|
||||
|
||||
**ManageSessionUseCase**:
|
||||
- `createSession()`: Load config, inject API keys, initialize + newSession
|
||||
- `restartSession()`: Cancel old, create new
|
||||
- `closeSession()`: Call IAgentClient.cancel()
|
||||
|
||||
**HandlePermissionUseCase**:
|
||||
- `approvePermission()`: Respond with selected option
|
||||
- `shouldAutoApprove()`: Check settings.autoAllowPermissions
|
||||
- `getAutoApproveOption()`: Select first allow_once/allow_always
|
||||
|
||||
**SwitchAgentUseCase**:
|
||||
- `switchAgent()`: Update settings.activeAgentId
|
||||
- `getAvailableAgents()`: Return claude, gemini, custom agents
|
||||
|
||||
### AcpAdapter (`adapters/acp/acp.adapter.ts`)
|
||||
Implements IAgentClient + IAcpClient (terminal ops)
|
||||
|
||||
- **Process**: spawn() with login shell (macOS/Linux -l, Windows shell:true)
|
||||
- **Protocol**: JSON-RPC over stdin/stdout via ndJsonStream
|
||||
- **Flow**: initialize() → newSession() → sendMessage() → sessionUpdate() callbacks
|
||||
- **Callbacks**: setMessageCallbacks() wires to ViewModel
|
||||
- **Updates**: agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan, available_commands_update
|
||||
- **Permissions**: Promise-based Map<requestId, resolver>
|
||||
- **Terminal**: createTerminal, terminalOutput, killTerminal, releaseTerminal
|
||||
|
||||
### Obsidian Adapters
|
||||
|
||||
**VaultAdapter**: IVaultAccess - searchNotes (fuzzy via NoteMentionService), getActiveNote, readNote
|
||||
**SettingsStore**: ISettingsAccess - Observer pattern, getSnapshot(), subscribe(), updateSettings()
|
||||
**MentionService**: File index, fuzzy search (basename, path, frontmatter aliases)
|
||||
|
||||
### Terminal Manager (`infrastructure/terminal/terminal-manager.ts`)
|
||||
- spawn(), capture stdout/stderr (10MB limit), track exit codes
|
||||
- killTerminal(): SIGTERM → wait → SIGKILL
|
||||
|
||||
### Mention System
|
||||
|
||||
**Flow**:
|
||||
1. User types `@` → ChatViewModel.updateMentionSuggestions()
|
||||
2. detectMention() finds cursor context
|
||||
3. IVaultAccess.searchNotes() → fuzzy search
|
||||
4. Display SuggestionDropdown (type: "mention")
|
||||
5. User selects → replaceMention() → convertMentionsToPath()
|
||||
|
||||
**Syntax**: `@[[note name]]` → `/absolute/path/to/note name.md`
|
||||
|
||||
### Slash Command System
|
||||
|
||||
**Flow**:
|
||||
1. User types `/` at start → ChatViewModel.updateSlashCommandSuggestions()
|
||||
2. Filter availableCommands by query after `/`
|
||||
3. Display SuggestionDropdown (type: "slash-command")
|
||||
4. User selects → Insert command, show hint overlay if command has hint
|
||||
5. Auto-mention temporarily disabled (ACP requires `/` at message start)
|
||||
|
||||
**Features**:
|
||||
- **Hint Overlay**: Visual hint displayed using invisible span for precise alignment
|
||||
- **Auto-mention Disable**: Prevents auto-mention from interfering with slash command recognition
|
||||
- **Dropdown Reuse**: SuggestionDropdown component handles both mentions and slash commands
|
||||
|
||||
**ACP Integration**: Receives `available_commands_update` notification with command metadata (name, description, hint)
|
||||
|
||||
## Ports (Interfaces)
|
||||
|
||||
```typescript
|
||||
interface IAgentClient {
|
||||
initialize(config: AgentConfig): Promise<InitializeResult>;
|
||||
newSession(workingDirectory: string): Promise<NewSessionResult>;
|
||||
authenticate(methodId: string): Promise<boolean>;
|
||||
sendMessage(sessionId: string, message: string): Promise<void>;
|
||||
cancel(sessionId: string): Promise<void>;
|
||||
disconnect(): Promise<void>;
|
||||
onMessage(callback: (message: ChatMessage) => void): void;
|
||||
onError(callback: (error: AgentError) => void): void;
|
||||
onPermissionRequest(callback: (request: PermissionRequest) => void): void;
|
||||
respondToPermission(requestId: string, optionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
interface IVaultAccess {
|
||||
readNote(path: string): Promise<string>;
|
||||
searchNotes(query: string): Promise<NoteMetadata[]>;
|
||||
getActiveNote(): Promise<NoteMetadata | null>;
|
||||
listNotes(): Promise<NoteMetadata[]>;
|
||||
}
|
||||
|
||||
interface ISettingsAccess {
|
||||
getSnapshot(): AgentClientPluginSettings;
|
||||
updateSettings(updates: Partial<AgentClientPluginSettings>): Promise<void>;
|
||||
subscribe(listener: () => void): () => void;
|
||||
}
|
||||
```
|
||||
|
||||
## Development Rules
|
||||
|
||||
### Clean Architecture
|
||||
1. **Dependencies**: Inward only (Presentation → Adapters → Use Cases → Domain)
|
||||
2. **Domain**: Zero external deps (no `obsidian`, `@agentclientprotocol/sdk`)
|
||||
3. **Use Ports**: Use Cases depend on interfaces, not implementations
|
||||
4. **No UI Logic**: ChatView/components render only, delegate to ViewModel
|
||||
|
||||
### Obsidian Plugin Review (CRITICAL)
|
||||
1. No innerHTML/outerHTML - use createEl/createDiv/createSpan
|
||||
2. NO detach leaves in onunload (antipattern)
|
||||
3. Styles in CSS only - no JS style manipulation
|
||||
4. Use Platform interface - not process.platform
|
||||
5. Minimize `any` - use proper types
|
||||
|
||||
### Naming Conventions
|
||||
- Ports: `*.port.ts`
|
||||
- Use Cases: `*.use-case.ts`
|
||||
- Adapters: `*.adapter.ts`
|
||||
- ViewModels: `*.view-model.ts`
|
||||
- Components: `PascalCase.tsx`
|
||||
- Utils/Models: `kebab-case.ts`
|
||||
|
||||
### Code Patterns
|
||||
1. Error handling: try-catch async ops
|
||||
2. Strict typing, avoid `any`
|
||||
3. React: hooks, useMemo for DI
|
||||
4. Settings: validate + defaults
|
||||
5. Logging: Logger class (respects debugMode)
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Add Use Case
|
||||
1. Create `core/use-cases/[name].use-case.ts`
|
||||
2. Define input/output interfaces
|
||||
3. Inject ports via constructor
|
||||
4. Add to ChatViewModel dependencies
|
||||
5. Call from ChatViewModel method
|
||||
|
||||
### Add Agent Type
|
||||
1. **Optional**: Define config in `core/domain/models/agent-config.ts`
|
||||
2. **Adapter**: Implement IAgentClient in `adapters/[agent]/[agent].adapter.ts`
|
||||
3. **Settings**: Add to AgentClientPluginSettings in plugin.ts
|
||||
4. **UI**: Update AgentClientSettingTab
|
||||
**No changes in Use Cases/Domain!**
|
||||
|
||||
### Modify Message Types
|
||||
1. Update `ChatMessage`/`MessageContent` in `core/domain/models/chat-message.ts`
|
||||
2. Update `AcpAdapter.sessionUpdate()` to handle new type
|
||||
3. Update `MessageContentRenderer` to render new type
|
||||
4. **Optional**: Update AcpTypeConverter
|
||||
|
||||
### Debug
|
||||
1. Settings → Developer Settings → Debug Mode ON
|
||||
2. Open DevTools (Cmd+Option+I / Ctrl+Shift+I)
|
||||
3. Filter logs: `[AcpAdapter]`, `[ViewModel]`, `[NoteMentionService]`
|
||||
|
||||
**Logged**: Process lifecycle, ACP messages, session state, permissions, terminal ops, errors
|
||||
|
||||
## ACP Protocol
|
||||
|
||||
**Communication**: JSON-RPC 2.0 over stdin/stdout
|
||||
|
||||
**Methods**: initialize, newSession, authenticate, prompt, cancel
|
||||
**Notifications**: session/update (agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan, available_commands_update)
|
||||
**Requests**: requestPermission
|
||||
|
||||
**Slash Commands**: Agents advertise available commands via `available_commands_update` notification. Commands include:
|
||||
- `name`: Command identifier (e.g., "web", "test")
|
||||
- `description`: Human-readable description
|
||||
- `hint`: Optional input hint (e.g., "query to search for")
|
||||
|
||||
**Agents**:
|
||||
- Claude Code: `@zed-industries/claude-code-acp` (ANTHROPIC_API_KEY)
|
||||
- Gemini CLI: `@google/gemini-cli --experimental-acp` (GOOGLE_API_KEY)
|
||||
- Custom: Any ACP-compatible agent
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: October 2025 | **Architecture**: Clean (5-layer) | **Version**: 0.2.0
|
||||
226
GEMINI.md
Normal file
226
GEMINI.md
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
# Agent Client Plugin - LLM Developer Guide
|
||||
|
||||
## Overview
|
||||
Obsidian plugin for AI agent interaction (Claude Code, Gemini CLI, custom agents). **Clean Architecture** (5 layers): Presentation → Adapters → Use Cases → Domain ← Infrastructure.
|
||||
|
||||
**Tech**: React 19, TypeScript, Obsidian API, Agent Client Protocol (ACP)
|
||||
|
||||
## Architecture
|
||||
|
||||
**Dependency Flow**: Inward only. Core domain has zero external dependencies.
|
||||
|
||||
```
|
||||
src/
|
||||
├── core/domain/ # Pure domain models + ports (interfaces)
|
||||
│ ├── models/ # agent-config, agent-error, chat-message, chat-session
|
||||
│ └── ports/ # IAgentClient, ISettingsAccess, IVaultAccess
|
||||
├── core/use-cases/ # Business logic
|
||||
│ ├── handle-permission.use-case.ts
|
||||
│ ├── manage-session.use-case.ts
|
||||
│ ├── send-message.use-case.ts
|
||||
│ └── switch-agent.use-case.ts
|
||||
├── adapters/ # Interface implementations
|
||||
│ ├── acp/ # ACP protocol (acp.adapter.ts, acp-type-converter.ts)
|
||||
│ ├── obsidian/ # Platform adapters (vault, settings, mention-service)
|
||||
│ └── view-models/ # chat.view-model.ts (MVVM)
|
||||
├── infrastructure/ # External frameworks
|
||||
│ ├── obsidian-plugin/ # plugin.ts (lifecycle, persistence)
|
||||
│ └── terminal/ # terminal-manager.ts
|
||||
├── presentation/ # UI layer
|
||||
│ ├── views/chat/ # ChatView.tsx (DI container + rendering)
|
||||
│ └── components/ # chat/, settings/, shared/
|
||||
└── shared/ # Utilities (logger, exporter, mention-utils, settings-utils)
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### ChatView (`presentation/views/chat/ChatView.tsx`)
|
||||
- **DI Container**: Instantiates Use Cases, Adapters, ViewModel via useMemo
|
||||
- **Rendering**: Uses useSyncExternalStore for ViewModel state
|
||||
- **No Business Logic**: Pure UI component
|
||||
|
||||
### ChatViewModel (`adapters/view-models/chat.view-model.ts`)
|
||||
- **State**: messages, session, errorInfo, isSending, mention dropdown, slash command dropdown
|
||||
- **Methods** (27): Session mgmt, messaging, permissions, agent switching, mentions, slash commands
|
||||
- **Delegates**: All logic to Use Cases
|
||||
- **Callbacks**: addMessage, updateLastMessage, updateMessage, updateAvailableCommands (from AcpAdapter)
|
||||
|
||||
### Use Cases (`core/use-cases/`)
|
||||
|
||||
**SendMessageUseCase**:
|
||||
- `prepareMessage()`: Sync - auto-mention, convert @[[note]] → paths
|
||||
- `sendPreparedMessage()`: Async - send via IAgentClient, auth retry
|
||||
- Error handling: Ignore "empty response text", auto-retry auth failures
|
||||
|
||||
**ManageSessionUseCase**:
|
||||
- `createSession()`: Load config, inject API keys, initialize + newSession
|
||||
- `restartSession()`: Cancel old, create new
|
||||
- `closeSession()`: Call IAgentClient.cancel()
|
||||
|
||||
**HandlePermissionUseCase**:
|
||||
- `approvePermission()`: Respond with selected option
|
||||
- `shouldAutoApprove()`: Check settings.autoAllowPermissions
|
||||
- `getAutoApproveOption()`: Select first allow_once/allow_always
|
||||
|
||||
**SwitchAgentUseCase**:
|
||||
- `switchAgent()`: Update settings.activeAgentId
|
||||
- `getAvailableAgents()`: Return claude, gemini, custom agents
|
||||
|
||||
### AcpAdapter (`adapters/acp/acp.adapter.ts`)
|
||||
Implements IAgentClient + IAcpClient (terminal ops)
|
||||
|
||||
- **Process**: spawn() with login shell (macOS/Linux -l, Windows shell:true)
|
||||
- **Protocol**: JSON-RPC over stdin/stdout via ndJsonStream
|
||||
- **Flow**: initialize() → newSession() → sendMessage() → sessionUpdate() callbacks
|
||||
- **Callbacks**: setMessageCallbacks() wires to ViewModel
|
||||
- **Updates**: agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan, available_commands_update
|
||||
- **Permissions**: Promise-based Map<requestId, resolver>
|
||||
- **Terminal**: createTerminal, terminalOutput, killTerminal, releaseTerminal
|
||||
|
||||
### Obsidian Adapters
|
||||
|
||||
**VaultAdapter**: IVaultAccess - searchNotes (fuzzy via NoteMentionService), getActiveNote, readNote
|
||||
**SettingsStore**: ISettingsAccess - Observer pattern, getSnapshot(), subscribe(), updateSettings()
|
||||
**MentionService**: File index, fuzzy search (basename, path, frontmatter aliases)
|
||||
|
||||
### Terminal Manager (`infrastructure/terminal/terminal-manager.ts`)
|
||||
- spawn(), capture stdout/stderr (10MB limit), track exit codes
|
||||
- killTerminal(): SIGTERM → wait → SIGKILL
|
||||
|
||||
### Mention System
|
||||
|
||||
**Flow**:
|
||||
1. User types `@` → ChatViewModel.updateMentionSuggestions()
|
||||
2. detectMention() finds cursor context
|
||||
3. IVaultAccess.searchNotes() → fuzzy search
|
||||
4. Display SuggestionDropdown (type: "mention")
|
||||
5. User selects → replaceMention() → convertMentionsToPath()
|
||||
|
||||
**Syntax**: `@[[note name]]` → `/absolute/path/to/note name.md`
|
||||
|
||||
### Slash Command System
|
||||
|
||||
**Flow**:
|
||||
1. User types `/` at start → ChatViewModel.updateSlashCommandSuggestions()
|
||||
2. Filter availableCommands by query after `/`
|
||||
3. Display SuggestionDropdown (type: "slash-command")
|
||||
4. User selects → Insert command, show hint overlay if command has hint
|
||||
5. Auto-mention temporarily disabled (ACP requires `/` at message start)
|
||||
|
||||
**Features**:
|
||||
- **Hint Overlay**: Visual hint displayed using invisible span for precise alignment
|
||||
- **Auto-mention Disable**: Prevents auto-mention from interfering with slash command recognition
|
||||
- **Dropdown Reuse**: SuggestionDropdown component handles both mentions and slash commands
|
||||
|
||||
**ACP Integration**: Receives `available_commands_update` notification with command metadata (name, description, hint)
|
||||
|
||||
## Ports (Interfaces)
|
||||
|
||||
```typescript
|
||||
interface IAgentClient {
|
||||
initialize(config: AgentConfig): Promise<InitializeResult>;
|
||||
newSession(workingDirectory: string): Promise<NewSessionResult>;
|
||||
authenticate(methodId: string): Promise<boolean>;
|
||||
sendMessage(sessionId: string, message: string): Promise<void>;
|
||||
cancel(sessionId: string): Promise<void>;
|
||||
disconnect(): Promise<void>;
|
||||
onMessage(callback: (message: ChatMessage) => void): void;
|
||||
onError(callback: (error: AgentError) => void): void;
|
||||
onPermissionRequest(callback: (request: PermissionRequest) => void): void;
|
||||
respondToPermission(requestId: string, optionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
interface IVaultAccess {
|
||||
readNote(path: string): Promise<string>;
|
||||
searchNotes(query: string): Promise<NoteMetadata[]>;
|
||||
getActiveNote(): Promise<NoteMetadata | null>;
|
||||
listNotes(): Promise<NoteMetadata[]>;
|
||||
}
|
||||
|
||||
interface ISettingsAccess {
|
||||
getSnapshot(): AgentClientPluginSettings;
|
||||
updateSettings(updates: Partial<AgentClientPluginSettings>): Promise<void>;
|
||||
subscribe(listener: () => void): () => void;
|
||||
}
|
||||
```
|
||||
|
||||
## Development Rules
|
||||
|
||||
### Clean Architecture
|
||||
1. **Dependencies**: Inward only (Presentation → Adapters → Use Cases → Domain)
|
||||
2. **Domain**: Zero external deps (no `obsidian`, `@agentclientprotocol/sdk`)
|
||||
3. **Use Ports**: Use Cases depend on interfaces, not implementations
|
||||
4. **No UI Logic**: ChatView/components render only, delegate to ViewModel
|
||||
|
||||
### Obsidian Plugin Review (CRITICAL)
|
||||
1. No innerHTML/outerHTML - use createEl/createDiv/createSpan
|
||||
2. NO detach leaves in onunload (antipattern)
|
||||
3. Styles in CSS only - no JS style manipulation
|
||||
4. Use Platform interface - not process.platform
|
||||
5. Minimize `any` - use proper types
|
||||
|
||||
### Naming Conventions
|
||||
- Ports: `*.port.ts`
|
||||
- Use Cases: `*.use-case.ts`
|
||||
- Adapters: `*.adapter.ts`
|
||||
- ViewModels: `*.view-model.ts`
|
||||
- Components: `PascalCase.tsx`
|
||||
- Utils/Models: `kebab-case.ts`
|
||||
|
||||
### Code Patterns
|
||||
1. Error handling: try-catch async ops
|
||||
2. Strict typing, avoid `any`
|
||||
3. React: hooks, useMemo for DI
|
||||
4. Settings: validate + defaults
|
||||
5. Logging: Logger class (respects debugMode)
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Add Use Case
|
||||
1. Create `core/use-cases/[name].use-case.ts`
|
||||
2. Define input/output interfaces
|
||||
3. Inject ports via constructor
|
||||
4. Add to ChatViewModel dependencies
|
||||
5. Call from ChatViewModel method
|
||||
|
||||
### Add Agent Type
|
||||
1. **Optional**: Define config in `core/domain/models/agent-config.ts`
|
||||
2. **Adapter**: Implement IAgentClient in `adapters/[agent]/[agent].adapter.ts`
|
||||
3. **Settings**: Add to AgentClientPluginSettings in plugin.ts
|
||||
4. **UI**: Update AgentClientSettingTab
|
||||
**No changes in Use Cases/Domain!**
|
||||
|
||||
### Modify Message Types
|
||||
1. Update `ChatMessage`/`MessageContent` in `core/domain/models/chat-message.ts`
|
||||
2. Update `AcpAdapter.sessionUpdate()` to handle new type
|
||||
3. Update `MessageContentRenderer` to render new type
|
||||
4. **Optional**: Update AcpTypeConverter
|
||||
|
||||
### Debug
|
||||
1. Settings → Developer Settings → Debug Mode ON
|
||||
2. Open DevTools (Cmd+Option+I / Ctrl+Shift+I)
|
||||
3. Filter logs: `[AcpAdapter]`, `[ViewModel]`, `[NoteMentionService]`
|
||||
|
||||
**Logged**: Process lifecycle, ACP messages, session state, permissions, terminal ops, errors
|
||||
|
||||
## ACP Protocol
|
||||
|
||||
**Communication**: JSON-RPC 2.0 over stdin/stdout
|
||||
|
||||
**Methods**: initialize, newSession, authenticate, prompt, cancel
|
||||
**Notifications**: session/update (agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan, available_commands_update)
|
||||
**Requests**: requestPermission
|
||||
|
||||
**Slash Commands**: Agents advertise available commands via `available_commands_update` notification. Commands include:
|
||||
- `name`: Command identifier (e.g., "web", "test")
|
||||
- `description`: Human-readable description
|
||||
- `hint`: Optional input hint (e.g., "query to search for")
|
||||
|
||||
**Agents**:
|
||||
- Claude Code: `@zed-industries/claude-code-acp` (ANTHROPIC_API_KEY)
|
||||
- Gemini CLI: `@google/gemini-cli --experimental-acp` (GOOGLE_API_KEY)
|
||||
- Custom: Any ACP-compatible agent
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: October 2025 | **Architecture**: Clean (5-layer) | **Version**: 0.2.0
|
||||
Loading…
Reference in a new issue