BINARY GARDEN
2026-04-13 // web · promt · sibuchen

PromptManager

PromptManager

项目概览

PromptManager 是一款面向 AI Prompt 工程师的本地化 Prompt 管理工具,采用纯前端无后端架构,通过浏览器原生 File System Access API 直接读写用户本地文件系统,实现 Prompt 的创建、编辑、检索、分类与导入导出。项目以 .md(Markdown + YAML Frontmatter)作为统一存储格式,兼顾可读性与结构化元数据管理。

核心定位:解决 AI 使用过程中 Prompt 模板散落在各处、缺乏统一管理和快速检索的问题。


技术栈

层级技术选型版本
框架React 19 + React Router 719.2.4 / 7.14.0
构建工具Vite 88.0.4
样式方案Tailwind CSS 4 + 自定义 CSS 变量主题系统4.2.2
代码编辑器Monaco Editor(@monaco-editor/react)4.7.0
Markdown 渲染react-markdown + remark-gfm10.1.0
元数据解析gray-matter(YAML Frontmatter 标准)4.0.3
持久化IndexedDB(idb-keyval) + File System Access API6.2.2
数据导出JSZip3.10.1
包管理pnpm

架构设计

整体分层

src/
├── main.jsx                    # 应用入口
├── App.jsx                     # 路由定义 + 全局 Provider 挂载
├── contexts/
│   └── SettingsContext.jsx     # 全局状态管理(主题/语言/工作区句柄)
├── components/                 # 布局 & 复用 UI 组件
│   ├── Layout.jsx              # Sidebar + Outlet 的根布局壳
│   ├── Sidebar.jsx             # 导航侧边栏(含 WorkspaceTree 嵌套)
│   ├── TopToolbar.jsx          # 通用顶部工具栏
│   ├── WorkspaceTree.jsx       # 递归文件树(惰性展开)
│   └── SavePromptDialog.jsx    # 保存对话框(含目录浏览器)
├── pages/                      # 页面级组件
│   ├── Editor.jsx              # 核心:Prompt 编辑器(Monaco + 实时预览)
│   ├── Library.jsx             # Prompt 库(搜索/标签/排序)
│   └── Settings.jsx            # 设置页(主题/语言/工作区/导入导出)
└── utils/
    ├── fileSystem.js           # File System Access API 全套封装
    └── i18n.js                 # 轻量级中英双语字典

数据流架构

┌─────────────────────────────────────────────────────────────────┐
│                        SettingsContext                           │
│  (theme, language, workspaceHandle)  ← 全局单一数据源            │
└──────────┬──────────────────────────────┬───────────────────────┘
           │                              │
     ┌─────▼─────┐                 ┌──────▼──────┐
     │  Editor    │                 │   Library    │
     │  页面      │                 │   页面       │
     └─────┬─────┘                 └──────┬──────┘
           │                              │
           ▼                              ▼
   ┌───────────────────────────────────────────────┐
   │            fileSystem.js 封装层                 │
   │                                               │
   │  readFile / writeFile    ← 读写 .md 文件       │
   │  readMetadata / writeMetadata  ← 读写索引     │
   │  parseMarkdown / stringifyMarkdown  ← 格式转换 │
   │  syncMetadataIndex  ← 增量同步                │
   └───────────────────┬───────────────────────────┘
                       │
                       ▼
   ┌───────────────────────────────────────────────┐
   │         File System Access API (浏览器原生)      │
   │                                               │
   │  FileSystemDirectoryHandle  ← 用户选定的目录    │
   │  IndexedDB (idb-keyval)     ← 句柄持久化       │
   └───────────────────────────────────────────────┘

核心功能模块

1. Monaco Editor 编辑器

文件src/pages/Editor.jsx

  • 集成 Monaco Editor,支持 Markdown 语法高亮、代码折叠、自动换行
  • 左右分屏布局:左侧为编辑区,右侧为 react-markdown 实时预览
  • 顶部内联编辑器:支持文件名直接修改、Tag 标签的增删操作
  • PreviewBar 组件通过 React.memo 隔离,避免编辑区每次击键触发预览组件重渲染
  • 自定义 Monaco 主题 logicCanvasDark,与应用深色模式无缝融合

性能优化:PreviewBar 使用 memo + useCallback 稳定引用,确保击键不会导致 Monaco 实例重新协调。

2. 文件存储引擎

文件src/utils/fileSystem.js

核心设计决策:无后端,通过浏览器 File System Access API 直接操作本地文件系统。

关键实现

  • 工作区持久化pickWorkspace()FileSystemDirectoryHandle 写入 IndexedDB,restoreWorkspace() 在应用启动时静默恢复,用户无需重复授权
  • 目录递归扫描scanDirectory() 递归遍历目录树,统计文件数量与磁盘占用
  • 元数据索引.metadata.json):维护所有 .md 文件的结构化索引(tags、preview、lastModified),避免每次加载都全量解析文件
  • 增量同步机制syncMetadataIndex()):通过 file.lastModified 时间戳比对,仅重新解析被外部修改过的文件,并自动清理已删除文件的索引条目
  • 兼容性设计:元数据 schema 从 v1(纯 tag 数组)到 v2(带 preview 和 lastModified 的对象),normaliseMetaEntry() 保证新旧格式无缝兼容

3. Markdown 序列化引擎

文件src/utils/fileSystem.js 中的 parseMarkdown() / stringifyMarkdown()

采用 YAML Frontmatter 作为标准格式:

---
tags:
  - backend
  - java
  - spring-boot
preview: 这是一个用于后端开发架构的标准化 Prompt 模板
---

# Prompt 正文内容...

解析策略(三层容错):

  1. 首选 gray-matter 库解析 — 标准 YAML Frontmatter
  2. 手动正则回退 — 当 gray-matter 解析失败时,用正则提取 --- 块中的 tags 和 preview
  3. 旧版 HTML 注释兼容 — 支持 <!-- tags: ... --> 格式的遗留文件,实现无感迁移

自愈机制parseMarkdown() 包含循环剥离逻辑,自动清理因多次保存产生的"千层饼"(多个 YAML 头部叠加)问题。stringifyMarkdown() 则通过 YAML 敏感字符检测,对 preview 值自动加引号,防止特殊字符破坏 YAML 结构。

跨平台处理:所有输入先经过 \r\n\n 归一化,确保 Windows 换行符不会导致正则失效。

4. Prompt 库与检索系统

文件src/pages/Library.jsx

  • 级联计算架构:三个 useMemo 链式派生 — 热门标签 → 搜索词解析 → 过滤排序结果,任一上游变化自动级联更新
  • 搜索算法:标签精确匹配(===) + 摘要模糊匹配(includes),多关键词取并集并按命中数打分排序
  • 两种排序模式:相关度排序(score 降序)和最近修改排序(lastModified 降序),一键切换
  • 快速加载 + 静默同步:先从 .metadata.json 缓存快速渲染,后台异步执行 syncMetadataIndex() 增量更新

5. 保存流程与冲突处理

文件src/components/SavePromptDialog.jsx

保存对话框实现了完整的目录浏览器,支持:

  • 路径面包屑导航:可逐级深入子目录
  • 原地新建文件夹:保存时可在任意位置创建新目录
  • 三种保存模式
    • 新建文件:检测同名冲突,直接阻止覆盖(非静默覆盖)
    • 编辑已有文件(路径+文件名未变):静默覆盖
    • 移动/重命名文件:删除旧路径的物理文件 + 清理旧元数据索引,写入新位置
  • 写入原子性:写入失败时调用 writable.abort() 确保文件句柄不泄漏

6. 递归文件树

文件src/components/WorkspaceTree.jsx

  • 惰性加载:目录节点仅在用户点击展开时才异步加载子条目,避免启动时全量扫描
  • React.memo 优化WorkspaceNode 组件使用 memo 包裹,展开/折叠操作不会导致兄弟节点重渲染
  • 路径状态管理:通过 Set 维护 expandedPathsactiveFilePath 高亮当前编辑的文件

7. 工作区导入导出

文件src/pages/Settings.jsx

  • 导出:使用 JSZip 递归打包整个工作区目录为 .zip 压缩包,通过 Blob URL 触发浏览器下载
  • 导入:通过 <input type="file" accept=".md"> 导入单个 Markdown 文件,自动携带内容跳转至编辑器页面

8. Vite 自定义插件:Git 状态监控

文件vite.config.js 中的 gitStatusPlugin()

  • 仅在开发模式下生效,提供 /api/git-status 中间件
  • 通过 spawnSync 调用 git loggit status,返回最近提交时间和工作区干净状态
  • 安全加固:硬编码 git 命令参数数组(无字符串拼接),CORS 仅允许 127.0.0.1:5173,锁死 dev server 到 loopback 地址

9. 国际化(i18n)

文件src/utils/i18n.js

  • 轻量级字典方案,覆盖侧边栏、编辑器、设置页等全部 UI 文案
  • 支持 en(英文)和 zh(简体中文),跟随系统偏好自动初始化
  • t() 函数支持 dot-notation 键名,缺失键自动降级到英文并打印 console.warn

10. 全局状态管理

文件src/contexts/SettingsContext.jsx

基于 React Context + useState 的轻量方案,管理三项全局状态:

状态持久化方式初始化逻辑
themelocalStorage (pm:theme)优先读取存储值,否则跟随 prefers-color-scheme
languagelocalStorage (pm:language)默认 'en'
workspaceHandleIndexedDB (idb-keyval)启动时 restoreWorkspace() 静默恢复

关键技术亮点

1. 无后端本地优先架构

完全依赖浏览器原生能力(File System Access API + IndexedDB),零服务器成本,数据完全在用户本地,隐私性极高。

2. YAML Frontmatter 三层容错解析

从标准库解析到手动正则到旧格式兼容,确保任何历史版本的文件都能正确读取,并在下次保存时自动迁移到标准格式。

3. 元数据索引与增量同步

.metadata.json 作为 Sidecar 索引文件,避免每次都全量解析所有 .md 文件。通过文件修改时间戳实现增量同步,外部编辑器修改的文件也能被自动感知。

4. Monaco Editor 性能隔离

将 PreviewBar 用 React.memo 隔离,配合 useCallback 稳定回调引用,避免编辑区每秒数十次的击键事件触发 Monaco 实例的完整重渲染。

5. 保存流程的状态机设计

通过 originalFilenull vs object)精确区分新建/编辑两种模式,配合路径比对实现"同路径静默覆盖 + 不同路径冲突阻止 + 跨路径物理文件清理"的三段式保存逻辑。


项目统计

指标数据
源文件数12 个(.jsx / .js)
代码符号数125 个
依赖关系边245 条
核心 npm 依赖10 个(均为主流库)
当前版本v0.1.1-alpha

源码位置:Github