Files
apes-sidebar/src/client/markdown-labels.tsx
T
Menghuan1918 6cfe7a736f feat: adapt to DSH 0.1.2-alpha.1 (Remote gateway + token auth + MarkdownText labels)
Dual-version compatibility: the plugin now works identically on
0.1.0-rc.8 ~ 0.1.1-rc.2 and 0.1.2-alpha.1 (the latter verified against a
source build of the dsh-v0.1.2-alpha.1 tag: mount smoke 14/14 + aggregate
double-mount; 0.1.1-rc.2 re-verified 14/14).

- MarkdownText: alpha.1 renamed the flat optional `codeLabels` prop to a
  required nested `labels: { code: {copyLabel, copiedLabel}, footnotes }`;
  the old prop alone crashes fence rendering with "reading 'code'". All
  four render sites (mermaid / MarkdownHtml / TextEditor / SideChatView)
  now go through src/client/markdown-labels.tsx (dual-shape object passed
  under both prop names).
- e2e mount lanes speak both host dialects (tests/e2e/host-protocol.ts +
  host.ts, unit-locked by tests/e2e-host-protocol.spec.ts):
  - one-time-token browser auth: the launch URL grep extends past the
    `/?token=` query (truncating at `/` loses the token), goto navigates
    the token URL (browser cookie exchange), and stamped navigations
    pre-seed the context cookie via addCookies — the exchange 303 drops
    sibling query params;
  - Remote gateway: dot endpoints first, slash endpoints on 404 fallback,
    with args keyed by the controller parameter name (workspace/create ->
    {request}, session/list -> {_request}; verified on a live host).
- package.json: drop the @deepseek-ai/dsh-client-runtime peer (package
  removed upstream in alpha.1; zero references in the source — the chunk
  externals entry stays and is resolution-tolerant).
- scripts/e2e-mount.sh: fix a latent set -u crash in the npx fallback
  branch ($DSH_CMD followed by a full-width comma parsed as part of the
  variable name).
- CI pin stays at @deepseek-ai/dsh@0.1.1-rc.2 until alpha.1 publishes to
  npm (comment updated); README/AGENTS document the new contracts.
- Version lockstep bumped to 0.17.1.
2026-08-28 04:20:36 +08:00

53 lines
2.3 KiB
TypeScript

/**
* Copy-button / chrome labels for DSH's shared `MarkdownText`, shaped for
* BOTH prop generations the plugin supports:
*
* - 0.1.1-rc.x: optional flat prop `codeLabels` — the renderer reads
* `labels.copyLabel` / `labels.copiedLabel` directly.
* - 0.1.2-alpha.1+: renamed to a REQUIRED `labels` prop with a nested shape
* (`labels.code.copyLabel` + a screen-reader-only `labels.footnotes`
* heading). Passing only the old prop crashes the fence render with
* "Cannot read properties of undefined (reading 'code')" — the exact
* regression the mount lane caught on a real 0.1.2-alpha.1 host.
*
* The union object satisfies both readers, and {@link markdownTextProps}
* passes it under BOTH prop names — each host ignores the one it does not
* know. `footnotes` is left empty (the heading is sr-only; give it a real
* string only if a locale key ever earns its place in all 19 dictionaries).
*/
import type { ComponentProps } from 'react'
import { MarkdownText } from '@deepseek-ai/dsh-client-ui-primitives'
/** The flat copy-button pair the plugin threads through its own props
* (e.g. MermaidMarkdownProps.codeLabels — the chunk contract stays put). */
export interface MarkdownCopyLabels {
copyLabel: string
copiedLabel: string
}
/** The dual-generation chrome labels object (see module doc). */
export interface MarkdownChromeLabels extends MarkdownCopyLabels {
/** 0.1.2-alpha.1+ nested reads. */
code: MarkdownCopyLabels
/** 0.1.2-alpha.1+ sr-only footnotes heading. */
footnotes: string
}
/** Build the dual-shape chrome labels from a flat copy-button pair. */
export function markdownChromeLabels(labels: MarkdownCopyLabels): MarkdownChromeLabels {
return {
copyLabel: labels.copyLabel,
copiedLabel: labels.copiedLabel,
code: { copyLabel: labels.copyLabel, copiedLabel: labels.copiedLabel },
footnotes: '',
}
}
/** MarkdownText props carrying the labels under BOTH prop names. The cast is
* load-bearing: the plugin builds against the 0.1.1-rc.x declaration, where
* `labels` does not exist yet (and vice versa on a 0.1.2-alpha.1+ host). */
export function markdownTextProps(text: string, labels: MarkdownCopyLabels): ComponentProps<typeof MarkdownText> {
const chrome = markdownChromeLabels(labels)
return { text, codeLabels: chrome, labels: chrome } as unknown as ComponentProps<typeof MarkdownText>
}