Scan Report
20 /100
x-bookmark-triage
Automatically triages X/Twitter bookmarks into structured knowledge cards posted to a Discord channel using Claude Haiku scoring
Legitimate bookmark-triage pipeline with documented network access and OAuth token handling, but shell execution via spawnSync(curl) is not declared in SKILL.md and docs reference persona-specific identifiers.
Safe to install
Add spawnSync/shell usage to SKILL.md capabilities section, replace 'Watson'/'Jeremy' persona references in adapting.md, and declare the markdown.new web proxy fetch in the skill description.
Findings 4 items
| Severity | Finding | Location |
|---|---|---|
| Low | Shell execution not declared in SKILL.md Doc Mismatch | scripts/triage-url.js:70 |
| Low | Undocumented markdown.new web proxy Doc Mismatch | scripts/triage-url.js:90 |
| Low | Persona cleanup required before deployment Doc Mismatch | references/adapting.md:3 |
| Low | No npm dependencies — pure Node.js, no lock file Supply Chain | package.json |
| Resource | Declared | Inferred | Status | Evidence |
|---|---|---|---|---|
| Filesystem | NONE | WRITE | ✓ Aligned | scripts/triage-url.js:37 — writes SEEN_FILE to WORKSPACE/data/ |
| Network | NONE | READ | ✓ Aligned | spawnSync('curl') calls to X API, Discord API, fxtwitter, Anthropic, markdown.ne… |
| Shell | NONE | WRITE | ✓ Aligned | spawnSync('curl') and spawnSync('sleep') used in all JS scripts — shell:WRITE no… |
| Environment | NONE | READ | ✓ Aligned | Reads X_OAUTH2_*, ANTHROPIC_DEFAULT_KEY, DISCORD_BOT_TOKEN, etc. — legitimately … |
17 findings
Medium External URL 外部 URL
https://developer.x.com README.md:28 Medium External URL 外部 URL
https://discord.com/developers/applications README.md:32 Medium External URL 外部 URL
https://console.anthropic.com README.md:35 Medium External URL 外部 URL
https://x.com/someone/status/123 README.md:59 Medium External URL 外部 URL
https://x.com/... README.md:81 Medium External URL 外部 URL
https://x.com/anthropic/status/... README.md:128 Medium External URL 外部 URL
https://x.com/@username/status/1234567890 SKILL.md:55 Medium External URL 外部 URL
http://www.apple.com/DTDs/PropertyList-1.0.dtd references/cron-setup.md:31 Medium External URL 外部 URL
https://x.com/i/oauth2/authorize?... references/oauth-setup.md:34 Medium External URL 外部 URL
https://api.x.com/2/users/me references/oauth-setup.md:73 Medium External URL 外部 URL
https://api.x.com/2/oauth2/token scripts/backlog-sweep.js:71 Medium External URL 外部 URL
https://api.x.com/2/users/$ scripts/backlog-sweep.js:112 Medium External URL 外部 URL
https://discord.com/api/v10/channels/$ scripts/poll-channel.js:47 Medium External URL 外部 URL
https://nodejs.org scripts/setup-check.js:27 Medium External URL 外部 URL
https://api.fxtwitter.com/$ scripts/triage-url.js:70 Medium External URL 外部 URL
https://markdown.new/$ scripts/triage-url.js:90 Medium External URL 外部 URL
https://twitter.com/i/oauth2/authorize scripts/x-oauth2-authorize.js:45 File Tree
13 files · 73.6 KB · 2103 lines JavaScript 6f · 1308L
Markdown 5f · 751L
Shell 1f · 23L
Text 1f · 21L
├─
▾
references
│ ├─
adapting.md
Markdown
│ ├─
cron-setup.md
Markdown
│ └─
oauth-setup.md
Markdown
├─
▾
scripts
│ ├─
backlog-sweep.js
JavaScript
│ ├─
bookmark-poll.js
JavaScript
│ ├─
poll-channel.js
JavaScript
│ ├─
run-poll.sh
Shell
│ ├─
setup-check.js
JavaScript
│ ├─
triage-url.js
JavaScript
│ └─
x-oauth2-authorize.js
JavaScript
├─
LICENSE.txt
Text
├─
README.md
Markdown
└─
SKILL.md
Markdown
Security Positives
✓ No external npm dependencies — eliminates supply-chain attack surface entirely
✓ OAuth tokens stored with 0o600 permissions (owner-only read/write) in backlog-sweep.js and x-oauth2-authorize.js
✓ Secrets file path uses a parent-directory traversal pattern (../../../secrets/) but only accessed if X_OAUTH2_SECRETS_FILE env is set
✓ Token values are never printed to stdout (only file path on rotation)
✓ No eval(), no base64 decode, no obfuscation, no anti-analysis patterns
✓ No access to ~/.ssh, ~/.aws, .env (only skill-scope data files and env vars explicitly named for this skill)
✓ Dedup mechanism prevents re-processing already-seen URLs
✓ Rate-limit handling implemented for both X API and Discord API
✓ Dry-run mode available for backlog-sweep to test without side effects
✓ No hardcoded credentials — all secrets from environment variables