# QA STLC Agents — Makefile
#
# Supports ADO, Jira, and Both pipelines.
#
# INTEGRATION variable controls which agents/skills/config are active.
# Override on the command line:
#   make install        INTEGRATION=jira
#   make mcp-config     INTEGRATION=both
#   make verify         INTEGRATION=jira
#
# Convenience aliases (no INTEGRATION override needed):
#   make install-ado              make install-jira              make install-both
#   make mcp-config-ado           make mcp-config-jira           make mcp-config-both
#   make mcp-config-vscode-ado    make mcp-config-vscode-jira    make mcp-config-vscode-both
#   make skills-ado               make skills-jira               make skills-both
#   make verify-ado               make verify-jira               make verify-both
#   make bootstrap-ado            make bootstrap-jira            make bootstrap-both
#   make migrate-ado              make migrate-jira              make migrate-both
#
# Migration (existing Playwright project → Helix-QA layout):
#   make migrate-preview  SOURCE=./old-tests HELIX=./helix-qa
#   make migrate          SOURCE=./old-tests HELIX=./helix-qa [INTEGRATION=both] [CONFLICT=overwrite]
#   make migrate-ado      SOURCE=./old-tests HELIX=./helix-qa
#   make audit-migration  HELIX=./helix-qa

PYTHON      := python3
VENV        := .venv
PIP         := $(VENV)/bin/pip
PYTEST      := $(VENV)/bin/pytest
INTEGRATION ?= ado

# ── Agent binary paths ─────────────────────────────────────────────────────────
MCP_TC   := $(VENV)/bin/qa-test-case-manager
MCP_GH   := $(VENV)/bin/qa-gherkin-generator
MCP_PW   := $(VENV)/bin/qa-playwright-generator
MCP_HX   := $(VENV)/bin/qa-helix-writer
MCP_JR   := $(VENV)/bin/qa-jira-manager
MCP_MG   := $(VENV)/bin/qa-migration

.PHONY: \
  install install-ado install-jira install-both install-dev \
  bootstrap bootstrap-ado bootstrap-jira bootstrap-both \
  skills skills-ado skills-jira skills-both skills-vscode \
  mcp-config mcp-config-ado mcp-config-jira mcp-config-both \
  mcp-config-vscode mcp-config-vscode-ado mcp-config-vscode-jira mcp-config-vscode-both \
  verify verify-ado verify-jira verify-both \
  serve serve-prod \
  install-webhook \
  docker-build-webhook docker-run-webhook \
  register-ado-hooks register-jira-hooks register-hooks \
  deploy-azure \
  test test-webhook test-all \
  publish clean \
  help \
  migrate migrate-ado migrate-jira migrate-both \
  migrate-preview migrate-help audit-migration

# ─── Default target ────────────────────────────────────────────────────────────
.DEFAULT_GOAL := help

help: ## Show this help
	@echo ""
	@echo "QA STLC Agents — available targets"
	@echo ""
	@echo "  INTEGRATION=[ado|jira|both]  (default: ado)"
	@echo ""
	@grep -E '^[a-zA-Z_-]+:.*##' $(MAKEFILE_LIST) \
	  | sed 's/:.*##/\t/' \
	  | column -t -s $$'\t' \
	  | sed 's/^/  /'
	@echo ""

# ─── Install ───────────────────────────────────────────────────────────────────
install: ## Create venv and install all five MCP agents
	$(PYTHON) -m venv $(VENV)
	$(PIP) install --upgrade pip
	$(PIP) install -e .
	@mkdir -p . && cp ORCHESTRATION_RULES.md . 2>/dev/null || true
	@echo ""
	@echo "✓ All six MCP agents installed"
	@echo "  ADO  entry point  : $(MCP_TC)"
	@echo "  Jira entry point  : $(MCP_JR)"
	@echo "  Shared (both)     : $(MCP_GH)"
	@echo "                      $(MCP_PW)"
	@echo "                      $(MCP_HX)"
	@echo "  Migration         : $(MCP_MG)  (stlc-migrate CLI also available)"
	@echo ""
	@echo "  Rules file        : ORCHESTRATION_RULES.md (project root)"
	@echo "Active integration  : $(INTEGRATION)"
	@$(MAKE) --no-print-directory _next_steps_$(INTEGRATION)

install-ado:  ## Install for ADO integration
	@$(MAKE) install INTEGRATION=ado

