From be32fec23d63785884fcd502c670834e126d015f Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 2 Feb 2026 07:17:36 +0000 Subject: [PATCH] feat(plugin): Implement workspace awareness to detect the current module (#75) Introduces a new script to detect the current module (PHP or Go) based on the presence of composer.json or go.mod files, git remote URL, or the current directory name. This context is loaded once per session and used to dynamically adjust commands, starting with the QA command. Refactors the QA command and verification scripts to use the new module context, removing redundant project-type detection. --- claude/code/commands/qa.md | 9 ++--- claude/code/hooks.json | 11 ++++++ claude/code/scripts/detect-module.sh | 51 ++++++++++++++++++++++++++++ claude/code/scripts/qa-verify.sh | 28 +++++++++------ 4 files changed, 82 insertions(+), 17 deletions(-) create mode 100755 claude/code/scripts/detect-module.sh diff --git a/claude/code/commands/qa.md b/claude/code/commands/qa.md index 8137441..6362c25 100644 --- a/claude/code/commands/qa.md +++ b/claude/code/commands/qa.md @@ -18,16 +18,11 @@ hooks: Run the full QA pipeline and fix all issues. -## Detection - -First, detect the project type: -- If `go.mod` exists → Go project → `core go qa` -- If `composer.json` exists → PHP project → `core php qa` -- If both exist → ask user or check current directory +**Workspace:** `{{env.CLAUDE_CURRENT_MODULE}}` ({{env.CLAUDE_MODULE_TYPE}}) ## Process -1. **Run QA**: Execute `core go qa` or `core php qa` +1. **Run QA**: Execute `core {{env.CLAUDE_MODULE_TYPE}} qa` 2. **Parse issues**: Extract failures from output (see format below) 3. **Fix each issue**: Address one at a time, simplest first 4. **Re-verify**: After fixes, re-run QA diff --git a/claude/code/hooks.json b/claude/code/hooks.json index 57a4dff..b6a364a 100644 --- a/claude/code/hooks.json +++ b/claude/code/hooks.json @@ -2,6 +2,17 @@ "$schema": "https://claude.ai/schemas/hooks.json", "hooks": { "PreToolUse": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/detect-module.sh" + } + ], + "description": "Detect current module and export context variables", + "once": true + }, { "matcher": "Bash", "hooks": [ diff --git a/claude/code/scripts/detect-module.sh b/claude/code/scripts/detect-module.sh new file mode 100755 index 0000000..dbd552a --- /dev/null +++ b/claude/code/scripts/detect-module.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Detects the current module and sets environment variables for other tools. +# Intended to be run once per session via a hook. + +# --- Detection Logic --- +MODULE_NAME="" +MODULE_TYPE="unknown" + +# 1. Check for composer.json (PHP) +if [ -f "composer.json" ]; then + MODULE_TYPE="php" + # Use jq, but check if it is installed first + if command -v jq >/dev/null 2>&1; then + MODULE_NAME=$(jq -r ".name // empty" composer.json) + fi +fi + +# 2. Check for go.mod (Go) +if [ -f "go.mod" ]; then + MODULE_TYPE="go" + MODULE_NAME=$(grep "^module" go.mod | awk '{print $2}') +fi + +# 3. If name is still empty, try git remote +if [ -z "$MODULE_NAME" ] || [ "$MODULE_NAME" = "unknown" ]; then + if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then + GIT_REMOTE=$(git remote get-url origin 2>/dev/null) + if [ -n "$GIT_REMOTE" ]; then + MODULE_NAME=$(basename "$GIT_REMOTE" .git) + fi + fi +fi + +# 4. As a last resort, use the current directory name +if [ -z "$MODULE_NAME" ] || [ "$MODULE_NAME" = "unknown" ]; then + MODULE_NAME=$(basename "$PWD") +fi + + +# --- Store Context --- +# Create a file with the context variables to be sourced by other scripts. +mkdir -p .claude-plugin/.tmp +CONTEXT_FILE=".claude-plugin/.tmp/module_context.sh" + +echo "export CLAUDE_CURRENT_MODULE=\"$MODULE_NAME\"" > "$CONTEXT_FILE" +echo "export CLAUDE_MODULE_TYPE=\"$MODULE_TYPE\"" >> "$CONTEXT_FILE" + +# --- User-facing Message --- +# Print a confirmation message to stderr. +echo "Workspace context loaded: Module='$MODULE_NAME', Type='$MODULE_TYPE'" >&2 diff --git a/claude/code/scripts/qa-verify.sh b/claude/code/scripts/qa-verify.sh index c9257a2..22e3780 100755 --- a/claude/code/scripts/qa-verify.sh +++ b/claude/code/scripts/qa-verify.sh @@ -12,18 +12,26 @@ if [ "$STOP_ACTIVE" = "true" ]; then exit 0 fi -# Detect project type and run QA -if [ -f "go.mod" ]; then - PROJECT="go" - RESULT=$(core go qa 2>&1) || true -elif [ -f "composer.json" ]; then - PROJECT="php" - RESULT=$(core php qa 2>&1) || true -else - # Not a Go or PHP project, allow stop - exit 0 +# Source module context to get CLAUDE_MODULE_TYPE +CONTEXT_FILE=".claude-plugin/.tmp/module_context.sh" +if [ -f "$CONTEXT_FILE" ]; then + source "$CONTEXT_FILE" fi +# Run QA based on module type +case "$CLAUDE_MODULE_TYPE" in + "go") + RESULT=$(core go qa 2>&1) || true + ;; + "php") + RESULT=$(core php qa 2>&1) || true + ;; + *) + # Not a Go or PHP project, allow stop + exit 0 + ;; +esac + # Check if QA passed if echo "$RESULT" | grep -qE "FAIL|ERROR|✗|panic:|undefined:"; then # Extract top issues for context