Skip to content
dsh.fish
Bundle

dsh-callout

GitHub-style alerts (> [!TIP] …) rendered as callout cards in the DeepSeek Harness (DSH) Web UI

Source
Aafff623
License
MIT
Updated
Updated 6 hours ago

Readme

<p align="right">
  <strong>English</strong> · <a href="./README.zh-CN.md">简体中文</a>
</p>

<p align="center">
  <img src="./assets/readme/hero-pixel-1.png" width="100%" alt="dsh-callout pixel-art sentinel turning DSH assistant Markdown alert markers into semantic cards.">
</p>

<p align="center">
  <a href="https://github.com/Aafff623/dsh-callout/actions/workflows/ci.yml"><img src="https://github.com/Aafff623/dsh-callout/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
  <a href="https://github.com/Aafff623/dsh-callout"><img src="https://img.shields.io/github/stars/Aafff623/dsh-callout?style=flat&color=238636" alt="GitHub stars"></a>
  <a href="https://github.com/Aafff623/dsh-callout/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Aafff623/dsh-callout?style=flat&color=58a6ff" alt="MIT license"></a>
  <a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DSH-0.1.2--rc.1-8957e5?style=flat" alt="Tested with DSH 0.1.2-rc.1"></a>
</p>

# dsh-callout

GitHub-style alert cards for [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) assistant Markdown. It turns a qualifying `> [!NOTE]` blockquote into a compact, theme-aware card without changing stored session content or DSH's core renderer.

## See it first

```markdown
> [!WARNING]
> This operation may overwrite existing configuration.
```

Install the plugin, refresh DSH Web, then send that assistant Markdown. A qualifying leading marker becomes a warning card; malformed or unknown markers remain ordinary text.

## Why this plugin exists

A warning should look like a warning before the reader reaches the command. A key decision should be easy to find without wrapping the entire answer in a colored box.

`dsh-callout` keeps the source format readable Markdown and upgrades it only at presentation time:

```text
assistant Markdown → DSH MarkdownText → ordinary blockquote → callout card
```

It does not modify stored session content, providers, permissions, tools, or the DSH core renderer.

## Supported types

| Type | Use it for | Accent |
|---|---|---|
| `NOTE` | Premises, environment facts, and boundaries | Blue |
| `TIP` | A better or less obvious approach | Green |
| `IMPORTANT` | A decision or key conclusion | Purple |
| `WARNING` | Potential loss or destructive operations | Amber |
| `CAUTION` | High-impact or difficult-to-reverse operations | Red |

## Visual map

The two diagrams below keep the proof close to the implementation: the type palette shows the supported semantic cards, and the flow shows the guarded DOM upgrade path.

<p align="center">
  <img src="./assets/readme/callout-types.svg" width="100%" alt="Five dsh-callout semantic card types: note, tip, important, warning, and caution.">
</p>

<p align="center">
  <img src="./assets/readme/callout-flow.svg" width="100%" alt="Assistant Markdown flows through DSH MarkdownText, a guarded first plain-text marker match, and a theme-aware callout card; unsupported shapes fail open as ordinary text.">
</p>

## Install

No settings. After install, the host half injects the authoring contract into the system prompt, and the browser half upgrades qualifying assistant Markdown.

### From GitHub

```powershell
dsh plugin --profile web add github:Aafff623/dsh-callout
```

Then hard-refresh the Web UI (`Ctrl+Shift+R`). `dsh.bundle.patch` inserts the plugin into the profile bundle.

`lib/` is committed, so a git install needs no local build.

### npm

Not published yet. `dsh plugin --profile web add dsh-callout` works only after the package is on the registry you use.

## Canonical syntax

Use one of these two forms:

```markdown
> [!NOTE]
> Body text on the next line.
```

```markdown
> [!NOTE] Body text on the same line.
```

The marker must be the first content of the blockquote. Every physical line in a multiline callout starts with `>`.

These are not canonical callouts:

```text
[!NOTE] Body without the `>` marker.
```

```text
Intro text > [!NOTE] > body squeezed onto one line.
```

Malformed or unknown markers fail open as ordinary text. The plugin does not attempt to turn every occurrence of `[!NOTE]` into a card.

## What is guaranteed

- Five fixed types, case-insensitive.
- Code, inline code, emphasis, links, lists, nested quotes, and later paragraphs do not activate the blockquote transform.
- The marker is removed only from a qualifying leading text node; the body node is retained.
- The observer-echo path is idempotent: the plugin's own text mutation is not mistaken for an edit.
- Real edits can remove plugin-owned card chrome and restore the source marker when it is still safe to do so.
- Light/dark palette rules follow DSH's `body[data-ds-dark-theme]` switch.

## What this plugin does not do

- Human messages are rendered by DSH as plain text and are intentionally outside this plugin's scope.
- It is not a Markdown parser replacement and does not add new Markdown AST node types.
- It does not guarantee source-level distinction between a real marker and a backslash-escaped marker after Markdown parsing.
- The plugin uses the current DSH Web DOM contract; a future renderer change should be checked with the regression suite and a browser smoke test.

## Architecture

| Layer | File | Responsibility |
|---|---|---|
| Host | `src/index.ts` | Injects the concise output contract into the system prompt |
| Bundle | `cordis.patch.yml` | Registers the plugin entry in the DSH bundle |
| Browser | `src/client/index.ts` | Matches rendered DOM, applies card attributes/CSS, observes streaming updates, and owns teardown |
| Verification | `test/callout.test.mjs` | Tests GFM shapes, negative cases, and the observer state machine |

Both halves build into `lib/` with esbuild. The browser half is deliberately presentation-only. It uses plugin-owned `data-md-alert-*` attributes and `--dsh-callout-*` variables, and registers cleanup with Cordis `ctx.effect()`.

## Development

```powershell
npm install
npm run typecheck   # tsc --noEmit
npm run build       # esbuild → lib/index.js + lib/client.js (ModuleLoader-wrapped)
npm test            # node:test, vm-isolated suite against the built bundle
```

`lib/` is committed on purpose: a git install works with zero build step. If you change `src/`, run `npm run build` and commit the refreshed `lib/` together — CI fails on drift.

The test suite currently covers 30 cases, including:

- standard one-line and multiline forms;
- all five types, lowercase types, CRLF, and CJK text;
- unknown/glued markers, code, emphasis, links, lists, nested quotes, and indented/fenced code;
- bare assistant-Markdown paragraph fallback;
- first upgrade, observer echo, real-edit cleanup, and node-removal release;
- incremental dirty-root hits, unrelated mutations that must not clear a card, and a rebuilt parent paragraph.

For a quick visual check, open [`demo-before-after.html`](./demo-before-after.html). The diagrams in this README are deterministic implementation maps, not screenshots of a running session.

## Compatibility and maintenance

| Plugin | DSH baseline | Status |
|---|---|---|
| `0.2.x` | `0.1.2-rc.1` | Tested |

After a DSH upgrade, run `npm test`, then smoke-test one standard callout, one code example, one theme switch, and one session switch. If the renderer, Markdown root class, client loader, or chat-flow attributes change, review `src/client/index.ts` before upgrading the plugin version.

## License

MIT — see [`LICENSE`](./LICENSE).

Install

dsh plugin --profile web add github:Aafff623/dsh-callout

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source