├── postcss.config.js ├── next.config.js ├── public ├── robots.txt ├── og-image.svg ├── test-count.html └── test-flow.html ├── .claude └── settings.local.json ├── .gitignore ├── vercel.json ├── tsconfig.json ├── components ├── ui │ ├── textarea.tsx │ ├── input.tsx │ ├── badge.tsx │ ├── card.tsx │ └── button.tsx ├── AuthorCard.tsx ├── FaqSection.tsx ├── StructuredData.tsx └── GeneratorClient.tsx ├── app ├── sitemap.ts ├── layout.tsx ├── api │ ├── cron │ │ └── clean-cache │ │ │ └── route.ts │ ├── analyze-hot-posts │ │ └── route.ts │ └── generate-combined │ │ └── route.ts ├── blog │ ├── page.tsx │ └── ai-xiaohongshu-secrets │ │ └── page.tsx ├── globals.css └── page.tsx ├── package.json ├── bash.exe.stackdump ├── test-optimization.md ├── lib ├── constants.ts ├── types.ts ├── utils.ts ├── sensitive-words.ts ├── error-handler.ts ├── cache-manager.ts ├── ai-manager.ts └── prompts.ts ├── .env.example ├── tailwind.config.js ├── DEPLOYMENT.md ├── CONTRIBUTING.md ├── README.md └── CLAUDE.md /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | // App directory is now stable in Next.js 13+ 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | # 允许搜索引擎抓取所有页面 5 | Disallow: /api/ 6 | Disallow: /_next/ 7 | Disallow: /admin/ 8 | 9 | # 站点地图位置 10 | Sitemap: https://xhs-ai-writer.vercel.app/sitemap.xml 11 | -------------------------------------------------------------------------------- /.claude/settings.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "allow": [ 4 | "Bash(npm run dev:*)", 5 | "Bash(npm run build:*)", 6 | "Bash(taskkill:*)", 7 | "Bash(git add:*)", 8 | "Bash(npm run lint)", 9 | "Bash(cat:*)" 10 | ], 11 | "deny": [], 12 | "ask": [] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | 38 | # cache data 39 | /data/cache/ 40 | *.cache 41 | 42 | # MCP workflow 43 | .spec-workflow/ 44 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "crons": [ 3 | { 4 | "path": "/api/cron/clean-cache", 5 | "schedule": "0 2 * * *" 6 | } 7 | ], 8 | "functions": { 9 | "app/api/*/route.ts": { 10 | "maxDuration": 180 11 | } 12 | }, 13 | "headers": [ 14 | { 15 | "source": "/api/(.*)", 16 | "headers": [ 17 | { 18 | "key": "X-Content-Type-Options", 19 | "value": "nosniff" 20 | }, 21 | { 22 | "key": "X-Frame-Options", 23 | "value": "DENY" 24 | }, 25 | { 26 | "key": "X-XSS-Protection", 27 | "value": "1; mode=block" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "es6"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "baseUrl": ".", 22 | "paths": { 23 | "@/*": ["./*"] 24 | } 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cn } from "@/lib/utils" 3 | 4 | export interface TextareaProps 5 | extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |