skill-forge-hub 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +82 -150
  3. package/annual-report/SKILL.md +23 -3
  4. package/annual-report/resources/data-collection.md +20 -4
  5. package/annual-report/resources/disk-and-html.md +3 -3
  6. package/annual-report/resources/reference.html +31 -10
  7. package/annual-report/resources/usage-guide.md +8 -0
  8. package/annual-report/user-config.md +5 -5
  9. package/article-to-html/SKILL.md +26 -7
  10. package/article-to-html/design-system.md +9 -3
  11. package/article-to-html/resources/reference.html +631 -0
  12. package/article-to-html/resources/usage-guide.md +9 -1
  13. package/article-to-html/user-config.md +6 -3
  14. package/cli.js +2 -2
  15. package/daily-report/SKILL.md +23 -3
  16. package/daily-report/resources/content-rules.md +1 -1
  17. package/daily-report/resources/data-collection.md +24 -4
  18. package/daily-report/resources/disk-and-html.md +2 -2
  19. package/daily-report/resources/reference.html +24 -3
  20. package/daily-report/resources/usage-guide.md +8 -0
  21. package/daily-report/user-config.md +5 -5
  22. package/deck-stage/SKILL.md +15 -4
  23. package/deck-stage/resources/cover-template.html +3 -3
  24. package/deck-stage/resources/data-schema.md +11 -1
  25. package/deck-stage/resources/pptx-builder.js +1 -1
  26. package/deck-stage/resources/usage-guide.md +9 -2
  27. package/docs/architecture.md +89 -0
  28. package/docs/images/article-to-html.png +0 -0
  29. package/docs/images/daily-report.png +0 -0
  30. package/docs/images/deck-stage.png +0 -0
  31. package/docs/images/magic-deck.png +0 -0
  32. package/docs/images/meeting-minutes.png +0 -0
  33. package/docs/images/prompt-pouch.png +0 -0
  34. package/docs/install.md +71 -0
  35. package/magic-deck/SKILL.md +23 -8
  36. package/magic-deck/resources/content-guide.md +5 -4
  37. package/magic-deck/resources/deck-spec.md +18 -11
  38. package/magic-deck/resources/reference.html +110 -32
  39. package/magic-deck/resources/usage-guide.md +10 -2
  40. package/magic-deck/user-config.md +4 -4
  41. package/meeting-minutes/SKILL.md +51 -0
  42. package/meeting-minutes/resources/content-rules.md +57 -0
  43. package/meeting-minutes/resources/disk-and-html.md +26 -0
  44. package/meeting-minutes/resources/meeting-type-dictionary.md +24 -0
  45. package/meeting-minutes/resources/reference.html +436 -0
  46. package/meeting-minutes/resources/usage-guide.md +63 -0
  47. package/meeting-minutes/user-config.md +56 -0
  48. package/meta-forge/SKILL.md +6 -6
  49. package/meta-forge/resources/forge-rules.md +60 -10
  50. package/meta-forge/resources/usage-guide.md +7 -2
  51. package/meta-forge/user-config.md +2 -1
  52. package/monthly-report/SKILL.md +62 -0
  53. package/monthly-report/resources/content-rules.md +40 -0
  54. package/monthly-report/resources/data-collection.md +44 -0
  55. package/monthly-report/resources/date-parsing.md +18 -0
  56. package/monthly-report/resources/disk-and-html.md +29 -0
  57. package/monthly-report/resources/industry-dictionary.md +21 -0
  58. package/monthly-report/resources/reference.html +531 -0
  59. package/monthly-report/resources/usage-guide.md +75 -0
  60. package/monthly-report/user-config.md +53 -0
  61. package/package.json +9 -2
  62. package/prompt-pouch/SKILL.md +17 -2
  63. package/prompt-pouch/resources/data-format.md +1 -1
  64. package/prompt-pouch/resources/reference.html +56 -24
  65. package/prompt-pouch/resources/usage-guide.md +10 -3
  66. package/quarterly-report/SKILL.md +63 -0
  67. package/quarterly-report/resources/content-rules.md +42 -0
  68. package/quarterly-report/resources/data-collection.md +46 -0
  69. package/quarterly-report/resources/date-parsing.md +19 -0
  70. package/quarterly-report/resources/disk-and-html.md +22 -0
  71. package/quarterly-report/resources/industry-dictionary.md +21 -0
  72. package/quarterly-report/resources/reference.html +509 -0
  73. package/quarterly-report/resources/usage-guide.md +76 -0
  74. package/quarterly-report/user-config.md +53 -0
  75. package/spec-doc2spec/SKILL.md +21 -22
  76. package/spec-doc2spec/resources/checklist.md +7 -0
  77. package/spec-doc2spec/resources/images.md +14 -5
  78. package/spec-doc2spec/resources/structure.md +19 -10
  79. package/spec-doc2spec/resources/usage-guide.md +10 -8
  80. package/spec-doc2spec/user-config.md +2 -2
  81. package/spec-spec2doc/SKILL.md +4 -4
  82. package/spec-spec2doc/resources/checklist.md +6 -0
  83. package/spec-spec2doc/resources/pdf-path.md +1 -0
  84. package/spec-spec2doc/resources/usage-guide.md +2 -2
  85. package/template/SKILL.md +18 -14
  86. package/template/resources/README.md +1 -1
  87. package/template/resources/usage-guide.md +17 -0
  88. package/template/user-config.md +28 -0
  89. package/weekly-report/SKILL.md +23 -3
  90. package/weekly-report/resources/content-rules.md +1 -1
  91. package/weekly-report/resources/data-collection.md +24 -4
  92. package/weekly-report/resources/disk-and-html.md +2 -2
  93. package/weekly-report/resources/reference.html +24 -3
  94. package/weekly-report/resources/usage-guide.md +8 -0
  95. package/weekly-report/user-config.md +5 -5
