opencode-janus
v1.4.0
Published
Directory-based OpenCode configuration switching tool. Automatically switch between different OpenCode configurations based on your current working directory.
Downloads
73
Maintainers
Readme
🔀 Janus
Directory-aware configuration switcher for OpenCode & Claude Code
Named after the Roman god of transitions—seamlessly transform your configuration as you navigate between projects
Features • Quick Start • Configuration • How It Works
✨ Features
🎯 Smart Path Matching
Automatically detects your working directory and applies the right configuration
⚡ Zero Overhead
Lightweight shell integration with instant switching
🔒 Process Isolation
Each tool instance runs with its own isolated configuration
🎨 Flexible Patterns
Full glob pattern support with longest-prefix priority
🧩 Multi-Tool Support
Shared mapping rules for OpenCode, Claude Code, and more
🔄 Backward Compatible
Existing single-tool configs continue to work without changes
🚀 Quick Start
Installation
npm install -g opencode-janusgit clone https://github.com/kuitos/janus.git
cd janus
bun install && bun run build
npm install -g .Setup in 3 steps
# 1. Create your configuration file
mkdir -p ~/.config/janus
nano ~/.config/janus/config.json
# 2. Install shell hook (auto-detects zsh/bash)
janus install
# 3. Reload your shell
source ~/.zshrc # or ~/.bashrcThat's it! 🎉 Your opencode and claude commands now adapt to each directory.
⚙️ Configuration
Create ~/.config/janus/config.json with your mapping rules:
Multi-Tool Configuration (Recommended)
{
"defaultConfigDir": [
{ "tool": "opencode", "dir": "~/.config/opencode-default" },
{ "tool": "claude", "dir": "~/.config/claude-default" }
],
"mappings": [
{
"match": ["~/work/**"],
"configDir": [
{ "tool": "opencode", "dir": "~/.config/opencode-work" },
{ "tool": "claude", "dir": "~/.config/claude-work" }
]
},
{
"match": ["~/projects/oss/**"],
"configDir": [
{ "tool": "opencode", "dir": "~/.config/opencode-oss" },
{ "tool": "claude", "dir": "~/.config/claude-oss" }
]
}
]
}Single-Tool Configuration (Backward Compatible)
{
"defaultConfigDir": "~/.config/opencode-default",
"mappings": [
{
"match": ["~/work/**"],
"configDir": "~/.config/opencode-work"
},
{
"match": ["~/projects/oss/**"],
"configDir": "~/.config/opencode-oss"
}
]
}String format
configDiris treated as OpenCode shorthand — no migration needed.
Supported Tools
| Tool | Command | Environment Variable |
|------|---------|---------------------|
| OpenCode | opencode | OPENCODE_CONFIG_DIR |
| Claude Code | claude | CLAUDE_CONFIG_DIR |
These are built-in — you only need to specify tool and dir in your config.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| defaultConfigDir | string \| [{tool, dir}] | No | Fallback configuration when no mappings match |
| mappings | Array | Yes | List of directory-to-config mapping rules |
| match | string[] | Yes | Path patterns to match (supports ** glob) |
| configDir | string \| [{tool, dir}] | Yes | Configuration directory per tool |
Pattern Matching:
- Supports glob patterns:
**,*,? - Supports tilde (
~) expansion for home directory - Multiple patterns per mapping
- Longest (most specific) match wins
- Falls back to
defaultConfigDirif configured and no match found
Path Examples:
{
"defaultConfigDir": [
{ "tool": "opencode", "dir": "~/.config/opencode-default" }
],
"mappings": [
{
"match": ["~/work/**"],
"configDir": [
{ "tool": "opencode", "dir": "~/.config/work" },
{ "tool": "claude", "dir": "~/.config/claude-work" }
]
},
{
"match": ["/absolute/path/**"],
"configDir": "~/.config/opencode-absolute"
}
]
}Default Configuration Behavior:
- When a directory doesn't match any pattern in
mappings,defaultConfigDiris used (if configured) - If
defaultConfigDiris not set, unmatched directories will not use any configuration (backward compatible) - Useful for providing a general-purpose configuration for casual projects
💡 How It Works
graph LR
A[cd ~/work/project] --> B{janus hook}
B --> C[Match path patterns]
C --> D[Find longest match]
D --> E[Set tool-specific env var]
E --> F[Tool uses custom config]- Shell Integration –
janus installadds wrapper functions for each tool - Path Resolution – Matches current path against patterns
- Priority Selection – Longest (most specific) pattern wins
- Environment Setup – Sets the correct env var per tool (
OPENCODE_CONFIG_DIR,CLAUDE_CONFIG_DIR) - Isolated Execution – Each process gets the right configuration
Shell Hook Example
After janus install, your shell RC file contains:
# >>> janus auto-initialization >>>
opencode() {
janus exec --tool opencode -- "$@"
}
claude() {
janus exec --tool claude -- "$@"
}
# <<< janus auto-initialization <<<🛠️ Commands
janus install # Install shell hook (auto-detects shell & tools from config)
janus uninstall # Remove shell hook
janus --version # Show version
janus --help # Show help🧪 Development
# Run tests
bun test
# Coverage report
bun test --coverage
# Type checking
bun run typecheck
# Build for production
bun run build🤝 Contributing
Contributions are welcome! Feel free to:
📄 License
🙏 Acknowledgments
Built with ❤️ using:
Inspired by:
