- Added TestServerConfigurations for server setup verification
- Added TestMultipleEndpointsConcurrency for concurrent access testing
- Added TestErrorHandling for error scenarios (invalid JSON, missing endpoints, invalid replay IDs)
These tests verify the CLI server behavior through integration testing
rather than unit testing the main function directly.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add .golangci.yml with sensible linting rules
- Add Makefile with test, lint, fmt, vet, build targets
- Enhance CI pipeline with Go formatting check and golangci-lint job
- Create shared testutil.FakeRepository for handler tests
- Refactor handler tests to use shared FakeRepository
- Add data/ and coverage.out to .gitignore
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Create static site structure in site/ directory
- Add landing page, blog index, and first blog post
- Include Open Graph meta tags for social sharing
- Add GitHub Actions workflow for GitHub Pages deployment
- Include brand assets (OG image, favicon)
- Add README with setup and DNS instructions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add v1 JSON API endpoints alongside existing HTML endpoints:
- POST /v1/endpoints/{id}/requests: Capture JSON request
- GET /v1/endpoints/{id}/requests: List or search requests
- POST /v1/endpoints/{id}/requests/{reqId}/replay: Replay captured request
- PUT /v1/endpoints/{id}/mock: Set mock configuration
- GET /v1/endpoints/{id}/openapi.json: OpenAPI 3.1 specification
Add SearchRequests to Repository interface and implement simple LIKE search.
Write integration tests for all v1 endpoints. Ensure backward compatibility
with existing HTML endpoints.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Replace Apache-2.0 LICENSE with MIT full text (Copyright (c) 2026 El Foundation)
- README License section: 'Hatch is released under the MIT License' with link to LICENSE
- ADR-0002: mark license decision superseded by CEO (ELF-141), preserve Apache-2.0 reasoning as history, update rollback note (MIT->Apache-2.0 compatible upgrade)
Closes ELF-149
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Integrate the full Hatch v0.1 product (capture, inspect, SSE, mock, replay,
SQLite store, E2E smoke test) with the migration branch's docs/license
realignment (Apache-2.0 LICENSE, ADR-0002, clean README layout).
This produces a single launch-ready HEAD where the three Show HN demo bullets
are true and the repo carries an Apache-2.0 license.
Conflict resolution:
- cmd/hatch/main.go, cmd/hatch/main_test.go, go.mod: took replay (integrated
chi router + handler routes + deps). Migration's foundation-only main.go
and dep-less go.mod are superseded.
- .gitignore: took replay (narrowed /hatch to avoid matching cmd/hatch/).
- README.md: took migration (clean Repository Layout, Apache-2.0 license
section). Replay's stale "Proprietary — All rights reserved" + apps/packages
layout dropped.
- go.sum: auto-merged.
- brand/, internal/, docs/adrs/0002: brought in from replay / migration as
non-conflicting additions.
Verified on merged HEAD:
- go test ./... — all pass
- go test ./cmd/hatch -run TestSmokeE2E — all 7 phases pass
- docker compose up --build — container runs; healthz/capture/inspect/mock
all 200; mock returns configured status + body + content-type
CTO engineering sign-off for ELF-57: GO on this HEAD.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
TestSmokeE2E starts a real server and exercises the full product flow:
- Phase 1: Health check (liveness probe)
- Phase 2: Capture all 5 HTTP methods, verify stored
- Phase 3: Inspect page renders HTML with request cards, replay UI, SSE script
- Phase 4: SSE stream receives live events on capture
- Phase 5: Mock configuration and response (set mock → capture returns mock)
- Phase 6: Replay a captured request to a sink server
- Phase 7: Edge cases (query params, binary body, SSRF protection)
The one-command gate: go test ./cmd/hatch -run TestSmokeE2E -v
Also fix .gitignore: the bare 'hatch' entry was matching cmd/hatch/
directory, preventing test files from being tracked. Narrowed to /hatch
(root binary only) and hatch.exe.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Added TestMockSetsAndConfiguresResponse: verifies PUT /e/{id}/mock stores mock config
- Added TestMockReturnsConfiguredResponseOnCapture: verifies capture returns mock response
when one is configured, and the request is still recorded
- Added TestMockAutoCreatesEndpointOnSet: verifies mock endpoint auto-creates if missing
- Fixed TestHealthzSmoke to use t.Setenv instead of os.Setenv to prevent env leak
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add formatTime template func for human-readable timestamps (just now, 2m ago, etc.)
- Add client-side formatTimeStr for SSE live-update timestamps
- Fix SSE body rendering: buildRequestBody() populates headers/query/body for live-added requests
- Fix SSE body encoding: use string in sseRequest to avoid base64 encoding of []byte
- Add inspect handler tests: renders HTML, empty state, auto-creates endpoint
- Timestamps include title attr with full ISO timestamp for hover detail
Without flusher.Flush() after WriteHeader, the HTTP response headers
were buffered and never sent to the client, causing SSE clients to hang
indefinitely waiting for the initial response.
- Add flusher.Flush() after WriteHeader in HandleSSE
- Add TestSSEStreamReceivesEventOnCapture integration test:
starts test server, subscribes to SSE, captures a request, and
verifies the event arrives within 2s
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add POST /e/{endpoint}/requests/{id}/replay endpoint
- Replay re-sends captured method, path, headers, query, body to target URL
- Response includes target status code, headers, body (truncated 64KB)
- SSRF guard: denies replay to private/loopback by default
- Opt-in env var HATCH_ALLOW_PRIVATE_REPLAY=true for local dev
- Server-rendered inspect page at GET /e/{endpoint} with replay button UI
- SSE live stream for new requests (EventSource)
- Mock configuration at PUT /e/{endpoint}/mock
- Store: GetRequest, GetMock, SetMock methods added
- Chi router migration from stdlib ServeMux
- 26 passing tests including replay unit tests and E2E capture-to-replay
Co-Authored-By: Paperclip <noreply@paperclip.ing>
v1 brand kit for the Hatch launch (ELF-53).
Files:
brand/wordmark/ - text+mark wordmark (SVG with embedded Inter Bold,
plus PNG exports at 200x60, 400x120, 800x240,
1200x360); light/dark and on-light/on-dark variants
brand/mark/ - the icon alone, in 16/32/48/64/128/192/256/512/1024
brand/favicon/ - favicon.ico (16+32+48) and the 5 required PNG sizes
brand/banner/ - README banner at 1280x640 (+ @2x retina)
brand/og/ - OG image at 1200x630 (+ @2x retina)
docs/brand/usage.md - one-pager on spacing, clear space, do-not rules,
light/dark mode behavior
Concept:
Mark is a rounded square with a horizontal slot — the literal "hatch".
A small "request" indicator drops into the slot. At 16px the slot still
reads; at 512px the proportions hold.
Type:
Inter Bold for the wordmark; JetBrains Mono for the code/tagline accent.
Both SIL OFL 1.1, attributed in docs/brand/usage.md.
Color:
Ink #0A0A0B, Paper #FAFAF9, Accent #F59E0B. No other colors in the kit.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Adds docs/marketing/community-listening-week1.md per ELF-51.
10 HN threads (requestbin / ngrok / self-hosted / single-binary Go)
with one-line engagement plans and explicit no-go lines.
Reddit half is deferred to ELF-58 because the JSON listing endpoint
was blocked by the network policy at draft time.
Reviewer: Head of Marketing.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Migration commit for the ELF-15 atomic PR. Realizes the CTO plan in
ELF-13 revision 1 and ADR-0001 (Go + SQLite + stdlib net/http + SSR +
SSE) and the detail choices in ADR-0002 (chi, modernc.org/sqlite, html/
template, stdlib testing, Apache-2.0).
Docs:
- docs/engineering/tech-stack.md rewritten for Go + SQLite + stdlib
net/http + SSR + SSE. Frontend is server-rendered HTML + a little
vanilla JS. Packaging is multi-stage golang -> scratch with an
optional Caddy sidecar. Boring-technology principle kept.
- docs/engineering/first-engineer-role.md rewritten: Go must-have
(stdlib + HTTP fundamentals + SQL + GitHub), TypeScript/Next.js/
Prisma/PostgreSQL moved to nice-to-have or deferred. Tailwind and
monorepo tooling explicitly deferred.
- docs/engineering/onboarding.md: pnpm install / pnpm dev replaced
with go test ./... and go run ./cmd/hatch. New step: read local-dev
and hatch-architecture on day 1.
- docs/engineering/local-dev.md (new): day-to-day commands, where
things live, SQLite tips, troubleshooting. Living doc, engineer owns.
- docs/engineering/hatch-architecture.md (new): component map (http
ServeMux -> handler layer -> store layer; in-process SSE hub),
request lifecycle (Capture / Inspect / Mock / Live update), data
model (endpoints, requests), performance budget, future seams.
- docs/adrs/0002-hatch-detail-stack.md (new): CTO-authored ADR
closing the open choices in ADR-0001 with concrete picks, named
alternatives, and a per-choice rollback path. Router: go-chi/chi.
SQLite driver: modernc.org/sqlite (pure Go, no CGO). Templates:
stdlib html/template + //go:embed. Tests: stdlib testing + httptest.
License: Apache-2.0.
Housekeeping:
- README.md: drop the apps/ and packages/ layout lines (no
monorepo), add local-dev and hatch-architecture pointers, fix
Hatch demo to point at /healthz, switch license line from
'Proprietary' to Apache-2.0 with a LICENSE file pointer.
- CONTRIBUTING.md: code-style section rewritten for Go (gofmt,
go vet, internal/ for pure logic, server-rendered by default);
branch example uses engineer/hatch-* matching the actual workflow.
- LICENSE: full Apache-2.0 text, copyright El Foundation 2026.
Per ADR-0002.
- .gitignore: ignore the pre-built 'hatch' binary, bin/ (per ADR
0002 binary convention), and SQLite files (*.db, *.db-journal,
*.db-wal, *.db-shm).
Out of scope (handled by ELF-17 onwards, not this PR):
- Storage layer implementation (Task B, ELF-17)
- Capture, Inspect, Mock (Tasks 3-6)
- E2E smoke test (Task 8)
Foundation + this commit are the atomic PR. CI is green (go vet,
go test ./... -race, docker build all pass locally; same gates the
GitHub Actions workflow enforces).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Set go directive to 1.25.0 (matches Docker golang:1.25-alpine)
- Track go.sum (empty — zero external dependencies for bootstrap)
- Fixes Docker build: COPY go.mod go.sum now finds both files
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The bootstrap module has zero external dependencies (stdlib only).
The previous commit accidentally included indirect deps from the storage
layer work (modernc.org/sqlite, google/uuid) that do not belong in the
bootstrap task.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Go module (github.com/elfoundation/hatch) with go 1.25
- cmd/hatch: HTTP server with GET /healthz returning 200 OK
- Multi-stage Dockerfile producing static binary from scratch
- docker-compose with hatch + optional Caddy reverse proxy
- CI placeholder with Go test/lint stubs
- .gitignore, .dockerignore, .env.example
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Use URL as endpoint ID so handler path-segment lookups resolve correctly.
Previously CreateEndpoint generated a random UUID for the ID, but the
handler always queries by the path segment — every GetEndpoint call
missed, causing duplicate UNIQUE violations on subsequent requests
and orphaned request records (endpoint_id mismatch).
- Register both /{endpoint} and /{endpoint}/ patterns so bare and
nested capture paths both route to the handler (Go 1.22+ ServeMux).
- Strip query string in extractID for robustness, even though the
library never sends ? in r.URL.Path.
- Remove unused net/http import from handler_test.go (caught by vet).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Go module (github.com/elfoundation/hatch) with go 1.25
- cmd/hatch: HTTP server with GET /healthz returning 200 OK
- Multi-stage Dockerfile producing static binary from scratch
- docker-compose with hatch + optional Caddy reverse proxy
- CI placeholder with Go test/lint stubs
- .gitignore, .dockerignore, .env.example
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Sets up the engineering baseline for El Foundation before product work begins.
- README.md: project overview and repo layout
- CONTRIBUTING.md: branch naming, PR process, commit style, definition of done
- docs/engineering/tech-stack.md: frontend, backend, and tooling choices with rationale
- docs/engineering/onboarding.md: 30-day onboarding checklist
- docs/adrs/adr-template.md: decision record template
- .github/workflows/ci.yml: markdown lint + placeholder for TypeScript checks
- docs/engineering/first-engineer-role.md: scope, skills, 30-day priorities, hire recommendation
Co-Authored-By: Paperclip <noreply@paperclip.ing>