🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

终端界面插件 xp266/dsh-tui

DeepSeek Harnessv0.1.31
xp26618 天前有提交已提供中文文档扫描:高危

dshtui 是 DeepSeek Harnessdsh的终端界面插件,基于 Ink…

30.5/100
综合分
1
GitHub 星标
116
npm 周下载
—/5
用户评分

数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add @xp266/dshtui
npm 源 · @xp266/dshtui 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]✓
静态安装检查通过
未做真实安装
L4 · 真实安装等级说明 →
数据截至 2026/10/28·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 18 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包@xp266/dshtui @ 0.1.31
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/7 04:10:57

🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

命令参数由运行时变量拼接读写/删除本地文件
查看扫描证据(共 96 处,展示前 67 条)
  • 执行外部命令来自配置/变量
    lib/index.mjs:1339
    execFile(command, args, {
  • 读取本地文件
    lib/index.mjs:1384
    data: new Uint8Array(await readFile(file)),
  • 删除本地文件
    lib/index.mjs:1390
    await rm(file, { force: true }).catch(() => {});
  • 读取本地文件
    lib/index.mjs:5789
    const parsed = JSON.parse(readFileSync(STORE_FILE$1, "utf8"));
  • 写入本地文件
    lib/index.mjs:5800
    mkdirSync(STORE_DIR$1, {
  • 写入本地文件
    lib/index.mjs:5804
    writeFileSync(temporary, JSON.stringify({
  • 写入本地文件
    lib/index.mjs:5808
    renameSync(temporary, STORE_FILE$1);
  • 删除本地文件
    lib/index.mjs:5811
    rmSync(temporary, { force: true });
  • 读取本地文件
    lib/index.mjs:5957
    return stat(logFile).then((stats) => {
  • 写入本地文件
    lib/index.mjs:5959
    return unlink(`${logFile}.1`).catch(() => {}).then(() => rename(logFile, `${logFile}.1`).catch(() => {})).then(() => chmod(logFile, 384).catch(() => {
  • 写入本地文件
    lib/index.mjs:5959
    return unlink(`${logFile}.1`).catch(() => {}).then(() => rename(logFile, `${logFile}.1`).catch(() => {})).then(() => chmod(logFile, 384).catch(() => {
  • 删除本地文件
    lib/index.mjs:5959
    return unlink(`${logFile}.1`).catch(() => {}).then(() => rename(logFile, `${logFile}.1`).catch(() => {})).then(() => chmod(logFile, 384).catch(() => {
  • 写入本地文件
    lib/index.mjs:5974
    rotateIfNeededAsync(logFile, rotation).then(() => appendFile(logFile, line, { mode: 384 })).catch(() => {});
  • 读取本地文件
    lib/index.mjs:6340
    return statSync(path).isFile();
  • 读取本地文件
    lib/index.mjs:7242
    const parsed = JSON.parse(readFileSync(STORE_FILE, "utf8"));
  • 删除本地文件
    lib/index.mjs:7266
    rmSync(temporary, { force: true });
  • 读取本地文件
    lib/index.mjs:7707
    if (JSON.parse(readFileSync(join(current, "package.json"), "utf8")).name === "@deepseek-ai/dsh") return current;
  • 删除本地文件
    lib/index.mjs:9580
    rmSync(temporary, { force: true });
  • 读取本地文件
    bin/dshtui.js:30
    const manifest = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))
  • 读取本地文件
    bin/dshtui.js:60
    return existsSync(join(dir, '.git')) && existsSync(join(dir, 'src'))
  • 读取本地文件
    bin/dshtui.js:72
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    bin/dshtui.js:75
    newest = Math.max(newest, entry.isDirectory() ? newestMtime(path) : statSync(path).mtimeMs)
  • 读取本地文件
    bin/dshtui.js:86
    built = statSync(join(root, 'lib', 'index.mjs')).mtimeMs
  • 读取本地文件
    bin/dshtui.js:101
    if (!existsSync(join(root, 'node_modules'))) {
  • 执行外部命令表达式求值
    bin/dshtui.js:108
    ? spawnSync(['pnpm', 'build'].map(quote).join(' '), { cwd: root, stdio: 'inherit', shell: true })
  • 执行外部命令固定命令
    bin/dshtui.js:109
    : spawnSync('pnpm', ['build'], { cwd: root, stdio: 'inherit' })
  • 执行外部命令表达式求值
    bin/dshtui.js:140
    ? spawnSync(['dsh', ...args].map(quote).join(' '), { stdio: 'inherit', shell: true })
  • 执行外部命令固定命令
    bin/dshtui.js:141
    : spawnSync('dsh', args, { stdio: 'inherit' })
  • 执行外部命令表达式求值
    bin/dshtui.js:146
    ? spawnSync(['dsh', '--version'].map(quote).join(' '), { stdio: 'ignore', shell: true })
  • 执行外部命令固定命令
    bin/dshtui.js:147
    : spawnSync('dsh', ['--version'], { stdio: 'ignore' })
  • 写入本地文件
    bin/dshtui.js:248
    writeFileSync(workspaceFile, content)
  • 读取本地文件
    src/chat/session-list.ts:86
    const info = await stat(location.path)
  • 读取本地文件
    src/contract/upstream.ts:145
    if ((JSON.parse(readFileSync(join(current, 'package.json'), 'utf8')) as { name?: string }).name === '@deepseek-ai/dsh') {
  • 读取本地文件
    src/contract/upstream.ts:162
    const parsed = JSON.parse(readFileSync(path, 'utf8')) as { version?: string }
  • 读取本地文件
    src/contract/upstream.ts:191
    version = (JSON.parse(readFileSync(path, 'utf8')) as { version?: string }).version
  • 读取本地文件
    src/core/delivery.ts:33
    const parsed: unknown = JSON.parse(readFileSync(STORE_FILE, 'utf8'))
  • 写入本地文件
    src/core/delivery.ts:48
    mkdirSync(STORE_DIR, { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/core/delivery.ts:49
    writeFileSync(temporary, JSON.stringify({ version: SCHEMA_VERSION, busyEnter: mode }), { mode: 0o600 })
  • 写入本地文件
    src/core/delivery.ts:50
    renameSync(temporary, STORE_FILE)
  • 删除本地文件
    src/core/delivery.ts:55
    rmSync(temporary, { force: true })
  • 读取本地文件
    src/core/language.ts:39
    const parsed: unknown = JSON.parse(readFileSync(STORE_FILE, 'utf8'))
  • 写入本地文件
    src/core/language.ts:52
    mkdirSync(STORE_DIR, { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/core/language.ts:53
    writeFileSync(temporary, JSON.stringify({ version: SCHEMA_VERSION, language }), { mode: 0o600 })
  • 写入本地文件
    src/core/language.ts:54
    renameSync(temporary, STORE_FILE)
  • 删除本地文件
    src/core/language.ts:59
    rmSync(temporary, { force: true })
  • 读取本地文件
    src/core/paste.ts:93
    return statSync(path).isFile()
  • 读取本地文件
    src/hot-theme.ts:24
    lastSource = readFileSync(themeUrl, 'utf8')
  • 读取本地文件
    src/hot-theme.ts:34
    source = readFileSync(themeUrl, 'utf8')
  • 读取本地文件
    src/log.ts:107
    return stat(logFile)
  • 删除本地文件
    src/log.ts:112
    return unlink(`${logFile}.1`).catch(() => {})
  • 写入本地文件
    src/log.ts:113
    .then(() => rename(logFile, `${logFile}.1`).catch(() => {}))
  • 写入本地文件
    src/log.ts:114
    .then(() => chmod(logFile, 0o600).catch(() => {}))
  • 写入本地文件
    src/log.ts:131
    .then(() => appendFile(logFile, line, { mode: 0o600 }))
  • 写入本地文件
    src/log.ts:143
    mkdirSync(dirname(logFile), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/log.ts:144
    appendFileSync(logFile, line, { mode: 0o600 })
  • 写入本地文件
    src/log.ts:175
    mkdirSync(dirname(logFile), { recursive: true, mode: 0o700 })
  • 读取本地文件
    src/sessions/frames.ts:47
    names = readdirSync(dir)
  • 读取本地文件
    src/sessions/list.ts:167
    return readdirSync(path, { withFileTypes: true }).filter(entry => entry.isDirectory()).map(entry => entry.name)
  • 读取本地文件
    src/sessions/store.ts:80
    const parsed: unknown = JSON.parse(readFileSync(INDEX_FILE, 'utf8'))
  • 写入本地文件
    src/sessions/store.ts:103
    mkdirSync(INDEX_DIR, { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/sessions/store.ts:104
    writeFileSync(temporary, JSON.stringify({ version: SCHEMA_VERSION, entries }), { mode: 0o600 })
  • 写入本地文件
    src/sessions/store.ts:105
    renameSync(temporary, INDEX_FILE)
  • 删除本地文件
    src/sessions/store.ts:110
    rmSync(temporary, { force: true })
  • 执行外部命令来自配置/变量
    src/terminal/clipboard.ts:34
    execFile(command, args, { timeout: EXEC_TIMEOUT_MS, maxBuffer: MAX_CAPTURE_BYTES, encoding: 'buffer' }, (error, stdout) => {
  • 读取本地文件
    src/terminal/clipboard.ts:87
    const data = new Uint8Array(await readFile(file))
  • 删除本地文件
    src/terminal/clipboard.ts:94
    await rm(file, { force: true }).catch(() => {})
  • 读取本地文件
    src/ui/home-logo.ts:132
    const manifest = JSON.parse(readFileSync(path, 'utf8')) as { version?: string }
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-agent-default-model@deepseek-ai/dsh-agent-loop@deepseek-ai/dsh-agent-presets@deepseek-ai/dsh-attachment@deepseek-ai/dsh-credentials@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-settings@deepseek-ai/dsh-tool-todo@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 基于Ink的终端界面

基于 ink 的终端界面插件,用于 DeepSeek Harness

README

由 DeepSeek 最新模型翻译生成
dshtui dshtui 是 DeepSeek Harness(dsh)的终端界面插件,基于 Ink 渲染,opencode的tui风格。它以 bundle 插件形式挂载进 dsh profile,接管整个终端界面:流式对话、可折叠的工具卡片、各类对话框,以及覆盖全部可见表面的插件贡献 API。 本项目作为 deepseek harness 的插件存在。 环境要求 - Node.js ^22.19.0 或 >=24.0.0 - dsh CLI:npm install -g @deepseek-ai/dsh 安装 npm install -g @xp266/dshtui@latest dshtui dshtui 会先确定要启动的 profile(优先 dshtui,否则使用已挂载本包的既有 profile),在其中安装或升级本插件,然后以 dsh --profile <name> 启动。 也可以不用启动器,手动装入任意 profile: dsh plugin --profile <name> add @xp266/dshtui@latest dsh --profile <name> 插件开发 界面的每一个可见表面都是 tui 服务背后的键控贡献注册表。完整的贡献点清单见扩展点指南。 从源码运行或开发 git clone https://github.com/xp266/dsh-tui.git cd dsh-tui pnpm install pnpm build npm install -g . dshtui 许可证 MIT
预览分享卡片长什么样 ↓xp266/dsh-tui
分享 · DeepSeek Harness Hub
xp266/dsh-tui

dshtui 是 DeepSeek Harnessdsh的终端界面插件,基于 Ink…

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部