Ctrl K
ComunidadGuías…

Makefile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
.PHONY: help plugin-submission-check install test lint lint-ruff lint-mypy format format-check preflight preflight-fix ci-local ci-smoke docker-build docker-run scan clean build-ui release-build publish-test publish analytics dev check-dupes clean-dupes secrets platform-up fullstack-up

help:  ## Show this help message
	@echo 'Usage: make [target]'
	@echo ''
	@echo 'Available targets:'
	@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "  %-20s %s\n", $$1, $$2}' $(MAKEFILE_LIST)

install:  ## Install agent-bom with the full contributor test extras
	pip install -e ".[dev-all]"

install-all:  ## Install agent-bom with all development extras
	pip install -e ".[dev-all]"

dev:  ## Start API server + Next.js dashboard for development
	@echo "Starting API server on :8422 and dashboard on :3000..."
	@echo "  API docs  → http://localhost:8422/docs"
	@echo "  Dashboard → http://localhost:3000"
	@echo "  Press Ctrl+C to stop."
	@$(MAKE) -j2 _dev-api _dev-ui

_dev-api:
	@python -m agent_bom.cli._entry serve --port 8422 --cors-allow-all --reload 2>&1

_dev-ui:
	@cd ui && npm run dev 2>&1

test:  ## Run unit tests
	pytest tests/ -v --cov=agent_bom --cov-fail-under=75

# Every Python directory that ships or gates a release. `scripts/` was outside
# this set, so a dead local in `generate_doc_architecture_svgs.py` sat on main
# unnoticed — release gates, drift checks and the SVG generators all live there.
# CI's Ruff step calls `lint-ruff` rather than repeating the paths, so the two
# cannot disagree about what gets linted.
LINT_PATHS := src/ tests/ scripts/ .clusterfuzzlite/fuzz/

lint-ruff:  ## Ruff over every linted path
	ruff check $(LINT_PATHS)

lint-mypy:  ## MyPy over the shipped package
	mypy src/ --ignore-missing-imports --disable-error-code import-untyped

lint: lint-ruff lint-mypy  ## Run linters (ruff + mypy)

format:  ## Format code with ruff
	ruff format $(LINT_PATHS)

format-check:  ## Fail if anything is unformatted (what CI runs)
	ruff format --check $(LINT_PATHS)

preflight:  ## Run the drift gates that CI's "Version Alignment" job runs — do this before pushing a PR
	@echo "→ architecture boundaries and complexity ratchet"; python scripts/check_architecture.py
	@echo "→ line ceiling (files/functions)";      python scripts/check_line_ceiling.py
	@echo "→ OpenAPI artifacts (docs/openapi/)";   python scripts/export_openapi.py --check
	@echo "→ v1 schemas (docs/schemas/v1/)";        python scripts/generate_v1_schemas.py --check
	@echo "→ per-agent BOM schema";                python scripts/generate_agent_bom_schema.py --check
	@echo "→ ATLAS dashboard labels";              python scripts/generate_atlas_labels.py --check
	@echo "→ Postgres migration contracts";         python -m pytest tests/test_postgres_migrations.py tests/test_postgres_schema_authority.py -q
	@echo "→ agent capability manifest";             python scripts/generate_agent_capability_manifest.py --check
	@echo "→ documented surface counts";            python scripts/check-counts.py
	@echo "→ product surface contract";             python scripts/check_product_surface_contract.py
	@echo "→ graph proof fixtures";                 python scripts/check_graph_epic_proof.py
	@echo "→ reference evidence lab";               python scripts/generate_reference_evidence_lab.py --check
	@echo "→ enterprise demo surfaces";             python scripts/check_enterprise_demo_surfaces.py
	@echo "→ release/README consistency";           python scripts/check_release_consistency.py
	@echo "→ release evidence matrix";              python scripts/check_release_evidence_matrix.py
	@echo "→ published counts vs shipped build";    python scripts/check_published_counts.py
	@echo "→ CI pipefail policy";                   python scripts/check_ci_pipefail.py
	@echo "→ default MCP argument inventory";       python scripts/generate_mcp_profile_catalog.py --check
	@echo "→ product metrics snapshot";             python scripts/product_metrics_snapshot.py --check
	@echo "→ vendor coverage matrix";               python scripts/generate_vendor_coverage.py --check
	@echo "→ banner + integration tables";          python scripts/render_social_preview_svg.py --check
	@echo "→ CVE matching accuracy";                python scripts/cve_matching_accuracy.py --check
	@echo "→ skill audit accuracy";                 python scripts/skill_audit_accuracy.py --check
	@echo "→ env-var reference";                    python scripts/generate_env_var_reference.py --check
	@echo "→ experimental-feature reference";       python scripts/generate_experimental_docs.py --check
	@echo "→ SDK patterns.json";                    python sdks/shared/generate-patterns.py --check
	@echo "→ documentation SVGs";                    python scripts/generate_doc_architecture_svgs.py --check
	@echo "→ blast-radius SVGs";                     python scripts/generate_blast_radius_svgs.py --check
	@echo "✓ preflight passed — CI's Version Alignment gate will be green (run 'make lint' separately for ruff/mypy)"

