mirror of
https://github.com/2949984428/claude-skill-sync.git
synced 2026-07-22 06:55:06 +00:00
Initial release v0.1.0
This commit is contained in:
commit
67fb0abf29
11 changed files with 2688 additions and 0 deletions
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# 用户本地设置(含本机 home 路径,不应入库)
|
||||
data.json
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# Editor
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Node(如果以后改成 TS 编译)
|
||||
node_modules/
|
||||
*.log
|
||||
29
CHANGELOG.md
Normal file
29
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this plugin will be documented here.
|
||||
|
||||
## [0.1.0] - 2026-04-23
|
||||
|
||||
### 首发版本
|
||||
|
||||
**核心功能**
|
||||
- 扫描 Obsidian 内的 Skill 文件夹,一键 symlink 到 18+ Coding 工具(Claude Code / Codex / Cursor / Gemini CLI / Windsurf / Trae 等)
|
||||
- 双向同步:vault → 工具(安装)+ 工具 → vault(导入)
|
||||
- 8 格同步状态卡:已同步 / 部分同步 / 未安装 / 待导入 / 指向错误 / 失效链接 / 冲突,每格 hover 显示用户视角的 tooltip
|
||||
- Skill 列表带搜索 + 折叠 description
|
||||
|
||||
**自动化**
|
||||
- 定时扫描(默认 5 分钟,可配置)
|
||||
- 自动安装新 Skill 到所有 Coding 工具(默认开,安全)
|
||||
- 自动从工具导入新 Skill 到 vault(默认关,需主动开启)
|
||||
- 启动时同步状态摘要通知
|
||||
|
||||
**安全护栏**
|
||||
- 移除只断开链接,不删除源 Skill
|
||||
- 冲突状态需人工处理,绝不覆盖工具自带的实体 Skill
|
||||
- 删除按钮二次确认(3 秒确认窗口)
|
||||
|
||||
**配置**
|
||||
- 添加 Coding 工具弹窗:18 个预设可选 + 自定义路径
|
||||
- 设置面板用用户视角语言,避免技术黑话
|
||||
- 仅桌面端(移动端 Obsidian 不支持 symlink)
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 Chocolae
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
151
PUBLISH.md
Normal file
151
PUBLISH.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
# 发布到 GitHub + Obsidian 插件商店
|
||||
|
||||
> 本指南假设你已安装 `git` 和 `gh`(GitHub CLI),且已 `gh auth login`。
|
||||
|
||||
## 一次性准备:替换占位符
|
||||
|
||||
发布前先把这些 `<YOUR-...>` 占位符替换成你的真实信息:
|
||||
|
||||
```bash
|
||||
# 在仓库根目录执行(macOS)
|
||||
cd ~/Documents/claude-skill-sync
|
||||
sed -i '' 's/<YOUR-NAME>/你的真名/g' manifest.json LICENSE
|
||||
sed -i '' 's/<YOUR-GITHUB>/你的GitHub用户名/g' manifest.json README.md docs/USAGE.md
|
||||
```
|
||||
|
||||
或者手动编辑:
|
||||
- `manifest.json` → `author`、`authorUrl`
|
||||
- `LICENSE` → 版权人姓名
|
||||
- `README.md` → repo 链接
|
||||
- `docs/USAGE.md` → repo 链接
|
||||
|
||||
## 第一阶段:发布到 GitHub
|
||||
|
||||
### 1. 初始化 git 仓库
|
||||
|
||||
```bash
|
||||
cd ~/Documents/claude-skill-sync
|
||||
git init
|
||||
git add .
|
||||
git status # 确认 data.json 已被 .gitignore 忽略
|
||||
git commit -m "Initial release v0.1.0"
|
||||
```
|
||||
|
||||
### 2. 在 GitHub 创建公开 repo 并 push
|
||||
|
||||
```bash
|
||||
gh repo create claude-skill-sync --public --source=. --push --description "Manage AI coding agent Skills from your Obsidian vault"
|
||||
```
|
||||
|
||||
或网页创建后:
|
||||
```bash
|
||||
git branch -M main
|
||||
git remote add origin https://github.com/<你的用户名>/claude-skill-sync.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
### 3. 创建 v0.1.0 Release(**Obsidian 商店硬要求**)
|
||||
|
||||
商店审核会从 GitHub Releases 拉取 `manifest.json` / `main.js` / `styles.css`,**tag 名必须等于 manifest.json 的 version,不带 `v` 前缀**。
|
||||
|
||||
```bash
|
||||
gh release create 0.1.0 \
|
||||
manifest.json main.js styles.css \
|
||||
--title "0.1.0 — 首发版本" \
|
||||
--notes-file CHANGELOG.md
|
||||
```
|
||||
|
||||
注意三个 asset 必须直接上传到 release(不是源码 zip 里)。
|
||||
|
||||
### 4. 验证 release 可访问
|
||||
|
||||
```bash
|
||||
curl -sI https://github.com/<你的用户名>/claude-skill-sync/releases/download/0.1.0/manifest.json | head -1
|
||||
# 期望 200 或 302
|
||||
```
|
||||
|
||||
## 第二阶段:提交到 Obsidian 插件商店
|
||||
|
||||
### 1. Fork obsidianmd/obsidian-releases
|
||||
|
||||
```bash
|
||||
gh repo fork obsidianmd/obsidian-releases --clone --remote
|
||||
cd obsidian-releases
|
||||
```
|
||||
|
||||
### 2. 编辑 community-plugins.json,追加你的条目
|
||||
|
||||
打开文件,在数组**末尾**追加(注意前一项末尾要补逗号):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "claude-skill-sync",
|
||||
"name": "Claude Skill Sync",
|
||||
"author": "<你的真名>",
|
||||
"description": "Manage AI coding agent Skills (Claude Code, Codex, Cursor, Gemini, and more) from your Obsidian vault. One source, symlinked to each tool.",
|
||||
"repo": "<你的GitHub用户名>/claude-skill-sync"
|
||||
}
|
||||
```
|
||||
|
||||
`repo` 字段格式必须是 `<owner>/<repo-name>`,不带 https://。
|
||||
|
||||
### 3. 提交 PR
|
||||
|
||||
```bash
|
||||
git checkout -b add-claude-skill-sync
|
||||
git add community-plugins.json
|
||||
git commit -m "Add Claude Skill Sync plugin"
|
||||
git push origin add-claude-skill-sync
|
||||
gh pr create --repo obsidianmd/obsidian-releases \
|
||||
--title "Add Claude Skill Sync" \
|
||||
--body "Plugin repo: https://github.com/<你的用户名>/claude-skill-sync
|
||||
|
||||
Manages AI coding agent Skills from Obsidian vault, symlinked to Claude Code / Codex / Cursor / 18+ tools."
|
||||
```
|
||||
|
||||
### 4. 等待审核
|
||||
|
||||
- 自动检查(bot):通常几分钟内完成,会跑 `manifest.json` 校验、文件存在性、命名规范等
|
||||
- 人工审核:1-4 周(受 Obsidian 团队的处理速度影响)
|
||||
- 如果 bot 标红,修复后 push 同分支即可重新触发
|
||||
|
||||
## 常见审核问题与修复
|
||||
|
||||
| 问题 | 原因 | 修复 |
|
||||
|---|---|---|
|
||||
| Release tag 不匹配 | tag 用了 `v0.1.0` 而非 `0.1.0` | `gh release delete v0.1.0` 后用正确 tag 重发 |
|
||||
| manifest.json not found in release | 上传到 release 时没附 asset | `gh release upload 0.1.0 manifest.json main.js styles.css` |
|
||||
| `id` 已被占用 | 跟现有插件 id 冲突 | 改一个独特的 id,记得 manifest.json 和商店 PR 都改 |
|
||||
| 包含 `console.log` | 商店要求 production 代码无调试输出 | 全文搜 `console.` 删除或注释 |
|
||||
| `data.json` 被提交 | `.gitignore` 没生效 | `git rm --cached data.json && git commit` |
|
||||
| Description 太长 | > 250 chars 会被警告 | 精简到一句话 |
|
||||
| innerHTML 用法 | Obsidian 出于 XSS 安全禁止 `innerHTML` | 改用 createEl / setText |
|
||||
|
||||
## 后续版本发布流程
|
||||
|
||||
```bash
|
||||
# 1. 改 manifest.json 的 version (如 0.2.0)
|
||||
# 2. versions.json 加新条目: "0.2.0": "1.4.0"
|
||||
# 3. CHANGELOG.md 加新版本说明
|
||||
# 4. 提交并打 tag
|
||||
git add manifest.json versions.json CHANGELOG.md
|
||||
git commit -m "Release v0.2.0"
|
||||
git push
|
||||
|
||||
# 5. 创建新 release
|
||||
gh release create 0.2.0 manifest.json main.js styles.css \
|
||||
--title "0.2.0 — 描述" \
|
||||
--notes "见 CHANGELOG.md"
|
||||
```
|
||||
|
||||
新版本发布后**不需要再提交 PR 到 obsidian-releases**,商店会自动从你的 GitHub Releases 拉新版。
|
||||
|
||||
## 用户安装方式
|
||||
|
||||
商店审核通过后,用户可以:
|
||||
1. Obsidian → 设置 → 第三方插件 → 浏览
|
||||
2. 搜索 "Claude Skill Sync"
|
||||
3. Install → Enable
|
||||
|
||||
也可以用 [BRAT](https://github.com/TfTHacker/obsidian42-brat) 提前预览(无需等审核):
|
||||
- 在 BRAT 里 Add Beta Plugin → 输入 `<你的用户名>/claude-skill-sync`
|
||||
114
README.md
Normal file
114
README.md
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# Claude Skill Sync
|
||||
|
||||
Obsidian 插件 — 把 Obsidian vault 作为 AI agent skill 的中央仓库,一键 symlink 到 Claude Code / Codex / Cursor 等工具的 skill 目录,跨电脑同步交给 vault 自身的 sync 方案。
|
||||
|
||||
> 配套理念:**单一真身(vault),多处替身(symlink)**。任何位置编辑都即时一致,不复制内容、不占额外空间。
|
||||
|
||||

|
||||
|
||||
> 详细使用指南:[docs/USAGE.md](docs/USAGE.md)
|
||||
|
||||
## 安装
|
||||
|
||||
### 方式 A:开发者本地(推荐)
|
||||
|
||||
```bash
|
||||
# 1. clone 到本地任意位置
|
||||
git clone https://github.com/<owner>/claude-skill-sync.git ~/Documents/claude-skill-sync
|
||||
|
||||
# 2. 在你的 Obsidian vault 里建 symlink 指向它
|
||||
cd /path/to/your-vault
|
||||
ln -s ~/Documents/claude-skill-sync .obsidian/plugins/claude-skill-sync
|
||||
|
||||
# 3. 启动 Obsidian → 设置 → 第三方插件 → 关闭安全模式 → 启用 Claude Skill Sync
|
||||
```
|
||||
|
||||
升级:`cd ~/Documents/claude-skill-sync && git pull`,然后在 Obsidian 里重新加载插件即可。
|
||||
|
||||
### 方式 B:直接复制(最简)
|
||||
|
||||
把整个目录复制到 vault 内:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<owner>/claude-skill-sync.git \
|
||||
/path/to/your-vault/.obsidian/plugins/claude-skill-sync
|
||||
```
|
||||
|
||||
## 启用后
|
||||
|
||||
1. 设置 → Claude Skill Sync 中确认:
|
||||
- **Vault 内 Skill 根目录**(默认 `Skills`,可改成你 vault 里的实际路径,如 `SkillPack/skills`)
|
||||
- **目标平台**(默认 Claude Code + Codex/Agents,可加任意)
|
||||
2. 左侧 ribbon 点插头图标打开侧边栏
|
||||
3. 在 vault 的 skill 根目录下放 skill(每个子目录 = 一个 skill,含 `SKILL.md`)
|
||||
4. 点"全部安装"——所有 skill symlink 到本机平台目录,AI 工具立即可用
|
||||
|
||||
## 功能
|
||||
|
||||
- **侧边栏状态卡**:8 格 grid 显示已同步 / 部分同步 / 未安装 / 待导入 / 指向错误 / 失效 link / 冲突
|
||||
- **双向同步**:vault → 平台(install)+ 平台 → vault(import 向导)
|
||||
- **失效 link 一键清理**:vault 删了 skill,残留的 symlink 一键扫掉
|
||||
- **指向错误一键修复**:vault 路径变了,所有 symlink 一键改指
|
||||
- **定时自动同步**(默认 5 分钟):vault 新 skill 自动安装;平台新真目录默认仅提醒、可选自动导入
|
||||
- **启动状态提醒**:打开 Obsidian 弹通知摘要
|
||||
|
||||
## 工作机制
|
||||
|
||||
```
|
||||
vault/<skillRoot>/<name>/ ← 真身(数据)
|
||||
▲
|
||||
│ symlink
|
||||
│
|
||||
~/.claude/skills/<name> ← 替身
|
||||
~/.agents/skills/<name> ← 替身
|
||||
~/.cursor/skills/<name> ← 替身(自行添加平台)
|
||||
```
|
||||
|
||||
所有 AI 工具读取的是同一份内容,跨工具立即一致。
|
||||
|
||||
## 跨电脑同步
|
||||
|
||||
vault 通过 Obsidian Sync / iCloud / Git / 坚果云等任意方案同步真身;每台电脑上的"替身"由本插件本地建立。
|
||||
|
||||
`data.json`(每机平台路径)应当**不参与跨机同步**(含 `~`,不同电脑展开后不同;本仓库 `.gitignore` 已忽略)。
|
||||
|
||||
## 平台支持
|
||||
|
||||
- ✅ macOS / Linux / Windows 桌面端
|
||||
- ❌ 移动端(iOS/Android Obsidian 无 Node fs / symlink 能力,插件 `isDesktopOnly: true`)
|
||||
|
||||
## 配置示例
|
||||
|
||||
`data.json`(首次启用后自动生成;勿提交至 git):
|
||||
|
||||
```json
|
||||
{
|
||||
"skillRoot": "SkillPack/skills",
|
||||
"platforms": [
|
||||
{ "name": "Claude Code", "target": "~/.claude/skills", "enabled": true },
|
||||
{ "name": "Codex / Agents", "target": "~/.agents/skills", "enabled": true },
|
||||
{ "name": "Cursor", "target": "~/.cursor/skills", "enabled": false }
|
||||
],
|
||||
"notifyOnStartup": true,
|
||||
"autoScanIntervalMin": 5,
|
||||
"autoInstall": true,
|
||||
"autoImport": false
|
||||
}
|
||||
```
|
||||
|
||||
## 开发
|
||||
|
||||
纯 JS,无 build。改 `main.js` → Obsidian 设置里关掉再开启插件即可。
|
||||
|
||||
```
|
||||
.
|
||||
├── manifest.json # 插件元信息
|
||||
├── main.js # 全部逻辑(~770 行)
|
||||
├── styles.css # 侧边栏样式
|
||||
├── data.json # 用户本地设置(gitignore)
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT — 见 LICENSE
|
||||
164
docs/USAGE.md
Normal file
164
docs/USAGE.md
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
# Claude Skill Sync — 使用指南
|
||||
|
||||
> Obsidian 插件 + AI Coding 工具的协同管理:把 vault 当中央仓库,所有 AI 工具读到的是同一份 skill。
|
||||
|
||||
## 架构图
|
||||
|
||||

|
||||
|
||||
> 源文件:[architecture.excalidraw](./architecture.excalidraw)
|
||||
> 在 [excalidraw.com](https://excalidraw.com) 打开 → Open → 选择该文件即可编辑。
|
||||
> 导出 PNG:在 excalidraw.com 里 Menu → Export image → PNG,覆盖 `architecture.png` 后 commit 即可在 README 里渲染。
|
||||
|
||||
## 30 秒理解
|
||||
|
||||
- vault 内 `SkillPack/skills/<name>/` 是 skill **真身**(数据本体,唯一一份)
|
||||
- `~/.claude/skills/<name>` `~/.agents/skills/<name>` 等是 **替身**(symlink,指向真身)
|
||||
- 跨电脑:vault 同步把真身推到另一台机;另一台机点插件「全部安装」自动建好替身
|
||||
- 任何位置编辑都即时一致 — Obsidian 改、Claude Code 立刻看到
|
||||
|
||||
## 安装(4 步)
|
||||
|
||||
### 1. clone 插件 repo
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<owner>/claude-skill-sync.git ~/Documents/claude-skill-sync
|
||||
```
|
||||
|
||||
### 2. 在 vault 里建 skill 中央目录
|
||||
|
||||
```bash
|
||||
mkdir -p /path/to/your-vault/SkillPack/skills
|
||||
```
|
||||
|
||||
> 目录名可改,默认是 `Skills/`,本指南推荐用 `SkillPack/skills/`(便于和文档放一起)。
|
||||
|
||||
### 3. 把插件 symlink 到 vault 的 .obsidian/plugins/
|
||||
|
||||
```bash
|
||||
cd /path/to/your-vault
|
||||
ln -s ~/Documents/claude-skill-sync .obsidian/plugins/claude-skill-sync
|
||||
```
|
||||
|
||||
> 用 symlink 而不是 cp:之后 `git pull` 升级插件,所有 vault 一起生效。
|
||||
|
||||
### 4. 在 Obsidian 启用
|
||||
|
||||
1. 设置 → 第三方插件 → **关闭安全模式**
|
||||
2. 启用 **Claude Skill Sync**
|
||||
3. 设置面板里把 **Vault 内 Skill 根目录**改成你的实际路径(如 `SkillPack/skills`)
|
||||
|
||||
## 日常使用
|
||||
|
||||
### 添加一个新 skill
|
||||
|
||||
```bash
|
||||
mkdir -p /path/to/your-vault/SkillPack/skills/my-new-skill
|
||||
```
|
||||
|
||||
在该目录里创建 `SKILL.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: my-new-skill
|
||||
description: 一句话描述这个 skill 干嘛
|
||||
---
|
||||
|
||||
# my-new-skill
|
||||
|
||||
详细内容...
|
||||
```
|
||||
|
||||
回到 Obsidian 侧边栏点「全部安装」(或等 5 分钟自动同步),所有 AI 工具立刻可用。
|
||||
|
||||
### 添加新平台
|
||||
|
||||
设置 → Claude Skill Sync → 「+ 添加平台」按钮,弹窗里选预设:
|
||||
|
||||
- Claude Code, Codex / Agents, Cursor, Gemini CLI, Qwen Code, Windsurf, Trae / Trae CN
|
||||
- Junie, Factory Droid, Augment, OpenCode, KiloCode, Qoder, OB1, Amp, Kiro, CodeBuddy
|
||||
- 自定义(点底部「+ 自定义平台」展开)
|
||||
|
||||
### 跨电脑同步
|
||||
|
||||
**新机首次接入**:
|
||||
1. vault 同步软件(Obsidian Sync / iCloud / Git / 坚果云 / Remotely Save)拉下 vault
|
||||
2. 按上面安装步骤 1+3+4(不需要重新建 SkillPack/skills/,sync 已经带过来了)
|
||||
3. 启用插件后状态卡显示「48 未安装」,点「全部安装」即完成
|
||||
|
||||
**日常**:
|
||||
- A 电脑添加新 skill → vault sync 推到云 → B 电脑拉到 → B 电脑插件 5 分钟内自动安装(默认开启)
|
||||
|
||||
## 侧边栏功能
|
||||
|
||||
**顶部**:
|
||||
- 「刷新」「全部安装」「导入现有」三个按钮
|
||||
- 中央目录路径显示
|
||||
|
||||
**同步状态卡**(8 格 grid):
|
||||
| 格子 | 含义 | 点击行为 |
|
||||
|---|---|---|
|
||||
| vault skill (×N 平台) | vault 内 skill 数 | — |
|
||||
| 已同步 | 在所有启用平台都装好的数 | — |
|
||||
| 部分同步 | 只装了部分平台 | 全部安装补齐 |
|
||||
| 未安装 | 一个平台都没装 | 全部安装 |
|
||||
| 待导入 | 平台目录有真目录、vault 无 | 开导入向导 |
|
||||
| 指向错误 | symlink 指向其他位置 | 修复全部 |
|
||||
| 失效 link | symlink 指向已不存在 | 一键清理 |
|
||||
| 冲突 | 平台目录有同名真目录 | 需手动处理 |
|
||||
|
||||
**搜索框**:按 skill 名 / description 即时过滤
|
||||
|
||||
**skill 列表**(默认收起 description):
|
||||
- 每行:`▸ skill-name` + 各平台徽章 + 操作按钮(安装 / 移除 / 改指向)
|
||||
- 点 ▸ 三角或 name 行展开 description
|
||||
|
||||
## 设置项详解
|
||||
|
||||
### 启动时提醒同步状态(默认 ON)
|
||||
打开 Obsidian 后 1.5 秒扫一遍,发现不一致弹通知。
|
||||
|
||||
### 定时扫描间隔(默认 5 分钟,0 = 关)
|
||||
后台轮询。修改即时生效。
|
||||
|
||||
### 自动安装新 skill (vault → 平台)(默认 ON,安全)
|
||||
扫描时发现 vault 新 skill 没装到平台 → 自动建 symlink。
|
||||
|
||||
### 自动导入新 skill (平台 → vault)(默认 OFF,⚠️ 危险)
|
||||
扫描时发现平台目录有新真目录 → 自动 mv 进 vault。
|
||||
**mv 不可逆**,仅当确定平台目录不会被其他工具临时使用时才开。
|
||||
|
||||
## 安全护栏
|
||||
|
||||
| 行为 | 保护 |
|
||||
|---|---|
|
||||
| 卸载 / 移除 | 只删 symlink,检测目标不是 symlink 拒绝执行 |
|
||||
| 全部安装 | 跳过冲突状态(同名真目录),不会覆盖 |
|
||||
| 导入现有 | 用 `fs.rename` 原子操作,跨设备失败立刻报告 |
|
||||
| 清理失效 | 只删孤儿 symlink,不动真目录 |
|
||||
| 自动同步 | install 默认开(安全),import 默认关(危险) |
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q:状态卡数字不对?**
|
||||
A:点「刷新」或在设置里修正 skillRoot 路径。
|
||||
|
||||
**Q:换电脑后所有 symlink 都「指向错误」?**
|
||||
A:vault 路径变了。点「指向错误」格子一键 repair,自动按当前 vault 路径重建。
|
||||
|
||||
**Q:移动设备能用吗?**
|
||||
A:不能。iOS/Android Obsidian 没有 Node fs / symlink 能力,插件 `isDesktopOnly: true`。但 vault 里的 skill 文档你仍然可以在手机上**阅读和编辑**,回到桌面端再 install。
|
||||
|
||||
**Q:插件升级怎么做?**
|
||||
A:`cd ~/Documents/claude-skill-sync && git pull`,回 Obsidian 设置里关掉再开启 Claude Skill Sync 即重载。
|
||||
|
||||
**Q:data.json 要不要提交 git?**
|
||||
A:**不要**。它含本机 home 路径,每台电脑展开后不同;本仓库 `.gitignore` 已忽略。
|
||||
|
||||
**Q:vault 同步把 .obsidian/ 排除了,插件怎么办?**
|
||||
A:插件本来就是每台电脑独立 `git clone` + `ln -s`。vault 同步只负责真身(`SkillPack/skills/`)。
|
||||
|
||||
## 反馈
|
||||
|
||||
- Issue: <https://github.com/<owner>/claude-skill-sync/issues>
|
||||
- 详细原理:[../docs/流程与原理.md](https://github.com/<owner>/skill-pack-data) (如果你也共享了 SkillPack 数据 repo)
|
||||
817
docs/architecture.excalidraw
Normal file
817
docs/architecture.excalidraw
Normal file
|
|
@ -0,0 +1,817 @@
|
|||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"id": "title-main",
|
||||
"type": "text",
|
||||
"x": 380, "y": 20, "width": 540, "height": 38,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100001, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Claude Skill Sync — 架构与使用流程",
|
||||
"fontSize": 28, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Claude Skill Sync — 架构与使用流程",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "github-container",
|
||||
"type": "rectangle",
|
||||
"x": 50, "y": 90, "width": 280, "height": 400,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "#d3f9d8",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100002, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "github-title",
|
||||
"type": "text",
|
||||
"x": 110, "y": 105, "width": 160, "height": 28,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100003, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "GitHub Repo",
|
||||
"fontSize": 20, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "GitHub Repo",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "github-sub",
|
||||
"type": "text",
|
||||
"x": 95, "y": 138, "width": 200, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100004, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "claude-skill-sync",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "claude-skill-sync",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "github-files",
|
||||
"type": "text",
|
||||
"x": 80, "y": 180, "width": 220, "height": 220,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100005, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "• main.js\n• manifest.json\n• styles.css\n• README.md\n• LICENSE\n• .gitignore",
|
||||
"fontSize": 16, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "• main.js\n• manifest.json\n• styles.css\n• README.md\n• LICENSE\n• .gitignore",
|
||||
"autoResize": true, "lineHeight": 1.5
|
||||
},
|
||||
{
|
||||
"id": "github-note",
|
||||
"type": "text",
|
||||
"x": 75, "y": 440, "width": 230, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100006, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "纯 JS · 无 build · MIT",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "纯 JS · 无 build · MIT",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "vault-container",
|
||||
"type": "rectangle",
|
||||
"x": 380, "y": 90, "width": 560, "height": 400,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#a5d8ff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100010, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "vault-title",
|
||||
"type": "text",
|
||||
"x": 575, "y": 105, "width": 170, "height": 28,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100011, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Obsidian Vault",
|
||||
"fontSize": 20, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Obsidian Vault",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "vault-sub",
|
||||
"type": "text",
|
||||
"x": 530, "y": 138, "width": 260, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100012, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "跨电脑通过 vault 自身同步",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "跨电脑通过 vault 自身同步",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "skills-box",
|
||||
"type": "rectangle",
|
||||
"x": 400, "y": 175, "width": 520, "height": 115,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100020, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "skills-title",
|
||||
"type": "text",
|
||||
"x": 415, "y": 187, "width": 280, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100021, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "SkillPack/skills/ 「真身, 唯一一份」",
|
||||
"fontSize": 16, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "SkillPack/skills/ 「真身, 唯一一份」",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "skills-list",
|
||||
"type": "text",
|
||||
"x": 415, "y": 218, "width": 490, "height": 60,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100022, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "├─ hello-world/ ├─ lark-im/ ├─ ai-products/\n├─ agent-browser/ ├─ pm-tracker/ ├─ research/\n└─ ... 「48 个 skill」",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "├─ hello-world/ ├─ lark-im/ ├─ ai-products/\n├─ agent-browser/ ├─ pm-tracker/ ├─ research/\n└─ ... 「48 个 skill」",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "docs-box",
|
||||
"type": "rectangle",
|
||||
"x": 400, "y": 305, "width": 250, "height": 80,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100030, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "docs-text",
|
||||
"type": "text",
|
||||
"x": 415, "y": 318, "width": 220, "height": 56,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100031, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "SkillPack/docs/\n流程·实现·共享文档",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "SkillPack/docs/\n流程·实现·共享文档",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "plugin-box",
|
||||
"type": "rectangle",
|
||||
"x": 670, "y": 305, "width": 250, "height": 80,
|
||||
"angle": 0,
|
||||
"strokeColor": "#f59e0b", "backgroundColor": "#fff3bf",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "dashed",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100040, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "plugin-text",
|
||||
"type": "text",
|
||||
"x": 685, "y": 318, "width": 220, "height": 56,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100041, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": ".obsidian/plugins/\nclaude-skill-sync 「symlink」",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": ".obsidian/plugins/\nclaude-skill-sync 「symlink」",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "vault-bottom-note",
|
||||
"type": "text",
|
||||
"x": 405, "y": 410, "width": 510, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100050, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Obsidian Sync · iCloud · Git · 坚果云 · Remotely Save",
|
||||
"fontSize": 13, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "Obsidian Sync · iCloud · Git · 坚果云 · Remotely Save",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "vault-bottom-note2",
|
||||
"type": "text",
|
||||
"x": 480, "y": 442, "width": 360, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100051, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "↑ vault 跨电脑同步任选其一",
|
||||
"fontSize": 13, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "↑ vault 跨电脑同步任选其一",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "tools-container",
|
||||
"type": "rectangle",
|
||||
"x": 990, "y": 90, "width": 380, "height": 400,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "#ffd8a8",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100060, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "tools-title",
|
||||
"type": "text",
|
||||
"x": 1095, "y": 105, "width": 170, "height": 28,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100061, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "AI Coding Tools",
|
||||
"fontSize": 20, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "AI Coding Tools",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "tools-sub",
|
||||
"type": "text",
|
||||
"x": 1060, "y": 138, "width": 240, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100062, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "本地各工具的 skills 目录",
|
||||
"fontSize": 13, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "本地各工具的 skills 目录",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "tool1-box",
|
||||
"type": "rectangle",
|
||||
"x": 1010, "y": 175, "width": 340, "height": 80,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100070, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "tool1-text",
|
||||
"type": "text",
|
||||
"x": 1025, "y": 188, "width": 310, "height": 56,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100071, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Claude Code\n~/.claude/skills/",
|
||||
"fontSize": 16, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Claude Code\n~/.claude/skills/",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "tool2-box",
|
||||
"type": "rectangle",
|
||||
"x": 1010, "y": 270, "width": 340, "height": 80,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100080, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "tool2-text",
|
||||
"type": "text",
|
||||
"x": 1025, "y": 283, "width": 310, "height": 56,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100081, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Codex / Agents\n~/.agents/skills/",
|
||||
"fontSize": 16, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Codex / Agents\n~/.agents/skills/",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "tool3-box",
|
||||
"type": "rectangle",
|
||||
"x": 1010, "y": 365, "width": 340, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "#ffffff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100090, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "tool3-text",
|
||||
"type": "text",
|
||||
"x": 1025, "y": 378, "width": 310, "height": 76,
|
||||
"angle": 0,
|
||||
"strokeColor": "#374151", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100091, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "Cursor / Gemini / Trae / ...\n~/.cursor/skills/\n~/.gemini/skills/ (18 个预设)",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "left", "verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Cursor / Gemini / Trae / ...\n~/.cursor/skills/\n~/.gemini/skills/ (18 个预设)",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "arrow-github-plugin",
|
||||
"type": "arrow",
|
||||
"x": 330, "y": 345, "width": 340, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#f59e0b", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "dashed",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100100, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [340, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "arrow-github-plugin-label",
|
||||
"type": "text",
|
||||
"x": 380, "y": 318, "width": 240, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#d97706", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100101, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "git clone + ln -s",
|
||||
"fontSize": 13, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "git clone + ln -s",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "arrow-skills-tool1",
|
||||
"type": "arrow",
|
||||
"x": 920, "y": 215, "width": 90, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100110, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [90, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "arrow-skills-tool2",
|
||||
"type": "arrow",
|
||||
"x": 920, "y": 230, "width": 90, "height": 80,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100111, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [90, 80]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "arrow-skills-tool3",
|
||||
"type": "arrow",
|
||||
"x": 920, "y": 245, "width": 90, "height": 175,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100112, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [90, 175]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "symlink-label",
|
||||
"type": "text",
|
||||
"x": 935, "y": 165, "width": 70, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100113, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "symlink",
|
||||
"fontSize": 13, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "symlink",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "flow-title",
|
||||
"type": "text",
|
||||
"x": 580, "y": 540, "width": 240, "height": 32,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100200, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "使用流程「6 步」",
|
||||
"fontSize": 24, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "使用流程「6 步」",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step1-box",
|
||||
"type": "rectangle",
|
||||
"x": 50, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#a5d8ff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100210, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step1-text",
|
||||
"type": "text",
|
||||
"x": 65, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100211, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "1. clone\n插件 GitHub repo\n到本地",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "1. clone\n插件 GitHub repo\n到本地",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step2-box",
|
||||
"type": "rectangle",
|
||||
"x": 280, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#a5d8ff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100220, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step2-text",
|
||||
"type": "text",
|
||||
"x": 295, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100221, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "2. 在 vault 建\nSkillPack/skills/\n目录",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "2. 在 vault 建\nSkillPack/skills/\n目录",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step3-box",
|
||||
"type": "rectangle",
|
||||
"x": 510, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#a5d8ff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100230, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step3-text",
|
||||
"type": "text",
|
||||
"x": 525, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100231, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "3. ln -s 插件\n到 .obsidian/\nplugins/",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "3. ln -s 插件\n到 .obsidian/\nplugins/",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step4-box",
|
||||
"type": "rectangle",
|
||||
"x": 740, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#a5d8ff",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100240, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step4-text",
|
||||
"type": "text",
|
||||
"x": 755, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100241, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "4. Obsidian\n启用插件\n「关安全模式」",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "4. Obsidian\n启用插件\n「关安全模式」",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step5-box",
|
||||
"type": "rectangle",
|
||||
"x": 970, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "#b2f2bb",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100250, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step5-text",
|
||||
"type": "text",
|
||||
"x": 985, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100251, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "5. 在 vault\n添加 / 编辑 skill\n「即时一致」",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "5. 在 vault\n添加 / 编辑 skill\n「即时一致」",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "step6-box",
|
||||
"type": "rectangle",
|
||||
"x": 1200, "y": 600, "width": 200, "height": 100,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "#b2f2bb",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 3}, "seed": 100260, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false
|
||||
},
|
||||
{
|
||||
"id": "step6-text",
|
||||
"type": "text",
|
||||
"x": 1215, "y": 615, "width": 170, "height": 70,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100261, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "6. 点「全部安装」\nAI 工具立即可用\n✓ 完成",
|
||||
"fontSize": 15, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "6. 点「全部安装」\nAI 工具立即可用\n✓ 完成",
|
||||
"autoResize": true, "lineHeight": 1.4
|
||||
},
|
||||
|
||||
{
|
||||
"id": "flow-arrow1",
|
||||
"type": "arrow",
|
||||
"x": 250, "y": 650, "width": 30, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100300, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [30, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "flow-arrow2",
|
||||
"type": "arrow",
|
||||
"x": 480, "y": 650, "width": 30, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100301, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [30, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "flow-arrow3",
|
||||
"type": "arrow",
|
||||
"x": 710, "y": 650, "width": 30, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100302, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [30, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "flow-arrow4",
|
||||
"type": "arrow",
|
||||
"x": 940, "y": 650, "width": 30, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100303, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [30, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "flow-arrow5",
|
||||
"type": "arrow",
|
||||
"x": 1170, "y": 650, "width": 30, "height": 0,
|
||||
"angle": 0,
|
||||
"strokeColor": "#15803d", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": {"type": 2}, "seed": 100304, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"points": [[0, 0], [30, 0]],
|
||||
"lastCommittedPoint": null, "startBinding": null, "endBinding": null,
|
||||
"startArrowhead": null, "endArrowhead": "arrow"
|
||||
},
|
||||
|
||||
{
|
||||
"id": "bottom-tagline",
|
||||
"type": "text",
|
||||
"x": 280, "y": 750, "width": 880, "height": 28,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1e40af", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100400, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "单一真身「vault」 · 多处替身「symlink」 · 跨电脑同步交给 vault 自身",
|
||||
"fontSize": 18, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "单一真身「vault」 · 多处替身「symlink」 · 跨电脑同步交给 vault 自身",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "bottom-tagline2",
|
||||
"type": "text",
|
||||
"x": 380, "y": 790, "width": 680, "height": 22,
|
||||
"angle": 0,
|
||||
"strokeColor": "#3b82f6", "backgroundColor": "transparent",
|
||||
"fillStyle": "solid", "strokeWidth": 2, "strokeStyle": "solid",
|
||||
"roughness": 1, "opacity": 100, "groupIds": [],
|
||||
"roundness": null, "seed": 100401, "version": 1,
|
||||
"isDeleted": false, "boundElements": null, "updated": 1, "link": null, "locked": false,
|
||||
"text": "任何位置编辑都即时一致 · 不复制内容 · 不占额外空间",
|
||||
"fontSize": 14, "fontFamily": 5,
|
||||
"textAlign": "center", "verticalAlign": "middle",
|
||||
"containerId": null,
|
||||
"originalText": "任何位置编辑都即时一致 · 不复制内容 · 不占额外空间",
|
||||
"autoResize": true, "lineHeight": 1.25
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
10
manifest.json
Normal file
10
manifest.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "claude-skill-sync",
|
||||
"name": "Claude Skill Sync",
|
||||
"version": "0.1.0",
|
||||
"minAppVersion": "1.4.0",
|
||||
"description": "Manage AI coding agent Skills (Claude Code, Codex, Cursor, Gemini, and 14+ more) from your Obsidian vault. One source, symlinked to each tool. Cross-machine sync via your existing vault sync.",
|
||||
"author": "Chocolae",
|
||||
"authorUrl": "https://github.com/2949984428",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
356
styles.css
Normal file
356
styles.css
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
.css-skill-sync {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.css-skill-sync .css-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.css-skill-sync .css-header h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.css-skill-sync .css-btn-row {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.css-skill-sync .css-btn-row button {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
}
|
||||
.css-skill-sync .css-meta {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.css-skill-sync .css-status-card {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
.css-skill-sync .css-status-loading {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
padding: 4px;
|
||||
}
|
||||
.css-skill-sync .css-status-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.css-skill-sync .css-status-title { font-weight: 600; }
|
||||
.css-skill-sync .css-status-overall {
|
||||
font-size: 10px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.css-skill-sync .css-status-overall.all-good {
|
||||
background: rgba(16, 185, 129, 0.15);
|
||||
color: #10b981;
|
||||
}
|
||||
.css-skill-sync .css-status-overall.has-issue {
|
||||
background: rgba(234, 179, 8, 0.15);
|
||||
color: #eab308;
|
||||
}
|
||||
.css-skill-sync .css-status-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
.css-skill-sync .css-status-cell {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
padding: 6px 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.css-skill-sync .css-status-cell.css-clickable {
|
||||
cursor: pointer;
|
||||
transition: background 0.1s;
|
||||
}
|
||||
.css-skill-sync .css-status-cell.css-clickable:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
.css-skill-sync .css-status-num {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.css-skill-sync .css-status-label {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.css-skill-sync .css-status-cell.css-good .css-status-num { color: #10b981; }
|
||||
.css-skill-sync .css-status-cell.css-warn .css-status-num { color: #eab308; }
|
||||
.css-skill-sync .css-status-cell.css-bad .css-status-num { color: #ef4444; }
|
||||
.css-skill-sync .css-status-cell.css-info .css-status-num { color: var(--text-normal); }
|
||||
.css-skill-sync .css-status-cell.css-mute .css-status-num { color: var(--text-muted); }
|
||||
.css-skill-sync .css-empty {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
padding: 12px;
|
||||
border: 1px dashed var(--background-modifier-border);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.css-skill-sync .css-search-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.css-skill-sync .css-search-input {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
background: var(--background-primary);
|
||||
}
|
||||
.css-skill-sync .css-search-count {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
white-space: nowrap;
|
||||
min-width: 30px;
|
||||
text-align: right;
|
||||
}
|
||||
.css-skill-sync .css-skill-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.css-skill-sync .css-skill {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 6px;
|
||||
padding: 8px 10px;
|
||||
margin-bottom: 6px;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
.css-skill-sync .css-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
user-select: none;
|
||||
}
|
||||
.css-skill-sync .css-toggle {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
width: 12px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
.css-skill-sync .css-name {
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
}
|
||||
.css-skill-sync .css-desc {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin: 6px 0 4px 16px;
|
||||
line-height: 1.4;
|
||||
padding-left: 6px;
|
||||
border-left: 2px solid var(--background-modifier-border);
|
||||
}
|
||||
.css-skill-sync .css-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.css-skill-sync .css-plat {
|
||||
flex: 1;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.css-skill-sync .css-badge {
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.css-skill-sync .css-linked { background: rgba(16, 185, 129, 0.15); color: #10b981; }
|
||||
.css-skill-sync .css-missing { background: rgba(255, 255, 255, 0.06); color: var(--text-muted); }
|
||||
.css-skill-sync .css-conflict { background: rgba(239, 68, 68, 0.15); color: #ef4444; }
|
||||
.css-skill-sync .css-mislinked { background: rgba(234, 179, 8, 0.15); color: #eab308; }
|
||||
.css-skill-sync .css-warn {
|
||||
font-size: 10px;
|
||||
color: var(--text-warning, #eab308);
|
||||
margin-left: 4px;
|
||||
}
|
||||
.css-skill-sync .css-row button {
|
||||
font-size: 10px;
|
||||
padding: 2px 8px;
|
||||
height: auto;
|
||||
}
|
||||
.css-platform-edit {
|
||||
border-left: 2px solid var(--background-modifier-border);
|
||||
padding-left: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.css-skill-sync-modal .css-import-hint {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin: 4px 0 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.css-skill-sync-modal .css-import-ctrl {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.css-skill-sync-modal .css-import-count {
|
||||
margin-left: auto;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.css-skill-sync-modal .css-import-list {
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 6px;
|
||||
padding: 4px;
|
||||
}
|
||||
.css-skill-sync-modal .css-import-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
padding: 6px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.css-skill-sync-modal .css-import-row:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
.css-skill-sync-modal .css-import-row label {
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
.css-skill-sync-modal .css-del-btn {
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
background: transparent;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
color: var(--text-muted);
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.css-skill-sync-modal .css-del-btn:hover {
|
||||
border-color: #ef4444;
|
||||
color: #ef4444;
|
||||
}
|
||||
.css-skill-sync-modal .css-del-btn.mod-warning {
|
||||
background: #ef4444;
|
||||
border-color: #ef4444;
|
||||
color: #fff;
|
||||
}
|
||||
.css-skill-sync-modal .css-source {
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
.css-skill-sync-modal .css-source-path {
|
||||
font-size: 10px;
|
||||
color: var(--text-faint);
|
||||
word-break: break-all;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.css-skill-sync-modal .css-empty {
|
||||
color: var(--text-muted);
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
.css-skill-sync-modal .css-custom-row {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.css-skill-sync-modal .css-custom-row input {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
background: var(--background-primary);
|
||||
}
|
||||
.css-skill-sync-modal .css-import-row input[type="checkbox"]:disabled + label {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* —— 添加平台 modal —— */
|
||||
.css-add-platform-modal .css-search-wrap {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-list {
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
.css-add-platform-modal .css-preset-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-row:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
.css-add-platform-modal .css-preset-row label {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-name {
|
||||
font-weight: 500;
|
||||
min-width: 110px;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-path {
|
||||
color: var(--text-muted);
|
||||
font-size: 11px;
|
||||
font-family: var(--font-monospace);
|
||||
flex: 1;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-tag {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
padding: 1px 6px;
|
||||
background: var(--background-modifier-border);
|
||||
border-radius: 3px;
|
||||
}
|
||||
.css-add-platform-modal .css-preset-exists {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.css-add-platform-modal .css-custom-toggle {
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
border: 1px dashed var(--background-modifier-border);
|
||||
color: var(--text-muted);
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.css-add-platform-modal .css-custom-toggle:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
color: var(--text-normal);
|
||||
}
|
||||
.css-add-platform-modal .css-custom-wrap {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
3
versions.json
Normal file
3
versions.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"0.1.0": "1.4.0"
|
||||
}
|
||||
Loading…
Reference in a new issue