Commit 0470ac4
refactor: move all site adapters to independent plugins (#216)
* docs: design LinkedIn post-comments command
* feat: add LinkedIn post-comments command
* fix: complete LinkedIn comment collection
* refactor: move LinkedIn commands to community plugin
* feat: add public Webcmd plugin runtime
* fix: preserve plugin runtime error messages
* feat: add independent plugin migration infrastructure
* fix: make plugin migrations collision safe
* refactor: migrate public API adapters to plugins
* refactor: migrate package and Jira adapters to plugins
* fix: make plugin manifest resolution fail closed
* refactor: migrate reference adapters to plugins
* refactor: consolidate PyPI commands in plugin
* refactor: migrate search and desktop adapters to plugins
* refactor: migrate content and market adapters to plugins
* refactor: migrate commerce and utility adapters to plugins
* refactor: migrate chat and professional adapters to plugins
* refactor: migrate document and messaging adapters to plugins
* refactor: complete independent adapter plugin migration
* refactor: make Webcmd core adapter-free
* fix: address plugin migration final review
* test: make CI portability checks deterministic
* test: fix Windows plugin path portability
* fix: match migrated plugin webcmd version floor to the shipping release
migrate-cli-sites.mjs hardcoded webcmd: ">=0.6.0" for every plugin it
generated a fresh manifest for, but package.json ships as 0.5.3 in this
release. Every one of the 108 affected plugins (including linkedin) was
uninstallable: `webcmd plugin install` hard-fails checkCompatibility()
with "Plugin requires webcmd >=0.6.0, but current version is
incompatible" before it ever reaches npm.
Derive the floor from package.json's actual version instead of a
literal, and regenerate the already-committed manifests (all
plugins/*/webcmd-plugin.json + package.json, and the aggregated root
webcmd-plugin.json catalog) to match. Update the two unit tests that
had the old literal baked into their expectations.
* test: install fixture plugins in e2e/smoke suites now that core ships no sites
Several e2e and smoke tests invoked site commands (hackernews, dictionary,
google, imdb, apple-podcasts, yollomi, paperreview) and asserted on `list`
output size/contents, assuming site adapters were bundled in core. After
this migration core registers zero site commands until a plugin is
installed, so these tests failed deterministically in any clean
environment (e.g. `list` returns 0 commands, not >50).
Add installFixturePlugin() to place a repo-local plugin directly under
an isolated HOME's .webcmd/plugins/ (skipping `plugin install`'s npm
step, which only resolves a peerDependency these fixture plugins don't
otherwise need and which fails until the in-progress release is actually
published). Each affected suite now installs the specific plugin(s) it
exercises before running. The smoke test's "all expected sites
registered" check is rewritten against the plugin catalog under
plugins/, since that's the equivalent invariant post-migration.
* docs: fix bundled skills to describe the plugin architecture, not clis/
webcmd-usage, webcmd-adapter-author, and webcmd-autofix (all shipped to
npm under skills/**) still described a repo-root clis/ directory as the
"official bundle" location for built-in adapters. That directory no
longer exists — every main-repo site, official or community, lives
under plugins/<site>/ now. Left the ~/.webcmd/clis/ references alone:
that private local-iteration directory is unaffected by this migration.
* feat: hint at plugin search/install when webcmd list has no sites
Now that core ships zero bundled site adapters, an empty `list` (0
sites) is the expected default state on a fresh install rather than a
sign something's broken. Point the user at `plugin search`/`plugin
install` instead of leaving them looking at a bare zero-count line.
* chore: stop committing the generated plugin-command-manifest.json
It's a build artifact (npm run build-plugin-manifest scans plugins/*
via a Node loader and writes it fresh), read only by CI-time checks
within the same run: check-plugin-command-parity, check-typed-error-lint,
check-silent-column-drop, and convention-audit. Nothing reads it from a
published package or at CLI/hosted runtime, so it doesn't need to be
in the npm tarball or in git history — same treatment as
hosted-contract.json, which was already gitignored for this reason.
* fix: generate plugin-command-manifest.json as part of npm run build
Gitignoring it in 4aec6c5 broke the unit-test CI job: that job runs on
a separate runner with a fresh checkout and only does `npm ci` +
vitest, so the file no longer existed for the three test files that
read it from the package root (hosted/availability, hosted/file-contract,
build-manifest) — 5 tests failed with ENOENT.
hosted-contract.json is safely gitignored only because `npm run build`
always regenerates it. Give the plugin manifest the same guarantee
instead of leaving it as a build artifact nothing in the install path
produces. Costs ~0.9s per build.
* feat: export deriveHostedAvailability for hosted consumers
* fix: handle ports in local IPv4 address detection for deriveHostedAvailability
The isLocalIpDomain function now strips port numbers from domain strings
(e.g. '127.0.0.1:3000') before validating the IPv4 format. This ensures
desktop-app adapters running on local IP addresses with ports are correctly
classified as 'app' rather than 'site'.
Includes regression tests to prevent port-handling regressions.
* feat: support plugin list, uninstall, update, and create in hosted mode
* fix: refuse to update a plugin with uncommitted changes unless forced
updatePlugin/updateAllPlugins now check for tracked-file modifications
in both the standalone plugin directory and the shared monorepo clone
before beginReplaceDir wipes them, with --force to opt out. Local
(symlinked) installs are unaffected since they never go through
beginReplaceDir.
* fix: count untracked files as dirty in the plugin update guard
git status --porcelain already omits gitignored paths (node_modules/dist
never show up), so --untracked-files=no was only hiding the case the
guard exists to catch: a new, unstaged command file. Drop the flag,
label refusal entries as new-unstaged vs modified for clarity.
* ci: reconcile the hosted plugin catalog on merge to main
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* ci: clarify --update-env-vars semantics and workflow_dispatch usage
Add inline comments explaining that --update-env-vars on 'execute' is a
per-execution override (not a job-spec mutation) and that workflow_dispatch
runs should target main to avoid delisting plugins.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: fail closed on unexpected git errors in the plugin dirty-checkout guard
getDirtyFiles previously treated any git failure (missing binary, "detected
dubious ownership in repository", permission errors) as "clean", letting
beginReplaceDir silently destroy uncommitted work. It also ran `git status
--porcelain` with no pathspec, which reports the whole enclosing repository
rather than just the plugin directory, causing spurious refusals for plugins
inside a larger repo (e.g. a dotfiles-tracked home directory).
Now getDirtyFiles probes with `git rev-parse --git-dir` first: a genuine
non-repository still proceeds, but any other failure refuses the update with
a message pointing at --force. `git status` is scoped with `-- .` so only the
plugin directory is considered.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: ensure parent directories exist before writing plugin output files
* chore: update lockfile dependencies for package-lock.json
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: beubax <tejasr@bu.edu>1 parent f4622fb commit 0470ac4
1,565 files changed
Lines changed: 38939 additions & 31612 deletions
File tree
- .github/workflows
- clis
- _atlassian
- codex
- cursor
- pypi
- docs
- plugins
- amazon-in
- test
- amazon
- test
- antigravity
- test
- apple-podcasts
- test
- archive
- test
- arxiv
- test
- band
- barchart
- test
- bbc
- bigbasket
- test
- binance
- test
- blinkit
- test
- bloomberg
- test
- bluesky
- booking
- test
- brave
- test
- chatgpt-app
- test
- chatgpt
- test
- chatwise
- test
- chess
- test
- cincinnati
- claude
- test
- codex
- test
- coingecko
- test
- concordia
- confluence
- test
- coupang
- test
- crates
- cursor
- dblp
- test
- defillama
- test
- devto
- test
- dictionary
- discord-app
- test
- district
- test
- dockerhub
- duckduckgo
- test
- endoflife
- test
- facebook
- __fixtures__
- test
- flathub
- test
- gemini
- test
- geogebra
- test
- github-trending
- test
- github
- goettingen
- google-scholar
- test
- google
- test
- goproxy
- test
- grok
- test
- hackernews
- test
- heidelberg
- hft
- hf
- test
- homebrew
- iit
- imdb
- test
- indeed
- test
- instagram
- test
- jhu
- jira
- test
- lesswrong
- test
- lichess
- test
- linkedin-learning
- test
- linkedin
- __fixtures__
- test
- lobsters
- test
- manus
- test
- maven
- mdn
- medium
- mercury
- test
- notebooklm
- test
- npm
- nuget
- test
- nvd
- oeis
- test
- openalex
- openfda
- test
- openreview
- test
- osv
- test
- packagist
- paperreview
- test
- pixiv
- test
- practo
- test
- producthunt
- test
- pubmed
- test
- pypi
- lib
- test
- qoder
- test
- reddit
- test
- rest-countries
- test
- reuters
- test
- rfc
- test
- rubygems
- semanticscholar
- test
- slock
- test
- spotify
- test
- stackoverflow
- test
- steam
- test
- substack
- test
- suno
- test
- techcrunch
- test
- tiktok
- test
- trae-solo
- test
- trip
- test
- tvmaze
- test
- twitter
- test
- ualberta
- uiverse
- test
- upwork
- test
- web
- test
- wikidata
- test
- wikipedia
- test
- wttr
- test
- yahoo-finance
- yahoo
- test
- yale
- ycombinator
- test
- yollomi
- youtube
- test
- zepto
- test
- zlibrary
- test
- scripts
- skills
- webcmd-adapter-author
- references
- webcmd-autofix
- webcmd-usage
- src
- hosted
- tests
- e2e
- smoke
- test/fixtures
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
50 | 58 | | |
51 | 59 | | |
52 | 60 | | |
53 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
54 | 66 | | |
55 | 67 | | |
56 | 68 | | |
| |||
85 | 97 | | |
86 | 98 | | |
87 | 99 | | |
88 | | - | |
89 | | - | |
| 100 | + | |
| 101 | + | |
90 | 102 | | |
91 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
92 | 108 | | |
93 | 109 | | |
94 | 110 | | |
| |||
100 | 116 | | |
101 | 117 | | |
102 | 118 | | |
103 | | - | |
104 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
105 | 124 | | |
106 | 125 | | |
107 | 126 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
71 | 83 | | |
72 | 84 | | |
73 | 85 | | |
74 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
75 | 91 | | |
76 | 92 | | |
77 | 93 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
70 | 79 | | |
71 | 80 | | |
72 | 81 | | |
| |||
110 | 119 | | |
111 | 120 | | |
112 | 121 | | |
113 | | - | |
| 122 | + | |
| 123 | + | |
114 | 124 | | |
115 | 125 | | |
116 | 126 | | |
| |||
130 | 140 | | |
131 | 141 | | |
132 | 142 | | |
133 | | - | |
| 143 | + | |
134 | 144 | | |
135 | 145 | | |
136 | 146 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
14 | 19 | | |
15 | 20 | | |
16 | 21 | | |
| 22 | + | |
17 | 23 | | |
18 | 24 | | |
19 | 25 | | |
| |||
0 commit comments