Merge/dsh gateway auth - #396
Open
Fairy-happy wants to merge 30 commits into
Open
Conversation
Upstream now publishes the official CI build to npm, so the 251 vendored tarballs under packages/harness-0.1.2-rc.1/ (8.1 MB, rebuilt by hand on a maintainer's machine every upgrade) are replaced by exact version pins plus lockfile integrity. That also removes the build-machine absolute paths the CSS patches used to carry. Upstream breaking changes handled: - The session-persistence seam is now a handle-ownership model (create/open/flush/stat/list). The permanent-deletion patch chain is rewritten against it: the JSONL backend's delete() takes the same write claim and directory lease a write open takes. - The replace surfaceOp renamed start/end to startSeq/endSeq; the bundled PPT plugin emitted the old shape and is fixed and repacked. - SystemPrompt's persona option split into personaPrefix/personaSuffix. - Prerelease peer ranges (^0.1.2-alpha.4) do not match 0.1.5-rc.1, so the in-repo plugins' dsh peer ranges are widened. All 20 patches are migrated. Several previously replaced whole CSS strings and class maps with a locally rebuilt copy, which silently mismatched after any upstream rebuild; they now only append desktop-owned rules and keys, and the tests assert that invariant instead of pinning CSS-module hashes. Verified: npm ci (20 patches), vitest 749/750, tsc, npm run build, verify-harness-auth.mjs, and a direct safe-mode profile boot. test/safe-mode-runtime.test.ts fails: its fault injection uses an ESM loader hook, and under 0.1.5 registering any loader hook makes boot exit 0 silently. The real launch path registers none and boots fine. See docs/harness-0.1.5-rc.1-upgrade.md.
…meta.main
Harness 0.1.5 moved lib/bin.js from top-level execution to
async function runCli() { ... }
if (import.meta.main) await runCli();
export { runCli };
build/harness-node-entry.mjs imports that entry rather than being it, so the
guard is false and the CLI never ran: the process loaded the module, did
nothing, and exited 0 with no diagnostics. The app surfaced only "Harness
stopped unexpectedly (exit code 0 (0x00000000))" after a 40s wait, on both
the web and safe-mode profiles.
Isolated with a clean DSH_HOME and no third-party plugins: running bin.js
directly serves (401), running it through the entry wrapper does not. The
fix calls the exported runCli(); builds that still self-execute on import
keep working.
This was also the root cause of the safe-mode-runtime failure previously
attributed to ESM loader hooks — that diagnosis compared against a direct
bin.js run, which bypassed the wrapper. Hooks were never involved. With the
entry fixed the suite is 751/751.
test/harness-node-entry.test.ts locks both halves of the contract: upstream
still gating on import.meta.main and exporting runCli, and the entry calling
it rather than relying on import side effects.
动态 import 不会触发 import.meta.main,导致 Harness 空载退出;PPT RPC 在未注入 webServer 的 fiber 上注册会启动失败。重打内置 PPT tarball 并同步 lockfile,保证同事 npm ci 后即可启动。 Co-authored-by: Cursor <cursoragent@cursor.com>
Harness 0.1.5 turns an RPC channel into a webServer route owned by the
Context that read `connection`:
get rpc() { const owner = this.ctx; ... }
register(owner, ...) { return owner.effect(() => owner.webServer.register(route)) }
The bundled PPT plugin called ctx.connection.rpc.handle() directly, so that
Context had no webServer and the read threw "cannot get property webServer
without inject", failing the whole plugin tree. Each cold start then burned
~30s per attempt: web profile fails, plugin recovery runs, safe mode boots,
and the app restarts into web again — roughly 90s before the user sees
anything, which is the reported slow startup.
Adding "webServer" to the plugin's inject array does not help; the failing
Context is not the plugin's own (verified: fiber.inject and fiber.store both
carry it and the read still throws). Registering from a scoped inject
Context does, and matches registerPreviewAssets in this same package. The
top-level inject stays unchanged so a profile without a web server still
gets the tool half.
The PPT fixtures fake ctx, so they need `effect` and `webServer.register`
for the scoped callbacks to run and register the channel.
Verified on clean DSH_HOME with the desktop's own launch arguments: the web
profile with PPT is ready in 4-6s with zero inject failures. Suite 751/751.
The same enforcement also hits the third-party dsh-plugin-width-slider,
which is not ours to fix.
The Harness log timestamped only the `starting` line, so a slow launch could
not be split between Harness booting and the desktop probing for readiness —
the only other signal was a progress tick every 10s.
Every file line now carries `+<ms>` since the launch began, the two
boundaries that matter are marked ("Harness announced its endpoint", "Harness
is ready"), and the progress tick drops to 5s. The in-memory log lines stay
verbatim because recovery detection, failure-cause extraction and their tests
match on the text.
Measured with this on a copy of a real profile (9 third-party plugins):
Harness serves in ~4s and the readiness probe answers in 2-19ms, so neither
is the reported slow startup.
The launch clock began at `[desktop] starting`, but launchHarness does its pre-flight first: splash, stopping the previous Harness, migration recovery, the pnpm store, generation projection and the LaunchAgent audit. All of that was unstamped, so the log made a launch look faster than it felt. beginLaunch() now starts the clock when the launch is requested and start() keeps a clock the launcher already began. The phases in between are marked so a slow start can be attributed to one of them. Measured so far on a copy of a real profile, time until Harness prints its token: 3.6s with no third-party plugins, 8.8s with the user's nine. Leaving one out at a time puts the whole 5.2s difference on a single entry — an MCP client that opens a remote streamable-http session during boot; the other eight are within noise. Same numbers under the Electron utility process (3.7s / 4.0s), so the runtime is not the cost.
…al path Profiling a boot of a real nine-plugin profile put a third of Harness CPU in @deepseek-ai/dsh-client-modules building the combined client bundle: - newlineCount walked each multi-megabyte bundle with `for (const char of value)`, allocating a string per code point, and identitySectionMap built a line-length array only to join it. Native indexOf and String#repeat give byte-identical counts and mappings (verified against all 64 real bundles plus edge cases) about 18x faster. - compose() runs on every graph flush and rebuilt every single-record combo each time; while a profile boots the graph flushes about nine times, so each unchanged bundle was re-concatenated, hashed and encoded ~9x (the 6.9MB document-preview bundle ~40ms per pass). Records keep their identity until their source changes and rebuilt() assigns a new content-hash rev on any byte change, so combos are memoised on the record, validated by rev. All 64 served bundles still return 200 at the same sizes and parse. Same machine, same profile, time until Harness prints its token: upstream 3.9-4.2s -> 1.8-2.6s. Desktop side, measured from the new launch clock: - The login-shell capture (310-440ms here) ran with execFileSync on the main process right before the spawn. It now starts asynchronously when the app starts and the launch reads the result. - Readiness waited a further 500ms sustain window after the first healthy probe. Health already requires the launch token, which Harness prints only once its plugin tree is loaded and it is serving, so the first healthy probe is the settled state.
Co-authored-by: Cursor <cursoragent@cursor.com>
Upstream rc.2 is four commits: the feedback dialog, delivered-file card layout and conversation spacing. - 217 @deepseek-ai/dsh-* dependencies move to 0.1.5-rc.2 and the 19 dsh patch files are renamed; the cordis family versions are unchanged. - Drop @deepseek-ai/dsh-typert-generator. It is a TypeScript analyzer and code generator that only the root project depended on, carried over from the old vendored package set; upstream did not publish it for rc.2. - Of the patched packages only dsh-client-ui-chat, -deliverables and -sidebar changed between rc.1 and rc.2. Every function and anchor the patches touch is identical in both, and the sidebar CSS-module hash did not change, so all 20 patches apply unchanged. - The in-repo plugins' `^0.1.5-rc.1` peer ranges already admit rc.2, so the PPT bundles are not repacked. Verified: vitest 754/754, tsc, build, verify-harness-auth; the web profile with PPT boots under both the bundled Node and the Electron utility process with no inject or entry failures, and a real Chromium load of the first screen logs no console errors.
# Conflicts: # package-lock.json
Adapt the feature to Harness 0.1.5-rc.2 and validate its independent Desktop composition.
… main 的市场安装与启动修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.