Skip to content

feat(dictionary): add dictionary search, synonyms, and examples adapters#241

Merged
jackwener merged 2 commits intojackwener:mainfrom
vkop007:feat/dictionary-adapter
Mar 24, 2026
Merged

feat(dictionary): add dictionary search, synonyms, and examples adapters#241
jackwener merged 2 commits intojackwener:mainfrom
vkop007:feat/dictionary-adapter

Conversation

@vkop007
Copy link
Copy Markdown
Contributor

@vkop007 vkop007 commented Mar 22, 2026

Description

This PR introduces the powerful new Dictionary adapter to OpenCLI. It leverages the completely free, public api.dictionaryapi.dev robust JSON endpoint to bring a reliable spell checker, dictionary, and thesaurus straight into the developer terminal.

Commands Added (opencli dictionary):

  • search - Get the phonetic pronunciation, part of speech, and primary definition of any word (e.g., opencli dictionary search --word "serendipity").
  • synonyms - Extract up to 5 related synonyms for a given word by scrubbing the entire JSON definitions tree.
  • examples - Find real-world sentence usage examples for complex vocabulary (falls back elegantly if a word lacks examples).

Implementation Note: The YAML dataset extraction mappings were custom-built using recursive ES6 IIFEs to safely traverse variable-depth JSON nodes. This guarantees 100% crash protection against unpredictable empty arrays in the Dictionary API.

Related issue: N/A

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • I ran the checks relevant to this PR (opencli validate)
  • I updated tests or docs if needed (README integration and VitePress docs)
  • I included output or screenshots when useful

Documentation (if adding/modifying an adapter)

  • Added doc page under docs/adapters/ (docs/adapters/browser/dictionary.md)
  • Updated docs/adapters/index.md table
  • Updated sidebar in docs/.vitepress/config.mts

Screenshots / Output

$ opencli dictionary search --word serendipity

  dictionary/search
┌─────────────┬─────────────────────┬──────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Word        │ Phonetic            │ Type │ Definition                                                                                                   │
├─────────────┼─────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ serendipity │ /ˌsɛ.ɹən.ˈdɪ.pɪ.ti/ │ noun │ A combination of events which have come together by chance to make a surprisingly good or wonderful outcome. │
└─────────────┴─────────────────────┴──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
1 items · 0.8s · dictionary/search
$ opencli dictionary synonyms --word serendipity

  dictionary/synonyms
┌─────────────┬──────────────┐
│ Word        │ Synonyms     │
├─────────────┼──────────────┤
│ serendipity │ chance, luck │
└─────────────┴──────────────┘
1 items · 0.6s · dictionary/synonyms
$ opencli dictionary examples --word perfect

  dictionary/examples
┌─────────┬──────────────────┐
│ Word    │ Example          │
├─────────┼──────────────────┤
│ perfect │ a perfect circle │
└─────────┴──────────────────┘
1 items · 0.8s · dictionary/examples

Copy link
Copy Markdown
Contributor

@Astro-Han Astro-Han left a comment

Choose a reason for hiding this comment

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

Solid use of the free Dictionary API — clean YAML pipelines. A few issues:

URL encoding missing

${{ args.word }} is interpolated directly into the URL path. Words with spaces or special characters (e.g. ice cream, C#) will break the request. The template engine has a urlencode filter — use ${{ args.word | urlencode }}. Affects all 3 YAML files.

search.yaml — chained || doesn't work as expected

phonetic: "${{ item.phonetic || item.phonetics?.[0]?.text || item.phonetics?.[1]?.text || '' }}"

The template engine's || handler only evaluates the left side of the first ||; the rest is returned as a literal string. When item.phonetic is empty, the output will show item.phonetics?.[0]?.text || ... as text instead of the actual value. Single || with a literal (e.g. item.x || 'N/A') works fine, but chained || with expressions doesn't. Wrapping in an IIFE (like synonyms.yaml and examples.yaml already do) would fix this.

word should be positional

Per CONTRIBUTING.md, the main target arg should use positional: true. opencli dictionary search serendipity is more natural than --word serendipity.

Tests

No E2E tests. Per TESTING.md, browser: false public commands should have entries in public-commands.test.ts.

@vkop007
Copy link
Copy Markdown
Contributor Author

vkop007 commented Mar 23, 2026

Thanks for the thorough review! I've applied all your suggestions:

  1. URL Encoding: Added the | urlencode filter to the args.word interpolation across all 3 YAML files to cleanly handle search terms with spaces or special characters.
  2. Robust Phonetics Mapping: Swapped out the chained || operator in search.yaml for a resilient JS IIFE (matching the pattern in the other files) to properly safely traverse the nested JSON nodes.
  3. Positional Arguments: Set positional: true on the word argument globally. The syntax is now much cleaner (opencli dictionary search serendipity), and I've updated docs/adapters/browser/dictionary.md to reflect this new usage.
  4. E2E Tests Added: Added native test coverage for search, synonyms, and examples directly into tests/e2e/public-commands.test.ts.

Everything is committed and running perfectly.

@jackwener jackwener force-pushed the feat/dictionary-adapter branch from 48f8d11 to ef574ea Compare March 24, 2026 11:23
@jackwener jackwener merged commit 3d39574 into jackwener:main Mar 24, 2026
10 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants