Discord Furlow — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Discord Furlow (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Declarative Discord Bot Framework
Build powerful Discord bots with YAML. No code required.
commands:
- name: ping
description: Check bot latency
actions:
- reply:
content: "Pong! ${client.ws.ping}ms"# Install the CLI
npm install -g @furlow/cli
# Create a bot
furlow init my-bot
cd my-bot
# Add your Discord credentials to .env
echo "DISCORD_TOKEN=your_token_here" > .env
echo "DISCORD_CLIENT_ID=your_client_id_here" >> .env
# Start
furlow startversion: "0.1"
identity:
name: "My Bot"
presence:
status: online
activity:
type: playing
text: "with FURLOW"
commands:
- name: hello
description: Greet someone
options:
- name: user
type: user
description: Who to greet
actions:
- reply:
content: "Hello, ${options.user.display_name || options.user.username}!"
- name: roll
description: Roll a dice
options:
- name: sides
type: integer
description: Number of sides
min_value: 2
max_value: 100
actions:
- reply:
content: "🎲 You rolled **${random(1, options.sides || 6)}**"
events:
- event: member_join
actions:
- send_message:
channel: "${env.WELCOME_CHANNEL}"
content: "Welcome ${member.displayName}!"| Command | Description |
|---|---|
furlow init [name] | Create a new bot project |
furlow start [path] | Run the bot |
furlow dev [path] | Development mode with hot reload |
furlow validate <path> | Validate YAML specification |
furlow add <builtin> | Add builtin module |
furlow build [path] | Bundle for deployment |
furlow export <path> | Export Discord command JSON |
| Guide | Description |
|---|---|
| Installation | Setup and requirements |
| Quick Start | Your first bot |
| Configuration | YAML specification |
| Actions Reference | All 85 actions |
| Expressions Reference | Functions and transforms |
| Events Reference | Event types |
| CLI Reference | Command-line interface |
| Pipes Reference | External integrations |
| Examples | Complete bot examples |
| Package | Description |
|---|---|
furlow | CLI tool |
@furlow/core | Runtime engine |
@furlow/discord | Discord.js adapter |
@furlow/schema | TypeScript types |
@furlow/storage | Database adapters |
@furlow/builtins | Pre-built modules |
@furlow/pipes | HTTP, WebSocket, MQTT, TCP/UDP, webhooks, database, file |
@furlow/testing | Test utilities |
A short checklist for shipping a bot to production. Each item lines up with a runtime guarantee — skipping one usually shows up later as silent data loss, an unscheduled feature, or a publicly forgeable session.
# Discord
DISCORD_TOKEN=...
DISCORD_CLIENT_ID=...
# Storage (pick one)
DATABASE_URL=postgres://user:pass@host:5432/furlow # production
# or for single-server bots:
SQLITE_PATH=/var/lib/furlow/bot.db
# Dashboard (only if running the web UI)
DASHBOARD_SECRET=$(openssl rand -hex 32) # required in NODE_ENV=production
DISCORD_CLIENT_SECRET=...
DISCORD_CALLBACK_URL=https://dashboard.example.com/auth/discord/callbackThe dashboard refuses to start in NODE_ENV=production without DASHBOARD_SECRET — there is no fallback default. WebSocket connections also require an authenticated session; unauthenticated clients are rejected at upgrade time and cannot subscribe to guild streams.
point-in-time recovery. The SQLite adapter is fine for single-server bots and tests, but write contention degrades quickly past a few thousand active users.
demand; Postgres deployments should pre-create the tables defined in your state.tables: block.
status, ticket transcripts); none of this is reconstructible.
CronScheduler that emits scheduler_tick every 60s.Builtins that rely on it (giveaways, polls, reminders) need the scheduler running — there is no separate cron process.
@discordjs/voice peer plus ffmpeg on thePATH. The voice_track_start / voice_track_end events used by the music builtin only fire when the voice manager is initialized.
furlow start under a process supervisor (systemd, pm2,Kubernetes Deployment) that restarts on exit. The bot does not self-daemonize.
SIGTERM so the gateway connection closes cleanly. The CLIflushes pending state on shutdown; killing with SIGKILL can lose the last batched writes.
The session cookie sets secure: true in production and will not be delivered over plain HTTP.
exact DISCORD_CALLBACK_URL you ship.
wrong-typed keys with 400. If you extend a settings shape, update the whitelist in apps/dashboard/server/routes/api.ts.
/health returns process uptime; wire it to your liveness probe./metrics exposes Prometheus-format counters. Add a scrape job pointedat the dashboard process.
--verbose for structured per-event logging duringincident triage.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.