Repository navigation
v2.2.0 — Fix: workspace in ASAR read-only (Windows silent launch)
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 crashesapp.requestSingleInstanceLock()— prevents zombie-process silent exits- 15-second fallback show timer — guarantees window appears if
ready-to-showis 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.mdbumped 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.