fix: fast node creation, first-run modal, simplified docs

- Skip AI calls when no valid OpenAI key (fixes 9-13s timeout)
- Add first-run modal prompting for API key
- Rewrite README for first-time users
- Add /api/health endpoint
- Remove all Anthropic references (not used in OS)
- Fix bootstrap script (dev:local → dev)
- Fix next.config.js devIndicators warning
- Add Node 18+ version check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-02-02 15:10:46 +11:00
co-authored by Claude Opus 4.5
parent 38386afea4
commit 7beba57f63
13 changed files with 616 additions and 389 deletions
+10
View File
@@ -1,6 +1,7 @@
import { getSQLiteClient } from './sqlite-client';
import { openai as openaiProvider } from '@ai-sdk/openai';
import { generateText } from 'ai';
import { hasValidOpenAiKey } from './descriptionService';
export interface Dimension {
name: string;
@@ -48,6 +49,9 @@ export class DimensionService {
/**
* Automatically assign locked dimensions + suggest keyword dimensions
* Returns { locked: string[], keywords: string[] }
*
* IMPORTANT: Returns empty result immediately if no valid API key is configured.
* This prevents slow node creation when OpenAI is unavailable.
*/
static async assignDimensions(nodeData: {
title: string;
@@ -55,6 +59,12 @@ export class DimensionService {
link?: string;
description?: string;
}): Promise<{ locked: string[]; keywords: string[] }> {
// Fast path: skip AI if no valid API key
if (!hasValidOpenAiKey()) {
console.log(`[DimensionAssignment] No valid OpenAI key, skipping for: "${nodeData.title}"`);
return { locked: [], keywords: [] };
}
try {
const lockedDimensions = await this.getLockedDimensions();