fix: make shared hooks parse in PowerShell (#265)
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "command -v node >/dev/null 2>&1 && node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\" || exit 0",
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\"; exit 0",
|
||||||
"commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-activate.js\" }",
|
"commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-activate.js\" }",
|
||||||
"timeout": 5,
|
"timeout": 5,
|
||||||
"statusMessage": "Loading ponytail mode..."
|
"statusMessage": "Loading ponytail mode..."
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "command -v node >/dev/null 2>&1 && node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-mode-tracker.js\" || exit 0",
|
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-mode-tracker.js\"; exit 0",
|
||||||
"commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-mode-tracker.js\" }",
|
"commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-mode-tracker.js\" }",
|
||||||
"timeout": 5,
|
"timeout": 5,
|
||||||
"statusMessage": "Tracking ponytail mode..."
|
"statusMessage": "Tracking ponytail mode..."
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ const HOST_PLUGIN_MANIFESTS = [
|
|||||||
];
|
];
|
||||||
// cmd.exe variable syntax (%FOO%); PowerShell leaves it literal, breaking the path.
|
// cmd.exe variable syntax (%FOO%); PowerShell leaves it literal, breaking the path.
|
||||||
const CMD_VAR_SYNTAX = /%[A-Za-z_][A-Za-z0-9_]*%/;
|
const CMD_VAR_SYNTAX = /%[A-Za-z_][A-Za-z0-9_]*%/;
|
||||||
|
// PowerShell 5.1 rejects these POSIX shell guards when a host runs `command`.
|
||||||
|
const POSIX_GUARD_SYNTAX = /\bcommand\s+-v\b|&&|\|\||>\/dev\/null|2>&1/;
|
||||||
// Pull the hooks/<script> a command launches, so we can check it exists.
|
// Pull the hooks/<script> a command launches, so we can check it exists.
|
||||||
const HOOK_SCRIPT = /hooks[\\/]([\w.-]+\.(?:js|mjs|cjs|ps1|sh))/;
|
const HOOK_SCRIPT = /hooks[\\/]([\w.-]+\.(?:js|mjs|cjs|ps1|sh))/;
|
||||||
|
|
||||||
@@ -40,6 +42,26 @@ test('every commandWindows uses PowerShell $env: syntax, not cmd.exe %VAR%', ()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('shared hook commands avoid POSIX-only guard syntax', () => {
|
||||||
|
const commands = commandHooks()
|
||||||
|
.map((h) => h.command)
|
||||||
|
.filter(Boolean);
|
||||||
|
assert.ok(commands.length > 0, 'expected at least one shared command entry');
|
||||||
|
for (const cmd of commands) {
|
||||||
|
assert.doesNotMatch(cmd, POSIX_GUARD_SYNTAX, `command uses POSIX-only guard syntax: ${cmd}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('shared hook commands keep lifecycle hooks non-blocking', () => {
|
||||||
|
const commands = commandHooks()
|
||||||
|
.map((h) => h.command)
|
||||||
|
.filter(Boolean);
|
||||||
|
assert.ok(commands.length > 0, 'expected at least one shared command entry');
|
||||||
|
for (const cmd of commands) {
|
||||||
|
assert.match(cmd, /;\s*exit 0$/, `command must exit successfully if node or the hook script fails: ${cmd}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('every hook command points at a script that ships in hooks/', () => {
|
test('every hook command points at a script that ships in hooks/', () => {
|
||||||
for (const hook of commandHooks()) {
|
for (const hook of commandHooks()) {
|
||||||
for (const cmd of [hook.command, hook.commandWindows].filter(Boolean)) {
|
for (const cmd of [hook.command, hook.commandWindows].filter(Boolean)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user