install-jira: ## Install for Jira integration
	@$(MAKE) install INTEGRATION=jira

install-both: ## Install for both ADO and Jira
	@$(MAKE) install INTEGRATION=both

install-dev: install ## Install + pytest for local development
	$(PIP) install pytest pytest-asyncio

install-webhook: ## Install webhook bridge extra deps (FastAPI + uvicorn)
	$(PIP) install -e ".[webhook]"

# ─── Internal next-step hints ──────────────────────────────────────────────────
_next_steps_ado:
	@echo "Next steps:"
	@echo "  make bootstrap-ado                              # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo ""
	@echo "  # Greenfield:"
	@echo "  qa-stlc scaffold --name my-qa-project           # new Playwright + Cucumber + TS project"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-ado SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

_next_steps_jira:
	@echo "Next steps:"
	@echo "  make bootstrap-jira                             # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo "  Add JIRA_CLIENT_ID / JIRA_CLIENT_SECRET / JIRA_CLOUD_ID to .env"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-jira SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

_next_steps_both:
	@echo "Next steps:"
	@echo "  make bootstrap-both                             # skills + .mcp.json in one shot"
	@echo "  npx @playwright/mcp@latest --port 8931          # browser MCP for live locator capture"
	@echo "  Add JIRA_CLIENT_ID / JIRA_CLIENT_SECRET / JIRA_CLOUD_ID to .env"
	@echo ""
	@echo "  # Migrate an existing Playwright project:"
	@echo "  make migrate-both SOURCE=./old-tests HELIX=./helix-qa"
	@echo ""
	@echo "Reference: ORCHESTRATION_RULES.md (multi-step workflow best practices)"

# ─── Bootstrap (skills + MCP config in one shot) ───────────────────────────────
bootstrap: ## Install skills + MCP config (Claude Code + VS Code) — INTEGRATION=ado|jira|both
	@$(MAKE) --no-print-directory skills          INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory skills-vscode   INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory mcp-config      INTEGRATION=$(INTEGRATION)
	@$(MAKE) --no-print-directory mcp-config-vscode INTEGRATION=$(INTEGRATION)
	@echo ""
	@echo "✓ Bootstrap complete (integration=$(INTEGRATION))"

bootstrap-ado:  ## skills + MCP config for ADO (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=ado

bootstrap-jira: ## skills + MCP config for Jira (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=jira

bootstrap-both: ## skills + MCP config for both (Claude Code + VS Code)
	@$(MAKE) bootstrap INTEGRATION=both

# ─── Verify ────────────────────────────────────────────────────────────────────
verify: ## Verify agent binaries and auth caches (INTEGRATION=ado|jira|both)
	@echo "=== Verifying integration: $(INTEGRATION) ==="
ifeq ($(INTEGRATION),ado)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_ado_auth
else ifeq ($(INTEGRATION),jira)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_jira_auth
else ifeq ($(INTEGRATION),both)
	@$(MAKE) --no-print-directory _verify_shared
	@$(MAKE) --no-print-directory _verify_ado_auth
	@$(MAKE) --no-print-directory _verify_jira_auth
else
	@echo "Unknown INTEGRATION=$(INTEGRATION). Use ado, jira, or both." && exit 1
endif

_verify_shared:
	@echo "--- Shared agents ---"
	@test -f $(MCP_GH) && echo "✓ $(MCP_GH)" || echo "✗ $(MCP_GH) not found — run: make install"
	@test -f $(MCP_PW) && echo "✓ $(MCP_PW)" || echo "✗ $(MCP_PW) not found — run: make install"
	@test -f $(MCP_HX) && echo "✓ $(MCP_HX)" || echo "✗ $(MCP_HX) not found — run: make install"
	@test -f $(MCP_MG) && echo "✓ $(MCP_MG)" || echo "✗ $(MCP_MG) not found — run: make install"

_verify_ado_auth:
	@echo "--- ADO agent + MSAL auth ---"
	@test -f $(MCP_TC) && echo "✓ $(MCP_TC)" || echo "✗ $(MCP_TC) not found — run: make install"
	@$(PYTHON) -c \
	  "from stlc_agents.shared.auth import get_signed_in_user; \
	   u = get_signed_in_user(); \
	   print('✓ ADO MSAL: signed in as ' + u if u else \
	         '⚠ ADO MSAL: no cached account — browser opens on first tool call')" \
	  2>/dev/null || echo "⚠ ADO MSAL: auth module not found — run: make install"

