claudeship 0.2.24 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/server/dist/chat/chat.module.js +8 -1
- package/apps/server/dist/chat/chat.module.js.map +1 -1
- package/apps/server/dist/chat/chat.service.d.ts +5 -1
- package/apps/server/dist/chat/chat.service.js +35 -4
- package/apps/server/dist/chat/chat.service.js.map +1 -1
- package/apps/server/dist/chat/framework-detector.service.d.ts +17 -0
- package/apps/server/dist/chat/framework-detector.service.js +193 -0
- package/apps/server/dist/chat/framework-detector.service.js.map +1 -0
- package/apps/server/dist/chat/prompts/backend/django.d.ts +1 -0
- package/apps/server/dist/chat/prompts/backend/django.js +207 -0
- package/apps/server/dist/chat/prompts/backend/django.js.map +1 -0
- package/apps/server/dist/chat/prompts/backend/express.d.ts +1 -0
- package/apps/server/dist/chat/prompts/backend/express.js +260 -0
- package/apps/server/dist/chat/prompts/backend/express.js.map +1 -0
- package/apps/server/dist/chat/prompts/backend/fastapi.d.ts +1 -0
- package/apps/server/dist/chat/prompts/backend/fastapi.js +246 -0
- package/apps/server/dist/chat/prompts/backend/fastapi.js.map +1 -0
- package/apps/server/dist/chat/prompts/backend/index.d.ts +4 -0
- package/apps/server/dist/chat/prompts/backend/index.js +12 -0
- package/apps/server/dist/chat/prompts/backend/index.js.map +1 -0
- package/apps/server/dist/chat/prompts/backend/nestjs.d.ts +1 -0
- package/apps/server/dist/chat/prompts/backend/nestjs.js +270 -0
- package/apps/server/dist/chat/prompts/backend/nestjs.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/expo.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/expo.js +208 -0
- package/apps/server/dist/chat/prompts/frontend/expo.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/flutter.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/flutter.js +271 -0
- package/apps/server/dist/chat/prompts/frontend/flutter.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/index.d.ts +4 -0
- package/apps/server/dist/chat/prompts/frontend/index.js +12 -0
- package/apps/server/dist/chat/prompts/frontend/index.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/nextjs.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/nextjs.js +195 -0
- package/apps/server/dist/chat/prompts/frontend/nextjs.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/react-native.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/react-native.js +224 -0
- package/apps/server/dist/chat/prompts/frontend/react-native.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/react-vite.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/react-vite.js +187 -0
- package/apps/server/dist/chat/prompts/frontend/react-vite.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/svelte.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/svelte.js +255 -0
- package/apps/server/dist/chat/prompts/frontend/svelte.js.map +1 -0
- package/apps/server/dist/chat/prompts/frontend/vue.d.ts +1 -0
- package/apps/server/dist/chat/prompts/frontend/vue.js +267 -0
- package/apps/server/dist/chat/prompts/frontend/vue.js.map +1 -0
- package/apps/server/dist/chat/prompts/index.d.ts +4 -0
- package/apps/server/dist/chat/prompts/index.js +20 -1
- package/apps/server/dist/chat/prompts/index.js.map +1 -1
- package/apps/server/dist/chat/prompts/prompt-builder.service.d.ts +15 -0
- package/apps/server/dist/chat/prompts/prompt-builder.service.js +177 -0
- package/apps/server/dist/chat/prompts/prompt-builder.service.js.map +1 -0
- package/apps/server/dist/chat/prompts/sections/core.d.ts +9 -0
- package/apps/server/dist/chat/prompts/sections/core.js +149 -0
- package/apps/server/dist/chat/prompts/sections/core.js.map +1 -0
- package/apps/server/dist/project/project.controller.d.ts +6 -0
- package/apps/server/dist/project/project.service.d.ts +6 -0
- package/apps/server/dist/tsconfig.tsbuildinfo +1 -1
- package/apps/server/package.json +1 -1
- package/apps/server/prisma/dev.db +0 -0
- package/apps/server/prisma/migrations/20260127071040_add_frontend_framework/migration.sql +24 -0
- package/apps/server/prisma/migrations/20260127071520_add_app_type_and_mobile/migration.sql +25 -0
- package/apps/server/prisma/schema.prisma +33 -5
- package/apps/web/.next/BUILD_ID +1 -1
- package/apps/web/.next/app-build-manifest.json +5 -3
- package/apps/web/.next/build-manifest.json +2 -2
- package/apps/web/.next/cache/.previewinfo +1 -1
- package/apps/web/.next/cache/.rscinfo +1 -1
- package/apps/web/.next/cache/.tsbuildinfo +1 -1
- package/apps/web/.next/cache/config.json +3 -3
- package/apps/web/.next/cache/eslint/.cache_j3uhuz +1 -1
- package/apps/web/.next/cache/webpack/client-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/client-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/0.pack +0 -0
- package/apps/web/.next/cache/webpack/server-production/index.pack +0 -0
- package/apps/web/.next/prerender-manifest.json +3 -3
- package/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/_not-found.html +1 -1
- package/apps/web/.next/server/app/_not-found.rsc +2 -2
- package/apps/web/.next/server/app/index.html +1 -1
- package/apps/web/.next/server/app/index.rsc +3 -3
- package/apps/web/.next/server/app/page.js +2 -2
- package/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/project/[id]/page.js +2 -2
- package/apps/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/settings/page.js +1 -1
- package/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/apps/web/.next/server/app/settings.html +1 -1
- package/apps/web/.next/server/app/settings.rsc +2 -2
- package/apps/web/.next/server/pages/404.html +1 -1
- package/apps/web/.next/server/pages/500.html +1 -1
- package/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/apps/web/.next/static/chunks/18-22b1cf4231121555.js +1 -0
- package/apps/web/.next/static/chunks/app/page-6ea560755549086e.js +1 -0
- package/apps/web/.next/static/chunks/app/project/[id]/page-3e4777b355c4aec9.js +1 -0
- package/apps/web/.next/static/css/45ddb08a7b4470d5.css +3 -0
- package/apps/web/.next/trace +18 -18
- package/apps/web/package.json +1 -1
- package/apps/web/src/app/page.tsx +2 -5
- package/apps/web/src/components/project/CreateProjectModal.tsx +175 -80
- package/apps/web/src/components/project/ProjectCard.tsx +122 -31
- package/apps/web/src/stores/useProjectStore.ts +2 -1
- package/package.json +1 -1
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/types/project.ts +18 -3
- package/packages/shared/src/types/tech-stack.ts +74 -0
- package/apps/web/.next/static/chunks/app/page-f73b6424c8cbf96d.js +0 -1
- package/apps/web/.next/static/chunks/app/project/[id]/page-e9304c25ba897608.js +0 -1
- package/apps/web/.next/static/css/70f2a13cf3d254d8.css +0 -3
- /package/apps/web/.next/static/{fQQI0X4R8kXYUbd-0V8mo → IMWKpuHss3gLOeJ7K93sg}/_buildManifest.js +0 -0
- /package/apps/web/.next/static/{fQQI0X4R8kXYUbd-0V8mo → IMWKpuHss3gLOeJ7K93sg}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FLUTTER_PROMPT = void 0;
|
|
4
|
+
exports.FLUTTER_PROMPT = `## Flutter Development Guide
|
|
5
|
+
|
|
6
|
+
### Project Structure
|
|
7
|
+
|
|
8
|
+
\`\`\`
|
|
9
|
+
frontend/
|
|
10
|
+
├── lib/
|
|
11
|
+
│ ├── main.dart # Entry point
|
|
12
|
+
│ ├── app.dart # App widget with routing
|
|
13
|
+
│ ├── screens/ # Screen widgets
|
|
14
|
+
│ │ ├── home_screen.dart
|
|
15
|
+
│ │ └── profile_screen.dart
|
|
16
|
+
│ ├── widgets/ # Reusable widgets
|
|
17
|
+
│ │ ├── common/ # Generic widgets
|
|
18
|
+
│ │ └── features/ # Feature-specific widgets
|
|
19
|
+
│ ├── models/ # Data models
|
|
20
|
+
│ ├── services/ # API, storage services
|
|
21
|
+
│ ├── providers/ # State management
|
|
22
|
+
│ ├── utils/ # Utilities
|
|
23
|
+
│ └── constants/ # App constants
|
|
24
|
+
├── assets/ # Images, fonts
|
|
25
|
+
├── android/ # Android config
|
|
26
|
+
├── ios/ # iOS config
|
|
27
|
+
├── pubspec.yaml # Dependencies
|
|
28
|
+
└── analysis_options.yaml # Lint rules
|
|
29
|
+
\`\`\`
|
|
30
|
+
|
|
31
|
+
### Essential Dependencies (pubspec.yaml)
|
|
32
|
+
|
|
33
|
+
\`\`\`yaml
|
|
34
|
+
dependencies:
|
|
35
|
+
flutter:
|
|
36
|
+
sdk: flutter
|
|
37
|
+
go_router: ^14.0.0 # Navigation
|
|
38
|
+
provider: ^6.1.0 # State management
|
|
39
|
+
dio: ^5.4.0 # HTTP client
|
|
40
|
+
flutter_riverpod: ^2.5.0 # Alternative state management
|
|
41
|
+
freezed_annotation: ^2.4.0 # Immutable models
|
|
42
|
+
json_annotation: ^4.8.0 # JSON serialization
|
|
43
|
+
|
|
44
|
+
dev_dependencies:
|
|
45
|
+
flutter_test:
|
|
46
|
+
sdk: flutter
|
|
47
|
+
flutter_lints: ^4.0.0
|
|
48
|
+
build_runner: ^2.4.0
|
|
49
|
+
freezed: ^2.4.0
|
|
50
|
+
json_serializable: ^6.7.0
|
|
51
|
+
\`\`\`
|
|
52
|
+
|
|
53
|
+
### App Entry Point
|
|
54
|
+
|
|
55
|
+
\`\`\`dart
|
|
56
|
+
// lib/main.dart
|
|
57
|
+
import 'package:flutter/material.dart';
|
|
58
|
+
import 'package:provider/provider.dart';
|
|
59
|
+
import 'app.dart';
|
|
60
|
+
import 'providers/auth_provider.dart';
|
|
61
|
+
|
|
62
|
+
void main() {
|
|
63
|
+
runApp(
|
|
64
|
+
MultiProvider(
|
|
65
|
+
providers: [
|
|
66
|
+
ChangeNotifierProvider(create: (_) => AuthProvider()),
|
|
67
|
+
],
|
|
68
|
+
child: const MyApp(),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
\`\`\`
|
|
73
|
+
|
|
74
|
+
### Navigation with go_router
|
|
75
|
+
|
|
76
|
+
\`\`\`dart
|
|
77
|
+
// lib/app.dart
|
|
78
|
+
import 'package:flutter/material.dart';
|
|
79
|
+
import 'package:go_router/go_router.dart';
|
|
80
|
+
|
|
81
|
+
final _router = GoRouter(
|
|
82
|
+
initialLocation: '/',
|
|
83
|
+
routes: [
|
|
84
|
+
GoRoute(
|
|
85
|
+
path: '/',
|
|
86
|
+
builder: (context, state) => const HomeScreen(),
|
|
87
|
+
),
|
|
88
|
+
GoRoute(
|
|
89
|
+
path: '/profile/:id',
|
|
90
|
+
builder: (context, state) {
|
|
91
|
+
final id = state.pathParameters['id']!;
|
|
92
|
+
return ProfileScreen(userId: id);
|
|
93
|
+
},
|
|
94
|
+
),
|
|
95
|
+
],
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
class MyApp extends StatelessWidget {
|
|
99
|
+
const MyApp({super.key});
|
|
100
|
+
|
|
101
|
+
@override
|
|
102
|
+
Widget build(BuildContext context) {
|
|
103
|
+
return MaterialApp.router(
|
|
104
|
+
title: 'My App',
|
|
105
|
+
theme: ThemeData(
|
|
106
|
+
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
|
|
107
|
+
useMaterial3: true,
|
|
108
|
+
),
|
|
109
|
+
routerConfig: _router,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
### Screen Widget Pattern
|
|
116
|
+
|
|
117
|
+
\`\`\`dart
|
|
118
|
+
// lib/screens/home_screen.dart
|
|
119
|
+
import 'package:flutter/material.dart';
|
|
120
|
+
import 'package:go_router/go_router.dart';
|
|
121
|
+
|
|
122
|
+
class HomeScreen extends StatefulWidget {
|
|
123
|
+
const HomeScreen({super.key});
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
State<HomeScreen> createState() => _HomeScreenState();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
class _HomeScreenState extends State<HomeScreen> {
|
|
130
|
+
List<Item> _items = [];
|
|
131
|
+
bool _isLoading = true;
|
|
132
|
+
|
|
133
|
+
@override
|
|
134
|
+
void initState() {
|
|
135
|
+
super.initState();
|
|
136
|
+
_loadItems();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
Future<void> _loadItems() async {
|
|
140
|
+
try {
|
|
141
|
+
final items = await ApiService.getItems();
|
|
142
|
+
setState(() {
|
|
143
|
+
_items = items;
|
|
144
|
+
_isLoading = false;
|
|
145
|
+
});
|
|
146
|
+
} catch (e) {
|
|
147
|
+
setState(() => _isLoading = false);
|
|
148
|
+
// Handle error
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@override
|
|
153
|
+
Widget build(BuildContext context) {
|
|
154
|
+
return Scaffold(
|
|
155
|
+
appBar: AppBar(title: const Text('Home')),
|
|
156
|
+
body: _isLoading
|
|
157
|
+
? const Center(child: CircularProgressIndicator())
|
|
158
|
+
: ListView.builder(
|
|
159
|
+
itemCount: _items.length,
|
|
160
|
+
itemBuilder: (context, index) {
|
|
161
|
+
final item = _items[index];
|
|
162
|
+
return ListTile(
|
|
163
|
+
title: Text(item.name),
|
|
164
|
+
onTap: () => context.go('/details/\${item.id}'),
|
|
165
|
+
);
|
|
166
|
+
},
|
|
167
|
+
),
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
\`\`\`
|
|
172
|
+
|
|
173
|
+
### Data Models with Freezed
|
|
174
|
+
|
|
175
|
+
\`\`\`dart
|
|
176
|
+
// lib/models/user.dart
|
|
177
|
+
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
178
|
+
|
|
179
|
+
part 'user.freezed.dart';
|
|
180
|
+
part 'user.g.dart';
|
|
181
|
+
|
|
182
|
+
@freezed
|
|
183
|
+
class User with _\$User {
|
|
184
|
+
const factory User({
|
|
185
|
+
required String id,
|
|
186
|
+
required String name,
|
|
187
|
+
required String email,
|
|
188
|
+
}) = _User;
|
|
189
|
+
|
|
190
|
+
factory User.fromJson(Map<String, dynamic> json) => _\$UserFromJson(json);
|
|
191
|
+
}
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
### API Service with Dio
|
|
195
|
+
|
|
196
|
+
\`\`\`dart
|
|
197
|
+
// lib/services/api_service.dart
|
|
198
|
+
import 'package:dio/dio.dart';
|
|
199
|
+
|
|
200
|
+
class ApiService {
|
|
201
|
+
static final _dio = Dio(BaseOptions(
|
|
202
|
+
baseUrl: const String.fromEnvironment('API_URL', defaultValue: 'http://localhost:3001'),
|
|
203
|
+
connectTimeout: const Duration(seconds: 10),
|
|
204
|
+
receiveTimeout: const Duration(seconds: 10),
|
|
205
|
+
));
|
|
206
|
+
|
|
207
|
+
static Future<List<Item>> getItems() async {
|
|
208
|
+
final response = await _dio.get('/items');
|
|
209
|
+
return (response.data as List)
|
|
210
|
+
.map((json) => Item.fromJson(json))
|
|
211
|
+
.toList();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
static Future<Item> createItem(CreateItemInput input) async {
|
|
215
|
+
final response = await _dio.post('/items', data: input.toJson());
|
|
216
|
+
return Item.fromJson(response.data);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
\`\`\`
|
|
220
|
+
|
|
221
|
+
### State Management with Provider
|
|
222
|
+
|
|
223
|
+
\`\`\`dart
|
|
224
|
+
// lib/providers/auth_provider.dart
|
|
225
|
+
import 'package:flutter/material.dart';
|
|
226
|
+
import '../models/user.dart';
|
|
227
|
+
|
|
228
|
+
class AuthProvider extends ChangeNotifier {
|
|
229
|
+
User? _user;
|
|
230
|
+
|
|
231
|
+
User? get user => _user;
|
|
232
|
+
bool get isLoggedIn => _user != null;
|
|
233
|
+
|
|
234
|
+
void setUser(User user) {
|
|
235
|
+
_user = user;
|
|
236
|
+
notifyListeners();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
void logout() {
|
|
240
|
+
_user = null;
|
|
241
|
+
notifyListeners();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
\`\`\`
|
|
245
|
+
|
|
246
|
+
### Critical Rules
|
|
247
|
+
|
|
248
|
+
1. **Use const constructors** for performance optimization
|
|
249
|
+
2. **Separate business logic** from UI (use services/providers)
|
|
250
|
+
3. **Use StatelessWidget** when no local state is needed
|
|
251
|
+
4. **Run build_runner** after changing Freezed models: \`dart run build_runner build\`
|
|
252
|
+
5. **Test on both iOS and Android** - platform-specific issues are common
|
|
253
|
+
6. **Handle async errors** with try-catch and show user feedback
|
|
254
|
+
|
|
255
|
+
### Package Scripts
|
|
256
|
+
|
|
257
|
+
Add these to your workflow:
|
|
258
|
+
\`\`\`bash
|
|
259
|
+
# Run app
|
|
260
|
+
flutter run
|
|
261
|
+
|
|
262
|
+
# Build runner for code generation
|
|
263
|
+
dart run build_runner build --delete-conflicting-outputs
|
|
264
|
+
|
|
265
|
+
# Analyze code
|
|
266
|
+
flutter analyze
|
|
267
|
+
|
|
268
|
+
# Run tests
|
|
269
|
+
flutter test
|
|
270
|
+
\`\`\``;
|
|
271
|
+
//# sourceMappingURL=flutter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flutter.js","sourceRoot":"","sources":["../../../../src/chat/prompts/frontend/flutter.ts"],"names":[],"mappings":";;;AAIa,QAAA,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0QvB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SVELTE_PROMPT = exports.VUE_PROMPT = exports.NEXTJS_PROMPT = exports.REACT_VITE_PROMPT = void 0;
|
|
4
|
+
var react_vite_1 = require("./react-vite");
|
|
5
|
+
Object.defineProperty(exports, "REACT_VITE_PROMPT", { enumerable: true, get: function () { return react_vite_1.REACT_VITE_PROMPT; } });
|
|
6
|
+
var nextjs_1 = require("./nextjs");
|
|
7
|
+
Object.defineProperty(exports, "NEXTJS_PROMPT", { enumerable: true, get: function () { return nextjs_1.NEXTJS_PROMPT; } });
|
|
8
|
+
var vue_1 = require("./vue");
|
|
9
|
+
Object.defineProperty(exports, "VUE_PROMPT", { enumerable: true, get: function () { return vue_1.VUE_PROMPT; } });
|
|
10
|
+
var svelte_1 = require("./svelte");
|
|
11
|
+
Object.defineProperty(exports, "SVELTE_PROMPT", { enumerable: true, get: function () { return svelte_1.SVELTE_PROMPT; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/chat/prompts/frontend/index.ts"],"names":[],"mappings":";;;AAMA,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAC1B,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AACtB,6BAAmC;AAA1B,iGAAA,UAAU,OAAA;AACnB,mCAAyC;AAAhC,uGAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const NEXTJS_PROMPT = "## Frontend: Next.js (App Router)\n\nYou are building a Next.js application using the App Router.\n\n### Technology Stack (Frontend)\n\n| Category | Technology | Notes |\n|----------|------------|-------|\n| Framework | Next.js 15+ | App Router only |\n| Language | TypeScript | Strict mode |\n| UI Components | shadcn/ui | Install: `npx shadcn@latest add <component>` |\n| Styling | Tailwind CSS | Use design tokens |\n| State | Zustand | For client state |\n| Forms | React Hook Form + Zod | For validation |\n| Icons | Lucide React | Consistent iconography |\n\n### Project Initialization\n\n```bash\n# Create Next.js project\nnpx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias \"@/*\"\n\n# Install additional dependencies\nnpm install lucide-react clsx tailwind-merge zustand\nnpm install react-hook-form @hookform/resolvers zod\n\n# Initialize shadcn/ui\nnpx shadcn@latest init -d\n```\n\n### Project Structure\n\n```\napp/\n\u251C\u2500\u2500 layout.tsx # Root layout with fonts, metadata\n\u251C\u2500\u2500 page.tsx # Home page\n\u251C\u2500\u2500 globals.css # Tailwind imports + custom styles\n\u251C\u2500\u2500 loading.tsx # Global loading state\n\u251C\u2500\u2500 error.tsx # Global error boundary\n\u251C\u2500\u2500 not-found.tsx # 404 page\n\u251C\u2500\u2500 (routes)/ # Route groups\n\u2502 \u251C\u2500\u2500 about/\n\u2502 \u2502 \u2514\u2500\u2500 page.tsx\n\u2502 \u2514\u2500\u2500 dashboard/\n\u2502 \u2514\u2500\u2500 page.tsx\ncomponents/\n\u251C\u2500\u2500 ui/ # shadcn/ui components\n\u2514\u2500\u2500 [feature]/ # Feature-specific components\nlib/\n\u251C\u2500\u2500 utils.ts # cn() helper and utilities\n\u2514\u2500\u2500 api.ts # API client (if backend exists)\nhooks/ # Custom React hooks\ntypes/ # TypeScript type definitions\n```\n\n### SEO Best Practices\n\nEvery page MUST include proper SEO elements:\n\n```tsx\n// app/layout.tsx\nimport { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n title: {\n default: 'Site Name',\n template: '%s | Site Name',\n },\n description: 'Site description',\n openGraph: {\n title: 'Site Name',\n description: 'Site description',\n images: ['/og-image.png'],\n },\n};\n```\n\n### Server Components vs Client Components\n\n```tsx\n// Server Component (default) - for data fetching\n// app/users/page.tsx\nasync function getUsers() {\n const res = await fetch('https://api.example.com/users', {\n cache: 'no-store', // or next: { revalidate: 60 }\n });\n if (!res.ok) throw new Error('Failed to fetch');\n return res.json();\n}\n\nexport default async function UsersPage() {\n const users = await getUsers();\n return <UserList users={users} />;\n}\n\n// Client Component - for interactivity\n// components/Counter.tsx\n\"use client\";\n\nimport { useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\n\nexport function Counter() {\n const [count, setCount] = useState(0);\n return (\n <div className=\"flex items-center gap-4\">\n <Button onClick={() => setCount(c => c - 1)}>-</Button>\n <span className=\"text-2xl font-bold\">{count}</span>\n <Button onClick={() => setCount(c => c + 1)}>+</Button>\n </div>\n );\n}\n```\n\n### API Routes (if no separate backend)\n\n```typescript\n// app/api/users/route.ts\nimport { NextResponse } from 'next/server';\n\nexport async function GET() {\n const users = await db.user.findMany();\n return NextResponse.json(users);\n}\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const user = await db.user.create({ data: body });\n return NextResponse.json(user, { status: 201 });\n}\n```\n\n### Form with Server Actions\n\n```tsx\n// app/contact/page.tsx\nimport { submitContactForm } from './actions';\n\nexport default function ContactPage() {\n return (\n <form action={submitContactForm}>\n <input name=\"email\" type=\"email\" required />\n <textarea name=\"message\" required />\n <button type=\"submit\">Send</button>\n </form>\n );\n}\n\n// app/contact/actions.ts\n\"use server\";\n\nexport async function submitContactForm(formData: FormData) {\n const email = formData.get('email') as string;\n const message = formData.get('message') as string;\n\n // Process form...\n\n return { success: true };\n}\n```\n\n### UI/UX Requirements\n\n- Use semantic HTML (`<main>`, `<nav>`, `<article>`, `<section>`)\n- One `<h1>` per page, hierarchical headings\n- Implement responsive design (mobile-first)\n- Add proper loading states with `loading.tsx`\n- Keyboard navigation support\n- ARIA labels where needed\n- Color contrast ratio 4.5:1 minimum\n\n### Header/Navbar Best Practices\n\n```tsx\n// GOOD: Full-width header\n<header className=\"sticky top-0 z-50 border-b bg-background\">\n <div className=\"flex h-14 w-full items-center justify-between px-4\">\n {/* Logo on left, Nav on right */}\n </div>\n</header>\n\n// BAD: Header with gaps\n<header>\n <div className=\"container mx-auto\"> {/* Don't use for headers! */}\n```\n\n### What NOT to Do (Next.js specific)\n\n- Never use outdated patterns (pages router, getServerSideProps, getStaticProps)\n- Never create Python, Ruby, or non-TypeScript files\n- Never mix Server and Client logic in same component without \"use client\"";
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NEXTJS_PROMPT = void 0;
|
|
4
|
+
exports.NEXTJS_PROMPT = `## Frontend: Next.js (App Router)
|
|
5
|
+
|
|
6
|
+
You are building a Next.js application using the App Router.
|
|
7
|
+
|
|
8
|
+
### Technology Stack (Frontend)
|
|
9
|
+
|
|
10
|
+
| Category | Technology | Notes |
|
|
11
|
+
|----------|------------|-------|
|
|
12
|
+
| Framework | Next.js 15+ | App Router only |
|
|
13
|
+
| Language | TypeScript | Strict mode |
|
|
14
|
+
| UI Components | shadcn/ui | Install: \`npx shadcn@latest add <component>\` |
|
|
15
|
+
| Styling | Tailwind CSS | Use design tokens |
|
|
16
|
+
| State | Zustand | For client state |
|
|
17
|
+
| Forms | React Hook Form + Zod | For validation |
|
|
18
|
+
| Icons | Lucide React | Consistent iconography |
|
|
19
|
+
|
|
20
|
+
### Project Initialization
|
|
21
|
+
|
|
22
|
+
\`\`\`bash
|
|
23
|
+
# Create Next.js project
|
|
24
|
+
npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
|
|
25
|
+
|
|
26
|
+
# Install additional dependencies
|
|
27
|
+
npm install lucide-react clsx tailwind-merge zustand
|
|
28
|
+
npm install react-hook-form @hookform/resolvers zod
|
|
29
|
+
|
|
30
|
+
# Initialize shadcn/ui
|
|
31
|
+
npx shadcn@latest init -d
|
|
32
|
+
\`\`\`
|
|
33
|
+
|
|
34
|
+
### Project Structure
|
|
35
|
+
|
|
36
|
+
\`\`\`
|
|
37
|
+
app/
|
|
38
|
+
├── layout.tsx # Root layout with fonts, metadata
|
|
39
|
+
├── page.tsx # Home page
|
|
40
|
+
├── globals.css # Tailwind imports + custom styles
|
|
41
|
+
├── loading.tsx # Global loading state
|
|
42
|
+
├── error.tsx # Global error boundary
|
|
43
|
+
├── not-found.tsx # 404 page
|
|
44
|
+
├── (routes)/ # Route groups
|
|
45
|
+
│ ├── about/
|
|
46
|
+
│ │ └── page.tsx
|
|
47
|
+
│ └── dashboard/
|
|
48
|
+
│ └── page.tsx
|
|
49
|
+
components/
|
|
50
|
+
├── ui/ # shadcn/ui components
|
|
51
|
+
└── [feature]/ # Feature-specific components
|
|
52
|
+
lib/
|
|
53
|
+
├── utils.ts # cn() helper and utilities
|
|
54
|
+
└── api.ts # API client (if backend exists)
|
|
55
|
+
hooks/ # Custom React hooks
|
|
56
|
+
types/ # TypeScript type definitions
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
### SEO Best Practices
|
|
60
|
+
|
|
61
|
+
Every page MUST include proper SEO elements:
|
|
62
|
+
|
|
63
|
+
\`\`\`tsx
|
|
64
|
+
// app/layout.tsx
|
|
65
|
+
import { Metadata } from 'next';
|
|
66
|
+
|
|
67
|
+
export const metadata: Metadata = {
|
|
68
|
+
title: {
|
|
69
|
+
default: 'Site Name',
|
|
70
|
+
template: '%s | Site Name',
|
|
71
|
+
},
|
|
72
|
+
description: 'Site description',
|
|
73
|
+
openGraph: {
|
|
74
|
+
title: 'Site Name',
|
|
75
|
+
description: 'Site description',
|
|
76
|
+
images: ['/og-image.png'],
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
### Server Components vs Client Components
|
|
82
|
+
|
|
83
|
+
\`\`\`tsx
|
|
84
|
+
// Server Component (default) - for data fetching
|
|
85
|
+
// app/users/page.tsx
|
|
86
|
+
async function getUsers() {
|
|
87
|
+
const res = await fetch('https://api.example.com/users', {
|
|
88
|
+
cache: 'no-store', // or next: { revalidate: 60 }
|
|
89
|
+
});
|
|
90
|
+
if (!res.ok) throw new Error('Failed to fetch');
|
|
91
|
+
return res.json();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default async function UsersPage() {
|
|
95
|
+
const users = await getUsers();
|
|
96
|
+
return <UserList users={users} />;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Client Component - for interactivity
|
|
100
|
+
// components/Counter.tsx
|
|
101
|
+
"use client";
|
|
102
|
+
|
|
103
|
+
import { useState } from "react";
|
|
104
|
+
import { Button } from "@/components/ui/button";
|
|
105
|
+
|
|
106
|
+
export function Counter() {
|
|
107
|
+
const [count, setCount] = useState(0);
|
|
108
|
+
return (
|
|
109
|
+
<div className="flex items-center gap-4">
|
|
110
|
+
<Button onClick={() => setCount(c => c - 1)}>-</Button>
|
|
111
|
+
<span className="text-2xl font-bold">{count}</span>
|
|
112
|
+
<Button onClick={() => setCount(c => c + 1)}>+</Button>
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
\`\`\`
|
|
117
|
+
|
|
118
|
+
### API Routes (if no separate backend)
|
|
119
|
+
|
|
120
|
+
\`\`\`typescript
|
|
121
|
+
// app/api/users/route.ts
|
|
122
|
+
import { NextResponse } from 'next/server';
|
|
123
|
+
|
|
124
|
+
export async function GET() {
|
|
125
|
+
const users = await db.user.findMany();
|
|
126
|
+
return NextResponse.json(users);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function POST(request: Request) {
|
|
130
|
+
const body = await request.json();
|
|
131
|
+
const user = await db.user.create({ data: body });
|
|
132
|
+
return NextResponse.json(user, { status: 201 });
|
|
133
|
+
}
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
### Form with Server Actions
|
|
137
|
+
|
|
138
|
+
\`\`\`tsx
|
|
139
|
+
// app/contact/page.tsx
|
|
140
|
+
import { submitContactForm } from './actions';
|
|
141
|
+
|
|
142
|
+
export default function ContactPage() {
|
|
143
|
+
return (
|
|
144
|
+
<form action={submitContactForm}>
|
|
145
|
+
<input name="email" type="email" required />
|
|
146
|
+
<textarea name="message" required />
|
|
147
|
+
<button type="submit">Send</button>
|
|
148
|
+
</form>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// app/contact/actions.ts
|
|
153
|
+
"use server";
|
|
154
|
+
|
|
155
|
+
export async function submitContactForm(formData: FormData) {
|
|
156
|
+
const email = formData.get('email') as string;
|
|
157
|
+
const message = formData.get('message') as string;
|
|
158
|
+
|
|
159
|
+
// Process form...
|
|
160
|
+
|
|
161
|
+
return { success: true };
|
|
162
|
+
}
|
|
163
|
+
\`\`\`
|
|
164
|
+
|
|
165
|
+
### UI/UX Requirements
|
|
166
|
+
|
|
167
|
+
- Use semantic HTML (\`<main>\`, \`<nav>\`, \`<article>\`, \`<section>\`)
|
|
168
|
+
- One \`<h1>\` per page, hierarchical headings
|
|
169
|
+
- Implement responsive design (mobile-first)
|
|
170
|
+
- Add proper loading states with \`loading.tsx\`
|
|
171
|
+
- Keyboard navigation support
|
|
172
|
+
- ARIA labels where needed
|
|
173
|
+
- Color contrast ratio 4.5:1 minimum
|
|
174
|
+
|
|
175
|
+
### Header/Navbar Best Practices
|
|
176
|
+
|
|
177
|
+
\`\`\`tsx
|
|
178
|
+
// GOOD: Full-width header
|
|
179
|
+
<header className="sticky top-0 z-50 border-b bg-background">
|
|
180
|
+
<div className="flex h-14 w-full items-center justify-between px-4">
|
|
181
|
+
{/* Logo on left, Nav on right */}
|
|
182
|
+
</div>
|
|
183
|
+
</header>
|
|
184
|
+
|
|
185
|
+
// BAD: Header with gaps
|
|
186
|
+
<header>
|
|
187
|
+
<div className="container mx-auto"> {/* Don't use for headers! */}
|
|
188
|
+
\`\`\`
|
|
189
|
+
|
|
190
|
+
### What NOT to Do (Next.js specific)
|
|
191
|
+
|
|
192
|
+
- Never use outdated patterns (pages router, getServerSideProps, getStaticProps)
|
|
193
|
+
- Never create Python, Ruby, or non-TypeScript files
|
|
194
|
+
- Never mix Server and Client logic in same component without "use client"`;
|
|
195
|
+
//# sourceMappingURL=nextjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../../../src/chat/prompts/frontend/nextjs.ts"],"names":[],"mappings":";;;AAMa,QAAA,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2EA8L8C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const REACT_NATIVE_PROMPT = "## React Native Development Guide\n\n### Project Structure\n\n```\nfrontend/\n\u251C\u2500\u2500 src/\n\u2502 \u251C\u2500\u2500 screens/ # Screen components\n\u2502 \u2502 \u251C\u2500\u2500 HomeScreen.tsx\n\u2502 \u2502 \u2514\u2500\u2500 ProfileScreen.tsx\n\u2502 \u251C\u2500\u2500 components/ # Reusable components\n\u2502 \u2502 \u251C\u2500\u2500 ui/ # Basic UI components\n\u2502 \u2502 \u2514\u2500\u2500 features/ # Feature-specific\n\u2502 \u251C\u2500\u2500 navigation/ # Navigation config\n\u2502 \u2502 \u251C\u2500\u2500 RootNavigator.tsx\n\u2502 \u2502 \u2514\u2500\u2500 types.ts\n\u2502 \u251C\u2500\u2500 hooks/ # Custom hooks\n\u2502 \u251C\u2500\u2500 lib/ # Utilities\n\u2502 \u251C\u2500\u2500 stores/ # State management\n\u2502 \u2514\u2500\u2500 types/ # TypeScript types\n\u251C\u2500\u2500 android/ # Android native code\n\u251C\u2500\u2500 ios/ # iOS native code\n\u251C\u2500\u2500 index.js # Entry point\n\u251C\u2500\u2500 App.tsx # Root component\n\u251C\u2500\u2500 package.json\n\u251C\u2500\u2500 metro.config.js\n\u2514\u2500\u2500 tsconfig.json\n```\n\n### Essential Dependencies\n\n```json\n{\n \"dependencies\": {\n \"react\": \"18.2.0\",\n \"react-native\": \"0.74.0\",\n \"@react-navigation/native\": \"^6.1.0\",\n \"@react-navigation/native-stack\": \"^6.9.0\",\n \"@react-navigation/bottom-tabs\": \"^6.5.0\",\n \"react-native-screens\": \"^3.29.0\",\n \"react-native-safe-area-context\": \"^4.8.0\",\n \"react-native-gesture-handler\": \"^2.14.0\",\n \"react-native-reanimated\": \"^3.6.0\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"^7.23.0\",\n \"@babel/preset-env\": \"^7.23.0\",\n \"@babel/runtime\": \"^7.23.0\",\n \"@types/react\": \"^18.2.0\",\n \"typescript\": \"^5.3.0\"\n }\n}\n```\n\n### Navigation Setup\n\n**Root Navigator**:\n```tsx\n// src/navigation/RootNavigator.tsx\nimport { NavigationContainer } from \"@react-navigation/native\";\nimport { createNativeStackNavigator } from \"@react-navigation/native-stack\";\nimport { createBottomTabNavigator } from \"@react-navigation/bottom-tabs\";\n\nconst Stack = createNativeStackNavigator<RootStackParamList>();\nconst Tab = createBottomTabNavigator<TabParamList>();\n\nfunction TabNavigator() {\n return (\n <Tab.Navigator>\n <Tab.Screen name=\"Home\" component={HomeScreen} />\n <Tab.Screen name=\"Profile\" component={ProfileScreen} />\n </Tab.Navigator>\n );\n}\n\nexport function RootNavigator() {\n return (\n <NavigationContainer>\n <Stack.Navigator>\n <Stack.Screen\n name=\"Main\"\n component={TabNavigator}\n options={{ headerShown: false }}\n />\n <Stack.Screen name=\"Details\" component={DetailsScreen} />\n </Stack.Navigator>\n </NavigationContainer>\n );\n}\n```\n\n**Navigation Types**:\n```tsx\n// src/navigation/types.ts\nimport type { NativeStackScreenProps } from \"@react-navigation/native-stack\";\n\nexport type RootStackParamList = {\n Main: undefined;\n Details: { id: string };\n};\n\nexport type RootStackScreenProps<T extends keyof RootStackParamList> =\n NativeStackScreenProps<RootStackParamList, T>;\n```\n\n### Screen Component Pattern\n\n```tsx\n// src/screens/HomeScreen.tsx\nimport { StyleSheet, View, Text, FlatList } from \"react-native\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\nimport type { RootStackScreenProps } from \"../navigation/types\";\n\nexport function HomeScreen({ navigation }: RootStackScreenProps<\"Main\">) {\n return (\n <SafeAreaView style={styles.container}>\n <Text style={styles.title}>Home</Text>\n <FlatList\n data={items}\n keyExtractor={(item) => item.id}\n renderItem={({ item }) => (\n <TouchableOpacity\n onPress={() => navigation.navigate(\"Details\", { id: item.id })}\n >\n <ItemCard item={item} />\n </TouchableOpacity>\n )}\n />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: \"#fff\",\n },\n title: {\n fontSize: 24,\n fontWeight: \"bold\",\n padding: 16,\n },\n});\n```\n\n### API Communication\n\n```tsx\n// src/lib/api.ts\nimport { Platform } from \"react-native\";\n\n// Android emulator uses 10.0.2.2 for localhost\nconst getBaseUrl = () => {\n if (__DEV__) {\n return Platform.OS === \"android\"\n ? \"http://10.0.2.2:3001\"\n : \"http://localhost:3001\";\n }\n return \"https://api.example.com\";\n};\n\nconst API_URL = getBaseUrl();\n\nexport async function fetcher<T>(endpoint: string, options?: RequestInit): Promise<T> {\n const response = await fetch(`${API_URL}${endpoint}`, {\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n ...options,\n });\n\n if (!response.ok) {\n throw new Error(`API Error: ${response.status}`);\n }\n\n return response.json();\n}\n```\n\n### Critical Rules\n\n1. **Use SafeAreaView** from react-native-safe-area-context\n2. **Use FlatList** for lists, not ScrollView with map\n3. **Handle Android back button** with BackHandler\n4. **Test on both platforms** - iOS Simulator and Android Emulator\n5. **Use StyleSheet.create** for performance\n6. **Handle keyboard** with KeyboardAvoidingView\n\n### Platform-Specific Code\n\n```tsx\nimport { Platform, StyleSheet } from \"react-native\";\n\nconst styles = StyleSheet.create({\n shadow: Platform.select({\n ios: {\n shadowColor: \"#000\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.1,\n shadowRadius: 4,\n },\n android: {\n elevation: 4,\n },\n }),\n});\n```\n\n### Package Scripts\n\n```json\n{\n \"scripts\": {\n \"dev\": \"react-native start\",\n \"android\": \"react-native run-android\",\n \"ios\": \"react-native run-ios\"\n }\n}\n```";
|