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

hiwork-core

v0.0.30

Published

HiWork 企业统一登录与模型自动供给插件(ai-router 网关登录,Web 表单,无 CLI 认证)

Readme

hiwork-core

HiWork 的企业统一登录与模型自动供给插件,基于 DeepSeek Harness(DSH)插件机制实现,随 HiWork 桌面端打包分发。

员工在登录页用企业 LDAP 账号登录企业 AI 网关(ai-router),插件自动拉取该账号绑定的虚拟 Key 与预算内模型,写入凭据库与 llm-pi-ai 配置 —— Models 页即刻出现该员工可用的模型,请求经网关统一计费。全程零手动模型配置,登录面为 Web 表单(无 CLI 认证)。

架构一瞥

login gate / settings card(client)──credentials.set / settings.mutate──▶ Host onChange(server)
      ▶ POST /api/admin/auth/login → GET /api/me/keys + GET /api/me/key?key_id=
      ▶ 写 AI_ROUTER_API_KEY + session 凭据,写 llm-pi-ai.providers.<协议路由>
      ▶ pi-ai 热重载 → Models 页出现模型 → 请求走网关

复用 @deepseek-ai/dsh-llm-pi-ai 的手工路由,不新写 LLM 适配器。

多协议路由(协议随模型走)

网关按「入站协议 + 模型」匹配模型映射(GET /api/me/keymodel_mapping),而 pi-ai 的 api路由级的 —— 因此插件把预算内模型按协议拆到路由,每路由一个协议、baseURL 按协议取对。路由在模型选择器里的分组标题用「线路C/M/R」,后缀即该路由讲的协议首字母:

| 路由 | 展示名 | 协议 | baseURL 后缀 | 说明 | |---|---|---|---|---| | providers.ai-router-chat | 线路C | openai-completions | …/v1(SDK 追加 /chat/completions) | chat/completions,兜底协议 | | providers.ai-router-anthropic | 线路M | anthropic-messages | 裸 base | Anthropic SDK 自带 v1/ 前缀 | | providers.ai-router | 线路R | openai-responses | …/v1(SDK 追加 /responses) | key 与协议保持不变,兼容 agent-default-model: provider: ai-router |

  • 归属规则:精确 EqualFold 优先、*/? 通配(裸 * 兜底不参与归属);模型进入每一条映射命中的线路 —— 按协议分组、不做唯一归属,同一模型可以同时出现在多条线路里(例如同时声明 responses 与 anthropic 映射的模型,线路R 和线路M 都列出它),从哪条线路选它,请求就走那条线路的协议;无任何映射命中的模型落兜底线路C(网关的裸 * 兜底映射通常声明在 chat/completions 下,用 responses 入站反而匹配不到映射)。
  • 好处:DSH 里切换模型自动落到对应协议的路由;responses 系模型经 https://aigateway.hivery.cn/v1/responses;anthropic 系(如 k3/k3-256k/kimi-for-coding)不再 404(/v1/v1/messages)也不用手动整路切协议;只声明 chat/completions 映射的模型落线路C,不再被塞进 responses 入站。
  • 空线路不写入 profile(写入侧同时清掉该路由,旧版独立的 ai-router-responses 路由也会被清理)。
  • 官方 DeepSeek 提供方在本 bundle 内停用cordis.patch.yml- id: llm-deepseek + disabled: true 关掉 deepseek-official。官方适配器讲 DeepSeek 私有协议(请求体带 thinking、响应读 reasoning_content、图片走 Files API),网关只实现 OpenAI/Anthropic 兼容协议,改 baseURL 也对接不上,留着只会让模型选择器多出一个必然失败的分组。需要保留官方的部署,在 profile 的 cordis.patch.yml 里写同 id + disabled: false 覆盖(profile 层优先级高于 bundle 层)。
  • 官方 web 搜索同样停用web-search-deepseek 也走 DEEPSEEK_API_KEY(企业用户没有),故 - id: web-search-deepseek + disabled: true 停用提供方(设置页「Web 搜索」卡片随命名空间消失),并把 tool-websearch 关掉,只保留不依赖凭据的 web_fetch
  • 默认模型校正agent-default-model 的组合默认值指向官方提供方(deepseek-official/deepseek-v4-flash)。供给成功后(登录/刷新)校正一次:当前选择仍可路由(本插件线路内查表,或其它已注册提供方 + 模型仍在列)就保持不变,否则落到兜底线路C 的第一个模型,避免新会话第一次请求就 UNKNOWN_MODEL。只写用户层、不写 composition,用户自己选的模型只要仍可用就不会被覆盖。