_verify_jira_auth:
	@echo "--- Jira agent + OAuth cache ---"
	@test -f $(MCP_JR) && echo "✓ $(MCP_JR)" || echo "✗ $(MCP_JR) not found — run: make install"
	@test -f ~/.jira-cache/jira-token.json \
	  && echo "✓ Jira token cache found" \
	  || echo "⚠ Jira token cache not found — browser opens on first qa-jira-manager call"
	@test -n "$$JIRA_CLIENT_ID" \
	  && echo "✓ JIRA_CLIENT_ID set" \
	  || echo "⚠ JIRA_CLIENT_ID not set in env / .env"

verify-ado:  ## Verify ADO integration
	@$(MAKE) verify INTEGRATION=ado

verify-jira: ## Verify Jira integration
	@$(MAKE) verify INTEGRATION=jira

verify-both: ## Verify both integrations
	@$(MAKE) verify INTEGRATION=both

# ─── Skills ────────────────────────────────────────────────────────────────────
# ADO skill set
ADO_SKILL_DIRS  = generate-test-cases generate-gherkin generate-playwright-code \
                  write-helix-files deduplication-protocol migrate-framework

# Jira skill set (qa-jira-manager replaces generate-test-cases)
JIRA_SKILL_DIRS = qa-jira-manager generate-gherkin generate-playwright-code \
                  write-helix-files deduplication-protocol migrate-framework

# Common reference files (installed to all skill destinations)
# • ORCHESTRATION_RULES.md — reference guide for multi-step QA workflows
# • AGENT-BEHAVIOR.md      — agent decision rules and routing logic

skills: ## Install skills to .claude/skills/ (Claude Code)
	@echo "Installing skills (integration=$(INTEGRATION)) → .claude/skills/ ..."
	@mkdir -p .claude/skills
	@cp skills/AGENT-BEHAVIOR.md .claude/
	@cp ORCHESTRATION_RULES.md .claude/ 2>/dev/null || true
ifeq ($(INTEGRATION),ado)
	@for d in $(ADO_SKILL_DIRS); do cp -r skills/$$d .claude/skills/; done
else ifeq ($(INTEGRATION),jira)
	@for d in $(JIRA_SKILL_DIRS); do cp -r skills/$$d .claude/skills/; done
else ifeq ($(INTEGRATION),both)
	@for d in $(ADO_SKILL_DIRS) qa-jira-manager; do cp -r skills/$$d .claude/skills/; done
else
	@echo "Unknown INTEGRATION=$(INTEGRATION). Use ado, jira, or both." && exit 1
endif
	@echo "✓ Skills installed to .claude/skills/ (integration=$(INTEGRATION))"
	@echo "✓ ORCHESTRATION_RULES.md + AGENT-BEHAVIOR.md copied"

skills-vscode: ## Install skills to .github/copilot-instructions/ (VS Code / Copilot)
	@echo "Installing skills (integration=$(INTEGRATION)) → .github/copilot-instructions/ ..."
	@mkdir -p .github/copilot-instructions
	@cp skills/AGENT-BEHAVIOR.md .github/copilot-instructions/
	@cp ORCHESTRATION_RULES.md .github/copilot-instructions/ 2>/dev/null || true
ifeq ($(INTEGRATION),ado)
	@for d in $(ADO_SKILL_DIRS); do cp skills/$$d/SKILL.md .github/copilot-instructions/$$d.md; done
else ifeq ($(INTEGRATION),jira)
	@for d in $(JIRA_SKILL_DIRS); do cp skills/$$d/SKILL.md .github/copilot-instructions/$$d.md; done
else ifeq ($(INTEGRATION),both)
	@for d in $(ADO_SKILL_DIRS) qa-jira-manager; do cp skills/$$d/SKILL.md .github/copilot-instructions/$$d.md; done
else
	@echo "Unknown INTEGRATION=$(INTEGRATION). Use ado, jira, or both." && exit 1
endif
	@echo "✓ Skills installed to .github/copilot-instructions/ (integration=$(INTEGRATION))"
	@echo "✓ ORCHESTRATION_RULES.md + AGENT-BEHAVIOR.md copied"

skills-ado:  ## Install ADO skills (Claude Code + VS Code)
	@$(MAKE) skills INTEGRATION=ado && $(MAKE) skills-vscode INTEGRATION=ado

skills-jira: ## Install Jira skills (Claude Code + VS Code)
	@$(MAKE) skills INTEGRATION=jira && $(MAKE) skills-vscode INTEGRATION=jira

skills-both: ## Install all skills (Claude Code + VS Code)
	@$(MAKE) skills INTEGRATION=both && $(MAKE) skills-vscode INTEGRATION=both

# ─── MCP Config ────────────────────────────────────────────────────────────────
mcp-config: ## Write .mcp.json for Claude Code (INTEGRATION=ado|jira|both)
	@echo "Writing .mcp.json (integration=$(INTEGRATION)) ..."
	@ABS=$$(pwd); \
	case "$(INTEGRATION)" in \
	  ado) \
	    printf '{\n  "mcpServers": {\n    "qa-test-case-manager":    { "command": "%s" },\n    "qa-gherkin-generator":    { "command": "%s" },\n    "qa-playwright-generator": { "command": "%s" },\n    "qa-helix-writer":         { "command": "%s" },\n    "qa-migration":            { "command": "%s" },\n    "playwright":              { "command": "npx", "args": ["@playwright/mcp@latest", "--isolated"] }\n  }\n}\n' \
	      "$$ABS/$(MCP_TC)" "$$ABS/$(MCP_GH)" "$$ABS/$(MCP_PW)" "$$ABS/$(MCP_HX)" "$$ABS/$(MCP_MG)" > .mcp.json ;; \
	  jira) \
	    printf '{\n  "mcpServers": {\n    "qa-jira-manager":          { "command": "%s", "env": { "JIRA_CLIENT_ID": "${JIRA_CLIENT_ID}", "JIRA_CLIENT_SECRET": "${JIRA_CLIENT_SECRET}", "JIRA_CLOUD_ID": "${JIRA_CLOUD_ID}" } },\n    "qa-gherkin-generator":    { "command": "%s" },\n    "qa-playwright-generator": { "command": "%s" },\n    "qa-helix-writer":         { "command": "%s" },\n    "qa-migration":            { "command": "%s" },\n    "playwright":              { "command": "npx", "args": ["@playwright/mcp@latest", "--isolated"] }\n  }\n}\n' \
	      "$$ABS/$(MCP_JR)" "$$ABS/$(MCP_GH)" "$$ABS/$(MCP_PW)" "$$ABS/$(MCP_HX)" "$$ABS/$(MCP_MG)" > .mcp.json ;; \
	  both) \
	    printf '{\n  "mcpServers": {\n    "qa-test-case-manager":    { "command": "%s" },\n    "qa-jira-manager":          { "command": "%s", "env": { "JIRA_CLIENT_ID": "${JIRA_CLIENT_ID}", "JIRA_CLIENT_SECRET": "${JIRA_CLIENT_SECRET}", "JIRA_CLOUD_ID": "${JIRA_CLOUD_ID}" } },\n    "qa-gherkin-generator":    { "command": "%s" },\n    "qa-playwright-generator": { "command": "%s" },\n    "qa-helix-writer":         { "command": "%s" },\n    "qa-migration":            { "command": "%s" },\n    "playwright":              { "command": "npx", "args": ["@playwright/mcp@latest", "--isolated"] }\n  }\n}\n' \
	      "$$ABS/$(MCP_TC)" "$$ABS/$(MCP_JR)" "$$ABS/$(MCP_GH)" "$$ABS/$(MCP_PW)" "$$ABS/$(MCP_HX)" "$$ABS/$(MCP_MG)" > .mcp.json ;; \
	  *) echo "Unknown INTEGRATION=$(INTEGRATION). Use ado, jira, or both." && exit 1 ;; \
	esac
	@echo "✓ .mcp.json written (integration=$(INTEGRATION))"

mcp-config-ado:  ## Write .mcp.json for ADO
	@$(MAKE) mcp-config INTEGRATION=ado

mcp-config-jira: ## Write .mcp.json for Jira
	@$(MAKE) mcp-config INTEGRATION=jira

mcp-config-both: ## Write .mcp.json for both ADO and Jira
	@$(MAKE) mcp-config INTEGRATION=both

mcp-config-vscode: ## Write .vscode/mcp.json for VS Code / Copilot (INTEGRATION=ado|jira|both)
	$(PYTHON) scripts/generate-mcp-config.py --vscode --integration $(INTEGRATION)

mcp-config-vscode-ado:  ## Write .vscode/mcp.json for ADO
	@$(MAKE) mcp-config-vscode INTEGRATION=ado

mcp-config-vscode-jira: ## Write .vscode/mcp.json for Jira
	@$(MAKE) mcp-config-vscode INTEGRATION=jira

mcp-config-vscode-both: ## Write .vscode/mcp.json for both ADO and Jira
	@$(MAKE) mcp-config-vscode INTEGRATION=both

# ─── Webhook bridge ────────────────────────────────────────────────────────────
serve: ## Start webhook bridge locally (port 8080, auto-reload)
	qa-stlc-serve --host 0.0.0.0 --port 8080 --reload

serve-prod: ## Start webhook bridge (production mode, no reload)
	qa-stlc-serve --host 0.0.0.0 --port 8080

docker-build-webhook: ## Build webhook bridge Docker image
	docker build -f Dockerfile.webhook -t stlc-webhook-bridge:latest .

docker-run-webhook: ## Run webhook bridge in Docker (reads from .env)
	docker run --rm -p 8080:8080 \
	  --env-file .env \
	  -e PLAYWRIGHT_MCP_URL=http://host.docker.internal:8931/mcp \
	  stlc-webhook-bridge:latest

# ─── Hook registration ─────────────────────────────────────────────────────────
register-ado-hooks: ## Register ADO Service Hooks — requires BRIDGE_URL=https://...
	@test -n "$(BRIDGE_URL)" \
	  || (echo "Usage: make register-ado-hooks BRIDGE_URL=https://your-bridge" && exit 1)
	python scripts/register_ado_hooks.py --bridge-url $(BRIDGE_URL)

register-jira-hooks: ## Register Jira webhook — requires BRIDGE_URL=https://...
	@test -n "$(BRIDGE_URL)" \
	  || (echo "Usage: make register-jira-hooks BRIDGE_URL=https://your-bridge" && exit 1)
	python scripts/register_jira_hooks.py --bridge-url $(BRIDGE_URL)

register-hooks: ## Register both ADO and Jira hooks — requires BRIDGE_URL=https://...
	$(MAKE) register-ado-hooks  BRIDGE_URL=$(BRIDGE_URL)
	$(MAKE) register-jira-hooks BRIDGE_URL=$(BRIDGE_URL)

# ─── Azure Functions deploy ────────────────────────────────────────────────────
deploy-azure: ## Deploy webhook bridge to Azure Functions — requires FUNC_APP=<name>
	@test -n "$(FUNC_APP)" \
	  || (echo "Usage: make deploy-azure FUNC_APP=stlc-webhook-bridge" && exit 1)
	cd azure_functions && func azure functionapp publish $(FUNC_APP) --python

# ─── Migration helper targets ──────────────────────────────────────────────────
# Defaults: integration=both (every agent reachable), conflict=interactive.
# Override on the command line:
#   make migrate SOURCE=./old HELIX=./new INTEGRATION=ado    CONFLICT=overwrite
CONFLICT ?= interactive

migrate-preview: ## Preview migration without writing files (SOURCE=<dir> HELIX=<dir>)
	@test -n "$(SOURCE)" \
	  || (echo "Usage: make migrate-preview SOURCE=./old-tests HELIX=./helix-qa" && exit 1)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make migrate-preview SOURCE=./old-tests HELIX=./helix-qa" && exit 1)
	$(VENV)/bin/stlc-migrate --source $(SOURCE) --helix $(HELIX) --dry-run

migrate: ## Migrate a Playwright project (SOURCE=<dir> HELIX=<dir> [INTEGRATION=ado|jira|both] [CONFLICT=...])
	@test -n "$(SOURCE)" \
	  || (echo "Usage: make migrate SOURCE=./old-tests HELIX=./helix-qa [INTEGRATION=both] [CONFLICT=overwrite]" && exit 1)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make migrate SOURCE=./old-tests HELIX=./helix-qa [INTEGRATION=both] [CONFLICT=overwrite]" && exit 1)
	@mkdir -p $(HELIX)
	$(VENV)/bin/stlc-migrate \
	  --source $(SOURCE) \
	  --helix $(HELIX) \
	  --integration $(INTEGRATION) \
	  --conflict $(CONFLICT)
	@echo ""
	@echo "Next steps (in $(HELIX)):"
	@echo "  npm install                          # picks up dotenv + @types/* companions"
	@echo "  npx tsc --noEmit                     # should be clean"
	@echo "  npm test                             # healing fires on broken primary selectors"
	@echo "  npm run healix:dashboard             # http://localhost:7890 — Confirm/Revert UI"
	@echo "  npm run healix:review                # http://localhost:7891 — read-only mirror"

migrate-ado:  ## Migrate with ADO skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=ado SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-jira: ## Migrate with Jira skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=jira SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-both: ## Migrate with all agent skills + MCP entries (SOURCE=<dir> HELIX=<dir>)
	@$(MAKE) migrate INTEGRATION=both SOURCE=$(SOURCE) HELIX=$(HELIX) CONFLICT=$(CONFLICT)

migrate-help: ## Show stlc-migrate CLI help
	$(VENV)/bin/stlc-migrate --help

audit-migration: ## Verify a migrated tree is agent-ready (HELIX=<dir>)
	@test -n "$(HELIX)" \
	  || (echo "Usage: make audit-migration HELIX=./helix-qa" && exit 1)
	@echo "=== Auditing $(HELIX) ==="
	@$(VENV)/bin/python -c "\
	from stlc_agents.agent_helix_writer.tools.helix_write import inspect_helix_project; \
	r = inspect_helix_project('$(HELIX)'); \
	print('framework_state:', r['framework_state']); \
	print('recommendation: ', r['recommendation']); \
	print('existing_infra: %d files' % len(r['existing_infra'])); \
	print('missing_infra:  ', r['missing_infra'] or 'none'); \
	"
	@echo ""
	@echo "--- Agent assets ---"
	@test -f $(HELIX)/.mcp.json                         && echo "✓ .mcp.json"                          || echo "✗ .mcp.json"
	@test -d $(HELIX)/.claude/skills                    && echo "✓ .claude/skills/"                    || echo "✗ .claude/skills/"
	@test -d $(HELIX)/.github/copilot-instructions      && echo "✓ .github/copilot-instructions/"      || echo "✗ .github/copilot-instructions/"
	@test -f $(HELIX)/AGENT-BEHAVIOR.md                 && echo "✓ AGENT-BEHAVIOR.md"                  || echo "✗ AGENT-BEHAVIOR.md"
	@test -f $(HELIX)/ORCHESTRATION_RULES.md            && echo "✓ ORCHESTRATION_RULES.md"             || echo "✗ ORCHESTRATION_RULES.md"
	@echo ""
	@echo "--- Healer scaffold ---"
	@for f in LocatorHealer.ts LocatorRepository.ts TimingHealer.ts VisualIntentChecker.ts HealingDashboard.ts dashboard-server.ts; do \
	  test -f $(HELIX)/src/utils/locators/$$f \
	    && echo "✓ src/utils/locators/$$f" \
	    || echo "✗ src/utils/locators/$$f"; \
	done
	@echo ""
	@echo "--- Heal store / log (if tests have run) ---"
	@ls $(HELIX)/self-heals/*.json 2>/dev/null | head -3 || echo "  (no heal-store yet — run tests to populate)"
	@test -f $(HELIX)/self-heals/heal.log && echo "✓ self-heals/heal.log" || echo "  (no heal log yet)"

# ─── Tests ─────────────────────────────────────────────────────────────────────
test: test-all ## Alias for test-all

test-webhook: ## Run webhook unit tests only
	$(PYTEST) tests/test_webhook.py -v

test-all: ## Run all tests
	$(PYTEST) tests/ -v

# ─── Publish ───────────────────────────────────────────────────────────────────
# Bump version in package.json + pyproject.toml before running.
publish: ## Publish to npm and PyPI (bump version first)
	npm publish --access public
	$(PIP) install --quiet build twine
	rm -rf dist
	$(VENV)/bin/python -m build
	$(VENV)/bin/python -m twine upload --skip-existing dist/*

# ─── Clean ─────────────────────────────────────────────────────────────────────
clean: ## Remove venv, build artefacts, and __pycache__
	rm -rf $(VENV) __pycache__ dist *.egg-info
	find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
	find . -type f -name "*.pyc" -delete
	@echo "✓ Cleaned"	