opencode-skills-collection 3.0.24 → 3.0.25

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 (58) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +2 -1
  2. package/bundled-skills/007/scripts/scanners/dependency_scanner.py +1 -1
  3. package/bundled-skills/andrej-karpathy/SKILL.md +71 -1121
  4. package/bundled-skills/apify-actor-development/SKILL.md +2 -4
  5. package/bundled-skills/audit-skills/SKILL.md +1 -3
  6. package/bundled-skills/bun-development/SKILL.md +8 -5
  7. package/bundled-skills/claude-code-expert/SKILL.md +1 -3
  8. package/bundled-skills/cloud-penetration-testing/SKILL.md +3 -3
  9. package/bundled-skills/comfyui-gateway/references/integration.md +2 -2
  10. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  11. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +2 -2
  12. package/bundled-skills/docs/maintainers/full-repo-audit-2026-05-23.md +289 -0
  13. package/bundled-skills/docs/maintainers/merge-batch.md +2 -2
  14. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  15. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  16. package/bundled-skills/docs/users/agent-overload-recovery.md +2 -2
  17. package/bundled-skills/docs/users/bundles.md +1 -1
  18. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  19. package/bundled-skills/docs/users/faq.md +2 -2
  20. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  21. package/bundled-skills/docs/users/getting-started.md +3 -3
  22. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  23. package/bundled-skills/docs/users/usage.md +6 -6
  24. package/bundled-skills/docs/users/visual-guide.md +6 -6
  25. package/bundled-skills/docs/users/windows-truncation-recovery.md +1 -1
  26. package/bundled-skills/docs/vietnamese/FAQ.vi.md +2 -2
  27. package/bundled-skills/docs/vietnamese/GETTING_STARTED.vi.md +2 -2
  28. package/bundled-skills/docs/vietnamese/README.vi.md +6 -6
  29. package/bundled-skills/docs/vietnamese/SECURITY.vi.md +1 -1
  30. package/bundled-skills/docs/vietnamese/SKILLS_README.vi.md +8 -8
  31. package/bundled-skills/docs/vietnamese/VISUAL_GUIDE.vi.md +1 -1
  32. package/bundled-skills/environment-setup-guide/SKILL.md +6 -4
  33. package/bundled-skills/evolution/SKILL.md +3 -3
  34. package/bundled-skills/gitops-workflow/SKILL.md +6 -3
  35. package/bundled-skills/junta-leiloeiros/references/juntas_urls.md +1 -1
  36. package/bundled-skills/junta-leiloeiros/scripts/scraper/jucema.py +3 -3
  37. package/bundled-skills/junta-leiloeiros/scripts/scraper/jucesp.py +2 -2
  38. package/bundled-skills/junta-leiloeiros/scripts/scraper/jucisrs.py +7 -7
  39. package/bundled-skills/k8s-manifest-generator/resources/implementation-playbook.md +1 -3
  40. package/bundled-skills/linkerd-patterns/SKILL.md +6 -3
  41. package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package-lock.json +22 -22
  42. package/bundled-skills/openclaw-github-repo-commander/SKILL.md +4 -3
  43. package/bundled-skills/openclaw-github-repo-commander/scripts/repo-audit.sh +85 -0
  44. package/bundled-skills/pdf-conversion-router/SKILL.md +403 -0
  45. package/bundled-skills/remotion-best-practices/rules/charts.md +1 -1
  46. package/bundled-skills/security/aws-iam-best-practices/SKILL.md +1 -1
  47. package/bundled-skills/subagent-orchestrator/README.md +2 -2
  48. package/bundled-skills/subagent-orchestrator/scripts/install.js +4 -4
  49. package/bundled-skills/telegram/SKILL.md +14 -11
  50. package/bundled-skills/telegram/assets/boilerplate/nodejs/package.json +1 -2
  51. package/bundled-skills/telegram/assets/boilerplate/nodejs/src/bot-client.ts +24 -21
  52. package/bundled-skills/telegram/assets/boilerplate/nodejs/src/handlers.ts +34 -40
  53. package/bundled-skills/telegram/references/webhook-setup.md +16 -12
  54. package/bundled-skills/uv-package-manager/resources/implementation-playbook.md +4 -2
  55. package/bundled-skills/varlock/SKILL.md +6 -4
  56. package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/nodejs/src/webhook-handler.ts +12 -4
  57. package/package.json +1 -1
  58. package/skills_index.json +24 -2
