docs(compatibility): record the attachment preview route
The optional-column story the File Activity card already documents gains its second consumer: `/api/dsh-context/attachment`, what it authorizes (only an id the session's own log cites, and where the harness's gateway is stricter still), how a verbatim file's named alias differs from the hard link a suffixless image object needs, and what degrades when a face is absent.
This commit is contained in:
1 parent
c0e2fb47da
commit
ec76a220e7
1 file changed
+3
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
dsh-context declares per-release compatibility with `@deepseek-ai/dsh` in its package manifest (`dsh.compatibility.dshReleases`). This page records what is actually verified for each declared release, and how.
|
||||
|
||||
Last verified: **2026-10-11** (plugin `dsh-context@0.68.1` source tree, dsh `0.2.0-rc.2`). The disposable-profile column below records its own, earlier manual dates.
|
||||
Last verified: **2026-10-13** (plugin `dsh-context@0.69.1` source tree, dsh `0.2.0-rc.2`). The disposable-profile column below records its own, earlier manual dates.
|
||||
|
||||
## Supported dsh releases
|
||||
|
||||
@@ -92,6 +92,8 @@ The guide capsule carries `order`, `title`, `description`, and `icon` (the `guid
|
||||
|
||||
The File Activity card's file-name affordance is an optional-column story: the plugin opens the file's preview tab through `ctx.sidebarRight.openResource` (the built-in Files sidebar's own path), building the `dsh-resource://file/…` address with the harness's browser-safe `fileAddressFor` (inlined by the client bundle, exactly as the Sidebar's own file types inline it). Where the preview face is absent (or refuses the address), the name keeps its original system-open behavior; the `sidebar.nav` probe pins the navigation face's spelling.
|
||||
|
||||
The Context browser's attachment cards are another optional-column story. A message's `image` and `file` blocks render as one ordered card list, and a click hands the attachment to the harness's preview column through the same `previewAddressOf` → `openResourceVia` path the File Activity card rides. The path itself comes from the plugin's own `/api/dsh-context/attachment` fetch route (same authenticated `/api` fence, Connection exact-route registry, and cold-read gate as the detail and fleet routes): the route answers only an id the SESSION'S OWN log cites (a payload walk bounded in depth and total over hostile input, so an id no logged content block carries — the harness's own gateway is stricter still, reading declared fields per event type — resolves to nothing) and answers the store's named alias. A verbatim file already has one (`attachments.fileHostPath` → `<home>/attachments/v1/files/<xx>/<digest>/<name>`); a normalized image does not — its object is digest-named and suffixless, while the preview column dispatches its viewer by suffix — so the route publishes (or reuses) a named hard link under `<home>/cache/dsh-context/previews/<xx>/<digest>/<name>` and answers that. The link shares the immutable, digest-verified object bytes; the cache is disposable, and a deployment whose attachment store is not host-file-backed, or whose session log cannot be read, answers a typed `null` and the card reports "preview unavailable" instead. Image thumbnails keep riding the harness's own session-authorized `uiConversation.imageUrl` loader; the file-type glyph resolves defensively off the primitives module (`FileTypeGlyph`), and every card degrades to its metadata when a face is absent.
|
||||
|
||||
The session jump — a Context Insights session card or an Agent network node bringing its session forward — rides the harness's own selection verb (`openSessionVia` in `src/client/services.ts`): `uiWorkspace.openSession`, the verb the built-in sidebar's row click uses on every supported line. The face is re-proved per call and a deployment serving none (or a hostile face) swallows silently — the verb's own navigation returns the center column to the conversation (`selectPanel(null)`), so a dead jump simply stays on the page. Issue #90 was exactly the retired-spelling trap: the plugin once called the sessions service's own `open(id)`, which the 0.1.6 selection refactor removed from the service (the click then did nothing on `0.1.7-rc.2`), so the jump follows the view owner and the per-baseline `sessionNav` probe pins the verb's signature and the retired spelling's absence.
|
||||
|
||||
The Context Insights page's DeepSeek balance capsule is an all-optional stack, so it arms nowhere it cannot: the host reaches the `settings` and `credentials` services only inside a deferred `ctx.inject` (and re-reads them per request, so a key added while the host runs is picked up on the next open), mounts `/api/dsh-context/balance` through the same Connection exact-route registry as the detail and backfill routes, and the outbound `/user/balance` read carries the key only inside the host process. The provider's settings row is read off the Config-form `describe()` projection — the row is the entry whose served value declares the top-level `apiKeyEnv` credential ref, preferred under the settings ids the generations have served it as (`llm-deepseek` on product profiles, `llm-deepseek-api-key` elsewhere). The capsule appears only on a live, well-formed answer; a deployment whose DeepSeek API-key provider is not composed (no settings row), whose credentials service cannot resolve the key, whose connection service lacks the exact-route registry, or whose platform read fails (network, non-2xx, malformed payload, a third-party endpoint that does not serve the balance path) answers a typed `null` and the browser renders nothing — no pill, no spinner, no error state. The `balance` probe pins the settings face and the provider row's sources per baseline.
|
||||
|
||||
Reference in new issue
Block a user