feat: live plugin ops β outdated badges, streamed install/update, doctor copy-fix, leaner nav - #7
Conversation
β¦te output, copyable doctor fixes, leaner nav
|
π CorvidAgent is looking into this. |
corvid-agent
left a comment
There was a problem hiding this comment.
Good PR β four coherent threads tied together well. The streaming migration, outdated detection, and nav cleanup all land cleanly. A few notes:
Semver (src/semver.ts) β clean implementation, good test coverage. One pedantic note: the regex (?:[-+](.+))? conflates build metadata (+build.5) with pre-release (-rc1). Per semver spec, build metadata should be ignored for precedence, so 1.0.0+build.5 and 1.0.0 should compare equal β but the code treats the former as less than the latter. Unlikely to bite in practice for fledge plugins, but worth knowing.
Unhandled rejections β refreshOutdated() in both the store and installed loaders fires as a .then() without a .catch(). If the /plugins/outdated endpoint 500s or the network drops, that's a silent unhandled promise rejection. Easy fix: .catch(() => {}) like you already do inside streamPluginOp.
Input validation β VALID_SOURCE and VALID_NAME regexes look correct for keeping metacharacters out of argv. SSE endpoints being GET means they're theoretically CSRF-reachable, but this is a localhost dev tool so it's fine.
Streaming β pumpLines + opsConsole.attach handles the EventSource lifecycle well. The done β close β error race is handled correctly by nulling this.current before the error handler fires.
Minor β the timeout kill in spawnStream doesn't surface a "timed out" message to the client; the process just dies and the exit code reflects the signal. Not blocking but a future nice-to-have.
Tests pass, types check, removals are clean. Ship it.
Summary
Push toward "best tool for fledge" β make the hub feel alive and tighten its scope around plugin management. Four threads in one PR.
1. Outdated detection
Every installed plugin now reveals whether a newer release exists, with a one-click update.
src/semver.ts+ 12 unit tests β lenient comparator (handlesvprefix, missing patch segments, pre-release suffixes).src/github.tsfetchLatestVersion(owner, repo)β tries/releases/latestthen falls back to most-recent tag. 404s cached so missing-release repos don't hammer GitHub.GET /api/plugins/outdatedβ runs lookups in parallel, returns[{ name, source, current, latest, outdated }].2. SSE streaming for plugin operations
You can now watch installs / updates / removes happen live instead of waiting on a blocking POST.
src/fledge.tsspawnStream/fledgeStreamβ pumps stdout/stderr line-by-line from aBun.spawnprocess.3. Doctor: copy + rerun
Fix strings are arbitrary shell commands, not safely auto-runnable β so we don't try.
4. Navigation cleanup
Earlier conversation: the hub is the plugin hub, not a project IDE. Cut what didn't earn its place.
Test plan
π€ Generated with Claude Code