@djangocfg/nextjs 2.1.1 → 2.1.2
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/README.md +42 -0
- package/package.json +15 -6
- package/src/ai/CLAUDE.md +48 -0
- package/src/ai/cli.ts +74 -0
- package/src/ai/client.ts +171 -0
- package/src/ai/constants.ts +31 -0
- package/src/ai/index.ts +29 -0
- package/src/ai/types.ts +35 -0
- package/src/config/index.ts +8 -0
- package/src/config/packages/updater.ts +4 -3
- package/src/config/plugins/devStartup.ts +7 -3
- package/src/index.ts +3 -0
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
## Features
|
|
19
19
|
|
|
20
20
|
- **Base Next.js Config** - Universal, reusable Next.js configuration factory for monorepos
|
|
21
|
+
- **AI Documentation** - Search DjangoCFG docs via MCP server and CLI
|
|
21
22
|
- **Sitemap Generation** - Dynamic XML sitemap generation for SEO
|
|
22
23
|
- **Health Checks** - Production-ready health monitoring endpoints
|
|
23
24
|
- **OG Images** - Dynamic Open Graph image generation with templates
|
|
@@ -38,6 +39,46 @@ yarn add @djangocfg/nextjs
|
|
|
38
39
|
|
|
39
40
|
## Quick Start
|
|
40
41
|
|
|
42
|
+
### AI Documentation Search
|
|
43
|
+
|
|
44
|
+
Search DjangoCFG documentation from the terminal:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# CLI
|
|
48
|
+
pnpm ai-docs search "database configuration"
|
|
49
|
+
pnpm ai-docs mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or use the TypeScript API:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { search, getDocs, getMcpConfig } from '@djangocfg/nextjs/ai';
|
|
56
|
+
|
|
57
|
+
// Search documentation
|
|
58
|
+
const results = await search('database configuration');
|
|
59
|
+
results.forEach(r => console.log(r.title, r.url));
|
|
60
|
+
|
|
61
|
+
// Get formatted docs
|
|
62
|
+
const docs = await getDocs('How to configure PostgreSQL?');
|
|
63
|
+
|
|
64
|
+
// Get MCP server config for AI assistants
|
|
65
|
+
const config = getMcpConfig();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### MCP Server for AI Assistants
|
|
69
|
+
|
|
70
|
+
Add to your AI assistant configuration:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"djangocfg-docs": {
|
|
76
|
+
"url": "https://mcp.djangocfg.com/mcp"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
41
82
|
### Base Next.js Configuration
|
|
42
83
|
|
|
43
84
|
Create a reusable base configuration for all your Next.js projects:
|
|
@@ -203,6 +244,7 @@ import { RedirectPage } from '@djangocfg/layouts/components/RedirectPage';
|
|
|
203
244
|
| Path | Description |
|
|
204
245
|
|------|-------------|
|
|
205
246
|
| `@djangocfg/nextjs` | Main exports (all modules) |
|
|
247
|
+
| `@djangocfg/nextjs/ai` | AI documentation search and MCP config |
|
|
206
248
|
| `@djangocfg/nextjs/config` | Base Next.js configuration factory |
|
|
207
249
|
| `@djangocfg/nextjs/sitemap` | Sitemap generation utilities |
|
|
208
250
|
| `@djangocfg/nextjs/health` | Health check handlers |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/nextjs",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nextjs",
|
|
@@ -79,6 +79,11 @@
|
|
|
79
79
|
"types": "./src/scripts/index.ts",
|
|
80
80
|
"import": "./src/scripts/index.ts",
|
|
81
81
|
"default": "./src/scripts/index.ts"
|
|
82
|
+
},
|
|
83
|
+
"./ai": {
|
|
84
|
+
"types": "./src/ai/index.ts",
|
|
85
|
+
"import": "./src/ai/index.ts",
|
|
86
|
+
"default": "./src/ai/index.ts"
|
|
82
87
|
}
|
|
83
88
|
},
|
|
84
89
|
"files": [
|
|
@@ -86,22 +91,26 @@
|
|
|
86
91
|
"README.md",
|
|
87
92
|
"LICENSE"
|
|
88
93
|
],
|
|
94
|
+
"bin": {
|
|
95
|
+
"ai-docs": "./src/ai/cli.ts"
|
|
96
|
+
},
|
|
89
97
|
"scripts": {
|
|
90
98
|
"build": "tsup",
|
|
91
99
|
"dev": "tsup --watch",
|
|
92
100
|
"clean": "rm -rf dist",
|
|
93
101
|
"lint": "eslint .",
|
|
94
102
|
"check": "tsc --noEmit",
|
|
95
|
-
"check-links": "tsx src/scripts/check-links.ts"
|
|
103
|
+
"check-links": "tsx src/scripts/check-links.ts",
|
|
104
|
+
"ai-docs": "tsx src/ai/cli.ts"
|
|
96
105
|
},
|
|
97
106
|
"peerDependencies": {
|
|
98
|
-
"@djangocfg/api": "^2.1.
|
|
107
|
+
"@djangocfg/api": "^2.1.2",
|
|
99
108
|
"next": "^15.5.7"
|
|
100
109
|
},
|
|
101
110
|
"devDependencies": {
|
|
102
|
-
"@djangocfg/imgai": "^2.1.
|
|
103
|
-
"@djangocfg/layouts": "^2.1.
|
|
104
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
111
|
+
"@djangocfg/imgai": "^2.1.2",
|
|
112
|
+
"@djangocfg/layouts": "^2.1.2",
|
|
113
|
+
"@djangocfg/typescript-config": "^2.1.2",
|
|
105
114
|
"@types/node": "^24.7.2",
|
|
106
115
|
"@types/react": "19.2.2",
|
|
107
116
|
"@types/react-dom": "19.2.1",
|
package/src/ai/CLAUDE.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @djangocfg/nextjs - AI Documentation
|
|
2
|
+
|
|
3
|
+
DjangoCFG documentation is available via MCP server.
|
|
4
|
+
|
|
5
|
+
## MCP Server
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"mcpServers": {
|
|
10
|
+
"djangocfg-docs": {
|
|
11
|
+
"url": "https://mcp.djangocfg.com/mcp"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## API
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
curl 'https://mcp.djangocfg.com/api/search?q=database+configuration&limit=5'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## TypeScript
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { search, getDocs, getMcpConfig } from '@djangocfg/nextjs/ai';
|
|
27
|
+
|
|
28
|
+
// Search documentation
|
|
29
|
+
const results = await search('database configuration');
|
|
30
|
+
results.forEach(r => console.log(r.title, r.url));
|
|
31
|
+
|
|
32
|
+
// Get formatted docs
|
|
33
|
+
const docs = await getDocs('How to configure PostgreSQL?');
|
|
34
|
+
|
|
35
|
+
// Get MCP config
|
|
36
|
+
const config = getMcpConfig();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Common Topics
|
|
40
|
+
|
|
41
|
+
- DatabaseConfig - PostgreSQL, MySQL, SQLite
|
|
42
|
+
- CacheConfig - Redis, Memcached
|
|
43
|
+
- EmailConfig - SMTP, SendGrid
|
|
44
|
+
- LoggingConfig - Logging setup
|
|
45
|
+
- SecurityConfig - CORS, CSRF
|
|
46
|
+
- DRFConfig - Django REST Framework
|
|
47
|
+
- OG Image - Open Graph image generation
|
|
48
|
+
- Sitemap - XML sitemap generation
|
package/src/ai/cli.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* DjangoCFG AI Docs CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* pnpm exec ai-docs search "database configuration"
|
|
7
|
+
* pnpm exec ai-docs mcp
|
|
8
|
+
* npx @djangocfg/nextjs ai-docs search "query"
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { search, getMcpConfig, MCP_SERVER_URL, MCP_API_URL } from './index';
|
|
12
|
+
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const command = args[0];
|
|
15
|
+
const query = args.slice(1).join(' ');
|
|
16
|
+
|
|
17
|
+
async function main() {
|
|
18
|
+
switch (command) {
|
|
19
|
+
case 'search':
|
|
20
|
+
case 's':
|
|
21
|
+
if (!query) {
|
|
22
|
+
console.error('Usage: ai-docs search "your query"');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
console.log(`\n🔍 Searching: ${query}\n`);
|
|
26
|
+
try {
|
|
27
|
+
const results = await search(query, { limit: 5 });
|
|
28
|
+
if (results.length === 0) {
|
|
29
|
+
console.log('No results found.');
|
|
30
|
+
} else {
|
|
31
|
+
results.forEach((r, i) => {
|
|
32
|
+
console.log(`${i + 1}. ${r.title}`);
|
|
33
|
+
console.log(` ${r.content.slice(0, 150)}...`);
|
|
34
|
+
if (r.url) console.log(` 📖 ${r.url}`);
|
|
35
|
+
console.log('');
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error('Error:', err instanceof Error ? err.message : err);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
|
|
44
|
+
case 'mcp':
|
|
45
|
+
console.log('\n📡 MCP Server Configuration:\n');
|
|
46
|
+
console.log(JSON.stringify(getMcpConfig(), null, 2));
|
|
47
|
+
console.log('\nAdd this to your AI assistant configuration.');
|
|
48
|
+
break;
|
|
49
|
+
|
|
50
|
+
case 'info':
|
|
51
|
+
case 'i':
|
|
52
|
+
console.log('\n🤖 DjangoCFG AI Documentation\n');
|
|
53
|
+
console.log(`MCP Server: ${MCP_SERVER_URL}`);
|
|
54
|
+
console.log(`Search API: ${MCP_API_URL}`);
|
|
55
|
+
console.log('\nUsage:');
|
|
56
|
+
console.log(' pnpm exec ai-docs search "database configuration"');
|
|
57
|
+
console.log(' pnpm exec ai-docs mcp');
|
|
58
|
+
break;
|
|
59
|
+
|
|
60
|
+
default:
|
|
61
|
+
console.log('🤖 DjangoCFG AI Documentation CLI\n');
|
|
62
|
+
console.log('Commands:');
|
|
63
|
+
console.log(' search <query> Search documentation');
|
|
64
|
+
console.log(' mcp Show MCP server config');
|
|
65
|
+
console.log(' info Show help\n');
|
|
66
|
+
console.log('Examples:');
|
|
67
|
+
console.log(' pnpm exec ai-docs search "database configuration"');
|
|
68
|
+
console.log(' pnpm exec ai-docs search "redis cache"');
|
|
69
|
+
console.log(' pnpm exec ai-docs mcp');
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main();
|
package/src/ai/client.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DjangoCFG Documentation Client
|
|
3
|
+
*
|
|
4
|
+
* HTTP client for accessing DjangoCFG documentation via MCP server API.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
MCP_BASE_URL,
|
|
9
|
+
API_SEARCH_ENDPOINT,
|
|
10
|
+
API_INFO_ENDPOINT,
|
|
11
|
+
DEFAULT_TIMEOUT,
|
|
12
|
+
} from './constants';
|
|
13
|
+
import type { SearchResult, SearchOptions, McpConfig, ApiSearchResponse } from './types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Client for DjangoCFG Documentation API.
|
|
17
|
+
*/
|
|
18
|
+
export class DjangoCfgDocsClient {
|
|
19
|
+
private baseUrl: string;
|
|
20
|
+
private timeout: number;
|
|
21
|
+
|
|
22
|
+
constructor(baseUrl: string = MCP_BASE_URL, timeout: number = DEFAULT_TIMEOUT) {
|
|
23
|
+
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
24
|
+
this.timeout = timeout;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private async makeRequest<T>(endpoint: string, params?: Record<string, string | number>): Promise<T> {
|
|
28
|
+
let url = `${this.baseUrl}${endpoint}`;
|
|
29
|
+
|
|
30
|
+
if (params) {
|
|
31
|
+
const searchParams = new URLSearchParams();
|
|
32
|
+
for (const [key, value] of Object.entries(params)) {
|
|
33
|
+
searchParams.set(key, String(value));
|
|
34
|
+
}
|
|
35
|
+
url = `${url}?${searchParams.toString()}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url, {
|
|
43
|
+
method: 'GET',
|
|
44
|
+
headers: {
|
|
45
|
+
Accept: 'application/json',
|
|
46
|
+
'User-Agent': 'DjangoCFG-AI-Client/1.0',
|
|
47
|
+
},
|
|
48
|
+
signal: controller.signal,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`HTTP Error ${response.status}: ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return await response.json();
|
|
56
|
+
} finally {
|
|
57
|
+
clearTimeout(timeoutId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Search documentation.
|
|
63
|
+
*/
|
|
64
|
+
async search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {
|
|
65
|
+
const { limit = 5, category } = options;
|
|
66
|
+
|
|
67
|
+
const params: Record<string, string | number> = { q: query, limit };
|
|
68
|
+
if (category) {
|
|
69
|
+
params.category = category;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const data = await this.makeRequest<ApiSearchResponse>(API_SEARCH_ENDPOINT, params);
|
|
73
|
+
|
|
74
|
+
const results = data.results || (Array.isArray(data) ? data : []);
|
|
75
|
+
|
|
76
|
+
return results.map((item) => ({
|
|
77
|
+
title: item.title || '',
|
|
78
|
+
content: item.content || item.snippet || '',
|
|
79
|
+
url: item.url || '',
|
|
80
|
+
score: item.score || 0,
|
|
81
|
+
category: item.category || '',
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get detailed info about a specific topic.
|
|
87
|
+
*/
|
|
88
|
+
async getInfo(topic: string): Promise<Record<string, unknown>> {
|
|
89
|
+
return this.makeRequest(API_INFO_ENDPOINT, { topic });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get MCP server configuration for AI assistants.
|
|
94
|
+
*/
|
|
95
|
+
getMcpConfig(): McpConfig {
|
|
96
|
+
return {
|
|
97
|
+
mcpServers: {
|
|
98
|
+
'djangocfg-docs': {
|
|
99
|
+
url: `${this.baseUrl}/mcp`,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Default client instance
|
|
107
|
+
let defaultClient: DjangoCfgDocsClient | null = null;
|
|
108
|
+
|
|
109
|
+
function getClient(): DjangoCfgDocsClient {
|
|
110
|
+
if (!defaultClient) {
|
|
111
|
+
defaultClient = new DjangoCfgDocsClient();
|
|
112
|
+
}
|
|
113
|
+
return defaultClient;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Search DjangoCFG documentation.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const results = await search('database configuration');
|
|
122
|
+
* results.forEach(r => console.log(r.title, r.url));
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export async function search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {
|
|
126
|
+
return getClient().search(query, options);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get documentation as formatted text.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const docs = await getDocs('How to configure PostgreSQL?');
|
|
135
|
+
* console.log(docs);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export async function getDocs(query: string, limit: number = 3): Promise<string> {
|
|
139
|
+
const results = await search(query, { limit });
|
|
140
|
+
|
|
141
|
+
if (results.length === 0) {
|
|
142
|
+
return `No documentation found for: ${query}`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const output: string[] = [];
|
|
146
|
+
|
|
147
|
+
results.forEach((r, i) => {
|
|
148
|
+
output.push(`## ${i + 1}. ${r.title}`);
|
|
149
|
+
output.push(r.content);
|
|
150
|
+
if (r.url) {
|
|
151
|
+
output.push(`📖 Read more: ${r.url}`);
|
|
152
|
+
}
|
|
153
|
+
output.push('');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return output.join('\n');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get detailed info about a topic.
|
|
161
|
+
*/
|
|
162
|
+
export async function getInfo(topic: string): Promise<Record<string, unknown>> {
|
|
163
|
+
return getClient().getInfo(topic);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Get MCP server configuration.
|
|
168
|
+
*/
|
|
169
|
+
export function getMcpConfig(): McpConfig {
|
|
170
|
+
return getClient().getMcpConfig();
|
|
171
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Documentation Constants
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// MCP Server URLs
|
|
6
|
+
export const MCP_BASE_URL = 'https://mcp.djangocfg.com';
|
|
7
|
+
export const MCP_SERVER_URL = `${MCP_BASE_URL}/mcp`;
|
|
8
|
+
export const MCP_API_URL = `${MCP_BASE_URL}/api/search`;
|
|
9
|
+
|
|
10
|
+
// API Endpoints
|
|
11
|
+
export const API_SEARCH_ENDPOINT = '/api/search';
|
|
12
|
+
export const API_INFO_ENDPOINT = '/api/info';
|
|
13
|
+
export const DEFAULT_TIMEOUT = 10000; // ms
|
|
14
|
+
|
|
15
|
+
// AI Hint for console output
|
|
16
|
+
export const AI_DOCS_HINT = `🤖 AI Docs: ${MCP_SERVER_URL} | pnpm ai-docs search "query"`;
|
|
17
|
+
|
|
18
|
+
// Full AI Hint description
|
|
19
|
+
export const AI_HINT = `
|
|
20
|
+
DjangoCFG Documentation is available via MCP server.
|
|
21
|
+
|
|
22
|
+
To get help with DjangoCFG configuration:
|
|
23
|
+
1. Use the MCP server: ${MCP_SERVER_URL}
|
|
24
|
+
2. Or search directly: ${MCP_API_URL}?q=YOUR_QUERY&limit=5
|
|
25
|
+
|
|
26
|
+
Example queries:
|
|
27
|
+
- "How to configure PostgreSQL database?"
|
|
28
|
+
- "What is DatabaseConfig?"
|
|
29
|
+
- "How to setup Redis cache?"
|
|
30
|
+
- "Email configuration with SMTP"
|
|
31
|
+
`;
|
package/src/ai/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DjangoCFG AI Documentation Client
|
|
3
|
+
*
|
|
4
|
+
* Provides access to DjangoCFG documentation via MCP server API.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { search, getDocs, getMcpConfig } from '@djangocfg/nextjs/ai';
|
|
9
|
+
*
|
|
10
|
+
* // Search documentation
|
|
11
|
+
* const results = await search('database configuration');
|
|
12
|
+
*
|
|
13
|
+
* // Get formatted docs
|
|
14
|
+
* const docs = await getDocs('How to configure PostgreSQL?');
|
|
15
|
+
*
|
|
16
|
+
* // Get MCP config for AI assistants
|
|
17
|
+
* const config = getMcpConfig();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export { DjangoCfgDocsClient, search, getDocs, getInfo, getMcpConfig } from './client';
|
|
22
|
+
export type { SearchResult, SearchOptions, McpConfig } from './types';
|
|
23
|
+
export {
|
|
24
|
+
MCP_BASE_URL,
|
|
25
|
+
MCP_SERVER_URL,
|
|
26
|
+
MCP_API_URL,
|
|
27
|
+
AI_DOCS_HINT,
|
|
28
|
+
AI_HINT,
|
|
29
|
+
} from './constants';
|
package/src/ai/types.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Documentation Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface SearchResult {
|
|
6
|
+
title: string;
|
|
7
|
+
content: string;
|
|
8
|
+
url: string;
|
|
9
|
+
score: number;
|
|
10
|
+
category: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SearchOptions {
|
|
14
|
+
limit?: number;
|
|
15
|
+
category?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface McpConfig {
|
|
19
|
+
mcpServers: {
|
|
20
|
+
'djangocfg-docs': {
|
|
21
|
+
url: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ApiSearchResponse {
|
|
27
|
+
results: Array<{
|
|
28
|
+
title: string;
|
|
29
|
+
content?: string;
|
|
30
|
+
snippet?: string;
|
|
31
|
+
url: string;
|
|
32
|
+
score?: number;
|
|
33
|
+
category?: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -24,6 +24,14 @@ export {
|
|
|
24
24
|
DJANGO_CFG_BANNER,
|
|
25
25
|
} from './constants';
|
|
26
26
|
|
|
27
|
+
// Re-export AI constants from ai module
|
|
28
|
+
export {
|
|
29
|
+
MCP_BASE_URL,
|
|
30
|
+
MCP_SERVER_URL,
|
|
31
|
+
MCP_API_URL,
|
|
32
|
+
AI_DOCS_HINT,
|
|
33
|
+
} from '../ai/constants';
|
|
34
|
+
|
|
27
35
|
// Utils
|
|
28
36
|
export { deepMerge } from './utils/deepMerge';
|
|
29
37
|
export {
|
|
@@ -300,11 +300,12 @@ async function updateSinglePackage(
|
|
|
300
300
|
|
|
301
301
|
spinner.start();
|
|
302
302
|
|
|
303
|
+
// Always install with @latest to keep package.json consistent
|
|
303
304
|
const command = pm === 'pnpm'
|
|
304
|
-
? `pnpm add ${pkg.name}
|
|
305
|
+
? `pnpm add ${pkg.name}@latest`
|
|
305
306
|
: pm === 'yarn'
|
|
306
|
-
? `yarn add ${pkg.name}
|
|
307
|
-
: `npm install ${pkg.name}
|
|
307
|
+
? `yarn add ${pkg.name}@latest`
|
|
308
|
+
: `npm install ${pkg.name}@latest`;
|
|
308
309
|
|
|
309
310
|
return new Promise((resolve) => {
|
|
310
311
|
const proc = spawn(command, {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { Compiler } from 'webpack';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { DJANGO_CFG_BANNER } from '../constants';
|
|
10
|
+
import { AI_DOCS_HINT } from '../../ai/constants';
|
|
10
11
|
import { getCurrentVersion } from '../utils/version';
|
|
11
12
|
import { checkAndInstallPackages } from '../packages/installer';
|
|
12
13
|
import { checkAndUpdatePackages } from '../packages/updater';
|
|
@@ -64,10 +65,13 @@ export class DevStartupPlugin {
|
|
|
64
65
|
// 2. Print current version
|
|
65
66
|
const version = getCurrentVersion();
|
|
66
67
|
if (version) {
|
|
67
|
-
console.log(chalk.dim(` 📦 @djangocfg/nextjs v${version}
|
|
68
|
+
console.log(chalk.dim(` 📦 @djangocfg/nextjs v${version}`));
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
// 3.
|
|
71
|
+
// 3. Print AI docs hint
|
|
72
|
+
console.log(chalk.magenta(` ${AI_DOCS_HINT}\n`));
|
|
73
|
+
|
|
74
|
+
// 4. Check for package updates
|
|
71
75
|
if (this.options.checkUpdates !== false) {
|
|
72
76
|
try {
|
|
73
77
|
await checkAndUpdatePackages({
|
|
@@ -80,7 +84,7 @@ export class DevStartupPlugin {
|
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
|
|
83
|
-
//
|
|
87
|
+
// 5. Check for missing optional packages
|
|
84
88
|
if (this.options.checkPackages !== false) {
|
|
85
89
|
await checkAndInstallPackages({
|
|
86
90
|
autoInstall: this.options.autoInstall,
|