@astro-minimax/cli 0.5.0 → 0.7.1

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.
Files changed (174) hide show
  1. package/README.md +69 -0
  2. package/dist/commands/ai.d.ts +2 -0
  3. package/dist/commands/ai.d.ts.map +1 -0
  4. package/dist/commands/ai.js +99 -0
  5. package/dist/commands/ai.js.map +1 -0
  6. package/dist/commands/data.d.ts +2 -0
  7. package/dist/commands/data.d.ts.map +1 -0
  8. package/dist/commands/data.js +111 -0
  9. package/dist/commands/data.js.map +1 -0
  10. package/dist/commands/hooks.d.ts +2 -0
  11. package/dist/commands/hooks.d.ts.map +1 -0
  12. package/dist/commands/hooks.js +378 -0
  13. package/dist/commands/hooks.js.map +1 -0
  14. package/dist/commands/init.d.ts +2 -0
  15. package/dist/commands/init.d.ts.map +1 -0
  16. package/dist/commands/init.js +50 -0
  17. package/dist/commands/init.js.map +1 -0
  18. package/dist/commands/podcast.d.ts +2 -0
  19. package/dist/commands/podcast.d.ts.map +1 -0
  20. package/dist/commands/podcast.js +89 -0
  21. package/dist/commands/podcast.js.map +1 -0
  22. package/dist/commands/post.d.ts +2 -0
  23. package/dist/commands/post.d.ts.map +1 -0
  24. package/dist/commands/post.js +190 -0
  25. package/dist/commands/post.js.map +1 -0
  26. package/dist/commands/profile.d.ts +2 -0
  27. package/dist/commands/profile.d.ts.map +1 -0
  28. package/dist/commands/profile.js +88 -0
  29. package/dist/commands/profile.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +81 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/tools/ai-process.d.ts +20 -0
  35. package/dist/tools/ai-process.d.ts.map +1 -0
  36. package/dist/tools/ai-process.js +607 -0
  37. package/dist/tools/ai-process.js.map +1 -0
  38. package/dist/tools/build-author-context.d.ts +13 -0
  39. package/dist/tools/build-author-context.d.ts.map +1 -0
  40. package/dist/tools/build-author-context.js +313 -0
  41. package/dist/tools/build-author-context.js.map +1 -0
  42. package/dist/tools/build-voice-profile.d.ts +12 -0
  43. package/dist/tools/build-voice-profile.d.ts.map +1 -0
  44. package/dist/tools/build-voice-profile.js +270 -0
  45. package/dist/tools/build-voice-profile.js.map +1 -0
  46. package/dist/tools/eval-ai-chat.d.ts +17 -0
  47. package/dist/tools/eval-ai-chat.d.ts.map +1 -0
  48. package/dist/tools/eval-ai-chat.js +362 -0
  49. package/dist/tools/eval-ai-chat.js.map +1 -0
  50. package/dist/tools/generate-author-profile.d.ts +14 -0
  51. package/dist/tools/generate-author-profile.d.ts.map +1 -0
  52. package/dist/tools/generate-author-profile.js +289 -0
  53. package/dist/tools/generate-author-profile.js.map +1 -0
  54. package/dist/tools/generate-cover.d.ts +14 -0
  55. package/dist/tools/generate-cover.d.ts.map +1 -0
  56. package/dist/tools/generate-cover.js +95 -0
  57. package/dist/tools/generate-cover.js.map +1 -0
  58. package/dist/tools/generate-og.d.ts +3 -0
  59. package/dist/tools/generate-og.d.ts.map +1 -0
  60. package/dist/tools/generate-og.js +254 -0
  61. package/dist/tools/generate-og.js.map +1 -0
  62. package/dist/tools/generate-related.d.ts +11 -0
  63. package/dist/tools/generate-related.d.ts.map +1 -0
  64. package/dist/tools/generate-related.js +124 -0
  65. package/dist/tools/generate-related.js.map +1 -0
  66. package/dist/tools/generate-tags.d.ts +14 -0
  67. package/dist/tools/generate-tags.d.ts.map +1 -0
  68. package/dist/tools/generate-tags.js +182 -0
  69. package/dist/tools/generate-tags.js.map +1 -0
  70. package/dist/tools/lib/ai-provider.d.ts +43 -0
  71. package/dist/tools/lib/ai-provider.d.ts.map +1 -0
  72. package/dist/tools/lib/ai-provider.js +146 -0
  73. package/dist/tools/lib/ai-provider.js.map +1 -0
  74. package/dist/tools/lib/audio-processor.d.ts +46 -0
  75. package/dist/tools/lib/audio-processor.d.ts.map +1 -0
  76. package/dist/tools/lib/audio-processor.js +188 -0
  77. package/dist/tools/lib/audio-processor.js.map +1 -0
  78. package/dist/tools/lib/frontmatter.d.ts +11 -0
  79. package/dist/tools/lib/frontmatter.d.ts.map +1 -0
  80. package/dist/tools/lib/frontmatter.js +80 -0
  81. package/dist/tools/lib/frontmatter.js.map +1 -0
  82. package/dist/tools/lib/index.d.ts +7 -0
  83. package/dist/tools/lib/index.d.ts.map +1 -0
  84. package/{template/tools/lib/index.ts → dist/tools/lib/index.js} +1 -0
  85. package/dist/tools/lib/index.js.map +1 -0
  86. package/dist/tools/lib/markdown.d.ts +6 -0
  87. package/dist/tools/lib/markdown.d.ts.map +1 -0
  88. package/dist/tools/lib/markdown.js +34 -0
  89. package/dist/tools/lib/markdown.js.map +1 -0
  90. package/dist/tools/lib/posts.d.ts +25 -0
  91. package/dist/tools/lib/posts.d.ts.map +1 -0
  92. package/dist/tools/lib/posts.js +63 -0
  93. package/dist/tools/lib/posts.js.map +1 -0
  94. package/dist/tools/lib/script-generator.d.ts +61 -0
  95. package/dist/tools/lib/script-generator.d.ts.map +1 -0
  96. package/dist/tools/lib/script-generator.js +182 -0
  97. package/dist/tools/lib/script-generator.js.map +1 -0
  98. package/dist/tools/lib/tts-provider.d.ts +65 -0
  99. package/dist/tools/lib/tts-provider.d.ts.map +1 -0
  100. package/dist/tools/lib/tts-provider.js +116 -0
  101. package/dist/tools/lib/tts-provider.js.map +1 -0
  102. package/dist/tools/lib/types.d.ts +129 -0
  103. package/dist/tools/lib/types.d.ts.map +1 -0
  104. package/dist/tools/lib/types.js +64 -0
  105. package/dist/tools/lib/types.js.map +1 -0
  106. package/dist/tools/lib/utils.d.ts +18 -0
  107. package/dist/tools/lib/utils.d.ts.map +1 -0
  108. package/dist/tools/lib/utils.js +121 -0
  109. package/dist/tools/lib/utils.js.map +1 -0
  110. package/dist/tools/lib/vectors.d.ts +27 -0
  111. package/dist/tools/lib/vectors.d.ts.map +1 -0
  112. package/dist/tools/lib/vectors.js +64 -0
  113. package/dist/tools/lib/vectors.js.map +1 -0
  114. package/dist/tools/podcast-feed.d.ts +6 -0
  115. package/dist/tools/podcast-feed.d.ts.map +1 -0
  116. package/dist/tools/podcast-feed.js +121 -0
  117. package/dist/tools/podcast-feed.js.map +1 -0
  118. package/dist/tools/podcast-generate.d.ts +15 -0
  119. package/dist/tools/podcast-generate.d.ts.map +1 -0
  120. package/dist/tools/podcast-generate.js +318 -0
  121. package/dist/tools/podcast-generate.js.map +1 -0
  122. package/dist/tools/podcast-list.d.ts +6 -0
  123. package/dist/tools/podcast-list.d.ts.map +1 -0
  124. package/dist/tools/podcast-list.js +66 -0
  125. package/dist/tools/podcast-list.js.map +1 -0
  126. package/dist/tools/summarize.d.ts +16 -0
  127. package/dist/tools/summarize.d.ts.map +1 -0
  128. package/dist/tools/summarize.js +108 -0
  129. package/dist/tools/summarize.js.map +1 -0
  130. package/dist/tools/translate.d.ts +13 -0
  131. package/dist/tools/translate.d.ts.map +1 -0
  132. package/dist/tools/translate.js +46 -0
  133. package/dist/tools/translate.js.map +1 -0
  134. package/dist/tools/vectorize.d.ts +13 -0
  135. package/dist/tools/vectorize.d.ts.map +1 -0
  136. package/dist/tools/vectorize.js +87 -0
  137. package/dist/tools/vectorize.js.map +1 -0
  138. package/package.json +14 -9
  139. package/template/astro.config.ts +8 -28
  140. package/template/datas/ai-seo.json +8 -0
  141. package/template/datas/ai-skip-list.json +1 -0
  142. package/template/datas/author-profile-context.json +21 -0
  143. package/template/datas/author-profile-report.json +21 -0
  144. package/template/datas/eval/gold-set.json +72 -0
  145. package/template/functions/README.md +82 -0
  146. package/template/functions/api/ai-info.ts +2 -2
  147. package/template/functions/api/chat.ts +4 -1
  148. package/template/functions/api/notify/comment.ts +140 -68
  149. package/template/functions/api/notify/debug.ts +41 -0
  150. package/template/functions/api/notify/status.ts +97 -0
  151. package/template/functions/api/notify/test-ai-chat.ts +67 -0
  152. package/template/package.json +22 -25
  153. package/template/src/config.ts +11 -0
  154. package/template/src/content.config.ts +29 -16
  155. package/template/src/env.d.ts +0 -5
  156. package/index.js +0 -36
  157. package/template/tools/README.md +0 -169
  158. package/template/tools/ai-process.ts +0 -816
  159. package/template/tools/build-author-context.ts +0 -405
  160. package/template/tools/build-voice-profile.ts +0 -322
  161. package/template/tools/generate-author-profile.ts +0 -369
  162. package/template/tools/generate-cover.ts +0 -123
  163. package/template/tools/generate-og.ts +0 -280
  164. package/template/tools/generate-related.ts +0 -146
  165. package/template/tools/generate-tags.ts +0 -251
  166. package/template/tools/lib/ai-provider.ts +0 -240
  167. package/template/tools/lib/frontmatter.ts +0 -94
  168. package/template/tools/lib/markdown.ts +0 -40
  169. package/template/tools/lib/posts.ts +0 -89
  170. package/template/tools/lib/utils.ts +0 -138
  171. package/template/tools/lib/vectors.ts +0 -96
  172. package/template/tools/summarize.ts +0 -142
  173. package/template/tools/translate.ts +0 -60
  174. package/template/tools/vectorize.ts +0 -105
