AI Integration
ShipKit provides a comprehensive set of AI integration features to enhance development and user experience. This guide covers the AI components, utilities, and integration points available in the system.
Table of Contents
Quick Start
To get started with AI integration in your ShipKit project:
Install Dependencies
pnpm add @shipkit/ai-core @shipkit/ai-components
Configure AI Services
// src/config/ai.ts
export const aiConfig = {
openai: {
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4",
temperature: 0.7,
},
customModels: {
enabled: true,
endpoint: process.env.CUSTOM_MODEL_ENDPOINT,
},
};
Initialize AI Services
// src/lib/ai/init.ts
import { aiLoader, aiAnalyzer, aiAssistant } from "@shipkit/ai-core";
import { aiConfig } from "@/config/ai";
export function initAIServices() {
aiLoader.init(aiConfig);
aiAnalyzer.init(aiConfig);
aiAssistant.init(aiConfig);
}
Add Environment Variables
OPENAI_API_KEY=your-api-key
CUSTOM_MODEL_ENDPOINT=your-custom-endpoint
Architecture Overview
graph TD
A[Client Components] --> B[AI Integration Layer]
B --> C[AI Utilities]
C --> D[AI Loader]
C --> E[AI Analyzer]
C --> F[AI Assistant]
B --> G[External AI Services]
G --> H[OpenAI]
G --> I[Custom Models]
style A fill:#f9f,stroke:#333,stroke-width:2px
style B fill:#bbf,stroke:#333,stroke-width:2px
style C fill:#dfd,stroke:#333,stroke-width:2px
Component Flow
sequenceDiagram
participant U as User
participant C as Client Component
participant S as Server Action
participant AI as AI Service
U->>C: Input Text
C->>S: Send Request
S->>AI: Process Input
AI->>S: Return Response
S->>C: Update UI
C->>U: Show Result
Core AI Features
WWJHD (What Would Jesus Huang Do)
The WWJHD feature provides AI-powered assistance for development decisions:
// src/app/(app)/(ai)/wwjhd/page.tsx
import { WWJHDDemo } from "@/app/(app)/(ai)/wwjhd/_components/wwjhd-demo";
export default function Page() {
return (
<div className="flex min-h-screen items-center justify-center bg-gradient-to-b from-sky-300 to-sky-100">
<WWJHDDemo />
</div>
);
}
Type-Ahead AI
The type-ahead feature provides intelligent suggestions during typing:
// src/app/(app)/(ai)/type-ahead/page.tsx
"use client";
import AIEditor from "@/app/(app)/(ai)/type-ahead/_components/AIEditor";
export default function TypeAheadPage() {
return (
<div className="container mx-auto p-4">
<h1 className="mb-4 text-2xl font-bold">AI-Powered Document Editor</h1>
<AIEditor />
</div>
);
}
Spam Detection
AI-powered spam detection for content moderation:
// src/app/(app)/(ai)/is-spam/page.tsx
import { SpamDemo } from "@/app/(app)/(ai)/is-spam/_components/spam-demo";
export default function Page() {
return (
<>
<h1>Demo</h1>
<SpamDemo />
</>
);
}
AI Utilities
AI Loader
The AI Loader provides context about the project structure and conventions:
// src/lib/ai/ai-loader.ts
export interface AIContext {
projectName: string;
description: string;
version: string;
technologies: TechnologyStack;
structure: ProjectStructure;
conventions: {
files: string[];
components: string[];
database: string[];
api: string[];
};
routes: typeof routes;
config: typeof siteConfig;
}
/**
* AILoader provides context and information about the project to AI assistants
* to help them understand the codebase and make informed decisions.
*/
export class AILoader {
private context: AIContext;
constructor() {
this.context = {
projectName: "ShipKit",
description: "Production-ready SaaS starter kit built with Next.js",
version: "1.0.0",
technologies: {
framework: "Next.js (App Router)",
language: "TypeScript",
styling: ["Tailwind CSS", "CSS Modules"],
ui: ["Shadcn/UI", "Radix UI", "Lucide Icons"],
state: ["React Context", "Zustand"],
database: "PostgreSQL",
cms: "Payload CMS",
email: "Resend",
auth: "NextAuth/AuthJS",
packageManager: "pnpm"
},
// ... more configuration
};
}
}
AI Analyzer
The AI Analyzer helps understand and improve code quality:
// src/lib/ai/ai-analyzer.ts
export interface CodebaseInsights {
fileStructure: string[];
conventions: string[];
bestPractices: string[];
commonPatterns: string[];
keyConsiderations: string[];
}
/**
* AIAnalyzer helps AI assistants analyze and understand different aspects of the codebase
* to make better decisions and provide more accurate assistance.
*/
export class AIAnalyzer {
public getCodebaseInsights(): CodebaseInsights {
return {
fileStructure: [
"App Router's file-based routing system",
"Route groups for feature organization",
"Parallel routes for complex layouts",
"Intercepting routes for modals",
"Dynamic routes for data-driven pages",
],
conventions: [
"Server-first approach with React Server Components",
"Client components marked with 'use client'",
"Server actions for data mutations",
"Server-side data fetching in layout and page components",
"Component-level TypeScript types",
],
// ... more insights
};
}
}
AI Assistant
The AI Assistant provides implementation guidance:
// src/lib/ai/ai-assistant.ts
export interface ImplementationDecision {
approach: string;
reasoning: string[];
considerations: string[];
recommendations: string[];
pitfalls: string[];
}
/**
* AIAssistant helps make decisions about code implementation and provides
* guidance on best practices for the ShipKit codebase.
*/
export class AIAssistant {
private context = aiLoader.getContext();
private insights = aiAnalyzer.getCodebaseInsights();
public getImplementationGuidance(feature: string): ImplementationDecision {
return {
approach: "Server-first implementation with React Server Components",
reasoning: [
"Following established project patterns",
"Maintaining consistency with existing codebase",
"Optimizing for performance and maintainability",
"Ensuring type safety with TypeScript",
"Following Next.js best practices",
],
considerations: [
"Server vs client component trade-offs",
"Data fetching strategy",
"State management approach",
"Performance implications",
],
// ... more guidance
};
}
}
Integration Points
Component Integration
// Example of integrating AI features into components
"use client";
import { useState } from "react";
import { Input } from "@/components/ui/input";
import { LoadingSpinner } from "@/components/ui/loading-spinner";
import { SuggestionsList } from "@/components/ui/suggestions-list";
import { getAISuggestions } from "@/lib/ai/suggestions";
export const AIEnabledComponent = () => {
const [suggestions, setSuggestions] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const handleInput = async (value: string) => {
setLoading(true);
try {
const aiSuggestions = await getAISuggestions(value);
setSuggestions(aiSuggestions);
} catch (error) {
console.error('AI suggestion error:', error);
} finally {
setLoading(false);
}
};
return (
<div className="space-y-4">
<Input onChange={(e) => void handleInput(e.target.value)} />
{loading ? (
<LoadingSpinner />
) : (
<SuggestionsList suggestions={suggestions} />
)}
</div>
);
};
Server Integration
// Example of server-side AI integration
import { aiLoader } from "@/lib/ai/ai-loader";
import { aiAnalyzer } from "@/lib/ai/ai-analyzer";
import { aiAssistant } from "@/lib/ai/ai-assistant";
import { AIProcessingError } from "@/lib/ai/errors";
export async function processWithAI(input: string) {
try {
const aiContext = aiLoader.getContext();
const insights = aiAnalyzer.getCodebaseInsights();
const guidance = aiAssistant.getImplementationGuidance(input);
return {
success: true,
data: {
context: aiContext,
insights,
guidance,
},
};
} catch (error) {
console.error('AI processing error:', error);
if (error instanceof AIProcessingError) {
return {
success: false,
error: error.message,
code: error.code,
};
}
return {
success: false,
error: 'Failed to process with AI',
};
}
}
Best Practices
Data Flow
flowchart TD
A[User Input] --> B{Validate Input}
B -->|Valid| C[Process with AI]
B -->|Invalid| D[Return Error]
C --> E{Check Response}
E -->|Success| F[Transform Data]
E -->|Error| G[Handle Error]
F --> H[Return Response]
G --> I[Log Error]
I --> J[Return Error Response]
Error Handling Flow
flowchart TD
A[AI Request] --> B{Try Process}
B -->|Success| C[Return Result]
B -->|Error| D{Error Type}
D -->|AI Error| E[Handle AI Error]
D -->|Network| F[Handle Network Error]
D -->|Validation| G[Handle Validation Error]
E --> H[Return Error Response]
F --> H
G --> H
Performance
Use streaming for real-time suggestions
Implement proper caching
Handle rate limiting
Error Handling
try {
const result = await aiProcessor.process(input);
// Handle success
} catch (error) {
if (error instanceof AIProcessingError) {
// Handle AI-specific error
} else {
// Handle general error
}
}
Security
Validate AI inputs
Sanitize outputs
Implement access controls
Testing
Unit Tests
import { describe, it, expect } from "vitest";
import { AILoader } from "@/lib/ai/ai-loader";
import { AIAnalyzer } from "@/lib/ai/ai-analyzer";
describe('AIIntegration', () => {
it('should process input correctly', () => {
const aiLoader = new AILoader();
const context = aiLoader.getContext();
expect(context.projectName).toBe('ShipKit');
});
it('should handle errors gracefully', () => {
const aiAnalyzer = new AIAnalyzer();
const insights = aiAnalyzer.getCodebaseInsights();
expect(insights.conventions).toContain('Server-first approach with React Server Components');
});
});
Integration Tests
import { describe, it, expect } from "vitest";
import { render, screen } from "@testing-library/react";
import { AIAssistant } from "@/lib/ai/ai-assistant";
import { AIEnabledComponent } from "@/components/ai/ai-enabled-component";
describe('AIFeatures', () => {
it('should provide accurate suggestions', async () => {
const aiAssistant = new AIAssistant();
const guidance = await aiAssistant.getImplementationGuidance('feature');
expect(guidance.approach).toBeDefined();
});
it('should integrate with components', () => {
render(<AIEnabledComponent />);
expect(screen.getByRole('textbox')).toBeInTheDocument();
});
});
Customization
Adding New AI Features
export const NewAIFeature = () => {
const aiAssistant = new AIAssistant();
const guidance = aiAssistant.getImplementationGuidance('newFeature');
return (
<div className="container mx-auto py-8">
<h1 className="mb-6 text-2xl font-bold">New AI Feature</h1>
<pre>{JSON.stringify(guidance, null, 2)}</pre>
</div>
);
};
Extending AI Utilities
export class CustomAIAnalyzer extends AIAnalyzer {
public getCustomInsights(): CodebaseInsights {
const baseInsights = super.getCodebaseInsights();
return {
...baseInsights,
customPatterns: [
"Custom implementation patterns",
"Project-specific conventions",
],
};
}
}
Configuration
const aiConfig = {
model: "gpt-4",
temperature: 0.7,
maxTokens: 1000,
// ... more configuration options
};
Integration Architecture
graph LR
A[Components] --> B[AI Integration]
B --> C[AI Loader]
B --> D[AI Analyzer]
B --> E[AI Assistant]
subgraph AI Services
F[OpenAI]
G[Custom Models]
H[Vector DB]
end
B --> AI Services
style A fill:#f9f,stroke:#333,stroke-width:2px
style B fill:#bbf,stroke:#333,stroke-width:2px
style C,D,E fill:#dfd,stroke:#333,stroke-width:2px
Interactive Examples
WWJHD Demo
The WWJHD demo can be tested using the following steps:
Navigate to /wwjhd
in your browser
Enter a development question in the textarea
Click the submit button
Verify that:
Loading state is shown during processing
Response is displayed in the designated area
Error handling works when API is unavailable
// Test the WWJHD component
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { WWJHDDemo } from "@/app/(app)/(ai)/wwjhd/_components/wwjhd-demo";
describe("WWJHDDemo", () => {
it("should handle form submission", async () => {
render(<WWJHDDemo />);
const textarea = screen.getByRole("textbox");
const submitButton = screen.getByRole("button");
fireEvent.change(textarea, {
target: { value: "How should I structure my Next.js app?" }
});
fireEvent.click(submitButton);
await waitFor(() => {
expect(screen.getByText(/loading/i)).toBeInTheDocument();
});
});
});
Type-Ahead Editor
The AI-powered editor can be tested with these steps:
Navigate to /type-ahead
in your browser
Start typing in the editor
Wait for suggestions to appear (500ms debounce)
Press Tab to accept suggestions
Verify that:
Suggestions appear after typing
Tab key accepts suggestions
Error states are handled properly
// Test the AI Editor component
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import AIEditor from "@/app/(app)/(ai)/type-ahead/_components/AIEditor";
describe("AIEditor", () => {
it("should handle text input and suggestions", async () => {
render(<AIEditor />);
const textarea = screen.getByRole("textbox");
fireEvent.change(textarea, {
target: { value: "const component" }
});
await waitFor(() => {
expect(screen.getByText(/suggestion/i)).toBeInTheDocument();
});
fireEvent.keyDown(textarea, { key: "Tab" });
});
});
Spam Detection
The spam detection demo can be tested following these steps:
Navigate to /is-spam
in your browser
Enter text to analyze in the form
Submit the form
Verify that:
Form validation works
Loading state is shown
Results are displayed correctly
Error states are handled
// Test the Spam Detection component
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import { SpamDemo } from "@/app/(app)/(ai)/is-spam/_components/spam-demo";
describe("SpamDemo", () => {
it("should handle form submission and validation", async () => {
render(<SpamDemo />);
const textarea = screen.getByRole("textbox");
const submitButton = screen.getByRole("button");
// Test empty submission
fireEvent.click(submitButton);
expect(screen.getByText(/please enter/i)).toBeInTheDocument();
// Test valid submission
fireEvent.change(textarea, {
target: { value: "This is a test message" }
});
fireEvent.click(submitButton);
await waitFor(() => {
expect(screen.getByText(/result/i)).toBeInTheDocument();
});
});
});
Running the Tests
To run the interactive example tests:
# Run all tests
pnpm test
# Run specific test file
pnpm test wwjhd-demo.test.tsx
pnpm test ai-editor.test.tsx
pnpm test spam-demo.test.tsx
# Run tests in watch mode
pnpm test:watch
Common Issues and Solutions
API Connection Issues
// Mock API responses for testing
import { rest } from "msw";
import { setupServer } from "msw/node";
const server = setupServer(
rest.post("/wwjhd/api", (req, res, ctx) => {
return res(ctx.json({ response: "Test response" }));
}),
rest.post("/type-ahead/api", (req, res, ctx) => {
return res(ctx.json({ suggestion: "Test suggestion" }));
}),
rest.post("/is-spam/api", (req, res, ctx) => {
return res(ctx.json({ isSpam: false }));
})
);
Form Validation
// Test form validation
it("should validate required fields", async () => {
render(<SpamDemo />);
const submitButton = screen.getByRole("button");
fireEvent.click(submitButton);
await waitFor(() => {
expect(screen.getByText(/required/i)).toBeInTheDocument();
});
});
Error Handling
// Test error handling
it("should handle API errors", async () => {
server.use(
rest.post("/api/endpoint", (req, res, ctx) => {
return res(ctx.status(500));
})
);
render(<Component />);
// ... test error state
});
Feedback and Contributions
Providing Feedback
We welcome feedback from the team to improve our AI integration. Please use the following channels:
GitHub Issues
Use the issue template for AI-related feedback
Label issues with ai-integration
Include specific examples when possible
Pull Requests
Discussion Forums
Feedback Template
When providing feedback, please include:
## Component/Feature
[Specify the AI component or feature]
## Type
- [ ] Bug Report
- [ ] Enhancement Request
- [ ] Documentation Improvement
- [ ] Performance Issue
- [ ] Security Concern
## Description
[Detailed description of the feedback]
## Expected Behavior
[What you expected to happen]
## Current Behavior
[What actually happened]
## Steps to Reproduce
1. [First Step]
2. [Second Step]
3. [Additional Steps...]
## Environment
- Node.js Version: [e.g., 18.17.0]
- Next.js Version: [e.g., 14.0.3]
- Browser: [e.g., Chrome 119]
- OS: [e.g., macOS 14.0]
## Additional Context
[Any other context, screenshots, or code examples]
Review Process
Initial Review
Technical accuracy
Code quality
Documentation clarity
Performance impact
Security implications
Team Discussion
Weekly sync meetings
Async discussions in GitHub
Architecture reviews
Performance reviews
Implementation Planning
Prioritize feedback
Create action items
Assign owners
Set timelines
Feedback Categories
Technical Implementation
Code structure
Performance optimization
Error handling
Testing coverage
User Experience
Interface design
Response times
Error messages
Accessibility
Documentation
Clarity
Completeness
Examples
Troubleshooting
Security
Input validation
Output sanitization
API security
Rate limiting
Integration Points Feedback
Please provide specific feedback on:
AI Loader
Project structure detection
Configuration management
Performance impact
Error handling
AI Analyzer
Code analysis accuracy
Performance metrics
Resource usage
Integration points
AI Assistant
Suggestion quality
Response times
Error handling
User experience
Next Steps
After feedback is collected:
Review and Prioritize
Assess impact
Evaluate effort
Consider dependencies
Plan implementation
Implementation
Create tasks
Assign resources
Set deadlines
Track progress
Validation
Test changes
Review documentation
Gather user feedback
Monitor metrics