ci-local:  ## Run every gating CI job locally, step for step from ci.yml (lint, security, version-check, ui, 4 test shards)
	uv run --no-sync python scripts/ci_local.py

ci-smoke:  ## Fast pre-push tier: CI's lint, version-check and changed-domain smoke jobs
	uv run --no-sync python scripts/ci_local.py --jobs lint,version-check,test-smoke

preflight-fix:  ## Regenerate every drift artifact so you never push stale OpenAPI/schemas/patterns; then review + commit
	python scripts/export_openapi.py
	python scripts/generate_v1_schemas.py
	python scripts/generate_agent_bom_schema.py
	python scripts/generate_atlas_labels.py
	python scripts/generate_env_var_reference.py
	python scripts/generate_experimental_docs.py
	python sdks/shared/generate-patterns.py
	python scripts/product_metrics_snapshot.py --write
	python scripts/generate_agent_capability_manifest.py --write
	python scripts/generate_vendor_coverage.py --write
	python scripts/generate_mcp_profile_catalog.py
	python scripts/generate_reference_evidence_lab.py
	@echo "✓ regenerated — run 'git status', review, and commit the artifacts"

docker-build:  ## Build Docker image
	docker build -t agent-bom:latest .

docker-run:  ## Run agent-bom in Docker container
	docker run --rm \
		-v $(PWD):/workspace \
		-v ~/.config:/root/.config:ro \
		agent-bom:latest scan --help

scan:  ## Run local scan with enrichment
	agent-bom scan --enrich --format json --output report.json

scan-transitive:  ## Run scan with transitive dependencies
	agent-bom scan --enrich --transitive --max-depth 3 --output report.json

e2e-test:  ## Run end-to-end tests
	chmod +x test_e2e.sh
	./test_e2e.sh

secrets:  ## Generate the mounted Docker secret files (idempotent; run before platform/fullstack up)
	python scripts/deploy/hosted_poc_preflight.py --write-secret --skip-compose

platform-up: secrets  ## Bring up the production-shaped platform stack (generates secrets first)
	AGENT_BOM_SECRETS_GID=$$(id -g) docker compose -f deploy/docker-compose.platform.yml up --build -d

fullstack-up: secrets  ## Bring up the dev full-stack (API + UI + Postgres); generates secrets first
	AGENT_BOM_SECRETS_GID=$$(id -g) docker compose -f deploy/docker-compose.fullstack.yml up --build -d

build-ui:  ## Build Next.js dashboard and bundle into package
	bash scripts/build-ui.sh

release-build: build-ui  ## Build and verify release artifacts with the bundled dashboard
	rm -rf dist/
	uv build
	uv run python scripts/verify_release_wheel.py dist

check-dupes:  ## Detect Finder-style duplicate files (incl. untracked) in the working tree
	python3 scripts/check_duplicate_artifacts.py --working-tree

