Loading...
Loading...
Configure multiple Obsidian environments for development, testing, and production. Use when managing separate vaults, testing plugin versions, or establishing a proper development workflow with isolated environments. Trigger with phrases like "obsidian environments", "obsidian dev vault", "obsidian testing setup", "multiple obsidian vaults".
npx skill4agent add jeremylongshore/claude-code-plugins-plus obsidian-multi-env-setup.obsidian/# Base directory for all environments
mkdir -p ~/obsidian-envs/{dev,test,prod}
# Dev vault: your working vault with symlinked plugin source
mkdir -p ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/dev/sandbox # scratch notes for testing
# Test vault: clean environment for QA
mkdir -p ~/obsidian-envs/test/.obsidian/plugins/your-plugin
mkdir -p ~/obsidian-envs/test/test-data
# Prod vault: mirrors real user setup
mkdir -p ~/obsidian-envs/prod/.obsidian/plugins/your-plugin# Remove the empty plugin directory in dev
rm -rf ~/obsidian-envs/dev/.obsidian/plugins/your-plugin
# Symlink to your plugin's repo (contains manifest.json, main.js, styles.css)
ln -s /path/to/your-plugin ~/obsidian-envs/dev/.obsidian/plugins/your-plugin# Clone hot-reload into dev vault's plugins
git clone https://github.com/pjeby/hot-reload.git \
~/obsidian-envs/dev/.obsidian/plugins/hot-reload.obsidian/community-plugins.json["your-plugin", "hot-reload"]data.json// config/environments.ts
interface PluginConfig {
debugMode: boolean;
logLevel: 'debug' | 'info' | 'warn' | 'error';
apiEndpoint: string;
featureFlags: Record<string, boolean>;
}
const ENV_CONFIGS: Record<string, Partial<PluginConfig>> = {
dev: {
debugMode: true,
logLevel: 'debug',
apiEndpoint: 'http://localhost:3000',
featureFlags: { experimentalEditor: true, betaSync: true },
},
test: {
debugMode: true,
logLevel: 'info',
apiEndpoint: 'https://staging.api.example.com',
featureFlags: { experimentalEditor: true, betaSync: false },
},
prod: {
debugMode: false,
logLevel: 'error',
apiEndpoint: 'https://api.example.com',
featureFlags: {},
},
};
export function detectEnvironment(vaultPath: string): string {
if (vaultPath.includes('obsidian-envs/dev')) return 'dev';
if (vaultPath.includes('obsidian-envs/test')) return 'test';
return 'prod';
}
export function getConfig(env: string): PluginConfig {
const defaults: PluginConfig = {
debugMode: false,
logLevel: 'error',
apiEndpoint: '',
featureFlags: {},
};
return { ...defaults, ...ENV_CONFIGS[env] };
}onload()async onload() {
const vaultPath = (this.app.vault.adapter as any).basePath;
const env = detectEnvironment(vaultPath);
const config = getConfig(env);
console.log(`[your-plugin] Running in ${env} mode`);
if (config.debugMode) {
// Register debug commands only in dev/test
this.addCommand({
id: 'dump-state',
name: 'Dump Plugin State (debug)',
callback: () => console.log(JSON.stringify(this.settings, null, 2)),
});
}
}vault-template/
.obsidian/
app.json # Standard app settings
appearance.json # Theme and font settings
hotkeys.json # Team-standard keybindings
community-plugins.json # Approved plugin list
plugins/ # Pre-configured plugin data.json files
dataview/data.json
templater-obsidian/data.json
templates/ # Note templates (daily, meeting, project)
daily.md
meeting.md
project-kickoff.md
README.md # Vault orientation guide#!/bin/bash
# provision-vault.sh <username> <role>
USERNAME=$1
ROLE=${2:-editor}
VAULT_DIR=~/obsidian-team-vaults/$USERNAME
cp -r vault-template "$VAULT_DIR"
# Inject user-specific settings
cat > "$VAULT_DIR/.obsidian/plugins/rbac-plugin/data.json" <<EOF
{
"userEmail": "${USERNAME}@company.com",
"role": "${ROLE}"
}
EOF
echo "Vault provisioned at $VAULT_DIR for $USERNAME ($ROLE)"cd ~/obsidian-envs/prod
git init
cat > .gitignore <<'EOF'
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.obsidian/cache
.trash/
EOF
git add -A && git commit -m "Initial vault state".obsidian/plugins/.obsidian/.obsidian/| File | Sync across envs? | Why |
|---|---|---|
| Yes | Core settings should be consistent |
| Yes | Theme consistency |
| Per-env | Dev may have debug plugins |
| Yes | Muscle memory matters |
| Never | Layout is per-device |
| Per-env | Settings differ by environment |
#!/bin/bash
# sync-config.sh -- copy safe configs from prod to dev/test
SAFE_FILES="app.json appearance.json hotkeys.json"
SRC=~/obsidian-envs/prod/.obsidian
for env in dev test; do
DST=~/obsidian-envs/$env/.obsidian
for f in $SAFE_FILES; do
cp "$SRC/$f" "$DST/$f" 2>/dev/null && echo "Synced $f to $env"
done
done.obsidian/| Issue | Cause | Solution |
|---|---|---|
| Symlink not working | Permission denied on Windows | Run terminal as Administrator, or use |
| Plugin not appearing in dev vault | Symlink target missing | Run |
| Wrong config loaded | Vault path detection failed | Check |
| Hot reload not triggering | | Create empty |
Sync conflict on | Multiple devices open same vault | Add |
| Test vault has stale data | Forgot to refresh after plugin update | Copy latest build artifacts: |
npm run buildprovision-vault.sh alice editorobsidian-cliobsidian-observabilityobsidian-enterprise-rbac