Repository navigation
[1.0.0] - 2026-04-29
First public release. Three input surfaces (CLI, local web UI, hosted demo) sharing one core engine and a single Report shape.
Added — Core engine
- Pydantic v2 data model:
Report,Finding,RequestSummary,ResponseSummary,TimingBreakdown,CapturedRequest,CapturedResponse,CapturedDns,CapturedTls.schema_versionbump-tracked. - Parser: HAR 1.2 archives and curl command strings normalized to the same
CapturedRequestshape. - Runner: live HTTP execution via
httpx, withdnspythonpre-flight DNS probe and a separatecryptography-based TLS cert/protocol probe. Captures DNS / TLS / TTFB / total timing, redirect chain, raw headers (preserving duplicateSet-Cookie). - Check battery — 20+ diagnostic checks across:
- Network —
dns.no_records,dns.address_class - TLS —
tls.expired,tls.expiring_soon,tls.hostname_mismatch,tls.weak_protocol - Transport —
transport.redirect_loop,transport.redirect_to_http,transport.slow_tls - Auth —
auth.jwt_expired,auth.missing_authorization,auth.malformed_authorization,auth.suspicious_jwt_signature - CORS —
cors.preflight_failed,cors.origin_not_allowed,cors.credentials_misconfigured - Body —
body.malformed_json,body.content_length_mismatch,body.encoding_mismatch - Rate limit —
ratelimit.too_many_requests(with Retry-After context) - Status —
status.client_error,status.server_error
- Network —
- Renderers: terminal (rich), JSON, Markdown, HTML — pluggable via
--output.
Added — CLI
api-medic <URL>quick GET diagnosis (default subcommand).api-medic run <URL>full request with method, headers, body, auth.api-medic from-curl '<command>'parse + analyze (or just analyze) a curl command.api-medic from-har <file.har>analyze a captured HAR.api-medic serve [--port 8765]launch the local web UI.- Output flags:
--output {terminal,json,markdown,html},--save <path>,--no-color,--verbose.
Added — Local web UI
- Vite + React 18 + TypeScript + Tailwind, no design system library, no state management library.
- Three tabs: Demos (fixture browser), Run (request composer hitting
/api/run), HAR (file upload hitting/api/analyze). - TypeScript types auto-generated from Pydantic JSON Schema via
make types; CI fails if regenerated types drift from the committed file. - React bundle ships inside the Python wheel — no separate install step for the local UI.
Added — Hosted demo (AWS)
https://api-medic.markandrewmarquez.comon S3 + CloudFront + API Gateway HTTP API + Lambda.- Routes:
POST /api/analyze(captured-mode parser+engine),POST /api/run(live runner),GET /api/health. /api/runis SSRF-guarded (blocks RFC1918, link-local incl. EC2 metadata, multicast, loopback; HTTPS-only) with a 10-second per-request timeout.- API Gateway throttling on
/api/run(2 req/sec sustained, burst 5) plus a $10/month AWS Budget with 50%/100%/forecast email alerts. - Lambda log group is stack-managed with 14-day retention.
- Same Report shape as the CLI and local web UI — byte-identical given the same input.
- Deploy via SAM, OIDC-based GitHub Actions role with least-privilege inline policy (committed at
deploy/iam/).
Added — Demo polish
- Client-side HAR stripping in three tiers (passthrough → strip request/response bodies → first-entry only) so 12 MB browser exports survive API Gateway's 10 MB body cap. UI banner explains what was dropped.
VITE_DEMO_MODE=1build path uses same-origin API base so CloudFront routes/api/*to the Lambda.
Added — Quality
- 311 Python tests + 60 frontend tests.
- CI matrix: 3 operating systems × 3 Python versions = 9 cells.
- 80% coverage gate on
core/checks. - Static-import audit (
tests/unit/test_lambda_imports.py) enforces Lambda dep boundaries — no fastapi/uvicorn/typer/rich, and explicit positive assertion that the Lambda surface DOES include the runner + SSRF guard so/api/runcan't silently regress. - Schema-sync gate: CI regenerates
frontend/src/lib/types.tsfrom Pydantic and fails if it differs from the committed file.
Added — Project
- 8 hand-crafted fixture reports covering distinct diagnostic scenarios; double as UI dev data, schema validation, and integration smoke tests.
- MIT license, public repo, full architecture spec at
docs/architecture.md.
Architectural decisions
- Stateless by design. No DynamoDB, no S3 writes for user data, no CloudWatch persistence beyond default logs.
- No FastAPI / uvicorn on Lambda. The Lambda dispatches routes inline via
lambda_handlerto keep cold-start budget intact even with the runner deps (httpx, dnspython, cryptography). - Same
Reportshape from every surface — the contract that makes the future browser extension a thin capture layer rather than a parallel implementation.