Skip to content

v2.2.0 — Fix: workspace in ASAR read-only (Windows silent launch)

Choose a tag to compare

@l17728 l17728 released this 28 Feb 08:57
· 7 commits to master since this release

v2.2.0 — Critical Fix: App silently fails to launch on Windows

Root Cause (Now Fixed)

The packaged .exe writes workspace data to __dirname/../../workspace, but in a
packaged Electron app __dirname points inside the read-only ASAR archive.
Every mkdirSync call in initWorkspace() throws ENOTDIR, the
uncaughtException handler exits after 200ms — createWindow() was never called,
so the window never appears. The only visible symptom was Can't find filter element
(harmless Chromium GPU-init messages) before the silent exit.

Fix: when app.isPackaged === true, workspace is now redirected to:

C:\Users\<user>\AppData\Roaming\SkillManager\workspace

Also Included

  • app.disableHardwareAcceleration() — prevents GPU-related renderer crashes
  • app.requestSingleInstanceLock() — prevents zombie-process silent exits
  • 15-second fallback show timer — guarantees window appears if ready-to-show is delayed
  • NSIS oneClick: false — installer lets you choose install directory

Service Layer: CLI Error Handling (333 unit tests)

Four gaps in how Claude CLI failures propagate through the service layer were fixed:

1. Test loop crash guard (test-service.js)
_runLoop previously had no .catch() on the background setImmediate. Any unexpected error (disk-full on checkpoint write, a throwing progress callback, etc.) left the project silently stuck in status: 'running' with no way to recover short of restarting the app.
Now: crash guard sets status: 'interrupted' on disk, clears in-memory state, and delivers a final onProgress event with projectStatus: 'interrupted' so the UI can react immediately.

2. Structured task error field (test-service.js)
Task result error field used err.message || err.code — picking only one. It now captures both:
"CLI_NOT_AVAILABLE: Claude not found" / "CLI_TIMEOUT" / "CLI_EXECUTION_ERROR: ...".

3. Analysis & recompose error detail (analysis-service.js, recompose-service.js)
catch blocks previously called String(err) which drops err.code on plain error objects. Both now use [errCode, errMsg].filter(Boolean).join(': ') so onComplete({ status: 'failed', error }) contains a meaningful, code-bearing string. recompose-service catch also corrected from logService.info → logService.error.

4. generateBaselineCases CLI guard (cli-lite-service.js)
ENOENT / timeout errors from the CLI call propagated as raw unstructured throws with no context. Wrapped with try-catch that rethrows { code, message: 'generateBaselineCases: <detail>' }.

14 new unit tests covering all fixed paths:

Test What it verifies
UC6-6a onProgress throws → crash guard marks project interrupted, delivers final callback
UC6-6b CLI_NOT_AVAILABLE with message → result.error contains both code and message
UC6-6c CLI_TIMEOUT → result.error contains CLI_TIMEOUT
UC7-5a Analysis CLI_TIMEOUT → onComplete status:failed, error contains code
UC7-5b Analysis CLI_NOT_AVAILABLE → error contains code + message
UC7-5c Analysis CLI_EXECUTION_ERROR → onComplete called, no report file written
UC8-5a Recompose CLI_TIMEOUT → onComplete status:failed
UC8-5b Recompose CLI_NOT_AVAILABLE → error contains code + message
UC8-5c Recompose RATE_LIMITED → error contains RATE_LIMITED
generateBaselineCases success Valid cases array and rawOutput returned
generateBaselineCases CLI_NOT_AVAILABLE ENOENT rethrown with generateBaselineCases: prefix
generateBaselineCases CLI_EXECUTION_ERROR Non-zero exit code propagated with context prefix
generateBaselineCases OUTPUT_PARSE_FAILED Missing cases field throws structured error
generateBaselineCases model arg Custom model argument passed through to spawn args

63 E2E Tests (4 skipped — require live Claude CLI)

Previously 59; 4 new tests added this release:

Test ID Description
TC-019 Empty skill workspace shows guide card with quick-import button
TC-020 Hovering a skill list item shows the hover-preview card
TC-B-014 Empty baseline workspace shows guide card with quick-import button
TC-R-013 Clicking a skill test badge navigates to Rankings and pre-fills the search field

Also fixed an E2E reliability issue on Windows: _waitForPortFree timeout raised
from 8 s → 75 s to handle TCP TIME_WAIT after Electron exits (previously caused
intermittent CDP-unavailable failures when two Electron instances launched back-to-back).


Documentation

  • manual.md bumped to v2.2; FAQ §Problem 3 now lists specific CLI error codes (CLI_TIMEOUT, CLI_NOT_AVAILABLE, RATE_LIMITED, CLI_EXECUTION_ERROR) with remediation hints — users no longer need to dig into logs to identify the failure cause.