fix: honor CLAUDE_CONFIG_DIR in hooks (#37)
ponytail-activate.js and ponytail-runtime.js hardcoded ~/.claude for the flag file and settings lookup, ignoring CLAUDE_CONFIG_DIR. Add a shared getClaudeDir() to ponytail-config.js and use it in both. Regression test added to hooks.test.js. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6d990f8c54
commit
01578c0cd4
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const os = require('os');
|
const { getDefaultMode, getClaudeDir } = require('./ponytail-config');
|
||||||
const { getDefaultMode } = require('./ponytail-config');
|
|
||||||
const { getPonytailInstructions } = require('./ponytail-instructions');
|
const { getPonytailInstructions } = require('./ponytail-instructions');
|
||||||
const {
|
const {
|
||||||
clearMode,
|
clearMode,
|
||||||
@@ -18,7 +17,7 @@ const {
|
|||||||
writeHookOutput,
|
writeHookOutput,
|
||||||
} = require('./ponytail-runtime');
|
} = require('./ponytail-runtime');
|
||||||
|
|
||||||
const claudeDir = path.join(os.homedir(), '.claude');
|
const claudeDir = getClaudeDir();
|
||||||
const settingsPath = path.join(claudeDir, 'settings.json');
|
const settingsPath = path.join(claudeDir, 'settings.json');
|
||||||
|
|
||||||
const mode = getDefaultMode();
|
const mode = getDefaultMode();
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ function getConfigPath() {
|
|||||||
return path.join(getConfigDir(), 'config.json');
|
return path.join(getConfigDir(), 'config.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getClaudeDir() {
|
||||||
|
// ponytail: CLAUDE_CONFIG_DIR overrides ~/.claude, matching Claude Code.
|
||||||
|
return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
|
||||||
|
}
|
||||||
|
|
||||||
function getDefaultMode() {
|
function getDefaultMode() {
|
||||||
// 1. Environment variable (highest priority)
|
// 1. Environment variable (highest priority)
|
||||||
const envMode = process.env.PONYTAIL_DEFAULT_MODE;
|
const envMode = process.env.PONYTAIL_DEFAULT_MODE;
|
||||||
@@ -89,6 +94,7 @@ module.exports = {
|
|||||||
getDefaultMode,
|
getDefaultMode,
|
||||||
getConfigDir,
|
getConfigDir,
|
||||||
getConfigPath,
|
getConfigPath,
|
||||||
|
getClaudeDir,
|
||||||
normalizeMode,
|
normalizeMode,
|
||||||
normalizeConfigMode,
|
normalizeConfigMode,
|
||||||
normalizePersistedMode,
|
normalizePersistedMode,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const os = require('os');
|
const { getClaudeDir } = require('./ponytail-config');
|
||||||
|
|
||||||
const isCodex = Boolean(process.env.PLUGIN_DATA);
|
const isCodex = Boolean(process.env.PLUGIN_DATA);
|
||||||
const statePath = isCodex
|
const statePath = isCodex
|
||||||
? path.join(process.env.PLUGIN_DATA, '.ponytail-active')
|
? path.join(process.env.PLUGIN_DATA, '.ponytail-active')
|
||||||
: path.join(os.homedir(), '.claude', '.ponytail-active');
|
: path.join(getClaudeDir(), '.ponytail-active');
|
||||||
|
|
||||||
function setMode(mode) {
|
function setMode(mode) {
|
||||||
fs.mkdirSync(path.dirname(statePath), { recursive: true });
|
fs.mkdirSync(path.dirname(statePath), { recursive: true });
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ function run(script, env, input = '') {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep the base env clean so the default-dir checks are deterministic; the
|
||||||
|
// CLAUDE_CONFIG_DIR case sets it explicitly.
|
||||||
|
delete process.env.CLAUDE_CONFIG_DIR;
|
||||||
|
|
||||||
const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'ponytail-hooks-'));
|
const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'ponytail-hooks-'));
|
||||||
const home = path.join(temp, 'home');
|
const home = path.join(temp, 'home');
|
||||||
const pluginData = path.join(temp, 'plugin-data');
|
const pluginData = path.join(temp, 'plugin-data');
|
||||||
@@ -74,5 +78,26 @@ assert.equal(
|
|||||||
'full',
|
'full',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// CLAUDE_CONFIG_DIR overrides ~/.claude for the flag file (issue #34).
|
||||||
|
const home2 = path.join(temp, 'home2');
|
||||||
|
fs.mkdirSync(home2, { recursive: true });
|
||||||
|
const customConfigDir = path.join(temp, 'custom-claude');
|
||||||
|
result = run('ponytail-activate.js', {
|
||||||
|
HOME: home2,
|
||||||
|
USERPROFILE: home2,
|
||||||
|
CLAUDE_CONFIG_DIR: customConfigDir,
|
||||||
|
PONYTAIL_DEFAULT_MODE: 'lite',
|
||||||
|
});
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
assert.equal(
|
||||||
|
fs.readFileSync(path.join(customConfigDir, '.ponytail-active'), 'utf8'),
|
||||||
|
'lite',
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
fs.existsSync(path.join(home2, '.claude', '.ponytail-active')),
|
||||||
|
false,
|
||||||
|
'flag must not land in ~/.claude when CLAUDE_CONFIG_DIR is set',
|
||||||
|
);
|
||||||
|
|
||||||
fs.rmSync(temp, { recursive: true, force: true });
|
fs.rmSync(temp, { recursive: true, force: true });
|
||||||
console.log('hook compatibility checks passed');
|
console.log('hook compatibility checks passed');
|
||||||
|
|||||||
Reference in New Issue
Block a user