clean-dupes:  ## Delete untracked Finder-style duplicates (e.g. 'foo 2.py'); tracked files are never removed
	@python3 scripts/check_duplicate_artifacts.py --working-tree 2>&1 | sed -n 's/^- //p' | while IFS= read -r f; do \
		if [ -n "$$f" ] && [ -z "$$(git ls-files -- "$$f")" ]; then echo "removing $$f"; rm -rf -- "$$f"; fi; \
	done; echo "✓ untracked duplicates removed (tracked files untouched)"

clean:  ## Clean build artifacts
	rm -rf build/ dist/ *.egg-info
	find . -type d -name __pycache__ -exec rm -rf {} +
	find . -type f -name '*.pyc' -delete
	rm -f report.json ai-bom*.json *.cdx.json

publish-test: release-build  ## Publish verified artifacts to TestPyPI
	twine upload --repository testpypi dist/*

publish: release-build  ## Publish verified artifacts to PyPI
	twine upload dist/*

version:  ## Show agent-bom version
	agent-bom --version

demo:  ## Run demo scan
	@echo "Running demo scan..."
	agent-bom scan --enrich --format console
	@echo ""
	@echo "JSON output:"
	agent-bom scan --enrich --format json --output demo.json
	@cat demo.json | python -m json.tool | head -50

# Git workflow commands
git-feature:  ## Create new feature branch (usage: make git-feature name=my-feature)
	@if [ -z "$(name)" ]; then \
		echo "Error: Please provide branch name: make git-feature name=my-feature"; \
		exit 1; \
	fi
	git checkout main
	git pull origin main
	git checkout -b feature/$(name)
	@echo "✓ Created and switched to feature/$(name)"

git-pr:  ## Create pull request for current branch
	gh pr create --fill --base main

git-sync:  ## Sync main branch with remote
	git checkout main
	git pull origin main
	@echo "✓ main branch updated"

git-cleanup:  ## Delete merged feature branches
	git branch --merged main | grep -v "^\* main" | xargs -n 1 git branch -d || true
	@echo "✓ Cleaned up merged branches"

git-status:  ## Show git status and current branch
	@echo "Current branch:"
	@git branch --show-current
	@echo ""
	@git status


analytics:  ## Show adoption metrics (PyPI downloads, GitHub traffic, stars)
	@echo "=== PyPI downloads (recent) ==="
	@curl -sf "https://pypistats.org/api/packages/agent-bom/recent" 2>/dev/null \
		| python3 -c "import json,sys; d=json.load(sys.stdin)['data']; print(f\"  Last day:   {d['last_day']:>8,}\n  Last week:  {d['last_week']:>8,}\n  Last month: {d['last_month']:>8,}\")" \
		|| echo "  (pypistats rate-limited — try again in 60s)"
	@echo ""
	@echo "=== PyPI downloads by Python version ==="
	@curl -sf "https://pypistats.org/api/packages/agent-bom/python_minor" 2>/dev/null \
		| python3 -c "import json,sys; d=json.load(sys.stdin)['data']; [print(f\"  Python {r['category']:6} {r['downloads']:>8,}\") for r in sorted(d, key=lambda x: x['downloads'], reverse=True)[:8] if r['category'] and r['category'] != 'null']" \
		|| echo "  (pypistats rate-limited)"
	@echo ""
	@echo "=== GitHub traffic (last 14 days) ==="
	@gh api /repos/koda-ai-studio/agent-bom/traffic/views 2>/dev/null \
		| python3 -c "import json,sys; d=json.load(sys.stdin); print(f\"  Views:  {d['count']:>8,}  unique: {d['uniques']:,}\")" \
		|| echo "  (requires repo write access)"
	@gh api /repos/koda-ai-studio/agent-bom/traffic/clones 2>/dev/null \
		| python3 -c "import json,sys; d=json.load(sys.stdin); print(f\"  Clones: {d['count']:>8,}  unique: {d['uniques']:,}\")" \
		|| true
	@echo ""
	@echo "=== GitHub stars & forks ==="
	@gh api /repos/koda-ai-studio/agent-bom --jq '"  Stars: " + (.stargazers_count|tostring) + "   Forks: " + (.forks_count|tostring)' 2>/dev/null || true

plugin-submission-check:  ## Stop a plugin directory submission that would ship stale pins or draft legal pages
	python scripts/check_plugin_submission_ready.py