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

Overleaf 工作区 chenqaq123/dsh-overleaf-workshop

DeepSeek Harness
chenqaq1237 天前有提交已提供中文文档扫描:含敏感能力

在编辑器内直接编辑 Overleaf 项目并实时双向同步

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add chenqaq123/dsh-overleaf-workshop
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · tool
装得上吗
实装验证未通过(runtime_smoke_failed),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 7 天前
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(runtime_smoke_failed · 2026/10/28) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 109 处,展示前 75 条)
  • 写入本地文件
    index.js:144
    if (firstOpen) mkdirSync(dir, { recursive: true, mode: 0o755 });
  • 删除本地文件
    index.js:163
    rmSync(join(dir, '.overleaf', 'state.json'), { force: true });
  • 读取本地文件
    scripts/profile.mjs:30
    const cli = candidates.find(path => existsSync(path)
  • 读取本地文件
    scripts/profile.mjs:31
    && (lstatSync(path).isFile() || lstatSync(path).isSymbolicLink()));
  • 执行外部命令来自配置/变量
    scripts/profile.mjs:37
    return spawnSync(command, args, {
  • 读取本地文件
    scripts/profile.mjs:47
    return lstatSync(join(base, 'profiles', profile, 'node_modules', packageName)).isSymbolicLink();
  • 写入本地文件
    scripts/profile.mjs:56
    mkdirSync(destination, { recursive: true, mode: 0o755 });
  • 执行外部命令来自配置/变量
    scripts/profile.mjs:58
    const result = spawnSync(npm, ['pack', source, '--pack-destination', destination, '--json'], {
  • 读取本地文件
    scripts/profile.mjs:73
    if (!existsSync(tarball)) throw new Error(`npm pack did not create ${tarball}`);
  • 读取本地文件
    scripts/profile.mjs:103
    if (!existsSync(manifestPath)) {
  • 读取本地文件
    scripts/profile.mjs:108
    const metadata = JSON.parse(readFileSync(join(source, 'package.json'), 'utf8'));
  • 读取本地文件
    lib/host-modules.js:50
    if (!existsSync(scope)) continue;
  • 发起网络请求
    lib/api.js:160
    const response = await this.fetch(url, {
  • 发起网络请求
    lib/api.js:183
    const response = await this.request('GET', '/project');
  • 发起网络请求
    lib/api.js:198
    const script = await this.request('GET', '/socket.io/socket.io.js');
  • 发起网络请求
    lib/api.js:211
    const response = await this.request('POST', '/api/project', { body: {} });
  • 发起网络请求
    lib/api.js:218
    const response = await this.request('GET', '/user/projects');
  • 发起网络请求
    lib/api.js:229
    const response = await this.request('GET', `/project/${encodeURIComponent(projectId)}/download/zip`,
  • 读取本地文件
    lib/compile.js:20
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 写入本地文件
    lib/compile.js:72
    mkdirSync(outDir, { recursive: true });
  • 写入本地文件
    lib/compile.js:74
    writeFileSync(join(localDir, 'output.pdf'), data, { mode: 0o644 });
  • 写入本地文件
    lib/compile.js:79
    mkdirSync(outDir, { recursive: true });
  • 写入本地文件
    lib/compile.js:80
    writeFileSync(join(localDir, 'output.log'), data, { mode: 0o644 });
  • 读取本地文件
    lib/secrets.js:40
    text = readFileSync(this.file, 'utf8');
  • 读取本地文件
    lib/secrets.js:60
    if ((statSync(this.file).mode & 0o077) !== 0) {
  • 写入本地文件
    lib/secrets.js:61
    chmodSync(this.file, 0o600);
  • 写入本地文件
    lib/secrets.js:105
    mkdirSync(dirname(this.file), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/secrets.js:108
    writeFileSync(temp, `${JSON.stringify(body, null, 2)}\n`, { mode: 0o600 });
  • 写入本地文件
    lib/secrets.js:109
    renameSync(temp, this.file);
  • 删除本地文件
    lib/secrets.js:110
    } finally { rmSync(temp, { force: true }); }
  • 读取本地文件
    lib/sync.js:30
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    lib/sync.js:42
    try { return readFileSync(join(localDir, path.split('/').join(sep))); } catch { return undefined; }
  • 写入本地文件
    lib/sync.js:93
    mkdirSync(dirname(localPath), { recursive: true, mode: 0o755 });
  • 写入本地文件
    lib/sync.js:94
    writeFileSync(localPath, data, { mode: 0o644 });
  • 读取本地文件
    lib/sync.js:104
    if (existsSync(localPath)) {
  • 删除本地文件
    lib/sync.js:110
    rmSync(localPath, { force: true });
  • 读取本地文件
    lib/store.js:29
    return JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/store.js:37
    mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/store.js:40
    writeFileSync(temp, `${JSON.stringify(value, null, 2)}\n`, { mode });
  • 写入本地文件
    lib/store.js:41
    renameSync(temp, file);
  • 删除本地文件
    lib/store.js:42
    } finally { rmSync(temp, { force: true }); }
  • 读取本地文件
    lib/store.js:112
    return existsSync(statePath(localDir));
  • 读取本地文件
    ui/host.js:155
    hasPdf: existsSync(join(localDir, 'output.pdf')),
  • 读取本地文件
    ui/host.js:197
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    ui/host.js:202
    const info = statSync(join(dir, entry.name));
  • 读取本地文件
    ui/host.js:216
    const info = statSync(file);
  • 读取本地文件
    ui/host.js:218
    const buffer = readFileSync(file);
  • 读取本地文件
    ui/host.js:236
    try { info = statSync(file); } catch { continue; }
  • 写入本地文件
    ui/host.js:261
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    ui/host.js:262
    writeFileSync(file, combined.text, { mode: 0o644 });
  • 读取本地文件
    lib/live.js:291
    if (!existsSync(file)) continue;
  • 读取本地文件
    lib/live.js:294
    if (model !== undefined && readFileSync(file, 'utf8') !== model.baseText) dirty.add(entity.path);
  • 读取本地文件
    lib/live.js:295
    } else if (this.binaryHashes.get(entity.path) !== sha256(readFileSync(file))) {
  • 写入本地文件
    lib/live.js:338
    if (path !== '') mkdirSync(this.fileOf(path), { recursive: true });
  • 读取本地文件
    lib/live.js:341
    if (entity.type === 'file' && existsSync(this.fileOf(entity.path))) {
  • 读取本地文件
    lib/live.js:342
    this.binaryHashes.set(entity.path, sha256(readFileSync(this.fileOf(entity.path))));
  • 读取本地文件
    lib/live.js:373
    const localBefore = existsSync(localFile) ? readFileSync(localFile, 'utf8') : undefined;
  • 写入本地文件
    lib/live.js:824
    mkdirSync(this.fileOf(rel), { recursive: true });
  • 写入本地文件
    lib/live.js:881
    mkdirSync(this.fileOf(path), { recursive: true });
  • 删除本地文件递归
    lib/live.js:915
    rmSync(this.fileOf(prefix), { recursive: true, force: true });
  • 写入本地文件
    lib/live.js:946
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/live.js:947
    writeFileSync(file, text, { mode: 0o644 });
  • 写入本地文件
    lib/live.js:952
    mkdirSync(dirname(file), { recursive: true });
  • 删除本地文件递归
    lib/live.js:966
    rmSync(source, { recursive: true, force: true });
  • 删除本地文件递归
    lib/live.js:1015
    rmSync(this.fileOf(entity.path), { recursive: true, force: true });
  • 写入本地文件
    lib/workspace-files.js:35
    mkdirSync(dirname(absolute), { recursive: true });
  • 写入本地文件
    lib/workspace-files.js:37
    writeFileSync(absolute, '', { flag: 'wx', mode: 0o644 });
  • 读取本地文件
    lib/workspace-files.js:52
    if (existsSync(absolute)) throw new Error('同名文件或文件夹已存在。');
  • 写入本地文件
    lib/workspace-files.js:54
    mkdirSync(absolute, { recursive: true });
  • 发起网络请求
    lib/socket.js:64
    async fetch(url, init = {}) {
  • 发起网络请求
    lib/socket.js:65
    const response = await this.client.fetch(url, {
  • 发起网络请求
    lib/socket.js:90
    const response = await this.fetch(`${this.base}/socket.io/1/${query}`);
  • 发起网络请求
    lib/socket.js:138
    response = await this.fetch(`${this.base}/socket.io/1/xhr-polling/${this.sid}?projectId=${encodeURIComponent(this.projectId)}&t=${Date.now()}`);
  • 发起网络请求
    lib/socket.js:222
    const response = await this.fetch(`${this.base}/socket.io/1/xhr-polling/${this.sid}?t=${Date.now()}`, {
  • 发起网络请求
    lib/socket.js:246
    await this.client.fetch(`${this.base}/socket.io/1/xhr-polling/${sid}?t=${Date.now()}&disconnect=1`,
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

基于DeepSeek Harness 的 Overleaf Workshop 插件:三栏工作区、实时同步

README

由 DeepSeek 最新模型翻译生成
DeepSeek Harness · Overleaf Workshop 在 DeepSeek Harness 里直接编辑 Overleaf 项目,实时双向同步。 Overleaf 工作区:左侧是项目目录树,中间是 LaTeX 编辑器,右侧是对话栏 界面示意(示例项目):左侧 Overleaf 目录,中间带高亮与自动保存的编辑器,右侧直接和智能体对话。 功能 - 实时双向同步:本地编辑、智能体修改会自动推送到 Overleaf,网页端的协作修改也会同步回本地。支持文件新建、重命名、移动和删除,以及并发编辑时的三方合并。 - 三栏编辑界面:目录树、文件编辑器、智能体对话并排显示。内置 CodeMirror 编辑器,支持 LaTeX 语法高亮、搜索、自动保存和快捷键操作。 - 在线编译与 PDF 预览:在 Overleaf 服务器上编译当前打开的 .tex 文件,生成的 output.pdf 可以直接在内置预览中查看。 - 项目与会话管理:侧边栏独立显示 Overleaf 项目及同步状态,支持快速编译、新建会话、切换历史会话和结束同步。 - 按需同步:可以随时停止实时连接,保留全部本地文件;重新进入项目即可恢复同步。实时连接不可用时,也支持手动拉取和推送。
展开完整文档(README 剩余 1 节)
DeepSeek Harness · Overleaf Workshop

在 DeepSeek Harness 里直接编辑 Overleaf 项目,实时双向同步。

Overleaf 工作区:左侧是项目目录树,中间是 LaTeX 编辑器,右侧是对话栏

界面示意(示例项目):左侧 Overleaf 目录,中间带高亮与自动保存的编辑器,右侧直接和智能体对话。

功能

- 实时双向同步:本地编辑、智能体修改会自动推送到 Overleaf,网页端的协作修改也会同步回本地。支持文件新建、重命名、移动和删除,以及并发编辑时的三方合并。
- 三栏编辑界面:目录树、文件编辑器、智能体对话并排显示。内置 CodeMirror 编辑器,支持 LaTeX 语法高亮、搜索、自动保存和快捷键操作。
- 在线编译与 PDF 预览:在 Overleaf 服务器上编译当前打开的 .tex 文件,生成的 output.pdf 可以直接在内置预览中查看。
- 项目与会话管理:侧边栏独立显示 Overleaf 项目及同步状态,支持快速编译、新建会话、切换历史会话和结束同步。
- 按需同步:可以随时停止实时连接,保留全部本地文件;重新进入项目即可恢复同步。实时连接不可用时,也支持手动拉取和推送。

安装

推荐通过 GitHub 安装:

dsh plugin --profile desktop add github:chenqaq123/dsh-overleaf-workshop

macOS 桌面版如果找不到 dsh 命令,可以使用应用内自带的命令行:

"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin --profile desktop add github:chenqaq123/dsh-overleaf-workshop

安装完成后重启 Harness,在「插件 → 已安装」中管理插件。

登录与使用

1. 在浏览器中登录 Overleaf。
2. 按 F12 打开开发者工具,在 Network 中找到任意请求,复制请求头里的 Cookie 值。
3. 打开 Harness 侧边栏的 Overleaf → 管理,粘贴 Cookie,点击「验证并登录」。
4. 选择项目,即可进入本地工作区。

Cookie 仅保存在本机 ~/.dsh/overleaf/secrets.json。

进入项目后,可以直接编辑文件,也可以让智能体完成任务,例如:

许可证

MIT

本项目未使用 Overleaf Workshop(AGPL-3.0)的代码,相关协议实现基于独立研究。
预览分享卡片长什么样 ↓chenqaq123/dsh-overleaf-workshop
分享 · DeepSeek Harness Hub
chenqaq123/dsh-overleaf-workshop

在编辑器内直接编辑 Overleaf 项目并实时双向同步

这是你的仓库?认领条目

回到顶部