Skip to content
Open
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
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: CI

on:
pull_request:
paths-ignore:
- '**/*.md'
- 'docs/**'
push:
branches: [main]
paths-ignore:
- '**/*.md'
- 'docs/**'

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

jobs:
quality:
name: Typecheck
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: pnpm

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

- name: Typecheck
run: pnpm typecheck

unit:
name: Unit tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: pnpm

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

- name: Web tests
run: pnpm test:web

- name: CLI tests
run: pnpm test:cli
7 changes: 4 additions & 3 deletions src/app/api/macro/flat/data/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export async function GET() {
const buf = await getMacroFlatData();
if (!buf) return new NextResponse('Not found', { status: 404 });
// Cache binary strongly; it only changes when prep runs
return new NextResponse(buf, { status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=86400, immutable' } });
return new NextResponse(
new Blob([Uint8Array.from(buf)]),
{ status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=86400, immutable' } },
);
}


7 changes: 4 additions & 3 deletions src/app/api/macro/flat/models/[modelId]/data/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export async function GET(_: Request, ctx: { params: Promise<{ modelId: string }
const params = await ctx.params;
const buf = await getMacroPerModelData(params.modelId);
if (!buf) return new NextResponse('Not found', { status: 404 });
return new NextResponse(buf, { status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=86400, immutable' } });
return new NextResponse(
new Blob([Uint8Array.from(buf)]),
{ status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=86400, immutable' } },
);
}


7 changes: 4 additions & 3 deletions src/app/api/macro/tiles/[z]/[x]/[y]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export async function GET(_: Request, ctx: { params: Promise<{ z: string; x: str
const y = parseInt(params.y, 10);
const buf = await getMacroTile(z, x, y);
if (!buf) return new NextResponse('Not found', { status: 404 });
return new NextResponse(buf, { status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=31536000, immutable' } });
return new NextResponse(
new Blob([Uint8Array.from(buf)]),
{ status: 200, headers: { 'Content-Type': 'application/octet-stream', 'Cache-Control': 'public, max-age=31536000, immutable' } },
);
}


13 changes: 7 additions & 6 deletions src/app/api/sandbox/auto-wiki/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,14 @@ export async function POST(req: NextRequest) {
}

// wtf.fetch can return an array if it follows redirects, take the last one.
if (Array.isArray(doc)) {
doc = doc[doc.length - 1];
const article = Array.isArray(doc) ? doc[doc.length - 1] : doc;
if (!article) {
return NextResponse.json({ error: 'Could not resolve the Wikipedia article.' }, { status: 404 });
}

const articleText = doc.text();
const articleSummary = (doc as any).summary() || 'No summary available.';
const title = doc.title() || articleTitle;
const articleText = article.text();
const articleSummary = (article as any).summary() || 'No summary available.';
const title = article.title() || articleTitle;

if (!articleText || articleText.length < 100) {
return NextResponse.json({ error: 'The article content is too short to generate a meaningful blueprint.' }, { status: 400 });
Expand Down Expand Up @@ -200,4 +201,4 @@ export async function POST(req: NextRequest) {
console.error('[Auto-Wiki Error]', error);
return NextResponse.json({ error: 'An unexpected error occurred.', details: error.message }, { status: 500 });
}
}
}