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.
- package/SKILL.md +37 -0
- package/bin/index.js +372 -0
- 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
|
+
}
|