npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-canvas-tsx-sidebar

v0.7.0

Published

DSH web plugin (dsh-better-sidebar consumer) for the DSH 0.2.0 line: render Qoder Canvas `*.canvas.tsx` reports as a structured page in the right sidebar. Static parse only — no code execution.

Readme

dsh-canvas-tsx-sidebar

简体中文 | Français | Deutsch | Italiano | Русский | Español

Веб-плагин DSH (DeepSeek Harness) — плагин-потребитель dsh-better-sidebar.

Статически разбирает файлы *.canvas.tsx из Qoder Canvas в рабочей области в структурированные страницы и отображает их в правой боковой панели DSH.

Полностью статический конвейер: исходники canvas не выполняются. Без eval, без new Function, без бандлера, без sandbox-iframe. Разбор выполняется на стороне браузера собственным легковесным рекурсивным парсером (ноль зависимостей парсера).

В репозитории также есть Skill: skills/writing-qoder-canvas/, который учит LLM писать этот формат. См. Интеграция Skill.

canvas-tsx-sidebar

Диапазон совместимости: линия DSH 0.2.0 (эта линия) — engines.dsh равен >=0.2.0-rc.1 <0.2.1-0, проверенная база — dsh-client-locale 0.2.0-rc.1, публикация через npm dist-tag dsh-0.2.0. 0.2.0 чисто аддитивен для всех API хоста, которые использует этот плагин (он потребляет только register(ns, locale, dict) / bind(ns) из dsh-client-locale; поверхность клиентских экспортов идентична 0.1.7-rc.2), поэтому линия поддержки целиком сдвигается вперёд — ветка совместимости на уровне рантайма не нужна. Версию плагина выбирайте строго по версии DSH (не используйте latest вслепую на старых хостах: engines старого хоста перестают выполняться, и плагин молча отключается стартовой предпроверкой; caret-диапазоны также не переходят через minor хоста):

| Хост DSH | Последняя версия плагина | dist-tag для установки | |---|---|---| | 0.2.0 | 0.5.0 (latest) | dsh-0.2.0 | | 0.1.7 | 0.4.0 | dsh-0.1.7 | | 0.1.5 | 0.3.2 | dsh-0.1.5 | | 0.1.2 | 0.2.2 | dsh-0.1.2 | | 0.1.1 и ранее | не поддерживается (у линии 0.1.2 нижняя граница — 0.1.2-rc.1) | — |

(по состоянию на 2026-09-30; старые линии обслуживают compat/0.1.7, а также замороженные ветки compat/0.1.5 и archive/release/0.1.2.)


Предварительные требования

  • DSH dsh web нормально запускается
  • Установлен dsh-better-sidebar (>=0.19.1)

Без better-sidebar плагин полностью пассивен: обе регистрации молча пропускаются и не затрагивают остальные функции DSH.

Установка

Способ A (рекомендуется, официальный CLI)

# выбирайте dist-tag по версии хоста DSH (рекомендуется, не используйте latest вслепую)
dsh plugin --profile <profile> add [email protected]   # линия DSH 0.2.0 (0.5.0)
dsh plugin --profile <profile> add [email protected]   # линия DSH 0.1.7 (0.4.0)
dsh plugin --profile <profile> add [email protected]   # линия DSH 0.1.5 (0.3.2)
dsh plugin --profile <profile> add [email protected]   # линия DSH 0.1.2 (0.2.2)
# альтернатива: локальный tarball (эта линия: dsh-canvas-tsx-sidebar-0.5.0.tgz)
dsh plugin --profile <profile> add <dsh-canvas-tsx-sidebar-0.5.0.tgz>

dsh добавляет этот пакет в dsh.profile.bundles; при запуске входящий в пакет cordis.patch.yml вставляет запись загрузчика, и клиентский бандл регистрируется и доставляется согласно entry.name.

Способ B (вручную, альтернативный)

  1. Скопировать пакет в ~/.dsh/profiles/<profile>/node_modules/dsh-canvas-tsx-sidebar (либо добавить "dsh-canvas-tsx-sidebar": "link:<путь-к-плагину>" в dependencies файла package.json профиля);

  2. дописать следующую строку в ~/.dsh/profiles/<profile>/cordis.patch.yml:

    - insert:
        - id: dsh-canvas-tsx-sidebar
          name: dsh-canvas-tsx-sidebar
  3. выполнить pnpm install в каталоге профиля.

⚠️ Выберите способ A или способ B — не регистрируйте дважды.

Активация

  1. Перезапустите dsh web — добавление бандла требует перезагрузки на стороне хоста (hot reload работает только для изменений клиента уже подключённого плагина);
  2. жёсткое обновление страницы в браузере (Ctrl+Shift+R).

Состояние подключения можно перепроверить через pwsh -NoProfile -File ./scripts/mount-check.ps1.

Использование

Две точки входа:

| Точка входа | Как вызывается | Поведение | |---|---|---| | Просмотрщик файлов (перехват) | Открыть любой .tsx в дереве файлов | .canvas.tsx → структурированная страница + переключатель Просмотр/Код; остальные .tsx → просмотр исходника | | Вкладка | меню + правой панели → Отчёт Canvas | ввести путь вручную и посмотреть, не открывая файл в редакторе |

Просмотрщик файлов можно отключить в настройках карточки Side; после отключения такие файлы возвращаются к встроенному просмотрщику кода.

Открытие одного файла рендерит именно этот файл — плагин не сканирует рабочую область.

Почему просмотрщик файлов обязан перехватывать все .tsx

exts: ['tsx'] — единственный работоспособный способ перехвата; цена в том, что перехватываются и .tsx вне canvas. Все доказательства взяты из исходников better-sidebar и практических проверок в экосистеме:

| # | Ограничение | Доказательство | |---|---|---| | L1 | extOf() берёт только последний сегмент расширения → extOf('a.canvas.tsx') === 'tsx' | src/client/paths.ts:80-85 | | L2 | exts: ['tsx'] перехватывает все .tsx рабочей области, а priority 0 перекрывает CodeMirror встроенного code (-100) | service.ts:847-875 | | L3 | detect вызывается только при доступных байтах head, а head приходит только из бинарного fs.read — текстовый .tsx до этой ветки никогда не доходит | service.ts:860 | | L4 | после перехвата дескриптором component обязан отрисоваться, API делегирования/отката нет | EditorHost.tsx:349,486 | | L5 | экосистемный плагин dsh-code-nav уже содержит tsx в своём LANG_EXT и перехватывает с priority: 10 | dsh-code-nav/src/lang-registry.js |

→ Определение .canvas.tsx возможно только внутри собственного компонента. Поэтому: просмотрщик перехватывает все .tsx (canvas идёт на страницу, остальное — на исходник), а вкладка сохранена как второй вход, минующий перехват файлов.

Интеграция Skill: научить LLM писать .canvas.tsx

skills/writing-qoder-canvas/ — самодостаточный, полностью переносимый Skill:

skills/writing-qoder-canvas/
  SKILL.md                      # условия срабатывания, скелет файла, пять железных правил, список красных флагов
  references/components.md      # 38 реально отрисовываемых тегов + prop каждого (машинная проверка)
  references/expressions.md     # замкнутые правила статического парсера: какие значения выживают
  references/layout.md          # писать под боковую панель ~400px (а не под превью 960px)
  examples/status-report.canvas.tsx   # рендеримый образец, тесты гарантируют ноль деградаций

Почему он не лжёт

Документация дрейфует, поэтому каждое утверждение здесь привязано к исходникам (tests/skill.spec.ts):

  • список поддерживаемого в components.md должен поэлементно совпадать с тегами case в render.tsx (38 штук, включая порядок);
  • ни одно имя из списка «не поддерживается» не должно встречаться в рендерере;
  • examples/status-report.canvas.tsx должен отрисовываться без единой деградации — без пометок unsupported, без пунктирных рамок неизвестных компонентов.

Если документация расходится с реальными возможностями, pnpm test падает.

Как установить его в DSH

DSH обнаруживает Skill в фиксированном наборе корней, причём Skill должен лежать ровно на один уровень в глубину: <root>/<name>/SKILL.md. Вложенные **/SKILL.md не находятся (провайдер следит за каждым корнем через chokidar, depth: 1).

| rank | Источник | Путь | |---|---|---| | 100 | project-dsh | <projectRoot>/.dsh/skills | | 200 | project-agents | <projectRoot>/.agents/skills | | 300 | custom | customSkillDirs из конфигурации DSH | | 400 | user-dsh | ~/.dsh/skills | | 500 | user-agents | ~/.agents/skills | | 600 | bundled | $DSH_BUNDLED_SKILL_DIR |

# по умолчанию: установка в ~/.agents/skills через junction (без копий, без дрейфа)
pwsh -NoProfile -File ./scripts/install-skill.ps1

# установка в другое место; -Copy делает настоящую независимую копию (дрейфует, после правок запускать заново)
pwsh -NoProfile -File ./scripts/install-skill.ps1 -Target UserDsh
pwsh -NoProfile -File ./scripts/install-skill.ps1 -Path D:\some\skills -Copy

# удаление
pwsh -NoProfile -File ./scripts/install-skill.ps1 -Uninstall

Провайдер следит за корнями, перезапускать dsh web не нужно: после установки Skill появится в каталоге skill'ов следующей сессии.

По умолчанию junction, а не копия, потому что копии дрейфуют — эта рабочая область уже обжигалась на memport с «тремя копиями, ни одна не синхронна». Junction делает копию в репозитории единственным авторитетным источником.

skills/ не входит в files[] в package.json — это актив репозитория, а не публикуемый npm-артефакт.

Ограничения версий

На [email protected] / 0.19.1 path seed у openTab({ path }) перенаправляется в редактор файлов, и вкладка-компонент не монтируется (upstream #632, исправлено с 0.19.2). Поэтому плагин не полагается на path seed, а сам разрешает целевой файл через /sidebar/api (session.cwd → fs.tree → fs.read) — этот подход одинаково работает и на 0.19.2+.

Скины и темы

Оболочка плагина (вкладки, карточка настроек, кнопки) потребляет только токены --dsw-alias-* от DSH и автоматически следует всем скинам и светлой/тёмной теме.

Поддерево документов canvas — исключение, и намеренное: .canvas.tsx описывает лист с фиксированной вёрсткой, цвета выбирает автор; перекраска по скину изменила бы сам вид отчёта. Поэтому styles.ts использует буквальные значения цветов, и каждый селектор ограничен .dsh-canvas-doc, без протечек в UI хоста (tests/render.spec.tsx сторожит область действия, tests/purity.spec.ts — поверхность регистрации).

Известные ограничения

  • Разбор ведёт легковесный собственный парсер, а не компиляторная точность. Дженерики, декораторы и произвольные вызовы не моделируются и всегда деградируют, но ошибка никогда не бросается.

  • Разбор значений — замкнутый набор правил (подробности в skills/writing-qoder-canvas/references/expressions.md). Поддерживается: литералы, утверждения as const / as T, литеральные const на уровне модуля и в начале тела функции, проекции ARR.map(x => литерал) по статическим массивам, canvasImage('литерал'). Не поддерживается (не вычисляется): условные выражения, вызовы функций, цепочки членов, шаблонная интерполяция, арифметика, new, await, const внутри вложенных блоков, данные из межмодульных import.

    • не-литеральный дочерний узел → отрисовывается как встроенная полоса деградации, исходный фрагмент остаётся видимым;
    • не-литеральное свойство → свойство отбрасывается, имя попадает в unresolved IR, остальные свойства отрисовываются как обычно.
  • Теги в нижнем регистре всегда прозрачно проходят как нативный HTML; только заглавные и не отображённые компоненты рисуются пунктирной рамкой с именем.

  • Вкладки отрисовываются только для чтения.

  • Парсер терпимее компилятора: Qoder SDK требует, чтобы авторы правили диагностику через «Canvas TypeScript check» в IDE, но реальные файлы не всегда чисты. На нелегальном TSX этот плагин не падает и не прерывается, деградирует только проблемный узел. Авторитетную диагностику можно посмотреть через node scripts/syntax-oracle.cjs <file.canvas.tsx>.

    Проверено на практике: строка 46 входящего в репозиторий образца cmp-cloud-sdk-report.canvas.tsx, {'created': ...}, — нелегальный TSX (TypeScript выдаёт TS1005 + TS1381 — «голый» оператор разворота). Плагин деградирует это место во встроенную пометку, остальные 147 строк рендерит как обычно.

Семантика пробелов в JSX

Текстовые дочерние узлы сворачиваются строго по семантике cleanJSXElementLiteralChild из React:

  • ведущий отступ на всех строках, кроме первой, безусловно срезается;
  • концевые пробелы последней строки сохраняются — этот пробел несущий: он отделяет текст от идущего следом контейнера выражения (пример: пробел в …сложение (0 + {'created': ...})…; уберите его — и два куска слипнутся).

Разработка

pnpm install
pnpm typecheck     # tsc (включая проверку «ноль зависимостей от Node» в клиентской части)
pnpm test          # vitest
pnpm build         # tsc dts + tsdown (хостовая половина + клиентский бандл)
pnpm run audit:bundle   # аудит реальных артефактов сборки

Скрипты разработки

| Скрипт | Назначение | |---|---| | scripts/dump-ir.ts | Экспорт IR-структуры / JSON / эталонных фикстур файла (--write) | | scripts/syntax-oracle.cjs | Определяет настоящим компилятором TypeScript, является ли исходник корректным TSX (typescript остаётся devDependency и в бандл не попадает) | | scripts/audit-bundle.cjs | Аудит реальных артефактов сборки: утечки встроенных модулей, повторные парсеры, eval, регистрации вне зоны ответственности | | scripts/mount-check.ps1 | Проверка/исправление подключения профиля (чистый ASCII, совместим с Windows PowerShell 5.1) | | scripts/install-skill.ps1 | Устанавливает skills/writing-qoder-canvas в корень skill'ов DSH (по умолчанию junction) | | scripts/component-census.cjs | Автономная перепись компонентов (без жёстко зашитой таблицы компонентов, с учётом многострочности) | | scripts/corpus-stats.ts / format-economics.ts / audit-corpus.ts / corpus-gaps.ts | Статистика корпуса и практические замеры экономики формата (источник цифр для docs/canvas-format-rules.md) |