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

@qzsy/dsh-yunxiao-panel

v1.4.1

Published

Yunxiao (阿里云云效) panel for the DeepSeek Harness Web client: a cross-project workbench with charts, project/repository navigation, Projex work items, Codeup commits and merge requests.

Readme

@qzsy/dsh-yunxiao-panel

A DeepSeek Harness Web panel for 阿里云云效. The left column starts with 我的工作台 (a cross-project workbench with charts), then a switchable 项目 / 仓库 list; a project opens its Projex work items (缺陷 / 需求 / 任务) and a repository chip row for its merge requests.

What it does

  • Two left-menu list modes — 项目 and 仓库 — switched by a segmented control at the top of the navigation. The selected mode is remembered per browser.
    • 项目: flat project list with customCode and mapped repository count.
    • 仓库: flat repository list; the second line shows pathWithNamespace plus its project. Selecting a repository opens its project with that repository active for merge requests; an unbound repository opens its own repository page instead.
    • Every row leads with its icon: the project's Projex icon (also used for a repository without its own avatarUrl). Yunxiao serves those images behind a session, so when the browser cannot load one the row falls back to a deterministic two-letter monogram tile tinted with a theme color.
  • Mixed Chinese/English quick search on both lists, powered by the vendored text-search-engine (MIT, dynamic-programming fuzzy match): full pinyin (qunxing), pinyin initials (qxkj), project codes (QXERP), and mixed forms all match, and the hit ranges are highlighted in the rows.
  • 我的工作台 — a cross-project workbench with two scopes, switched at the top and remembered per browser:
    • 我的 aggregates the work items assigned to the token's user; 组织 drops that filter and covers every open item in the organization (up to 400, open ones first), so an organization manager can triage work unrelated to them.
    • a hero card with a status ring (completion in the middle), a plain-language summary, and a 优先处理 row that picks the most urgent open item (bugs first) and opens it in one click,
    • four clickable KPI cards (全部工作项 / 未完成 / 缺陷 / 待评审), then status, project, type and trend charts whose bars, slices and legends filter the list; organization scope adds a 按负责人 chart,
    • a scrollable work-item list (serial, project code + Chinese project name, assignee in organization scope, type, status, relative time) with removable filter chips; rows open the detail pane,
    • a 列表 / 看板 switch: the board groups the filtered items into one column per status (ordered by workflow stage, empty columns still shown), and dragging a card onto another column changes its status through the same workflow lookup the detail pane uses — on touch screens a column becomes a full-width swipe page and a tap opens the detail pane instead,
    • merge requests waiting for review (all open ones in organization scope), with a direct link to Yunxiao when the list is empty.
  • Detail sheet — opening a work item slides in a right-hand sheet (up to 820 px wide, always on top of a dimmed panel) so descriptions, images, comments and the footer actions get room; Esc, the close button or a click on the dimmed area dismisses it, and it stays full-width on phones.
  • Change status from the detail pane — the pane shows the current status, a dropdown of the whole workflow for that work item type, and a 标记完成 button that picks the type's own done status (缺陷 → 已修复, 需求 → 已完成, else 已关闭). The item is repainted in the detail, every project list and the workbench (including its status chart) before the request returns, and a failure rolls every snapshot back.
  • 在对话中处理 opens a workspace picker first: it lists the local DSH workspaces (suggesting the one whose name matches the repository or project), remembers the choice per Yunxiao project, and shows it on the button so the next handoff is a single click with a 切换 action beside it.
  • Repository page — clicking any repository (in the repository list or under 未绑定的仓库) opens its own page with four tabs: 概览 / 提交 / 工作项 / 合并请求.
    • 概览 shows the repository icon, description, default branch, visibility, last activity and creation date, a 贡献者 avatar stack (from the recent commit authors, avatars resolved through repository members, monogram fallback), a 克隆仓库 card with ready-to-copy git clone commands for both SSH and HTTPS, plus the root README rendered as Markdown: headings, lists, quotes, code, tables, strikethrough, nested badge images, and images from absolute URLs, relative paths, or embedded HTML <img> tags (relative paths go through the Host file proxy so private repositories render without a Yunxiao session).
    • 提交 lists the latest 30 commits of the default branch with author avatar, title, short SHA and relative time; each row opens the commit in Yunxiao.
    • 工作项 uses the bound project; an unbound repository explains that a project is required and offers 绑定项目 in both the empty state and the header. Binding from that page keeps you there and loads the work items in place.
    • 合并请求 works without a project, scoped to the repository.
  • Project view — the project's Projex work items plus a repository picker that scopes the merge-request tab. Repository chips and filter chips share one active style (brand-tinted fill + brand border), and the tab switch is a segmented control with a sliding thumb and the loaded-item count on each side. The 绑定仓库 action in the project header binds unbound repositories to the project (useful when repositories live in the shared root code group instead of a project-named group).
  • Project identification per repository. The repository's Codeup namespace path (for example QXERP) is matched against the Projex project customCode; unmatched repositories are collected under 未绑定的仓库 and can be bound manually. Bindings are kept in browser local storage as repoId → projectId.
  • Issues = the project's Projex work items, filtered by category (缺陷 / 需求 / 任务), with a title filter and paging.
  • Pull requests = the selected repository's Codeup change requests, filtered by state (进行中 / 已合并 / 已关闭).
  • Detail pane for a work item (description, comments, status, assignee) or a merge request (branches, author, reviewers, description, conflicts). Descriptions and comments may be plain Markdown, raw HTML, or Yunxiao's rich payload {"htmlValue": "...", "jsonMLValue": ["root", ...]}; all three are rendered through an allow-list sanitizer (scripts, styles, iframes, event handlers and inline styles are dropped), with inline images lazy loaded and clickable. Images embedded in a work item use the web-only workitem/file/url?fileIdentifier=… URL, so they are rewritten to /api/yunxiao/workitem-image: the Host resolves the identifier through the Projex API to a signed OSS URL and serves real image bytes, avoiding both the browser-session requirement and the attachment download that breaks <img>.
  • 转为 Issue on a work item opens a prefilled form (type, title, Markdown description quoting the source, assignee from project members) and creates a new Projex work item in the owning project. A Yunxiao "issue" is a project work item — Codeup has no repository-level issue API.
  • 在对话中处理 puts a structured context block into a new session draft through ctx.uiWorkspace.startSession; nothing is sent automatically.
  • Registered as a sidebar.panellist entry with id=yunxiao, order=25 — right below the command palette — and as the main panel keyed yunxiao.

Mobile

The panel is usable down to phone widths (≤ 760 px):

  • the left menu becomes a drawer behind a hamburger button in a compact top bar; it slides in with a scrim and closes on navigation, scrim click or Escape;
  • workbench KPIs collapse to two columns and the charts stack vertically;
  • the kanban board becomes one swipeable column per screen with snap scrolling;
  • unbound repositories render as a single-column card list;
  • the work-item detail pane becomes a full-width overlay with its own close button, and dialogs use the full width with a scrollable body;
  • filter rows wrap, the keyword input takes the full width, and wide Markdown tables scroll horizontally instead of overflowing the card.

Search engine

The browser module table only resolves React and client-plugin rows, so a plain JS plugin cannot require('text-search-engine'). The package's MIT browser IIFE is vendored at vendor/text-search-engine.min.js and injected into the factory scope of client.js by scripts/sync-vendor-engine.mjs (node scripts/sync-vendor-engine.mjs after updating the vendor file). The license is kept at vendor/text-search-engine.LICENSE.

Caching

The client runs a vendored @tanstack/react-query v5 (MIT) client shared by the whole page, so data survives view switches and stale data renders immediately while it revalidates in the background.

| Data | Query key | staleTime | gcTime | |---|---|---|---| | bootstrap (repos / namespaces / projects) | ['bootstrap'] | 30s | 10min | | workbench aggregation (per scope) | ['workbench', scope] | 30s (+90s poll while visible) | 10min | | work items page | ['workitems', spaceId, category] | 30s | 10min | | merge requests page | ['prs', repoId, state] | 30s | 10min | | one work item | ['workitem', id] | 15s | 10min | | workflow statuses | ['workflow', spaceId, typeId] | 10min | 10min | | repository detail / activity | ['repo-detail' | 'repo-activity', …] | 2min | 10min | | DSH workspaces | ['workspaces'] | 60s | 10min | | types / members / me | ['workitem-types' | 'members' | 'me', …] | 5min | 10min |

  • Window focus and reconnect revalidate stale queries (refetchOnWindowFocus).
  • 刷新 clears the Host cache, drops the localStorage snapshot, resets every query, and tells other open tabs to refresh too.
  • A status write paints the new status into the detail, every project list and the workbench immediately, broadcasts it to other tabs, and rolls back on failure.
  • The Host keeps its own short-lived cache and overlays recent status writes on stale search results for 3 minutes, so a list refetched right after a write cannot resurrect the old status.
  • localStorage persistence: 700ms after the cache changes, the freshest successful queries are snapshotted under dsh.yunxiao.queryCache.v2 (2 MB cap, largest entries skipped, failures clear the snapshot). Snapshots older than 24 hours are discarded on load; the v1 key is removed automatically. Hydrated data keeps its original updatedAt, so the first paint after a reload is instant and a background revalidation follows when the data is stale.
  • The bundle is generated by scripts/sync-vendor-query.mjs from vendor/react-query.min.cjs (React stays external and resolves through the host module table); the license is kept at vendor/react-query.LICENSE.

Data path

The browser never receives the personal access token. The Host half registers a loopback-only same-origin facade at /api/yunxiao:

| Route | Purpose | |---|---| | GET /bootstrap | repositories (all pages), namespaces, projects, connection state | | GET /repos?page&search | one page of repositories | | GET /workbench?scope=mine\|org | cross-project aggregation: items, stats, reviews per scope | | GET /repo-detail?id | repository detail + decoded root README | | GET /repo-activity?id&ref | recent commits + contributors (avatars) | | GET /file?repoId&ref&path | raw file bytes (README images, relative links) | | GET /workitem-image?workitemId&fileId | bytes for images embedded in a work item | | GET /workitems?spaceId&category&page | projex .../workitems:search | | GET /workitem?id | one work item plus its comments | | GET /workitem-types?spaceId&category | work item types of a project | | GET /members?spaceId | project members for the assignee picker | | GET /me | the user behind the personal access token | | POST /workitems | create a work item (ProjexCreateWorkitem) | | GET /workflow?spaceId&typeId | workflow statuses of a work item type | | POST /workitem-status | move a work item to another status (PUT /workitems/{id}) | | GET /workspaces | local DSH workspaces for the chat handoff picker | | GET /prs?repoId&state&page | codeup .../changeRequests | | GET /status | token / organization presence | | POST /refresh | drop the short-lived cache |

Credentials resolve from the process environment first, then (Windows) from the persisted user and machine environment:

  • ALIBABA_CLOUD_YUNXIAO_ACCESS_TOKEN (required)
  • ALIBABA_CLOUD_YUNXIAO_ORGANIZATION_ID (center version)
  • ALIBABA_CLOUD_YUNXIAO_API_BASE_URL (region version; used instead of the organization id)

The center-version endpoint defaults to https://openapi-rdc.aliyuncs.com. The token is attached as x-yunxiao-token on the request from the Host; it is never returned by any route.

Install

Published on npm as @qzsy/dsh-yunxiao-panel. Install it from the Harness Plugin Manager by package name, or during development install this directory with plugin_manager install_bundle (absolute package directory).

Each person needs their own Yunxiao personal access token in the environment (see Data path); the panel never ships a credential. The token needs Codeup read access and Projex read/write access (to change status and create work items). After installation and setting the environment variables, restart the Harness and reload the Web page; the 云效 icon appears in the left rail between the command palette and the Git entry.

Project↔repository bindings, the remembered chat workspace and the workbench scope live in the browser's local storage, so each teammate binds and picks once per browser.

Test

The browser half has a jsdom render test that mounts the real component against a mocked facade and exercises repository switching, the unbound-project state, the work-item list and detail pane, status changes (including the list repaint), the chat handoff with its workspace picker and remembered choice, the workbench scopes, and the merge-request tab.

npm install --no-save react@18 react-dom@18 jsdom@24
node test/render-test.mjs

Security notes

  • The facade answers requests whose socket address is loopback only. The panel is a local tool; it does not widen the Host's reach to a network.
  • Short-lived caches: repositories 45s, work items 20s, merge requests 20s.