neoagent 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/.env.example +28 -0
- package/LICENSE +21 -0
- package/README.md +42 -0
- package/bin/neoagent.js +8 -0
- package/com.neoagent.plist +45 -0
- package/docs/configuration.md +45 -0
- package/docs/skills.md +45 -0
- package/lib/manager.js +459 -0
- package/package.json +61 -0
- package/server/db/database.js +239 -0
- package/server/index.js +442 -0
- package/server/middleware/auth.js +35 -0
- package/server/public/app.html +559 -0
- package/server/public/css/app.css +608 -0
- package/server/public/css/styles.css +472 -0
- package/server/public/favicon.svg +17 -0
- package/server/public/js/app.js +3283 -0
- package/server/public/login.html +313 -0
- package/server/routes/agents.js +125 -0
- package/server/routes/auth.js +105 -0
- package/server/routes/browser.js +116 -0
- package/server/routes/mcp.js +164 -0
- package/server/routes/memory.js +193 -0
- package/server/routes/messaging.js +153 -0
- package/server/routes/protocols.js +87 -0
- package/server/routes/scheduler.js +63 -0
- package/server/routes/settings.js +98 -0
- package/server/routes/skills.js +107 -0
- package/server/routes/store.js +1192 -0
- package/server/services/ai/compaction.js +82 -0
- package/server/services/ai/engine.js +1690 -0
- package/server/services/ai/models.js +46 -0
- package/server/services/ai/multiStep.js +112 -0
- package/server/services/ai/providers/anthropic.js +181 -0
- package/server/services/ai/providers/base.js +40 -0
- package/server/services/ai/providers/google.js +187 -0
- package/server/services/ai/providers/grok.js +121 -0
- package/server/services/ai/providers/ollama.js +162 -0
- package/server/services/ai/providers/openai.js +167 -0
- package/server/services/ai/toolRunner.js +218 -0
- package/server/services/browser/controller.js +320 -0
- package/server/services/cli/executor.js +204 -0
- package/server/services/mcp/client.js +260 -0
- package/server/services/memory/embeddings.js +126 -0
- package/server/services/memory/manager.js +431 -0
- package/server/services/messaging/base.js +23 -0
- package/server/services/messaging/discord.js +238 -0
- package/server/services/messaging/manager.js +328 -0
- package/server/services/messaging/telegram.js +243 -0
- package/server/services/messaging/telnyx.js +693 -0
- package/server/services/messaging/whatsapp.js +304 -0
- package/server/services/scheduler/cron.js +312 -0
- package/server/services/websocket.js +191 -0
- package/server/utils/security.js +71 -0
|
@@ -0,0 +1,1192 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { requireAuth } = require('../middleware/auth');
|
|
5
|
+
|
|
6
|
+
router.use(requireAuth);
|
|
7
|
+
|
|
8
|
+
const SKILLS_DIR = path.join(__dirname, '../../agent-data/skills');
|
|
9
|
+
|
|
10
|
+
// ── Skill catalog ─────────────────────────────────────────────────────────────
|
|
11
|
+
// Each entry: id (becomes filename <id>.md), name, description, category, icon, content
|
|
12
|
+
const CATALOG = [
|
|
13
|
+
|
|
14
|
+
// ── SYSTEM ──────────────────────────────────────────────────────────────────
|
|
15
|
+
{
|
|
16
|
+
id: 'disk-usage',
|
|
17
|
+
name: 'Disk Usage',
|
|
18
|
+
description: 'Show disk space usage for all mounted filesystems.',
|
|
19
|
+
category: 'system',
|
|
20
|
+
icon: '💾',
|
|
21
|
+
content: `---
|
|
22
|
+
name: disk-usage
|
|
23
|
+
description: Show disk space usage for all mounted filesystems
|
|
24
|
+
category: system
|
|
25
|
+
icon: 💾
|
|
26
|
+
enabled: true
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
Run \`df -h\` to show disk usage. If the user asks about a specific path, run \`du -sh <path>\`. Present the output in a readable table, highlight any filesystems above 80% usage.`
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
id: 'system-stats',
|
|
34
|
+
name: 'System Stats',
|
|
35
|
+
description: 'Report CPU, RAM, load average and uptime.',
|
|
36
|
+
category: 'system',
|
|
37
|
+
icon: '📊',
|
|
38
|
+
content: `---
|
|
39
|
+
name: system-stats
|
|
40
|
+
description: Report CPU, RAM, load average and uptime
|
|
41
|
+
category: system
|
|
42
|
+
icon: 📊
|
|
43
|
+
enabled: true
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
Run these commands and summarise the results:
|
|
47
|
+
- \`uptime\` — load average and uptime
|
|
48
|
+
- \`free -m\` (Linux) or \`vm_stat\` (macOS) — memory usage
|
|
49
|
+
- \`nproc\` or \`sysctl -n hw.logicalcpu\` — CPU count
|
|
50
|
+
|
|
51
|
+
Combine into a short dashboard-style summary.`
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
id: 'process-monitor',
|
|
56
|
+
name: 'Process Monitor',
|
|
57
|
+
description: 'List the top 15 processes by CPU or memory usage.',
|
|
58
|
+
category: 'system',
|
|
59
|
+
icon: '⚙️',
|
|
60
|
+
content: `---
|
|
61
|
+
name: process-monitor
|
|
62
|
+
description: List the top 15 processes by CPU or memory usage
|
|
63
|
+
category: system
|
|
64
|
+
icon: ⚙️
|
|
65
|
+
enabled: true
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
Run \`ps aux --sort=-%cpu | head -16\` on Linux or \`ps aux -r | head -16\` on macOS to show top CPU processes. If the user asks for memory, use \`ps aux --sort=-%mem | head -16\`. Format as a readable table with PID, command, CPU%, MEM%.`
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
id: 'tail-log',
|
|
73
|
+
name: 'Tail Log File',
|
|
74
|
+
description: 'Show the last N lines of any log file, with optional filtering.',
|
|
75
|
+
category: 'system',
|
|
76
|
+
icon: '📋',
|
|
77
|
+
content: `---
|
|
78
|
+
name: tail-log
|
|
79
|
+
description: Show the last N lines of any log file, with optional filtering
|
|
80
|
+
category: system
|
|
81
|
+
icon: 📋
|
|
82
|
+
enabled: true
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
Run \`tail -n <lines> <file>\` to show recent log lines. Default to 50 lines if not specified. If the user provides a filter keyword, pipe through \`grep <keyword>\`. For common logs, suggest: /var/log/syslog, /var/log/nginx/error.log, ./logs/app.log etc.`
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
id: 'find-large-files',
|
|
90
|
+
name: 'Find Large Files',
|
|
91
|
+
description: 'Find the largest files in a directory tree.',
|
|
92
|
+
category: 'system',
|
|
93
|
+
icon: '🔍',
|
|
94
|
+
content: `---
|
|
95
|
+
name: find-large-files
|
|
96
|
+
description: Find the largest files in a directory tree
|
|
97
|
+
category: system
|
|
98
|
+
icon: 🔍
|
|
99
|
+
enabled: true
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
Run \`find <dir> -type f -exec du -sh {} + 2>/dev/null | sort -rh | head -20\` to list the 20 largest files. Default to current directory if none provided. Present as a ranked list with human-readable sizes.`
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
// ── NETWORK ─────────────────────────────────────────────────────────────────
|
|
106
|
+
{
|
|
107
|
+
id: 'ping-host',
|
|
108
|
+
name: 'Ping Host',
|
|
109
|
+
description: 'Ping a hostname or IP and report latency and packet loss.',
|
|
110
|
+
category: 'network',
|
|
111
|
+
icon: '📡',
|
|
112
|
+
content: `---
|
|
113
|
+
name: ping-host
|
|
114
|
+
description: Ping a hostname or IP and report latency and packet loss
|
|
115
|
+
category: network
|
|
116
|
+
icon: 📡
|
|
117
|
+
enabled: true
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
Run \`ping -c 5 <host>\` to send 5 ICMP packets. Report average RTT, packet loss %, and whether the host is reachable. If the host is unreachable, suggest checking DNS or firewall.`
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
{
|
|
124
|
+
id: 'ip-info',
|
|
125
|
+
name: 'IP Info',
|
|
126
|
+
description: 'Get your public IP address and geolocation details.',
|
|
127
|
+
category: 'network',
|
|
128
|
+
icon: '🌐',
|
|
129
|
+
content: `---
|
|
130
|
+
name: ip-info
|
|
131
|
+
description: Get your public IP address and geolocation details
|
|
132
|
+
category: network
|
|
133
|
+
icon: 🌐
|
|
134
|
+
enabled: true
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
Make a GET request to \`https://ipinfo.io/json\` (no auth needed for basic info). Display the IP, city, region, country, org (ISP), and timezone in a clean summary. If the user asks about a specific IP, use \`https://ipinfo.io/<ip>/json\`.`
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
id: 'ssl-check',
|
|
142
|
+
name: 'SSL Certificate Check',
|
|
143
|
+
description: 'Check the SSL certificate expiry date for any domain.',
|
|
144
|
+
category: 'network',
|
|
145
|
+
icon: '🔒',
|
|
146
|
+
content: `---
|
|
147
|
+
name: ssl-check
|
|
148
|
+
description: Check the SSL certificate expiry date for any domain
|
|
149
|
+
category: network
|
|
150
|
+
icon: 🔒
|
|
151
|
+
enabled: true
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
Run \`echo | openssl s_client -connect <domain>:443 -servername <domain> 2>/dev/null | openssl x509 -noout -dates\` to get cert validity dates. Calculate how many days until expiry. Warn if < 30 days, alert if < 7 days, or if already expired.`
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
{
|
|
158
|
+
id: 'port-check',
|
|
159
|
+
name: 'Port Check',
|
|
160
|
+
description: 'Test whether a specific TCP port is open on a host.',
|
|
161
|
+
category: 'network',
|
|
162
|
+
icon: '🔌',
|
|
163
|
+
content: `---
|
|
164
|
+
name: port-check
|
|
165
|
+
description: Test whether a specific TCP port is open on a host
|
|
166
|
+
category: network
|
|
167
|
+
icon: 🔌
|
|
168
|
+
enabled: true
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
Run \`nc -zv -w3 <host> <port> 2>&1\` or \`curl -s --connect-timeout 3 telnet://<host>:<port>\` to test connectivity. Report clearly: open or closed/filtered, and response time if measurable. Common ports to suggest: 80 (HTTP), 443 (HTTPS), 22 (SSH), 3306 (MySQL), 5432 (Postgres), 6379 (Redis).`
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
id: 'dns-lookup',
|
|
176
|
+
name: 'DNS Lookup',
|
|
177
|
+
description: 'Perform DNS lookups (A, MX, TXT, CNAME records) for any domain.',
|
|
178
|
+
category: 'network',
|
|
179
|
+
icon: '🗺️',
|
|
180
|
+
content: `---
|
|
181
|
+
name: dns-lookup
|
|
182
|
+
description: Perform DNS lookups (A, MX, TXT, CNAME records) for any domain
|
|
183
|
+
category: network
|
|
184
|
+
icon: 🗺️
|
|
185
|
+
enabled: true
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
Use \`dig <domain> <type>\` or \`nslookup\` to query DNS records. Default to A records. If the user says "all records", run dig for A, MX, TXT, CNAME in one go. Present results cleanly without raw dig headers.`
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// ── INFO ────────────────────────────────────────────────────────────────────
|
|
192
|
+
{
|
|
193
|
+
id: 'weather',
|
|
194
|
+
name: 'Weather',
|
|
195
|
+
description: 'Get current weather and a 3-day forecast for any city.',
|
|
196
|
+
category: 'info',
|
|
197
|
+
icon: '🌤️',
|
|
198
|
+
content: `---
|
|
199
|
+
name: weather
|
|
200
|
+
description: Get current weather and a 3-day forecast for any city
|
|
201
|
+
category: info
|
|
202
|
+
icon: 🌤️
|
|
203
|
+
enabled: true
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
Make a GET request to \`https://wttr.in/<city>?format=j1\` (returns JSON). Parse:
|
|
207
|
+
- current_condition[0]: temp_C, weatherDesc, humidity, windspeedKmph, feels_like
|
|
208
|
+
- weather[0..2]: date, maxtempC, mintempC, hourly[4].weatherDesc (midday)
|
|
209
|
+
|
|
210
|
+
Present as a clean weather card: current conditions + 3-day forecast with icons. URL-encode city names with spaces.`
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
{
|
|
214
|
+
id: 'crypto-price',
|
|
215
|
+
name: 'Crypto Price',
|
|
216
|
+
description: 'Look up live cryptocurrency prices from CoinGecko.',
|
|
217
|
+
category: 'info',
|
|
218
|
+
icon: '₿',
|
|
219
|
+
content: `---
|
|
220
|
+
name: crypto-price
|
|
221
|
+
description: Look up live cryptocurrency prices from CoinGecko
|
|
222
|
+
category: info
|
|
223
|
+
icon: ₿
|
|
224
|
+
enabled: true
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
Use the CoinGecko free API (no key needed):
|
|
228
|
+
- Single coin: \`GET https://api.coingecko.com/api/v3/simple/price?ids=<id>&vs_currencies=usd,eur&include_24hr_change=true\`
|
|
229
|
+
- Common IDs: bitcoin, ethereum, solana, cardano, dogecoin, ripple, polkadot, chainlink, litecoin, avalanche-2
|
|
230
|
+
|
|
231
|
+
Show price in USD and EUR, 24h change %, and a trend arrow ↑↓. If the user uses a ticker (BTC), map it to the CoinGecko ID first.`
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
{
|
|
235
|
+
id: 'exchange-rate',
|
|
236
|
+
name: 'Exchange Rate',
|
|
237
|
+
description: 'Get live currency exchange rates between any two currencies.',
|
|
238
|
+
category: 'info',
|
|
239
|
+
icon: '💱',
|
|
240
|
+
content: `---
|
|
241
|
+
name: exchange-rate
|
|
242
|
+
description: Get live currency exchange rates between any two currencies
|
|
243
|
+
category: info
|
|
244
|
+
icon: 💱
|
|
245
|
+
enabled: true
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
Use the free Open Exchange Rates API:
|
|
249
|
+
\`GET https://open.er-api.com/v6/latest/<base_currency>\`
|
|
250
|
+
|
|
251
|
+
Example: \`https://open.er-api.com/v6/latest/USD\` returns rates for all currencies relative to USD.
|
|
252
|
+
Show the requested conversion with the exact rate and the last updated time. If the user gives an amount (e.g. "200 EUR to GBP"), calculate and show the converted value.`
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
{
|
|
256
|
+
id: 'world-time',
|
|
257
|
+
name: 'World Time',
|
|
258
|
+
description: 'Show the current local time in major cities around the world.',
|
|
259
|
+
category: 'info',
|
|
260
|
+
icon: '🕐',
|
|
261
|
+
content: `---
|
|
262
|
+
name: world-time
|
|
263
|
+
description: Show the current local time in major cities around the world
|
|
264
|
+
category: info
|
|
265
|
+
icon: 🕐
|
|
266
|
+
enabled: true
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
Run \`date\` for local time. Get world times via the API:
|
|
270
|
+
\`GET https://worldtimeapi.org/api/timezone/<Region/City>\`
|
|
271
|
+
|
|
272
|
+
Show a table of current times for: New York (America/New_York), London (Europe/London), Berlin (Europe/Berlin), Dubai (Asia/Dubai), Singapore (Asia/Singapore), Tokyo (Asia/Tokyo), Sydney (Australia/Sydney). Format as HH:MM timezone with day name.`
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
{
|
|
276
|
+
id: 'news-hackernews',
|
|
277
|
+
name: 'Hacker News Top Stories',
|
|
278
|
+
description: 'Fetch the top 10 stories from Hacker News right now.',
|
|
279
|
+
category: 'info',
|
|
280
|
+
icon: '📰',
|
|
281
|
+
content: `---
|
|
282
|
+
name: news-hackernews
|
|
283
|
+
description: Fetch the top 10 stories from Hacker News right now
|
|
284
|
+
category: info
|
|
285
|
+
icon: 📰
|
|
286
|
+
enabled: true
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
1. GET \`https://hacker-news.firebaseio.com/v0/topstories.json\` → get array of IDs
|
|
290
|
+
2. Take the first 10 IDs
|
|
291
|
+
3. For each ID, GET \`https://hacker-news.firebaseio.com/v0/item/<id>.json\` → title, url, score, by, descendants
|
|
292
|
+
Present as a numbered list: score points | title | by author (N comments). Link the title.`
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
// ── DEV ─────────────────────────────────────────────────────────────────────
|
|
296
|
+
{
|
|
297
|
+
id: 'git-summary',
|
|
298
|
+
name: 'Git Summary',
|
|
299
|
+
description: 'Show recent commits, current branch, and status for a git repo.',
|
|
300
|
+
category: 'dev',
|
|
301
|
+
icon: '🌿',
|
|
302
|
+
content: `---
|
|
303
|
+
name: git-summary
|
|
304
|
+
description: Show recent commits, current branch, and status for a git repo
|
|
305
|
+
category: dev
|
|
306
|
+
icon: 🌿
|
|
307
|
+
enabled: true
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
Run in the user's specified directory (default: current working directory):
|
|
311
|
+
1. \`git log --oneline -10\` — last 10 commits
|
|
312
|
+
2. \`git status --short\` — dirty files
|
|
313
|
+
3. \`git branch --show-current\` — current branch
|
|
314
|
+
4. \`git remote -v\` — remotes
|
|
315
|
+
|
|
316
|
+
Present as a structured git dashboard. Note any uncommitted changes or detached HEAD.`
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
{
|
|
320
|
+
id: 'docker-status',
|
|
321
|
+
name: 'Docker Status',
|
|
322
|
+
description: 'List all running and stopped Docker containers with their status.',
|
|
323
|
+
category: 'dev',
|
|
324
|
+
icon: '🐳',
|
|
325
|
+
content: `---
|
|
326
|
+
name: docker-status
|
|
327
|
+
description: List all running and stopped Docker containers with their status
|
|
328
|
+
category: dev
|
|
329
|
+
icon: 🐳
|
|
330
|
+
enabled: true
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
Run \`docker ps -a --format "table {{.Names}}\\t{{.Image}}\\t{{.Status}}\\t{{.Ports}}"\` to list all containers. Also run \`docker images --format "table {{.Repository}}:{{.Tag}}\\t{{.Size}}"\` to show local images.
|
|
334
|
+
Highlight running vs stopped vs exited. If Docker isn't installed/running, say so clearly.`
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
{
|
|
338
|
+
id: 'npm-outdated',
|
|
339
|
+
name: 'NPM Outdated Check',
|
|
340
|
+
description: 'Check for outdated npm packages in a Node.js project.',
|
|
341
|
+
category: 'dev',
|
|
342
|
+
icon: '📦',
|
|
343
|
+
content: `---
|
|
344
|
+
name: npm-outdated
|
|
345
|
+
description: Check for outdated npm packages in a Node.js project
|
|
346
|
+
category: dev
|
|
347
|
+
icon: 📦
|
|
348
|
+
enabled: true
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
Run \`npm outdated --json\` in the project directory. Parse the JSON and display as a table:
|
|
352
|
+
Package | Current | Wanted | Latest | Type (dep/devDep)
|
|
353
|
+
|
|
354
|
+
Categorise: minor updates (wanted > current), major updates (latest >> current). Suggest running \`npm update\` for minor updates or manual upgrades for majors. Handle "everything up to date" gracefully.`
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
{
|
|
358
|
+
id: 'run-tests',
|
|
359
|
+
name: 'Run Tests',
|
|
360
|
+
description: 'Run the test suite for a project and summarise results.',
|
|
361
|
+
category: 'dev',
|
|
362
|
+
icon: '✅',
|
|
363
|
+
content: `---
|
|
364
|
+
name: run-tests
|
|
365
|
+
description: Run the test suite for a project and summarise results
|
|
366
|
+
category: dev
|
|
367
|
+
icon: ✅
|
|
368
|
+
enabled: true
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
Check what test runner is configured (look at package.json scripts.test). Then run \`npm test\` (or \`yarn test\`, \`pytest\`, etc. as appropriate). Capture stdout/stderr.
|
|
372
|
+
Summarise: total tests, passed, failed, skipped. If failures occur, show the first 3 failed test names and errors. Do NOT truncate error details — they're important.`
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
{
|
|
376
|
+
id: 'http-debug',
|
|
377
|
+
name: 'HTTP Debug',
|
|
378
|
+
description: 'Make a detailed HTTP request and inspect headers, status, timing.',
|
|
379
|
+
category: 'dev',
|
|
380
|
+
icon: '🔎',
|
|
381
|
+
content: `---
|
|
382
|
+
name: http-debug
|
|
383
|
+
description: Make a detailed HTTP request and inspect headers, status, timing
|
|
384
|
+
category: dev
|
|
385
|
+
icon: 🔎
|
|
386
|
+
enabled: true
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
Use the http_request tool to make the request with full header capture. Also run \`curl -o /dev/null -s -w "\\n%{http_code} | %{time_total}s | %{size_download} bytes\\n" <url>\` for timing. Report:
|
|
390
|
+
- Status code and meaning
|
|
391
|
+
- Response time
|
|
392
|
+
- Key headers (Content-Type, Cache-Control, X-Frame-Options, etc.)
|
|
393
|
+
- Body preview (first 500 chars)
|
|
394
|
+
- Any redirects`
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
// ── PRODUCTIVITY ─────────────────────────────────────────────────────────────
|
|
398
|
+
{
|
|
399
|
+
id: 'summarize-url',
|
|
400
|
+
name: 'Summarize URL',
|
|
401
|
+
description: 'Fetch a webpage and give a concise summary of its content.',
|
|
402
|
+
category: 'productivity',
|
|
403
|
+
icon: '📄',
|
|
404
|
+
content: `---
|
|
405
|
+
name: summarize-url
|
|
406
|
+
description: Fetch a webpage and give a concise summary of its content
|
|
407
|
+
category: productivity
|
|
408
|
+
icon: 📄
|
|
409
|
+
enabled: true
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
Use http_request to GET the URL. Extract text content from the HTML (skip scripts, styles, nav). Write a structured summary:
|
|
413
|
+
- **What it is**: 1 sentence
|
|
414
|
+
- **Key points**: 3–5 bullet points
|
|
415
|
+
- **Takeaway**: most important thing to know
|
|
416
|
+
|
|
417
|
+
Keep total summary under 200 words. If the URL fails or returns non-HTML, say so.`
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
{
|
|
421
|
+
id: 'wikipedia',
|
|
422
|
+
name: 'Wikipedia Summary',
|
|
423
|
+
description: 'Get a Wikipedia article summary for any topic.',
|
|
424
|
+
category: 'productivity',
|
|
425
|
+
icon: '📚',
|
|
426
|
+
content: `---
|
|
427
|
+
name: wikipedia
|
|
428
|
+
description: Get a Wikipedia article summary for any topic
|
|
429
|
+
category: productivity
|
|
430
|
+
icon: 📚
|
|
431
|
+
enabled: true
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
Use the Wikipedia REST API:
|
|
435
|
+
\`GET https://en.wikipedia.org/api/rest_v1/page/summary/<title>\`
|
|
436
|
+
|
|
437
|
+
URL-encode the title (replace spaces with underscores). The response contains \`extract\` (plain text summary) and \`content_urls.desktop.page\` (full article link).
|
|
438
|
+
|
|
439
|
+
Show the summary with the article URL. If the topic resolves to a disambiguation page, show the top options. Support language override via \`https://<lang>.wikipedia.org/...\`.`
|
|
440
|
+
},
|
|
441
|
+
|
|
442
|
+
{
|
|
443
|
+
id: 'translate',
|
|
444
|
+
name: 'Translate Text',
|
|
445
|
+
description: 'Translate any text to a target language.',
|
|
446
|
+
category: 'productivity',
|
|
447
|
+
icon: '🌍',
|
|
448
|
+
content: `---
|
|
449
|
+
name: translate
|
|
450
|
+
description: Translate any text to a target language
|
|
451
|
+
category: productivity
|
|
452
|
+
icon: 🌍
|
|
453
|
+
enabled: true
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
Use the LibreTranslate free API:
|
|
457
|
+
\`POST https://libretranslate.com/translate\`
|
|
458
|
+
Body: \`{"q": "<text>", "source": "auto", "target": "<lang_code>", "format": "text"}\`
|
|
459
|
+
|
|
460
|
+
Common language codes: en, de, fr, es, it, pt, nl, ru, zh, ja, ko, ar.
|
|
461
|
+
Show the translation clearly, note the detected source language. If the API fails, fall back to using your own translation ability with a note.`
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
{
|
|
465
|
+
id: 'quick-note',
|
|
466
|
+
name: 'Quick Note',
|
|
467
|
+
description: 'Save a timestamped note to a notes file on disk.',
|
|
468
|
+
category: 'productivity',
|
|
469
|
+
icon: '📝',
|
|
470
|
+
content: `---
|
|
471
|
+
name: quick-note
|
|
472
|
+
description: Save a timestamped note to a notes file on disk
|
|
473
|
+
category: productivity
|
|
474
|
+
icon: 📝
|
|
475
|
+
enabled: true
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
Append the note to \`~/notes.md\` (or a user-specified file) with this format:
|
|
479
|
+
\`\`\`
|
|
480
|
+
## 2025-01-15 14:32
|
|
481
|
+
<note content>
|
|
482
|
+
\`\`\`
|
|
483
|
+
Use \`echo\` or \`tee -a\` to append. Confirm the note was saved and show the file path. If the file doesn't exist, create it with a \`# Notes\` header first.`
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
{
|
|
487
|
+
id: 'pomodoro',
|
|
488
|
+
name: 'Pomodoro Timer',
|
|
489
|
+
description: 'Start a Pomodoro focus timer with a desktop notification at the end.',
|
|
490
|
+
category: 'productivity',
|
|
491
|
+
icon: '🍅',
|
|
492
|
+
content: `---
|
|
493
|
+
name: pomodoro
|
|
494
|
+
description: Start a Pomodoro focus timer with a desktop notification at the end
|
|
495
|
+
category: productivity
|
|
496
|
+
icon: 🍅
|
|
497
|
+
enabled: true
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
Default: 25-minute work session followed by a 5-minute break. Run in background:
|
|
501
|
+
\`\`\`bash
|
|
502
|
+
(sleep 1500 && osascript -e 'display notification "Pomodoro complete! Take a break." with title "🍅 Pomodoro"' 2>/dev/null || notify-send "🍅 Pomodoro" "Complete! Take a break." 2>/dev/null || echo "POMODORO DONE") &
|
|
503
|
+
\`\`\`
|
|
504
|
+
Print the PID and end time so the user can track it. Support custom durations.`
|
|
505
|
+
},
|
|
506
|
+
|
|
507
|
+
// ── GOOGLE ──────────────────────────────────────────────────────────────────
|
|
508
|
+
{
|
|
509
|
+
id: 'gogcli',
|
|
510
|
+
name: 'Google Suite (gogcli)',
|
|
511
|
+
description: 'Control Gmail, Calendar, Drive, Tasks, Contacts, Sheets, Chat and more via the gog CLI.',
|
|
512
|
+
category: 'productivity',
|
|
513
|
+
icon: '🌐',
|
|
514
|
+
content: `---
|
|
515
|
+
name: gogcli
|
|
516
|
+
description: Control Gmail, Calendar, Drive, Tasks, Contacts, Sheets, Chat and more via the gog CLI
|
|
517
|
+
category: productivity
|
|
518
|
+
icon: 🌐
|
|
519
|
+
trigger: gmail|calendar|drive|tasks|contacts|sheets|google
|
|
520
|
+
enabled: true
|
|
521
|
+
source: https://github.com/steipete/gogcli
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Overview
|
|
525
|
+
\`gog\` (gogcli) is a fast, JSON-first CLI for Google Workspace services. Install via:
|
|
526
|
+
\`\`\`
|
|
527
|
+
brew install steipete/tap/gogcli
|
|
528
|
+
\`\`\`
|
|
529
|
+
Use \`--json\` for machine-readable output.
|
|
530
|
+
|
|
531
|
+
## Credential Storage (NeoAgent)
|
|
532
|
+
Store the Google account email in API_KEYS.json so you can always retrieve it:
|
|
533
|
+
\`\`\`
|
|
534
|
+
memory_write target=api_keys content={"gog_account": "you@gmail.com"}
|
|
535
|
+
\`\`\`
|
|
536
|
+
For non-interactive / headless runs, also store the keyring password:
|
|
537
|
+
\`\`\`
|
|
538
|
+
memory_write target=api_keys content={"gog_account": "you@gmail.com", "gog_keyring_password": "<your-keyring-password>"}
|
|
539
|
+
\`\`\`
|
|
540
|
+
Before every \`gog\` command, read back these keys:
|
|
541
|
+
\`\`\`
|
|
542
|
+
memory_read target=api_keys
|
|
543
|
+
\`\`\`
|
|
544
|
+
Then run gog with the stored values:
|
|
545
|
+
\`\`\`bash
|
|
546
|
+
export GOG_ACCOUNT="<gog_account from api_keys>"
|
|
547
|
+
export GOG_KEYRING_BACKEND=file # use on-disk encrypted keyring (no Keychain prompts)
|
|
548
|
+
export GOG_KEYRING_PASSWORD="<gog_keyring_password from api_keys>" # if set
|
|
549
|
+
gog ...
|
|
550
|
+
\`\`\`
|
|
551
|
+
|
|
552
|
+
## First-Time Setup (run once manually by the user)
|
|
553
|
+
\`\`\`bash
|
|
554
|
+
gog auth credentials ~/Downloads/client_secret_....json # store OAuth client credentials
|
|
555
|
+
gog auth keyring file # switch to file backend (avoids Keychain prompts)
|
|
556
|
+
gog auth add you@gmail.com # authorize account — opens browser
|
|
557
|
+
gog auth status # verify auth state
|
|
558
|
+
gog auth list # list stored accounts
|
|
559
|
+
\`\`\`
|
|
560
|
+
After setup, save the account email with memory_write (above) so the agent can use it automatically.
|
|
561
|
+
|
|
562
|
+
## Gmail
|
|
563
|
+
\`\`\`bash
|
|
564
|
+
gog gmail search 'newer_than:7d is:unread' --max 10 --json
|
|
565
|
+
gog gmail thread get <threadId>
|
|
566
|
+
gog gmail send --to a@b.com --subject "Subject" --body "Body"
|
|
567
|
+
gog gmail send --to a@b.com --subject "Subject" --body-html "<p>Hi</p>"
|
|
568
|
+
gog gmail labels list
|
|
569
|
+
gog gmail thread modify <threadId> --add STARRED --remove INBOX
|
|
570
|
+
\`\`\`
|
|
571
|
+
|
|
572
|
+
## Calendar
|
|
573
|
+
\`\`\`bash
|
|
574
|
+
gog calendar events primary --today --json
|
|
575
|
+
gog calendar events primary --week
|
|
576
|
+
gog calendar search "standup" --days 7 --json
|
|
577
|
+
gog calendar create primary --summary "Meeting" --from 2026-01-15T10:00:00Z --to 2026-01-15T11:00:00Z --attendees "a@b.com"
|
|
578
|
+
gog calendar freebusy --calendars primary --from 2026-01-15T00:00:00Z --to 2026-01-16T00:00:00Z
|
|
579
|
+
gog calendar delete primary <eventId> --force
|
|
580
|
+
\`\`\`
|
|
581
|
+
|
|
582
|
+
## Drive
|
|
583
|
+
\`\`\`bash
|
|
584
|
+
gog drive ls --max 20 --json
|
|
585
|
+
gog drive search "invoice" --max 20 --json
|
|
586
|
+
gog drive upload ./file.pdf
|
|
587
|
+
gog drive download <fileId> --out ./file.pdf
|
|
588
|
+
gog drive share <fileId> --to user --email user@example.com --role reader
|
|
589
|
+
\`\`\`
|
|
590
|
+
|
|
591
|
+
## Tasks
|
|
592
|
+
\`\`\`bash
|
|
593
|
+
gog tasks lists --json
|
|
594
|
+
gog tasks list <tasklistId> --json
|
|
595
|
+
gog tasks add <tasklistId> --title "Task title" --due 2026-02-01
|
|
596
|
+
gog tasks done <tasklistId> <taskId>
|
|
597
|
+
\`\`\`
|
|
598
|
+
|
|
599
|
+
## Contacts
|
|
600
|
+
\`\`\`bash
|
|
601
|
+
gog contacts search "John" --max 20 --json
|
|
602
|
+
gog contacts create --given "Jane" --family "Doe" --email "jane@example.com"
|
|
603
|
+
\`\`\`
|
|
604
|
+
|
|
605
|
+
## Sheets
|
|
606
|
+
\`\`\`bash
|
|
607
|
+
gog sheets metadata <spreadsheetId>
|
|
608
|
+
gog sheets get <spreadsheetId> 'Sheet1!A1:D10' --json
|
|
609
|
+
gog sheets update <spreadsheetId> 'Sheet1!A1' 'val1|val2,val3|val4'
|
|
610
|
+
gog sheets append <spreadsheetId> 'Sheet1!A:C' 'new|row|data'
|
|
611
|
+
\`\`\`
|
|
612
|
+
|
|
613
|
+
## Docs / Slides
|
|
614
|
+
\`\`\`bash
|
|
615
|
+
gog docs cat <docId>
|
|
616
|
+
gog docs export <docId> --format pdf --out ./doc.pdf
|
|
617
|
+
gog docs sed <docId> 's/old/new/g'
|
|
618
|
+
gog slides export <presentationId> --format pptx --out ./deck.pptx
|
|
619
|
+
\`\`\`
|
|
620
|
+
|
|
621
|
+
## Tips
|
|
622
|
+
- Pipe JSON output to \`jq\` for filtering: \`gog --json gmail search 'is:unread' | jq '.threads[].id'\`
|
|
623
|
+
- Use \`GOG_ENABLE_COMMANDS=gmail,calendar\` to sandbox allowed commands
|
|
624
|
+
- \`--plain\` outputs stable TSV for shell scripting
|
|
625
|
+
- Calendar JSON includes \`startDayOfWeek\` and localized time fields, useful for scheduling logic`
|
|
626
|
+
},
|
|
627
|
+
|
|
628
|
+
// ── COMMUNITY ────────────────────────────────────────────────────────────────
|
|
629
|
+
{
|
|
630
|
+
id: 'answeroverflow',
|
|
631
|
+
name: 'Answer Overflow',
|
|
632
|
+
description: 'Search indexed Discord community discussions for coding answers via Answer Overflow.',
|
|
633
|
+
category: 'productivity',
|
|
634
|
+
icon: '💬',
|
|
635
|
+
content: `---
|
|
636
|
+
name: answeroverflow
|
|
637
|
+
description: Search indexed Discord community discussions for coding answers via Answer Overflow
|
|
638
|
+
category: productivity
|
|
639
|
+
icon: 💬
|
|
640
|
+
trigger: discord|answeroverflow|community support
|
|
641
|
+
enabled: true
|
|
642
|
+
source: https://github.com/AnswerOverflow/AnswerOverflow
|
|
643
|
+
---
|
|
644
|
+
|
|
645
|
+
## What is Answer Overflow?
|
|
646
|
+
Answer Overflow indexes public Discord support channels and makes them searchable via Google and direct API. Perfect for finding answers that only exist in Discord conversations — from servers like Valorant, Cloudflare, C#, Nuxt, and thousands more.
|
|
647
|
+
|
|
648
|
+
## Quick Search (via Google)
|
|
649
|
+
\`\`\`bash
|
|
650
|
+
# Best approach — Answer Overflow results appear in Google
|
|
651
|
+
web_search "site:answeroverflow.com prisma connection pooling"
|
|
652
|
+
web_search "site:answeroverflow.com nextjs app router error"
|
|
653
|
+
web_search "site:answeroverflow.com discord.js slash commands"
|
|
654
|
+
\`\`\`
|
|
655
|
+
|
|
656
|
+
## Fetch Thread Content
|
|
657
|
+
\`\`\`bash
|
|
658
|
+
# Markdown format (preferred for agents)
|
|
659
|
+
http_request GET https://www.answeroverflow.com/m/<message-id>
|
|
660
|
+
# Add Accept: text/markdown header, or use /m/ prefix URL
|
|
661
|
+
\`\`\`
|
|
662
|
+
|
|
663
|
+
URL patterns:
|
|
664
|
+
- Thread: \`https://www.answeroverflow.com/m/<message-id>\`
|
|
665
|
+
- Server: \`https://www.answeroverflow.com/c/<server-slug>\`
|
|
666
|
+
- Channel: \`https://www.answeroverflow.com/c/<server-slug>/<channel-slug>\`
|
|
667
|
+
|
|
668
|
+
## MCP Server
|
|
669
|
+
Answer Overflow exposes an MCP server at \`https://www.answeroverflow.com/mcp\`:
|
|
670
|
+
|
|
671
|
+
| Tool | Description |
|
|
672
|
+
|------|-------------|
|
|
673
|
+
| \`search_answeroverflow\` | Search all indexed communities; filter by server/channel ID |
|
|
674
|
+
| \`search_servers\` | Discover indexed Discord servers |
|
|
675
|
+
| \`get_thread_messages\` | Get all messages from a specific thread |
|
|
676
|
+
| \`find_similar_threads\` | Find threads related to a given thread |
|
|
677
|
+
|
|
678
|
+
To add it as an MCP server in NeoAgent: command \`npx -y @answeroverflow/mcp\`
|
|
679
|
+
|
|
680
|
+
## Tips
|
|
681
|
+
- Results are real Discord conversations — context may be informal
|
|
682
|
+
- Threads often have back-and-forth before the solution; read the whole thread
|
|
683
|
+
- Check the server/channel name to understand context (official support vs community)
|
|
684
|
+
- Many major open-source projects index their Discord support channels here`
|
|
685
|
+
},
|
|
686
|
+
|
|
687
|
+
// ── FUN ─────────────────────────────────────────────────────────────────────
|
|
688
|
+
{
|
|
689
|
+
id: 'random-joke',
|
|
690
|
+
name: 'Random Joke',
|
|
691
|
+
description: 'Fetch a random joke (clean, programmer or general).',
|
|
692
|
+
category: 'fun',
|
|
693
|
+
icon: '😄',
|
|
694
|
+
content: `---
|
|
695
|
+
name: random-joke
|
|
696
|
+
description: Fetch a random joke (clean, programmer or general)
|
|
697
|
+
category: fun
|
|
698
|
+
icon: 😄
|
|
699
|
+
enabled: true
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
GET \`https://v2.jokeapi.dev/joke/Programming,Miscellaneous?blacklistFlags=nsfw,racist,sexist,explicit\`
|
|
703
|
+
|
|
704
|
+
The response has either a single \`joke\` field or a two-part \`setup\`/\`delivery\`. Present it naturally — pause before the punchline in delivery style. If the user asks for a specific category (dark, pun, etc.), adjust the URL accordingly.`
|
|
705
|
+
},
|
|
706
|
+
|
|
707
|
+
{
|
|
708
|
+
id: 'random-quote',
|
|
709
|
+
name: 'Random Quote',
|
|
710
|
+
description: 'Get a random motivational or philosophical quote.',
|
|
711
|
+
category: 'fun',
|
|
712
|
+
icon: '💭',
|
|
713
|
+
content: `---
|
|
714
|
+
name: random-quote
|
|
715
|
+
description: Get a random motivational or philosophical quote
|
|
716
|
+
category: fun
|
|
717
|
+
icon: 💭
|
|
718
|
+
enabled: true
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
GET \`https://api.quotable.io/random\`
|
|
722
|
+
|
|
723
|
+
Show: \`"<content>"\` — *<author>*
|
|
724
|
+
|
|
725
|
+
If the user specifies a topic or author, use:
|
|
726
|
+
\`https://api.quotable.io/random?tags=<tag>\` (common tags: technology, wisdom, success, life, motivational, literature, science)
|
|
727
|
+
\`https://api.quotable.io/quotes?author=<slug>\` for a specific author.`
|
|
728
|
+
},
|
|
729
|
+
|
|
730
|
+
{
|
|
731
|
+
id: 'random-fact',
|
|
732
|
+
name: 'Random Fact',
|
|
733
|
+
description: 'Get a random interesting fact.',
|
|
734
|
+
category: 'fun',
|
|
735
|
+
icon: '🧠',
|
|
736
|
+
content: `---
|
|
737
|
+
name: random-fact
|
|
738
|
+
description: Get a random interesting fact
|
|
739
|
+
category: fun
|
|
740
|
+
icon: 🧠
|
|
741
|
+
enabled: true
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
GET \`https://uselessfacts.jsph.pl/api/v2/facts/random?language=en\` for a random fact.
|
|
745
|
+
Alternatively: \`https://api.api-ninjas.com/v1/facts?limit=1\` (no key needed for free tier).
|
|
746
|
+
Present the fact naturally, optionally adding a brief "why this is interesting" comment if it's not immediately obvious.`
|
|
747
|
+
},
|
|
748
|
+
|
|
749
|
+
{
|
|
750
|
+
id: 'word-definition',
|
|
751
|
+
name: 'Word Definition',
|
|
752
|
+
description: 'Look up the definition, pronunciation and examples for any word.',
|
|
753
|
+
category: 'fun',
|
|
754
|
+
icon: '📖',
|
|
755
|
+
content: `---
|
|
756
|
+
name: word-definition
|
|
757
|
+
description: Look up the definition, pronunciation and examples for any word
|
|
758
|
+
category: fun
|
|
759
|
+
icon: 📖
|
|
760
|
+
enabled: true
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
GET \`https://api.dictionaryapi.dev/api/v2/entries/en/<word>\`
|
|
764
|
+
|
|
765
|
+
Extract and display:
|
|
766
|
+
- Pronunciation (phonetic)
|
|
767
|
+
- Part of speech
|
|
768
|
+
- Primary definition(s)
|
|
769
|
+
- Example sentence if available
|
|
770
|
+
- Synonyms (first 5)
|
|
771
|
+
|
|
772
|
+
If the word isn't found, suggest similar spellings. Supports multiple meanings grouped by part of speech.`
|
|
773
|
+
},
|
|
774
|
+
|
|
775
|
+
{
|
|
776
|
+
id: 'qr-code',
|
|
777
|
+
name: 'QR Code Generator',
|
|
778
|
+
description: 'Generate a QR code image URL for any text or URL.',
|
|
779
|
+
category: 'fun',
|
|
780
|
+
icon: '⬛',
|
|
781
|
+
content: `---
|
|
782
|
+
name: qr-code
|
|
783
|
+
description: Generate a QR code image URL for any text or URL
|
|
784
|
+
category: fun
|
|
785
|
+
icon: ⬛
|
|
786
|
+
enabled: true
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
Use the QR Server API (no auth):
|
|
790
|
+
\`https://api.qrserver.com/v1/create-qr-code/?data=<encoded_text>&size=300x300&margin=10\`
|
|
791
|
+
|
|
792
|
+
URL-encode the input data. Provide the direct image URL that the user can open in a browser or embed. Also calculate: at the default error correction level (M), the QR can hold the given text reliably up to X characters.`
|
|
793
|
+
},
|
|
794
|
+
|
|
795
|
+
// ── DEV (continued) ──────────────────────────────────────────────────────────
|
|
796
|
+
{
|
|
797
|
+
id: 'github',
|
|
798
|
+
name: 'GitHub',
|
|
799
|
+
description: 'Interact with GitHub repos, PRs, issues, branches, CI and releases using git and the gh CLI.',
|
|
800
|
+
category: 'dev',
|
|
801
|
+
icon: '🐙',
|
|
802
|
+
content: `---
|
|
803
|
+
name: github
|
|
804
|
+
description: Interact with GitHub repos, PRs, issues, branches, CI and releases using git and the gh CLI
|
|
805
|
+
trigger: When the user asks to clone a repo, create a PR, open/close issues, check CI status, fork, review diffs, manage branches, or do anything GitHub-related
|
|
806
|
+
category: dev
|
|
807
|
+
icon: 🐙
|
|
808
|
+
enabled: true
|
|
809
|
+
---
|
|
810
|
+
|
|
811
|
+
# GitHub Skill
|
|
812
|
+
|
|
813
|
+
Use \`git\` for local version control and \`gh\` (GitHub CLI) for GitHub-specific actions.
|
|
814
|
+
Always verify both tools are available: \`which git && which gh\`.
|
|
815
|
+
If \`gh\` is not authenticated, prompt the user to run \`gh auth login\`.
|
|
816
|
+
|
|
817
|
+
## Repo Status & Info
|
|
818
|
+
\`\`\`
|
|
819
|
+
gh repo view # show current repo overview
|
|
820
|
+
gh repo view <owner>/<repo> # show a specific repo
|
|
821
|
+
git status # show working tree state
|
|
822
|
+
git log --oneline -20 # last 20 commits
|
|
823
|
+
git diff # unstaged changes
|
|
824
|
+
git diff --staged # staged changes
|
|
825
|
+
\`\`\`
|
|
826
|
+
|
|
827
|
+
## Clone & Fork
|
|
828
|
+
\`\`\`
|
|
829
|
+
gh repo clone <owner>/<repo> # clone via gh (sets up remote automatically)
|
|
830
|
+
gh repo fork <owner>/<repo> --clone # fork and clone in one step
|
|
831
|
+
\`\`\`
|
|
832
|
+
|
|
833
|
+
## Branches
|
|
834
|
+
\`\`\`
|
|
835
|
+
git checkout -b <branch> # create and switch to new branch
|
|
836
|
+
git branch -a # list all branches (local + remote)
|
|
837
|
+
git push -u origin <branch> # push new branch to origin
|
|
838
|
+
git branch -d <branch> # delete local branch
|
|
839
|
+
gh repo sync # sync fork with upstream
|
|
840
|
+
\`\`\`
|
|
841
|
+
|
|
842
|
+
## Commits & Push
|
|
843
|
+
\`\`\`
|
|
844
|
+
git add -A && git commit -m "<msg>" # stage all and commit
|
|
845
|
+
git push # push to tracked remote branch
|
|
846
|
+
git pull --rebase # pull with rebase
|
|
847
|
+
\`\`\`
|
|
848
|
+
|
|
849
|
+
## Pull Requests
|
|
850
|
+
\`\`\`
|
|
851
|
+
gh pr create --title "<title>" --body "<body>" # open a PR
|
|
852
|
+
gh pr list # list open PRs
|
|
853
|
+
gh pr view <number> # view a specific PR
|
|
854
|
+
gh pr checkout <number> # check out a PR branch locally
|
|
855
|
+
gh pr merge <number> --squash # merge PR (squash)
|
|
856
|
+
gh pr review <number> --approve # approve a PR
|
|
857
|
+
gh pr review <number> --request-changes -b "<feedback>"
|
|
858
|
+
gh pr close <number> # close without merging
|
|
859
|
+
gh pr status # PRs involving you
|
|
860
|
+
\`\`\`
|
|
861
|
+
|
|
862
|
+
## Issues
|
|
863
|
+
\`\`\`
|
|
864
|
+
gh issue create --title "<title>" --body "<body>" # create issue
|
|
865
|
+
gh issue list # list open issues
|
|
866
|
+
gh issue view <number> # view an issue
|
|
867
|
+
gh issue close <number> # close an issue
|
|
868
|
+
gh issue comment <number> -b "<comment>" # add a comment
|
|
869
|
+
gh issue assign <number> --assignee @me # assign to yourself
|
|
870
|
+
\`\`\`
|
|
871
|
+
|
|
872
|
+
## Releases & Tags
|
|
873
|
+
\`\`\`
|
|
874
|
+
gh release create <tag> --title "<title>" --notes "<notes>"
|
|
875
|
+
gh release list
|
|
876
|
+
gh release view <tag>
|
|
877
|
+
git tag -a v1.0.0 -m "Release v1.0.0" && git push --tags
|
|
878
|
+
\`\`\`
|
|
879
|
+
|
|
880
|
+
## CI / Actions
|
|
881
|
+
\`\`\`
|
|
882
|
+
gh run list # list recent workflow runs
|
|
883
|
+
gh run view <run-id> # view a run's details and logs
|
|
884
|
+
gh run watch <run-id> # stream live logs
|
|
885
|
+
gh workflow list # list workflows
|
|
886
|
+
gh workflow run <workflow-file> # trigger a workflow manually
|
|
887
|
+
\`\`\`
|
|
888
|
+
|
|
889
|
+
## Presentation Tips
|
|
890
|
+
- For pr/issue lists, format as a table: number, title, author, date.
|
|
891
|
+
- For git log, show short hash, message, and relative date.
|
|
892
|
+
- For CI runs, summarise: ✅ success / ❌ failure / ⏳ in progress per job.
|
|
893
|
+
- Confirm with the user before any repo-modifying operation (push, merge, delete).`
|
|
894
|
+
},
|
|
895
|
+
|
|
896
|
+
// ── RESEARCH ─────────────────────────────────────────────────────────────────
|
|
897
|
+
{
|
|
898
|
+
id: 'deep-research',
|
|
899
|
+
name: 'Deep Research',
|
|
900
|
+
description: 'Conduct thorough multi-source research on any topic and synthesise findings into a structured report.',
|
|
901
|
+
category: 'research',
|
|
902
|
+
icon: '🔬',
|
|
903
|
+
content: `---
|
|
904
|
+
name: deep-research
|
|
905
|
+
description: Conduct thorough multi-source research on any topic, synthesising findings into a structured report
|
|
906
|
+
trigger: When the user asks for deep research, a detailed investigation, a comprehensive overview, or wants to understand a complex topic in depth
|
|
907
|
+
category: research
|
|
908
|
+
icon: 🔬
|
|
909
|
+
enabled: true
|
|
910
|
+
---
|
|
911
|
+
|
|
912
|
+
# Deep Research Skill
|
|
913
|
+
|
|
914
|
+
Perform iterative, multi-source research by combining web searches, page reads, and cross-referencing. Don't stop at the first result — go wide, then go deep.
|
|
915
|
+
|
|
916
|
+
## Research Process
|
|
917
|
+
|
|
918
|
+
### 1. Clarify the Query
|
|
919
|
+
Decompose the topic into 3–5 sub-questions that together fully answer the user's request. State them so the user can correct scope before you begin.
|
|
920
|
+
|
|
921
|
+
### 2. Broad Discovery (go wide)
|
|
922
|
+
Run multiple searches using varied queries and angles:
|
|
923
|
+
- Direct topic searches: \`<topic> overview\`, \`<topic> explained\`
|
|
924
|
+
- Authoritative sources: \`site:en.wikipedia.org <topic>\`, \`site:arxiv.org <topic>\`
|
|
925
|
+
- Recent developments: \`<topic> 2025\`, \`<topic> latest research\`
|
|
926
|
+
- Opposing views: \`<topic> criticism\`, \`<topic> limitations\`, \`<topic> controversy\`
|
|
927
|
+
|
|
928
|
+
Use \`https://html.duckduckgo.com/html/?q=<query>\` for web searches (parse \`<a class="result__a">\` links and snippets).
|
|
929
|
+
|
|
930
|
+
### 3. Deep Reads (go deep)
|
|
931
|
+
For each sub-question, identify the 3–5 most relevant URLs. Fetch and read each one fully. Extract:
|
|
932
|
+
- Key claims and data points
|
|
933
|
+
- Author / publication / date (assess credibility)
|
|
934
|
+
- References to follow up on
|
|
935
|
+
|
|
936
|
+
### 4. Cross-Reference & Validate
|
|
937
|
+
- Note where sources agree and disagree.
|
|
938
|
+
- Flag claims from only one source as unverified.
|
|
939
|
+
- If numbers or stats are cited, trace to the primary source.
|
|
940
|
+
- Prefer sources from the last 2 years unless historical context is needed.
|
|
941
|
+
|
|
942
|
+
### 5. Synthesise & Report
|
|
943
|
+
\`\`\`
|
|
944
|
+
## Summary
|
|
945
|
+
2–3 sentence TL;DR.
|
|
946
|
+
|
|
947
|
+
## Background
|
|
948
|
+
Context needed to understand the topic.
|
|
949
|
+
|
|
950
|
+
## Key Findings
|
|
951
|
+
- Finding 1 (source: [title](url))
|
|
952
|
+
- Finding 2 ...
|
|
953
|
+
|
|
954
|
+
## Different Perspectives / Debate
|
|
955
|
+
Where experts or sources disagree, and why.
|
|
956
|
+
|
|
957
|
+
## Open Questions / Gaps
|
|
958
|
+
What is still unknown or contested.
|
|
959
|
+
|
|
960
|
+
## Sources
|
|
961
|
+
Numbered list of all URLs consulted, with title and date.
|
|
962
|
+
\`\`\`
|
|
963
|
+
|
|
964
|
+
## Tips
|
|
965
|
+
- Run at least 5 distinct searches before writing the report.
|
|
966
|
+
- Read at least 4 full pages (not just snippets).
|
|
967
|
+
- Never present a single source as definitive — always triangulate.
|
|
968
|
+
- Cite every factual claim with a link.`
|
|
969
|
+
},
|
|
970
|
+
|
|
971
|
+
{
|
|
972
|
+
id: 'coding',
|
|
973
|
+
name: 'Coding',
|
|
974
|
+
description: 'Write, debug, refactor, explain, and review code in any programming language.',
|
|
975
|
+
category: 'dev',
|
|
976
|
+
icon: '💻',
|
|
977
|
+
content: `---
|
|
978
|
+
name: coding
|
|
979
|
+
description: Write, debug, refactor, explain, and review code in any programming language
|
|
980
|
+
trigger: When the user asks to write code, fix a bug, refactor, explain how code works, review a function, add tests, or help with any programming task
|
|
981
|
+
category: dev
|
|
982
|
+
icon: 💻
|
|
983
|
+
enabled: true
|
|
984
|
+
---
|
|
985
|
+
|
|
986
|
+
# Coding Skill
|
|
987
|
+
|
|
988
|
+
Handle the full software development lifecycle: writing new code, understanding existing code, debugging, refactoring, and testing — in any language.
|
|
989
|
+
|
|
990
|
+
## Write New Code
|
|
991
|
+
- Confirm the language, framework, and environment before starting.
|
|
992
|
+
- Ask for constraints (performance, style guide, existing dependencies).
|
|
993
|
+
- Write clean, idiomatic code with comments for non-obvious logic.
|
|
994
|
+
- Include a usage example or short test block where helpful.
|
|
995
|
+
|
|
996
|
+
## Debug & Fix
|
|
997
|
+
1. Read the full error message and stack trace carefully.
|
|
998
|
+
2. Identify the exact file and line where the error originates.
|
|
999
|
+
3. Inspect surrounding code for logic errors, type mismatches, null-dereferences, or off-by-one errors.
|
|
1000
|
+
4. Run the code in a terminal to reproduce the error if needed.
|
|
1001
|
+
5. Apply the minimal fix that resolves the root cause — avoid masking errors with bare try/catch.
|
|
1002
|
+
6. Explain what was wrong and why the fix works.
|
|
1003
|
+
|
|
1004
|
+
## Refactor
|
|
1005
|
+
- Identify code smells: duplication, long functions, deep nesting, magic numbers, unclear naming.
|
|
1006
|
+
- Refactor in small, safe steps — preserve behaviour before improving structure.
|
|
1007
|
+
- Prefer readability over cleverness.
|
|
1008
|
+
- Verify functionality is unchanged after refactoring.
|
|
1009
|
+
|
|
1010
|
+
## Explain Code
|
|
1011
|
+
- Summarise what the code does at a high level first.
|
|
1012
|
+
- Walk through it section by section, explaining intent not just mechanics.
|
|
1013
|
+
- Highlight non-obvious patterns (closures, generators, recursion, bitwise tricks, etc.).
|
|
1014
|
+
- Point out potential edge cases or bugs noticed during the read.
|
|
1015
|
+
|
|
1016
|
+
## Code Review
|
|
1017
|
+
Evaluate on these dimensions and provide concrete, actionable feedback:
|
|
1018
|
+
- **Correctness** — does it do what it's supposed to? Are edge cases handled?
|
|
1019
|
+
- **Readability** — are names clear? Is logic easy to follow?
|
|
1020
|
+
- **Performance** — any O(n²) loops, N+1 queries, or memory leaks?
|
|
1021
|
+
- **Security** — injection risks, unvalidated input, exposed secrets, insecure defaults?
|
|
1022
|
+
- **Tests** — adequate coverage? Are tests meaningful?
|
|
1023
|
+
|
|
1024
|
+
## Add Tests
|
|
1025
|
+
- Identify the testing framework in use (Jest, pytest, Go test, etc.) or ask.
|
|
1026
|
+
- Write unit tests for individual functions, edge cases, and failure paths.
|
|
1027
|
+
- Aim for tests that are independent, deterministic, and fast.
|
|
1028
|
+
|
|
1029
|
+
## Quick-Run Commands
|
|
1030
|
+
\`\`\`
|
|
1031
|
+
python3 <file>.py # Python
|
|
1032
|
+
node <file>.js # Node.js
|
|
1033
|
+
npx ts-node <file>.ts # TypeScript
|
|
1034
|
+
go run <file>.go # Go
|
|
1035
|
+
cargo run # Rust
|
|
1036
|
+
java <ClassName>.java # Java 11+
|
|
1037
|
+
swift <file>.swift # Swift
|
|
1038
|
+
ruby <file>.rb # Ruby
|
|
1039
|
+
\`\`\`
|
|
1040
|
+
|
|
1041
|
+
## Pre-Delivery Checklist
|
|
1042
|
+
- No hardcoded secrets or credentials
|
|
1043
|
+
- Input is validated / sanitised at entry points
|
|
1044
|
+
- Error paths are handled (not silently swallowed)
|
|
1045
|
+
- Async code uses proper await / error handling
|
|
1046
|
+
- No unused imports or dead code left behind`
|
|
1047
|
+
},
|
|
1048
|
+
|
|
1049
|
+
// ── MAKER ────────────────────────────────────────────────────────────────────
|
|
1050
|
+
{
|
|
1051
|
+
id: 'bambu-studio-cli',
|
|
1052
|
+
name: 'BambuStudio CLI',
|
|
1053
|
+
description: 'Slice 3MF/STL files, export G-code and slicing data using BambuStudio on the command line.',
|
|
1054
|
+
category: 'maker',
|
|
1055
|
+
icon: '🖨️',
|
|
1056
|
+
content: `---
|
|
1057
|
+
name: bambu-studio-cli
|
|
1058
|
+
description: Slice 3MF/STL files and export results using the BambuStudio command-line interface
|
|
1059
|
+
category: maker
|
|
1060
|
+
icon: 🖨️
|
|
1061
|
+
enabled: true
|
|
1062
|
+
---
|
|
1063
|
+
|
|
1064
|
+
# BambuStudio CLI
|
|
1065
|
+
|
|
1066
|
+
Invoke BambuStudio headlessly for slicing and exporting. The binary is typically \`bambu-studio\` on Linux/macOS or \`bambu-studio.exe\` on Windows.
|
|
1067
|
+
|
|
1068
|
+
## Core flags
|
|
1069
|
+
|
|
1070
|
+
| Flag | Description |
|
|
1071
|
+
|------|-------------|
|
|
1072
|
+
| \`--slice <plate>\` | Slice plates: \`0\` = all, \`N\` = plate N |
|
|
1073
|
+
| \`--export-3mf <out.3mf>\` | Export sliced result as 3MF |
|
|
1074
|
+
| \`--outputdir <dir>\` | Directory for all exported files |
|
|
1075
|
+
| \`--load-settings "machine.json;process.json"\` | Override printer + process settings |
|
|
1076
|
+
| \`--load-filaments "f1.json;f2.json"\` | Override filament settings (use \`;\` separators, skip slots with empty entry) |
|
|
1077
|
+
| \`--curr-bed-type "Cool Plate"\` | Set bed type via command line |
|
|
1078
|
+
| \`--arrange <0\|1>\` | Auto-arrange: 0=off, 1=on |
|
|
1079
|
+
| \`--orient\` | Auto-orient models before slicing |
|
|
1080
|
+
| \`--scale <factor>\` | Scale model by float factor (e.g. \`1.5\`) |
|
|
1081
|
+
| \`--export-settings <out.json>\` | Dump merged settings to JSON |
|
|
1082
|
+
| \`--export-slicedata <dir>\` | Export slicing data to folder |
|
|
1083
|
+
| \`--load-slicedata <dir>\` | Load cached slicing data |
|
|
1084
|
+
| \`--info\` | Print model info without slicing |
|
|
1085
|
+
| \`--debug <0-5>\` | Log level: 0=fatal … 5=trace |
|
|
1086
|
+
| \`--pipe <name>\` | Send progress to named pipe |
|
|
1087
|
+
| \`--uptodate\` | Upgrade 3MF config values to latest profiles |
|
|
1088
|
+
| \`--help\` | Show CLI help |
|
|
1089
|
+
|
|
1090
|
+
Setting priority (highest → lowest):
|
|
1091
|
+
1. \`--key=value\` flags on the command line
|
|
1092
|
+
2. Files loaded via \`--load-settings\` / \`--load-filaments\`
|
|
1093
|
+
3. Settings embedded in the 3MF file
|
|
1094
|
+
|
|
1095
|
+
## Common usage patterns
|
|
1096
|
+
|
|
1097
|
+
### Slice a 3MF using its own settings
|
|
1098
|
+
\`\`\`bash
|
|
1099
|
+
bambu-studio --slice 0 --debug 2 --export-3mf output.3mf model.3mf
|
|
1100
|
+
\`\`\`
|
|
1101
|
+
Slices all plates in model.3mf and exports to output.3mf.
|
|
1102
|
+
|
|
1103
|
+
### Slice a 3MF with custom machine/process/filament overrides
|
|
1104
|
+
\`\`\`bash
|
|
1105
|
+
bambu-studio \\
|
|
1106
|
+
--load-settings "machine.json;process.json" \\
|
|
1107
|
+
--load-filaments "filament1.json;;filament3.json" \\
|
|
1108
|
+
--curr-bed-type "Cool Plate" \\
|
|
1109
|
+
--slice 2 --debug 2 \\
|
|
1110
|
+
--export-3mf output.3mf \\
|
|
1111
|
+
model.3mf
|
|
1112
|
+
\`\`\`
|
|
1113
|
+
Slices plate 2 only, overriding printer/process/filament settings from JSON files.
|
|
1114
|
+
Empty \`;\;\` entries keep the filament slot from the 3MF unchanged.
|
|
1115
|
+
|
|
1116
|
+
### Slice raw STL files
|
|
1117
|
+
\`\`\`bash
|
|
1118
|
+
bambu-studio \\
|
|
1119
|
+
--orient --arrange 1 \\
|
|
1120
|
+
--load-settings "machine.json;process.json" \\
|
|
1121
|
+
--load-filaments "filament.json" \\
|
|
1122
|
+
--slice 0 --debug 2 \\
|
|
1123
|
+
--export-3mf output.3mf \\
|
|
1124
|
+
model.stl
|
|
1125
|
+
\`\`\`
|
|
1126
|
+
Auto-orients and arranges the STL, applies settings from JSON files, slices all plates.
|
|
1127
|
+
|
|
1128
|
+
## When the user asks to slice a file:
|
|
1129
|
+
1. Confirm the path to \`bambu-studio\` binary (run \`which bambu-studio\` or ask the user)
|
|
1130
|
+
2. Check if custom settings JSON files are needed or if the 3MF is self-contained
|
|
1131
|
+
3. Build the command from the flags above
|
|
1132
|
+
4. Run it and check for errors in the output (debug level 2 is a good default)
|
|
1133
|
+
5. Report the output file location and any warnings`
|
|
1134
|
+
}
|
|
1135
|
+
];
|
|
1136
|
+
|
|
1137
|
+
// ── Routes ─────────────────────────────────────────────────────────────────────
|
|
1138
|
+
|
|
1139
|
+
/** GET /api/store — return catalog with installed status */
|
|
1140
|
+
router.get('/', (req, res) => {
|
|
1141
|
+
const fs = require('fs');
|
|
1142
|
+
const installed = new Set();
|
|
1143
|
+
|
|
1144
|
+
if (fs.existsSync(SKILLS_DIR)) {
|
|
1145
|
+
for (const f of fs.readdirSync(SKILLS_DIR)) {
|
|
1146
|
+
installed.add(f.replace(/\.md$/i, ''));
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
const items = CATALOG.map(s => ({
|
|
1151
|
+
id: s.id,
|
|
1152
|
+
name: s.name,
|
|
1153
|
+
description: s.description,
|
|
1154
|
+
category: s.category,
|
|
1155
|
+
icon: s.icon,
|
|
1156
|
+
installed: installed.has(s.id)
|
|
1157
|
+
}));
|
|
1158
|
+
|
|
1159
|
+
res.json(items);
|
|
1160
|
+
});
|
|
1161
|
+
|
|
1162
|
+
/** POST /api/store/:id/install — write the skill file */
|
|
1163
|
+
router.post('/:id/install', (req, res) => {
|
|
1164
|
+
const fs = require('fs');
|
|
1165
|
+
const skill = CATALOG.find(s => s.id === req.params.id);
|
|
1166
|
+
if (!skill) return res.status(404).json({ error: 'Skill not found in catalog' });
|
|
1167
|
+
|
|
1168
|
+
if (!fs.existsSync(SKILLS_DIR)) fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
1169
|
+
|
|
1170
|
+
const filePath = path.join(SKILLS_DIR, `${skill.id}.md`);
|
|
1171
|
+
fs.writeFileSync(filePath, skill.content, 'utf-8');
|
|
1172
|
+
|
|
1173
|
+
// Also reload the skill runner if available
|
|
1174
|
+
const skillRunner = req.app.locals?.skillRunner;
|
|
1175
|
+
if (skillRunner) skillRunner.loadSkillFile(filePath);
|
|
1176
|
+
|
|
1177
|
+
res.json({ success: true, id: skill.id, name: skill.name, filePath });
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
/** DELETE /api/store/:id/uninstall — remove the skill file */
|
|
1181
|
+
router.delete('/:id/uninstall', (req, res) => {
|
|
1182
|
+
const fs = require('fs');
|
|
1183
|
+
const skill = CATALOG.find(s => s.id === req.params.id);
|
|
1184
|
+
if (!skill) return res.status(404).json({ error: 'Skill not found in catalog' });
|
|
1185
|
+
|
|
1186
|
+
const filePath = path.join(SKILLS_DIR, `${skill.id}.md`);
|
|
1187
|
+
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
|
|
1188
|
+
|
|
1189
|
+
res.json({ success: true, id: skill.id });
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
module.exports = router;
|