mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-01-16 08:21:55 +00:00
Update the package.json and pnpm-lock.yaml files by adding dependencies for sanitize-basename and unsanitize-basename, optimize the chat manager to support new filename formats, and improve code readability as well as user experience.
This commit is contained in:
parent
306817741f
commit
d3271f85e9
34
README.md
34
README.md
@ -4,17 +4,26 @@
|
||||
|
||||
<a href="README.md" target="_blank"><b>English</b></a> | <a href="README_zh-CN.md" target="_blank"><b>中文</b></a>
|
||||
|
||||
## Latest Version
|
||||
[0.5.0](https://github.com/infiolab/infio-copilot/releases/tag/0.5.0) Enhanced performance and stability improvements, added MCP support
|
||||
## ✨ What's New
|
||||
[0.7.2](https://github.com/infiolab/infio-copilot/releases/tag/0.7.2)
|
||||
We're excited to announce a major update packed with new features to streamline your workflow and supercharge your knowledge management within Obsidian.
|
||||
---
|
||||
|
||||
## Recent Updates
|
||||
[0.2.4](https://github.com/infiolab/infio-copilot/releases/tag/0.2.4) Added multilingual support
|
||||
* **🚀 Out-of-the-Box Embedding Model**
|
||||
To help you get started faster, we now include a default local embedding model (`bge-micro-v2`). No more manual setup is required to use powerful semantic features!
|
||||
|
||||
[0.2.3](https://github.com/infiolab/infio-copilot/releases/tag/0.2.3) Add custom mode config, you can create you own agent now
|
||||
* **🗂️ Workspaces**
|
||||
Organize your projects, research, and personal notes with the new **Workspaces** feature. Keep your context clean and switch between different setups seamlessly.
|
||||
|
||||
[0.1.7](https://github.com/infiolab/infio-copilot/releases/tag/0.1.7) Added image selector modal, allowing users to search, select, and upload images in obsidian vault or local file browser
|
||||
* **💡 Insights**
|
||||
Go beyond simple notes with our new **Insights** feature. Synthesize information, discover connections, and gain a deeper understanding of your knowledge base.
|
||||
|
||||
* **🔍 Advanced Multi-Dimensional Queries**
|
||||
Converse with your notes! You can now perform complex queries based on various dimensions like time, tasks, and other metadata. Finding the exact piece of information has never been easier.
|
||||
|
||||
* **✍️ New "Write" Mode**
|
||||
We've rebuilt our **Write** mode from the ground up to provide a more intuitive, powerful, and distraction-free writing experience.
|
||||
|
||||
[0.1.6](https://github.com/infiolab/infio-copilot/releases/tag/0.1.6) update apply view, you can edit content in apply view
|
||||
|
||||
## Features
|
||||
|
||||
@ -24,10 +33,15 @@
|
||||
| 📝 Autocomplete | Receive context-aware writing suggestions as you type |
|
||||
| ✏️ Inline Editing | Edit your notes directly within the current file |
|
||||
| 🔍 Vault Chat | Interact with your entire Obsidian vault using AI |
|
||||
| 🖼️ Image Analysis | Upload and analyze images from your vault or local system |
|
||||
| 🔍 Vault Search | Use semantic search to explore your entire vault |
|
||||
| ⌨️ Commands | Create and manage custom commands for quick actions |
|
||||
| 🎯 Custom Mode | Define personalized AI modes with specific behaviors |
|
||||
| 🔌 MCP | Manage Model Context Protocol integrations |
|
||||
| 🗂️ Workspaces | Organize projects, research, and personal notes with seamless context switching |
|
||||
| 💡 Insights | Synthesize information, discover connections, and gain deeper understanding |
|
||||
| 🔍 dataview query | Perform complex queries based on time, tasks, and metadata |
|
||||
| ✍️ New Write Mode | Rebuilt writing experience with intuitive, powerful, and distraction-free interface |
|
||||
|
||||
|
||||
### Chat & Edit Flow
|
||||
|
||||
@ -83,8 +97,8 @@ Leverage the power of AI to interact with your entire Obsidian vault, gaining in
|
||||
* Infio Copilot: Infio add selection to chat -> cmd + shift + L
|
||||
* Infio Copilot: Infio Inline Edit -> cmd + shift + K
|
||||

|
||||
7. If you need to chat with documents, you must configure an embedding model.
|
||||
- Currently, only SiliconFlow, Alibaba, Google, and OpenAI platforms support embedding models.
|
||||
7. **NEW: Out-of-the-Box Embedding Model** - The plugin now includes a default local embedding model (`bge-micro-v2`), so you can start using semantic features immediately! For enhanced performance, you can still configure additional embedding models:
|
||||
- Currently, SiliconFlow, Alibaba, Google, and OpenAI platforms support embedding models.
|
||||
|
||||
## Feedback and Support
|
||||
We value your input and want to ensure you can easily share your thoughts and report any issues:
|
||||
|
||||
@ -10,17 +10,20 @@ Infio Copilot 是一款可高度个人定制化的 Obsidian AI 插件,旨在
|
||||
|
||||
[](https://ko-fi.com/felixduan)
|
||||
|
||||
## 最新版本
|
||||
[0.5.0](https://github.com/infiolab/infio-copilot/releases/tag/0.5.0) 增强性能和稳定性改进, 增加了 MC P支持
|
||||
# 🚀 新版本发布:引入工作区、洞察与本地模型!
|
||||
|
||||
## 最近更新
|
||||
[0.2.4](https://github.com/infiolab/infio-copilot/releases/tag/0.2.4) 增加了多语言支持
|
||||
我们很高兴地宣布一个重要更新,它将彻底改变您的知识管理体验。此版本引入了强大的新功能,如工作区、洞察、以及开箱即用的本地嵌入模型,让您更深入地与笔记互动。
|
||||
|
||||
[0.2.3](https://github.com/infiolab/infio-copilot/releases/tag/0.2.3) 增加了自定义模式配置,现在无法创建自己的 agent
|
||||
---
|
||||
* **🧠 内置本地嵌入模型**:现在默认包含 `LocalProdver(bge-micro-v2)` 模型。无需任何额外配置,即可享受强大的本地语义搜索和分析功能。
|
||||
|
||||
[0.1.7](https://github.com/infiolab/infio-copilot/releases/tag/0.1.7) 增加了图片选择器模态框,允许用户在 Obsidian vault 或本地文件浏览器中搜索、选择和上传图片
|
||||
* **🗂️ 工作区 (Workspaces)**:引入全新的工作区功能,帮助您更好地组织和隔离不同的项目和知识领域,让您的工作流更加清晰。
|
||||
|
||||
[0.1.6](https://github.com/infiolab/infio-copilot/releases/tag/0.1.6) 更新了应用视图 (apply view),现在可以在应用视图中编辑内容
|
||||
* **💡 洞察 (Insights)**:我们增加了强大的“洞察”功能。您可以从笔记中提取关键摘要、进行反思或生成内容大纲,从您的知识库中发现深层联系。
|
||||
|
||||
* **🔍 多维度查询与对话**:像与人交谈一样与您的笔记互动。现在您可以根据时间、任务状态等多种维度进行查询,轻松找到所需信息。
|
||||
|
||||
* **✍️ 全新 `write` 模式**:一个专为写作而生的新模式,提供更专注、更流畅的创作体验,帮助您将想法转化为结构清晰的文档。
|
||||
|
||||
## 功能特点
|
||||
|
||||
@ -30,10 +33,14 @@ Infio Copilot 是一款可高度个人定制化的 Obsidian AI 插件,旨在
|
||||
| 📝 智能补全 | 在输入时获取上下文感知的写作建议 |
|
||||
| ✏️ 内联编辑 | 直接在当前文件中编辑笔记 |
|
||||
| 🔍 全库对话 | 使用 AI 与整个 Obsidian vault 交互 |
|
||||
| 🖼️ 图片分析 | 上传并分析来自 vault 或本地系统的图片 |
|
||||
| 语义搜索 | |
|
||||
| ⌨️ 快捷命令 | 创建和管理自定义快捷命令,实现快速操作 |
|
||||
| 🎯 自定义Mode | 定义具有特定行为的个性化 AI 模式 |
|
||||
| 🔌 MCP | 管理模型上下文协议集成 |
|
||||
| 🗂️ 工作空间 | 组织项目、研究和个人笔记,无缝切换上下文 |
|
||||
| 💡 深度洞察 | 综合信息、发现连接、获得更深层次的理解 |
|
||||
| 🔍 多维查询 | 基于时间、任务和元数据执行复杂查询 |
|
||||
| ✍️ 新写作模式 | 重构的写作体验,提供直观、强大且无干扰的界面 |
|
||||
|
||||
### 🖋️ 内联编辑
|
||||
|
||||
@ -95,8 +102,6 @@ Infio Copilot 是一款可高度个人定制化的 Obsidian AI 插件,旨在
|
||||
* Infio Copilot: Infio add selection to chat -> cmd + shift + L
|
||||
* Infio Copilot: Infio Inline Edit -> cmd + shift + K
|
||||

|
||||
7. 如果需要 跟文档聊天 , 需要配置 embedding 模型
|
||||
- 目前之后 SiliconFlow Alibaba Google OpenAI 平台支持嵌入模型
|
||||
|
||||
## 反馈与支持
|
||||
我们重视您的意见,并希望确保您能轻松分享想法和报告问题:
|
||||
|
||||
@ -120,11 +120,13 @@
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"remove-markdown": "^0.6.2",
|
||||
"sanitize-basename": "^2.0.2",
|
||||
"shell-env": "^4.0.1",
|
||||
"simple-git": "^3.27.0",
|
||||
"smart-embed-model": "^1.0.7",
|
||||
"string-similarity": "^4.0.4",
|
||||
"styled-components": "^6.1.19",
|
||||
"unsanitize-basename": "^2.0.1",
|
||||
"uuid": "^10.0.0",
|
||||
"zod": "3.24.2"
|
||||
},
|
||||
|
||||
53
pnpm-lock.yaml
generated
53
pnpm-lock.yaml
generated
@ -153,9 +153,6 @@ importers:
|
||||
lucide-react:
|
||||
specifier: ^0.447.0
|
||||
version: 0.447.0(react@18.3.1)
|
||||
markdown-to-text:
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1
|
||||
mermaid:
|
||||
specifier: ^11.6.0
|
||||
version: 11.8.0
|
||||
@ -213,6 +210,9 @@ importers:
|
||||
remove-markdown:
|
||||
specifier: ^0.6.2
|
||||
version: 0.6.2
|
||||
sanitize-basename:
|
||||
specifier: ^2.0.2
|
||||
version: 2.0.2
|
||||
shell-env:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1
|
||||
@ -228,6 +228,9 @@ importers:
|
||||
styled-components:
|
||||
specifier: ^6.1.19
|
||||
version: 6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
unsanitize-basename:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
uuid:
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
@ -580,8 +583,8 @@ packages:
|
||||
'@codemirror/language@6.11.2':
|
||||
resolution: {integrity: sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==}
|
||||
|
||||
'@codemirror/language@git+https://git@github.com:lishid/cm-language.git#6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67':
|
||||
resolution: {commit: 6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67, repo: git@github.com:lishid/cm-language.git, type: git}
|
||||
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67':
|
||||
resolution: {tarball: https://codeload.github.com/lishid/cm-language/tar.gz/6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67}
|
||||
version: 6.10.8
|
||||
|
||||
'@codemirror/lint@0.20.3':
|
||||
@ -2436,9 +2439,6 @@ packages:
|
||||
'@types/babel__traverse@7.20.7':
|
||||
resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==}
|
||||
|
||||
'@types/chai@4.3.20':
|
||||
resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==}
|
||||
|
||||
'@types/codemirror@5.60.8':
|
||||
resolution: {integrity: sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==}
|
||||
|
||||
@ -2608,9 +2608,6 @@ packages:
|
||||
resolution: {integrity: sha512-AlvLWYer6u4BkO4QzMkHo0t9RkvVIgqggVZmO+5snUiuX2caTKqtdqygX6GeE1VQa/TnXw9WoH0spcmHtG0inQ==}
|
||||
deprecated: This is a stub types definition. mermaid provides its own type definitions, so you do not need this installed.
|
||||
|
||||
'@types/mocha@8.2.3':
|
||||
resolution: {integrity: sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==}
|
||||
|
||||
'@types/ms@2.1.0':
|
||||
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
|
||||
|
||||
@ -5027,9 +5024,6 @@ packages:
|
||||
markdown-table@3.0.4:
|
||||
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
|
||||
|
||||
markdown-to-text@0.1.1:
|
||||
resolution: {integrity: sha512-co/J5l8mJ2RK9wD/nQRGwO7JxoeyfvVNtOZll016EdAX2qYkwCWMdtYvJO42b41Ho7GFEJMuly9llf0Nj+ReQw==}
|
||||
|
||||
marked@15.0.12:
|
||||
resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
|
||||
engines: {node: '>= 18'}
|
||||
@ -5454,8 +5448,8 @@ packages:
|
||||
'@codemirror/state': ^6.0.0
|
||||
'@codemirror/view': ^6.0.0
|
||||
|
||||
obsidian@git+https://git@github.com:obsidianmd/obsidian-api.git#103ff76a0712a02dd0da28646b5a6b0ba6686d66:
|
||||
resolution: {commit: 103ff76a0712a02dd0da28646b5a6b0ba6686d66, repo: git@github.com:obsidianmd/obsidian-api.git, type: git}
|
||||
obsidian@https://codeload.github.com/obsidianmd/obsidian-api/tar.gz/103ff76a0712a02dd0da28646b5a6b0ba6686d66:
|
||||
resolution: {tarball: https://codeload.github.com/obsidianmd/obsidian-api/tar.gz/103ff76a0712a02dd0da28646b5a6b0ba6686d66}
|
||||
version: 1.8.7
|
||||
peerDependencies:
|
||||
'@codemirror/state': ^6.0.0
|
||||
@ -6017,6 +6011,9 @@ packages:
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
sanitize-basename@2.0.2:
|
||||
resolution: {integrity: sha512-zaOQiK4PPsUQZ0Nx3KCrT9p0oEx1dTef14qflYq7TdxPRI2RY9faLYuExCiF8LiJdeKVYb5o/KdF0fGEvvEZUA==}
|
||||
|
||||
saxes@6.0.0:
|
||||
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
||||
engines: {node: '>=v12.22.7'}
|
||||
@ -6514,6 +6511,9 @@ packages:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
unsanitize-basename@2.0.1:
|
||||
resolution: {integrity: sha512-ywgB/ygePvtjszN3ZTK9H+OWF7Bt2AFbeLDxkx01/EjWuB4DhmdFpkLv2sg0twaZbELi+JQjLUwjZrVbgQSuJg==}
|
||||
|
||||
update-browserslist-db@1.1.3:
|
||||
resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
|
||||
hasBin: true
|
||||
@ -7089,7 +7089,7 @@ snapshots:
|
||||
'@lezer/lr': 1.4.2
|
||||
style-mod: 4.1.2
|
||||
|
||||
'@codemirror/language@git+https://git@github.com:lishid/cm-language.git#6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67':
|
||||
'@codemirror/language@https://codeload.github.com/lishid/cm-language/tar.gz/6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.38.0
|
||||
@ -8967,8 +8967,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/types': 7.28.0
|
||||
|
||||
'@types/chai@4.3.20': {}
|
||||
|
||||
'@types/codemirror@5.60.8':
|
||||
dependencies:
|
||||
'@types/tern': 0.23.9
|
||||
@ -9175,8 +9173,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@types/mocha@8.2.3': {}
|
||||
|
||||
'@types/ms@2.1.0': {}
|
||||
|
||||
'@types/node-fetch@2.6.12':
|
||||
@ -12055,11 +12051,6 @@ snapshots:
|
||||
|
||||
markdown-table@3.0.4: {}
|
||||
|
||||
markdown-to-text@0.1.1:
|
||||
dependencies:
|
||||
'@types/chai': 4.3.20
|
||||
'@types/mocha': 8.2.3
|
||||
|
||||
marked@15.0.12: {}
|
||||
|
||||
matcher@3.0.0:
|
||||
@ -12604,7 +12595,7 @@ snapshots:
|
||||
|
||||
obsidian-daily-notes-interface@0.8.4(@codemirror/state@6.5.2)(@codemirror/view@6.38.0):
|
||||
dependencies:
|
||||
obsidian: git+https://git@github.com:obsidianmd/obsidian-api.git#103ff76a0712a02dd0da28646b5a6b0ba6686d66(@codemirror/state@6.5.2)(@codemirror/view@6.38.0)
|
||||
obsidian: https://codeload.github.com/obsidianmd/obsidian-api/tar.gz/103ff76a0712a02dd0da28646b5a6b0ba6686d66(@codemirror/state@6.5.2)(@codemirror/view@6.38.0)
|
||||
tslib: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- '@codemirror/state'
|
||||
@ -12612,7 +12603,7 @@ snapshots:
|
||||
|
||||
obsidian-dataview@0.5.68:
|
||||
dependencies:
|
||||
'@codemirror/language': git+https://git@github.com:lishid/cm-language.git#6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67
|
||||
'@codemirror/language': https://codeload.github.com/lishid/cm-language/tar.gz/6c1c5f5b677f6f6503d1ca2ec47f62f6406cda67
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.38.0
|
||||
emoji-regex: 10.4.0
|
||||
@ -12631,7 +12622,7 @@ snapshots:
|
||||
'@types/codemirror': 5.60.8
|
||||
moment: 2.29.4
|
||||
|
||||
obsidian@git+https://git@github.com:obsidianmd/obsidian-api.git#103ff76a0712a02dd0da28646b5a6b0ba6686d66(@codemirror/state@6.5.2)(@codemirror/view@6.38.0):
|
||||
obsidian@https://codeload.github.com/obsidianmd/obsidian-api/tar.gz/103ff76a0712a02dd0da28646b5a6b0ba6686d66(@codemirror/state@6.5.2)(@codemirror/view@6.38.0):
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.38.0
|
||||
@ -13336,6 +13327,8 @@ snapshots:
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
sanitize-basename@2.0.2: {}
|
||||
|
||||
saxes@6.0.0:
|
||||
dependencies:
|
||||
xmlchars: 2.2.0
|
||||
@ -13991,6 +13984,8 @@ snapshots:
|
||||
|
||||
unpipe@1.0.0: {}
|
||||
|
||||
unsanitize-basename@2.0.1: {}
|
||||
|
||||
update-browserslist-db@1.1.3(browserslist@4.25.1):
|
||||
dependencies:
|
||||
browserslist: 4.25.1
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { App } from 'obsidian'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import sanitize from 'sanitize-basename'
|
||||
import unsanitize from 'unsanitize-basename'
|
||||
|
||||
import { ChatConversationMeta } from '../../../types/chat'
|
||||
import { AbstractJsonRepository } from '../base'
|
||||
@ -12,7 +14,6 @@ import {
|
||||
ChatConversation
|
||||
} from './types'
|
||||
|
||||
|
||||
export class ChatManager extends AbstractJsonRepository<
|
||||
ChatConversation,
|
||||
ChatConversationMeta
|
||||
@ -25,35 +26,89 @@ export class ChatManager extends AbstractJsonRepository<
|
||||
}
|
||||
|
||||
protected generateFileName(chat: ChatConversation): string {
|
||||
// 新格式: v{schemaVersion}_{title}_{updatedAt}_{id}_{workspaceId}.json
|
||||
// 新格式 v2: v{schemaVersion}_{sanitizedTitle}_{updatedAt}_{id}_{workspaceId}.json
|
||||
const sanitizedTitle = sanitize(chat.title, { maxLength: 100 })
|
||||
// 如果没有工作区,使用 'vault' 作为默认值
|
||||
const encodedTitle = encodeURIComponent(chat.title)
|
||||
const workspaceId = chat.workspace || 'vault'
|
||||
return `v${chat.schemaVersion}_${encodedTitle}_${chat.updatedAt}_${chat.id}_${workspaceId}.json`
|
||||
return `v${chat.schemaVersion}_${sanitizedTitle}_${chat.updatedAt}_${chat.id}_${workspaceId}.json`
|
||||
}
|
||||
|
||||
protected parseFileName(fileName: string): ChatConversationMeta | null {
|
||||
// 使用一个正则表达式,工作区部分为可选: v{schemaVersion}_{title}_{updatedAt}_{id}_{workspaceId}?.json
|
||||
// 通过头两个字符判断版本
|
||||
if (fileName.startsWith('v2_')) {
|
||||
return this.parseFileNameV2(fileName)
|
||||
} else if (fileName.startsWith('v1_')) {
|
||||
return this.parseFileNameV1(fileName)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析新版本 (v2) 文件名
|
||||
* 格式: v2_{sanitizedTitle}_{updatedAt}_{id}_{workspaceId}.json
|
||||
*/
|
||||
private parseFileNameV2(fileName: string): ChatConversationMeta | null {
|
||||
const regex = new RegExp(
|
||||
`^v${CHAT_SCHEMA_VERSION}_(.+)_(\\d+)_([0-9a-f-]+)(?:_([^_]+))?\\.json$`,
|
||||
`^v2_(.+)_(\\d+)_([0-9a-f-]+)(?:_([^_]+))?\\.json$`,
|
||||
)
|
||||
const match = fileName.match(regex)
|
||||
|
||||
if (!match) return null
|
||||
|
||||
const title = decodeURIComponent(match[1])
|
||||
const updatedAt = parseInt(match[2], 10)
|
||||
const id = match[3]
|
||||
const workspaceId = match[4] // 可能为undefined(老格式)
|
||||
try {
|
||||
// 使用 unsanitize-basename 还原原始标题
|
||||
const title = unsanitize(match[1])
|
||||
const updatedAt = parseInt(match[2], 10)
|
||||
const id = match[3]
|
||||
const workspaceId = match[4] // 可能为undefined(老格式)
|
||||
|
||||
return {
|
||||
id,
|
||||
schemaVersion: CHAT_SCHEMA_VERSION,
|
||||
title,
|
||||
updatedAt,
|
||||
createdAt: 0,
|
||||
// 如果没有工作区信息(老格式),则认为是vault(全局消息)
|
||||
workspace: workspaceId === 'vault' ? undefined : workspaceId,
|
||||
return {
|
||||
id,
|
||||
schemaVersion: 2,
|
||||
title,
|
||||
updatedAt,
|
||||
createdAt: 0,
|
||||
// 如果没有工作区信息(老格式),则认为是vault(全局消息)
|
||||
workspace: workspaceId === 'vault' ? undefined : workspaceId,
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to unsanitize filename:', fileName, error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析旧版本 (v1) 文件名
|
||||
* 格式: v1_{encodedTitle}_{updatedAt}_{id}_{workspaceId}.json
|
||||
*/
|
||||
private parseFileNameV1(fileName: string): ChatConversationMeta | null {
|
||||
const regex = new RegExp(
|
||||
`^v1_(.+)_(\\d+)_([0-9a-f-]+)(?:_([^_]+))?\\.json$`,
|
||||
)
|
||||
const match = fileName.match(regex)
|
||||
|
||||
if (!match) return null
|
||||
|
||||
try {
|
||||
// 旧版本使用 decodeURIComponent
|
||||
const title = decodeURIComponent(match[1])
|
||||
const updatedAt = parseInt(match[2], 10)
|
||||
const id = match[3]
|
||||
const workspaceId = match[4] // 可能为undefined(老格式)
|
||||
|
||||
return {
|
||||
id,
|
||||
schemaVersion: 1,
|
||||
title,
|
||||
updatedAt,
|
||||
createdAt: 0,
|
||||
// 如果没有工作区信息(老格式),则认为是vault(全局消息)
|
||||
workspace: workspaceId === 'vault' ? undefined : workspaceId,
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to decode v1 filename:', fileName, error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { SerializedChatMessage } from '../../../types/chat'
|
||||
|
||||
export const CHAT_SCHEMA_VERSION = 1
|
||||
export const CHAT_SCHEMA_VERSION = 2
|
||||
|
||||
export type ChatConversation = {
|
||||
id: string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user