登录门禁

  • 打开即检测登录(硬门禁):页面加载后检测登录状态,未登录时全屏登录窗覆盖整个应用(不可交互、不可聚焦,防隐私泄漏),登录成功才放行;不可跳过。
  • 登录页为 HiWork 品牌视觉:左侧品牌标语「智联万物,从智联工作开始。」,右侧企业账号登录卡。
  • 网关地址固定为 https://aigateway.hivery.cn(无需、也不提供用户填写)。
  • 设置页「AI Router 网关」为一级 tab,可刷新模型 / 退出登录。
  • 多虚拟 KEY 支持:一个账号绑定多把虚拟 Key 时,已登录页显示 KEY 选择器(掩码明文 + 团队名),切换后自动按新 Key 重拉额度与模型。
  • 已下架模型自动隐藏:网关 /api/me/keymodel_statusinactive(目录已下架、不可调用)时,插件直接隐藏该模型——额度展示列表与 Models 页可用模型均不含它;重新上架后下次刷新自动恢复。旧网关缺省该字段,行为不变。

分发与开发

本插件为 HiWork 内部项目,随桌面端离线打包,版本在 hiwork-desktop/src/bundled-plugins.tsBUNDLED_PLUGINS 中锁定;scripts/publish-to-desktop.mjs 负责把构建产物同步进桌面端离线仓库。

要求 Node.js 22+ 与 pnpm:

pnpm install
pnpm build       # host(tsc + host-build)+ client(tsc + esbuild 单文件 bundle)
pnpm test        # vitest

客户端 bundle 由 scripts/client-build.mjs 用 esbuild 打成单文件:@deepseek-ai/* 与 react 走宿主模块表 external,品牌图片内联为 data URL。

Feature Center(扩展注册面)

hiwork-core 的 client 半边提供 cordis 服务 hiworkFeatureCenter,把左侧 HiWork 菜单与中央内容区做成可复用机制:业务插件(hiwork-automation、未来的 hiwork-knowledge)只注册一个 feature,即可出现在菜单里并在中央区独立渲染, 不需要再碰侧栏 DOM 或中央区状态机。

interface HiWorkFeature {
  readonly id: string                        // 稳定 id,同时写入 data-hiwork-active-page
  readonly label: () => string               // 函数形式,跟随语言切换
  readonly icon?: string                     // 内联 SVG 字符串
  readonly order?: number                    // 缺省 1000,按 order → id 稳定排序
  readonly render: (context: FeatureRenderContext) => React.ReactNode
}
interface FeatureRenderContext {
  readonly openNativeSession: (sessionId: string) => void  // 先退出 takeover,再交给宿主
  readonly openNativeHome: () => void
}
interface HiWorkCoreClientFace {
  readonly featureRegistry: FeatureRegistry  // register / list / activeId / open / openNative / subscribe
  readonly openFeature: (id: string) => boolean
  readonly openNativeSession: (sessionId: string) => void
  readonly openNativeHome: () => void
}

业务插件按服务名发现本面( runtime-import 本包的值):

ctx.inject(['hiworkFeatureCenter'], (scope) => {
  const face = scope.get('hiworkFeatureCenter') as HiWorkCoreClientFace
  ctx.effect(() => face.featureRegistry.register({
    id: 'knowledge',
    label: () => '知识库',
    order: 30,
    render: (context) => React.createElement(KnowledgeView, { openSession: context.openNativeSession }),
  }), 'hiwork-knowledge: feature center')
})

机制要点(实现见 src/client/feature-registry.tssrc/client/feature-center.ts):

  • 侧栏菜单注入:隐藏原生「新会话」按钮(保留 DOM 与 click handler,只加隐藏属性), 在同位置插入 HiWork 菜单;首项「新会话」直接代理原生按钮(图标克隆原生按钮的 SVG), 其余项按 order 排序。icon 是内联 SVG 字符串;缺省用兜底图标,保证侧栏折叠成 56px 图标栏时每个入口仍有可辨识图形(折叠态由宿主加在侧栏根上的 *_collapsed 类驱动纯 CSS:隐藏文字、图标放大到 18px,与原生控件同形)。 折叠态悬停 500ms 弹出提示气泡,黑底白字、圆角与字号逐项对齐框架 ui-primitivesTooltip--dsw-alias-tooltip-bg),取代浏览器自带的浅色 title 提示; 展开态文字已可见,与原生控件一致(Tooltip disabled={wide})不出气泡。 找不到原生按钮时不抛错、不隐藏任何入口,菜单只列 feature(安全降级)。
  • 中央区 takeover:挂一个 [data-hiwork-feature-root] React root,用 html[data-hiwork-active-page] 上的纯 CSS 规则隐藏原生会话子树(保持挂载、保留状态); 点击任意原生会话行或调用 openNativeSession 时,先卸载 root、移除属性恢复原生内容, 再交给宿主。切换 feature 先卸载旧 root,任意时刻只有一个业务页面。 takeover root 自带 background: var(--dsw-alias-bg-base)——与原生会话根同一个主题变量, 否则会透出框架灰底、与侧栏同色而不是原生页面的底色。
  • 自愈与清理MutationObserver + 有界重试处理延迟挂载、语言切换与壳重建; render 抛错由错误边界捕获并恢复原生会话区;注入节点带实例令牌,HMR/重复 apply 不会出现两份菜单,旧实例的 dispose 也不会删掉新实例的节点。
  • Host 纯度:全部 DOM 逻辑只在 src/client/**,Host build 不引用 document

目录结构

  • src/index.ts:宿主入口,登录编排、凭据写入与依赖接口。
  • src/client/feature-registry.ts:扩展注册表(排序、校验、活动页)。
  • src/client/feature-center.ts:侧栏菜单注入 + 中央区 takeover。
  • src/client/contracts.ts:业务插件可见的 client 面与服务名。
  • src/orchestration.ts:登录后模型供给编排(拉 Key、写路由、热重载)。
  • src/office-credentials.ts:OnlyOffice 集成凭据的 host 侧服务 (hiworkOfficeCredentials)——hiwork-office 按登录态经它取 Document Server 地址与共享 JWT 密钥(网关 GET /api/me/office-config),终端零配置;网关会话 cookie 不出 Host。
  • src/office-relay.ts:文档中继的 host 侧服务(hiworkOfficeRelay)—— 跨 NAT 的在线编辑:插件把文档暂存到 DS 能访问的服务器侧(上传/轮询/取回/关闭), 用户侧不再需要入向可达性;同样只在 Host 持 cookie、失败用稳定信封。
  • src/identity.ts:当前登录身份的只读 host 服务(hiworkIdentity)—— 业务插件(hiwork-memory 的记忆隔离键等)经 ctx.get('hiworkIdentity'){ loggedIn, subject, username, displayName, employeeName, teamName }subject 是 账号名的 sha256 前 16 位(u_ 前缀,不含账号原文),未登录回 { loggedIn: false }
  • src/memory-config.ts:记忆系统配置下发的只读 host 服务(hiworkMemory)—— hiwork-memory 经 ctx.get('hiworkMemory').config() 取网关下发的 panelUrl / serviceId / teamIds / apiKey(网关 GET /api/me/memory-config;snake_case → camelCase 的转换只在 Host 做), 成功结果 5 分钟内存缓存、force 可绕过;凭据只在内存里活、不落盘、不进日志。
  • src/default-model.ts:供给成功后校正 agent-default-model(默认模型落点)。
  • src/client/login-gate.tsx:全屏登录门禁页。
  • src/client/section.tsx:设置页「AI Router 网关」卡片。
  • src/client/user-badge.tsx:已登录身份与 KEY 选择器。