DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Bilibili Note — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
B

dsh-bilibili-note

Bilibili Note

把 B站视频链接变成 Obsidian 结构化笔记的 DSH 技能插件:只拉字幕、不下载视频,机械环节写死、判断环节交给模型。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:3588834014-del/bilibili-note-plugin#bfc9656081b30ed5f14e531c680fe9417651b4d6
README兼容性版本

兼容性与来源证明

Bilibili Note 以 dsh-bilibili-note 发布,当前版本为 1.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/10/18

版本

1.2.0stable
2026/10/18

相关插件

正在加载相关插件…

最新版
1.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/18
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundle为 Web 组合添加 Schedule、其任务页面和时间上下文的可选捆绑包Client Ui Task Board@linxin666/dsh-client-ui-task-board面向 DSH Web GUI 的主机权威任务面板,支持实际会话执行、主机 cron 调度以及可选的跨平台空闲睡眠保护;以挂载方式提供,无需修改 DSH 源代码。Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / remote-web-ui / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。

README

bilibili-note

DSH plugin packaging of 3588834014-del/bilibili-note.

This repository is the plugin edition: the upstream project plus a DeepSeek Harness bundle wrapper (package.json / cordis.patch.yml / lib/index.js). The original skill + CLI lives upstream — use that one if you don't need to install it as a dsh plugin. GitHub does not allow forking a repository into the same account, so this is a derivative copy rather than a fork-network fork.

Turn Bilibili videos into structured Obsidian notes — subtitles only, never the video.

中文说明见 README.zh-CN.md。

A small CLI — plus an optional agent skill — that turns a Bilibili video into a structured Markdown note in your Obsidian vault. It downloads only the subtitle file (--skip-download), cleans the timestamps, and writes a note with YAML front matter, a summary section, bullet points carrying clickable ?t= jump links, and the full transcript collapsed at the bottom.

The repetitive half (fetch, parse, format, verify) is a script. The judgment half (summary, key points, tags) is left as a documented contract you or an agent fill in.

Bilibili URL ──▶ fetch ──▶ manifest.json ──▶ [you / agent] ──▶ content.json ──▶ write ──▶ note.md
                  │         subtitles +                      summary, bullets,       │
                  │         timestamped segments             tags                    │
                  └── yt-dlp, subtitles only ────────────────────────────────────────┘

Real output

fetch on a real video — note what is not there: no .mp4, .flv, .m4a or .part, only the subtitle file and its manifest.

fetch: subtitles only, no media files

And the note it produces (Obsidian rendering — front matter, clickable ?t= jump links, summary, bullets, tags). Screenshot taken from a real run, not a mock-up:

the generated note

Why this one

  • Subtitles only. --skip-download is mandatory, and the tool verifies no media file (.mp4/.flv/.m4a/.part) landed in the working directory. No reverse-engineering, no private APIs — just yt-dlp.
  • Multi-part videos are merged. For an anthology (B站 分P 合集) it fetches every part's subtitles and rebases the timestamps onto one continuous timeline. Verified on a real 6-part anthology: 2:10:32 → 2807 segments / 33214 characters, matching an independent concatenation segment-for-segment. A part with no subtitles is skipped while keeping its time slot, so later timestamps stay correct.
  • It refuses to produce garbage. If two parts yield byte-identical subtitles, it errors out instead of silently emitting a note whose content is one part repeated N times. (That exact bug shipped during development and was caught by this guard.)
  • No subtitles? It skips and tells you. It never fabricates content or writes an empty note.

Install

No dependencies — standard library only. yt-dlp is an external command, not a Python package.

As a DSH plugin (recommended for DeepSeek Harness)

dsh plugin --profile web add github:3588834014-del/bilibili-note-plugin

This is a bundle plugin that registers the bilibili-note skill straight into the DSH skill catalog — no manual copying into ~/.agents/skills. Restart your profile afterwards and the skill is available; the model picks it up from phrases like 「B站笔记」 or a pasted BV link.

The plugin ships its own copy of scripts/bili_note.py, docs/ and SKILL.md, and rewrites the <skill-dir> placeholders in the skill body to the absolute install path, so the model never has to guess where the script lives. Uninstall with dsh plugin --profile web remove dsh-bilibili-note.

There is no npm package yet, so this plugin is source-installed — it is listed on dsh-plugin.org but will not appear in the in-app plugin store. pnpm ≥10 may ask you to allow the git dependency's build script; this package has no prepare script, so nothing runs at install time.

As a standalone CLI

pipx install git+https://github.com/3588834014-del/bilibili-note.git
# or
git clone https://github.com/3588834014-del/bilibili-note.git
cd bilibili-note && python -m pip install .

Then:

bili-note --version
bili-note note "https://www.bilibili.com/video/BVxxxxxxxxx" \
    --note-dir ~/MyVault/Sources/Videos

As a plain agent skill (no plugin)

python scripts/install.py            # installs to ~/.agents/skills/bilibili-note
python scripts/install.py --dry-run  # show what would be copied

The skill then appears in the dsh skill catalog and can be triggered with phrases like 「B站笔记」. The plugin, the skill-file install and the CLI all share the same implementation (scripts/bili_note.py).

Requirements

RequirementNotes
Python 3.8+stdlib only
yt-dlppip install -U yt-dlp — the only download channel
Bilibili login cookiesRequired for AI subtitles; see below
DSH >=0.2.0-rc.2 <0.3.0Only for the plugin/skill route

Permissions and external services

Worth knowing before you install, since this tool touches the network and your vault:

  • Network: talks to bilibili.com through yt-dlp only. It downloads subtitles, never video or audio (--skip-download is mandatory and verified).
  • Credentials: reads a Bilibili cookie file from $BILI_COOKIES or ./cookies.txt. It writes a normalized temporary copy next to the work dir for yt-dlp; it never uploads, logs, or commits cookies.
  • Filesystem: writes notes into the --note-dir you pass, plus a scratch work directory. Nothing outside those two paths is modified.
  • No telemetry, no extra dependencies, no reverse-engineered APIs.

Cookies (required)

Bilibili's AI-subtitle endpoint needs an authenticated session.

  1. Install the Get cookies.txt LOCALLY browser extension.
  2. Log into bilibili.com.
  3. Export cookies.txt.
  4. Put it in your working directory, or point at it:
export BILI_COOKIES=/path/to/cookies.txt      # Linux / macOS
$env:BILI_COOKIES = "C:\path\cookies.txt"     # PowerShell

Videos where the uploader supplied their own subtitles may work without this.

⚠️ Why you can't feed the export straight to yt-dlp

This is the single most surprising thing in this repository. That extension writes lines like:

.bilibili.com	FALSE	/	FALSE	1819635894	SESSDATA	xxxxx

The domain carries a leading dot, yet the host-only flag in column 2 is FALSE. Python's http.cookiejar asserts:

assert domain_specified == initial_dot

The mismatch raises, and yt-dlp refuses to load the entire file:

ERROR: invalid Netscape format cookies file '...': '.bilibili.com\tFALSE\t/...'

The practical symptom is nasty: subtitles never arrive, and the error looks like "this video has no subtitles." The fix is normalization — strip the leading dot and set the flag to FALSE (a host-only cookie is still sent to api.bilibili.com and friends, so the session is preserved). normalize_cookies() does this, plus filters to the bilibili domain and de-duplicates by domain/path/name. You never have to do it by hand.

Output directory

Nothing is hard-coded. Pick either:

bili-note note "<URL>" --note-dir "<vault>/Sources/Videos"    # explicit

export BILI_VAULT="/path/to/MyVault"                           # or environment
export BILI_TARGET_DIR="Sources/Videos"                        # optional, this is the default

Deliberately no built-in default vault path: hard-coding one "looks right" path silently creates an empty directory on someone else's machine, and notes vanish into it.

Usage

# fetch metadata + subtitles (subtitles only, never the video)
bili-note fetch "<URL>" --out ./work

# write the note straight from an existing work dir
bili-note write --work ./work --note-dir "<vault>/Sources/Videos" --content-file content.json

# one shot: fetch + write
bili-note note "<URL>" --note-dir "<vault>/Sources/Videos" [--content-file content.json]

# structural self-check
bili-note verify --note "<note path>"

# environment self-check: cookies / yt-dlp / output dir (no network)
bili-note selftest

selftest answers the question you will actually ask — "why did I get no subtitles?" — before you blame the code:

  ✓ cookie file: /home/me/cookies.txt
  ✓ has SESSDATA login: ...
  ✓ yt-dlp: /usr/local/bin/yt-dlp
  ✗ output dir: not configured (pass --note-dir, or set BILI_VAULT/BILI_TARGET_DIR)

fetch walks you through each step:

✓ cookie normalized: ... (33 bilibili cookies)
✓ metadata: <title> (<uploader>) | 12:34
  subtitle languages: danmaku, ai-zh, ai-en
✓ subtitles: ai-zh, 134 segments, 1625 chars
✓ manifest: /path/to/work/manifest.json

content.json — the judgment half

{
  "summary": "One sentence, 60-120 chars, conclusion first.",
  "body": "200-400 chars covering the argument and the conclusion.",
  "tags": ["认知", "人文"],
  "cards": ["CC_example"],
  "bullets": [
    {"time": 0,  "title": "Short heading", "text": "One sentence."},
    {"time": 23, "title": "Short heading", "text": "One sentence."}
  ]
}

time is seconds; the tool renders the MM:SS label and the jump link for you. title and cards are optional. Omit --content-file entirely to get a draft note with placeholders and status: draft.

What a note looks like

---
title: Video title
source: https://www.bilibili.com/video/BVxxxxxxxxx
author: Uploader
captured: 2026-01-01
duration: "12:34"
type: video-note
status: completed
needs_summary: false
tags: ["认知", "人文"]
---
> [!info] 视频信息
> **UP主**:Uploader | **时长**:12:34 | [原视频](https://www.bilibili.com/video/BVxxxxxxxxx)

## 一句话摘要
…
## 核心要点
|- [00:00](https://www.bilibili.com/video/BVxxxxxxxxx/?t=0s) **Heading**:One sentence.
|- [00:23](https://www.bilibili.com/video/BVxxxxxxxxx/?t=23s) **Heading**:One sentence.
## 总结
…
## 笔记标签
认知 | 人文
## 原始字幕
> [!quote]- 完整字幕(点击展开)
> …cleaned transcript, no timestamps or indices

The |- prefix on bullet lines looks like a broken table row, and it is — deliberately. A downstream archive checker matches ^\|- \[[0-9]{2}:[0-9]{2}\], so standard - list syntax would be rejected. All format constraints and their reasons live in docs/FORMAT.md.

Tests

No network, no cookies required:

python -m unittest discover -s tests -v

108 tests covering SRT parsing and timestamp cleanup (LF/CRLF/BOM, multi-line cues, over-1-hour offsets, HTML and ASS tags, literal < > in text, zero-width characters, duplicate rolling captions, empty cues), both timestamp formats, bullet-line contract, draft-literal contract, cookie normalization, URL normalization (tracking params and ?p=), anthology timestamp rebasing and subtitle-file selection, duplicate-part detection, on-disk write and de-duplication, verify positive/negative cases, the CLI wiring, Python minimum-version compatibility guards, and repository hygiene.

CI runs the same suite on Linux + Windows × Python 3.8/3.10/3.12 — see .github/workflows/ci.yml.

Known limitations

  • Bilibili only. Other yt-dlp-supported sites are out of scope.
  • Multi-part anthologies are merged and take a while. Two requests per part; a 2-hour 6-part anthology takes roughly 2 minutes. Pass ?p=6 to grab a single part instead. Jump links point at {anthology URL}/?t={cumulative}s, so they are exact when playing the anthology as a whole but not when you open one part standalone. That is inherent to merging, not a fixable bug.
  • Depends on Bilibili's AI subtitles. Videos without subtitles (and without uploader-supplied ones) are skipped. No speech-to-text — this tool deliberately does not pull in ffmpeg/whisper.
  • AI subtitles contain recognition errors. ai-zh is machine-generated and regularly mis-hears or drops words. The rule this project follows: quotes are copied verbatim and not silently corrected; anything recoverable from context is paraphrased without quote marks; anything unintelligible is dropped rather than guessed. See SKILL.md §2.6.
  • Timestamps over 1 hour use total minutes ([93:31]), not H:MM:SS — deliberate, to match the existing corpus.
  • ⚠️ Videos longer than 99 minutes trip a downstream checker. Because bullet labels are total minutes, labels past 100 minutes are 3 digits ([100:00], [123:49]). A validator using ^\|- \[[0-9]{2}:[0-9]{2}\] only accepts 2 digits and will under-count, flagging long videos as "too few bullet points." Measured on the 2:10:32 anthology: 24% of the timeline has 3-digit minutes, first at 100:00. Fix is to widen {2} to {1,3} downstream; this repo's checker does that. verify passes such notes but prints a warning.

Contributing

Issues and PRs welcome. Read docs/FORMAT.md before touching anything format-related, and keep python -m unittest discover -s tests green — TestDownstreamContract exists specifically to pin those contracts down.

License

MIT