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

笔记工作流包 Jacobinwwey/dsh-NotEMD

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

审批门控自动生成笔记索引、图表与幻灯片导出

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

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

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Jacobinwwey/dsh-NotEMD
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · security
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 29 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装
要求 Node:>=22.19.0(dsh 本身要求 Node ≥ 22.19)

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

✗npm 包dsh-notemd-workspace(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

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

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件发起外部网络请求
查看扫描证据(共 76 处,展示前 68 条)
  • 发起网络请求
    packages/notemd-bundle/src/approval.ts:59
    return this.gate.request(...args)
  • 发起网络请求
    packages/notemd-bundle/src/runtime-adapter.ts:44
    if (await approval.request(request) === 'allowed-once') {
  • 写入本地文件
    packages/notemd-jobs/src/file-job-store.ts:62
    await mkdir(jobsDirectory, { recursive: true })
  • 读取本地文件
    packages/notemd-jobs/src/file-job-store.ts:267
    const entries = await readdir(this.jobsDirectory, { withFileTypes: true })
  • 读取本地文件
    packages/notemd-jobs/src/file-job-store.ts:298
    parsed = JSON.parse(await readFile(path, 'utf8'))
  • 写入本地文件
    packages/notemd-jobs/src/file-job-store.ts:313
    await writeFile(temporary, JSON.stringify(record), { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    packages/notemd-jobs/src/file-job-store.ts:314
    await rename(temporary, destination)
  • 删除本地文件
    packages/notemd-jobs/src/file-job-store.ts:316
    await rm(temporary, { force: true }).catch(() => undefined)
  • 发起网络请求
    packages/notemd-llm-openai-compatible/src/index.ts:110
    const response = await this.request(request, false, signal)
  • 发起网络请求
    packages/notemd-llm-openai-compatible/src/index.ts:124
    const response = await this.request({
  • 发起网络请求
    packages/notemd-llm-openai-compatible/src/index.ts:184
    const response = await this.request(request, true, signal)
  • 写入本地文件
    packages/notemd-process/src/allowlisted-process.ts:518
    await writeFile(join(runDirectory, profile.inputFilename), input, { flag: 'wx', mode: 0o600 })
  • 删除本地文件递归
    packages/notemd-process/src/allowlisted-process.ts:592
    await rm(runDirectory, { recursive: true, force: true }).catch(() => undefined)
  • 写入本地文件
    packages/notemd-process/src/allowlisted-process.ts:598
    await mkdir(this.stagingRoot, { recursive: true, mode: 0o700 })
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:600
    realpath(this.workspaceRoot),
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:601
    realpath(this.stagingRoot),
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:607
    const canonicalRunDirectory = await realpath(runDirectory)
  • 删除本地文件递归
    packages/notemd-process/src/allowlisted-process.ts:609
    await rm(runDirectory, { recursive: true, force: true }).catch(() => undefined)
  • 写入本地文件
    packages/notemd-process/src/allowlisted-process.ts:653
    await writeFile(join(runDirectory, 'source.md'), sourceBytes, { flag: 'wx', mode: 0o600 })
  • 写入本地文件
    packages/notemd-process/src/allowlisted-process.ts:654
    await mkdir(join(runDirectory, 'output-frames'))
  • 写入本地文件
    packages/notemd-process/src/allowlisted-process.ts:694
    await writeFile(join(runDirectory, 'frames.txt'), `${concatLines.join('\n')}\n`, { flag: 'wx', mode: 0o600 })
  • 删除本地文件递归
    packages/notemd-process/src/allowlisted-process.ts:744
    await rm(runDirectory, { recursive: true, force: true }).catch(() => undefined)
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:772
    entry = await lstat(outputPath)
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:782
    const canonicalOutput = await realpath(outputPath)
  • 读取本地文件
    packages/notemd-process/src/allowlisted-process.ts:789
    const bytes = await readFile(canonicalOutput)
  • 发起网络请求
    packages/notemd-research/src/dsh-research-client.ts:41
    fetch(request: { readonly url: string }, signal?: AbortSignal): Promise<DshWebFetchResult>
  • 发起网络请求
    packages/notemd-research/src/dsh-research-client.ts:82
    result = await this.web.fetch({ url: source.url }, signal)
  • 读取本地文件
    packages/notemd-research/src/research-evidence.ts:141
    serialized = await readFile(path, 'utf8')
  • 读取本地文件
    packages/notemd-research/src/research-evidence.ts:158
    await readFile(path, 'utf8')
  • 写入本地文件
    packages/notemd-research/src/research-evidence.ts:164
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    packages/notemd-research/src/research-evidence.ts:167
    await writeFile(temporaryPath, JSON.stringify(value), 'utf8')
  • 写入本地文件
    packages/notemd-research/src/research-evidence.ts:168
    await rename(temporaryPath, path)
  • 删除本地文件
    packages/notemd-research/src/research-evidence.ts:396
    await rm(path, { force: true })
  • 写入本地文件
    packages/notemd-tools/src/approval-ledger.ts:57
    await mkdir(approvalsDirectory, { recursive: true })
  • 读取本地文件
    packages/notemd-tools/src/approval-ledger.ts:111
    const content = await readFile(this.pathFor(approvalId), 'utf8')
  • 写入本地文件
    packages/notemd-tools/src/approval-ledger.ts:128
    await writeFile(temporary, `${JSON.stringify(receipt)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    packages/notemd-tools/src/approval-ledger.ts:129
    await rename(temporary, destination)
  • 删除本地文件
    packages/notemd-tools/src/approval-ledger.ts:131
    await rm(temporary, { force: true }).catch(() => undefined)
  • 发起网络请求
    packages/notemd-tools/src/write-tools.ts:96
    const decision = await context.notemdApprovalGate.request(plan, execution)
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:236
    await mkdir(payloadDirectory, { recursive: true })
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:331
    await mkdir(dirname(quarantinePath), { recursive: true })
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:344
    await mkdir(dirname(backupPath), { recursive: true })
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:415
    await mkdir(dirname(resolved.absolutePath), { recursive: true })
  • 删除本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:445
    await rm(resolved.absolutePath, { force: true })
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:447
    await mkdir(dirname(resolved.absolutePath), { recursive: true })
  • 删除本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:456
    await rm(resolved.absolutePath, { force: true })
  • 删除本地文件递归
    packages/notemd-vault-local/src/local-mutation-executor.ts:525
    await rm(this.planStagingRoot(planId), { recursive: true, force: true })
  • 读取本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:551
    return await readFile(path)
  • 写入本地文件
    packages/notemd-vault-local/src/local-mutation-executor.ts:565
    await rename(source, destination)
  • 读取本地文件
    packages/notemd-vault-local/src/local-mutation-journal.ts:164
    entries = await readdir(this.journalDirectory, { withFileTypes: true })
  • 读取本地文件
    packages/notemd-vault-local/src/local-mutation-journal.ts:188
    parsed = JSON.parse(await readFile(this.pathFor(planId), 'utf8'))
  • 读取本地文件
    packages/notemd-vault-local/src/local-vault.ts:97
    const entries = await readdir(directory, { withFileTypes: true })
  • 读取本地文件
    packages/notemd-vault-local/src/local-vault.ts:121
    const content = await readFile(absolutePath, 'utf8')
  • 读取本地文件
    packages/notemd-vault-local/src/path-boundary.ts:32
    return new VaultPathBoundary(await realpath(workspaceRoot))
  • 写入本地文件
    packages/notemd-vault-local/src/path-boundary.ts:53
    await mkdir(dirname(resolved.absolutePath), { recursive: true })
  • 读取本地文件
    packages/notemd-vault-local/src/path-boundary.ts:98
    const canonicalCandidate = await realpath(candidate)
  • 读取本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:45
    content = await readFile(this.pathFor(stagedAsset))
  • 写入本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:69
    await mkdir(dirname(destination), { recursive: true })
  • 写入本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:80
    await rename(temporaryPath, destination)
  • 删除本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:82
    await rm(temporaryPath, { force: true }).catch(() => undefined)
  • 写入本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:88
    await mkdir(dirname(destination), { recursive: true })
  • 删除本地文件
    packages/notemd-vault-local/src/staged-asset-store.ts:96
    await rm(destination, { force: true }).catch(() => undefined)
  • 写入本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:132
    await mkdir(lockDirectory, { recursive: true })
  • 删除本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:151
    await unlink(lockPath)
  • 删除本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:221
    await unlink(this.lockPath)
  • 写入本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:290
    await writeFile(this.lockPath, `${JSON.stringify(metadata)}\n`, 'utf8')
  • 读取本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:314
    return realpath(resolved)
  • 读取本地文件
    packages/notemd-vault-local/src/workspace-ownership.ts:352
    content = await readFile(lockPath, 'utf8')
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

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

功能亮点

  • 审批门禁控制
  • 自动生成知识索引
  • 图表与幻灯片导出

DeepSeek Harness 的可移植 NoteMD 工作流包:带审批门禁的 markdown 自动化、知识索引、图表、SVG 预览和 Slidev 导出。

README

由 DeepSeek 最新模型翻译生成
dsh-NotEMD 面向 DeepSeek Harness 的可移植、审批门控 NoteMD 工作流 bundle。它针对显式工作区根目录运行,将 canonical source 与派生 artifact 统一管理,不依赖 Obsidian API、编辑器状态、命令或 UI 宿主。 当前版本: dsh-notemd@0.1.1 · GitHub 仓库 安装 支持的验收基线: | 前提 | 版本或策略 | | Node.js | >=22.19.0 | | pnpm | 10.7.1(workspace 的 packageManager) | | DeepSeek Harness | 0.1.0-rc.5 验收基线 | | Cordis | @deepseek-ai/cordis 4.0.1 验收基线 | 从公共 npm registry 安装,并将同一版本加入 DSH profile: npm install --save-exact dsh-notemd@0.1.1 dsh plugin --profile notes add dsh-notemd@0.1.1 npm install 让 Node workspace 可以解析该包;dsh plugin ... add 才会把 bundle patch 激活到指定 profile。
展开完整文档(README 剩余 1 节)
dsh-NotEMD

面向 DeepSeek Harness 的可移植、审批门控 NoteMD 工作流 bundle。它针对显式工作区根目录运行,将 canonical source 与派生 artifact 统一管理,不依赖 Obsidian API、编辑器状态、命令或 UI 宿主。

当前版本: dsh-notemd@0.1.1 · GitHub 仓库

安装

支持的验收基线:

| 前提 | 版本或策略 |
| Node.js | >=22.19.0 |
| pnpm | 10.7.1(workspace 的 packageManager) |
| DeepSeek Harness | 0.1.0-rc.5 验收基线 |
| Cordis | @deepseek-ai/cordis 4.0.1 验收基线 |

从公共 npm registry 安装,并将同一版本加入 DSH profile:

npm install --save-exact dsh-notemd@0.1.1
dsh plugin --profile notes add dsh-notemd@0.1.1

npm install 让 Node workspace 可以解析该包;dsh plugin ... add 才会把 bundle patch 激活到指定 profile。只执行前者不会启用 DSH 插件。

离线或未发布构建使用已验证的 tarball:

git clone git@github.com:Jacobinwwey/dsh-NotEMD.git
cd dsh-NotEMD
pnpm install --frozen-lockfile
pnpm build
pnpm pack:bundle
dsh plugin --profile notes add ./artifacts/dsh-notemd-0.1.1.tgz

pnpm pack:bundle 会内嵌尚未发布的 @notemd-harness/ 实现包;minisearch 保持普通 runtime dependency,由 profile 包管理器解析。打包校验要求 artifacts/ 下恰好有一个 .tgz,反复打包前请清理旧 tarball。

仓库中的 fixture profile 是 profiles/notemd,仅用于验收,不代替部署方自己的 profile。安装后可检查最终生效配置:

dsh --profile notes --dump-config

快速使用

bundle 首先暴露规划工具。典型请求:

读取 notes/architecture.md。分别生成 wiki-link 与 Mermaid 修复的不可变计划。
展示受影响路径和 revision。请求审批;只有 revision 仍匹配的计划才允许应用。

写入协议固定且可审计:

read -> immutable WorkspaceMutationPlan -> approval -> apply -> committed receipt -> workspace event -> index update

只有匹配的 committed receipt 才会生成工作区变更事件。conflict、rejected、cancelled、failed、recovered 以及不一致 receipt 都不会被当作可索引内容变化。

能力矩阵

对应 NotEMD 1.9.12 的源代码升级

当前源码为七个图形渲染器增加基于关系的 SVG 投影:可见层级连线、有计算预算且只接受距离改善的排布、节点边界连接、独立自环/平行/反向关系,以及完整换行标签。SVG 投影指纹更新为 2,语义/原生源格式与适配器契约保持不变。这是已发布 0.1.1 软件包之后的源码更新。

布局是确定性且有计算预算的启发式算法,不保证任意密集图零交叉。它使用估算文本宽度,并对最近 64 条路径进行拥挤度评分。原生 JSON Canvas 坐标仍由独立实现负责。浏览器 SVG 到 PDF 和模态诊断折叠不属于此 bundle 的运行能力;既有持久化任务已经保留前序阶段结果。详见迁移分析。

| 区域 | 面向模型的入口 | 契约 |
| 工作区 | notemd_workspace_list、notemd_workspace_read | 工作区相对 Markdown 路径、根目录 containment、不可变 revision。 |
| 知识索引 | notemd_knowledge_search、notemd_knowledge_retrieve | 查询返回索引内容及 citation;已提交的工作区事件刷新受影响的源章节,外部编辑需要刷新索引。 |
| 笔记工作流 | notemd_plan_ | Wiki-link、标题生成、翻译、概念提取、Mermaid/公式修复、章节拆分、原文提取、文件夹批处理、重复检查与人工确认去重;规划不写入。 |
| 联网研究 | notemd_research_discover、notemd_research_capture_evidence、notemd_plan_research_synthesis | 使用 DSH web;持久化 evidence 只保存身份、citation 与 digest,不把不可信工具输出作为事实。 |
| 修改 | notemd_request_plan_approval、notemd_apply_approved_plan | 一个 plan digest、一个 approval receipt、一次消费;精确 revision 前置条件;陈旧 plan fail closed。 |
| 持久化作业 | notemd_job_start_、notemd_job_resume、notemd_job_status、notemd_job_cancel | 异步、仅规划 checkpoint,位于 <workspace>/.notemd/jobs/;作业绝不应用 plan。 |
| 图表与预览 | notemd_plan_mermaid_artifact、notemd_plan_vega_lite_artifact、notemd_plan_json_canvas_artifact、notemd_plan_html_artifact、notemd_plan_editable_svg_artifact | canonical source 加显式标记的 SVG preview。 |
| 专用图形 | notemd_plan_drawio_artifact、notemd_plan_drawnix_artifact、notemd_plan_circuitikz_artifact | canonical source 加 SVG projection;native export 受 capability 门控,不会静默替换。 |
| Slidev | notemd_plan_slidev_source、notemd_plan_slidev__export | source、standalone HTML、PDF、PNG、native PPTX、MP4 是独立具名 provider。 |
| 能力状态 | _render_status、_export_status | Playwright、FFmpeg、Draw.io、Tectonic 或 adapter 缺失时返回带结构化诊断的 unavailable。 |

刻意不存在 generic renderer 或 export selector。不同 target 的保真、进程 allowlist、staging 与失败语义不同,单一多态开关会隐藏关键契约。

Composite workflow

one-click-extract@1 是源插件 One-Click Extract 行为的具名 composite workflow:

~~~text
add-links -> generate-complete -> repair-mermaid

需要一个 aggregate immutable plan 与一份 approval receipt 时,调用 notemd_plan_one_click_extract。必须显式提供 sourcePath、conceptFolderPath、completedFolderPath、mermaidFolderPath,以及可选的 mermaidErrorFolderPath;独立 bundle 不推断 Obsidian active-file 或 UI folder state。需要持久化、只规划的作业时调用 notemd_job_start_one_click_extract;executor key 为 one-click-extract-v1,持久化 record 仍保留 workflow version 与 definition digest 用于 drift 检测。

Composite 使用 virtual workspace overlay。后续步骤可以读取前一步规划出的 Markdown write,但 approval 前不会写物理工作区。collision、stale virtual revision、binary dependency、budget overflow 与 net no-op 都会 fail closed。

Profile 配置

bundle patch 默认把有状态 provider 指向 process.cwd()。部署 profile 覆盖某一行时必须替换完整 config 对象;DSH patch 不会深度合并。请保留完整字段集:

~~~yaml
- id: notemd-vault
config:
workspaceRoot: !!js process.env.NOTEMD_WORKSPACE_ROOT

- id: notemd-jobs
config:
workspaceRoot: !!js process.env.NOTEMD_WORKSPACE_ROOT
concurrency: 2

- id: notemd-workspace-changes
config:
scanIntervalMs: 5000

- id: notemd-approval
config:
workspaceRoot: !!js process.env.NOTEMD_WORKSPACE_ROOT
approvalTtlMs: 300000

- id: notemd-research
config:
workspaceRoot: !!js process.env.NOTEMD_WORKSPACE_ROOT

- id: notemd-artifacts
config:
workspaceRoot: !!js process.env.NOTEMD_WORKSPACE_ROOT

- id: notemd-llm
config:
provider: deepseek
model: deepseek-chat
maxTokens: 4096
promptPolicyId: notemd.default.v1

默认 notemd-llm provider 注入 DSH llm。其封闭 route policy 只接受 provider、model、maxTokens、promptPolicyId。endpoint、key、header、transport retry 与 model discovery 会被拒绝,不会被忽略。凭据、adapter 与 provider 选择由 DSH 配置;NoteMD 不会读取或持久化它们。

显式的 dsh-notemd/llm-openai-compatible-legacy entry 仅供迁移期使用,为尚不能使用 DSH routing 的部署提供旧 OpenAI-compatible diagnostic 与 model-discovery 工具。使用时必须替换默认 notemd-llm row,不能同时加载,因为两者都提供 notemdTextTransformer。

图表与导出

由于 DSH 没有 Obsidian preview host,SVG 是默认 preview derivative。这是预览策略,不代表每个 target 都有等价的 SVG export:

- Mermaid、Vega-Lite、JSON Canvas、HTML、editable SVG 保留 canonical source,并生成带标签的 SVG preview。
- Mermaid repair 前先运行 deterministic normalization。versioned semantic/render/export catalog 对 timeline、swimlane、quadrant payload 做类型化约束;svg-preview 是显式 derivative,不代表 native target parity。
- Draw.io、Drawnix、Circuitikz 保留 canonical source;只有受控 executable 或 adapter 可用时才暴露 native SVG 或 PDF。
- Slidev source preparation 是确定性的,并强制 offline fonts。HTML、PDF、PNG、PPTX、MP4 是 approval-gated planner 后的独立 provider。
- 外部进程在 request-scoped staging 目录执行,返回 digest-verified staged asset,绝不直接写工作区。

接受的 Slidev runtime 是 NoteMD fork,不是 upstream Slidev:

origin: github:Jacobinwwey/slidev
revision: bbcb2efae709c2ebaa96bda522cd6c192476817c
package: @slidev/cli@52.16.0

该 fork 的 standalone HTML 输出为 index-standalone.html。PPTX 保持 native OOXML;MP4 是 Slidev PNG frames 加 FFmpeg。SVG 不会被宣传为 PPTX 或 MP4 的 fallback。

运行边界

- bundle 不是 Obsidian 兼容层。UI、编辑器选区、命令、modal 与 preview hosting 仍由宿主负责。
- notemdWorkspaceChanges 首次捕获 snapshot,之后通过有序轮询协调。默认间隔 5000 ms,合法范围 250 到 60000;扫描成本与工作区 Markdown 规模成正比。
- 事件只携带路径、revision、origin、causation id 与时间戳,不携带笔记内容或凭据。
- 中断的 running 作业恢复为静止的 queued record。notemd_job_resume 是显式继续操作,不是写入授权或任意重放。
- 文件型 store 没有跨进程 lease;一个工作区只运行一个 bundle 进程。
- 默认 DSH route 不注册 notemd_provider_diagnostic 或 notemd_provider_models;它们只存在于显式 legacy transport entry。
- @deepseek-ai/* API 以验收使用的固定 DSH source 为准;未来 DSH 版本可能需要兼容性更新。
- 第三方 DSH plugin 会在宿主进程执行代码。生产 profile 只安装可信包,并在启动前检查实际生效的 patch。

开发

代码遵循 DSH/Cordis composition model:每个 provider 负责一个 service 或 capability,注册是可逆 effect,面向模型的 tool 消费稳定 seam(llm、web、subprocess、tools)。不要把 Obsidian 或第二套宿主 loop 引入 bundle。

关键入口:

| 区域 | 源码 |
| Bundle manifest 与 patch | packages/notemd-bundle |
| Tool 注册 | packages/notemd-tools/src |
| Workflow planner | packages/notemd-workflows/src |
| Artifact provider | packages/notemd-artifacts/src、packages/notemd-export-slidev/src |
| 已安装 profile 验收 | scripts/accept-dsh-profile.ts |
| 打包 bundle 校验 | scripts/verify-bundle.ts |

先运行聚焦门禁,再运行发行门禁:

~~~powershell
pnpm typecheck
pnpm lint
pnpm test
pnpm test:coverage
pnpm build
pnpm pack:bundle
pnpm verify:bundle
pnpm accept:dsh
pnpm capability:lane
git diff --check

accept:dsh 会创建隔离的 DSH_HOME,通过固定版本 source DSH CLI 安装打包 tarball,启动已安装的 ToolRuntime,检查审批与陈旧 revision 行为、仅规划作业、research fail-closed,以及图表/Slidev capability surface;记录证据后删除临时 profile 与 fixture workspace。

新增 capability 时,应同时定义 service contract、provider 与 consumer。面向模型的行为通过 ctx.tools 注册,使用 DSH 的 llm/web/subprocess seam,不创建私有 transport,并增加真实安装产物的验收断言。可选 executable 必须显式表达:缺失是 capability 结果,不能变成格式替换。

发布

公共 npm 包为无 scope、public package。维护者应只发布通过安装态 profile 验收的同一个 tarball:

~~~powershell
pnpm install --frozen-lockfile
pnpm typecheck
pnpm lint
pnpm test
pnpm test:coverage
pnpm build
pnpm pack:bundle
pnpm verify:bundle
pnpm accept:dsh
npm publish ./artifacts/dsh-notemd-0.1.1.tgz --access public --registry=https://registry.npmjs.org/

包内发布的 README.md 是 npm canonical README。同一份中文文档会以 docs/README.zh-CN.md 发布,并继续由 canonical 文档链接;它不放在包根目录,以避免 npm 把它选为 readmeFilename。

维护者账号启用 npm 2FA 时,npm publish 可能暂停等待 OTP;普通使用者不需要维护者的 npm 登录或 OTP。

发布后验证 registry 元数据:

~~~powershell
npm view dsh-notemd version --registry=https://registry.npmjs.org/
npm view dsh-notemd@0.1.1 readmeFilename --registry=https://registry.npmjs.org/

预期值是 0.1.1 与 README.md。

文档与外部契约

主页只保留可执行的使用与开发信息;架构与验收证据放在仓库双语文档中:

- 架构规范(English) · 中文
- 验收证据(English) · 中文
- DeepSeek Harness architecture
- DeepSeek Harness development guide
- DeepSeek Harness capability seams
- DeepSeek Harness testing policy
- awesome-dsh-plugin

状态

本仓库是 developer-preview bundle。公共契约是打包 tarball 与最终生效的 DSH profile patch,不是 Obsidian plugin API。DSH 仍处于 1.0 之前,后续版本可能需要兼容性更新。
预览分享卡片长什么样 ↓Jacobinwwey/dsh-NotEMD
分享 · DeepSeek Harness Hub
Jacobinwwey/dsh-NotEMD

审批门控自动生成笔记索引、图表与幻灯片导出

这是你的仓库?认领条目

回到顶部