feat(desktop): DSH Electron desktop shell — harness internals visualized
Minimal Electron shell over the DSH JSON-RPC runtime — a first-look at what a ChatGPT.app-style host on top of the DeepSeek Harness looks like, with the harness's normally-invisible internals (trace timeline, context surface, subagent tree, compaction, plugin registry, rubrics) brought forward as first-class UI surfaces so plugin authors and researchers can see what the agent is actually doing. Runs against three keyless-to-live profiles (stdio-echo works on master out of the box; daemon-echo / daemon-vibe-echo activate once the daemon-demo lands; stdio-deepseek and daemon-vibe hit the real DeepSeek API when you supply a key). HARNESS_DEV auto-resolves to the in-repo runtime when this shell ships under examples/desktop/, so a fresh clone launches without config; env DSH_DEV_ROOT overrides for custom layouts, and a sibling deepseek-harness-dev/ checkout is the original dev workflow. Cold-clone gate (P0 fixes for first-time-clone usability): - HARNESS_DEV: 3-candidate resolver (env → walk-up in-repo marker → sibling), unit-tested via mock fs so ordering is locked without needing either real layout on disk. - config yml leaves rewritten at assemble time so the sibling-clone paths (../../deepseek-harness-dev/examples/echo-agent/…) become the in-repo paths (../../echo-agent/…) in the released tree — source yml stays usable for local dev, released tree ships a working shape. - pnpm-workspace.yaml allowBuilds.electron = true (was placeholder). - missing-key card in stdio-deepseek offers a one-click switch to stdio-echo (the keyless profile that works on master) rather than daemon-echo (blocked on the not-yet-shipped daemon-demo). - assemble-oss-release.sh rewrites the source-side breadcrumb name 'dsh-desktop-demo' → 'dsh-desktop' for the released package.json. FOUC guard on the onboarding gate (41fc5df carried) keeps the first-launch splash from flashing before the runtime probe finishes. Test suite (1634 tests in source, 3990 in the runtime repo) covers resolver ordering, renderer classifiers, trace timeline shape, compaction diff rendering, rubric parity, and the missing-key onboarding paths.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 268 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 238 KiB |
81
examples/desktop/docs/default-profile-real-probe/README.md
Normal file
81
examples/desktop/docs/default-profile-real-probe/README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# default-profile-real probe (2026-07-18)
|
||||
|
||||
Isolated real-machine verification for `fix/default-profile-real` (default
|
||||
profile → stdio-deepseek + missing-key guided-switch card).
|
||||
|
||||
## Isolation (mandatory)
|
||||
|
||||
`--user-data-dir=/tmp/dsh-probe-default-real/user-data` (Electron caches +
|
||||
Local Storage) AND `DSH_DESKTOP_HOME=/tmp/dsh-probe-default-real/dsh-home`
|
||||
(shell overlay + config.json + `.onboarded` sentinel). Team-lead flagged
|
||||
that a prior probe wrote through to the user's real `~/.dsh-desktop/user-
|
||||
overlay.cordis.yml` because DSH_DESKTOP_HOME wasn't isolated; this probe
|
||||
respects both.
|
||||
|
||||
Driver: `/tmp/dsh-probe-default-real/run.sh {with-key|no-key} [port]`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### 01 · no-key boot (`01-no-key-boot.png`)
|
||||
|
||||
Boots stdio-deepseek with DEEPSEEK_API_KEY unset. Confirms:
|
||||
- Bottom-right chip: `stdio-deepseek · deepseek-v4-flash` (NEW DEFAULT
|
||||
correctly landed — was `daemon-echo · mock-echo` before this change)
|
||||
- Composer model chip: `deepseek-v4-flash` (matches profile default)
|
||||
- Status bar: `crashed` (expected — the deepseek runtime dies during
|
||||
plugin load because this dev-clone snapshot has a `workspaceContext`
|
||||
schema drift; NOT the api-key error we designed against)
|
||||
- Banner: **generic "Runtime warning"** — the raw message reaching
|
||||
the classifier is `runtime not writable` (from
|
||||
`transport.js:53 write() throws when stdin isn't writable`), which
|
||||
correctly falls through to the generic bucket. My missing-api-key
|
||||
regex would ONLY match if the deepseek plugin actually got to throw
|
||||
its api-key error, which requires the config schema to pass first.
|
||||
|
||||
### 02 · guided-switch card (synthetic inject, `02-guided-card-injected.png`)
|
||||
|
||||
Fires `showRuntimeErrorBanner('llm-deepseek: an API key is required
|
||||
(Config.apiKey or $DEEPSEEK_API_KEY)')` via the __dshRenderer test seam
|
||||
so we can see the classifier + banner logic end-to-end without needing
|
||||
the real llm-deepseek error to surface. Confirms:
|
||||
- Banner title: **"! DEEPSEEK_API_KEY needed for real-model profile"**
|
||||
- Hint: full two-option copy (set env in .env/shell, or try keyless demo)
|
||||
- Switch button: **"Switch to keyless demo (daemon-echo)"** (ghost small,
|
||||
under hint, wired to `window.dsh.startRuntime('daemon-echo')`)
|
||||
- Layout: amber-tinted banner sits above the welcome cards, NO red wall,
|
||||
full-width row (respects density spec)
|
||||
|
||||
### 03 · with-key boot (`03-with-key-boot.png`)
|
||||
|
||||
Boots stdio-deepseek with the dev-clone `.env` key loaded. Same shape as
|
||||
#01 in this environment because the config schema drift dies before the
|
||||
key check — the WITH-key scenario would surface `status=ready` +
|
||||
`no banner` only after the dev clone is bumped past the `workspaceContext`
|
||||
requirement. Documenting for reproducibility.
|
||||
|
||||
## Known limits (dev-clone drift)
|
||||
|
||||
`deepseek-harness-dev` currently requires `workspaceContext` in the
|
||||
agent-spine-demo entry (packages/examples/agent-spine-demo/src/index.ts:94).
|
||||
The demo repo's `config/deepseek-jsonrpc.yml` predates that requirement, so
|
||||
the runtime dies at config validation before either the key check or the
|
||||
actual daemon handshake. This is orthogonal to the default-profile change
|
||||
and does NOT block:
|
||||
- The default profile stdio-deepseek IS observably active (screenshots
|
||||
and CDP eval of `#profile.value` confirm)
|
||||
- The guided-switch card renders correctly when the api-key error DOES
|
||||
reach the classifier (screenshot #02 proves this via the test seam)
|
||||
- The static test suite (`test/default-profile-real.test.js` +
|
||||
`test/renderer-runtime-banner-classify.test.js`) locks every step of
|
||||
the wire path (currentProfileName, cfg.profile persistence, stderr
|
||||
accumulator, classification bucket, banner switch button)
|
||||
|
||||
## Follow-up
|
||||
|
||||
- **Dev-clone bump**: separate ticket. When `agent-spine-demo` becomes
|
||||
optional or the yml gains `workspaceContext`, re-run this probe in
|
||||
full to see the api-key error surface organically. Current 1554 test
|
||||
suite locks the code paths that would fire when it does.
|
||||
- **README quick-start** — team-lead owns this batch, keeping just the
|
||||
minimum quote-of-fact edits to README in this commit (default is
|
||||
stdio-deepseek, keyless demo callout).
|
||||
Reference in New Issue
Block a user