@@ -0,0 +1,53 @@
1
+ # 用户配置(升级技能时本文件不会被覆盖)
2
+
3
+ > 你的个人配置全放在这里。skill-forge 升级技能时官方只更新 SKILL.md 与 resources/,
4
+ > 本文件始终保留你的版本——落盘目录、格式、角色画像、自定义模板放心改。
5
+ > 官方升级若带来新配置点,会另存 `user-config.md.upstream` 对照文件到同目录,
6
+ > 你按需查看并手动合并新配置点到本文件。
7
+
8
+
9
+ ## ⚙️ 默认配置(用户可手动修改;临时口头要求永远优先)
10
+
11
+ ```yaml
12
+ DISK: true # 是否落盘写文件;false = 默认只在对话输出,不写文件不开浏览器
13
+ CONFIG_VERSION: 3 # 配置结构版本:skill 升级时若配置结构变化会递增;AI 每次执行前对比 SKILL.md「配置版本机制」节声明的当前版本,不一致时按 SKILL.md 的迁移规则处理(先备份本文件为带时间戳 .bak,再迁移,最后对话告知用户)
14
+ FORMATS: [md, txt, html, content-png] # 落盘哪些格式(数组,可删减/增,如 [md, html] / [md, txt, html](不截图);content-png = 内容区截图(四张分节卡片整体,不含头部标题/复制按钮/页脚),删除该项即不截图;不影响对话中的 md 正文输出)
15
+ DIR: auto # 落盘根目录:auto = 按当前系统自动选 DIR_MAC / DIR_WIN(也可直接写死某个绝对路径)
16
+ DIR_MAC: ~/reports # macOS 落盘根目录(自动按目标月份建子目录 2026-11 式样;目录不存在时回退用户主目录下 reports)
17
+ DIR_WIN: %USERPROFILE%\reports # Windows 落盘根目录(自动按目标月份建子目录 2026-11 式样;目录/盘符不存在时回退用户主目录下 reports)
18
+ OPEN_HTML: true # 落盘后是否自动用浏览器打开 html(FORMATS 不含 html 时忽略)
19
+ THEME: tech # html 页面主题:tech 深蓝科技(默认)/ biz 浅色商务 / mono IDEA 黑亮 / light IDEA 白亮 / warm 温暖渐变;生成时写 <html data-theme="THEME值"> 定默认,页面右下角换肤坞五色点随点随换(浏览器本地记忆(键按页内嵌唯一 ID 隔离、多份产物互不串台、改名/移动目录记忆不丢;生成时头部写 `<meta name="monthly-id" content="<UUID>">`,每次新 UUID),?shot 截图模式自动隐藏,打印隐藏)
20
+ TEMPLATE: default # 报告模板:default = 内置四段式(月度概览/本月关键成果/问题与改进/下月计划);custom = 使用下方「📝 自定义模板」节;口头临时指定模板仅当次生效
21
+ ROLE: 全栈开发工程师(企业内技术开发) # 用户默认职业角色与主要工作内容(两者并存:职业名 + 括号内工作内容,生成内容/术语/量化指标/里程碑/风险话术全部按此画像走);用户随口描述职业时(如「我搞装修的,天天跑工地」)→ AI 提炼为规范表述(装修项目经理(负责工地现场管理、施工进度与质量巡检))更新此处;说「以 XX 的身份写」→ 当次临时换角色不改配置;说「以后默认用 XX 角色 / 我的职业是 XX / 我的主要工作是 XX」→ 永久更新此处
22
+ CONFIRM: never # 落盘前确认:never = 直接生成落盘不确认(默认);text = 纯文字整理模式先出效果确认后再落盘;always = 任何方式生成都先确认;临时说「先看看效果」当次先确认、说「不用确认」当次跳过
23
+ DATA_SOURCES: [] # 数据源清单(升级不覆盖;AI 每次生成前 Read 本文件按此清单收集;空清单 = 只按会话/文字内容生成)。每项:name 唯一名称 + type 类型 + 路径。三种类型示例(把下方 # 注释示例改成你的真实数据源后填入上方数组;未知 type(拼写错误)忽略该项并在生成时一句话提示,不中断):
24
+ # - name: 主项目仓库 # 名称:唯一 key(重名视为同一数据源;口述「只聚合 xxx」按 name 匹配)
25
+ # type: git # git = 代码仓库(git log 聚合提交;路径不存在/非代码仓库时静默跳过)
26
+ # mac: ~/Projects/main-app # macOS 路径(绝对路径或 ~ 开头)
27
+ # win: D:\Projects\main-app # Windows 路径;「-」= 该系统不存在,自动跳过
28
+ # - name: 月例会纪要
29
+ # type: file # file = 普通文件/目录(文件 Read 全文、目录逐个 Read 文本文件,二进制跳过;路径无效静默跳过)
30
+ # mac: ~/Documents/meeting-notes.md
31
+ # win: -
32
+ # - name: 数据接口
33
+ # type: remote # remote = 远程网络源(只需 url 字段忽略 mac/win;AI 联网拉取内容提取要点;失败静默跳过不阻塞;仅收集时联网,HTML 产物仍零外链)
34
+ # url: https://example.com/data.json
35
+ ```
36
+
37
+ > 临时口头要求(仅对当次生效,不修改上方配置):说「不落盘/别写文件」→ 当次 DISK=false;说「写到桌面/存到 ~/report(macOS)或 D:\report(Windows)」→ 当次改用该 DIR;说「只要 md / 只出 html / 只要内容区截图」→ 当次只落指定格式;说「这次不截图」→ 当次不生成内容区截图;说「只要截图/重新截个图」→ 当次只对现有 html 执行内容区截图(不重新收集数据、不重写 md/txt/html 内容文件);说「别开浏览器」→ 当次 OPEN_HTML=false;说「这次按 xxx 模板来」→ 当次临时换模板(不改配置);说「以后都用这个模板」→ 自动写入下方「📝 自定义模板」节并把 TEMPLATE 改为 custom(永久生效);说「先看看效果/先出效果再落盘」→ 当次先出效果确认后再落盘;说「不用确认/直接落盘」→ 当次跳过确认直接落盘。说「页面用浅色商务主题/浅色主题」→ 当次 THEME=biz;说「以后默认用暖色主题」→ 永久改 THEME=warm。
38
+
39
+ ## 📝 自定义模板(TEMPLATE: custom 时启用,用户可手改,适配各类岗位)
40
+
41
+ 把顶部 TEMPLATE 改为 custom 后,按下面结构生成报告(段名、段数、条目格式均可改):
42
+
43
+ ```text
44
+ 段一:月度工作概述(每条:概述 - 量化结果)
45
+ 段二:本月重点成果(每条:成果描述 - 完成时间 - 影响)
46
+ 段三:问题与改进(每条:问题 - 影响 - 改进措施)
47
+ 段四:下月工作计划(每条:计划描述 - 预期目标 - 时间节点)
48
+ ```
49
+
50
+ > 只写段结构与条目格式即可;未写明的细节(中文顿号序号、生成时间行、落盘行为、HTML 样式)沿用默认规范。
51
+
52
+ ---
53
+ > 更多用法见 SKILL.md 的「生成流程」与 resources/ 分册。
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "skill-forge-hub",
3
- "version": "1.0.4",
4
- "description": "SkillForge (技能锻造坊) — a curated collection of AI craft skills. Install once, then pick skills interactively: daily/weekly/annual reports, article-to-HTML, magic-deck slides, deck-stage PPTX, prompt-pouch manager, Pandoc doc converters, meta-forge.",
3
+ "version": "1.0.6",
4
+ "description": "SkillForge (技能锻造坊) — a curated collection of AI craft skills. Install once, then pick skills interactively: daily/weekly/monthly/quarterly/annual reports, meeting minutes, article-to-HTML, magic-deck slides, deck-stage PPTX, prompt-pouch manager, Pandoc doc converters, meta-forge.",
5
5
  "bin": {
6
6
  "skill-forge": "cli.js"
7
7
  },
@@ -9,8 +9,11 @@
9
9
  "cli.js",
10
10
  "daily-report",
11
11
  "weekly-report",
12
+ "monthly-report",
13
+ "quarterly-report",
12
14
  "annual-report",
13
15
  "article-to-html",
16
+ "meeting-minutes",
14
17
  "magic-deck",
15
18
  "deck-stage",
16
19
  "spec-doc2spec",
@@ -18,6 +21,7 @@
18
21
  "meta-forge",
19
22
  "prompt-pouch",
20
23
  "template",
24
+ "docs",
21
25
  "README.md",
22
26
  "CHANGELOG.md",
23
27
  "LICENSE"
@@ -31,6 +35,9 @@
31
35
  "daily-report",
32
36
  "weekly-report",
33
37
  "annual-report",
38
+ "meeting-minutes",
39
+ "quarterly-report",
40
+ "monthly-report",
34
41
  "article-to-html",
35
42
  "magic-deck",
36
43
  "deck-stage",
@@ -42,7 +42,7 @@ disable-model-invocation: false
42
42
  1. **初始化**(目标目录无 `prompt-pouch.html` 时):
43
43
  - **已有页面分支**:用户说「创建/生成」但目标目录已有 prompt-pouch.html → AskUserQuestion 三选项:A 打开现有页面(推荐,数据无损);B 覆盖重建——旧页面先复制 .bak-时间戳,仅重置页面为新版 reference.html(DATA_DIR/BACKUP_DIR 数据目录一概不动,用户数据绝不丢);C 取消不创建。默认推荐 A
44
44
  - **目录确认**:用户未提目录 → 用配置 `DIR`;`CONFIRM: true` 时先 AskUserQuestion 确认(选项:用默认目录 / 换目录);用户已说「放到 XX 目录」→ 直接用该目录(本次会话有效,不改配置文件)