@@ -0,0 +1,378 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join, dirname, relative } from "node:path";
3
+ import { readFile, writeFile, mkdir, rm } from "node:fs/promises";
4
+ import { exec } from "node:child_process";
5
+ import { promisify } from "node:util";
6
+ const execAsync = promisify(exec);
7
+ function findGitRoot(startDir) {
8
+ let dir = startDir;
9
+ while (dir !== "/") {
10
+ if (existsSync(join(dir, ".git"))) {
11
+ return dir;
12
+ }
13
+ dir = dirname(dir);
14
+ }
15
+ return null;
16
+ }
17
+ function findBlogRoot(startDir) {
18
+ let dir = startDir;
19
+ while (dir !== "/") {
20
+ if (existsSync(join(dir, "src", "data", "blog"))) {
21
+ return dir;
22
+ }
23
+ if (existsSync(join(dir, "pnpm-workspace.yaml")) &&
24
+ existsSync(join(dir, "apps", "blog", "src", "data", "blog"))) {
25
+ return join(dir, "apps", "blog");
26
+ }
27
+ dir = dirname(dir);
28
+ }
29
+ return null;
30
+ }
31
+ function detectPackageManager(dir) {
32
+ if (existsSync(join(dir, "pnpm-lock.yaml")))
33
+ return "pnpm";
34
+ if (existsSync(join(dir, "yarn.lock")))
35
+ return "yarn";
36
+ return "npm";
37
+ }
38
+ function isMonorepo(dir) {
39
+ return (existsSync(join(dir, "pnpm-workspace.yaml")) ||
40
+ existsSync(join(dir, "apps")) ||
41
+ existsSync(join(dir, "packages")));
42
+ }
43
+ function analyzeProject() {
44
+ const cwd = process.cwd();
45
+ const gitRoot = findGitRoot(cwd);
46
+ const blogRoot = findBlogRoot(cwd);
47
+ if (!gitRoot) {
48
+ return null;
49
+ }
50
+ if (!blogRoot) {
51
+ return null;
52
+ }
53
+ const blogPath = join(blogRoot, "src", "data", "blog");
54
+ const blogPkgPath = join(blogRoot, "package.json");
55
+ const monorepo = isMonorepo(gitRoot);
56
+ const installPath = monorepo ? gitRoot : blogRoot;
57
+ const installPkgPath = join(installPath, "package.json");
58
+ const relativeBlogPath = relative(installPath, blogPath);
59
+ return {
60
+ gitRoot,
61
+ blogPath,
62
+ blogPkgPath,
63
+ installPath,
64
+ installPkgPath,
65
+ isMonorepo: monorepo,
66
+ relativeBlogPath,
67
+ };
68
+ }
69
+ function generatePreCommitScript(ctx) {
70
+ const blogPattern = ctx.isMonorepo
71
+ ? `${ctx.relativeBlogPath}/*.md|${ctx.relativeBlogPath}/**/*.md`
72
+ : `src/data/blog/*.md|src/data/blog/**/*.md`;
73
+ return `#!/usr/bin/env sh
74
+ . "$(dirname -- "$0")/_/husky.sh"
75
+
76
+ # astro-minimax pre-commit hook
77
+ # Auto-fill pubDatetime/modDatetime only when empty or missing
78
+ # Will NOT overwrite manually specified dates
79
+
80
+ git diff --cached --name-status | while read -r status file; do
81
+ case "$file" in
82
+ ${blogPattern})
83
+ case "$status" in
84
+ M)
85
+ filecontent=$(cat "$file" 2>/dev/null) || continue
86
+ frontmatter=$(echo "$filecontent" | awk -v RS='---' 'NR==2{print}')
87
+ draft=$(echo "$frontmatter" | awk '/^draft: /{print $2}')
88
+
89
+ if [ "$draft" = "false" ]; then
90
+ modDatetime=$(echo "$frontmatter" | awk '/^modDatetime: /{print $2}')
91
+ if [ -z "$modDatetime" ] || [ "$modDatetime" = "" ]; then
92
+ echo "Auto-filled modDatetime: $file"
93
+ sed -i.bak "/---.*/,/---.*/s/^modDatetime:.*$/modDatetime: $(date -u "+%Y-%m-%dT%H:%M:%SZ")/" "$file" && rm -f "$file.bak"
94
+ git add "$file"
95
+ fi
96
+ fi
97
+
98
+ if [ "$draft" = "first" ]; then
99
+ echo "First release: $file"
100
+ sed -i.bak -e "/---.*/,/---.*/s/^modDatetime:.*$/modDatetime:/" -e "/---.*/,/---.*/s/^draft:.*$/draft: false/" "$file" && rm -f "$file.bak"
101
+ git add "$file"
102
+ fi
103
+ ;;
104
+ A)
105
+ filecontent=$(cat "$file" 2>/dev/null) || continue
106
+ frontmatter=$(echo "$filecontent" | awk -v RS='---' 'NR==2{print}')
107
+ pubDatetime=$(echo "$frontmatter" | awk '/^pubDatetime: /{print $2}')
108
+
109
+ if [ -z "$pubDatetime" ] || [ "$pubDatetime" = "" ]; then
110
+ echo "Auto-filled pubDatetime: $file"
111
+ sed -i.bak "/---.*/,/---.*/s/^pubDatetime:.*$/pubDatetime: $(date -u "+%Y-%m-%dT%H:%M:%SZ")/" "$file" && rm -f "$file.bak"
112
+ git add "$file"
113
+ fi
114
+ ;;
115
+ esac
116
+ ;;
117
+ esac
118
+ done
119
+ `;
120
+ }
121
+ async function getInstallCommand(pm, isMonorepo) {
122
+ if (isMonorepo) {
123
+ switch (pm) {
124
+ case "pnpm":
125
+ return "pnpm add -Dw husky";
126
+ case "yarn":
127
+ return "yarn add -DW husky";
128
+ case "npm":
129
+ return "npm install -D -w . husky";
130
+ }
131
+ }
132
+ switch (pm) {
133
+ case "pnpm":
134
+ return "pnpm add -D husky";
135
+ case "yarn":
136
+ return "yarn add -D husky";
137
+ case "npm":
138
+ return "npm install -D husky";
139
+ }
140
+ }
141
+ async function getRemoveCommand(pm, isMonorepo) {
142
+ if (isMonorepo) {
143
+ switch (pm) {
144
+ case "pnpm":
145
+ return "pnpm remove -w husky";
146
+ case "yarn":
147
+ return "yarn remove -W husky";
148
+ case "npm":
149
+ return "npm uninstall -w . husky";
150
+ }
151
+ }
152
+ switch (pm) {
153
+ case "pnpm":
154
+ return "pnpm remove husky";
155
+ case "yarn":
156
+ return "yarn remove husky";
157
+ case "npm":
158
+ return "npm uninstall husky";
159
+ }
160
+ }
161
+ async function installCommand() {
162
+ const ctx = analyzeProject();
163
+ if (!ctx) {
164
+ console.error("\n Error: Could not find a valid blog project.");
165
+ console.error(" Make sure you're in an astro-minimax blog directory with git initialized.\n");
166
+ process.exit(1);
167
+ }
168
+ if (!existsSync(ctx.installPkgPath)) {
169
+ console.error(`\n Error: package.json not found at ${ctx.installPath}`);
170
+ console.error(" Run this command from your blog's root directory.\n");
171
+ process.exit(1);
172
+ }
173
+ const pm = detectPackageManager(ctx.installPath);
174
+ console.log(`\n Project type: ${ctx.isMonorepo ? "Monorepo" : "Single project"}`);
175
+ console.log(` Git root: ${ctx.gitRoot}`);
176
+ console.log(` Blog path: ${ctx.blogPath}`);
177
+ console.log(` Package manager: ${pm}`);
178
+ console.log(`\n Installing husky...\n`);
179
+ try {
180
+ const installCmd = await getInstallCommand(pm, ctx.isMonorepo);
181
+ await execAsync(installCmd, { cwd: ctx.installPath });
182
+ console.log(" ✅ Husky installed\n");
183
+ }
184
+ catch (error) {
185
+ const message = error instanceof Error ? error.message : String(error);
186
+ if (message.includes("workspace")) {
187
+ console.error(" ❌ Failed to install husky in monorepo.");
188
+ console.error(" Try running: pnpm add -Dw husky (at monorepo root)\n");
189
+ }
190
+ else {
191
+ console.error(` ❌ Failed to install husky: ${message}\n`);
192
+ }
193
+ process.exit(1);
194
+ }
195
+ console.log(" Initializing husky...\n");
196
+ try {
197
+ await execAsync("npx husky init", { cwd: ctx.installPath });
198
+ console.log(" ✅ Husky initialized\n");
199
+ }
200
+ catch {
201
+ const huskyDir = join(ctx.installPath, ".husky");
202
+ const huskyUnderscoreDir = join(huskyDir, "_");
203
+ await mkdir(huskyUnderscoreDir, { recursive: true });
204
+ await writeFile(join(huskyUnderscoreDir, "husky.sh"), `#!/usr/bin/env sh
205
+ if [ -z "$husky_skip_init" ]; then
206
+ debug () {
207
+ if [ "$HUSKY_DEBUG" = "1" ]; then
208
+ echo "husky (debug) - $1"
209
+ fi
210
+ }
211
+
212
+ readonly hook_name="\$(basename "\$0")"
213
+ debug "starting $hook_name..."
214
+
215
+ if [ "$HUSKY" = "0" ]; then
216
+ debug "HUSKY env variable is set to 0, skipping hook"
217
+ exit 0
218
+ fi
219
+
220
+ if [ -f ~/.huskyrc ]; then
221
+ debug "sourcing ~/.huskyrc"
222
+ . ~/.huskyrc
223
+ fi
224
+
225
+ readonly husky_skip_init=1
226
+ export husky_skip_init
227
+ sh -e "\$0" "\$@"
228
+ exitCode="\$?"
229
+
230
+ if [ $exitCode != 0 ]; then
231
+ echo "husky - $hook_name hook exited with code $exitCode (error)"
232
+ fi
233
+
234
+ exit $exitCode
235
+ fi
236
+ `);
237
+ }
238
+ const huskyDir = join(ctx.installPath, ".husky");
239
+ await mkdir(huskyDir, { recursive: true });
240
+ const preCommitPath = join(huskyDir, "pre-commit");
241
+ const script = generatePreCommitScript(ctx);
242
+ await writeFile(preCommitPath, script, { mode: 0o755 });
243
+ console.log(" ✅ Created .husky/pre-commit\n");
244
+ try {
245
+ const pkgContent = await readFile(ctx.installPkgPath, "utf-8");
246
+ const pkg = JSON.parse(pkgContent);
247
+ pkg.scripts = pkg.scripts || {};
248
+ pkg.scripts.prepare = "husky";
249
+ await writeFile(ctx.installPkgPath, JSON.stringify(pkg, null, 2) + "\n");
250
+ console.log(' ✅ Added "prepare": "husky" script\n');
251
+ }
252
+ catch {
253
+ console.warn(' ⚠️ Could not update package.json. Add "prepare": "husky" manually.\n');
254
+ }
255
+ console.log(" ═══════════════════════════════════════");
256
+ console.log(" Git hooks installed successfully!\n");
257
+ console.log(" The pre-commit hook will auto-fill:");
258
+ console.log(" • pubDatetime (new files, if empty)");
259
+ console.log(" • modDatetime (modified files, draft: false, if empty)");
260
+ console.log(" • Handle draft: first for first publish\n");
261
+ console.log(" Manually specified dates are NEVER overwritten.");
262
+ console.log(`\n Watching: ${ctx.relativeBlogPath}/*.md\n`);
263
+ }
264
+ async function uninstallCommand() {
265
+ const ctx = analyzeProject();
266
+ if (!ctx) {
267
+ console.error("\n Error: Could not find a valid blog project.\n");
268
+ process.exit(1);
269
+ }
270
+ const pm = detectPackageManager(ctx.installPath);
271
+ console.log(`\n Project type: ${ctx.isMonorepo ? "Monorepo" : "Single project"}`);
272
+ console.log(` Package manager: ${pm}`);
273
+ console.log("\n Uninstalling husky...\n");
274
+ const huskyDir = join(ctx.installPath, ".husky");
275
+ if (existsSync(huskyDir)) {
276
+ await rm(huskyDir, { recursive: true, force: true });
277
+ console.log(" ✅ Removed .husky directory\n");
278
+ }
279
+ else {
280
+ console.log(" ℹ️ No .husky directory found\n");
281
+ }
282
+ try {
283
+ const removeCmd = await getRemoveCommand(pm, ctx.isMonorepo);
284
+ await execAsync(removeCmd, { cwd: ctx.installPath });
285
+ console.log(" ✅ Removed husky from dependencies\n");
286
+ }
287
+ catch {
288
+ console.log(" ℹ️ Husky was not installed\n");
289
+ }
290
+ try {
291
+ const pkgContent = await readFile(ctx.installPkgPath, "utf-8");
292
+ const pkg = JSON.parse(pkgContent);
293
+ if (pkg.scripts?.prepare === "husky") {
294
+ delete pkg.scripts.prepare;
295
+ if (Object.keys(pkg.scripts).length === 0) {
296
+ delete pkg.scripts;
297
+ }
298
+ await writeFile(ctx.installPkgPath, JSON.stringify(pkg, null, 2) + "\n");
299
+ console.log(' ✅ Removed "prepare" script\n');
300
+ }
301
+ }
302
+ catch {
303
+ }
304
+ console.log(" Git hooks uninstalled successfully!\n");
305
+ }
306
+ async function statusCommand() {
307
+ const ctx = analyzeProject();
308
+ if (!ctx) {
309
+ console.log("\n ❌ Not in an astro-minimax blog directory\n");
310
+ return;
311
+ }
312
+ const huskyDir = join(ctx.installPath, ".husky");
313
+ const preCommitPath = join(huskyDir, "pre-commit");
314
+ const hasHusky = existsSync(huskyDir);
315
+ const hasPreCommit = existsSync(preCommitPath);
316
+ console.log("\n Git Hooks Status\n");
317
+ console.log(` Project type: ${ctx.isMonorepo ? "Monorepo" : "Single project"}`);
318
+ console.log(` Git root: ${ctx.gitRoot}`);
319
+ console.log(` Blog path: ${ctx.blogPath}`);
320
+ console.log(` Install location: ${ctx.installPath}`);
321
+ console.log(` Package manager: ${detectPackageManager(ctx.installPath)}`);
322
+ console.log(` Husky installed: ${hasHusky ? "✅ Yes" : "❌ No"}`);
323
+ console.log(` Pre-commit hook: ${hasPreCommit ? "✅ Yes" : "❌ No"}\n`);
324
+ if (!hasHusky) {
325
+ console.log(" Run 'astro-minimax hooks install' to set up git hooks.\n");
326
+ }
327
+ }
328
+ export async function hooksCommand(args) {
329
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
330
+ console.log(`
331
+ Git hooks setup for astro-minimax
332
+
333
+ Usage:
334
+ astro-minimax hooks <subcommand>
335
+
336
+ Subcommands:
337
+ install Install Husky and create pre-commit hook
338
+ uninstall Remove Husky and hooks
339
+ status Show current hooks status
340
+
341
+ Pre-commit Hook Behavior:
342
+ The hook auto-fills dates ONLY when empty or missing:
343
+ • New files: Fill pubDatetime if not specified
344
+ • Modified files (draft: false): Fill modDatetime if empty
345
+ • First release (draft: first): Set draft to false
346
+
347
+ Important: Manually specified dates are NEVER overwritten.
348
+ If you set pubDatetime or modDatetime yourself, the hook respects it.
349
+
350
+ Project Types:
351
+ • Single project: Blog created via 'astro-minimax init'
352
+ • Monorepo: Development setup with apps/ and packages/
353
+
354
+ Examples:
355
+ astro-minimax hooks install # Set up hooks
356
+ astro-minimax hooks status # Check installation
357
+ astro-minimax hooks uninstall # Remove hooks
358
+ `);
359
+ return;
360
+ }
361
+ const subcommand = args[0];
362
+ switch (subcommand) {
363
+ case "install":
364
+ await installCommand();
365
+ break;
366
+ case "uninstall":
367
+ await uninstallCommand();
368
+ break;
369
+ case "status":
370
+ await statusCommand();
371
+ break;
372
+ default:
373
+ console.error(`\n Unknown subcommand: ${subcommand}`);
374
+ console.error(" Available: install, uninstall, status\n");
375
+ process.exit(1);
376
+ }
377
+ }
378
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function initCommand(args: string[]): void;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgDhD"}
@@ -0,0 +1,50 @@
1
+ import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join, resolve, basename } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __dirname = fileURLToPath(new URL("..", import.meta.url));
5
+ const templateDir = join(__dirname, "..", "template");
6
+ export function initCommand(args) {
7
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
8
+ console.log(`
9
+ Create a new astro-minimax blog project
10
+
11
+ Usage:
12
+ astro-minimax init <project-name>
13
+
14
+ Arguments:
15
+ <project-name> Directory name for the new blog
16
+
17
+ Description:
18
+ Creates a new blog with all necessary configuration files,
19
+ AI-powered features, and a clean structure ready for content.
20
+
21
+ Examples:
22
+ astro-minimax init my-blog
23
+ astro-minimax init ./blogs/tech-blog
24
+ `);
25
+ return;
26
+ }
27
+ const projectName = args[0];
28
+ const targetDir = resolve(process.cwd(), projectName);
29
+ if (existsSync(targetDir)) {
30
+ console.error(`Error: Directory "${projectName}" already exists.`);
31
+ process.exit(1);
32
+ }
33
+ mkdirSync(targetDir, { recursive: true });
34
+ cpSync(templateDir, targetDir, { recursive: true });
35
+ const pkgPath = join(targetDir, "package.json");
36
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
37
+ pkg.name = basename(targetDir);
38
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
39
+ console.log(`\n ✅ Created "${projectName}" successfully!\n`);
40
+ console.log(" Getting started:\n");
41
+ console.log(` cd ${projectName}`);
42
+ console.log(" pnpm install");
43
+ console.log(" pnpm dev\n");
44
+ console.log(" CLI commands:\n");
45
+ console.log(" astro-minimax post new <title> Create a new post");
46
+ console.log(" astro-minimax ai process Process with AI");
47
+ console.log(" astro-minimax profile build Build author profile\n");
48
+ console.log(" Documentation: https://github.com/souloss/astro-minimax\n");
49
+ }
50
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAEtD,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;CAgBf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAEtD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,qBAAqB,WAAW,mBAAmB,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/B,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE5D,OAAO,CAAC,GAAG,CAAC,kBAAkB,WAAW,mBAAmB,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function podcastCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=podcast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcast.d.ts","sourceRoot":"","sources":["../../src/commands/podcast.ts"],"names":[],"mappings":"AAQA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqElE"}
@@ -0,0 +1,89 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const __dirname = fileURLToPath(new URL("..", import.meta.url));
6
+ const toolsDir = join(__dirname, "tools");
7
+ export async function podcastCommand(args) {
8
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
9
+ console.log(`
10
+ Generate AI podcasts from blog posts
11
+
12
+ Usage:
13
+ astro-minimax podcast <subcommand> [options]
14
+
15
+ Subcommands:
16
+ generate Generate podcasts from blog posts
17
+ list List generated podcasts
18
+ feed Generate podcast RSS feed
19
+
20
+ Options for "generate":
21
+ --force Regenerate all (ignore cache)
22
+ --slug=<slug> Process only specified post
23
+ --task=<type> "script" (text only) or "audio" (full)
24
+ --dry-run Preview without generating
25
+ --lang=<zh|en> Process only specified language
26
+
27
+ Description:
28
+ Converts blog posts to multi-speaker podcast audio using:
29
+ - LLM for script generation (host/guest dialogue)
30
+ - OpenAI TTS for audio synthesis
31
+ - FFmpeg for audio concatenation
32
+
33
+ Results cached in datas/podcast-scripts.json
34
+ Audio files saved to public/podcasts/{lang}/{slug}.mp3
35
+
36
+ Environment Variables:
37
+ AI_API_KEY OpenAI API key (required)
38
+ AI_BASE_URL API base URL (optional)
39
+ AI_MODEL Model for script generation (optional)
40
+
41
+ Examples:
42
+ astro-minimax podcast generate
43
+ astro-minimax podcast generate --slug=zh/getting-started
44
+ astro-minimax podcast generate --task=script --dry-run
45
+ astro-minimax podcast list
46
+ astro-minimax podcast feed
47
+ `);
48
+ return;
49
+ }
50
+ const subcommand = args[0];
51
+ const subArgs = args.slice(1);
52
+ const blogDir = process.cwd();
53
+ const contentDir = join(blogDir, "src", "data", "blog");
54
+ if (!existsSync(contentDir)) {
55
+ console.error("Error: Not in an astro-minimax blog directory.");
56
+ console.error("Run this command from your blog's root directory.");
57
+ process.exit(1);
58
+ }
59
+ const scriptMap = {
60
+ generate: "podcast-generate.js",
61
+ list: "podcast-list.js",
62
+ feed: "podcast-feed.js",
63
+ };
64
+ const script = scriptMap[subcommand];
65
+ if (!script) {
66
+ console.error(`Unknown subcommand: ${subcommand}`);
67
+ console.error("Available: generate, list, feed");
68
+ process.exit(1);
69
+ }
70
+ await runTool(script, subArgs, blogDir);
71
+ }
72
+ async function runTool(script, args, cwd) {
73
+ const scriptPath = join(toolsDir, script);
74
+ return new Promise((resolve, reject) => {
75
+ const child = spawn("npx", ["tsx", scriptPath, ...args], {
76
+ stdio: "inherit",
77
+ shell: true,
78
+ cwd,
79
+ });
80
+ child.on("close", (code) => {
81
+ if (code === 0)
82
+ resolve();
83
+ else
84
+ reject(new Error(`Process exited with code ${code}`));
85
+ });
86
+ child.on("error", reject);
87
+ });
88
+ }
89
+ //# sourceMappingURL=podcast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcast.js","sourceRoot":"","sources":["../../src/commands/podcast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAc;IACjD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAA2B;QACxC,QAAQ,EAAE,qBAAqB;QAC/B,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,iBAAiB;KACxB,CAAC;IAEF,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,MAAc,EACd,IAAc,EACd,GAAW;IAEX,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;YACvD,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,IAAI;YACX,GAAG;SACJ,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function postCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=post.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../src/commands/post.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD/D"}