@@ -1,19 +1,19 @@
1
- import TelegramBot from 'node-telegram-bot-api';
1
+ import { Telegraf } from 'telegraf';
2
2
  import express from 'express';
3
3
 
4
4
  export class TelegramBotClient {
5
- public bot: TelegramBot;
6
- private token: string;
5
+ public bot: Telegraf;
7
6
 
8
7
  constructor(token: string, webhookMode: boolean = false) {
9
- this.token = token;
10
- this.bot = new TelegramBot(token, {
11
- polling: !webhookMode,
12
- });
8
+ this.bot = new Telegraf(token);
9
+ if (webhookMode) {
10
+ this.bot.telegram.deleteWebhook({ drop_pending_updates: true }).catch(() => undefined);
11
+ }
13
12
  }
14
13
 
15
14
  async startPolling(): Promise<void> {
16
- const me = await this.bot.getMe();
15
+ await this.bot.launch();
16
+ const me = await this.bot.telegram.getMe();
17
17
  console.log(`Bot @${me.username} (${me.first_name}) started with polling`);
18
18
  }
19
19
 
@@ -21,16 +21,18 @@ export class TelegramBotClient {
21
21
  const app = express();
22
22
  app.use(express.json());
23
23
 
24
- // Webhook endpoint
25
- app.post(`/webhook/${this.token}`, (req, res) => {
24
+ app.post('/webhook', async (req, res) => {
26
25
  if (secret) {
27
26
  const headerSecret = req.headers['x-telegram-bot-api-secret-token'];
28
27
  if (headerSecret !== secret) {
29
28
  return res.sendStatus(403);
30
29
  }
31
30
  }
32
- this.bot.processUpdate(req.body);
33
- res.sendStatus(200);
31
+
32
+ await this.bot.handleUpdate(req.body, res);
33
+ if (!res.headersSent) {
34
+ res.sendStatus(200);
35
+ }
34
36
  });
35
37
 
36
38
  // Health check
@@ -39,19 +41,20 @@ export class TelegramBotClient {
39
41
  });
40
42
 
41
43
  // Register webhook with Telegram
42
- await this.bot.setWebHook(`${webhookUrl}/webhook/${this.token}`, {
44
+ const normalizedWebhookUrl = webhookUrl.replace(/\/+$/, '');
45
+ await this.bot.telegram.setWebhook(`${normalizedWebhookUrl}/webhook`, {
43
46
  max_connections: 40,
44
47
  secret_token: secret,
45
48
  } as any);
46
49
 
47
- const info = await this.bot.getWebHookInfo();
50
+ const info = await this.bot.telegram.getWebhookInfo();
48
51
  console.log('Webhook registered:', info.url);
49
52
 
50
53
  app.listen(port, () => {
51
54
  console.log(`Express server listening on port ${port}`);
52
55
  });
53
56
 
54
- const me = await this.bot.getMe();
57
+ const me = await this.bot.telegram.getMe();
55
58
  console.log(`Bot @${me.username} (${me.first_name}) started with webhook`);
56
59
  }
57
60
 
@@ -61,20 +64,20 @@ export class TelegramBotClient {
61
64
  async sendMessageSafe(
62
65
  chatId: number | string,
63
66
  text: string,
64
- options?: TelegramBot.SendMessageOptions
65
- ): Promise<TelegramBot.Message | null> {
67
+ options?: Record<string, unknown>
68
+ ): Promise<unknown | null> {
66
69
  const maxRetries = 3;
67
70
  for (let attempt = 0; attempt < maxRetries; attempt++) {
68
71
  try {
69
- return await this.bot.sendMessage(chatId, text, options);
72
+ return await this.bot.telegram.sendMessage(chatId, text, options as any);
70
73
  } catch (error: any) {
71
- if (error?.response?.statusCode === 429) {
72
- const retryAfter = error.response.body?.parameters?.retry_after || 5;
74
+ if (error?.response?.error_code === 429) {
75
+ const retryAfter = error.response.parameters?.retry_after || 5;
73
76
  console.warn(`Rate limited. Retrying after ${retryAfter}s...`);
74
77
  await new Promise((r) => setTimeout(r, retryAfter * 1000));
75
78
  continue;
76
79
  }
77
- if (error?.response?.statusCode === 403) {
80
+ if (error?.response?.error_code === 403) {
78
81
  console.warn(`Bot blocked by user ${chatId}`);
79
82
  return null;
80
83
  }
@@ -1,23 +1,29 @@
1
1
  import { TelegramBotClient } from './bot-client';
2
- import TelegramBot from 'node-telegram-bot-api';
2
+
3
+ function escapeHtml(value: string): string {
4
+ return value
5
+ .replace(/&/g, '&amp;')
6
+ .replace(/</g, '&lt;')
7
+ .replace(/>/g, '&gt;')
8
+ .replace(/"/g, '&quot;')
9
+ .replace(/'/g, '&#39;');
10
+ }
3
11
 
4
12
  export function registerHandlers(client: TelegramBotClient): void {
5
13
  const bot = client.bot;
6
14
 
7
- // /start command
8
- bot.onText(/\/start/, async (msg) => {
9
- const name = msg.from?.first_name || 'usuario';
15
+ bot.start(async (ctx) => {
16
+ const name = escapeHtml(ctx.from?.first_name || 'usuario');
10
17
  await client.sendMessageSafe(
11
- msg.chat.id,
18
+ ctx.chat.id,
12
19
  `Ola, ${name}! Bem-vindo ao bot.\n\nComandos disponiveis:\n/start - Iniciar\n/help - Ajuda\n/about - Sobre`,
13
20
  { parse_mode: 'HTML' }
14
21
  );
15
22
  });
16
23
 
17
- // /help command
18
- bot.onText(/\/help/, async (msg) => {
24
+ bot.help(async (ctx) => {
19
25
  await client.sendMessageSafe(
20
- msg.chat.id,
26
+ ctx.chat.id,
21
27
  '<b>Comandos:</b>\n' +
22
28
  '/start - Iniciar o bot\n' +
23
29
  '/help - Ver esta mensagem\n' +
@@ -27,52 +33,40 @@ export function registerHandlers(client: TelegramBotClient): void {
27
33
  );
28
34
  });
29
35
 
30
- // /about command
31
- bot.onText(/\/about/, async (msg) => {
32
- const me = await bot.getMe();
36
+ bot.command('about', async (ctx) => {
37
+ const me = await bot.telegram.getMe();
38
+ const firstName = escapeHtml(me.first_name);
39
+ const username = escapeHtml(me.username || 'sem_username');
33
40
  await client.sendMessageSafe(
34
- msg.chat.id,
35
- `<b>${me.first_name}</b>\n@${me.username}\n\nBot criado com Telegram Bot API`,
41
+ ctx.chat.id,
42
+ `<b>${firstName}</b>\n@${username}\n\nBot criado com Telegram Bot API`,
36
43
  { parse_mode: 'HTML' }
37
44
  );
38
45
  });
39
46
 
40
- // /echo command
41
- bot.onText(/\/echo (.+)/, async (msg, match) => {
42
- const text = match?.[1] || '';
43
- await client.sendMessageSafe(msg.chat.id, text);
47
+ bot.hears(/^\/echo (.+)/, async (ctx) => {
48
+ const text = ctx.match?.[1] || '';
49
+ await client.sendMessageSafe(ctx.chat.id, text);
44
50
  });
45
51
 
46
- // Callback query handler (for inline keyboards)
47
- bot.on('callback_query', async (query) => {
48
- await bot.answerCallbackQuery(query.id, { text: `Opcao: ${query.data}` });
52
+ bot.on('callback_query', async (ctx) => {
53
+ const data = 'data' in ctx.callbackQuery ? ctx.callbackQuery.data : '';
54
+ await ctx.answerCbQuery(`Opcao: ${data}`);
49
55
 
50
- if (query.message) {
51
- await bot.editMessageText(`Voce escolheu: ${query.data}`, {
52
- chat_id: query.message.chat.id,
53
- message_id: query.message.message_id,
54
- });
56
+ if (ctx.callbackQuery.message) {
57
+ await ctx.editMessageText(`Voce escolheu: ${data}`);
55
58
  }
56
59
  });
57
60
 
58
- // Default message handler (echo)
59
- bot.on('message', async (msg) => {
60
- // Skip commands
61
- if (msg.text?.startsWith('/')) return;
62
-
63
- // Echo non-command text messages
64
- if (msg.text) {
65
- await client.sendMessageSafe(msg.chat.id, `Voce disse: ${msg.text}`);
66
- }
67
- });
61
+ bot.on('text', async (ctx) => {
62
+ if (ctx.message.text.startsWith('/')) return;
68
63
 
69
- // Error handler
70
- bot.on('polling_error', (error) => {
71
- console.error('Polling error:', error.message);
64
+ await client.sendMessageSafe(ctx.chat.id, `Voce disse: ${ctx.message.text}`);
72
65
  });
73
66
 
74
- bot.on('webhook_error', (error) => {
75
- console.error('Webhook error:', error.message);
67
+ bot.catch((error) => {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ console.error('Telegram bot error:', message);
76
70
  });
77
71
 
78
72
  console.log('All handlers registered');
@@ -50,27 +50,26 @@ POST https://api.telegram.org/bot<TOKEN>/deleteWebhook
50
50
 
51
51
  ```typescript
52
52
  import express from 'express';
53
- import TelegramBot from 'node-telegram-bot-api';
53
+ import { Telegraf } from 'telegraf';
54
54
 
55
55
  const app = express();
56
56
  const TOKEN = process.env.TELEGRAM_BOT_TOKEN!;
57
57
  const WEBHOOK_URL = process.env.WEBHOOK_URL!; // https://seu-dominio.com
58
58
  const SECRET_TOKEN = process.env.WEBHOOK_SECRET || 'meu-secret-seguro';
59
59
 
60
- // Bot sem polling (webhook mode)
61
- const bot = new TelegramBot(TOKEN);
60
+ const bot = new Telegraf(TOKEN);
62
61
 
63
62
  app.use(express.json());
64
63
 
65
64
  // Validar secret token
66
- app.post(`/webhook/${TOKEN}`, (req, res) => {
65
+ app.post('/webhook', async (req, res) => {
67
66
  const secretHeader = req.headers['x-telegram-bot-api-secret-token'];
68
67
  if (secretHeader !== SECRET_TOKEN) {
69
68
  return res.sendStatus(403);
70
69
  }
71
70
 
72
- bot.processUpdate(req.body);
73
- res.sendStatus(200);
71
+ await bot.handleUpdate(req.body, res);
72
+ if (!res.headersSent) res.sendStatus(200);
74
73
  });
75
74
 
76
75
  // Health check
@@ -78,13 +77,13 @@ app.get('/health', (req, res) => res.json({ status: 'ok' }));
78
77
 
79
78
  // Registrar webhook na inicializacao
80
79
  async function start() {
81
- await bot.setWebHook(`${WEBHOOK_URL}/webhook/${TOKEN}`, {
80
+ await bot.telegram.setWebhook(`${WEBHOOK_URL.replace(/\/+$/, '')}/webhook`, {
82
81
  max_connections: 40,
83
82
  allowed_updates: ['message', 'callback_query'],
84
83
  secret_token: SECRET_TOKEN,
85
84
  });
86
85
 
87
- const info = await bot.getWebHookInfo();
86
+ const info = await bot.telegram.getWebhookInfo();
88
87
  console.log('Webhook info:', info);
89
88
 
90
89
  app.listen(3000, () => console.log('Server rodando na porta 3000'));
@@ -256,14 +255,19 @@ services:
256
255
  ```typescript
257
256
  // api/webhook.ts
258
257
  import { VercelRequest, VercelResponse } from '@vercel/node';
259
- import TelegramBot from 'node-telegram-bot-api';
258
+ import { Telegraf } from 'telegraf';
260
259
 
261
- const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN!);
260
+ const bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN!);
262
261
 
263
262
  export default async function handler(req: VercelRequest, res: VercelResponse) {
264
263
  if (req.method === 'POST') {
265
- bot.processUpdate(req.body);
266
- res.status(200).send('OK');
264
+ const secretHeader = req.headers['x-telegram-bot-api-secret-token'];
265
+ if (secretHeader !== process.env.WEBHOOK_SECRET) {
266
+ return res.status(403).send('Forbidden');
267
+ }
268
+
269
+ await bot.handleUpdate(req.body, res);
270
+ if (!res.writableEnded) res.status(200).send('OK');
267
271
  } else {
268
272
  res.status(200).json({ status: 'ok' });
269
273
  }
@@ -51,10 +51,12 @@ Comprehensive guide to using uv, an extremely fast Python package installer and
51
51
 
52
52
  ```bash
53
53
  # macOS/Linux
54
- curl -LsSf https://astral.sh/uv/install.sh | sh
54
+ curl -LsSf https://astral.sh/uv/install.sh -o /tmp/uv-install.sh
55
+ sed -n '1,160p' /tmp/uv-install.sh
56
+ sh /tmp/uv-install.sh
55
57
 
56
58
  # Windows (PowerShell)
57
- powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
59
+ powershell -NoProfile -Command "Invoke-WebRequest https://astral.sh/uv/install.ps1 -OutFile $env:TEMP\\uv-install.ps1; Get-Content $env:TEMP\\uv-install.ps1 -TotalCount 120; powershell -ExecutionPolicy Bypass -File $env:TEMP\\uv-install.ps1"
58
60
 
59
61
  # Using pip (if you already have Python)
60
62
  pip install uv
@@ -6,8 +6,6 @@ source: "https://github.com/dmno-dev/varlock"
6
6
  version: 1.0.0
7
7
  ---
8
8
 
9
- <!-- security-allowlist: curl-pipe-bash -->
10
-
11
9
  # Varlock Security Skill
12
10
 
13
11
  Secure-by-default environment variable management for Claude Code sessions.
@@ -90,7 +88,9 @@ curl -H "Authorization: Bearer $API_KEY" https://api.example.com
90
88
 
91
89
  ```bash
92
90
  # Install Varlock CLI
93
- curl -sSfL https://varlock.dev/install.sh | sh -s -- --force-no-brew
91
+ curl -sSfL https://varlock.dev/install.sh -o /tmp/varlock-install.sh
92
+ sed -n '1,160p' /tmp/varlock-install.sh
93
+ sh /tmp/varlock-install.sh --force-no-brew
94
94
 
95
95
  # Add to PATH (add to ~/.zshrc or ~/.bashrc)
96
96
  export PATH="$HOME/.varlock/bin:$PATH"
@@ -245,7 +245,9 @@ varlock load
245
245
 
246
246
  ```dockerfile
247
247
  # Install Varlock in container
248
- RUN curl -sSfL https://varlock.dev/install.sh | sh -s -- --force-no-brew \
248
+ RUN curl -sSfL https://varlock.dev/install.sh -o /tmp/varlock-install.sh \
249
+ && sed -n '1,160p' /tmp/varlock-install.sh \
250
+ && sh /tmp/varlock-install.sh --force-no-brew \
249
251
  && ln -s /root/.varlock/bin/varlock /usr/local/bin/varlock
250
252
 
251
253
  # Validate at container start
@@ -3,6 +3,7 @@ import { Request, Response, NextFunction } from 'express';
3
3
  import { WebhookPayload, IncomingMessage, StatusUpdate } from './types';
4
4
 
5
5
  const SAFE_CHALLENGE_RE = /^[A-Za-z0-9._-]{1,200}$/;
6
+ const SIGNATURE_RE = /^sha256=[a-f0-9]{64}$/i;
6
7
 
7
8
  /**
8
9
  * Middleware para validar assinatura HMAC-SHA256 dos webhooks do WhatsApp.
@@ -35,10 +36,17 @@ export function validateHMAC(appSecret: string) {
35
36
  'sha256=' +
36
37
  crypto.createHmac('sha256', appSecret).update(rawBody).digest('hex');
37
38
 
38
- const isValid = crypto.timingSafeEqual(
39
- Buffer.from(signature),
40
- Buffer.from(expectedSignature)
41
- );
39
+ if (!SIGNATURE_RE.test(signature)) {
40
+ console.warn('Invalid webhook signature format');
41
+ res.sendStatus(401);
42
+ return;
43
+ }
44
+
45
+ const signatureBuffer = Buffer.from(signature, 'utf8');
46
+ const expectedSignatureBuffer = Buffer.from(expectedSignature, 'utf8');
47
+ const isValid =
48
+ signatureBuffer.length === expectedSignatureBuffer.length &&
49
+ crypto.timingSafeEqual(signatureBuffer, expectedSignatureBuffer);
42
50
 
43
51
  if (!isValid) {
44
52
  console.warn('Invalid webhook signature');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-skills-collection",
3
- "version": "3.0.24",
3
+ "version": "3.0.25",
4
4
  "description": "OpenCode CLI plugin that automatically downloads and keeps skills up to date.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/skills_index.json CHANGED
@@ -1332,9 +1332,9 @@
1332
1332
  {
1333
1333
  "id": "andrej-karpathy",
1334
1334
  "path": "skills/andrej-karpathy",
1335
- "category": "ai-ml",
1335
+ "category": "uncategorized",
1336
1336
  "name": "andrej-karpathy",
1337
- "description": "Agente que simula Andrej Karpathy \u2014 ex-Director of AI da Tesla, co-fundador da OpenAI, fundador da Eureka Labs, e o maior educador de deep learning do mundo.",
1337
+ "description": "Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.",
1338
1338
  "risk": "safe",
1339
1339
  "source": "community",
1340
1340
  "date_added": "2026-03-06",
@@ -21744,6 +21744,28 @@
21744
21744
  "reasons": []
21745
21745
  }
21746
21746
  },
21747
+ {
21748
+ "id": "pdf-conversion-router",
21749
+ "path": "skills/pdf-conversion-router",
21750
+ "category": "uncategorized",
21751
+ "name": "pdf-conversion-router",
21752
+ "description": "Use when converting a PDF into another format such as Markdown, HTML, text, JSON, DOCX, or structured notes and the agent must choose the best extraction route, settings, and cleanup strategy for maximum fidelity and readability.",
21753
+ "risk": "safe",
21754
+ "source": "community",
21755
+ "date_added": "2026-05-23",
21756
+ "plugin": {
21757
+ "targets": {
21758
+ "codex": "supported",
21759
+ "claude": "supported"
21760
+ },
21761
+ "setup": {
21762
+ "type": "none",
21763
+ "summary": "",
21764
+ "docs": null
21765
+ },
21766
+ "reasons": []
21767
+ }
21768
+ },
21747
21769
  {
21748
21770
  "id": "pdf-official",
21749
21771
  "path": "skills/pdf-official",