From 0d4d62b11ae37b5c92e1338ab189ceab954be020 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Wed, 27 May 2026 07:25:38 -0500 Subject: [PATCH 1/6] fix: pass hook event name to speckit.git.commit so AI agents read config The speckit.git.commit command template described script behavior in a 'Behavior' section that AI agents interpreted as instructions to follow without actually reading the config file. This caused agents to assume the default config (all events disabled) and fabricate 'disabled in configuration' messages even when the user had enabled auto-commit. Changes: - Rewrite speckit.git.commit.md with explicit step-by-step instructions that mandate reading .specify/extensions/git/git-config.yml before deciding whether to commit - Add 'Hook event: ' line to format_hook_message() output for both optional and mandatory hooks so agents know which event triggered the hook without guessing - Append event name to EXECUTE_COMMAND_INVOCATION so agents can pass it to the auto-commit script Fixes #2279, fixes #2702 --- extensions/git/commands/speckit.git.commit.md | 65 ++++++++++--------- src/specify_cli/extensions.py | 6 +- tests/integrations/test_integration_claude.py | 3 +- tests/test_extensions.py | 12 ++-- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index e606f911df..467920c559 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -6,43 +6,50 @@ description: "Auto-commit changes after a Spec Kit command completes" Automatically stage and commit all changes after a Spec Kit command completes. -## Behavior +## Instructions -This command is invoked as a hook after (or before) core commands. It: +Follow these steps **exactly**. Do NOT skip the config file read or assume default values. -1. Determines the event name from the hook context (e.g., if invoked as an `after_specify` hook, the event is `after_specify`; if `before_plan`, the event is `before_plan`) -2. Checks `.specify/extensions/git/git-config.yml` for the `auto_commit` section -3. Looks up the specific event key to see if auto-commit is enabled -4. Falls back to `auto_commit.default` if no event-specific key exists -5. Uses the per-command `message` if configured, otherwise a default message -6. If enabled and there are uncommitted changes, runs `git add .` + `git commit` +### Step 1 — Determine the event name -## Execution +Identify the hook event that triggered this command from the surrounding context: +- If triggered as part of an `after_tasks` hook → event is `after_tasks` +- If triggered as part of a `before_plan` hook → event is `before_plan` +- The event name matches the `hooks.` key from `.specify/extensions.yml` +- If invoked manually without hook context, ask the user which event to use -Determine the event name from the hook that triggered this command, then run the script: +### Step 2 — Read the configuration file -- **Bash**: `.specify/extensions/git/scripts/bash/auto-commit.sh ` -- **PowerShell**: `.specify/extensions/git/scripts/powershell/auto-commit.ps1 ` +**You MUST read** the file `.specify/extensions/git/git-config.yml` before deciding whether to commit. Do NOT assume its contents — the user may have changed the defaults. -Replace `` with the actual hook event (e.g., `after_specify`, `before_plan`, `after_implement`). +If the file does not exist, auto-commit is disabled. Exit silently. -## Configuration +### Step 3 — Check whether auto-commit is enabled -In `.specify/extensions/git/git-config.yml`: +Look under the `auto_commit:` section in the config file you just read: -```yaml -auto_commit: - default: false # Global toggle — set true to enable for all commands - after_specify: - enabled: true # Override per-command - message: "[Spec Kit] Add specification" - after_plan: - enabled: false - message: "[Spec Kit] Add implementation plan" -``` +1. Find the key matching the event name (e.g., `after_tasks:`). +2. If the event key exists **and** has `enabled: true` → auto-commit is **enabled**. Use the `message` value from that key. +3. If the event key exists **and** has `enabled: false` → auto-commit is **disabled**. Exit silently. +4. If the event key does **not** exist at all, check `auto_commit.default`: + - `default: true` → auto-commit is **enabled**. Use a default message `"[Spec Kit] Auto-commit "`. + - `default: false` or missing → auto-commit is **disabled**. Exit silently. -## Graceful Degradation +### Step 4 — Execute the commit (only if enabled) -- If Git is not available or the current directory is not a repository: skips with a warning -- If no config file exists: skips (disabled by default) -- If no changes to commit: skips with a message +If auto-commit is enabled: + +**Option A — Run the script** (preferred, handles edge cases): +- **Bash (macOS/Linux)**: `.specify/extensions/git/scripts/bash/auto-commit.sh ` +- **PowerShell (Windows)**: `.specify/extensions/git/scripts/powershell/auto-commit.ps1 ` + +**Option B — Run git directly** (if scripts are unavailable): +1. Check for uncommitted changes: `git status --porcelain` +2. If there are changes, run `git add .` then `git commit -m ""` +3. Report the result + +### Graceful Degradation + +- Git not available or not a repository → skip with a warning +- No config file → skip silently (disabled by default) +- No changes to commit → skip with a brief message diff --git a/src/specify_cli/extensions.py b/src/specify_cli/extensions.py index 5a595fbffa..681f25cd55 100644 --- a/src/specify_cli/extensions.py +++ b/src/specify_cli/extensions.py @@ -2833,16 +2833,18 @@ def format_hook_message( if optional: lines.append(f"\n**Optional Hook**: {extension}") + lines.append(f"Hook event: {event_name}") lines.append(f"Command: `{display_invocation}`") if description: lines.append(f"Description: {description}") lines.append(f"\nPrompt: {prompt}") - lines.append(f"To execute: `{display_invocation}`") + lines.append(f"To execute: `{display_invocation} {event_name}`") else: lines.append(f"\n**Automatic Hook**: {extension}") + lines.append(f"Hook event: {event_name}") lines.append(f"Executing: `{display_invocation}`") lines.append(f"EXECUTE_COMMAND: {command_text}") - lines.append(f"EXECUTE_COMMAND_INVOCATION: {display_invocation}") + lines.append(f"EXECUTE_COMMAND_INVOCATION: {display_invocation} {event_name}") return "\n".join(lines) diff --git a/tests/integrations/test_integration_claude.py b/tests/integrations/test_integration_claude.py index a42c395bdf..b782ba6ccb 100644 --- a/tests/integrations/test_integration_claude.py +++ b/tests/integrations/test_integration_claude.py @@ -269,9 +269,10 @@ def test_claude_hooks_render_skill_invocation(self, tmp_path): ], ) + assert "Hook event: before_plan" in message assert "Executing: `/speckit-plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message - assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan" in message + assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan before_plan" in message def test_claude_preset_creates_new_skill_without_commands_dir(self, tmp_path): from specify_cli import save_init_options diff --git a/tests/test_extensions.py b/tests/test_extensions.py index b26a4b8f2a..f4903d5964 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -4533,9 +4533,10 @@ def test_kimi_hooks_render_skill_invocation(self, project_dir): ], ) + assert "Hook event: before_plan" in message assert "Executing: `/skill:speckit-plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message - assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-plan" in message + assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-plan before_plan" in message def test_codex_hooks_render_dollar_skill_invocation(self, project_dir): """Codex projects with --ai-skills should render $speckit-* invocations.""" @@ -4573,9 +4574,10 @@ def test_non_skill_command_keeps_slash_invocation(self, project_dir): ], ) + assert "Hook event: before_tasks" in message assert "Executing: `/pre_tasks_test`" in message assert "EXECUTE_COMMAND: pre_tasks_test" in message - assert "EXECUTE_COMMAND_INVOCATION: /pre_tasks_test" in message + assert "EXECUTE_COMMAND_INVOCATION: /pre_tasks_test before_tasks" in message def test_extension_command_uses_hyphenated_skill_invocation(self, project_dir): """Multi-segment extension command ids should map to hyphenated skills.""" @@ -4595,9 +4597,10 @@ def test_extension_command_uses_hyphenated_skill_invocation(self, project_dir): ], ) + assert "Hook event: after_tasks" in message assert "Executing: `/skill:speckit-test-ext-hello`" in message assert "EXECUTE_COMMAND: speckit.test-ext.hello" in message - assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-test-ext-hello" in message + assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-test-ext-hello after_tasks" in message def test_hook_executor_caches_init_options_lookup(self, project_dir, monkeypatch): """Init options should be loaded once per executor instance.""" @@ -4632,9 +4635,10 @@ def test_hook_message_falls_back_when_invocation_is_empty(self, project_dir): ], ) + assert "Hook event: after_tasks" in message assert "Executing: `/`" in message assert "EXECUTE_COMMAND: " in message - assert "EXECUTE_COMMAND_INVOCATION: /" in message + assert "EXECUTE_COMMAND_INVOCATION: / after_tasks" in message class TestExtensionRemoveCLI: From 30df51f63a9f260f4d8dd20b63e1588337570a0d Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Wed, 27 May 2026 07:37:52 -0500 Subject: [PATCH 2/6] address PR review: prefer explicit event arg, fix default message format, add event to Executing line - Step 1: prefer explicit event name argument over context inference - Fix default commit message format to match script output: '[Spec Kit] Auto-commit ' - Include event_name in the 'Executing:' line so agents see the full invocation immediately, not just on EXECUTE_COMMAND_INVOCATION --- extensions/git/commands/speckit.git.commit.md | 11 +++++------ src/specify_cli/extensions.py | 2 +- tests/integrations/test_integration_claude.py | 2 +- tests/test_extensions.py | 8 ++++---- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index 467920c559..03aecfd456 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -12,11 +12,10 @@ Follow these steps **exactly**. Do NOT skip the config file read or assume defau ### Step 1 — Determine the event name -Identify the hook event that triggered this command from the surrounding context: -- If triggered as part of an `after_tasks` hook → event is `after_tasks` -- If triggered as part of a `before_plan` hook → event is `before_plan` -- The event name matches the `hooks.` key from `.specify/extensions.yml` -- If invoked manually without hook context, ask the user which event to use +Identify the hook event name to use: +- If the invocation includes an explicit event name argument (e.g., `/speckit.git.commit after_tasks`), use it. +- Otherwise infer it from the surrounding hook context (e.g., `after_tasks`, `before_plan`), matching `hooks.` in `.specify/extensions.yml`. +- If invoked manually with no hook context and no event argument, ask the user which event to use. ### Step 2 — Read the configuration file @@ -32,7 +31,7 @@ Look under the `auto_commit:` section in the config file you just read: 2. If the event key exists **and** has `enabled: true` → auto-commit is **enabled**. Use the `message` value from that key. 3. If the event key exists **and** has `enabled: false` → auto-commit is **disabled**. Exit silently. 4. If the event key does **not** exist at all, check `auto_commit.default`: - - `default: true` → auto-commit is **enabled**. Use a default message `"[Spec Kit] Auto-commit "`. + - `default: true` → auto-commit is **enabled**. Use a default message `"[Spec Kit] Auto-commit "` (e.g., `after_tasks` → `"[Spec Kit] Auto-commit after tasks"`). - `default: false` or missing → auto-commit is **disabled**. Exit silently. ### Step 4 — Execute the commit (only if enabled) diff --git a/src/specify_cli/extensions.py b/src/specify_cli/extensions.py index 681f25cd55..085f62df93 100644 --- a/src/specify_cli/extensions.py +++ b/src/specify_cli/extensions.py @@ -2842,7 +2842,7 @@ def format_hook_message( else: lines.append(f"\n**Automatic Hook**: {extension}") lines.append(f"Hook event: {event_name}") - lines.append(f"Executing: `{display_invocation}`") + lines.append(f"Executing: `{display_invocation} {event_name}`") lines.append(f"EXECUTE_COMMAND: {command_text}") lines.append(f"EXECUTE_COMMAND_INVOCATION: {display_invocation} {event_name}") diff --git a/tests/integrations/test_integration_claude.py b/tests/integrations/test_integration_claude.py index b782ba6ccb..761882276b 100644 --- a/tests/integrations/test_integration_claude.py +++ b/tests/integrations/test_integration_claude.py @@ -270,7 +270,7 @@ def test_claude_hooks_render_skill_invocation(self, tmp_path): ) assert "Hook event: before_plan" in message - assert "Executing: `/speckit-plan`" in message + assert "Executing: `/speckit-plan before_plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan before_plan" in message diff --git a/tests/test_extensions.py b/tests/test_extensions.py index f4903d5964..b29068f232 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -4534,7 +4534,7 @@ def test_kimi_hooks_render_skill_invocation(self, project_dir): ) assert "Hook event: before_plan" in message - assert "Executing: `/skill:speckit-plan`" in message + assert "Executing: `/skill:speckit-plan before_plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-plan before_plan" in message @@ -4575,7 +4575,7 @@ def test_non_skill_command_keeps_slash_invocation(self, project_dir): ) assert "Hook event: before_tasks" in message - assert "Executing: `/pre_tasks_test`" in message + assert "Executing: `/pre_tasks_test before_tasks`" in message assert "EXECUTE_COMMAND: pre_tasks_test" in message assert "EXECUTE_COMMAND_INVOCATION: /pre_tasks_test before_tasks" in message @@ -4598,7 +4598,7 @@ def test_extension_command_uses_hyphenated_skill_invocation(self, project_dir): ) assert "Hook event: after_tasks" in message - assert "Executing: `/skill:speckit-test-ext-hello`" in message + assert "Executing: `/skill:speckit-test-ext-hello after_tasks`" in message assert "EXECUTE_COMMAND: speckit.test-ext.hello" in message assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-test-ext-hello after_tasks" in message @@ -4636,7 +4636,7 @@ def test_hook_message_falls_back_when_invocation_is_empty(self, project_dir): ) assert "Hook event: after_tasks" in message - assert "Executing: `/`" in message + assert "Executing: `/ after_tasks`" in message assert "EXECUTE_COMMAND: " in message assert "EXECUTE_COMMAND_INVOCATION: / after_tasks" in message From df3bb96bc6a8bb183eb430c818c52fde78fd1c3a Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Wed, 27 May 2026 17:23:25 -0500 Subject: [PATCH 3/6] revert extensions.py and test changes, keep commit.md template fix only Address PR review: remove hook message changes from extensions.py (avoids changing $ARGUMENTS semantics for all hooks). The fix is now entirely in the speckit.git.commit.md command template which instructs agents to read the config file and documents the message fallback. --- extensions/git/commands/speckit.git.commit.md | 2 +- src/specify_cli/extensions.py | 8 +++----- tests/integrations/test_integration_claude.py | 5 ++--- tests/test_extensions.py | 20 ++++++++----------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index 03aecfd456..aa1dc94352 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -28,7 +28,7 @@ If the file does not exist, auto-commit is disabled. Exit silently. Look under the `auto_commit:` section in the config file you just read: 1. Find the key matching the event name (e.g., `after_tasks:`). -2. If the event key exists **and** has `enabled: true` → auto-commit is **enabled**. Use the `message` value from that key. +2. If the event key exists **and** has `enabled: true` → auto-commit is **enabled**. Use the `message` value from that key if present; if `message` is missing or empty, fall back to the default format `"[Spec Kit] Auto-commit "`. 3. If the event key exists **and** has `enabled: false` → auto-commit is **disabled**. Exit silently. 4. If the event key does **not** exist at all, check `auto_commit.default`: - `default: true` → auto-commit is **enabled**. Use a default message `"[Spec Kit] Auto-commit "` (e.g., `after_tasks` → `"[Spec Kit] Auto-commit after tasks"`). diff --git a/src/specify_cli/extensions.py b/src/specify_cli/extensions.py index 085f62df93..5a595fbffa 100644 --- a/src/specify_cli/extensions.py +++ b/src/specify_cli/extensions.py @@ -2833,18 +2833,16 @@ def format_hook_message( if optional: lines.append(f"\n**Optional Hook**: {extension}") - lines.append(f"Hook event: {event_name}") lines.append(f"Command: `{display_invocation}`") if description: lines.append(f"Description: {description}") lines.append(f"\nPrompt: {prompt}") - lines.append(f"To execute: `{display_invocation} {event_name}`") + lines.append(f"To execute: `{display_invocation}`") else: lines.append(f"\n**Automatic Hook**: {extension}") - lines.append(f"Hook event: {event_name}") - lines.append(f"Executing: `{display_invocation} {event_name}`") + lines.append(f"Executing: `{display_invocation}`") lines.append(f"EXECUTE_COMMAND: {command_text}") - lines.append(f"EXECUTE_COMMAND_INVOCATION: {display_invocation} {event_name}") + lines.append(f"EXECUTE_COMMAND_INVOCATION: {display_invocation}") return "\n".join(lines) diff --git a/tests/integrations/test_integration_claude.py b/tests/integrations/test_integration_claude.py index 761882276b..a42c395bdf 100644 --- a/tests/integrations/test_integration_claude.py +++ b/tests/integrations/test_integration_claude.py @@ -269,10 +269,9 @@ def test_claude_hooks_render_skill_invocation(self, tmp_path): ], ) - assert "Hook event: before_plan" in message - assert "Executing: `/speckit-plan before_plan`" in message + assert "Executing: `/speckit-plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message - assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan before_plan" in message + assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan" in message def test_claude_preset_creates_new_skill_without_commands_dir(self, tmp_path): from specify_cli import save_init_options diff --git a/tests/test_extensions.py b/tests/test_extensions.py index b29068f232..b26a4b8f2a 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -4533,10 +4533,9 @@ def test_kimi_hooks_render_skill_invocation(self, project_dir): ], ) - assert "Hook event: before_plan" in message - assert "Executing: `/skill:speckit-plan before_plan`" in message + assert "Executing: `/skill:speckit-plan`" in message assert "EXECUTE_COMMAND: speckit.plan" in message - assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-plan before_plan" in message + assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-plan" in message def test_codex_hooks_render_dollar_skill_invocation(self, project_dir): """Codex projects with --ai-skills should render $speckit-* invocations.""" @@ -4574,10 +4573,9 @@ def test_non_skill_command_keeps_slash_invocation(self, project_dir): ], ) - assert "Hook event: before_tasks" in message - assert "Executing: `/pre_tasks_test before_tasks`" in message + assert "Executing: `/pre_tasks_test`" in message assert "EXECUTE_COMMAND: pre_tasks_test" in message - assert "EXECUTE_COMMAND_INVOCATION: /pre_tasks_test before_tasks" in message + assert "EXECUTE_COMMAND_INVOCATION: /pre_tasks_test" in message def test_extension_command_uses_hyphenated_skill_invocation(self, project_dir): """Multi-segment extension command ids should map to hyphenated skills.""" @@ -4597,10 +4595,9 @@ def test_extension_command_uses_hyphenated_skill_invocation(self, project_dir): ], ) - assert "Hook event: after_tasks" in message - assert "Executing: `/skill:speckit-test-ext-hello after_tasks`" in message + assert "Executing: `/skill:speckit-test-ext-hello`" in message assert "EXECUTE_COMMAND: speckit.test-ext.hello" in message - assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-test-ext-hello after_tasks" in message + assert "EXECUTE_COMMAND_INVOCATION: /skill:speckit-test-ext-hello" in message def test_hook_executor_caches_init_options_lookup(self, project_dir, monkeypatch): """Init options should be loaded once per executor instance.""" @@ -4635,10 +4632,9 @@ def test_hook_message_falls_back_when_invocation_is_empty(self, project_dir): ], ) - assert "Hook event: after_tasks" in message - assert "Executing: `/ after_tasks`" in message + assert "Executing: `/`" in message assert "EXECUTE_COMMAND: " in message - assert "EXECUTE_COMMAND_INVOCATION: / after_tasks" in message + assert "EXECUTE_COMMAND_INVOCATION: /" in message class TestExtensionRemoveCLI: From 5bf1675acdd989ba2309e9dd38f75aed208d3604 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Thu, 28 May 2026 07:31:50 -0500 Subject: [PATCH 4/6] address review: clarify event source and file-access fallback in commit template - Step 1: reference 'Hooks available for event' line as primary event source - Step 2: instruct agent to ask user for file contents if it cannot access files --- extensions/git/commands/speckit.git.commit.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index aa1dc94352..9648794eb0 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -13,14 +13,16 @@ Follow these steps **exactly**. Do NOT skip the config file read or assume defau ### Step 1 — Determine the event name Identify the hook event name to use: +- If hook output is present, read it from the `"Hooks available for event ''"` line emitted by Spec Kit — this is the most reliable source. - If the invocation includes an explicit event name argument (e.g., `/speckit.git.commit after_tasks`), use it. -- Otherwise infer it from the surrounding hook context (e.g., `after_tasks`, `before_plan`), matching `hooks.` in `.specify/extensions.yml`. - If invoked manually with no hook context and no event argument, ask the user which event to use. ### Step 2 — Read the configuration file **You MUST read** the file `.specify/extensions/git/git-config.yml` before deciding whether to commit. Do NOT assume its contents — the user may have changed the defaults. +If you cannot access local files directly, ask the user to provide the contents of this file. Do NOT guess or fabricate config values. + If the file does not exist, auto-commit is disabled. Exit silently. ### Step 3 — Check whether auto-commit is enabled From 0608a14f421c06fd2ce6d5a61a499e6b0e34cd75 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Thu, 28 May 2026 08:53:01 -0500 Subject: [PATCH 5/6] clarify hook event source precedence in git commit template --- extensions/git/commands/speckit.git.commit.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index 9648794eb0..c22901b434 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -13,8 +13,8 @@ Follow these steps **exactly**. Do NOT skip the config file read or assume defau ### Step 1 — Determine the event name Identify the hook event name to use: -- If hook output is present, read it from the `"Hooks available for event ''"` line emitted by Spec Kit — this is the most reliable source. -- If the invocation includes an explicit event name argument (e.g., `/speckit.git.commit after_tasks`), use it. +- If hook output is present, read it from the `"Hooks available for event ''"` line emitted by Spec Kit. When executing from an Extension Hooks prompt, treat this line as the source of truth. +- If the invocation includes an explicit event name argument (e.g., `/speckit.git.commit after_tasks`), use it as an override. This is optional/rare in current hook prompts. - If invoked manually with no hook context and no event argument, ask the user which event to use. ### Step 2 — Read the configuration file From 6db18fe0360b05f2b2b03d2e9eb6f485798e7890 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Thu, 28 May 2026 10:17:52 -0500 Subject: [PATCH 6/6] clarify project-root requirement for auto-commit script paths --- extensions/git/commands/speckit.git.commit.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/git/commands/speckit.git.commit.md b/extensions/git/commands/speckit.git.commit.md index c22901b434..1134afe64c 100644 --- a/extensions/git/commands/speckit.git.commit.md +++ b/extensions/git/commands/speckit.git.commit.md @@ -40,6 +40,8 @@ Look under the `auto_commit:` section in the config file you just read: If auto-commit is enabled: +Before running either option, ensure your working directory is the project root (the directory that contains `.specify/`) so relative `.specify/extensions/...` script paths resolve correctly. + **Option A — Run the script** (preferred, handles edge cases): - **Bash (macOS/Linux)**: `.specify/extensions/git/scripts/bash/auto-commit.sh ` - **PowerShell (Windows)**: `.specify/extensions/git/scripts/powershell/auto-commit.ps1 `