Skip to content

EasySkills 3.2.0

Choose a tag to compare

@RunhuaHuang RunhuaHuang released this 12 Jul 14:21
· 15 commits to main since this release

EasySkills 3.2.0

A hardening release focused on robustness, data safety, and correctness across
the deploy engine, installers, background supervisors, and the WebUI — the
result of a full multi-round audit. No behaviour or API changes; all fixes are
drop-in. All 98 contract tests pass.

Process Termination Safety (macOS / Linux)

Three sites matched a backend process purely by a webui.py path appearing on
its command line, then force-killed the match. That also matched editors,
greps, and language servers
that had the file open — and kill -9 would
destroy unsaved work.

  • own_webui_pid / stop_own_webui (deploy.sh) and own_webui_pid
    (webui-service.sh) now require the matched process to be a Python
    interpreter
    (ps -o comm= basename check) before killing. The uninstaller
    (uninstall_mac.command) gained the same guard for both bash/sh and
    python backends.

Concurrency (Windows)

  • Recover from an abandoned deploy mutex. deploy.ps1 Acquire-Lock now
    catches AbandonedMutexException. Previously, a single force-killed deploy
    (Task Manager, hard reboot mid-sync) left the named mutex abandoned, and every
    subsequent deploy.ps1 invocation threw the unhandled exception, re-abandoned
    the mutex, and bricked all future deploys until a reboot. macOS/Linux already
    self-healed via PID-lock recovery; Windows now matches that behaviour.

Data Safety

  • Atomic config writes (Windows). Write-Utf8NoBom in deploy.ps1 now
    writes to a temp file and atomically moves it over the target, mirroring
    deploy.sh's temp+mv pattern. A direct WriteAllText truncated-then-wrote
    custom-targets.txt / disabled-targets.txt, so an interruption could leave
    them truncated and silently drop every persisted custom agent path.
  • Verbatim custom-targets preservation (install.sh). The installer no
    longer round-trips custom-targets.txt through a shell variable
    ($(cat …) + echo "$VAR"), which mangled paths containing backslashes,
    glob characters, or a leading -. It now copies the file verbatim (matching
    disabled-targets.txt and webui.py's do_self_update).

Status & Labelling Correctness

  • deploy.sh --status no longer false-reports a running watcher.
    launchctl list prints - in the PID column for a job that is loaded but not
    running; that was reported as ✅ Running (PID -). Now treated as not-running,
    consistent with get_watcher_status in webui.py.
  • Trae/Trae-CN AppData paths labelled correctly in fallback mode (Windows).
    In deploy.ps1's prefix-based Get-AgentName fallback, %APPDATA%\Trae\skills
    was shadowed by the broader $Home\ prefix and mislabelled "Custom Agent". The
    more specific $env:APPDATA\ prefix is now tested first, with explicit
    Trae\* / Trae-CN\* branches.

Uninstaller Safety (macOS)

  • Warn when symlink cleanup fails. uninstall_mac.command now captures the
    exit code of deploy.sh --cleanup. On failure it prints a clear warning with
    a manual-cleanup command before trashing ~/EasySkills, so a partial cleanup
    no longer leaves dangling symlinks scattered across every agent's skills
    directory with no indication.

Installer Reporting (Windows)

  • Fix empty version reporting. install_windows.bat read OLD_VERSION /
    NEW_VERSION with %VAR% inside the parenthesised install block, where CMD
    expands once at parse time — so every install printed an empty version and
    upgrades were undetectable. The version report is now emitted after the
    block, where the variables hold their real values.

WebUI Supervisor (Windows)

  • Don't restart-storm when the port is held by a foreign process.
    webui-service.ps1 now mirrors webui-service.sh: when port 6633 responds but
    no webui.ps1 from this install owns it, it waits instead of relaunching —
    preventing the supervisor from burning through its restart throttle with no
    chance of recovery.

WebUI Frontend

  • Surface backend failures on read polls. apiCall previously swallowed
    network/parse errors for GET routes (/api/status, /api/skills, …) with no
    toast, so a dead backend left the dashboard looking alive. GET failures now
    show a localised error toast, rate-limited to once per 15 s (with re-announce
    after recovery) so the 5 s poller can't spam.
  • Localise the agent-path-edit error. saveCustomModalEdit's catch no
    longer shows the raw browser error string; it shows a consistent localised
    message.
  • Harden the central XSS boundary. escapeHtml now coerces null /
    undefined / non-strings to '' (via String(text)), so a future optional
    backend field rendered without a || '' guard can't throw and break the
    entire render loop.

Validation

  • All 98 contract tests pass (version/agent-count assertions derive from
    _maintenance/.version and agents.json, so they stay green on release).