45
- - 复制 `resources/reference.html` → `<DIR>/prompt-pouch.html`(原样复制,不修改任何样式与脚本;唯一例外:html 根标签 `data-theme` 属性值设为配置 `THEME`——reference 默认 "gold",仅当配置非 gold 时替换该属性值)
45
+ - 复制 `resources/reference.html` → `<DIR>/prompt-pouch.html`(原样复制,不修改任何样式与脚本;仅两处例外:①html 根标签 `data-theme` 属性值设为配置 `THEME`——reference 默认 "gold",仅当配置非 gold 时替换该属性值;②head 中 `<meta name="pouch-id" content="...">` 的 content 替换为本次用 crypto.randomUUID() 新生成的全局唯一 ID——标准 UUID v4(十六进制 8-4-4-4-12 节,禁止手写变体、禁止沿用 reference 的占位 ID REF-POUCH-0000、禁止两份锦囊共用同一 ID;复制文件副本=同一身份共享数据);落盘写文件前顺扫 <DIR> 下已有 html 的 pouch-id meta 查重,撞号重掷至不重复)
46
46
  - 创建 `<DIR>/<DATA_DIR>/` 与 `<DIR>/<BACKUP_DIR>/` 子目录(配置为空串则跳过、平铺根目录);生成 `<DIR>/<DATA_DIR>/prompts.json`:`INIT_DATA: example` 时写入「各职业通用」示例五组(写作输出/沟通协作/规划执行/复盘成长/提问艺术,每组 3 条,标题与正文按下方「## 默认示例数据」清单写,**每条必带 createdAt 当前时间(YYYY-MM-DD HH:mm:ss,写到时分秒)**);`empty` 时写空结构(version + 空 groups/prompts)
47
47
  - 收尾提示启动方式:`cd <DIR> && python3 -m http.server <PORT>`(Windows 无 python3 时 `py -m http.server`),浏览器访问 `http://localhost:<PORT>/prompt-pouch.html`(HTTP 才能读 prompts.json;file:// 直开回退缓存快照)
48
48
  2. **维护**(页面已存在时):读 `<DIR>/<DATA_DIR>/prompts.json` → 按用户意图修改 → 写回(UTF-8、2 空格缩进、保留 version 字段)→ 提醒用户刷新页面
@@ -65,11 +65,26 @@ disable-model-invocation: false
65
65
  - 条目少(≤3 条)时两段可合并一次确认:报完整方案表(条目 + 标签 + 分组 + 插值建议),一次确认
66
66
  6. **使用咨询**(用户只问「锦囊怎么用」等用法、未要求生成或修改)→ 读 `resources/usage-guide.md`,将其内容原样输出(首行标题改为「锦囊使用指南」),不读写任何文件
67
67
 
68
+
69
+ ## 🔧 报修处理流程(用户报页面问题时)
70
+
71
+ 用户说「锦囊页面效果不对 / 布局乱了 / 卡片显示异常 / 交互坏了」(常附截图或指出具体现象)→ 按以下流程处理:
72
+
73
+ 1. **立标准**:先 Read 本 skill 目录 `resources/reference.html`——它就是设计标准答案;再 Read `<DIR>/<DATA_DIR>/prompts.json` 确认数据本身合法(schema / group 引用 / order 连续)
74
+ 2. **分诊**:数据问题(读不到 / 卡数不对 / 分组错乱)→ 修 prompts.json;页面问题(样式 / 布局 / 交互)→ 对照 reference.html 比对那份 `<DIR>/prompt-pouch.html` 的跑偏处
75
+ 3. **修复**:页面跑偏 → 以 reference.html 为准重新复制覆盖 `<DIR>/prompt-pouch.html`(用户数据 prompts.json 一概不动,绝不丢);数据问题 → 重读最新文件后按 data-format.md 修正写回
76
+ 4. **自证**:Playwright headless(channel="chrome")→ 起本地服务 → 挂 pageerror 零容忍 → 断言卡片数等于 prompts.json 条数 → 截图 Read 自查
77
+ 5. **汇报**:一句话说清问题根因 + 修复了什么 + 附截图;若根因在 reference.html 自身,顺修 reference.html 并在汇报中说明「参考模板已同步修正」
78
+
79
+ ## 产物升级(回炉)
80
+
81
+ 生成/初始化页面时头部写版本戳 `<meta name="sf-template" content="prompt-pouch@2">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧锦囊/回炉旧页面/旧锦囊换新样式」时:扫 `<DIR>` 下 `prompt-pouch.html` 读版本戳筛出旧版(无版本戳或缺少 `<meta name="pouch-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/有无用户数据)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本;深升级(DOM 结构变化)从 reference.html 重建,**必须沿用原页 pouch-id meta 值**(IndexedDB 用户数据按 pouch-id 命名空间存取,换 ID = 数据失联,重建后原收藏/分组照旧读回),`<DIR>/<DATA_DIR>/prompts.json` 数据文件一概不动,先备份旧页 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成/初始化新锦囊时顺扫 `<DIR>` 读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版锦囊,说『把我旧锦囊都升级成新样式』即可一键升级」,不让用户背触发语。
82
+
68
83
  ## ⚙️ 配置与自定义主题
69
84
 
70
85
  **执行本 skill 前必须先 Read 同目录 `user-config.md`**:目录(DIR/DIR_WIN)、端口(PORT)、初始化数据(INIT_DATA)、确认开关(CONFIRM)、主题(THEME)等默认配置都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留。
71
86
 
72
- **THEME 主题机制**:页面内置五套主题——gold 暖棕金(默认)/ tech 深蓝科技 / mono IDEA 黑亮(JetBrains New UI Dark 官方色系,编辑区 #1e1f22 + 面板 #2b2d30)/ light IDEA 白亮(IntelliJ Light 官方色系)/ mint 薄荷绿。初始化复制 reference.html 后,将 html 根标签 `data-theme` 属性值设为配置 `THEME`(仅此一处修改);页面右下角「换肤坞」色点可随时切换主题,选择经浏览器 localStorage 持久(key: sf-pouch-theme),刷新后保持;localStorage 优先级高于根标签 data-theme。已初始化的页面改配置 THEME 不追溯——用户手动换过主题即以其选择为准。
87
+ **THEME 主题机制**:页面内置五套主题——gold 暖棕金(默认)/ tech 深蓝科技 / mono IDEA 黑亮(JetBrains New UI Dark 官方色系,编辑区 #1e1f22 + 面板 #2b2d30)/ light IDEA 白亮(IntelliJ Light 官方色系)/ mint 薄荷绿。初始化复制 reference.html 后,将 html 根标签 `data-theme` 属性值设为配置 `THEME`(仅此一处修改);页面右下角「换肤坞」色点可随时切换主题,选择经浏览器 localStorage 持久(key: pouch:<pouch-id>-theme,按页内嵌唯一 ID 命名空间隔离、多份锦囊互不串台、改名/移动目录记忆不丢),刷新后保持;localStorage 优先级高于根标签 data-theme。已初始化的页面改配置 THEME 不追溯——用户手动换过主题即以其选择为准。
73
88
 
74
89
  **配置版本机制(升级保护)**:user-config.md 头部 `CONFIG_VERSION` 标识结构版本,本 skill 当前要求版本为 4;配置结构如有变化必须同步更新此版本号与迁移说明。升级 skill 后若发现新版本结构(如 v2 新增 THEME 字段)而用户配置是旧版:先备份旧配置为 `user-config.md.bak-时间戳`,将旧值迁移进新结构(保留用户已有 DIR/PORT/INIT_DATA/CONFIRM,缺失字段补默认值),更新 CONFIG_VERSION,最后用一句话告知用户配置已升级、旧文件备份在哪。v4 特例:用户配置 DATA_DIR: cache(v3 旧默认、非用户显式自定义)→ 目录改名 cache→data(先复制 .bak-时间戳)并同步更新配置值;用户显式自定义过其它目录名则尊重其选择不动。 **无法迁移项处理**(值域失效 / 语义漂移 / 数据不兼容):三绝不——绝不静默(无法迁移项停下问,不猜值)、绝不丢失(旧值永远在备份)、一次说清(升级报告三段式:⚠️ 版本与备份路径 / ✅ 已自动迁移 / 🟡 无法迁移项逐条附原因+影响+建议替代);随后 AskUserQuestion 三选项(A 用建议值 / B 用户给新值 / C 保持旧配置——不更新 CONFIG_VERSION,每次执行再提醒);报告必附回滚一句话;数据文件(prompts.json)迁移前先复制 .bak-时间戳,能映射则映射、不能则写兼容层(旧 id 兼容保留即范例)或留备份提示手动整理
75
90
 
@@ -63,6 +63,6 @@
63
63
  | 使用频率 | 复制时页面自动累加 `useCount`,倒序 | 页面自动(浏览器本地态) |
64
64
  | 手动顺序 | `order` 升序 | AI 按「复制变更指令」重写 order |
65
65
 
66
- - 排序模式选择、使用统计、收藏均存浏览器本地(IndexedDB + localStorage 镜像),**不写数据文件(prompts.json)**,AI 无需落盘这些字段
66
+ - 排序模式选择、使用统计、收藏均存浏览器本地(IndexedDB 库名 pouch-db-<pouch-id> + localStorage 镜像键 pouch:<pouch-id>-userstate,按页内嵌唯一 ID 命名空间隔离:多份锦囊互不串台、改名/移动目录数据不丢、复制文件副本=同一身份共享数据),**不写数据文件(prompts.json)**,AI 无需落盘这些字段
67
67
  - 用户在「最近添加/最近使用/使用频率」模式下拖动卡片或点 ▲▼,页面自动切回「手动顺序」并提示;随后按指令重写 order
68
68
  - 写 order 时注意:手动顺序只约束组内,跨组顺序无意义(页面按分组展示)
@@ -3,6 +3,8 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="sf-template" content="prompt-pouch@2">
7
+ <meta name="pouch-id" content="REF-POUCH-0000">
6
8
  <title>锦囊 Prompt Pouch — 提示词管理台</title>
7
9
  <style>
8
10
  /* ============ 锦囊 · 深棕金配色 ============ */
@@ -61,7 +63,7 @@
61
63
  [data-theme="mono"] .bk-item,
62
64
  [data-theme="mono"] .detail-content{ background:rgba(223,225,229,.06); }
63
65
  [data-theme="mono"] .theme-dock .th-dot[data-theme="mono"]{ border:1.5px solid rgba(94,154,255,.6); }
64
- [data-theme="mono"] body{ background:var(--bg); } /* 主体纯 #1e1f22:去掉顶部光晕/160° 渐变,消除上灰下黑断层(JetBrains New UI Dark 编辑区同色);四层氛围独立于 body,mono 下星点换装灰白、条纹灰白不泛蓝 */
66
+ [data-theme="mono"] body::before{ display:none; } /* mono 纯色:关闭顶部光晕/160° 渐变氛围层,消除上灰下黑断层(JetBrains New UI Dark 编辑区同色);四层氛围独立于 body,mono 下星点换装灰白、条纹灰白不泛蓝 */
65
67
 
66
68
  /* ═══ light IDEA 白亮:IntelliJ Light 官方色系(白编辑区 + 浅灰面板 #f2f2f2 + IDEA 蓝强调) ═══ */
67
69
  [data-theme="light"]{
@@ -92,7 +94,7 @@
92
94
  [data-theme="light"] .bk-item,
93
95
  [data-theme="light"] .detail-content{ background:#f7f9fb; }
94
96
  [data-theme="light"] .theme-dock .th-dot[data-theme="light"]{ border:1.5px solid rgba(38,117,191,.5); }
95
- [data-theme="light"] body{ background:var(--bg); } /* 主体纯白 #ffffff:去掉顶部光晕/160° 渐变,对齐 IntelliJ Light 编辑区;四层氛围独立于 body */
97
+ [data-theme="light"] body::before{ display:none; } /* light 纯白:关闭顶部光晕/160° 渐变氛围层,对齐 IntelliJ Light 编辑区;四层氛围独立于 body */
96
98
  [data-theme="mint"]{ /* 薄荷绿 */
97
99
  --bg:#0d1a12; --bg2:#12241a;
98
100
  --panel:#182f22; --panel2:#1e3a2a;
@@ -109,14 +111,19 @@
109
111
  *{ box-sizing:border-box; margin:0; padding:0; }
110
112
  html,body{ height:100%; }
111
113
  body{
112
- background:
113
- radial-gradient(1200px 500px at 70% -10%, var(--gold-dim), transparent 60%),
114
- linear-gradient(160deg, var(--bg) 0%, var(--bg2) 100%);
114
+ background:var(--bg); /* 主体纯色:光晕/160° 渐变移入 fixed 氛围层 body::before——避免背景传播到画布后滚动出现上下颜色断层(html,body 锁 height:100% 时 body 背景只覆盖第一屏,跨浏览器传播行为不一致);四层氛围与光晕层均 fixed 覆盖视口,滚动恒定 */
115
115
  color:var(--text);
116
116
  font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,Consolas,'PingFang SC','Microsoft YaHei',monospace;
117
117
  min-height:100%;
118
118
  }
119
119
 
120
+ /* 顶部光晕 + 160° 渐变 fixed 氛围层(独立于 body,滚动恒定;mono/light 下关闭保持纯色) */
121
+ body::before{
122
+ content:''; position:fixed; inset:0; z-index:-1; pointer-events:none; /* z-index:-1:画在画布背景之上、正文内容之下(光晕只衬底不压字) */
123
+ background:
124
+ radial-gradient(1200px 500px at 70% -10%, var(--gold-dim), transparent 60%),
125
+ linear-gradient(160deg, var(--bg) 0%, var(--bg2) 100%);
126
+ }
120
127
  /* ============ 四层科技氛围(与日报/周报/年报同源,透明度淡半档——工具页不扰读) ============ */
121
128
  .grid-pattern{
122
129
  position:fixed; inset:0; z-index:0; pointer-events:none;
@@ -194,9 +201,9 @@ header{
194
201
  aside{ width:200px; flex:0 0 auto;
195
202
  display:flex; flex-direction:column;
196
203
  position:sticky; top:80px; align-self:flex-start;
197
- max-height:calc(100vh - 100px);
204
+ height:calc(100vh - 100px);
198
205
  }
199
- /* 侧栏分组滚动区:收藏 + 全部分组局部滚动(「全部」与底部操作固定),窄滚动条 */
206
+ /* 侧栏分组滚动区:收藏 + 分组局部滚动,分组下方紧跟「+ 新建分组」,滚动流末尾附「锦囊用法」说明——滚动区占满「全部」与侧栏底缘之间的剩余屏幕高度(最大占满屏幕),说明被顶出首屏(滚到底可见);窄滚动条 */
200
207
  .nav-scroll{
201
208
  flex:1 1 auto; min-height:0; overflow-y:auto;
202
209
  margin:0 -4px 0 0; padding-right:4px;
@@ -224,7 +231,8 @@ aside{ width:200px; flex:0 0 auto;
224
231
  }
225
232
  .nav-item.on .cnt{ color:var(--gold); background:var(--gold-dim); }
226
233
  .side-tip{
227
- margin-top:16px; padding:12px 14px; border-radius:10px;
234
+ flex:0 0 auto;
235
+ margin:16px 4px 0 0; padding:12px 14px; border-radius:10px; /* margin-right 补偿 nav-scroll 负 margin(-4px)的右侧裁切,虚线边框完整不裁;滚动流末尾,分组多时被顶出首屏 */
228
236
  border:1px dashed var(--border); font-size:11px; line-height:1.9; color:var(--muted);
229
237
  }
230
238
  .side-tip b{ color:var(--gold); font-weight:700; }
@@ -573,7 +581,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
573
581
  .toast.warn{ color:#e06c5b; border-color:rgba(224,108,91,.5); }
574
582
  @media (max-width:820px){
575
583
  .layout{ flex-direction:column; padding:16px 16px 72px; }
576
- aside{ width:100%; display:flex; flex-wrap:wrap; gap:6px; position:static; max-height:none; }
584
+ aside{ width:100%; display:flex; flex-wrap:wrap; gap:6px; position:static; height:auto; }
577
585
  .nav-scroll{ display:contents; overflow:visible; }
578
586
  .nav-item{ margin-bottom:0; }
579
587
  .side-tip{ display:none; }
@@ -943,9 +951,9 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
943
951
  var n = state.data.prompts.filter(function(p){ return p.group === g.id; }).length;
944
952
  html += '<div class="nav-item' + (state.curGroup===g.id?' on':'') + '" data-g="' + g.id + '" draggable="true" title="拖拽调整分组顺序"><span class="icon">' + g.icon + '</span><span class="g-name">' + escapeHtml(g.name) + '</span><span class="cnt">' + n + '</span><span class="g-ops"><button class="g-edit" title="编辑分组">✎</button><button class="g-del" title="删除分组">🗑</button></span></div>';
945
953
  });
946
- html += '</div>';
947
954
  html += '<div class="nav-add" id="navAdd">+ 新建分组</div>';
948
955
  html += '<div class="side-tip"><b>锦囊用法</b><br>· 页面直接增删改:+ 新建分组 / + 新增提示词 / ✎ 编辑 / 🗑 删除(授权目录即写即存)<br>· 也可对 AI 说「把 XX 加到写作输出分组」<br>· 顶栏切换排序;⇄ 移组、拖卡片排序自动保存;拖分组条调整分组顺序<br>· 点卡片标签按标签筛选(再点取消);标签悬停 ✕ 删 / + 加;⤓ 导出 / ⤒ 导入 JSON 备份<br>· ⭐ 收藏常用 · 复制次数在卡片右上角</div>';
956
+ html += '</div>';
949
957
  sideNav.innerHTML = html;
950
958
  sideNav.querySelectorAll('.nav-item').forEach(function(el){
951
959
  el.addEventListener('click', function(){
@@ -1869,6 +1877,25 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
1869
1877
  });
1870
1878
 
1871
1879
  /* ---------- 本地持久化(IndexedDB + localStorage 镜像) ---------- */
1880
+ /* 稳定身份命名空间:每份锦囊 HTML 头部内嵌唯一 pouch-id(meta 标签),localStorage 键与 IndexedDB 库名以该 ID 命名——Chrome/Safari 下 file:// 与 localhost 共享同源存储,固定键/固定库会导致多份产物互相串台(B 份凭空继承 A 份的分组/收藏);ID 与文件路径解耦,改名/移动目录数据不丢 */
1881
+ var POUCH_ID = ((document.querySelector('meta[name="pouch-id"]') || {}).content || 'ref-pouch').trim();
1882
+ /* ID 格式自愈(格式定死执行层):meta 非法或缺失(占位残留/手写变体/误沿用旧值)时按路径键自愈为 crypto.randomUUID() 标准 v4,同路径跨打开稳定;合法 UUID 原样使用(复制文件副本=同一身份共享数据,是特性) */
1883
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUCH_ID)) {
1884
+ var __sfHealKey = 'sf-heal:' + location.pathname;
1885
+ try { POUCH_ID = localStorage.getItem(__sfHealKey) || POUCH_ID; } catch (e) {}
1886
+ if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(POUCH_ID)) {
1887
+ try { POUCH_ID = crypto.randomUUID(); } catch (e) {
1888
+ POUCH_ID = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c){ var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); return v.toString(16); });
1889
+ }
1890
+ try { localStorage.setItem(__sfHealKey, POUCH_ID); } catch (e) {}
1891
+ }
1892
+ var __sfMeta = document.querySelector('meta[name="pouch-id"]');
1893
+ if (__sfMeta) __sfMeta.setAttribute('content', POUCH_ID);
1894
+ console.warn('[prompt-pouch] meta pouch-id 非法或缺失,已自愈为标准 v4 ID(' + POUCH_ID + '),建议重新生成页面固化');
1895
+ }
1896
+
1897
+ var SF_NS = 'pouch:' + POUCH_ID;
1898
+
1872
1899
  var localState = null;
1873
1900
  var db = null;
1874
1901
  function withTimeout(p, ms, fallback){
@@ -1883,7 +1910,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
1883
1910
  if (db) return Promise.resolve(db);
1884
1911
  if (!('indexedDB' in window)) return Promise.reject(new Error('no idb'));
1885
1912
  var p = new Promise(function(res, rej){
1886
- var req = indexedDB.open('pouch-state-v1', 1);
1913
+ var req = indexedDB.open('pouch-db-' + POUCH_ID, 1);
1887
1914
  req.onupgradeneeded = function(){
1888
1915
  if (!req.result.objectStoreNames.contains('kv')) req.result.createObjectStore('kv');
1889
1916
  };
@@ -1926,7 +1953,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
1926
1953
  if (!state.data) return;
1927
1954
  localState = snapshotUserState();
1928
1955
  idbSet('userState', localState);
1929
- try{ localStorage.setItem('pouch-userstate', JSON.stringify(localState)); }catch(e){}
1956
+ try{ var usJson = JSON.stringify(localState); localStorage.setItem(SF_NS + '-userstate', usJson); }catch(e){}
1930
1957
  }
1931
1958
  function applyUserStateFrom(us){
1932
1959
  if (!us || !state.data) return;
@@ -1954,8 +1981,9 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
1954
1981
  return idbGet('userState').then(function(us){
1955
1982
  if (us){ localState = us; return; }
1956
1983
  try{
1957
- var raw = localStorage.getItem('pouch-userstate');
1958
- if (raw){ localState = JSON.parse(raw); idbSet('userState', localState); }
1984
+ var raw = localStorage.getItem(SF_NS + '-userstate');
1985
+ if (!raw) raw = localStorage.getItem('sf:' + location.pathname + '-userstate'); /* 迁移桥:旧版按路径键存的数据一次性迁入 ID 键 */
1986
+ if (raw){ localState = JSON.parse(raw); idbSet('userState', localState); localStorage.setItem(SF_NS + '-userstate', raw); }
1959
1987
  }catch(e){}
1960
1988
  });
1961
1989
  }
@@ -1966,8 +1994,8 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
1966
1994
  var lastBackupTs = 0;
1967
1995
  var pendingAuth = false;
1968
1996
  var bkDeclined = false;
1969
- try{ lastBackupTs = parseInt(localStorage.getItem('pouch-last-backup') || '0', 10) || 0; }catch(e){}
1970
- try{ bkDeclined = localStorage.getItem('pouch-bk-declined') === '1'; }catch(e){}
1997
+ try{ lastBackupTs = parseInt(localStorage.getItem(SF_NS + '-last-backup') || '0', 10) || 0; }catch(e){}
1998
+ try{ bkDeclined = localStorage.getItem(SF_NS + '-bk-declined') === '1'; }catch(e){}
1971
1999
  function bkSupported(){ return 'showDirectoryPicker' in window; }
1972
2000
  function fmtTime(ts){
1973
2001
  var d = ts instanceof Date ? ts : new Date(ts);
@@ -2038,7 +2066,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2038
2066
  });
2039
2067
  }).then(function(){
2040
2068
  lastBackupTs = Date.now();
2041
- try{ localStorage.setItem('pouch-last-backup', String(lastBackupTs)); }catch(e){}
2069
+ try{ localStorage.setItem(SF_NS + '-last-backup', String(lastBackupTs)); }catch(e){}
2042
2070
  updateBkUI();
2043
2071
  return true;
2044
2072
  }).catch(function(){
@@ -2055,7 +2083,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2055
2083
  return idbSet('snapRing', ring);
2056
2084
  }).then(function(){
2057
2085
  lastBackupTs = Date.now();
2058
- try{ localStorage.setItem('pouch-last-backup', String(lastBackupTs)); }catch(e){}
2086
+ try{ localStorage.setItem(SF_NS + '-last-backup', String(lastBackupTs)); }catch(e){}
2059
2087
  updateBkUI();
2060
2088
  return true;
2061
2089
  }).catch(function(){
@@ -2084,14 +2112,14 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2084
2112
  var ok = window.confirm('锦囊自动备份\n\n数据一有变更就会自动备份,建议授权写入 prompt-pouch.html 所在目录(首次弹窗选一次,浏览器会记住)。\n\n点「确定」打开目录选择 → 选 prompt-pouch.html 所在文件夹即可;\n点「取消」则改用浏览器本地快照(保留最近 5 份,清浏览器数据会丢)。');
2085
2113
  if (!ok){
2086
2114
  bkDeclined = true;
2087
- try{ localStorage.setItem('pouch-bk-declined', '1'); }catch(e){}
2115
+ try{ localStorage.setItem(SF_NS + '-bk-declined', '1'); }catch(e){}
2088
2116
  return Promise.resolve(false);
2089
2117
  }
2090
2118
  pendingAuth = true; updateBkUI();
2091
2119
  return window.showDirectoryPicker({ id: 'pouch-backup', mode: 'readwrite' })
2092
2120
  .then(function(h){
2093
2121
  bkDirHandle = h; pendingAuth = false; bkDeclined = false; subDirCache = {};
2094
- try{ localStorage.removeItem('pouch-bk-declined'); }catch(e){}
2122
+ try{ localStorage.removeItem(SF_NS + '-bk-declined'); }catch(e){}
2095
2123
  idbSet('bkHandle', bkDirHandle);
2096
2124
  updateBkUI();
2097
2125
  return true;
@@ -2159,7 +2187,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2159
2187
  window.showDirectoryPicker({ id: 'pouch-backup', mode: 'readwrite' })
2160
2188
  .then(function(h){
2161
2189
  bkDirHandle = h; pendingAuth = false; bkDeclined = false; subDirCache = {};
2162
- try{ localStorage.removeItem('pouch-bk-declined'); }catch(e){}
2190
+ try{ localStorage.removeItem(SF_NS + '-bk-declined'); }catch(e){}
2163
2191
  idbSet('bkHandle', bkDirHandle);
2164
2192
  updateBkUI();
2165
2193
  writeBackupNow();
@@ -2172,7 +2200,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2172
2200
  window.showDirectoryPicker({ id: 'pouch-backup', mode: 'readwrite' })
2173
2201
  .then(function(h){
2174
2202
  bkDirHandle = h; pendingAuth = false; bkDeclined = false; subDirCache = {};
2175
- try{ localStorage.removeItem('pouch-bk-declined'); }catch(e){}
2203
+ try{ localStorage.removeItem(SF_NS + '-bk-declined'); }catch(e){}
2176
2204
  idbSet('bkHandle', bkDirHandle);
2177
2205
  updateBkUI();
2178
2206
  writeBackupNow();
@@ -2321,6 +2349,10 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2321
2349
  });
2322
2350
  })();
2323
2351
 
2352
+ /* 稳定身份命名空间:本块在大 IIFE 之外需独立声明——键以页内嵌 pouch-id 命名,多份锦囊互不串台、改名/移动不丢记忆 */
2353
+ var POUCH_ID = ((document.querySelector('meta[name="pouch-id"]') || {}).content || 'ref-pouch').trim();
2354
+ var SF_NS = 'pouch:' + POUCH_ID;
2355
+
2324
2356
  /* 主题换肤:五套配色随点随换;记忆上次选择(localStorage,失败静默) */
2325
2357
  (function(){
2326
2358
  var THEMES = ['gold','tech','mono','light','mint'];
@@ -2332,11 +2364,11 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
2332
2364
  dock.querySelectorAll('.th-dot').forEach(function(d){
2333
2365
  d.classList.toggle('on', d.getAttribute('data-theme') === t);
2334
2366
  });
2335
- try{ localStorage.setItem('sf-pouch-theme', t); }catch(e){}
2367
+ try{ localStorage.setItem(SF_NS + '-theme', t); }catch(e){}
2336
2368
  }
2337
2369
  var cur = document.documentElement.getAttribute('data-theme') || 'gold';
2338
2370
  var saved = null;
2339
- try{ saved = localStorage.getItem('sf-pouch-theme'); }catch(e){}
2371
+ try{ saved = localStorage.getItem(SF_NS + '-theme') || localStorage.getItem('sf:' + location.pathname + '-theme'); }catch(e){}
2340
2372
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
2341
2373
  else{
2342
2374
  dock.querySelectorAll('.th-dot').forEach(function(d){
@@ -10,7 +10,7 @@
10
10
  4. **删除**:页面点卡片「🗑」;或对 AI 说「删掉锦囊里『XX』这条」
11
11
  5. **排序与移组**:顶栏「排序」切换四种方式——最新添加(默认)/ 最近使用 / 使用频率 / 手动顺序;想手动排时拖动卡片或点 ▲▼(自动切回手动),点卡片 ⇄ 可把提示词移到其它分组;已授权目录时排序/移组 2 秒内自动保存,未授权时点「📋 复制变更指令」把指令发给 AI 落盘;复制过提示词后卡片右上角会显示「⧉ N 次 · 最近时间」(最近使用/使用频率排序即按复制统计);AI 落盘后回页面点「✓ 已落盘」清除未保存标记
12
12
  6. **收藏**:卡片右上角星标,收藏/取消收藏指令由 AI 同步到数据文件
13
- 7. **分组管理**:侧栏底部「+ 新建分组」;悬停分组名出现「✎ 改名 / 🗑 删除」(组内还有提示词时不允许删,先移出或删条目);重名分组会提示;新建/编辑分组时图标输入框下方有快捷 emoji 面板(点击即填入、选中高亮,输入框仍可手输/粘贴任意 emoji)
13
+ 7. **分组管理**:分组下方「+ 新建分组」(紧随分组列表);悬停分组名出现「✎ 改名 / 🗑 删除」(组内还有提示词时不允许删,先移出或删条目);重名分组会提示;新建/编辑分组时图标输入框下方有快捷 emoji 面板(点击即填入、选中高亮,输入框仍可手输/粘贴任意 emoji)
14
14
  8. **标签全交互**:点卡片标签立即按标签筛选(顶栏出现「🏷 标签」胶囊,点 ✕ 或再点同标签取消,切分组自动清除,与搜索叠加);标签悬停出「✕」点它直接删除该标签;标签不满 3 个时悬停出「+」快速加标签(多个用逗号分隔)——已授权目录即写即存,未授权时操作指令复制给 AI 落盘
15
15
  9. **分组排序**:左侧分组条可直接拖拽调整顺序(已授权目录即写即存,未授权时指令自动复制给 AI 落盘)
16
16
  10. **导入 / 导出**:顶栏「⤓ 导出」把当前全部数据下载为 JSON 备份文件(文件名带时间戳);「⤒ 导入」选择 JSON 文件整库覆盖现有数据(导入前自动备份,可从「↩ 恢复」回滚;未授权目录时导出仍可用、导入需先授权)
@@ -22,7 +22,7 @@
22
22
  - **自动备份(默认开启)**:数据一有变更 2 秒内自动备份——首次变更会请求授权写入 prompt-pouch.html 所在目录(弹窗选同目录即可,选一次后浏览器记住),写 backup/pouch-backup.json 并滚动保留上一版 .prev.json;未授权或浏览器不支持时自动降级为本地快照(浏览器内保留最近 5 份),页内「↩ 恢复」均可一键回滚;顶栏「📂 换目录」可随时重新配置备份目录
23
23
  - **详情弹窗**:点卡片「👁 详情」弹出全文查看(超长内容限高 52vh 内滚动),带复制与修改入口,附时间线(创建 / 上次修改 / 最近使用);含 {变量} 的模板会在弹窗里标出变量清单,复制时自动进入填充面板
24
24
  - **页面直写(双笔)**:页面增删改直接写入 data/prompts.json(与自动备份共用同一目录授权);未授权时自动降级——生成操作指令复制到剪贴板,粘贴给 AI 落盘
25
- - **侧栏局部滚动**:分组较多时,左侧「收藏 + 分组列表」区域独立滚动(窄滚动条),「全部」「+ 新建分组」「锦囊用法」固定不滚;窄屏下自动恢复平铺排列
25
+ - **侧栏局部滚动**:分组较多时,左侧「收藏 + 分组列表」区域独立滚动(窄滚动条,滚动区最大占满屏幕剩余高度),「+ 新建分组」紧随分组流、「锦囊用法」滚到底可见,「全部」固定不滚;窄屏下自动恢复平铺排列
26
26
  - **批量整理入囊**:把一堆文字/文件交给 AI,或说「把最近对话框内容整理进锦囊」——两段确认:先定条目(AI 默认智能打标——每条自动配 1-3 个语义标签,可改可删;含具体词的可泛化为 {变量} 插值,附改写示例)→ 再定分组(归组理由 + 装不下的推荐新分组名),都确认后一次性写入;条目少(≤3 条)两段合一
27
27
  - **标签全交互**:点标签即筛选(顶栏胶囊一键清除,再点取消,切分组自动清除,与搜索叠加);标签悬停「✕」删、「+」加(最多 3 个),授权目录即写即存,未授权指令交 AI
28
28
  - **导入 / 导出 JSON**:顶栏「⤓ 导出」一键下载全量数据为 JSON 备份文件(文件名带时间戳);「⤒ 导入」选择 JSON 文件整库覆盖(导入前自动备份、可恢复);未授权目录时导出仍可用、导入需先授权
@@ -30,10 +30,17 @@
30
30
  - **四种排序**:最新添加(按添加时间倒序,全时间范围)/ 最近使用 / 使用频率 / 手动顺序;排序选择会自动记住,下次打开不变
31
31
  - **使用统计**:每次点复制,页面自动记录该提示词的最近使用时间与累计次数(存浏览器本地),供「最近使用」「使用频率」排序使用,数据文件不写这些字段
32
32
  - **修改时间**:每次修改提示词(页面直写或 AI 代笔),数据文件会记下 updatedAt 修改时间,详情弹窗时间线可见;新增不写、仅排序不写
33
- - **本地态**:收藏、排序选择、使用统计、主题选择存浏览器本地(IndexedDB + localStorage 镜像),刷新不丢,不写数据文件
33
+ - **本地态**:收藏、排序选择、使用统计、主题选择存浏览器本地(IndexedDB 库名 + localStorage 镜像键均按页内嵌唯一 ID 命名空间隔离:多份锦囊互不串台、改名/移动目录不丢、复制文件副本=同一身份共享数据),刷新不丢,不写数据文件
34
34
 
35
35
  ## 提醒
36
36
 
37
37
  - 数据在 data/prompts.json(备份在 backup/ 目录);迁移/备份复制 data/ 与 backup/ 两个目录即可
38
38
  - 「⤓ 导出」的 JSON 文件可直接在另一台电脑「⤒ 导入」整库恢复(含分组与标签)
39
39
  - 页面样式与脚本升级由仓库 reference.html 重新复制完成,不影响你的数据
40
+
41
+ ## 效果不对怎么办
42
+
43
+ - 页面效果不对(布局乱 / 卡片显示异常 / 搜索筛选失灵 / 主题错乱),对 AI 说「锦囊页面有 XX 问题,对照参考模板修复」,把问题描述清楚(什么操作、什么现象,能截图最好)
44
+ - 本技能的设计标准答案就在技能目录里:`resources/reference.html`(页面样式真相源),AI 修复时以此为唯一对照
45
+ - AI 的处理流程固定:先查数据文件 data/prompts.json 是否合法 → 再对照 reference.html 定位是页面问题还是数据问题 → 页面问题以 reference 为准重新复制页面(你的数据一概不动)、数据问题只修 json → 自动验证页面零报错、卡片数正确,截图自证
46
+ - 说「打开锦囊」发现打不开 / 白屏:优先说清报什么错,AI 会先确认是否按 HTTP 方式启动(file:// 直开会退回缓存快照,不是页面坏了)
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: quarterly-report
3
+ description: 生成工作季报(默认季度概览/季度关键成果/问题与改进/下季度计划四段结构,中文顿号序号),适配各行业(内置 12 行业职业词典,可指定角色身份)。核心数据卡带环比(较上季度)+ 同比(较去年同期)双基准,概览附 Q1-Q4 季度走势图;成果段按季度内月份(M1/M2/M3)时间线,支持全年 Q1-Q4 季度回顾模式。数据来源灵活:直接口述、给一段文字、发文件(Word/PDF/Excel/PPT 等)或图片,都能整理成季报;开发类用户可聚合代码仓库当季提交。支持自定义模板(可永久或临时指定)。支持自然语言指定季度(这个季度/上季度/Q3/近三个月等)。当用户请求写季报、季度总结、季度复盘、Q3 总结、Q4 总结、/quarterly-report,或询问季报用法(季报怎么用/季报使用说明)时使用。用户说「写总结/工作总结/写个汇报」等未言明周期的词时,先 AskUserQuestion 分流(日报/周报/月报/季报/年报)再执行,不擅自默认。
4
+ allowed-tools: Bash, Read, Write
5
+ disable-model-invocation: false
6
+ ---
7
+
8
+ # 季度总结生成
9
+
10
+ 聚合各仓库 git 当季提交 + 本次会话口述内容生成四段式季度总结(季度概览/季度关键成果/问题与改进/下季度计划),对话输出 md 正文 + 落盘 md/txt/html/content-png 并自动打开 html。
11
+
12
+ ## 生成流程
13
+
14
+ 0.5 **周期歧义分流**:用户说「写总结/工作总结/写个汇报/做一份总结」等未言明周期的词 → AskUserQuestion 五选一(日报/周报/月报/季报/年报)确认周期再继续,不擅自默认
15
+ 0. **读用户配置**(DISK/FORMATS/DIR/OPEN_HTML/TEMPLATE/ROLE/CONFIRM、自定义模板)→ 先 Read 同目录 `user-config.md`
16
+ 1. **解析季度**(自然语言 → 目标季度区间)→ 读 `resources/date-parsing.md`
17
+ 2. **收集数据**(git 当季提交聚合 + 环比/同比双基准统计 + 会话口述 + 口头补充,合并去重)→ 读 `resources/data-collection.md`
18
+ 3. **内容归类与润色**(四段式结构 / 双基准口径 / 聚合来源 / 纯文字模式 / 输出格式 / 写作风格)→ 读 `resources/content-rules.md`
19
+ 4. **行业词条**(话术含职业词时按词典取词)→ 读 `resources/industry-dictionary.md`
20
+ 5. **落盘与截图**(md/txt/html/content-png + 自动打开 html)→ 读 `resources/disk-and-html.md`
21
+ 5.5 **交付前自检**(落盘与截图前必做,硬门禁不可跳过):quarterly-report-YYYY-QN.html 文件写好后——
22
+ - Bash 起 `python3 -m http.server 8945`(后台,端口占用换 8946/8947…)
23
+ - Playwright headless 自检(缺则 `pip3 install --user playwright`;用系统 Chrome,channel="chrome" 无需下载浏览器):goto 页面 → 挂 pageerror 监听(零容忍)→ 滚动到底部 → 断言头部标题卡与季度概览/季度关键成果/问题与改进/下季度计划四张分节卡存在(证明主体结构完整未被破坏)
24
+ - 截全页 PNG Read 自查:头部标题卡与季度概览/季度关键成果/问题与改进/下季度计划四张分节卡齐全、文字无溢出截断、无豆腐块缺字
25
+ - 任何报错或视觉问题:修 HTML → 重检;全绿才进第 6 步
26
+ 6. **使用咨询**(用户只问「季报怎么用」等用法、未要求生成)→ 读 `resources/usage-guide.md`,将其内容原样输出(首行标题改为「季度总结生成器使用指南」),不收集 git、不生成报告、不落盘、不开浏览器
27
+
28
+ ## ⚙️ 配置与自定义模板
29
+
30
+ **执行本 skill 前必须先 Read 同目录 `user-config.md`**:默认配置(DISK/FORMATS/DIR/OPEN_HTML/TEMPLATE/ROLE/CONFIRM)与自定义模板都在该文件中,以它为准。升级技能时 user-config.md 不会被覆盖,你的修改永久保留。
31
+ - **THEME**:html 页面主题,tech 深蓝科技(默认)/ biz 浅色商务 / mono IDEA 黑亮 / light IDEA 白亮 / warm 温暖渐变;生成时写 `<html data-theme="THEME值">` 定默认,页面右下角换肤坞随点随换(localStorage 记忆(键按页内嵌唯一 ID 隔离、多份产物互不串台、改名/移动目录记忆不丢(生成时头部写 `<meta name="quarterly-id" content="<UUID>">`,每次 crypto.randomUUID() 生成标准 UUID v4(8-4-4-4-12 十六进制,禁止手写变体、禁止沿用占位与旧值);落盘写文件前顺扫落盘目录下本技能命名的 html,读各文件 id meta 查重,撞号重掷至不重复))、?shot 截图模式与打印隐藏)
32
+ - **DATA_SOURCES**:数据源清单(默认空清单 + git/file/remote 三类型示例注释),个人数据源只写 user-config.md,本文件随升级覆盖
33
+ - **DATA_SOURCES 意图路由**:用户说「把这些 git 地址 / 目录配置到这个 skill」「数据源加一下」「以后数据从 XX 仓库取」→ 默认指配置到 `user-config.md` 的 `DATA_SOURCES` 数据源清单(不是 SKILL.md、不是 disk-and-html.md);「git 地址」给的是 URL 或本地仓库路径、目录给的是本地路径都写进 DATA_SOURCES。用户话术只指向某个特定数据源(如「只算这个仓库」)→ 当次生效,不写配置。意图仍有歧义(如分不清「数据收集配置」与「落盘目录配置」)→ 一句话与用户确认后写入,不猜
34
+
35
+ ## 配置版本机制(升级保护)
36
+
37
+ 本 skill 当前配置版本为 `3`(对应 user-config.md 中的 `CONFIG_VERSION`)。执行时若发现 user-config.md 的 CONFIG_VERSION 与本节声明的当前版本不一致:先将旧 user-config.md 备份为 `user-config.md.bak-<时间戳>`(同目录,绝不删除旧值)→ 按本节「当前版本变更记录」迁移字段(新增字段补默认值、改名字段按映射改写、删除字段的值保留在备份中并在对话提示用户手动确认)→ 更新 CONFIG_VERSION 为当前版本 → 对话中明确告知用户「检测到配置版本从 X 升级到 Y,旧配置已备份至 <路径>」。禁止在未声明版本变更的情况下静默修改配置语义。
38
+
39
+ **无法迁移项处理**(值域失效 / 语义漂移 / 数据不兼容):三情形——①旧值不在新值域(如旧模板/主题名已移除)②同名键含义变化(单位/枚举变更)③数据文件 schema 不兼容。三绝不:绝不静默(无法迁移项停下问,不猜值)、绝不丢失(旧值永远在 .bak-时间戳)、一次说清(升级报告三段式:⚠️ 版本与备份路径 → ✅ 已自动迁移清单 → 🟡 无法迁移项逐条附原因+影响+建议替代);随后 AskUserQuestion 三选项(A 用建议值 / B 用户给新值 / C 保持旧配置——不更新 CONFIG_VERSION,每次执行再提醒);报告必附回滚一句话。
40
+
41
+ 当前版本变更记录:v1→v2 新增 THEME 字段(默认 tech)。v2→v3 新增 DATA_SOURCES 数据源清单段(默认空清单 + git/file/remote 三类型示例注释)。
42
+
43
+ ## 产物升级(回炉)
44
+
45
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="quarterly-report@2">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧季报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="quarterly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版季报(vN-1 或无版本戳的历史产物),说『把我旧季报都升级成新样式』即可一键升级」,不让用户背触发语。
46
+
47
+ ## 🔧 报修处理流程(用户报页面问题时)
48
+
49
+ 用户说「这个页面效果不对 / 布局乱了 / 有 UI 问题 / 样式错了 / 交互坏了」(常附截图或指出具体现象)→ 按以下流程处理,不以「重新生成一份」敷衍:
50
+
51
+ 1. **立标准**:先 Read 本 skill 目录 `resources/reference.html`——它就是设计标准答案(布局/配色/交互全在代码里)
52
+ 2. **找问题**:Read 用户那份问题 html 文件,与 reference 逐处比对(结构顺序 / CSS 变量 / 关键类名 / 交互 JS),定位跑偏处;用户给了截图则按截图现象反查
53
+ 3. **修复**:以 reference 为准修复那份 html(只修跑偏处,不动正确内容;reference 与 html 不一致时以 reference 为准)
54
+ 4. **自证**:Chrome headless 访问修复后页面截全页 PNG,Read 自查修复点恢复标准效果;用户给了问题截图时尽量复现同视角截图做前后对比
55
+ 5. **汇报**:一句话说清问题根因 + 修复了什么 + 附截图;若根因在 reference.html 自身(生成结果与 reference 一模一样但仍有问题),顺修 reference.html 对应处并在汇报中说明「参考模板已同步修正」,避免下一份重蹈覆辙
56
+
57
+ ## 规则速览
58
+
59
+ - 四段式骨架行业无关:季度概览(一句话 TL;DR + 4-6 项核心数据卡,数字必带环比上季度 + 同比去年同期双基准,缺基准来源不作要求 + Q1-Q4 季度走势图)/ 季度关键成果(单季报按季度内 M1/M2/M3 月时间线 8-12 项,全季报按 Q1/Q2/Q3/Q4 季度时间线;每项 20-40 字)/ 问题与改进(2-4 条三环:问题+影响+改进)/ 下季度计划(3-5 项目标,各带量化指标与月度行动节点 M1/M2/M3)
60
+ - 中文顿号序号(1、2、3);段内无内容写「暂无」;量化优先,杜绝空话套话
61
+ - 行业术语/指标/里程碑主题/风险话术按 `resources/industry-dictionary.md` 职业词典取词(未提职业按 ROLE 画像)
62
+ - 汇报链联动:当季内已生成的月报核心指标可直接引用(同源数据不重复统计),季报必须有季度视角的独立判断,不把月报原文拼贴成季报
63
+ - 完整规则(聚合来源 / 纯文字模式 / 写作风格约束 / 使用提示)见 `resources/content-rules.md`
@@ -0,0 +1,42 @@
1
+ # 内容规则(四段式)
2
+
3
+ 四段式骨架行业无关(任何职业通用),术语与指标由职业词典适配。
4
+
5
+ ## 段结构
6
+
7
+ **段一 季度概览**
8
+ - 一句话 TL;DR:本季度工作的总体判断(如「收敛与沉淀的一季:季度版本数从上季度 42 个收敛到 25 个,质量门禁覆盖全部命令族」)
9
+ - 核心数据卡 4-6 项:本季度最关键的量化指标(按职业词典),每项:数字 + 单位 + 标签;数字凡有对比基准必带(**环比上季度 + 同比去年同期双基准,至少其一**),无基准来源不作要求
10
+ - 双基准小字(「较上季度:+18%」「较去年同期:+35%」),上涨与下跌按语义色区分
11
+ - 附 Q1-Q4 季度走势图:当年各季度核心指标(如提交数)走势,当前季度高亮,季度间对比一目了然
12
+
13
+ **段二 季度关键成果**
14
+ - 单季报:按季度内月份(M1/M2/M3,即季内第 1/2/3 月,标题写具体月份如「M1 · 10 月」)时间线排列 8-12 项,每项:成果描述 20-40 字 + 所属月 + 量化结果 + 价值归因(做了什么→改变了什么→与季度目标的关联)
15
+ - 全季报(用户要「今年 Q1-Q4 总结」):按 Q1/Q2/Q3/Q4 季度时间线排列,每季度 2-3 项
16
+ - 里程碑事件优先(版本发布/项目上线/重大交付/关键会议决策),日常任务不逐条列
17
+ - 未过完的季度(如写到 11 月中旬)注明「截至当前」
18
+
19
+ **段三 问题与改进**
20
+ - 2-4 条三环结构:问题(是什么)+ 影响(导致什么)+ 改进(下季度怎么改,含可验证动作与时间节点,如「Q1 起双周一次代码走查,缺陷率降到 X%」)
21
+ - 具体诚实,不写「还需努力」这类空话;无真实不足才写「暂无」
22
+ - 与当季月报问题与改进、复盘结论呼应(同源问题不重复展开)
23
+
24
+ **段四 下季度计划**
25
+ - 季度目标 3-5 项:目标描述 + 可量化指标(「完成 XX,季末达到 XX」)+ 完成标准(可验证的终点;杜绝「努力提升 XX」类不可验证表述)
26
+ - 每项目标带月度行动节点(M1 起…M2 完成…M3 验收…)
27
+ - 目标与段三问题的改进方向呼应
28
+
29
+ ## 写作风格
30
+
31
+ - 中文顿号序号(1、2、3),段内条目数按上述区间;不足处写「暂无」
32
+ - 量化优先:能带数字的带数字,估算值注明「约」;用户口述的业务结果指标(响应时间/错误率/成功率等)优先于提交统计(提交数/行数/版本数),提交统计作兜底
33
+ - 语言朴素具体,杜绝「再接再厉/砥砺前行」等套话;季度视角有判断、有取舍,不是月报拼接;流水与清单条目保持无主语,结论/判断/归因处允许第一人称「我」
34
+ - 技术动作翻译:口述技术动作且带结果数据时,翻译为业务结果表述(「重写 SQL 加索引」→「查询响应 3.2s→0.4s」);仅含动作无结果时保留动作,并提示可补充结果指标
35
+ - 落笔前五问自检:①第一句是不是结论?②数字有没有对比基准?③卡点有没有责任动作和时间?④计划能不能被验证?⑤个人贡献与团队成果的归属是否清晰?任一不过,改写后再输出
36
+ - md/txt 正文含生成时间行(精确到时分秒,如 2026-11-12 19:10:38)
37
+
38
+ ## 聚合来源与纯文字模式
39
+
40
+ - 提交记录聚合来源(提交统计/里程碑/双基准)与口述来源(大事/感悟)合并后按段归类;两者矛盾时业务结果指标以用户口述为准、提交统计(提交数/行数)兜底
41
+ - 纯文字/图片/文件整理模式(没有提交记录):用户提供什么用什么,按四段结构归类;素材不足的段写「暂无」并提示用户可补充素材
42
+ - 季度与月报的关系:同季度内月报核心指标可直接引用(季度概览卡可汇总季度内三个月报核心指标),但季度总结必须有独立判断(季度视角的取舍与结论),不把月报原文拼贴成季报
@@ -0,0 +1,46 @@
1
+ # 数据收集(季度)
2
+
3
+ 三种来源合并去重:口述与文字/文件/图片并重(业务结果以口述为准、统计数字以提交记录兜底);没有提交记录也适用——给一段文字、文件里的描述或图片即可成稿。开发类用户可另做代码仓库当季提交聚合与环比/同比双基准统计(见第 1 节)。
4
+
5
+ ## 1. 代码仓库当季提交聚合(可选,开发类用户)
6
+
7
+ 清单形状(每项 name 唯一名称 + type 类型 + 路径;完整填写说明见 user-config.md「默认配置」的 DATA_SOURCES 注释):
8
+
9
+ ```yaml
10
+ DATA_SOURCES:
11
+ - name: 主项目仓库 # name = 唯一 key(重名视为同一数据源;口述「只聚合 xxx」按 name 匹配)
12
+ type: git # git = 代码仓库(git log 聚合提交)
13
+ mac: ~/Projects/main-app # macOS 路径(绝对路径或 ~ 开头)
14
+ win: D:\Projects\main-app # Windows 路径;「-」= 该系统不存在,自动跳过
15
+ - name: 季度例会纪要
16
+ type: file # file = 普通文件/目录(直接 Read 内容聚合)
17
+ mac: ~/Documents/meeting-notes.md
18
+ win: -
19
+ - name: 数据接口
20
+ type: remote # remote = 远程网络源(联网拉取 url 内容)
21
+ url: https://example.com/data.json
22
+ ```
23
+ - 遍历 user-config.md 的 DATA_SOURCES 清单(type: git 项;个人数据源必须写在 user-config.md,本文件随升级覆盖),对每仓执行当季统计:
24
+ - 总提交数:`git log --since={季首} --until={季末 23:59} --oneline | wc -l`
25
+ - 增删行数:`git log --since=... --until=... --numstat --pretty=tformat: | awk` 汇总 add/del
26
+ - **先剔除生成物路径**(.build/code-graph/、node_modules、dist、*.lock 等,用 grep -vE 按制表符+路径过滤),否则 graph.json 之类单文件可贡献数十万行噪音
27
+ - Q1-Q4 走势数据:对当年各季度分别统计总提交数(`git log --since={各季首} --until={各季末} --oneline | wc -l`),喂给 HTML 概览区的 Q1-Q4 季度走势图(当年未到的季度不统计,图形只画已有季度)
28
+ - 里程碑:`git tag` / `git log --merges --oneline` 提取版本发布与重要合并,读 tag 信息取版本号与日期,筛选落在目标季度内的
29
+ - **双基准统计**(概览卡「较上季度/较去年同期」两行小字的数据来源):
30
+ - 环比:同样口径统计上季度总提交数/完成任务数
31
+ - 同比:同样口径统计去年同季度(如 2025-Q4)总提交数
32
+ - 仓库按系统取有效路径(mac / win 双字段,「-」= 该系统不存在跳过)
33
+
34
+ ## 2. 会话口述与文字材料
35
+
36
+ - 用户口述的季度大事(「这季度上了 XX」「Q4 初做了 YY」)逐条记录
37
+ - 用户提供的总结草稿/文档(md/txt/docx)Read 提取要点;图片逐张 Read 识别内容
38
+ - DATA_SOURCES 清单中 type: file 的文件 Read 全文、目录逐个 Read 文本文件提取要点(二进制跳过、路径无效静默跳过);type: remote 只需 url 字段(mac/win 忽略)联网拉取内容提取要点(拉取失败静默跳过;仅收集时联网,HTML 产物仍零外链);未知 type 忽略该项并在生成时提示
39
+ - 聊天记录/周报/月报/会议纪要文件也可作为素材;本季度已生成的月报直接引用其核心指标(同源数据不重复统计)
40
+
41
+ ## 3. 合并去重与口径
42
+
43
+ - 同一成果提交数据与口述重合时合并为一条,量化以提交统计为准、定性以口述为准;file/remote 提取要点与口述同等对待
44
+ - 无法量化的条目写定性描述,不编造数字
45
+ - 季度核心指标(概览卡数据)优先取:总提交数/季度增删行数/版本发布数(研发),其它行业按职业词典量化指标
46
+ - 双基准口径:环比/同比数据仅在用户要求对比或数据卡有基准需求时统计;「较上季度/较去年同期」必须同口径(同仓库、同剔除规则),口径不同宁可不写