haraps 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/SKILL.md +37 -0
  2. package/bin/index.js +372 -0
  3. package/package.json +15 -0
package/SKILL.md ADDED
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: scaffold-project-env
3
+ description: Scaffolds the standard development environment, deployment scripts, AGENTS.md guidelines, and core workflows for a Next.js frontend + Rust Cloudflare Worker backend.
4
+ ---
5
+
6
+ # Scaffold Project Environment Skill (Rust + Next.js)
7
+
8
+ This skill automatically sets up a new repository with standard `dev` and `deploy` scripts tailored for a Rust backend (Cloudflare Workers) and a standard Next.js frontend (Vercel/Node deployment, not Pages), along with preferred agent guidelines and workflows.
9
+
10
+ ## Instructions for the Agent
11
+
12
+ When the user runs this skill, execute the following steps precisely:
13
+
14
+ ### Step 1: Run the Scaffolder CLI
15
+
16
+ Execute the following command in the terminal to automatically generate the project scaffolding (dev scripts, deploy scripts, AGENTS.md, workflows, and skills):
17
+
18
+ ```bash
19
+ npx --yes haraps
20
+ ```
21
+
22
+ ### Step 2: Verification
23
+
24
+ Verify that the following files were successfully created in the root directory:
25
+ - `dev.sh` / `dev.ps1`
26
+ - `deploy.sh` / `deploy.ps1`
27
+ - `AGENTS.md`
28
+ - `.agents/workflows/git-it.md`
29
+ - `.agents/workflows/deploy-and-talk.md`
30
+ - `.agents/skills/ponytail/SKILL.md`
31
+ - `.agents/skills/ui-sniper-telegram/SKILL.md`
32
+ - `.agents/skills/kill-ai-slop/SKILL.md`
33
+ - `.agents/skills/security-review/SKILL.md`
34
+
35
+ ### Step 3: Inform the User
36
+
37
+ Notify the user that the project has been successfully scaffolded and all the lazy senior dev standards, security reviews, UI sniper setups, and AI slop removers are in place. Remind them to use `./dev.ps1` or `./dev.sh` once their `frontend/` and `backend/` directories are initialized.
package/bin/index.js ADDED
@@ -0,0 +1,372 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ console.log('πŸš€ Scaffold Project Environment (Hara-XY) πŸš€');
8
+
9
+ function ensureDir(dir) {
10
+ if (!fs.existsSync(dir)) {
11
+ fs.mkdirSync(dir, { recursive: true });
12
+ }
13
+ }
14
+
15
+ function writeFile(filePath, content) {
16
+ const fullPath = path.resolve(process.cwd(), filePath);
17
+ ensureDir(path.dirname(fullPath));
18
+ fs.writeFileSync(fullPath, content.trim() + '\n', 'utf8');
19
+ console.log(`βœ… Created: ${filePath}`);
20
+ }
21
+
22
+ // 1. Dev Scripts
23
+ writeFile('dev.sh', `
24
+ #!/usr/bin/env bash
25
+ # =============================================
26
+ # Local Development Runner (Rust + Next.js)
27
+ # =============================================
28
+
29
+ echo -e "\\e[36m=============================================\\e[0m"
30
+ echo -e "\\e[36m πŸš€ Local Dev Server (Rust + Next.js)\\e[0m"
31
+ echo -e "\\e[36m=============================================\\e[0m"
32
+
33
+ # Aggressive cleanup of ports 3000 (Next) and 8787 (Worker)
34
+ for port in 8787 3000; do
35
+ targetPid=$(lsof -ti :$port)
36
+ if [ ! -z "$targetPid" ]; then
37
+ echo -e "\\e[33m Freeing port $port (PID $targetPid)...\\e[0m"
38
+ kill -9 $targetPid 2>/dev/null
39
+ fi
40
+ done
41
+
42
+ # Run Next.js and Rust Worker concurrently
43
+ npx concurrently \\
44
+ -n "NEXT,RUST" \\
45
+ -c "blue,green" \\
46
+ "cd frontend && npm run dev" \\
47
+ "cd backend && npx wrangler dev"
48
+ `);
49
+ fs.chmodSync(path.resolve(process.cwd(), 'dev.sh'), '755');
50
+
51
+ writeFile('dev.ps1', `
52
+ # =============================================
53
+ # Local Development Runner (Rust + Next.js)
54
+ # =============================================
55
+
56
+ Write-Host "=============================================" -ForegroundColor Cyan
57
+ Write-Host " πŸš€ Local Dev Server (Rust + Next.js)" -ForegroundColor Cyan
58
+ Write-Host "=============================================" -ForegroundColor Cyan
59
+
60
+ # Aggressive cleanup of ports 3000 and 8787
61
+ $ports = @(8787, 3000)
62
+ foreach ($port in $ports) {
63
+ $netstatOutput = netstat -ano | Select-String ":$port\\s+.*LISTENING\\s+(\\d+)"
64
+ if ($netstatOutput) {
65
+ $targetPid = $netstatOutput.Matches[0].Groups[1].Value
66
+ Write-Host " Freeing port $port (PID $targetPid)..." -ForegroundColor Yellow
67
+ Stop-Process -Id $targetPid -Force -ErrorAction SilentlyContinue
68
+ }
69
+ }
70
+
71
+ Write-Host "Starting development environment..." -ForegroundColor Green
72
+ $runnerScript = @'
73
+ const { spawn, execSync } = require('child_process');
74
+ let buffer = '';
75
+ let workerChild;
76
+ let frontendChild;
77
+ let lastRestartTime = 0;
78
+ const startTime = Date.now();
79
+
80
+ function formatSize(bytes) {
81
+ if (bytes < 1024) return bytes + 'B';
82
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + 'KB';
83
+ return (bytes / (1024 * 1024)).toFixed(1) + 'MB';
84
+ }
85
+
86
+ function formatUptime() {
87
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
88
+ const m = Math.floor(elapsed / 60).toString().padStart(2, '0');
89
+ const s = (elapsed % 60).toString().padStart(2, '0');
90
+ return \`\${m}m \${s}s\`;
91
+ }
92
+
93
+ let lastRows = 0;
94
+ let lastCols = 0;
95
+
96
+ function updateLegend() {
97
+ if (!process.stdout.isTTY) return;
98
+ const rows = process.stdout.rows || 30;
99
+ const cols = process.stdout.columns || 80;
100
+ if (rows !== lastRows || cols !== lastCols) {
101
+ process.stdout.write(\`\\x1b[1;\${rows - 2}r\`);
102
+ lastRows = rows;
103
+ lastCols = cols;
104
+ }
105
+ const lineCount = (buffer.match(/\\n/g) || []).length;
106
+ const legend1 = \` [Copy] 'c': All (\${lineCount}L) | 's': 500L | 'w': Backend | 'f': Frontend | 'e': Errors \`;
107
+ const legend2 = \` [System] Uptime: \${formatUptime()} | 'x': Clear | 'r': Restart ALL | 'q': Quit \`;
108
+ process.stdout.write(\`\\x1b[s\\x1b[\${rows - 1};1H\\x1b[42m\\x1b[30m\${legend1.padEnd(cols)}\\x1b[0m\\x1b[\${rows};1H\\x1b[42m\\x1b[30m\${legend2.padEnd(cols)}\\x1b[0m\\x1b[u\`);
109
+ }
110
+
111
+ setInterval(updateLegend, 1000);
112
+
113
+ function createStreamHandler(isError, source) {
114
+ let remainder = '';
115
+ return (d) => {
116
+ const chunk = remainder + d.toString();
117
+ const lines = chunk.split('\\n');
118
+ remainder = lines.pop();
119
+ for (let line of lines) {
120
+ line = line.replace(/\\x1b\\[[23]J/g, '').replace(/\\r/g, '').replace(/^\\[[^\\]]+\\]\\s*/, '');
121
+ if (line.trim() === '') continue;
122
+ const tag = source === 'worker' ? '\\x1b[36m[BACKEND]\\x1b[0m' : '\\x1b[35m[FRONTEND]\\x1b[0m';
123
+ const out = \`\${tag} \${line}\\n\`;
124
+ if (isError) process.stderr.write(out);
125
+ else process.stdout.write(out);
126
+ buffer += out;
127
+ }
128
+ if (buffer.length > 500000) buffer = buffer.slice(-250000);
129
+ };
130
+ }
131
+
132
+ function startWorker() {
133
+ workerChild = spawn('npx.cmd', ['concurrently', '-c', 'cyan', '-n', 'worker', '"cd backend && npx wrangler dev"'], {
134
+ env: { ...process.env, FORCE_COLOR: '1' }, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true, shell: true
135
+ });
136
+ workerChild.stdout.on('data', createStreamHandler(false, 'worker'));
137
+ workerChild.stderr.on('data', createStreamHandler(true, 'worker'));
138
+ }
139
+
140
+ function startFrontend() {
141
+ frontendChild = spawn('npx.cmd', ['concurrently', '-c', 'magenta', '-n', 'frontend', '"cd frontend && npm run dev"'], {
142
+ env: { ...process.env, FORCE_COLOR: '1' }, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true, shell: true
143
+ });
144
+ frontendChild.stdout.on('data', createStreamHandler(false, 'frontend'));
145
+ frontendChild.stderr.on('data', createStreamHandler(true, 'frontend'));
146
+ }
147
+
148
+ startWorker();
149
+ startFrontend();
150
+ console.clear();
151
+ updateLegend();
152
+
153
+ if (process.stdin.isTTY) {
154
+ process.stdin.setRawMode(true);
155
+ process.stdin.resume();
156
+ process.stdin.setEncoding('utf8');
157
+ process.stdin.on('data', k => {
158
+ if (k === 'c' || k === 's' || k === 'w' || k === 'f' || k === 'e') {
159
+ const clean = buffer.replace(/\\x1B(?:[@-Z\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');
160
+ let out = clean;
161
+ if (k === 's') out = clean.split('\\n').slice(-500).join('\\n');
162
+ if (k === 'w') out = clean.split('\\n').filter(l => l.includes('[BACKEND]')).slice(-1000).join('\\n');
163
+ if (k === 'f') out = clean.split('\\n').filter(l => l.includes('[FRONTEND]')).slice(-1000).join('\\n');
164
+ try { execSync('clip', { input: out }); console.log('\\n\\x1b[32mπŸ“‹ Copied to clipboard!\\x1b[0m\\n'); } catch (e) {}
165
+ } else if (k === 'r') {
166
+ console.log('\\n\\x1b[33mπŸ”„ Restarting...\\x1b[0m\\n');
167
+ if (workerChild) try { execSync('taskkill /pid ' + workerChild.pid + ' /t /f', { stdio: 'ignore' }); } catch(e) {}
168
+ if (frontendChild) try { execSync('taskkill /pid ' + frontendChild.pid + ' /t /f', { stdio: 'ignore' }); } catch(e) {}
169
+ startWorker(); startFrontend();
170
+ } else if (k === '\\u0003' || k === 'q') {
171
+ if (workerChild) try { execSync('taskkill /pid ' + workerChild.pid + ' /t /f', { stdio: 'ignore' }); } catch(e) {}
172
+ if (frontendChild) try { execSync('taskkill /pid ' + frontendChild.pid + ' /t /f', { stdio: 'ignore' }); } catch(e) {}
173
+ process.exit();
174
+ }
175
+ });
176
+ }
177
+ '@
178
+ $runnerPath = Join-Path $env:TEMP "mediqueue-dev-runner.js"
179
+ Set-Content -Path $runnerPath -Value $runnerScript -Encoding UTF8
180
+ node $runnerPath
181
+ `);
182
+
183
+ // 2. Deploy Scripts
184
+ writeFile('deploy.sh', `
185
+ #!/usr/bin/env bash
186
+ set -e
187
+
188
+ echo -e "\\e[36m=============================================\\e[0m"
189
+ echo -e "\\e[36m πŸš€ Deploying System (Rust + Next.js)\\e[0m"
190
+ echo -e "\\e[36m=============================================\\e[0m"
191
+
192
+ echo -e "\\e[32m[1/2] Deploying Rust Cloudflare Worker...\\e[0m"
193
+ cd backend
194
+ npx wrangler deploy
195
+ cd ..
196
+
197
+ echo -e "\\e[34m[2/2] Deploying Next.js Frontend...\\e[0m"
198
+ cd frontend
199
+ npm run build
200
+ npx vercel deploy --prod
201
+ cd ..
202
+
203
+ echo -e "\\e[32mDeployment Complete!\\e[0m"
204
+ `);
205
+ fs.chmodSync(path.resolve(process.cwd(), 'deploy.sh'), '755');
206
+
207
+ writeFile('deploy.ps1', `
208
+ $ErrorActionPreference = 'Stop'
209
+
210
+ Write-Host "=============================================" -ForegroundColor Cyan
211
+ Write-Host " πŸš€ Deploying System (Rust + Next.js)" -ForegroundColor Cyan
212
+ Write-Host "=============================================" -ForegroundColor Cyan
213
+
214
+ Write-Host "[1/2] Deploying Rust Cloudflare Worker..." -ForegroundColor Green
215
+ Set-Location backend
216
+ npx wrangler deploy
217
+ Set-Location ..
218
+
219
+ Write-Host "[2/2] Deploying Next.js Frontend..." -ForegroundColor Blue
220
+ Set-Location frontend
221
+ npm run build
222
+ npx vercel deploy --prod
223
+ Set-Location ..
224
+
225
+ Write-Host "Deployment Complete!" -ForegroundColor Green
226
+ `);
227
+
228
+ // 3. Agent Rules
229
+ writeFile('AGENTS.md', `
230
+ # High-Performance Engineering Standards
231
+ 1. **Ponytail, lazy senior dev mode**: The best code is the code never written. YAGNI. Question complex requests, reuse existing standards, prefer deletion over addition, and write the minimal correct code.
232
+ 2. **Edge-First Execution**: Backend logic must be optimized for serverless edge deployment (Cloudflare Workers).
233
+ 3. **Data Layer Optimization**: Never execute untuned queries. Use connection pooling and batching.
234
+ 4. **Minimalist Frontend Render**: Ensure frontend implementations are highly optimized for Next.js, favoring SSR where appropriate, avoiding heavy client bundles, and ensuring mobile-first responsive design.
235
+ 5. **Master Debugging**: Trace issues to their root cause before writing a fix. Use the "Five Whys" protocol.
236
+ 6. **Strict Typing**: TypeScript and Rust types must be explicit, avoid \`any\` or \`unwrap()\` where possible.
237
+ 7. **Structured Logging**: Implement structured logging, avoiding excessive console.logs in production.
238
+ 8. **Atomic Commits**: Ensure commits are small, atomic, and pass CI checks before pushing.
239
+ 9. **Error Boundaries**: Frontend must wrap critical components in Error Boundaries to prevent full app crashes.
240
+ 10. **No Placeholder Code**: Never write generic "TODO" or placeholder logic if the requirements are known.
241
+ 11. **Security Best Practices**: Enforce strict input validation, rate limiting, and secure credential handling by default.
242
+ 12. **Automated Testing & TDD**: Require unit and integration tests for critical paths. Code is not done until it's tested.
243
+ 13. **Strict Linting & Formatting**: Enforce ESLint, Prettier, and Clippy with zero warnings allowed.
244
+ 14. **Accessibility (a11y) First**: Require ARIA labels, semantic HTML, and keyboard navigation for all frontend components.
245
+ 15. **Documentation Standards**: Mandate JSDoc (frontend) and Rustdoc (backend) for all public APIs and reusable components.
246
+ 16. **CI/CD Pipeline Setup**: Ensure GitHub Actions (or similar) are configured for automated checks, tests, and deployments.
247
+ 17. **State Management Rules**: Prefer local state or React Context; enforce strict rules against unnecessary global state.
248
+ 18. **Environment Variable Validation**: Fail fast at startup if required \`.env\` variables are missing.
249
+ 19. **Kill AI Slop**: Remove aesthetic clichΓ©s (indigo gradients, glowing cards, excessive emojis) that serve no functional purpose.
250
+ 20. **Security First Principle**: Treat all external input as malicious; leverage the Security Review skill for all external-facing endpoints.
251
+ `);
252
+
253
+ // 4. Workflows
254
+ writeFile('.agents/workflows/git-it.md', `
255
+ # Safe Git Sync Workflow
256
+ 1. Stage all changes (\`git add .\`).
257
+ 2. Write a descriptive, conventional commit message based on the recent changes.
258
+ 3. Commit the changes (\`git commit -m "..."\`).
259
+ 4. Pull with rebase (\`git pull --rebase\`).
260
+ 5. Push to the remote branch (\`git push\`).
261
+ `);
262
+
263
+ writeFile('.agents/workflows/deploy-and-talk.md', `
264
+ # Deploy and Talk Workflow
265
+ 1. Execute the deployment script (\`./deploy.ps1\` or \`./deploy.sh\`).
266
+ 2. Verify successful deployment output.
267
+ 3. Send a Telegram notification using \`Invoke-RestMethod\` to alert the team that the deployment is complete. Include a brief changelog.
268
+ `);
269
+
270
+ // 5. Skills
271
+ writeFile('.agents/skills/ponytail/SKILL.md', `
272
+ ---
273
+ name: ponytail
274
+ description: Enforces lazy senior dev principles. Efficient, not careless. Deletion over addition.
275
+ ---
276
+ # Ponytail, lazy senior dev mode
277
+
278
+ You are a lazy senior developer. Lazy means efficient, not careless. The best code is the code never written.
279
+
280
+ Before writing any code, stop at the first rung that holds:
281
+ 1. Does this need to be built at all? (YAGNI)
282
+ 2. Does it already exist in this codebase? Reuse the helper, util, or pattern that's already here, don't re-write it.
283
+ 3. Does the standard library already do this? Use it.
284
+ 4. Does a native platform feature cover it? Use it.
285
+ 5. Does an already-installed dependency solve it? Use it.
286
+ 6. Can this be one line? Make it one line.
287
+ 7. Only then: write the minimum code that works.
288
+
289
+ The ladder runs after you understand the problem, not instead of it: read the task and the code it touches, trace the real flow end to end, then climb.
290
+
291
+ Bug fix = root cause, not symptom: a report names a symptom. Grep every caller of the function you touch and fix the shared function once.
292
+
293
+ Rules:
294
+ - No abstractions that weren't explicitly requested.
295
+ - No new dependency if it can be avoided.
296
+ - No boilerplate nobody asked for.
297
+ - Deletion over addition. Boring over clever. Fewest files possible.
298
+ - Shortest working diff wins, but only once you understand the problem.
299
+ - Question complex requests: "Do you actually need X, or does Y cover it?"
300
+ - Mark deliberate simplifications that cut a real corner with a known ceiling with a \`ponytail:\` comment naming the ceiling and upgrade path.
301
+ `);
302
+
303
+ writeFile('.agents/skills/ui-sniper-telegram/SKILL.md', `
304
+ ---
305
+ name: ui-sniper-telegram
306
+ description: Automates the setup of a UI Sniper system integrated with a Telegram bot for capturing frontend UI feedback directly to a Telegram group.
307
+ ---
308
+ # UI Sniper Telegram Integration Skill
309
+ 1. **Ask for Credentials**: Prompt the user for their \`TELEGRAM_BOT_TOKEN\` and \`TELEGRAM_CHAT_ID\`. Wait for their response.
310
+ 2. **Install**: Install \`ui-sniper\` and scaffold the Next.js API route (\`app/api/ui-sniper-webhook/route.ts\`), and set up the \`UISniperWrapper.tsx\` component.
311
+ 3. **Configure**: Add the wrapper to \`app/layout.tsx\` and place the credentials in \`.env.local\`.
312
+ `);
313
+
314
+ writeFile('.agents/skills/kill-ai-slop/SKILL.md', `
315
+ ---
316
+ name: kill-ai-slop
317
+ description: Scans a web project to detect and strip out AI-generated aesthetic clichΓ©s (indigo gradients, excessive emojis, glowing cards) replacing them with clean, tasteful, and accessible design patterns.
318
+ ---
319
+
320
+ # Kill AI Slop Skill
321
+ Run the following command in the terminal to execute the scanner:
322
+ \`\`\`bash
323
+ npx --yes skills add yetone/kill-ai-slop
324
+ \`\`\`
325
+ Or execute the scanner directly on the project directory:
326
+ \`\`\`bash
327
+ npx --yes kill-ai-slop .
328
+ \`\`\`
329
+ Review the reported "tells" and apply the suggested clean fixes (e.g., removing indigo gradients, replacing emojis with proper SVG icons, removing glowing cards in favor of paper/ink aesthetics).
330
+ `);
331
+
332
+ writeFile('.agents/skills/security-review/SKILL.md', `
333
+ ---
334
+ name: security-review
335
+ description: 'AI-powered codebase security scanner that reasons about code like a security researcher β€” tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching tools miss.'
336
+ ---
337
+
338
+ # Security Review
339
+
340
+ An AI-powered security scanner that reasons about your codebase the way a human security researcher would β€” tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching tools miss.
341
+
342
+ ## Execution Workflow
343
+ 1. **Scope Resolution**: Determine what to scan (specific path or entire project).
344
+ 2. **Dependency Audit**: Audit dependencies first (check package.json, Cargo.toml for known vulnerable packages).
345
+ 3. **Secrets & Exposure Scan**: Scan ALL files for hardcoded API keys, tokens, passwords, and \`.env\` files.
346
+ 4. **Vulnerability Deep Scan**: Check for Injection Flaws, Authentication/Access Control issues, Data Handling weaknesses, and Cryptography issues.
347
+ 5. **Cross-File Data Flow Analysis**: Trace user-controlled input from entry points to dangerous sinks.
348
+ 6. **Self-Verification Pass**: Filter false positives.
349
+ 7. **Generate Security Report**: Output a findings summary table and structured report with severities (CRITICAL, HIGH, MEDIUM, LOW, INFO).
350
+ 8. **Propose Patches**: For every CRITICAL and HIGH finding, generate a concrete patch for human review. **Never auto-apply any patch.**
351
+ `);
352
+
353
+ console.log('βœ… All skills, workflows, dev scripts, and rules generated successfully.');
354
+ console.log('');
355
+ console.log('πŸ“¦ Installing additional NPM packages in the current project...');
356
+
357
+ try {
358
+ // If there is a package.json, install UI dependencies
359
+ if (fs.existsSync('package.json')) {
360
+ console.log(' - Installing ui-sniper and html2canvas...');
361
+ execSync('npm install ui-sniper html2canvas', { stdio: 'inherit' });
362
+ } else {
363
+ console.log(' - No package.json found. Skipping ui-sniper installation.');
364
+ }
365
+ } catch (error) {
366
+ console.warn('⚠️ Could not install npm dependencies automatically.');
367
+ }
368
+
369
+ console.log('');
370
+ console.log('πŸŽ‰ Scaffolding Complete! πŸŽ‰');
371
+ console.log('πŸ‘‰ To start your project, run ./dev.ps1 or ./dev.sh (if your frontend/backend folders are set up).');
372
+ console.log('πŸ‘‰ Agents have been loaded with Ponytail, Security Review, and Kill AI Slop skills.');
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "haraps",
3
+ "version": "1.0.0",
4
+ "description": "NPM package to scaffold standard development environment, deployment scripts, AGENTS.md guidelines, and core workflows for a Next.js frontend + Rust Cloudflare Worker backend.",
5
+ "main": "bin/index.js",
6
+ "bin": {
7
+ "haraps": "bin/index.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "keywords": [],
13
+ "author": "",
14
+ "license": "ISC"
15
+ }