mirror of
https://github.com/lobehub/lobehub.git
synced 2026-09-20 04:56:13 +08:00
95dfa1d389
* 🐛 fix(device): probe the helper this app ships, not the one the backend guesses Reported from an installed canary build: the Local Sandbox row said Sandbox Runtime dependencies are unavailable: srt-win.exe not found. Looked in: …\resources\app.asar\vendor\srt-win\x64\srt-win.exe while `resources/sandbox-runtime/vendor/srt-win/x64/srt-win.exe` was sitting right there. The Set-up button was equally useless, because provisioning was never the thing that was missing. `probeSandboxCapability` went through `SandboxManager.checkDependencies()`, which resolves the helper via the backend's own `getSrtWinPath()` — a path relative to the backend's package directory. Bundling that package into the main process makes the computed path land inside `app.asar`, where no file can exist. The launch path was already immune (it passes `windows.srtWin.path`); only the probe still asked the wrong question, so a correctly installed app reported a missing binary and offered a button that could not change the answer. Windows now runs the checks directly against the resolved path, mirroring the backend's own sequence — binary present, sandbox user provisioned with a readable credential, WFP filters installed — and stages the helper first, so the path it validates is the one the launch will use. `cannot-read` on filter enumeration stays a non-failure: it is admin-gated, and the behavioural egress check at `initialize()` is what fails closed. macOS and Linux keep the backend's own check. Neither resolves anything relative to the app, so neither was affected. Verified against the installed build's own layout: the probe that reported "not found" now returns available. Two follow-ons: - ship the backend's package.json beside the binaries, so the staging directory stays keyed on the real version instead of falling back to the binary's size — the fallback worked, but defeated per-version isolation in exactly the case it exists for, an installed app being updated; - make the `createSrtConfig` assertion platform-aware, since the Windows helper override is absent everywhere else and an exact-match expectation would fail on one platform or the other. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 🐛 fix(device): make one function decide the sandbox helper path Review follow-up on both findings. **Probe and launch could disagree.** The probe fell back to the unstaged source when staging failed, while `createSrtConfig` fell back to *no override at all* — letting the backend resolve its own package-relative path, which is inside `app.asar` once bundled. A host where staging cannot happen (ProgramData locked down, disk full) was therefore advertised as available and failed on the first command: exactly the "claims a guarantee it never applied" outcome this feature exists to avoid. `resolveEffectiveSrtWin` is now the single place that resolves and stages, and the probe, the launch, and setup all call it. They cannot diverge by construction. It falls back to the unstaged source rather than giving up, because a per-machine install already sits somewhere the sandbox account can read — staging is an accommodation for per-user installs, not a precondition. **The probe had no test.** The previous commit changed `probeSandboxCapability` but only asserted on `createSrtConfig`, which already used the staging helper — so putting the probe back on `SandboxManager.checkDependencies()` would have gone unnoticed, and AGENTS.md asks for a regression test that fails before the fix. Added one covering the Windows branch directly: it pins that the backend check is *not* consulted, that the resolved path is what gets validated, that an unprovisioned account stays distinguishable from a missing binary (only one of those is what the Set-up button fixes), that `cannot-read` filter enumeration is not a failure, and that other platforms keep the backend check. Five of the eight fail against the pre-fix implementation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * 🐛 fix(tool-runtime): stop runCommand swallowing the reason it failed Every sandboxed command came back as `[UNKNOWN_EXEC_ERROR] Tool execution failed`, with the actual reason discarded. `normalizeResult` put the daemon's `error` inside `result.result.error`, but `ComputerRuntime.errorOutput` reads the ServiceResult's own `error`, then `state.stderr`, then `state.error`. A command that fails *before spawning* fills none of those — there is no process, so no stderr and no exit code — so the chain ran to its last-resort fallback every time. That is the exact shape of every Local Sandbox refusal ("requires a working directory", "unavailable on this device"), which is how a precise, actionable message turned into a generic one that told the user nothing and gave the model nothing to correct. The same gap was already fixed for editLocalFile / grep / glob; runCommand was missed. Surfaces `raw.error` at the top level like those tools do, and pins both halves: a pre-spawn failure keeps its reason, and a successful run still reports whether it was actually sandboxed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>