Agent Skills 标准 · MIT · 零第三方依赖 · v1.14.4

让 AI 整理你的书签栏,
直改 JSON,不绕导出导入

Chrome / Edge 的书签底层就是一个纯 JSON 文件。绕开「导出 HTML → 导入」的追加地狱, 让 AI 按内容归类、重排、改名、去重、清理失效链接——重启浏览器即生效,开着同步自动同步到账号。

一句话定位 一段提示词打底,一份脚本保底——默认用脚本跑。

Python 仅标准库 离线 · 不联网 · 不上传 Windows / macOS / Linux 有脚本必用脚本
chrome://bookmarks
🔖 书签栏
🌐 淘宝网
🌐 GitHub
🌐 bilibili
🌐 大众点评
🌐 大众点评 重复
📁 新建文件夹
📁 新建文件夹 (1)
📁 新建文件夹 (2)
… 40 条随手乱放
🔖 书签栏
📁 购物 6
📁 新闻资讯 6
📁 技术开发 6
📁 学习资源 6
📁 视频娱乐 6
📁 生活工具 6
📁 博客与阅读 2
✅ 同目录重复已合并 · 失效链接已清理
40 条 · 平铺 + 3 个「新建文件夹」 sample/ · 零隐私演示数据
0
bm.py 子命令
0
项回归护栏
0
第三方依赖
0
行单文件实现
0
Chromium 系内核
0
CI 矩阵(3 OS × 2 Py)
01

为什么要绕开「导出 → 导入」

浏览器的导入是追加不是替换——整理完永远多出一个「已导入」文件夹,还得手工去重合并。

常规路线

导出 HTML → 整理 → 导入

  • 导入是追加,旧书签一条不少地还在
  • 多出「已导入 xxxx」文件夹,得手工合并
  • 目录层级、favicon、添加时间容易丢
结果:越整理越乱
本项目

直接编辑 Bookmarks JSON

  • 书签底层是纯 JSON、无加密,改它 = 改正式数据
  • 重启浏览器即生效,开同步自动同步到账号
  • 结构、id、时间戳原样保留
前提:浏览器必须完全退出

不是在弥补 AI 的能力不足,而是补工程纪律

说实话,让 AI 自由发挥整理书签,效果通常也不差——AI 完全有能力读 JSON、归类、去重、写回去。 但「能做」和「每次都做得对」之间差着安全距离:没有强制备份、改了什么不透明、写坏了靠运气。 本仓库补的是完整性、安全性、可靠性——让每一次整理都可回溯、可校验、可还原, 无论交给哪个 AI 跑,结果都一致。

02

三份交付物 · 从轻到全

同一套逻辑的三种形态,闸门由谁守是唯一区别。真实书签一律走最下面那级。

轻
PROMPT.md 无闸门

一段话 · 复制给任意 AI

零安装的纯文本提示词,把 0→7 流程压缩成一段话。备份做没做、写坏没坏,全靠 AI 自觉。

适合:不 clone / 一次性小改 / 先体验 / 分享给别人
中
SKILL.md 人肉守闸

Skill 化的流程与纪律

符合 Agent Skills 开放标准。先看结构 → 先提方案 → 拍板才写 → 复验 → 可还原,流程不变,闸门由 AI 守。

适合:拿不到脚本时的降级执行层
默认
scripts/bm.py 闸门锁进代码

把纪律锁进可验证的闸门

体检 GO/NO-GO、自动备份 + sha256、HTML 预览、原子写回、一键还原,全部锁在 1010 行零依赖代码里。

适合:正式整理真实书签 · 唯一推荐方式
判定铁律 工作区有 scripts/bm.py → 一律走脚本;有脚本却手改 JSON = 丢掉护栏,禁止。
03

架构全景

三条路跑同一条带循环的 0→7 流程,差别只在闸门由谁守。悬停任意节点看说明。

交付物层 · 从轻到全 PROMPT.md 一段话 · 无闸门 · 轻路径 SKILL.md 流程与纪律 · 人肉守闸 scripts/bm.py 10 子命令 · 闸门锁进代码 流程层 · 0→7 带循环(只有第 4 步写回) 0 · detect 定位(只读) 0 · preflight 体检 GO/NO-GO 1 · backup 底牌 2 · show 读准结构 ③ 循环区 · 绝不碰原文件 · 可无限次 3 · plan 重排到候选 3 · preview 肉眼核对 4 · finalize 唯一写回 · 原子替换 用户拍板后才执行 5 · verify / diff 机器校验 · 路径感知对账 6 · 重启验收 人眼确认 7 · restore 一键回到底牌 不满意 → 回底牌 → 回到循环区 数据层 Bookmarks(真身) Profile/<名称>/Bookmarks Bookmarks.backup-<ts> 底牌 + sha256 + manifest cand / preview.html 候选与预览(临时)
只读 / 准备 循环区(不动真身) 写操作(带安全闸) 校验 / 验收 数据
仓库随附示意图(与 README 同源,由 scripts/visualization/ 生成 · 自动适配明暗主题)
0→7 带循环主流程示意图
workflow.svg — 准备段只读 → 循环区反复确认 → 唯一写回 → 校验验收 → 不满意回底牌
三份交付物从轻到全示意图
deliverables.svg — PROMPT.md → SKILL.md → scripts/bm.py,闸门由谁守是唯一区别
04

核心:一条带循环的流程

只有 finalize 一步会真正改文件,其余都在内存 / 候选文件里折腾。悬停站点看细节。

循环区 · 反复确认 0 定位 · 体检 detect / preflight 1 备份底牌 backup 2 读准结构 show 3 plan 3 preview 4 写回真身 finalize 5 机器校验 verify / diff 6 重启验收 人眼确认 7 restore 回底牌
铁律 第 3 步是循环不是直线——没拿到用户明确的「就这版」,绝不执行第 4 步。
05

安全设计 · 为什么敢让它动真实数据

八道护栏,每道都对应一次真实踩坑。它们锁在代码里,不依赖 AI 的自觉。

两道安全闸

① 进程名检测(tasklist / pgrep);② Profile 占用锁(SingletonLock 存在即拒)——回答「跑着的是不是这一个 Profile」。

原子写回

先落 .tmp 再 os.replace,中途失败不会留下半个 JSON;候选结构非法直接拒绝写回。

写前自动兜底

finalize 自动复制 prescript,restore 自动复制 prerestore——漏做 backup 也不至于裸奔。

预览先行

写回前先把结构渲染成可折叠的本地 HTML 让你肉眼核对;预览和浏览器看到的一致,才证明脚本可信。

不自作主张删

去重只在同目录内合并,跨目录同链接保留;show 会逐条标注「同目录(会去重)/ 跨目录(保留)」。

数量护栏

候选 0 条直接拒绝,条数暴跌 <50% 大声告警——防「AI 改 JSON 把书签弄丢一半」。

目标闸门

目标存在却解析不出 roots 拒绝覆盖(防指到 Preferences);--from 与 --target 同文件也拒绝。

底牌先校验

restore 覆盖真身前先校验底牌能解析、有 roots——坏底牌直接拒绝,绝不连最后一份好副本也写坏。

云端不是备份,是复制品。 Chrome 书签同步是合并——本地的删除会跟着传播到所有设备。preflight 会在体检时点出这一点, 唯一的保险始终是磁盘上那份底牌。
06

工具箱 · 10 个子命令

scripts/bm.py:单文件、1010 行、仅 Python 标准库。只读 命令随便跑,写 命令带闸。

命令作用性质
detect 按 OS 环境变量自动定位各浏览器 Profile 的 Bookmarks(根路径不写死,跨 Win/mac/Linux),还能识别 Chromium / Brave / Vivaldi / Opera 只读
preflight 只读体检:存在 / 可读写 / JSON 合法 / 浏览器进程 / Profile 占用锁 / 是否开云端同步 → 给出 GO / NO-GO 只读
backup 改前时间戳底牌 + sha256 校验 + 打印可直接粘贴运行的还原命令(绝对路径) 写
show 打印真实结构(目录树 / 数量 / 重复 id / 重复 URL / checksum);--depth N 只看 N 层、--stats 只看体检;重复 URL 标出同目录还是跨目录 只读
plan 内存里按 --sort / --dedup 重排到候选文件,绝不碰原文件 写候选
preview 渲染成本地嵌套树 HTML(<details> 可折叠、无 JS),双击肉眼核对;--base 附「删 / 增 / 移动 / 改名 / 副本减少」差异 写候选
diff 路径感知对账:除增 / 删 URL 外,还能识别移动(同名链接换目录)、改名、副本减少(删掉多份同名同链中的一份) 只读
finalize 唯一动真身:先验候选与目标合法性(目标解析不出 roots 也拒,防误盖别的文件)+ 删 checksum + 改名陈旧 .bak + 原子写回(先 .tmp 再 replace);浏览器在跑 / Profile 被占用拒绝(除非 --force),写前自动再兜一份;--from 与 --target 同一文件则拒;候选 0 条拒绝、条数暴跌 <50% 告警 写
verify JSON 合法性 + 结构合法 + id 唯一 + 数量对账;传 --before 时额外给出变更分类(删 / 增 / 移动 / 改名 / 副本减少),与 diff 同口径 只读
restore 回退到底牌那一刻;与 finalize 同级安全闸(浏览器在跑拒绝)并自动兜底;覆盖前先校验底牌,坏底牌不碰真身 写
07

快速开始

三条路跑的是同一条 0→7 流程,区别只在闸门由谁守。真实书签走第一种。

clone 本仓库后,让 AI 调用 scripts/bm.py。体检、底牌、闸门、写回、校验、还原都锁在代码里。

bash
# 0 定位 + 体检(找出要整理哪个 Profile,拿到 GO 才继续)
python scripts/bm.py detect
python scripts/bm.py preflight --file "<Bookmarks>"

# 1 底牌(会打印 restore_cmd,先复制存好)
python scripts/bm.py backup --file "<Bookmarks>"

# 2 读准结构
python scripts/bm.py show --file "<Bookmarks>"

# 3 循环区:重排到候选 → 预览核对(可无限次,不碰真身)
python scripts/bm.py plan    --file "<Bookmarks>" --out cand --sort --dedup
python scripts/bm.py preview --file cand --base "<Bookmarks>" --out preview.html

# 4 满意后写回(浏览器已完全退出)
python scripts/bm.py finalize --from cand --target "<Bookmarks>"

# 5 校验 & 6 重启浏览器验收
python scripts/bm.py verify --file "<Bookmarks>" --before "<底牌>"

# 7 不满意:一键回退到底牌那一刻
python scripts/bm.py restore --backup "<底牌>" --target "<Bookmarks>"
<Bookmarks> 由 detect 给出;Windows 一般形如 %LOCALAPPDATA%\Google\Chrome\User Data\Default\Bookmarks,Edge 把 Google\Chrome 换成 Microsoft\Edge。

把 SKILL.md 加载进 AI(联网装 skill、或直接把文件交给它),流程不变,闸门由 AI 人肉守。

text · 提示词
加载 SKILL.md,帮我整理书签。

流程按 0→7 走:定位 → 体检 → 备份 → 读结构
→〔循环:提方案 → 我确认 → 再改〕
→ 我拍板才写回 → 校验 → 重启验收
→ 不满意用底牌还原。

没有 scripts/bm.py 时按「仅提示词时怎么做」的硬约束执行,
不要假装跑 bm.py。
这一模式没有进程探测、没有 sha256 底牌校验、没有 HTML 预览、没有一键 restore——先备份、再确认、再写,写坏了用底牌手动盖回。

把 PROMPT.md 整段复制给任意聊天 AI,再补一句「我的书签文件路径是 ……」。零安装,也零闸门。

text · 提示词
你是"浏览器书签整理助手"。Chrome/Edge 等 Chromium 浏览器里,
书签本质是一个 JSON 文件,直接改文件 = 正式修改书签,
重启浏览器后生效(开着同步会自动同步)。
不要走"导出 HTML → 导入"——导入是追加不是替换。

动手前按顺序做完这三件事:
1. 定位书签文件(找不到就问,不许编造路径)
2. 请我确认浏览器已完全退出(含托盘/后台图标)
3. 备份为 Bookmarks.backup-<YYYYMMDD-HHMMSS>,并把路径告诉我

然后:解析结构给我确认 → 在副本里整理 → 我拍板后写回
→ 复验 → 重启验收 → 不满意用备份盖回。

绝对不做:不经我逐条同意就删任何书签;改动 date_added 的数值。
适合:不 clone / 一次性小改 / 先体验 / 分享给别人。正式整理请回到第一个 Tab。
1

先在假数据上跑一遍

scripts/test/sample/ 是随仓库入库的通用站点演示样例(before 乱 40 条 / after 归好 38 条,零隐私),跑完整流程也碰不到真实数据。

2

预览阶段零写入

plan / preview / diff 一个字节都不写进真身,可以无限次预览到满意为止;finalize 是唯一写入口。

3

把 restore_cmd 存好

backup 会当场打印一行绝对路径还原命令。看到它的那一刻就生效了——先复制到记事本,再继续往下走。

08

测试与质量

54 项零依赖回归,约 1 秒跑完。它锁的是安全不变量,不是覆盖率。

护栏增长曲线

版本回归项数关键变化
v1.6.028首次引入 run_tests.py
v1.7.032云端同步感知
v1.8.042占用锁 + 最小参数路径
v1.9.046底牌校验 / 拒绝自我覆盖
v1.10.048数量护栏(防丢书签)
v1.13.054脏输入边界加固 6 项
v1.14.454README 排版系统重构,行为零变化

这 54 项锁住了什么

  • 去重保留最新、跨目录不被误删
  • plan 有没有写过源文件
  • 两个安全闸(含 Profile 占用锁)是否还拦得住
  • 写回是否原子、结构闸门是否还生效
  • 移动 / 改名 / 副本减少的分类对不对
  • 每个命令最省参数组合还能不能跑到底
  • 脏输入边界:超大门户时间戳、非 UTF-8 垃圾文件、含引号 / 尖括号的名称与 URL、残缺节点结构
这套断言做过变异验证:故意把「保留最新一条」改反,测试立刻变红——它真的有约束力,不是摆设。

样例归类分布 · sample/after(38 条归入 7 个类目)

零隐私 · 入库

scripts/test/sample/ 是随仓库入库的通用站点演示样例:before 40 条乱放, after 38 条全部归好类,净变化 -2(去重掉 1 条同目录重复 + 删掉 1 条失效链接)。 make_sample.py 全确定性,重跑逐字节一致。

验证命令预期输出
show --stats40 条 · 1 组同目录重复 URL
plan --sort --dedup40 → 39,原文件未动
diff before → after删 1 / 增 0 / 移动 38 / 改名 0 / 副本减少 1
verify afterJSON 合法 · 无 checksum · 38 条 · 无结构问题
CI 矩阵
3 OS × 2 Python

Windows / macOS / Linux × Python 3.9 / 3.11,跑同一套测试 + 样例端到端冒烟。

运行时长
≈ 1 秒

零第三方依赖,python scripts/test/run_tests.py 一条命令,改完 bm.py 必跑。

浏览器状态
全部 monkeypatch

测试不碰真实 Profile——浏览器进程、占用锁一律模拟,跑测试不需要关浏览器。

09

仓库结构

真实目录树。灰色标注的 scripts/test/Bookmarks.* 含隐私、被 .gitignore 屏蔽,不入库。

  • ▾ chrome-bookmarks-organize/
    • PROMPT.md — 零安装轻路径:一段可复制给任意 AI 的提示词(无闸门)
    • SKILL.md — 给 AI 看的操作规范(默认脚本 + 无脚本降级 + 0→7 流程 + Pitfalls)
    • README.md — 项目主页、三种用法、安全设计、快速上手
    • MAINTENANCE.md — 长期维护:AI/脚本分工合同、质量台账、边界矩阵、变更日志
    • LICENSE — MIT
    • ▾ .github/workflows/
      • test.yml — 三平台 × 两 Python 版本回归 CI
      • pages.yml — Pages 部署 workflow(当前未启用,走经典模式 main/docs)
    • ▾ scripts/
      • bm.py — 工具箱主体:单文件 1010 行、零第三方依赖、10 个子命令
      • ▾ visualization/
        • generate_workflow.py — 生成 docs/workflow.svg
        • generate_deliverables.py — 生成 docs/deliverables.svg
      • ▾ test/
        • run_tests.py — 零依赖回归测试(54 项)
        • sample/ — 入库的通用站点演示样例(before 40 / after 38,零隐私)
        • Bookmarks.before / .after — 真实快照(含隐私,不入库)
    • ▾ project_overview/
      • index.html / style.css / script.js / charts.js — 本全景观览站源目录
      • assets/ — 示意图副本(workflow.svg / deliverables.svg)
    • ▾ docs/
      • GitHub Pages 部署源(经典模式 main/docs):全景观览站副本 + 两张 SVG + .nojekyll
    • project_overview.html — 根目录跳转入口(meta refresh)
10

已知边界

不吹能力,先把做不到的事写清楚。

🚫

没有热编辑

改文件时浏览器必须完全关着(含托盘后台),这是机制限制。

🕒

时间戳别手推

date_added 是自 1601-01-01 的微秒,bm.py 已自动转日期显示。

🔍

只管结构,不判内容

不判断链接是否失效、内容好坏;失效链接的取舍由你拍板。

🧭

mac / Linux 未实测

detect 的 macOS / Linux 分支与更多内核已实现,但尚未在非 Windows 机器上实测。

☁️

同步是双刃剑

本地删除会同步传播到所有设备;restore 也会退回底牌之后从他端同步来的书签。

🧩

AI 判断未脚本化

归类、改名、移动仍是 AI 的判断;plan 目前只脚本化 --sort / --dedup。

11

文档索引

链接指向 GitHub 仓库内的原文(本站只部署全景观览页本身)。