@astro-minimax/cli 0.5.0 → 0.7.0
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 +69 -0
- package/dist/commands/ai.d.ts +2 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +99 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/data.d.ts +2 -0
- package/dist/commands/data.d.ts.map +1 -0
- package/dist/commands/data.js +111 -0
- package/dist/commands/data.js.map +1 -0
- package/dist/commands/hooks.d.ts +2 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +378 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +50 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/post.d.ts +2 -0
- package/dist/commands/post.d.ts.map +1 -0
- package/dist/commands/post.js +190 -0
- package/dist/commands/post.js.map +1 -0
- package/dist/commands/profile.d.ts +2 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +88 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/ai-process.d.ts +20 -0
- package/dist/tools/ai-process.d.ts.map +1 -0
- package/dist/tools/ai-process.js +607 -0
- package/dist/tools/ai-process.js.map +1 -0
- package/dist/tools/build-author-context.d.ts +13 -0
- package/dist/tools/build-author-context.d.ts.map +1 -0
- package/dist/tools/build-author-context.js +313 -0
- package/dist/tools/build-author-context.js.map +1 -0
- package/dist/tools/build-voice-profile.d.ts +12 -0
- package/dist/tools/build-voice-profile.d.ts.map +1 -0
- package/dist/tools/build-voice-profile.js +270 -0
- package/dist/tools/build-voice-profile.js.map +1 -0
- package/dist/tools/eval-ai-chat.d.ts +17 -0
- package/dist/tools/eval-ai-chat.d.ts.map +1 -0
- package/dist/tools/eval-ai-chat.js +332 -0
- package/dist/tools/eval-ai-chat.js.map +1 -0
- package/dist/tools/generate-author-profile.d.ts +14 -0
- package/dist/tools/generate-author-profile.d.ts.map +1 -0
- package/dist/tools/generate-author-profile.js +289 -0
- package/dist/tools/generate-author-profile.js.map +1 -0
- package/dist/tools/generate-cover.d.ts +14 -0
- package/dist/tools/generate-cover.d.ts.map +1 -0
- package/dist/tools/generate-cover.js +95 -0
- package/dist/tools/generate-cover.js.map +1 -0
- package/dist/tools/generate-og.d.ts +3 -0
- package/dist/tools/generate-og.d.ts.map +1 -0
- package/dist/tools/generate-og.js +254 -0
- package/dist/tools/generate-og.js.map +1 -0
- package/dist/tools/generate-related.d.ts +11 -0
- package/dist/tools/generate-related.d.ts.map +1 -0
- package/dist/tools/generate-related.js +124 -0
- package/dist/tools/generate-related.js.map +1 -0
- package/dist/tools/generate-tags.d.ts +14 -0
- package/dist/tools/generate-tags.d.ts.map +1 -0
- package/dist/tools/generate-tags.js +182 -0
- package/dist/tools/generate-tags.js.map +1 -0
- package/dist/tools/lib/ai-provider.d.ts +43 -0
- package/dist/tools/lib/ai-provider.d.ts.map +1 -0
- package/dist/tools/lib/ai-provider.js +146 -0
- package/dist/tools/lib/ai-provider.js.map +1 -0
- package/dist/tools/lib/frontmatter.d.ts +11 -0
- package/dist/tools/lib/frontmatter.d.ts.map +1 -0
- package/dist/tools/lib/frontmatter.js +80 -0
- package/dist/tools/lib/frontmatter.js.map +1 -0
- package/dist/tools/lib/index.d.ts +7 -0
- package/dist/tools/lib/index.d.ts.map +1 -0
- package/{template/tools/lib/index.ts → dist/tools/lib/index.js} +1 -0
- package/dist/tools/lib/index.js.map +1 -0
- package/dist/tools/lib/markdown.d.ts +6 -0
- package/dist/tools/lib/markdown.d.ts.map +1 -0
- package/dist/tools/lib/markdown.js +34 -0
- package/dist/tools/lib/markdown.js.map +1 -0
- package/dist/tools/lib/posts.d.ts +25 -0
- package/dist/tools/lib/posts.d.ts.map +1 -0
- package/dist/tools/lib/posts.js +63 -0
- package/dist/tools/lib/posts.js.map +1 -0
- package/dist/tools/lib/utils.d.ts +18 -0
- package/dist/tools/lib/utils.d.ts.map +1 -0
- package/dist/tools/lib/utils.js +121 -0
- package/dist/tools/lib/utils.js.map +1 -0
- package/dist/tools/lib/vectors.d.ts +27 -0
- package/dist/tools/lib/vectors.d.ts.map +1 -0
- package/dist/tools/lib/vectors.js +64 -0
- package/dist/tools/lib/vectors.js.map +1 -0
- package/dist/tools/summarize.d.ts +16 -0
- package/dist/tools/summarize.d.ts.map +1 -0
- package/dist/tools/summarize.js +108 -0
- package/dist/tools/summarize.js.map +1 -0
- package/dist/tools/translate.d.ts +13 -0
- package/dist/tools/translate.d.ts.map +1 -0
- package/dist/tools/translate.js +46 -0
- package/dist/tools/translate.js.map +1 -0
- package/dist/tools/vectorize.d.ts +13 -0
- package/dist/tools/vectorize.d.ts.map +1 -0
- package/dist/tools/vectorize.js +87 -0
- package/dist/tools/vectorize.js.map +1 -0
- package/package.json +14 -9
- package/template/astro.config.ts +8 -28
- package/template/datas/ai-seo.json +8 -0
- package/template/datas/ai-skip-list.json +1 -0
- package/template/datas/author-profile-context.json +21 -0
- package/template/datas/author-profile-report.json +21 -0
- package/template/datas/eval/gold-set.json +72 -0
- package/template/functions/README.md +82 -0
- package/template/functions/api/ai-info.ts +2 -2
- package/template/functions/api/chat.ts +4 -1
- package/template/functions/api/notify/comment.ts +140 -68
- package/template/functions/api/notify/debug.ts +41 -0
- package/template/functions/api/notify/status.ts +97 -0
- package/template/functions/api/notify/test-ai-chat.ts +67 -0
- package/template/package.json +22 -25
- package/template/src/config.ts +11 -0
- package/template/src/content.config.ts +29 -16
- package/template/src/env.d.ts +0 -5
- package/index.js +0 -36
- package/template/tools/README.md +0 -169
- package/template/tools/ai-process.ts +0 -816
- package/template/tools/build-author-context.ts +0 -405
- package/template/tools/build-voice-profile.ts +0 -322
- package/template/tools/generate-author-profile.ts +0 -369
- package/template/tools/generate-cover.ts +0 -123
- package/template/tools/generate-og.ts +0 -280
- package/template/tools/generate-related.ts +0 -146
- package/template/tools/generate-tags.ts +0 -251
- package/template/tools/lib/ai-provider.ts +0 -240
- package/template/tools/lib/frontmatter.ts +0 -94
- package/template/tools/lib/markdown.ts +0 -40
- package/template/tools/lib/posts.ts +0 -89
- package/template/tools/lib/utils.ts +0 -138
- package/template/tools/lib/vectors.ts +0 -96
- package/template/tools/summarize.ts +0 -142
- package/template/tools/translate.ts +0 -60
- package/template/tools/vectorize.ts +0 -105
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
|
|
3
|
+
interface NotifyStatusEnv {
|
|
4
|
+
NOTIFY_TELEGRAM_BOT_TOKEN?: string;
|
|
5
|
+
NOTIFY_TELEGRAM_CHAT_ID?: string;
|
|
6
|
+
NOTIFY_WEBHOOK_URL?: string;
|
|
7
|
+
NOTIFY_RESEND_API_KEY?: string;
|
|
8
|
+
NOTIFY_RESEND_FROM?: string;
|
|
9
|
+
NOTIFY_RESEND_TO?: string;
|
|
10
|
+
SITE_URL?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ProviderStatus {
|
|
15
|
+
configured: boolean;
|
|
16
|
+
missingFields?: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface NotifyStatusResponse {
|
|
20
|
+
timestamp: string;
|
|
21
|
+
environment: 'production' | 'preview' | 'unknown';
|
|
22
|
+
providers: {
|
|
23
|
+
telegram: ProviderStatus;
|
|
24
|
+
email: ProviderStatus;
|
|
25
|
+
webhook: ProviderStatus;
|
|
26
|
+
};
|
|
27
|
+
siteUrl: {
|
|
28
|
+
configured: boolean;
|
|
29
|
+
value?: string;
|
|
30
|
+
};
|
|
31
|
+
summary: {
|
|
32
|
+
totalProviders: number;
|
|
33
|
+
configuredProviders: number;
|
|
34
|
+
hasAnyProvider: boolean;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const onRequest: PagesFunction<NotifyStatusEnv> = async (context) => {
|
|
39
|
+
const env = context.env;
|
|
40
|
+
|
|
41
|
+
const telegramMissing = [
|
|
42
|
+
!env.NOTIFY_TELEGRAM_BOT_TOKEN && 'NOTIFY_TELEGRAM_BOT_TOKEN',
|
|
43
|
+
!env.NOTIFY_TELEGRAM_CHAT_ID && 'NOTIFY_TELEGRAM_CHAT_ID',
|
|
44
|
+
].filter(Boolean) as string[];
|
|
45
|
+
|
|
46
|
+
const emailMissing = [
|
|
47
|
+
!env.NOTIFY_RESEND_API_KEY && 'NOTIFY_RESEND_API_KEY',
|
|
48
|
+
!env.NOTIFY_RESEND_FROM && 'NOTIFY_RESEND_FROM',
|
|
49
|
+
!env.NOTIFY_RESEND_TO && 'NOTIFY_RESEND_TO',
|
|
50
|
+
].filter(Boolean) as string[];
|
|
51
|
+
|
|
52
|
+
const webhookMissing = [
|
|
53
|
+
!env.NOTIFY_WEBHOOK_URL && 'NOTIFY_WEBHOOK_URL',
|
|
54
|
+
].filter(Boolean) as string[];
|
|
55
|
+
|
|
56
|
+
const environment = context.request.headers.get('x-cf-env') || 'unknown';
|
|
57
|
+
|
|
58
|
+
const providers = {
|
|
59
|
+
telegram: {
|
|
60
|
+
configured: telegramMissing.length === 0,
|
|
61
|
+
missingFields: telegramMissing.length > 0 ? telegramMissing : undefined,
|
|
62
|
+
},
|
|
63
|
+
email: {
|
|
64
|
+
configured: emailMissing.length === 0,
|
|
65
|
+
missingFields: emailMissing.length > 0 ? emailMissing : undefined,
|
|
66
|
+
},
|
|
67
|
+
webhook: {
|
|
68
|
+
configured: webhookMissing.length === 0,
|
|
69
|
+
missingFields: webhookMissing.length > 0 ? webhookMissing : undefined,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const configuredProviders = Object.values(providers).filter(p => p.configured).length;
|
|
74
|
+
|
|
75
|
+
const response: NotifyStatusResponse = {
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
environment: environment as 'production' | 'preview' | 'unknown',
|
|
78
|
+
providers,
|
|
79
|
+
siteUrl: {
|
|
80
|
+
configured: !!env.SITE_URL,
|
|
81
|
+
value: env.SITE_URL ? '[CONFIGURED]' : undefined,
|
|
82
|
+
},
|
|
83
|
+
summary: {
|
|
84
|
+
totalProviders: 3,
|
|
85
|
+
configuredProviders,
|
|
86
|
+
hasAnyProvider: configuredProviders > 0,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return new Response(JSON.stringify(response, null, 2), {
|
|
91
|
+
status: 200,
|
|
92
|
+
headers: {
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
'Cache-Control': 'no-store, no-cache, must-revalidate',
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
|
|
3
|
+
import { notifyAiChat } from '@astro-minimax/ai/server';
|
|
4
|
+
|
|
5
|
+
interface TestEnv {
|
|
6
|
+
NOTIFY_TELEGRAM_BOT_TOKEN?: string;
|
|
7
|
+
NOTIFY_TELEGRAM_CHAT_ID?: string;
|
|
8
|
+
NOTIFY_WEBHOOK_URL?: string;
|
|
9
|
+
NOTIFY_RESEND_API_KEY?: string;
|
|
10
|
+
NOTIFY_RESEND_FROM?: string;
|
|
11
|
+
NOTIFY_RESEND_TO?: string;
|
|
12
|
+
SITE_URL?: string;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const onRequest: PagesFunction<TestEnv> = async (context) => {
|
|
17
|
+
const env = context.env;
|
|
18
|
+
|
|
19
|
+
const result = await notifyAiChat({
|
|
20
|
+
env,
|
|
21
|
+
sessionId: `test-${Date.now()}`,
|
|
22
|
+
messages: [
|
|
23
|
+
{ id: '1', role: 'user', parts: [{ type: 'text', text: '这是一条测试消息' }] }
|
|
24
|
+
],
|
|
25
|
+
aiResponse: '这是一条测试 AI 回复',
|
|
26
|
+
referencedArticles: [
|
|
27
|
+
{ title: '测试文章', url: '/posts/test' }
|
|
28
|
+
],
|
|
29
|
+
model: {
|
|
30
|
+
name: 'test-model',
|
|
31
|
+
provider: 'test',
|
|
32
|
+
},
|
|
33
|
+
usage: {
|
|
34
|
+
total: 150,
|
|
35
|
+
input: 100,
|
|
36
|
+
output: 50,
|
|
37
|
+
},
|
|
38
|
+
timing: {
|
|
39
|
+
total: 1000,
|
|
40
|
+
keywordExtraction: 100,
|
|
41
|
+
search: 200,
|
|
42
|
+
evidenceAnalysis: 100,
|
|
43
|
+
generation: 600,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return new Response(JSON.stringify({
|
|
48
|
+
success: !!result,
|
|
49
|
+
result: result ? {
|
|
50
|
+
event: result.event,
|
|
51
|
+
success: result.success,
|
|
52
|
+
channels: result.results.map(r => ({
|
|
53
|
+
channel: r.channel,
|
|
54
|
+
success: r.success,
|
|
55
|
+
error: r.error,
|
|
56
|
+
})),
|
|
57
|
+
} : null,
|
|
58
|
+
envCheck: {
|
|
59
|
+
hasTelegram: !!env.NOTIFY_TELEGRAM_BOT_TOKEN,
|
|
60
|
+
hasChatId: !!env.NOTIFY_TELEGRAM_CHAT_ID,
|
|
61
|
+
hasResend: !!env.NOTIFY_RESEND_API_KEY,
|
|
62
|
+
},
|
|
63
|
+
}, null, 2), {
|
|
64
|
+
status: 200,
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
});
|
|
67
|
+
};
|
package/template/package.json
CHANGED
|
@@ -5,29 +5,32 @@
|
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "astro dev",
|
|
7
7
|
"dev:ai": "pnpm exec astro-ai-dev",
|
|
8
|
-
"dev:full": "concurrently -n \"astro,ai\" -c \"blue,green\" \"astro dev\" \"pnpm exec astro-ai-dev\"",
|
|
9
8
|
"build": "astro check && astro build && pagefind --site dist && cp -r dist/pagefind public/",
|
|
10
9
|
"preview": "wrangler pages dev dist",
|
|
11
10
|
"preview:astro": "astro preview",
|
|
12
11
|
"lint": "eslint .",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
12
|
+
"cli": "astro-minimax",
|
|
13
|
+
"ai:process": "astro-minimax ai process",
|
|
14
|
+
"ai:seo": "astro-minimax ai seo",
|
|
15
|
+
"ai:summary": "astro-minimax ai summary",
|
|
16
|
+
"ai:eval": "astro-minimax ai eval",
|
|
17
|
+
"profile:build": "astro-minimax profile build",
|
|
18
|
+
"profile:context": "astro-minimax profile context",
|
|
19
|
+
"profile:voice": "astro-minimax profile voice",
|
|
20
|
+
"profile:report": "astro-minimax profile report",
|
|
21
|
+
"post:new": "astro-minimax post new",
|
|
22
|
+
"post:list": "astro-minimax post list",
|
|
23
|
+
"post:stats": "astro-minimax post stats",
|
|
24
|
+
"data:status": "astro-minimax data status",
|
|
25
|
+
"data:clear": "astro-minimax data clear"
|
|
23
26
|
},
|
|
24
27
|
"dependencies": {
|
|
25
28
|
"@ai-sdk/openai-compatible": "^2.0.35",
|
|
26
29
|
"@ai-sdk/react": "^3.0.118",
|
|
27
|
-
"@astro-minimax/ai": "^0.
|
|
28
|
-
"@astro-minimax/core": "^0.
|
|
29
|
-
"@astro-minimax/notify": "^0.
|
|
30
|
-
"@astro-minimax/viz": "^0.
|
|
30
|
+
"@astro-minimax/ai": "^0.5.0",
|
|
31
|
+
"@astro-minimax/core": "^0.5.0",
|
|
32
|
+
"@astro-minimax/notify": "^0.5.0",
|
|
33
|
+
"@astro-minimax/viz": "^0.5.0",
|
|
31
34
|
"@astrojs/mdx": "^5.0.0",
|
|
32
35
|
"@astrojs/preact": "^5.0.0",
|
|
33
36
|
"@astrojs/rss": "^4.0.17",
|
|
@@ -44,34 +47,28 @@
|
|
|
44
47
|
"mermaid": "^11.12.3",
|
|
45
48
|
"preact": "^10.29.0",
|
|
46
49
|
"rehype-katex": "^7.0.1",
|
|
47
|
-
"remark-collapse": "^0.1.2",
|
|
48
50
|
"remark-emoji": "^5.0.2",
|
|
49
51
|
"remark-github-alerts": "^0.1.1",
|
|
50
52
|
"remark-markmap": "^1.1.5",
|
|
51
53
|
"remark-math": "^6.0.0",
|
|
52
|
-
"remark-toc": "^9.0.0",
|
|
53
54
|
"satori": "^0.18.0",
|
|
54
55
|
"sharp": "^0.34.5",
|
|
55
56
|
"slugify": "^1.6.6",
|
|
56
57
|
"tailwindcss": "^4.2.1"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
60
|
+
"@astro-minimax/cli": "^0.6.0",
|
|
59
61
|
"@astrojs/check": "^0.9.6",
|
|
60
62
|
"@cloudflare/workers-types": "^4.20260313.1",
|
|
61
63
|
"@pagefind/default-ui": "^1.4.0",
|
|
62
|
-
"@shikijs/transformers": "^4.0.
|
|
64
|
+
"@shikijs/transformers": "^4.0.2",
|
|
63
65
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
64
|
-
"@types/mdast": "^4.0.4",
|
|
65
|
-
"concurrently": "^9.1.2",
|
|
66
66
|
"eslint": "^9.39.3",
|
|
67
67
|
"eslint-plugin-astro": "^1.6.0",
|
|
68
|
-
"globals": "^16.
|
|
68
|
+
"globals": "^16.5.0",
|
|
69
69
|
"pagefind": "^1.4.0",
|
|
70
|
-
"tsx": "^4.21.0",
|
|
71
70
|
"typescript": "^5.9.3",
|
|
72
|
-
"typescript-eslint": "^8.
|
|
73
|
-
"undici": "^7.24.1",
|
|
74
|
-
"unist-util-visit": "^5.1.0",
|
|
71
|
+
"typescript-eslint": "^8.56.1",
|
|
75
72
|
"wrangler": "^4.73.0"
|
|
76
73
|
}
|
|
77
74
|
}
|
package/template/src/config.ts
CHANGED
|
@@ -87,6 +87,17 @@ export const SITE: SiteConfig = {
|
|
|
87
87
|
// src: "https://your-umami-instance.com/script.js",
|
|
88
88
|
// },
|
|
89
89
|
|
|
90
|
+
// Search provider: 'pagefind' (default, static) or 'docsearch' (Algolia)
|
|
91
|
+
// search: {
|
|
92
|
+
// provider: 'docsearch',
|
|
93
|
+
// docsearch: {
|
|
94
|
+
// appId: 'YOUR_ALGOLIA_APP_ID',
|
|
95
|
+
// apiKey: 'YOUR_ALGOLIA_SEARCH_API_KEY',
|
|
96
|
+
// indexName: 'YOUR_INDEX_NAME',
|
|
97
|
+
// placeholder: 'Search docs...',
|
|
98
|
+
// },
|
|
99
|
+
// },
|
|
100
|
+
|
|
90
101
|
copyright: {
|
|
91
102
|
license: "CC BY-NC-SA 4.0",
|
|
92
103
|
licenseUrl: "https://creativecommons.org/licenses/by-nc-sa/4.0/",
|
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import { defineCollection } from "astro:content";
|
|
2
2
|
import { z } from "astro/zod";
|
|
3
3
|
import { glob } from "astro/loaders";
|
|
4
|
+
import { SITE } from "@/config";
|
|
5
|
+
|
|
6
|
+
export const BLOG_PATH = "src/data/blog";
|
|
4
7
|
|
|
5
8
|
const blog = defineCollection({
|
|
6
9
|
loader: glob({
|
|
7
10
|
pattern: "**/[^_]*.{md,mdx}",
|
|
8
|
-
base:
|
|
9
|
-
generateId: ({ entry }) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
title: z.string(),
|
|
13
|
-
description: z.string(),
|
|
14
|
-
pubDatetime: z.date(),
|
|
15
|
-
modDatetime: z.date().optional().nullable(),
|
|
16
|
-
author: z.string().optional(),
|
|
17
|
-
tags: z.array(z.string()).default(["others"]),
|
|
18
|
-
category: z.string().optional(),
|
|
19
|
-
series: z.object({ name: z.string(), order: z.number() }).optional(),
|
|
20
|
-
featured: z.boolean().optional(),
|
|
21
|
-
draft: z.boolean().optional(),
|
|
22
|
-
ogImage: z.string().optional(),
|
|
23
|
-
canonicalURL: z.string().optional(),
|
|
11
|
+
base: `./${BLOG_PATH}`,
|
|
12
|
+
generateId: ({ entry }) => {
|
|
13
|
+
return entry.replace(/\.(md|mdx)$/, "");
|
|
14
|
+
},
|
|
24
15
|
}),
|
|
16
|
+
schema: ({ image }) =>
|
|
17
|
+
z.object({
|
|
18
|
+
author: z.string().default(SITE.author),
|
|
19
|
+
pubDatetime: z.date(),
|
|
20
|
+
modDatetime: z.date().optional().nullable(),
|
|
21
|
+
title: z.string(),
|
|
22
|
+
featured: z.boolean().optional(),
|
|
23
|
+
draft: z.boolean().optional(),
|
|
24
|
+
tags: z.array(z.string()).default(["others"]),
|
|
25
|
+
category: z.string().optional(),
|
|
26
|
+
series: z
|
|
27
|
+
.object({
|
|
28
|
+
name: z.string(),
|
|
29
|
+
order: z.number(),
|
|
30
|
+
})
|
|
31
|
+
.optional(),
|
|
32
|
+
ogImage: image().or(z.string()).optional(),
|
|
33
|
+
description: z.string(),
|
|
34
|
+
canonicalURL: z.string().optional(),
|
|
35
|
+
hideEditPost: z.boolean().optional(),
|
|
36
|
+
timezone: z.string().optional(),
|
|
37
|
+
}),
|
|
25
38
|
});
|
|
26
39
|
|
|
27
40
|
export const collections = { blog };
|
package/template/src/env.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
/// <reference types="astro/content" />
|
|
2
|
-
declare module "remark-collapse" {
|
|
3
|
-
import type { Plugin } from "unified";
|
|
4
|
-
const plugin: Plugin;
|
|
5
|
-
export default plugin;
|
|
6
|
-
}
|
|
7
2
|
declare module "remark-github-alerts" {
|
|
8
3
|
import type { Plugin } from "unified";
|
|
9
4
|
const plugin: Plugin;
|
package/index.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join, resolve, basename } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
|
|
6
|
-
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
7
|
-
const templateDir = join(__dirname, "template");
|
|
8
|
-
|
|
9
|
-
const projectName = process.argv[2];
|
|
10
|
-
if (!projectName) {
|
|
11
|
-
console.error("Usage: astro-minimax <project-name>");
|
|
12
|
-
console.error(" npx @astro-minimax/cli <project-name>");
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const targetDir = resolve(process.cwd(), projectName);
|
|
17
|
-
|
|
18
|
-
if (existsSync(targetDir)) {
|
|
19
|
-
console.error(`Directory "${projectName}" already exists.`);
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
mkdirSync(targetDir, { recursive: true });
|
|
24
|
-
cpSync(templateDir, targetDir, { recursive: true });
|
|
25
|
-
|
|
26
|
-
const pkgPath = join(targetDir, "package.json");
|
|
27
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
28
|
-
pkg.name = basename(targetDir);
|
|
29
|
-
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
30
|
-
|
|
31
|
-
console.log(`\n ✅ Created "${projectName}" successfully!\n`);
|
|
32
|
-
console.log(" Next steps:\n");
|
|
33
|
-
console.log(` cd ${projectName}`);
|
|
34
|
-
console.log(" pnpm install");
|
|
35
|
-
console.log(" pnpm dev\n");
|
|
36
|
-
console.log(" Docs: https://github.com/souloss/astro-minimax\n");
|
package/template/tools/README.md
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
# AI 数据构建工具
|
|
2
|
-
|
|
3
|
-
本目录包含用于博客内容处理和 AI 功能数据构建的工具脚本。
|
|
4
|
-
|
|
5
|
-
## 环境配置
|
|
6
|
-
|
|
7
|
-
在 `.env` 文件中配置以下环境变量:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# AI API 配置(必需,用于 AI 相关脚本)
|
|
11
|
-
AI_API_KEY=your_api_key
|
|
12
|
-
AI_BASE_URL=https://api.openai.com # 或其他 OpenAI 兼容 API
|
|
13
|
-
AI_MODEL=gpt-4o-mini # 模型名称
|
|
14
|
-
|
|
15
|
-
# 站点配置(可选)
|
|
16
|
-
SITE_URL=https://your-domain.com
|
|
17
|
-
SITE_AUTHOR=博主名称
|
|
18
|
-
SITE_DESCRIPTION=站点描述
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## 脚本列表
|
|
22
|
-
|
|
23
|
-
### 内容处理
|
|
24
|
-
|
|
25
|
-
| 脚本 | 命令 | 说明 |
|
|
26
|
-
|------|------|------|
|
|
27
|
-
| `ai-process.ts` | `pnpm ai:process` | AI 文章批处理(摘要、SEO) |
|
|
28
|
-
| `summarize.ts` | `pnpm tools:summarize` | 生成文章摘要 |
|
|
29
|
-
| `generate-related.ts` | `pnpm tools:generate-related` | 生成相关文章 |
|
|
30
|
-
| `generate-tags.ts` | `pnpm tools:tags` | 生成文章标签 |
|
|
31
|
-
| `translate.ts` | `pnpm tools:translate` | 文章翻译 |
|
|
32
|
-
| `vectorize.ts` | `pnpm tools:vectorize` | 生成文章向量 |
|
|
33
|
-
| `generate-cover.ts` | `pnpm tools:cover` | 生成文章封面 |
|
|
34
|
-
| `generate-og.ts` | `pnpm og` | 生成 OG 图片 |
|
|
35
|
-
|
|
36
|
-
### AI 分身数据构建
|
|
37
|
-
|
|
38
|
-
| 脚本 | 命令 | 说明 |
|
|
39
|
-
|------|------|------|
|
|
40
|
-
| `build-author-context.ts` | `pnpm context:build` | 构建作者上下文数据 |
|
|
41
|
-
| `build-voice-profile.ts` | `pnpm voice:build` | 构建表达风格画像 |
|
|
42
|
-
| `generate-author-profile.ts` | `pnpm profile:generate` | 生成作者画像报告 |
|
|
43
|
-
|
|
44
|
-
## 详细说明
|
|
45
|
-
|
|
46
|
-
### ai-process.ts — AI 文章批处理
|
|
47
|
-
|
|
48
|
-
为文章生成 AI 摘要和 SEO 元数据。
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# 处理所有文章
|
|
52
|
-
pnpm ai:process
|
|
53
|
-
|
|
54
|
-
# 只处理中文文章
|
|
55
|
-
pnpm ai:process --lang=zh
|
|
56
|
-
|
|
57
|
-
# 只处理指定文章
|
|
58
|
-
pnpm ai:process --slug=zh/getting-started
|
|
59
|
-
|
|
60
|
-
# 只生成摘要
|
|
61
|
-
pnpm ai:process --task=summary
|
|
62
|
-
|
|
63
|
-
# 预览模式
|
|
64
|
-
pnpm ai:process --dry-run
|
|
65
|
-
|
|
66
|
-
# 强制重新处理
|
|
67
|
-
pnpm ai:process --force
|
|
68
|
-
|
|
69
|
-
# 清空跳过列表后重试
|
|
70
|
-
pnpm ai:process --clear-skip
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**输出文件**:
|
|
74
|
-
- `datas/ai-summaries.json` — 文章摘要数据
|
|
75
|
-
- `datas/ai-seo.json` — SEO 元数据
|
|
76
|
-
- `datas/ai-skip-list.json` — 失败文章跳过列表
|
|
77
|
-
|
|
78
|
-
### build-author-context.ts — 构建作者上下文
|
|
79
|
-
|
|
80
|
-
聚合博客文章数据,为 AI 分身对话提供上下文。
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
pnpm context:build
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
**输出文件**:
|
|
87
|
-
- `datas/author-context.json` — 作者上下文数据
|
|
88
|
-
- `datas/sources/blog-digest.json` — 文章摘要
|
|
89
|
-
|
|
90
|
-
### build-voice-profile.ts — 构建表达风格画像
|
|
91
|
-
|
|
92
|
-
从博客标题、正文中提取作者的表达风格特征。纯本地分析,不调用 AI。
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
pnpm voice:build
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**输出文件**:
|
|
99
|
-
- `datas/voice-profile.json` — 表达风格画像
|
|
100
|
-
|
|
101
|
-
### generate-author-profile.ts — 生成作者画像报告
|
|
102
|
-
|
|
103
|
-
基于上下文数据生成用于 About 页面的结构化简介。
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# AI 生成(需要配置 AI API)
|
|
107
|
-
pnpm profile:generate
|
|
108
|
-
|
|
109
|
-
# 使用规则模板(不需要 AI)
|
|
110
|
-
pnpm profile:generate --no-ai
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**输出文件**:
|
|
114
|
-
- `datas/author-profile-report.json` — 画像报告
|
|
115
|
-
- `datas/author-profile-context.json` — 生成上下文
|
|
116
|
-
|
|
117
|
-
## 输出目录结构
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
datas/
|
|
121
|
-
├── ai-summaries.json # AI 生成的文章摘要
|
|
122
|
-
├── ai-seo.json # AI 生成的 SEO 数据
|
|
123
|
-
├── ai-skip-list.json # AI 处理失败的文章列表
|
|
124
|
-
├── author-context.json # 作者上下文(AI 分身使用)
|
|
125
|
-
├── author-profile-report.json # 作者画像报告
|
|
126
|
-
├── author-profile-context.json
|
|
127
|
-
├── voice-profile.json # 表达风格画像
|
|
128
|
-
└── sources/
|
|
129
|
-
└── blog-digest.json # 文章摘要数据
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## 开发说明
|
|
133
|
-
|
|
134
|
-
### 共享模块
|
|
135
|
-
|
|
136
|
-
- `lib/ai-provider.ts` — AI API 调用封装(支持代理)
|
|
137
|
-
- `lib/utils.ts` — 通用工具函数
|
|
138
|
-
- `lib/posts.ts` — 文章读取工具
|
|
139
|
-
- `lib/frontmatter.ts` — Frontmatter 解析
|
|
140
|
-
- `lib/markdown.ts` — Markdown 处理
|
|
141
|
-
|
|
142
|
-
### AI Provider 使用
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
import { chatCompletion, hasAPIKey, getConfig } from "./lib/ai-provider.js";
|
|
146
|
-
|
|
147
|
-
if (hasAPIKey()) {
|
|
148
|
-
const result = await chatCompletion([
|
|
149
|
-
{ role: "system", content: "系统提示" },
|
|
150
|
-
{ role: "user", content: "用户输入" },
|
|
151
|
-
], { maxTokens: 2000, responseFormat: "json" });
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### URL 策略
|
|
156
|
-
|
|
157
|
-
工具脚本生成的 URL 均为**相对路径**(如 `/zh/my-post`),不包含域名前缀。在 AI 对话运行时,`initializeMetadata()` 会根据 `SITE_URL` 环境变量动态拼接完整 URL。这使得生成的数据文件与部署环境无关。
|
|
158
|
-
|
|
159
|
-
### 数据文件与 AI 对话的关系
|
|
160
|
-
|
|
161
|
-
`datas/` 目录中的 JSON 文件在运行时被 `@astro-minimax/ai/server` 的 `initializeMetadata()` 加载,用于构建搜索索引和系统提示词上下文。
|
|
162
|
-
|
|
163
|
-
### 代理支持
|
|
164
|
-
|
|
165
|
-
脚本自动支持 `HTTP_PROXY` / `HTTPS_PROXY` 环境变量,无需额外配置。
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
export HTTPS_PROXY=http://127.0.0.1:7890
|
|
169
|
-
```
|