Thank you for your interest in contributing to the Agent Client plugin!
For significant changes, please open an issue before writing code:
- New features
- Architecture changes
- Adding or modifying external dependencies
- Implementing draft/experimental ACP specifications
This helps ensure alignment with the project direction and saves time for both contributors and maintainers.
You can submit a PR directly for:
- Obvious bug fixes (typos, crashes, etc.)
- Fixes for existing issues
- Documentation improvements
This plugin focuses on ACP client implementation + features that make ACP convenient to use in Obsidian.
In scope:
- ACP protocol implementation
- Note mentions (
@[[note]]to pass note content to agents) - Obsidian-specific UI integration
Out of scope:
- Features achievable via standard protocols like MCP (these should be provided as MCP servers for a consistent experience across all agents)
- Agent-specific features (these should be handled via agent-specific config files, e.g.,
.claude/directory)
- Node.js 18.x or later
- npm
# Navigate to your vault's plugins directory
cd /path/to/your/vault/.obsidian/plugins
# Clone the repository as "agent-client"
# The directory name must match the id in manifest.json
git clone https://github.com/RAIT-09/obsidian-agent-client.git agent-client
cd agent-client
# Install dependencies
npm install
# Start development build (watch mode)
npm run dev- After cloning to
.obsidian/plugins/agent-client, runnpm run dev - Enable the plugin in Obsidian Settings → Community Plugins
- Code changes trigger automatic rebuilds, but you need to reload the plugin (toggle it off/on in Community Plugins) to see changes
| Command | Description |
|---|---|
npm run dev |
Development build (watch mode) |
npm run build |
Production build (includes TypeScript type check) |
npm run lint |
Run ESLint |
npm run lint:fix |
Run ESLint with auto-fix |
npm run format |
Format code with Prettier |
npm run format:check |
Check formatting (used in CI) |
| Setting | Value |
|---|---|
| Indentation | Tabs (width 4) |
| Semicolons | Yes |
| Quotes | Double |
| Trailing comma | All |
| Print width | 80 |
| End of line | LF |
We use eslint-plugin-obsidianmd for Obsidian-specific rules and typescript-eslint for TypeScript.
- No innerHTML/outerHTML — Use
createEl,createDiv,createSpan - Don't detach leaves in onunload — This is an anti-pattern
- Styles in CSS only — No JS style manipulation
- Use Platform API — Don't use
process.platform - Minimize
any— Use proper types
- Ports:
*.port.ts - Adapters:
*.adapter.ts - Hooks:
use*.ts - Components:
PascalCase.tsx - Utils/Models:
kebab-case.ts
{username}/{type}/{description}
Types:
feature/— New featurefix/— Bug fixrefactor/— Refactoringdocs/— Documentationhotfix/— Urgent fix
Examples:
yourname/feature/add-exportyourname/fix/message-rendering
We recommend Conventional Commits style:
<type>: <description>
<optional body>
Types:
feat:— New featurefix:— Bug fixrefactor:— Refactoringdocs:— Documentationchore:— Build/dependenciesstyle:— Formatting (no functional changes)
- Create a branch from
mastermasteris the stable branch,devis for development- Feature PRs typically target
dev, hotfixes targetmaster
- Make your changes and commit
- Create a pull request
- Ensure CI passes (lint, build)
- Wait for review
Before submitting, please verify:
-
npm run lintpasses -
npm run buildpasses - Tested in Obsidian
- Existing functionality still works
- Documentation updated if needed
Pull requests automatically run:
- ESLint (
npx eslint src/) - Build (
npm run build)
Please ensure these pass locally before submitting.
Note: "Use sentence case for UI text" lint errors are acceptable for brand names and proper nouns (e.g., "Claude Code", "Gemini CLI").
src/
├── domain/ # Pure domain models + ports (interfaces)
│ ├── models/ # agent-config, chat-message, session-update, etc.
│ └── ports/ # IAgentClient, ISettingsAccess, IVaultAccess
├── adapters/ # Interface implementations
│ ├── acp/ # ACP protocol implementation
│ └── obsidian/ # Obsidian-specific implementations
├── hooks/ # React custom hooks (state + logic)
├── components/ # UI components
└── shared/ # Utility functions
- Hooks for state and logic — No ViewModel or Use Case classes
- Pure functions in shared/ — Non-React business logic
- Ports absorb protocol changes — IAgentClient interface provides isolation
- Domain has zero dependencies — No
obsidianor@agentclientprotocol/sdkimports
For more details, see CLAUDE.md.
- Prioritize implementations that conform to the official (stable) ACP specification
- If implementing draft/experimental specs, please discuss in an issue first
- Implementations should work with official ACP-compatible agents (e.g.,
@zed-industries/claude-agent-acp)
Open an issue if you have any questions!