Skip to content

feat(skills): add QR code generation/decoding skill - #57791

Open
nolanchic wants to merge 2 commits into
NousResearch:mainfrom
nolanchic:feat/qr-code-skill
Open

feat(skills): add QR code generation/decoding skill#57791
nolanchic wants to merge 2 commits into
NousResearch:mainfrom
nolanchic:feat/qr-code-skill

Conversation

@nolanchic

Copy link
Copy Markdown
Contributor

What

Adds a new bundled skill at skills/media/qr-code/ that generates and decodes QR codes — encode text/URLs/Wi-Fi/vCards to PNG or terminal art, and decode a QR image back to text. Runs entirely locally: no API key, no network calls.

Why

No existing bundled or optional skill covers QR encode/decode. A grep across skills/ and optional-skills/ (173 skills) confirms there is no QR skill — the few matches for "qr" are incidental mentions inside unrelated skills. QR is a broadly useful, frequently-requested utility (share a URL/Wi-Fi/contact for phone scanning, decode a screenshot/photo), which fits the CONTRIBUTING.md bar for a bundled skill.

How it works

A single stdlib-only helper, scripts/qr_code.py, auto-detects the best available backend and degrades gracefully:

Action Backend order
Encode qrencode (CLI) → qrcode (Python)
Decode zbarimg (CLI) → pyzbar (Python)

When no backend is present, python3 scripts/qr_code.py doctor reports what's missing with platform-specific install hints — the skill never crashes, it tells the user how to enable itself.

Skill standards (CONTRIBUTING.md hardline)

  • description is 58 chars, one sentence, ends with a period, no marketing words
  • Prose references native Hermes tools by name (terminal, write_file, read_file), not raw shell utilities
  • platforms: [linux, macos, windows] — matches the stdlib-only script (no POSIX-only primitives); scripts/check-windows-footguns.py passes clean
  • author credits the human contributor (Nolan (nolanchic)), not "Hermes Agent"
  • SKILL.md uses the modern section order (When to Use → Prerequisites → How to Run → Quick Reference → Procedure → Pitfalls → Verification)
  • Helper script lives in scripts/; no inline parser logic expected from the model
  • Tests at tests/skills/test_qr_code_skill.py: 22 tests, all passing, stdlib + pytest + unittest.mock, no live network calls, all backends monkeypatched so it runs under the hermetic CI env
  • No new dependencies added to the project — all backends are optional and user-installed

How to test

```bash

1. Run the skill's test suite

scripts/run_tests.sh tests/skills/test_qr_code_skill.py -q # 22 passed

2. End-to-end (with a backend installed)

python3 skills/media/qr-code/scripts/qr_code.py doctor
python3 skills/media/qr-code/scripts/qr_code.py encode "https://example.com" -o site.png
python3 skills/media/qr-code/scripts/qr_code.py wifi --ssid MyNet --password s3cret -o wifi.png
python3 skills/media/qr-code/scripts/qr_code.py vcard --name "Ada" --phone "+15551234" -o ada.png
python3 skills/media/qr-code/scripts/qr_code.py decode site.png --raw

3. Verification round-trip

python3 skills/media/qr-code/scripts/qr_code.py encode "hermes-qr-ok" -o /tmp/qrtest.png && \
python3 skills/media/qr-code/scripts/qr_code.py decode /tmp/qrtest.png --raw

→ hermes-qr-ok

```

Confirmed working end-to-end on macOS: generated a valid 290×290 PNG with the qrcode Python backend.

Platforms tested

macOS (Darwin 24.3.0, Python 3.11). The script is pure stdlib with platform-guarded optional-backend detection, so Linux and Windows are covered by the same code path; check-windows-footguns.py passes.

Related

Closes no issue — fills a capability gap (no duplicate of any existing skill).

A bundled, cross-platform skill that encodes text/URLs/Wi-Fi/vCards into QR
codes (PNG or terminal art) and decodes QR images back to text. Runs entirely
locally — no API key, no network. Auto-detects the best available backend
(qrencode/zbarimg CLI, or qrcode/pyzbar Python) and degrades gracefully with
clear install guidance when none is present.

- SKILL.md follows the modern section order; description 58 chars, author is
  the human contributor (not "Hermes Agent").
- scripts/qr_code.py is stdlib-only; optional encoders/decoders imported lazily.
- tests/skills/test_qr_code_skill.py: 22 tests, stdlib + pytest + mock, no
  network, all backends monkeypatched for the hermetic CI env.

Closes no issue — fills a gap: no existing bundled/optional skill covers QR
encode/decode (grep of skills/ + optional-skills/ confirms no QR skill).
@alt-glitch alt-glitch added type/feature New feature or request tool/skills Skills system (list, view, manage) P3 Low — cosmetic, nice to have labels Jul 3, 2026
@nolanchic

Copy link
Copy Markdown
Contributor Author

Hi maintainers 👋 — first-time contributor here.

It looks like the CI workflows haven't started on this PR (checks count is 0). Could someone approve the workflow run so CI can begin? Happy to address any feedback on the skill.

For reference: the change is a new self-contained bundled skill (skills/media/qr-code/) plus its test suite (tests/skills/test_qr_code_skill.py, 22 tests, all passing locally). No core files are touched. Thanks!

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the self-contained skill contribution. Current main has no generic QR encode/decode skill, and a skill plus helper script is the appropriate low-footprint integration.

Problems

  • skills/media/qr-code/scripts/qr_code.py:167-173 claims to emit a minimal vCard but omits N and uses "\n". RFC 2426's grammar requires VERSION, FN, and N`, with CRLF-delimited content lines and a trailing CRLF. A strict contact importer can therefore reject the generated payload.

Suggested changes

  • Emit an escaped N field and CRLF-terminated records from vcard_encode.
  • Make tests/skills/test_qr_code_skill.py:200-214 assert the complete vCard payload, including N, \r\n, and separator escaping.

Automated hermes-sweeper review.

lines.append(f"EMAIL:{email}")
lines.append("END:VCARD")
return encode("\n".join(lines), out, terminal, ec)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This returns an LF-only payload and the constructed lines above omit N. RFC 2426 requires VERSION, FN, and N, with CRLF-delimited content lines and a final CRLF. Please emit an escaped N property and use \r\n so strict vCard importers accept the generated QR payload.

@teknium1 teknium1 added the sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users label Jul 15, 2026
Address review feedback on NousResearch#57791: the vCard builder was producing a
non-conformant payload that strict contact importers reject.

- Add required N property (Family;Given;Additional;Prefix;Suffix)
- Delimit records with CRLF and terminate with a trailing CRLF
- Escape backslash, comma, semicolon, and newline in property values
- Strengthen test_vcard_payload_format and add a dedicated escape test
@nolanchic

Copy link
Copy Markdown
Contributor Author

Thanks @teknium1 — addressed in the latest push (d8e77a0). The vCard builder now emits an RFC 2426-conformant payload:

  • N property addedN:{escaped};;;; (Family;Given;Additional;Prefix;Suffix), alongside the existing FN.
  • CRLF-delimited records with a trailing CRLF ("\r\n".join(lines) + "\r\n"), replacing the previous LF-only join.
  • Value escaping via a new _vcard_escape helper — backslash, comma, semicolon, and newline are escaped per the spec (name input is the only user-controlled value in N/FN).

Tests: strengthened test_vcard_payload_format to assert N, \r\n, and the trailing CRLF, and added test_vcard_escapes_special_characters covering a name with , and ; ("Doe, John; Jr."N:Doe\, John\; Jr.;;;;). Full skills suite passes (220 tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users tool/skills Skills system (list, view, manage) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants