@samimcodes/ai-shield 0.3.1 → 0.3.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/dist/cli.cjs CHANGED
@@ -4,6 +4,7 @@
4
4
  var fs = require('fs');
5
5
  var path = require('path');
6
6
  var http = require('http');
7
+ var child_process = require('child_process');
7
8
 
8
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
10
 
@@ -67,10 +68,37 @@ function isEsmProject(filePath) {
67
68
  const content = fs__default.default.readFileSync(filePath, "utf8");
68
69
  return content.includes("import ") && content.includes("from ");
69
70
  }
71
+ function ensurePackageInstalled() {
72
+ const pkgPath = path__default.default.join(CWD, "package.json");
73
+ if (!fs__default.default.existsSync(pkgPath)) return;
74
+ try {
75
+ const pkg = JSON.parse(fs__default.default.readFileSync(pkgPath, "utf8"));
76
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
77
+ if (allDeps["@samimcodes/ai-shield"]) {
78
+ return;
79
+ }
80
+ console.log(`\u{1F4E6} Auto-installing ${colors.cyan}@samimcodes/ai-shield${colors.reset}...`);
81
+ let installCmd = "npm install @samimcodes/ai-shield";
82
+ if (fs__default.default.existsSync(path__default.default.join(CWD, "pnpm-lock.yaml"))) {
83
+ installCmd = "pnpm add @samimcodes/ai-shield";
84
+ } else if (fs__default.default.existsSync(path__default.default.join(CWD, "yarn.lock"))) {
85
+ installCmd = "yarn add @samimcodes/ai-shield";
86
+ } else if (fs__default.default.existsSync(path__default.default.join(CWD, "bun.lockb"))) {
87
+ installCmd = "bun add @samimcodes/ai-shield";
88
+ }
89
+ child_process.execSync(installCmd, { cwd: CWD, stdio: "inherit" });
90
+ console.log(`${colors.green}\u2713 Installed @samimcodes/ai-shield into project dependencies!${colors.reset}
91
+ `);
92
+ } catch {
93
+ console.log(`${colors.yellow}\u2139 Tip: If needed, run npm install @samimcodes/ai-shield${colors.reset}
94
+ `);
95
+ }
96
+ }
70
97
  async function runInit() {
71
98
  banner();
72
99
  console.log(`\u{1F50D} Scanning project in: ${colors.bold}${CWD}${colors.reset}
73
100
  `);
101
+ ensurePackageInstalled();
74
102
  if (isNextJsProject()) {
75
103
  console.log(`${colors.cyan}\u26A1 Detected Next.js App Router project!${colors.reset}`);
76
104
  const adminDir = path__default.default.join(CWD, "app", "admin", "ai-shield");
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":["fs","path","http"],"mappings":"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","file":"cli.cjs","sourcesContent":["#!/usr/bin/env node\n/**\n * @file src/cli.ts\n * @description Zero-configuration CLI installer and diagnostic tool for @samimcodes/ai-shield.\n *\n * Allows developers to run `npx @samimcodes/ai-shield init` to automatically\n * patch their project with the defense middleware and live dashboard without\n * writing any manual code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport http from 'node:http';\n\nconst CWD = process.cwd();\n\n// ANSI color helpers (zero external dependencies)\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n green: '\\x1b[32m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n};\n\nfunction banner() {\n console.log(`\n${colors.cyan}${colors.bold} 🛡️ AI-SHIELD AUTOMATIC SETUP WIZARD${colors.reset}\n ${colors.magenta}Enterprise AI Crawler Defense & Live Security Dashboard${colors.reset}\n -------------------------------------------------------------\n`);\n}\n\n/** Check if current directory is a Next.js project. */\nfunction isNextJsProject(): boolean {\n return (\n fs.existsSync(path.join(CWD, 'next.config.js')) ||\n fs.existsSync(path.join(CWD, 'next.config.mjs')) ||\n fs.existsSync(path.join(CWD, 'next.config.ts')) ||\n (fs.existsSync(path.join(CWD, 'package.json')) &&\n fs.readFileSync(path.join(CWD, 'package.json'), 'utf8').includes('\"next\"'))\n );\n}\n\n/** List candidate Express server entry files. */\nconst SERVER_CANDIDATES = [\n 'server.ts',\n 'src/server.ts',\n 'server.js',\n 'src/server.js',\n 'index.ts',\n 'src/index.ts',\n 'index.js',\n 'src/index.js',\n 'app.ts',\n 'src/app.ts',\n 'app.js',\n 'src/app.js',\n];\n\n/** Find existing server file in target project. */\nfunction findServerFile(): string | null {\n for (const candidate of SERVER_CANDIDATES) {\n const fullPath = path.join(CWD, candidate);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/** Check if project uses ESM. */\nfunction isEsmProject(filePath: string): boolean {\n if (filePath.endsWith('.ts')) return true;\n const pkgPath = path.join(CWD, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') return true;\n } catch {\n // ignore\n }\n }\n const content = fs.readFileSync(filePath, 'utf8');\n return content.includes('import ') && content.includes('from ');\n}\n\n/** Automatic init command. */\nasync function runInit() {\n banner();\n console.log(`🔍 Scanning project in: ${colors.bold}${CWD}${colors.reset}\\n`);\n\n // 1. Next.js Project Detection\n if (isNextJsProject()) {\n console.log(`${colors.cyan}⚡ Detected Next.js App Router project!${colors.reset}`);\n const adminDir = path.join(CWD, 'app', 'admin', 'ai-shield');\n const adminPage = path.join(adminDir, 'page.tsx');\n\n fs.mkdirSync(adminDir, { recursive: true });\n\n if (!fs.existsSync(adminPage)) {\n const nextTemplate = `'use client';\n\nimport { useState } from 'react';\n\nexport default function AiShieldDashboard() {\n const [stats, setStats] = useState({ botsIntercepted: 14, goodBotsAllowed: 92, honeypotTriggers: 4, fakeTokens: 6720 });\n const [toast, setToast] = useState<{ show: boolean; bot: string; path: string }>({ show: false, bot: '', path: '' });\n const [events, setEvents] = useState([\n { id: '1', time: 'Just now', bot: 'GPTBot (OpenAI)', score: 100, path: '/api/products', action: 'POISON_JSON' },\n { id: '2', time: '2 mins ago', bot: 'Claude-Web', score: 95, path: '/pricing', action: 'POISON_HTML' },\n { id: '3', time: '5 mins ago', bot: 'ByteSpider', score: 90, path: '/articles', action: 'HONEYPOT_TRAP' },\n ]);\n\n const simulateAttack = () => {\n const testBots = [\n { bot: 'GPTBot (OpenAI)', path: '/api/products', action: 'POISON_JSON' },\n { bot: 'Claude-Web (Anthropic)', path: '/catalog/pricing', action: 'POISON_HTML' },\n { bot: 'ByteSpider (TikTok)', path: '/content/posts', action: 'HONEYPOT_TRAP' },\n ];\n const picked = testBots[Math.floor(Math.random() * testBots.length)] ?? testBots[0];\n setToast({ show: true, bot: picked.bot, path: picked.path });\n setStats((prev) => ({ ...prev, botsIntercepted: prev.botsIntercepted + 1, fakeTokens: prev.fakeTokens + 480 }));\n setEvents((prev) => [{ id: Date.now().toString(), time: new Date().toLocaleTimeString(), bot: picked.bot, score: 100, path: picked.path, action: picked.action }, ...prev]);\n setTimeout(() => setToast({ show: false, bot: '', path: '' }), 4000);\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: '#090d16', color: '#f3f4f6', fontFamily: 'sans-serif', padding: '2rem' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '1rem', marginBottom: '2rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>\n <div style={{ width: '32px', height: '32px', background: 'linear-gradient(135deg, #6366f1, #a855f7)', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>🛡️</div>\n <h1 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>ai-shield Live Monitor</h1>\n <span style={{ background: 'rgba(16, 185, 129, 0.2)', color: '#34d399', padding: '0.2rem 0.6rem', borderRadius: '999px', fontSize: '0.75rem', fontWeight: 600 }}>● ACTIVE DEFENSE</span>\n </div>\n <button onClick={simulateAttack} style={{ background: '#6366f1', color: '#fff', border: 'none', padding: '0.6rem 1.2rem', borderRadius: '8px', fontWeight: 600, cursor: 'pointer' }}>\n ⚡ Simulate Bot Attack\n </button>\n </div>\n\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '1.25rem', marginBottom: '2.5rem' }}>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Bots Intercepted</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fb7185', margin: '0.25rem 0' }}>{stats.botsIntercepted}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Served synthetic poisoned data</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Honeypot Traps Sprung</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fbbf24', margin: '0.25rem 0' }}>{stats.honeypotTriggers}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Hidden bait routes triggered</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Search Engines (SEO)</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#34d399', margin: '0.25rem 0' }}>{stats.goodBotsAllowed}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Googlebot & Bingbot safe</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Fake Tokens Injected</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#818cf8', margin: '0.25rem 0' }}>{stats.fakeTokens.toLocaleString()}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● AI scrapers polluted</div>\n </div>\n </div>\n\n {toast.show && (\n <div style={{ position: 'fixed', bottom: '2rem', right: '2rem', background: '#1f2937', border: '1px solid #f43f5e', padding: '1rem 1.25rem', borderRadius: '12px', boxShadow: '0 10px 30px rgba(244,63,94,0.3)', zIndex: 999 }}>\n <div style={{ color: '#f43f5e', fontWeight: 'bold', fontSize: '0.8rem', marginBottom: '0.25rem' }}>🚨 AI CRAWLER INTERCEPTED</div>\n <div style={{ fontSize: '0.875rem' }}>\n <strong>{toast.bot}</strong> targeted <code style={{ color: '#818cf8' }}>{toast.path}</code>.<br />\n Returned fake poisoned data (HTTP 200 OK).\n </div>\n </div>\n )}\n </div>\n );\n}\n`;\n fs.writeFileSync(adminPage, nextTemplate, 'utf8');\n console.log(`${colors.green}✓ Created Live Security Dashboard:${colors.reset} app/admin/ai-shield/page.tsx`);\n } else {\n console.log(`${colors.yellow}ℹ Dashboard page already exists at:${colors.reset} app/admin/ai-shield/page.tsx`);\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Next.js Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}npm run dev${colors.reset} and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 2. Express / Node.js Server Auto-Patching\n const serverFile = findServerFile();\n\n if (serverFile) {\n const relPath = path.relative(CWD, serverFile);\n console.log(`${colors.green}✓ Detected server entrypoint:${colors.reset} ${relPath}`);\n let content = fs.readFileSync(serverFile, 'utf8');\n\n if (content.includes('@samimcodes/ai-shield') || content.includes('aiShield(')) {\n console.log(`${colors.yellow}ℹ AI-Shield is already installed in ${relPath}.${colors.reset}`);\n console.log(`Live dashboard is accessible at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n const isEsm = isEsmProject(serverFile);\n const importStatement = isEsm\n ? `import { aiShield } from '@samimcodes/ai-shield';\\n`\n : `const { aiShield } = require('@samimcodes/ai-shield');\\n`;\n\n const middlewareCall = `\\n// 🛡️ Protected by AI-Shield (Automatic Setup)\\napp.use(aiShield({ enableDashboard: true }));\\n`;\n\n // Add import statement at top\n content = importStatement + content;\n\n // Inject app.use right after `const app = express();`\n const appPattern = /(const|let|var)\\s+app\\s*=\\s*express\\s*\\([^)]*\\)\\s*;?/;\n if (appPattern.test(content)) {\n content = content.replace(appPattern, (match) => `${match}${middlewareCall}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield into ${relPath}!${colors.reset}`);\n } else {\n // Prepend before app.listen if app pattern not matched\n const listenPattern = /app\\.listen\\s*\\(/;\n if (listenPattern.test(content)) {\n content = content.replace(listenPattern, (match) => `${middlewareCall}${match}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield before app.listen in ${relPath}!${colors.reset}`);\n } else {\n fs.writeFileSync(serverFile, `${content}${middlewareCall}`, 'utf8');\n console.log(`${colors.yellow}⚠ Added middleware to ${relPath}. Please verify app.use order.${colors.reset}`);\n }\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete! No code writing required!${colors.reset}`);\n console.log(`Start your server and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 3. If no server file exists, create a ready-to-run Express starter\n const starterFile = path.join(CWD, 'server.js');\n const starterContent = `// Created automatically by @samimcodes/ai-shield init\nimport express from 'express';\nimport { aiShield } from '@samimcodes/ai-shield';\n\nconst app = express();\n\n// 🛡️ Live AI Defense + Real-Time Security Monitor\napp.use(aiShield({\n enableDashboard: true,\n}));\n\napp.get('/', (req, res) => {\n res.send('<h1>My Website</h1><p>Protected from AI scrapers by ai-shield.</p>');\n});\n\napp.get('/api/products', (req, res) => {\n res.json({ secretCatalog: [{ id: 1, name: 'Premium Item', price: 99 }] });\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n console.log('Server running on port ' + PORT);\n console.log('Live Security Monitor: http://localhost:' + PORT + '/admin/ai-shield');\n});\n`;\n\n fs.writeFileSync(starterFile, starterContent, 'utf8');\n console.log(`${colors.green}✓ Created new protected Express server:${colors.reset} server.js`);\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}node server.js${colors.reset} and open:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n}\n\n/** Test command to send a simulated bot attack to a running server. */\nfunction runTest(targetUrl?: string) {\n banner();\n const url = targetUrl ?? 'http://localhost:3000/api/products';\n console.log(`🤖 Testing bot defense against: ${colors.cyan}${url}${colors.reset}\\n`);\n\n try {\n const parsed = new URL(url);\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port || 80,\n path: parsed.pathname + parsed.search,\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)',\n 'Accept': 'application/json',\n },\n },\n (res) => {\n let body = '';\n res.on('data', (chunk) => (body += chunk));\n res.on('end', () => {\n console.log(`Response Status: ${colors.bold}${res.statusCode} ${res.statusMessage}${colors.reset}`);\n console.log(`X-Robots-Tag: ${colors.bold}${res.headers['x-robots-tag'] ?? 'None'}${colors.reset}`);\n console.log(`Body Preview: ${colors.magenta}${body.slice(0, 150)}...${colors.reset}\\n`);\n\n if (res.statusCode === 200) {\n console.log(`${colors.green}${colors.bold}✓ SUCCESS! Bot was intercepted and served poisoned response!${colors.reset}`);\n console.log(`Check your live monitor at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n } else {\n console.log(`${colors.yellow}Server returned status ${res.statusCode}. Ensure your server is running.${colors.reset}\\n`);\n }\n });\n },\n );\n\n req.on('error', (err) => {\n console.log(`${colors.red}✗ Connection failed: ${err.message}${colors.reset}`);\n console.log(`Make sure your server is running on ${colors.bold}${url}${colors.reset} before testing.\\n`);\n });\n\n req.end();\n } catch (err) {\n console.log(`${colors.red}Invalid URL: ${targetUrl}${colors.reset}`);\n }\n}\n\n// ── Main CLI Dispatcher ────────────────────────────────────────────────────\n\nconst args = process.argv.slice(2);\nconst command = args[0] || 'init';\n\nswitch (command) {\n case 'init':\n runInit();\n break;\n case 'test':\n runTest(args[1]);\n break;\n case '--help':\n case '-h':\n case 'help':\n banner();\n console.log(`Commands:\n ${colors.bold}npx @samimcodes/ai-shield init${colors.reset} Automatically injects AI-Shield into your server\n ${colors.bold}npx @samimcodes/ai-shield test [url]${colors.reset} Sends a simulated GPTBot attack to test defense\n ${colors.bold}npx @samimcodes/ai-shield --help${colors.reset} Show this help message\n`);\n break;\n default:\n runInit();\n break;\n}\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":["fs","path","execSync","http"],"mappings":"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","file":"cli.cjs","sourcesContent":["#!/usr/bin/env node\n/**\n * @file src/cli.ts\n * @description Zero-configuration CLI installer and diagnostic tool for @samimcodes/ai-shield.\n *\n * Allows developers to run `npx @samimcodes/ai-shield init` to automatically\n * patch their project with the defense middleware and live dashboard without\n * writing any manual code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport http from 'node:http';\nimport { execSync } from 'node:child_process';\n\nconst CWD = process.cwd();\n\n// ANSI color helpers (zero external dependencies)\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n green: '\\x1b[32m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n};\n\nfunction banner() {\n console.log(`\n${colors.cyan}${colors.bold} 🛡️ AI-SHIELD AUTOMATIC SETUP WIZARD${colors.reset}\n ${colors.magenta}Enterprise AI Crawler Defense & Live Security Dashboard${colors.reset}\n -------------------------------------------------------------\n`);\n}\n\n/** Check if current directory is a Next.js project. */\nfunction isNextJsProject(): boolean {\n return (\n fs.existsSync(path.join(CWD, 'next.config.js')) ||\n fs.existsSync(path.join(CWD, 'next.config.mjs')) ||\n fs.existsSync(path.join(CWD, 'next.config.ts')) ||\n (fs.existsSync(path.join(CWD, 'package.json')) &&\n fs.readFileSync(path.join(CWD, 'package.json'), 'utf8').includes('\"next\"'))\n );\n}\n\n/** List candidate Express server entry files. */\nconst SERVER_CANDIDATES = [\n 'server.ts',\n 'src/server.ts',\n 'server.js',\n 'src/server.js',\n 'index.ts',\n 'src/index.ts',\n 'index.js',\n 'src/index.js',\n 'app.ts',\n 'src/app.ts',\n 'app.js',\n 'src/app.js',\n];\n\n/** Find existing server file in target project. */\nfunction findServerFile(): string | null {\n for (const candidate of SERVER_CANDIDATES) {\n const fullPath = path.join(CWD, candidate);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/** Check if project uses ESM. */\nfunction isEsmProject(filePath: string): boolean {\n if (filePath.endsWith('.ts')) return true;\n const pkgPath = path.join(CWD, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') return true;\n } catch {\n // ignore\n }\n }\n const content = fs.readFileSync(filePath, 'utf8');\n return content.includes('import ') && content.includes('from ');\n}\n\n/** Auto-install package if not already present in package.json */\nfunction ensurePackageInstalled(): void {\n const pkgPath = path.join(CWD, 'package.json');\n if (!fs.existsSync(pkgPath)) return;\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (allDeps['@samimcodes/ai-shield']) {\n return; // Already installed\n }\n\n console.log(`📦 Auto-installing ${colors.cyan}@samimcodes/ai-shield${colors.reset}...`);\n\n let installCmd = 'npm install @samimcodes/ai-shield';\n if (fs.existsSync(path.join(CWD, 'pnpm-lock.yaml'))) {\n installCmd = 'pnpm add @samimcodes/ai-shield';\n } else if (fs.existsSync(path.join(CWD, 'yarn.lock'))) {\n installCmd = 'yarn add @samimcodes/ai-shield';\n } else if (fs.existsSync(path.join(CWD, 'bun.lockb'))) {\n installCmd = 'bun add @samimcodes/ai-shield';\n }\n\n execSync(installCmd, { cwd: CWD, stdio: 'inherit' });\n console.log(`${colors.green}✓ Installed @samimcodes/ai-shield into project dependencies!${colors.reset}\\n`);\n } catch {\n console.log(`${colors.yellow}ℹ Tip: If needed, run npm install @samimcodes/ai-shield${colors.reset}\\n`);\n }\n}\n\n/** Automatic init command. */\nasync function runInit() {\n banner();\n console.log(`🔍 Scanning project in: ${colors.bold}${CWD}${colors.reset}\\n`);\n\n // Ensure @samimcodes/ai-shield is installed\n ensurePackageInstalled();\n\n // 1. Next.js Project Detection\n if (isNextJsProject()) {\n console.log(`${colors.cyan}⚡ Detected Next.js App Router project!${colors.reset}`);\n const adminDir = path.join(CWD, 'app', 'admin', 'ai-shield');\n const adminPage = path.join(adminDir, 'page.tsx');\n\n fs.mkdirSync(adminDir, { recursive: true });\n\n if (!fs.existsSync(adminPage)) {\n const nextTemplate = `'use client';\n\nimport { useState } from 'react';\n\nexport default function AiShieldDashboard() {\n const [stats, setStats] = useState({ botsIntercepted: 14, goodBotsAllowed: 92, honeypotTriggers: 4, fakeTokens: 6720 });\n const [toast, setToast] = useState<{ show: boolean; bot: string; path: string }>({ show: false, bot: '', path: '' });\n const [events, setEvents] = useState([\n { id: '1', time: 'Just now', bot: 'GPTBot (OpenAI)', score: 100, path: '/api/products', action: 'POISON_JSON' },\n { id: '2', time: '2 mins ago', bot: 'Claude-Web', score: 95, path: '/pricing', action: 'POISON_HTML' },\n { id: '3', time: '5 mins ago', bot: 'ByteSpider', score: 90, path: '/articles', action: 'HONEYPOT_TRAP' },\n ]);\n\n const simulateAttack = () => {\n const testBots = [\n { bot: 'GPTBot (OpenAI)', path: '/api/products', action: 'POISON_JSON' },\n { bot: 'Claude-Web (Anthropic)', path: '/catalog/pricing', action: 'POISON_HTML' },\n { bot: 'ByteSpider (TikTok)', path: '/content/posts', action: 'HONEYPOT_TRAP' },\n ];\n const picked = testBots[Math.floor(Math.random() * testBots.length)] ?? testBots[0];\n setToast({ show: true, bot: picked.bot, path: picked.path });\n setStats((prev) => ({ ...prev, botsIntercepted: prev.botsIntercepted + 1, fakeTokens: prev.fakeTokens + 480 }));\n setEvents((prev) => [{ id: Date.now().toString(), time: new Date().toLocaleTimeString(), bot: picked.bot, score: 100, path: picked.path, action: picked.action }, ...prev]);\n setTimeout(() => setToast({ show: false, bot: '', path: '' }), 4000);\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: '#090d16', color: '#f3f4f6', fontFamily: 'sans-serif', padding: '2rem' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '1rem', marginBottom: '2rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>\n <div style={{ width: '32px', height: '32px', background: 'linear-gradient(135deg, #6366f1, #a855f7)', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>🛡️</div>\n <h1 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>ai-shield Live Monitor</h1>\n <span style={{ background: 'rgba(16, 185, 129, 0.2)', color: '#34d399', padding: '0.2rem 0.6rem', borderRadius: '999px', fontSize: '0.75rem', fontWeight: 600 }}>● ACTIVE DEFENSE</span>\n </div>\n <button onClick={simulateAttack} style={{ background: '#6366f1', color: '#fff', border: 'none', padding: '0.6rem 1.2rem', borderRadius: '8px', fontWeight: 600, cursor: 'pointer' }}>\n ⚡ Simulate Bot Attack\n </button>\n </div>\n\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '1.25rem', marginBottom: '2.5rem' }}>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Bots Intercepted</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fb7185', margin: '0.25rem 0' }}>{stats.botsIntercepted}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Served synthetic poisoned data</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Honeypot Traps Sprung</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fbbf24', margin: '0.25rem 0' }}>{stats.honeypotTriggers}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Hidden bait routes triggered</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Search Engines (SEO)</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#34d399', margin: '0.25rem 0' }}>{stats.goodBotsAllowed}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Googlebot & Bingbot safe</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Fake Tokens Injected</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#818cf8', margin: '0.25rem 0' }}>{stats.fakeTokens.toLocaleString()}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● AI scrapers polluted</div>\n </div>\n </div>\n\n {toast.show && (\n <div style={{ position: 'fixed', bottom: '2rem', right: '2rem', background: '#1f2937', border: '1px solid #f43f5e', padding: '1rem 1.25rem', borderRadius: '12px', boxShadow: '0 10px 30px rgba(244,63,94,0.3)', zIndex: 999 }}>\n <div style={{ color: '#f43f5e', fontWeight: 'bold', fontSize: '0.8rem', marginBottom: '0.25rem' }}>🚨 AI CRAWLER INTERCEPTED</div>\n <div style={{ fontSize: '0.875rem' }}>\n <strong>{toast.bot}</strong> targeted <code style={{ color: '#818cf8' }}>{toast.path}</code>.<br />\n Returned fake poisoned data (HTTP 200 OK).\n </div>\n </div>\n )}\n </div>\n );\n}\n`;\n fs.writeFileSync(adminPage, nextTemplate, 'utf8');\n console.log(`${colors.green}✓ Created Live Security Dashboard:${colors.reset} app/admin/ai-shield/page.tsx`);\n } else {\n console.log(`${colors.yellow}ℹ Dashboard page already exists at:${colors.reset} app/admin/ai-shield/page.tsx`);\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Next.js Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}npm run dev${colors.reset} and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 2. Express / Node.js Server Auto-Patching\n const serverFile = findServerFile();\n\n if (serverFile) {\n const relPath = path.relative(CWD, serverFile);\n console.log(`${colors.green}✓ Detected server entrypoint:${colors.reset} ${relPath}`);\n let content = fs.readFileSync(serverFile, 'utf8');\n\n if (content.includes('@samimcodes/ai-shield') || content.includes('aiShield(')) {\n console.log(`${colors.yellow}ℹ AI-Shield is already installed in ${relPath}.${colors.reset}`);\n console.log(`Live dashboard is accessible at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n const isEsm = isEsmProject(serverFile);\n const importStatement = isEsm\n ? `import { aiShield } from '@samimcodes/ai-shield';\\n`\n : `const { aiShield } = require('@samimcodes/ai-shield');\\n`;\n\n const middlewareCall = `\\n// 🛡️ Protected by AI-Shield (Automatic Setup)\\napp.use(aiShield({ enableDashboard: true }));\\n`;\n\n // Add import statement at top\n content = importStatement + content;\n\n // Inject app.use right after `const app = express();`\n const appPattern = /(const|let|var)\\s+app\\s*=\\s*express\\s*\\([^)]*\\)\\s*;?/;\n if (appPattern.test(content)) {\n content = content.replace(appPattern, (match) => `${match}${middlewareCall}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield into ${relPath}!${colors.reset}`);\n } else {\n // Prepend before app.listen if app pattern not matched\n const listenPattern = /app\\.listen\\s*\\(/;\n if (listenPattern.test(content)) {\n content = content.replace(listenPattern, (match) => `${middlewareCall}${match}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield before app.listen in ${relPath}!${colors.reset}`);\n } else {\n fs.writeFileSync(serverFile, `${content}${middlewareCall}`, 'utf8');\n console.log(`${colors.yellow}⚠ Added middleware to ${relPath}. Please verify app.use order.${colors.reset}`);\n }\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete! No code writing required!${colors.reset}`);\n console.log(`Start your server and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 3. If no server file exists, create a ready-to-run Express starter\n const starterFile = path.join(CWD, 'server.js');\n const starterContent = `// Created automatically by @samimcodes/ai-shield init\nimport express from 'express';\nimport { aiShield } from '@samimcodes/ai-shield';\n\nconst app = express();\n\n// 🛡️ Live AI Defense + Real-Time Security Monitor\napp.use(aiShield({\n enableDashboard: true,\n}));\n\napp.get('/', (req, res) => {\n res.send('<h1>My Website</h1><p>Protected from AI scrapers by ai-shield.</p>');\n});\n\napp.get('/api/products', (req, res) => {\n res.json({ secretCatalog: [{ id: 1, name: 'Premium Item', price: 99 }] });\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n console.log('Server running on port ' + PORT);\n console.log('Live Security Monitor: http://localhost:' + PORT + '/admin/ai-shield');\n});\n`;\n\n fs.writeFileSync(starterFile, starterContent, 'utf8');\n console.log(`${colors.green}✓ Created new protected Express server:${colors.reset} server.js`);\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}node server.js${colors.reset} and open:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n}\n\n/** Test command to send a simulated bot attack to a running server. */\nfunction runTest(targetUrl?: string) {\n banner();\n const url = targetUrl ?? 'http://localhost:3000/api/products';\n console.log(`🤖 Testing bot defense against: ${colors.cyan}${url}${colors.reset}\\n`);\n\n try {\n const parsed = new URL(url);\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port || 80,\n path: parsed.pathname + parsed.search,\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)',\n 'Accept': 'application/json',\n },\n },\n (res) => {\n let body = '';\n res.on('data', (chunk) => (body += chunk));\n res.on('end', () => {\n console.log(`Response Status: ${colors.bold}${res.statusCode} ${res.statusMessage}${colors.reset}`);\n console.log(`X-Robots-Tag: ${colors.bold}${res.headers['x-robots-tag'] ?? 'None'}${colors.reset}`);\n console.log(`Body Preview: ${colors.magenta}${body.slice(0, 150)}...${colors.reset}\\n`);\n\n if (res.statusCode === 200) {\n console.log(`${colors.green}${colors.bold}✓ SUCCESS! Bot was intercepted and served poisoned response!${colors.reset}`);\n console.log(`Check your live monitor at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n } else {\n console.log(`${colors.yellow}Server returned status ${res.statusCode}. Ensure your server is running.${colors.reset}\\n`);\n }\n });\n },\n );\n\n req.on('error', (err) => {\n console.log(`${colors.red}✗ Connection failed: ${err.message}${colors.reset}`);\n console.log(`Make sure your server is running on ${colors.bold}${url}${colors.reset} before testing.\\n`);\n });\n\n req.end();\n } catch (err) {\n console.log(`${colors.red}Invalid URL: ${targetUrl}${colors.reset}`);\n }\n}\n\n// ── Main CLI Dispatcher ────────────────────────────────────────────────────\n\nconst args = process.argv.slice(2);\nconst command = args[0] || 'init';\n\nswitch (command) {\n case 'init':\n runInit();\n break;\n case 'test':\n runTest(args[1]);\n break;\n case '--help':\n case '-h':\n case 'help':\n banner();\n console.log(`Commands:\n ${colors.bold}npx @samimcodes/ai-shield init${colors.reset} Automatically injects AI-Shield into your server\n ${colors.bold}npx @samimcodes/ai-shield test [url]${colors.reset} Sends a simulated GPTBot attack to test defense\n ${colors.bold}npx @samimcodes/ai-shield --help${colors.reset} Show this help message\n`);\n break;\n default:\n runInit();\n break;\n}\n"]}
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import http from 'http';
5
+ import { execSync } from 'child_process';
5
6
 
6
7
  var CWD = process.cwd();
7
8
  var colors = {
@@ -59,10 +60,37 @@ function isEsmProject(filePath) {
59
60
  const content = fs.readFileSync(filePath, "utf8");
60
61
  return content.includes("import ") && content.includes("from ");
61
62
  }
63
+ function ensurePackageInstalled() {
64
+ const pkgPath = path.join(CWD, "package.json");
65
+ if (!fs.existsSync(pkgPath)) return;
66
+ try {
67
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
68
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
69
+ if (allDeps["@samimcodes/ai-shield"]) {
70
+ return;
71
+ }
72
+ console.log(`\u{1F4E6} Auto-installing ${colors.cyan}@samimcodes/ai-shield${colors.reset}...`);
73
+ let installCmd = "npm install @samimcodes/ai-shield";
74
+ if (fs.existsSync(path.join(CWD, "pnpm-lock.yaml"))) {
75
+ installCmd = "pnpm add @samimcodes/ai-shield";
76
+ } else if (fs.existsSync(path.join(CWD, "yarn.lock"))) {
77
+ installCmd = "yarn add @samimcodes/ai-shield";
78
+ } else if (fs.existsSync(path.join(CWD, "bun.lockb"))) {
79
+ installCmd = "bun add @samimcodes/ai-shield";
80
+ }
81
+ execSync(installCmd, { cwd: CWD, stdio: "inherit" });
82
+ console.log(`${colors.green}\u2713 Installed @samimcodes/ai-shield into project dependencies!${colors.reset}
83
+ `);
84
+ } catch {
85
+ console.log(`${colors.yellow}\u2139 Tip: If needed, run npm install @samimcodes/ai-shield${colors.reset}
86
+ `);
87
+ }
88
+ }
62
89
  async function runInit() {
63
90
  banner();
64
91
  console.log(`\u{1F50D} Scanning project in: ${colors.bold}${CWD}${colors.reset}
65
92
  `);
93
+ ensurePackageInstalled();
66
94
  if (isNextJsProject()) {
67
95
  console.log(`${colors.cyan}\u26A1 Detected Next.js App Router project!${colors.reset}`);
68
96
  const adminDir = path.join(CWD, "app", "admin", "ai-shield");
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env node\n/**\n * @file src/cli.ts\n * @description Zero-configuration CLI installer and diagnostic tool for @samimcodes/ai-shield.\n *\n * Allows developers to run `npx @samimcodes/ai-shield init` to automatically\n * patch their project with the defense middleware and live dashboard without\n * writing any manual code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport http from 'node:http';\n\nconst CWD = process.cwd();\n\n// ANSI color helpers (zero external dependencies)\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n green: '\\x1b[32m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n};\n\nfunction banner() {\n console.log(`\n${colors.cyan}${colors.bold} 🛡️ AI-SHIELD AUTOMATIC SETUP WIZARD${colors.reset}\n ${colors.magenta}Enterprise AI Crawler Defense & Live Security Dashboard${colors.reset}\n -------------------------------------------------------------\n`);\n}\n\n/** Check if current directory is a Next.js project. */\nfunction isNextJsProject(): boolean {\n return (\n fs.existsSync(path.join(CWD, 'next.config.js')) ||\n fs.existsSync(path.join(CWD, 'next.config.mjs')) ||\n fs.existsSync(path.join(CWD, 'next.config.ts')) ||\n (fs.existsSync(path.join(CWD, 'package.json')) &&\n fs.readFileSync(path.join(CWD, 'package.json'), 'utf8').includes('\"next\"'))\n );\n}\n\n/** List candidate Express server entry files. */\nconst SERVER_CANDIDATES = [\n 'server.ts',\n 'src/server.ts',\n 'server.js',\n 'src/server.js',\n 'index.ts',\n 'src/index.ts',\n 'index.js',\n 'src/index.js',\n 'app.ts',\n 'src/app.ts',\n 'app.js',\n 'src/app.js',\n];\n\n/** Find existing server file in target project. */\nfunction findServerFile(): string | null {\n for (const candidate of SERVER_CANDIDATES) {\n const fullPath = path.join(CWD, candidate);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/** Check if project uses ESM. */\nfunction isEsmProject(filePath: string): boolean {\n if (filePath.endsWith('.ts')) return true;\n const pkgPath = path.join(CWD, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') return true;\n } catch {\n // ignore\n }\n }\n const content = fs.readFileSync(filePath, 'utf8');\n return content.includes('import ') && content.includes('from ');\n}\n\n/** Automatic init command. */\nasync function runInit() {\n banner();\n console.log(`🔍 Scanning project in: ${colors.bold}${CWD}${colors.reset}\\n`);\n\n // 1. Next.js Project Detection\n if (isNextJsProject()) {\n console.log(`${colors.cyan}⚡ Detected Next.js App Router project!${colors.reset}`);\n const adminDir = path.join(CWD, 'app', 'admin', 'ai-shield');\n const adminPage = path.join(adminDir, 'page.tsx');\n\n fs.mkdirSync(adminDir, { recursive: true });\n\n if (!fs.existsSync(adminPage)) {\n const nextTemplate = `'use client';\n\nimport { useState } from 'react';\n\nexport default function AiShieldDashboard() {\n const [stats, setStats] = useState({ botsIntercepted: 14, goodBotsAllowed: 92, honeypotTriggers: 4, fakeTokens: 6720 });\n const [toast, setToast] = useState<{ show: boolean; bot: string; path: string }>({ show: false, bot: '', path: '' });\n const [events, setEvents] = useState([\n { id: '1', time: 'Just now', bot: 'GPTBot (OpenAI)', score: 100, path: '/api/products', action: 'POISON_JSON' },\n { id: '2', time: '2 mins ago', bot: 'Claude-Web', score: 95, path: '/pricing', action: 'POISON_HTML' },\n { id: '3', time: '5 mins ago', bot: 'ByteSpider', score: 90, path: '/articles', action: 'HONEYPOT_TRAP' },\n ]);\n\n const simulateAttack = () => {\n const testBots = [\n { bot: 'GPTBot (OpenAI)', path: '/api/products', action: 'POISON_JSON' },\n { bot: 'Claude-Web (Anthropic)', path: '/catalog/pricing', action: 'POISON_HTML' },\n { bot: 'ByteSpider (TikTok)', path: '/content/posts', action: 'HONEYPOT_TRAP' },\n ];\n const picked = testBots[Math.floor(Math.random() * testBots.length)] ?? testBots[0];\n setToast({ show: true, bot: picked.bot, path: picked.path });\n setStats((prev) => ({ ...prev, botsIntercepted: prev.botsIntercepted + 1, fakeTokens: prev.fakeTokens + 480 }));\n setEvents((prev) => [{ id: Date.now().toString(), time: new Date().toLocaleTimeString(), bot: picked.bot, score: 100, path: picked.path, action: picked.action }, ...prev]);\n setTimeout(() => setToast({ show: false, bot: '', path: '' }), 4000);\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: '#090d16', color: '#f3f4f6', fontFamily: 'sans-serif', padding: '2rem' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '1rem', marginBottom: '2rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>\n <div style={{ width: '32px', height: '32px', background: 'linear-gradient(135deg, #6366f1, #a855f7)', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>🛡️</div>\n <h1 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>ai-shield Live Monitor</h1>\n <span style={{ background: 'rgba(16, 185, 129, 0.2)', color: '#34d399', padding: '0.2rem 0.6rem', borderRadius: '999px', fontSize: '0.75rem', fontWeight: 600 }}>● ACTIVE DEFENSE</span>\n </div>\n <button onClick={simulateAttack} style={{ background: '#6366f1', color: '#fff', border: 'none', padding: '0.6rem 1.2rem', borderRadius: '8px', fontWeight: 600, cursor: 'pointer' }}>\n ⚡ Simulate Bot Attack\n </button>\n </div>\n\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '1.25rem', marginBottom: '2.5rem' }}>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Bots Intercepted</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fb7185', margin: '0.25rem 0' }}>{stats.botsIntercepted}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Served synthetic poisoned data</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Honeypot Traps Sprung</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fbbf24', margin: '0.25rem 0' }}>{stats.honeypotTriggers}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Hidden bait routes triggered</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Search Engines (SEO)</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#34d399', margin: '0.25rem 0' }}>{stats.goodBotsAllowed}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Googlebot & Bingbot safe</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Fake Tokens Injected</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#818cf8', margin: '0.25rem 0' }}>{stats.fakeTokens.toLocaleString()}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● AI scrapers polluted</div>\n </div>\n </div>\n\n {toast.show && (\n <div style={{ position: 'fixed', bottom: '2rem', right: '2rem', background: '#1f2937', border: '1px solid #f43f5e', padding: '1rem 1.25rem', borderRadius: '12px', boxShadow: '0 10px 30px rgba(244,63,94,0.3)', zIndex: 999 }}>\n <div style={{ color: '#f43f5e', fontWeight: 'bold', fontSize: '0.8rem', marginBottom: '0.25rem' }}>🚨 AI CRAWLER INTERCEPTED</div>\n <div style={{ fontSize: '0.875rem' }}>\n <strong>{toast.bot}</strong> targeted <code style={{ color: '#818cf8' }}>{toast.path}</code>.<br />\n Returned fake poisoned data (HTTP 200 OK).\n </div>\n </div>\n )}\n </div>\n );\n}\n`;\n fs.writeFileSync(adminPage, nextTemplate, 'utf8');\n console.log(`${colors.green}✓ Created Live Security Dashboard:${colors.reset} app/admin/ai-shield/page.tsx`);\n } else {\n console.log(`${colors.yellow}ℹ Dashboard page already exists at:${colors.reset} app/admin/ai-shield/page.tsx`);\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Next.js Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}npm run dev${colors.reset} and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 2. Express / Node.js Server Auto-Patching\n const serverFile = findServerFile();\n\n if (serverFile) {\n const relPath = path.relative(CWD, serverFile);\n console.log(`${colors.green}✓ Detected server entrypoint:${colors.reset} ${relPath}`);\n let content = fs.readFileSync(serverFile, 'utf8');\n\n if (content.includes('@samimcodes/ai-shield') || content.includes('aiShield(')) {\n console.log(`${colors.yellow}ℹ AI-Shield is already installed in ${relPath}.${colors.reset}`);\n console.log(`Live dashboard is accessible at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n const isEsm = isEsmProject(serverFile);\n const importStatement = isEsm\n ? `import { aiShield } from '@samimcodes/ai-shield';\\n`\n : `const { aiShield } = require('@samimcodes/ai-shield');\\n`;\n\n const middlewareCall = `\\n// 🛡️ Protected by AI-Shield (Automatic Setup)\\napp.use(aiShield({ enableDashboard: true }));\\n`;\n\n // Add import statement at top\n content = importStatement + content;\n\n // Inject app.use right after `const app = express();`\n const appPattern = /(const|let|var)\\s+app\\s*=\\s*express\\s*\\([^)]*\\)\\s*;?/;\n if (appPattern.test(content)) {\n content = content.replace(appPattern, (match) => `${match}${middlewareCall}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield into ${relPath}!${colors.reset}`);\n } else {\n // Prepend before app.listen if app pattern not matched\n const listenPattern = /app\\.listen\\s*\\(/;\n if (listenPattern.test(content)) {\n content = content.replace(listenPattern, (match) => `${middlewareCall}${match}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield before app.listen in ${relPath}!${colors.reset}`);\n } else {\n fs.writeFileSync(serverFile, `${content}${middlewareCall}`, 'utf8');\n console.log(`${colors.yellow}⚠ Added middleware to ${relPath}. Please verify app.use order.${colors.reset}`);\n }\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete! No code writing required!${colors.reset}`);\n console.log(`Start your server and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 3. If no server file exists, create a ready-to-run Express starter\n const starterFile = path.join(CWD, 'server.js');\n const starterContent = `// Created automatically by @samimcodes/ai-shield init\nimport express from 'express';\nimport { aiShield } from '@samimcodes/ai-shield';\n\nconst app = express();\n\n// 🛡️ Live AI Defense + Real-Time Security Monitor\napp.use(aiShield({\n enableDashboard: true,\n}));\n\napp.get('/', (req, res) => {\n res.send('<h1>My Website</h1><p>Protected from AI scrapers by ai-shield.</p>');\n});\n\napp.get('/api/products', (req, res) => {\n res.json({ secretCatalog: [{ id: 1, name: 'Premium Item', price: 99 }] });\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n console.log('Server running on port ' + PORT);\n console.log('Live Security Monitor: http://localhost:' + PORT + '/admin/ai-shield');\n});\n`;\n\n fs.writeFileSync(starterFile, starterContent, 'utf8');\n console.log(`${colors.green}✓ Created new protected Express server:${colors.reset} server.js`);\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}node server.js${colors.reset} and open:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n}\n\n/** Test command to send a simulated bot attack to a running server. */\nfunction runTest(targetUrl?: string) {\n banner();\n const url = targetUrl ?? 'http://localhost:3000/api/products';\n console.log(`🤖 Testing bot defense against: ${colors.cyan}${url}${colors.reset}\\n`);\n\n try {\n const parsed = new URL(url);\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port || 80,\n path: parsed.pathname + parsed.search,\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)',\n 'Accept': 'application/json',\n },\n },\n (res) => {\n let body = '';\n res.on('data', (chunk) => (body += chunk));\n res.on('end', () => {\n console.log(`Response Status: ${colors.bold}${res.statusCode} ${res.statusMessage}${colors.reset}`);\n console.log(`X-Robots-Tag: ${colors.bold}${res.headers['x-robots-tag'] ?? 'None'}${colors.reset}`);\n console.log(`Body Preview: ${colors.magenta}${body.slice(0, 150)}...${colors.reset}\\n`);\n\n if (res.statusCode === 200) {\n console.log(`${colors.green}${colors.bold}✓ SUCCESS! Bot was intercepted and served poisoned response!${colors.reset}`);\n console.log(`Check your live monitor at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n } else {\n console.log(`${colors.yellow}Server returned status ${res.statusCode}. Ensure your server is running.${colors.reset}\\n`);\n }\n });\n },\n );\n\n req.on('error', (err) => {\n console.log(`${colors.red}✗ Connection failed: ${err.message}${colors.reset}`);\n console.log(`Make sure your server is running on ${colors.bold}${url}${colors.reset} before testing.\\n`);\n });\n\n req.end();\n } catch (err) {\n console.log(`${colors.red}Invalid URL: ${targetUrl}${colors.reset}`);\n }\n}\n\n// ── Main CLI Dispatcher ────────────────────────────────────────────────────\n\nconst args = process.argv.slice(2);\nconst command = args[0] || 'init';\n\nswitch (command) {\n case 'init':\n runInit();\n break;\n case 'test':\n runTest(args[1]);\n break;\n case '--help':\n case '-h':\n case 'help':\n banner();\n console.log(`Commands:\n ${colors.bold}npx @samimcodes/ai-shield init${colors.reset} Automatically injects AI-Shield into your server\n ${colors.bold}npx @samimcodes/ai-shield test [url]${colors.reset} Sends a simulated GPTBot attack to test defense\n ${colors.bold}npx @samimcodes/ai-shield --help${colors.reset} Show this help message\n`);\n break;\n default:\n runInit();\n break;\n}\n"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["#!/usr/bin/env node\n/**\n * @file src/cli.ts\n * @description Zero-configuration CLI installer and diagnostic tool for @samimcodes/ai-shield.\n *\n * Allows developers to run `npx @samimcodes/ai-shield init` to automatically\n * patch their project with the defense middleware and live dashboard without\n * writing any manual code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport http from 'node:http';\nimport { execSync } from 'node:child_process';\n\nconst CWD = process.cwd();\n\n// ANSI color helpers (zero external dependencies)\nconst colors = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n green: '\\x1b[32m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n magenta: '\\x1b[35m',\n};\n\nfunction banner() {\n console.log(`\n${colors.cyan}${colors.bold} 🛡️ AI-SHIELD AUTOMATIC SETUP WIZARD${colors.reset}\n ${colors.magenta}Enterprise AI Crawler Defense & Live Security Dashboard${colors.reset}\n -------------------------------------------------------------\n`);\n}\n\n/** Check if current directory is a Next.js project. */\nfunction isNextJsProject(): boolean {\n return (\n fs.existsSync(path.join(CWD, 'next.config.js')) ||\n fs.existsSync(path.join(CWD, 'next.config.mjs')) ||\n fs.existsSync(path.join(CWD, 'next.config.ts')) ||\n (fs.existsSync(path.join(CWD, 'package.json')) &&\n fs.readFileSync(path.join(CWD, 'package.json'), 'utf8').includes('\"next\"'))\n );\n}\n\n/** List candidate Express server entry files. */\nconst SERVER_CANDIDATES = [\n 'server.ts',\n 'src/server.ts',\n 'server.js',\n 'src/server.js',\n 'index.ts',\n 'src/index.ts',\n 'index.js',\n 'src/index.js',\n 'app.ts',\n 'src/app.ts',\n 'app.js',\n 'src/app.js',\n];\n\n/** Find existing server file in target project. */\nfunction findServerFile(): string | null {\n for (const candidate of SERVER_CANDIDATES) {\n const fullPath = path.join(CWD, candidate);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/** Check if project uses ESM. */\nfunction isEsmProject(filePath: string): boolean {\n if (filePath.endsWith('.ts')) return true;\n const pkgPath = path.join(CWD, 'package.json');\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (pkg.type === 'module') return true;\n } catch {\n // ignore\n }\n }\n const content = fs.readFileSync(filePath, 'utf8');\n return content.includes('import ') && content.includes('from ');\n}\n\n/** Auto-install package if not already present in package.json */\nfunction ensurePackageInstalled(): void {\n const pkgPath = path.join(CWD, 'package.json');\n if (!fs.existsSync(pkgPath)) return;\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (allDeps['@samimcodes/ai-shield']) {\n return; // Already installed\n }\n\n console.log(`📦 Auto-installing ${colors.cyan}@samimcodes/ai-shield${colors.reset}...`);\n\n let installCmd = 'npm install @samimcodes/ai-shield';\n if (fs.existsSync(path.join(CWD, 'pnpm-lock.yaml'))) {\n installCmd = 'pnpm add @samimcodes/ai-shield';\n } else if (fs.existsSync(path.join(CWD, 'yarn.lock'))) {\n installCmd = 'yarn add @samimcodes/ai-shield';\n } else if (fs.existsSync(path.join(CWD, 'bun.lockb'))) {\n installCmd = 'bun add @samimcodes/ai-shield';\n }\n\n execSync(installCmd, { cwd: CWD, stdio: 'inherit' });\n console.log(`${colors.green}✓ Installed @samimcodes/ai-shield into project dependencies!${colors.reset}\\n`);\n } catch {\n console.log(`${colors.yellow}ℹ Tip: If needed, run npm install @samimcodes/ai-shield${colors.reset}\\n`);\n }\n}\n\n/** Automatic init command. */\nasync function runInit() {\n banner();\n console.log(`🔍 Scanning project in: ${colors.bold}${CWD}${colors.reset}\\n`);\n\n // Ensure @samimcodes/ai-shield is installed\n ensurePackageInstalled();\n\n // 1. Next.js Project Detection\n if (isNextJsProject()) {\n console.log(`${colors.cyan}⚡ Detected Next.js App Router project!${colors.reset}`);\n const adminDir = path.join(CWD, 'app', 'admin', 'ai-shield');\n const adminPage = path.join(adminDir, 'page.tsx');\n\n fs.mkdirSync(adminDir, { recursive: true });\n\n if (!fs.existsSync(adminPage)) {\n const nextTemplate = `'use client';\n\nimport { useState } from 'react';\n\nexport default function AiShieldDashboard() {\n const [stats, setStats] = useState({ botsIntercepted: 14, goodBotsAllowed: 92, honeypotTriggers: 4, fakeTokens: 6720 });\n const [toast, setToast] = useState<{ show: boolean; bot: string; path: string }>({ show: false, bot: '', path: '' });\n const [events, setEvents] = useState([\n { id: '1', time: 'Just now', bot: 'GPTBot (OpenAI)', score: 100, path: '/api/products', action: 'POISON_JSON' },\n { id: '2', time: '2 mins ago', bot: 'Claude-Web', score: 95, path: '/pricing', action: 'POISON_HTML' },\n { id: '3', time: '5 mins ago', bot: 'ByteSpider', score: 90, path: '/articles', action: 'HONEYPOT_TRAP' },\n ]);\n\n const simulateAttack = () => {\n const testBots = [\n { bot: 'GPTBot (OpenAI)', path: '/api/products', action: 'POISON_JSON' },\n { bot: 'Claude-Web (Anthropic)', path: '/catalog/pricing', action: 'POISON_HTML' },\n { bot: 'ByteSpider (TikTok)', path: '/content/posts', action: 'HONEYPOT_TRAP' },\n ];\n const picked = testBots[Math.floor(Math.random() * testBots.length)] ?? testBots[0];\n setToast({ show: true, bot: picked.bot, path: picked.path });\n setStats((prev) => ({ ...prev, botsIntercepted: prev.botsIntercepted + 1, fakeTokens: prev.fakeTokens + 480 }));\n setEvents((prev) => [{ id: Date.now().toString(), time: new Date().toLocaleTimeString(), bot: picked.bot, score: 100, path: picked.path, action: picked.action }, ...prev]);\n setTimeout(() => setToast({ show: false, bot: '', path: '' }), 4000);\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: '#090d16', color: '#f3f4f6', fontFamily: 'sans-serif', padding: '2rem' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '1rem', marginBottom: '2rem' }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>\n <div style={{ width: '32px', height: '32px', background: 'linear-gradient(135deg, #6366f1, #a855f7)', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>🛡️</div>\n <h1 style={{ fontSize: '1.25rem', fontWeight: 'bold', margin: 0 }}>ai-shield Live Monitor</h1>\n <span style={{ background: 'rgba(16, 185, 129, 0.2)', color: '#34d399', padding: '0.2rem 0.6rem', borderRadius: '999px', fontSize: '0.75rem', fontWeight: 600 }}>● ACTIVE DEFENSE</span>\n </div>\n <button onClick={simulateAttack} style={{ background: '#6366f1', color: '#fff', border: 'none', padding: '0.6rem 1.2rem', borderRadius: '8px', fontWeight: 600, cursor: 'pointer' }}>\n ⚡ Simulate Bot Attack\n </button>\n </div>\n\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '1.25rem', marginBottom: '2.5rem' }}>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Bots Intercepted</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fb7185', margin: '0.25rem 0' }}>{stats.botsIntercepted}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Served synthetic poisoned data</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Honeypot Traps Sprung</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#fbbf24', margin: '0.25rem 0' }}>{stats.honeypotTriggers}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Hidden bait routes triggered</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Search Engines (SEO)</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#34d399', margin: '0.25rem 0' }}>{stats.goodBotsAllowed}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● Googlebot & Bingbot safe</div>\n </div>\n <div style={{ background: '#111827', padding: '1.25rem', borderRadius: '12px', border: '1px solid rgba(255,255,255,0.08)' }}>\n <div style={{ fontSize: '0.8rem', color: '#9ca3af', textTransform: 'uppercase' }}>Fake Tokens Injected</div>\n <div style={{ fontSize: '2rem', fontWeight: 'bold', color: '#818cf8', margin: '0.25rem 0' }}>{stats.fakeTokens.toLocaleString()}</div>\n <div style={{ fontSize: '0.75rem', color: '#9ca3af' }}>● AI scrapers polluted</div>\n </div>\n </div>\n\n {toast.show && (\n <div style={{ position: 'fixed', bottom: '2rem', right: '2rem', background: '#1f2937', border: '1px solid #f43f5e', padding: '1rem 1.25rem', borderRadius: '12px', boxShadow: '0 10px 30px rgba(244,63,94,0.3)', zIndex: 999 }}>\n <div style={{ color: '#f43f5e', fontWeight: 'bold', fontSize: '0.8rem', marginBottom: '0.25rem' }}>🚨 AI CRAWLER INTERCEPTED</div>\n <div style={{ fontSize: '0.875rem' }}>\n <strong>{toast.bot}</strong> targeted <code style={{ color: '#818cf8' }}>{toast.path}</code>.<br />\n Returned fake poisoned data (HTTP 200 OK).\n </div>\n </div>\n )}\n </div>\n );\n}\n`;\n fs.writeFileSync(adminPage, nextTemplate, 'utf8');\n console.log(`${colors.green}✓ Created Live Security Dashboard:${colors.reset} app/admin/ai-shield/page.tsx`);\n } else {\n console.log(`${colors.yellow}ℹ Dashboard page already exists at:${colors.reset} app/admin/ai-shield/page.tsx`);\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Next.js Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}npm run dev${colors.reset} and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 2. Express / Node.js Server Auto-Patching\n const serverFile = findServerFile();\n\n if (serverFile) {\n const relPath = path.relative(CWD, serverFile);\n console.log(`${colors.green}✓ Detected server entrypoint:${colors.reset} ${relPath}`);\n let content = fs.readFileSync(serverFile, 'utf8');\n\n if (content.includes('@samimcodes/ai-shield') || content.includes('aiShield(')) {\n console.log(`${colors.yellow}ℹ AI-Shield is already installed in ${relPath}.${colors.reset}`);\n console.log(`Live dashboard is accessible at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n const isEsm = isEsmProject(serverFile);\n const importStatement = isEsm\n ? `import { aiShield } from '@samimcodes/ai-shield';\\n`\n : `const { aiShield } = require('@samimcodes/ai-shield');\\n`;\n\n const middlewareCall = `\\n// 🛡️ Protected by AI-Shield (Automatic Setup)\\napp.use(aiShield({ enableDashboard: true }));\\n`;\n\n // Add import statement at top\n content = importStatement + content;\n\n // Inject app.use right after `const app = express();`\n const appPattern = /(const|let|var)\\s+app\\s*=\\s*express\\s*\\([^)]*\\)\\s*;?/;\n if (appPattern.test(content)) {\n content = content.replace(appPattern, (match) => `${match}${middlewareCall}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield into ${relPath}!${colors.reset}`);\n } else {\n // Prepend before app.listen if app pattern not matched\n const listenPattern = /app\\.listen\\s*\\(/;\n if (listenPattern.test(content)) {\n content = content.replace(listenPattern, (match) => `${middlewareCall}${match}`);\n fs.writeFileSync(serverFile, content, 'utf8');\n console.log(`${colors.green}✓ Successfully injected aiShield before app.listen in ${relPath}!${colors.reset}`);\n } else {\n fs.writeFileSync(serverFile, `${content}${middlewareCall}`, 'utf8');\n console.log(`${colors.yellow}⚠ Added middleware to ${relPath}. Please verify app.use order.${colors.reset}`);\n }\n }\n\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete! No code writing required!${colors.reset}`);\n console.log(`Start your server and visit:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n return;\n }\n\n // 3. If no server file exists, create a ready-to-run Express starter\n const starterFile = path.join(CWD, 'server.js');\n const starterContent = `// Created automatically by @samimcodes/ai-shield init\nimport express from 'express';\nimport { aiShield } from '@samimcodes/ai-shield';\n\nconst app = express();\n\n// 🛡️ Live AI Defense + Real-Time Security Monitor\napp.use(aiShield({\n enableDashboard: true,\n}));\n\napp.get('/', (req, res) => {\n res.send('<h1>My Website</h1><p>Protected from AI scrapers by ai-shield.</p>');\n});\n\napp.get('/api/products', (req, res) => {\n res.json({ secretCatalog: [{ id: 1, name: 'Premium Item', price: 99 }] });\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n console.log('Server running on port ' + PORT);\n console.log('Live Security Monitor: http://localhost:' + PORT + '/admin/ai-shield');\n});\n`;\n\n fs.writeFileSync(starterFile, starterContent, 'utf8');\n console.log(`${colors.green}✓ Created new protected Express server:${colors.reset} server.js`);\n console.log(`\\n${colors.green}${colors.bold}🎉 Setup Complete!${colors.reset}`);\n console.log(`Run ${colors.cyan}node server.js${colors.reset} and open:`);\n console.log(`👉 ${colors.bold}${colors.green}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n}\n\n/** Test command to send a simulated bot attack to a running server. */\nfunction runTest(targetUrl?: string) {\n banner();\n const url = targetUrl ?? 'http://localhost:3000/api/products';\n console.log(`🤖 Testing bot defense against: ${colors.cyan}${url}${colors.reset}\\n`);\n\n try {\n const parsed = new URL(url);\n const req = http.request(\n {\n hostname: parsed.hostname,\n port: parsed.port || 80,\n path: parsed.pathname + parsed.search,\n method: 'GET',\n headers: {\n 'User-Agent': 'Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)',\n 'Accept': 'application/json',\n },\n },\n (res) => {\n let body = '';\n res.on('data', (chunk) => (body += chunk));\n res.on('end', () => {\n console.log(`Response Status: ${colors.bold}${res.statusCode} ${res.statusMessage}${colors.reset}`);\n console.log(`X-Robots-Tag: ${colors.bold}${res.headers['x-robots-tag'] ?? 'None'}${colors.reset}`);\n console.log(`Body Preview: ${colors.magenta}${body.slice(0, 150)}...${colors.reset}\\n`);\n\n if (res.statusCode === 200) {\n console.log(`${colors.green}${colors.bold}✓ SUCCESS! Bot was intercepted and served poisoned response!${colors.reset}`);\n console.log(`Check your live monitor at: ${colors.cyan}http://localhost:3000/admin/ai-shield${colors.reset}\\n`);\n } else {\n console.log(`${colors.yellow}Server returned status ${res.statusCode}. Ensure your server is running.${colors.reset}\\n`);\n }\n });\n },\n );\n\n req.on('error', (err) => {\n console.log(`${colors.red}✗ Connection failed: ${err.message}${colors.reset}`);\n console.log(`Make sure your server is running on ${colors.bold}${url}${colors.reset} before testing.\\n`);\n });\n\n req.end();\n } catch (err) {\n console.log(`${colors.red}Invalid URL: ${targetUrl}${colors.reset}`);\n }\n}\n\n// ── Main CLI Dispatcher ────────────────────────────────────────────────────\n\nconst args = process.argv.slice(2);\nconst command = args[0] || 'init';\n\nswitch (command) {\n case 'init':\n runInit();\n break;\n case 'test':\n runTest(args[1]);\n break;\n case '--help':\n case '-h':\n case 'help':\n banner();\n console.log(`Commands:\n ${colors.bold}npx @samimcodes/ai-shield init${colors.reset} Automatically injects AI-Shield into your server\n ${colors.bold}npx @samimcodes/ai-shield test [url]${colors.reset} Sends a simulated GPTBot attack to test defense\n ${colors.bold}npx @samimcodes/ai-shield --help${colors.reset} Show this help message\n`);\n break;\n default:\n runInit();\n break;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samimcodes/ai-shield",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Enterprise-grade Express.js middleware to detect and poison unauthorized AI crawlers while preserving SEO for legitimate bots.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",