Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
pull_request:
push:
branches:
- main

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Install Chromium
run: bunx playwright install --with-deps chromium

- name: Lint
run: bun run lint

- name: Check formatting
run: bun run prettier:check

- name: Typecheck
run: bun run typecheck

- name: Run unit tests
run: bun test

- name: Run end-to-end tests
run: bun run test:e2e

- name: Build
run: bun run build
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Dependencies
node_modules/

# Build output
.next/
.turbo/
dist/
out/

# Test output
playwright-report/
test-results/
coverage/

# Local configuration
.env
.env.*
!.env.example

# Editors and operating systems
.DS_Store
*.swp
*.tsbuildinfo
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.next
.turbo
bun.lock
coverage
node_modules
playwright-report
test-results
4 changes: 4 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"plugins": [],
"proseWrap": "preserve"
}
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Repository instructions

- Run `bun run lint` and `bun run prettier:check` after making changes.
- Use kebab-case for project filenames unless a framework requires a conventional filename.
- Use `motion`, not `framer-motion`.
- Use inline function parameter types instead of isolated parameter interfaces.
- Add or update tests with every code change: unit tests for utilities and E2E tests for product features.
- Run `bun test` and `bun run test:e2e` before completing work.
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# hooky
A durable webhook inbox and local development relay.
# Hooky

Hooky is a durable webhook inbox and local development relay. It stores incoming webhooks in the cloud and delivers them when a developer's local environment is ready—without exposing localhost to the public internet.

The product plan and implementation decisions live in [PRD issue #1](https://github.com/dak-engineering/hooky/issues/1).

## Repository

This Bun workspace currently contains the Next.js web application in `apps/web`. Additional database, relay-core, shared, CLI, and test-support packages will be introduced with the vertical slices that need them.

## Development

Install dependencies and start the web application:

```bash
bun install
bun run dev
```

The application runs at [http://localhost:3000](http://localhost:3000), with its health endpoint at [http://localhost:3000/api/health](http://localhost:3000/api/health).

## Validation

```bash
bun run lint
bun run prettier:check
bun run typecheck
bun test
bun run test:e2e
bun run build
```
9 changes: 9 additions & 0 deletions apps/web/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- BEGIN:nextjs-agent-rules -->

# This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.

<!-- END:nextjs-agent-rules -->
1 change: 1 addition & 0 deletions apps/web/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
9 changes: 9 additions & 0 deletions apps/web/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";

export default defineConfig([
...nextVitals,
...nextTs,
globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
]);
7 changes: 7 additions & 0 deletions apps/web/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";
import "./.next/types/root-params.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
7 changes: 7 additions & 0 deletions apps/web/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
reactStrictMode: true,
};

export default nextConfig;
26 changes: 26 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@hooky/web",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "next build",
"dev": "next dev",
"lint": "eslint .",
"start": "next start",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"next": "16.3.0",
"react": "19.2.8",
"react-dom": "19.2.8"
},
"devDependencies": {
"@types/bun": "1.3.14",
"@types/node": "^20.19.32",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"eslint": "^9.39.2",
"eslint-config-next": "16.3.0",
"typescript": "^5.9.3"
}
}
15 changes: 15 additions & 0 deletions apps/web/src/app/api/health/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { describe, expect, test } from "bun:test";

import { GET } from "./route";

describe("health endpoint", () => {
test("reports that the web service is ready", async () => {
const response = GET();

expect(response.status).toBe(200);
expect(await response.json()).toEqual({
service: "hooky-web",
status: "ok",
});
});
});
6 changes: 6 additions & 0 deletions apps/web/src/app/api/health/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function GET() {
return Response.json({
service: "hooky-web",
status: "ok",
});
}
Loading
Loading