autosnippet 1.3.0 → 1.3.2

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 (74) hide show
  1. package/.editorconfig +7 -1
  2. package/.env.example +124 -0
  3. package/README.md +128 -109
  4. package/bin/asnip.js +233 -25
  5. package/bin/findPath.js +48 -244
  6. package/bin/init.js +3 -3
  7. package/bin/openChrome.applescript +65 -0
  8. package/bin/ui.js +856 -448
  9. package/dashboard/index.html +0 -10
  10. package/dashboard/package-lock.json +4062 -3229
  11. package/dashboard/package.json +34 -26
  12. package/dashboard/postcss.config.js +5 -0
  13. package/dashboard/scripts/build.mjs +13 -0
  14. package/dashboard/src/App.tsx +679 -1018
  15. package/dashboard/src/components/Layout/Header.tsx +144 -0
  16. package/dashboard/src/components/Layout/Sidebar.tsx +38 -0
  17. package/dashboard/src/components/Modals/CreateModal.tsx +55 -0
  18. package/dashboard/src/components/Modals/RecipeEditor.tsx +145 -0
  19. package/dashboard/src/components/Modals/SearchModal.tsx +97 -0
  20. package/dashboard/src/components/Modals/SnippetEditor.tsx +146 -0
  21. package/dashboard/src/components/Shared/CategoryBar.tsx +35 -0
  22. package/dashboard/src/components/Shared/CodeBlock.tsx +52 -0
  23. package/dashboard/src/components/Shared/MarkdownWithHighlight.tsx +63 -0
  24. package/dashboard/src/components/Views/AiChatView.tsx +44 -0
  25. package/dashboard/src/components/Views/CandidatesView.tsx +116 -0
  26. package/dashboard/src/components/Views/DepGraphView.tsx +408 -0
  27. package/dashboard/src/components/Views/HelpView.tsx +51 -0
  28. package/dashboard/src/components/Views/RecipesView.tsx +49 -0
  29. package/dashboard/src/components/Views/SPMExplorerView.tsx +250 -0
  30. package/dashboard/src/components/Views/SnippetsView.tsx +54 -0
  31. package/dashboard/src/constants/index.ts +18 -0
  32. package/dashboard/src/index.css +10 -0
  33. package/dashboard/src/main.tsx +4 -3
  34. package/dashboard/src/types.ts +59 -57
  35. package/dashboard/src/utils/index.ts +13 -0
  36. package/dashboard/tailwind.config.js +11 -0
  37. package/dashboard/vite.config.ts +15 -0
  38. package/images/20260131014718_38_167.png +0 -0
  39. package/images/20260131014812_40_167.png +0 -0
  40. package/images/20260131014843_41_167.png +0 -0
  41. package/lib/ai/AiFactory.js +179 -23
  42. package/lib/ai/AiProvider.js +26 -18
  43. package/lib/ai/candidateService.js +75 -75
  44. package/lib/ai/headerResolution.js +61 -61
  45. package/lib/ai/providers/ClaudeProvider.js +163 -0
  46. package/lib/ai/providers/GoogleGeminiProvider.js +176 -150
  47. package/lib/ai/providers/MockProvider.js +57 -0
  48. package/lib/ai/providers/OpenAiProvider.js +185 -0
  49. package/lib/ai/vectorStore.js +85 -0
  50. package/lib/infra/FileFinder.js +111 -0
  51. package/lib/infra/paths.js +4 -2
  52. package/lib/infra/vectorMath.js +88 -0
  53. package/lib/injection/moduleResolver.js +1 -1
  54. package/lib/snippet/markerLine.js +17 -17
  55. package/lib/snippet/specRepository.js +5 -5
  56. package/lib/spm/spmDepMapUpdater.js +92 -9
  57. package/lib/spm/spmDepsService.js +29 -20
  58. package/lib/spm/swiftParserClient.js +310 -0
  59. package/lib/spm/targetScanner.js +95 -95
  60. package/lib/watch/fileWatcher.js +116 -1
  61. package/package.json +62 -59
  62. package/{skills → recipes}/README.md +4 -4
  63. package/scripts/ensure-parse-package.js +33 -0
  64. package/scripts/install-cursor-skill.js +115 -0
  65. package/skills/autosnippet-concepts/SKILL.md +52 -0
  66. package/skills/autosnippet-create/SKILL.md +89 -0
  67. package/skills/autosnippet-dep-graph/SKILL.md +61 -0
  68. package/skills/autosnippet-recipes/SKILL.md +90 -0
  69. package/test/README.md +78 -0
  70. package/test/runner.js +563 -0
  71. package/tools/parse-package/Package.resolved +14 -0
  72. package/tools/parse-package/Package.swift +25 -0
  73. package/tools/parse-package/README.md +31 -0
  74. package/tools/parse-package/Sources/ParsePackage/main.swift +277 -0
package/.editorconfig CHANGED
@@ -1,7 +1,13 @@
1
1
  root = true
2
2
 
3
- [*.js]
3
+ [*]
4
4
  indent_style = tab
5
5
  indent_size = 4
6
6
  tab_width = 4
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
7
13
 
package/.env.example ADDED
@@ -0,0 +1,124 @@
1
+ # AutoSnippet 环境变量配置文件示例
2
+ #
3
+ # 使用方式:
4
+ # 1. 将本文件复制到「项目根目录」(即 AutoSnippetRoot.boxspec.json 所在目录)
5
+ # 2. 重命名为 .env(注意没有 .example 后缀)
6
+ # 3. 根据下方说明填写 API Key 等配置
7
+ # 可从本仓库下载: https://github.com/GxFn/AutoSnippet/blob/main/.env.example
8
+ #
9
+ # 配置生效范围:asd ui、asd create、asd ais、asd watch 的 Guard、asd embed、asd search -m 等
10
+ # 会优先读取项目根目录下的 .env;未配置 API Key 时,上述依赖 AI 的功能会报错或提示。
11
+ #
12
+ # =============================================================================
13
+ # --- 1. AI 提供商配置 ---
14
+ # =============================================================================
15
+ # 必填其一:根据所选提供商填写对应的 API Key;Ollama 本地 AI 通常不需要 Key。
16
+
17
+ # 当前使用的 AI 提供商
18
+ # 可选值: google, openai, deepseek, claude, ollama, mock
19
+ # google - Google Gemini,需填写 ASD_GOOGLE_API_KEY
20
+ # openai - OpenAI(含兼容接口),需填写 ASD_OPENAI_API_KEY
21
+ # deepseek - DeepSeek,需填写 ASD_DEEPSEEK_API_KEY
22
+ # claude - Anthropic Claude,需填写 ASD_CLAUDE_API_KEY
23
+ # ollama - 本地 Ollama,默认 http://localhost:11434/v1,一般不需 Key
24
+ # mock - 模拟模式,用于测试,无真实请求
25
+ ASD_AI_PROVIDER=google
26
+
27
+ # 模型名称,根据上面 ASD_AI_PROVIDER 选择对应厂商的模型 ID
28
+ # 常用示例:
29
+ # google: gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash
30
+ # openai: gpt-4o, gpt-4-turbo, gpt-4o-mini
31
+ # deepseek: deepseek-chat, deepseek-coder
32
+ # claude: claude-3-5-sonnet-20240620, claude-3-opus-20240229
33
+ # ollama: 填写本机已安装的模型名,如 llama3, qwen2, mistral
34
+ ASD_AI_MODEL=gemini-2.0-flash
35
+
36
+ # 各提供商的 API Key(只填当前使用的提供商即可,其余可留空)
37
+ ASD_GOOGLE_API_KEY=
38
+ ASD_OPENAI_API_KEY=
39
+ ASD_DEEPSEEK_API_KEY=
40
+ ASD_CLAUDE_API_KEY=
41
+
42
+ # 自定义 API 地址(可选)
43
+ # 适用于:自建代理、国内镜像、或 Ollama 等本地服务不在默认端口时
44
+ # 未设置时使用各厂商官方默认地址
45
+ # ASD_OPENAI_BASE_URL=https://api.openai.com/v1
46
+ # ASD_DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
47
+ # ASD_CLAUDE_BASE_URL=https://api.anthropic.com/v1
48
+ # ASD_OLLAMA_BASE_URL=http://127.0.0.1:11434/v1
49
+
50
+ # =============================================================================
51
+ # --- 2. Dashboard 与构建配置 ---
52
+ # =============================================================================
53
+
54
+ # 是否在启动 asd ui 时强制重新构建前端(0=否,1=是)
55
+ # 设为 1 时,每次 asd ui 都会先执行 npm run build:dashboard,适合本地改完 dashboard 代码后预览
56
+ # 正常使用保持 0 即可
57
+ ASD_UI_BUILD=0
58
+ ASD_UI_REBUILD=0
59
+
60
+ # =============================================================================
61
+ # --- 3. 监听与文件系统配置 ---
62
+ # =============================================================================
63
+
64
+ # 是否使用轮询方式监听文件变化(true / false)
65
+ # 默认 false 使用系统原生 watch;若项目在 NFS、网络盘或部分虚拟机上监听不生效,可改为 true
66
+ ASD_WATCH_POLLING=false
67
+
68
+ # Xcode Code Snippets 的存储路径(留空则使用默认)
69
+ # 默认: ~/Library/Developer/Xcode/UserData/CodeSnippets
70
+ # asd install 会把 Snippet 同步到此目录,Xcode 从这里加载
71
+ ASD_SNIPPETS_PATH=
72
+
73
+ # AutoSnippet 缓存目录(留空则使用默认)
74
+ # 用于缓存索引、临时数据等,一般无需修改
75
+ ASD_CACHE_PATH=
76
+
77
+ # 当工具发现「当前 Target 缺少对某模块的依赖」时,是否自动在 Package.swift 里插入依赖
78
+ # 典型场景:头文件注入(as:include)时,若当前 Target 的 dependencies 里没有对应模块,可自动补上
79
+ # 插入内容包含:同包内 .target 依赖、跨包 .product 依赖、以及 Package 级的 .package(path/url)
80
+ #
81
+ # ASD_FIX_SPM_DEPS:设为 1 或 true 时,启用自动插入(等价于 MODE=fix)
82
+ # ASD_FIX_SPM_DEPS_MODE:更细粒度控制,可选:
83
+ # off - 不自动改 Package.swift,仅给出修改建议(默认)
84
+ # suggest - 同上,仅建议
85
+ # fix - 自动在 Package.swift 中插入缺失的 target/product/package 依赖
86
+ # 日常使用建议保持 off;确认需要自动补依赖时再改为 fix
87
+ ASD_FIX_SPM_DEPS=false
88
+ ASD_FIX_SPM_DEPS_MODE=
89
+
90
+ # Package.swift 解析:npm install 时会尝试构建 ParsePackage(swift-syntax);成功则默认用它,失败则用 dump-package,再失败用 AST-lite
91
+ # ASD_USE_DUMP_PACKAGE=1(默认)- ParsePackage 不可用时用系统 dump-package;=0 则跳过 dump-package,仅 AST-lite
92
+ # ASD_SWIFT_PARSER_BIN - 指定 ParsePackage 可执行文件路径;未设置时使用 npm install 构建的 tools/parse-package/.build/release/ParsePackage
93
+ # ASD_SWIFT_PARSER_DISABLE=1 - 强制禁用 ParsePackage,仅用 dump-package 或 AST-lite
94
+ # ASD_SWIFT_PARSER_TIMEOUT_MS - 解析超时毫秒数,默认 5000
95
+ # ASD_USE_DUMP_PACKAGE=1
96
+ # ASD_SWIFT_PARSER_BIN=
97
+ # ASD_SWIFT_PARSER_DISABLE=
98
+ # ASD_SWIFT_PARSER_TIMEOUT_MS=5000
99
+
100
+ # =============================================================================
101
+ # --- 4. 开发与测试配置 ---
102
+ # =============================================================================
103
+ # 以下多为自动化测试或脚本调用时使用,日常使用可忽略。
104
+
105
+ # 预置输入 JSON 路径,用于非交互式 create 等(自动化/CI)
106
+ ASD_PRESET=
107
+ ASD_TEST_PRESET=
108
+
109
+ # 测试运行器使用的「模拟项目根目录」,默认指向 ../AutoSnippetTestHome/BiliDiliForTest
110
+ ASD_TEST_HOME=
111
+
112
+ # AI 提取时指定的源码文件路径(脚本/自动化用)
113
+ ASD_ACODE_FILE=
114
+
115
+ # 增量测试时传入的变更文件列表,供 test/runner.js --changed 使用
116
+ ASD_TEST_CHANGED_FILES=
117
+
118
+ # =============================================================================
119
+ # --- 5. 网络代理(可选) ---
120
+ # =============================================================================
121
+ # 访问 Google / OpenAI 等 API 时走代理时设置;仅在有代理需求时取消注释并修改地址。
122
+
123
+ # https_proxy=http://127.0.0.1:7890
124
+ # http_proxy=http://127.0.0.1:7890
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  基于 SPM 的 iOS 模块 Snippet 与 AI 知识库工具。将模块使用示范写入 Xcode CodeSnippets,支持分类检索、头文件注入,以及基于 AI 的知识沉淀与可视化管理。
4
4
 
5
+ 开发者与 AI 生产的代码,通过人工评审之后沉淀为 Snippet + Recipe 知识库,开发者通过 Snippets 得到标准代码与依赖注入,AI 通过 Recipes 得到标准代码与项目上下文,项目被迅速解构,产出可视化交互的知识库。
6
+
5
7
  [![npm version](https://img.shields.io/npm/v/autosnippet.svg?style=flat-square)](https://www.npmjs.com/package/autosnippet)
6
8
  [![npm downloads](https://img.shields.io/npm/dm/autosnippet.svg?style=flat-square)](https://www.npmjs.com/package/autosnippet)
7
9
  [![License](https://img.shields.io/npm/l/autosnippet.svg?style=flat-square)](https://github.com/GxFn/AutoSnippet/blob/main/LICENSE)
@@ -14,19 +16,86 @@
14
16
  npm install -g autosnippet
15
17
  ```
16
18
 
19
+ ---
20
+
17
21
  ## 快速开始
18
22
 
19
- 在**项目根目录**执行(需能找到 `AutoSnippetRoot.boxspec.json`,没有会自己创建,关键是首次创建一定要在根目录):
23
+ **项目根目录**:即将在此目录创建 `AutoSnippetRoot.boxspec.json` 的目录(单仓库用仓库根即可)。后续 `asd ui`、编辑器内指令、命令行等均以此目录为基准。
24
+
25
+ 在**你的业务项目根目录**执行:
20
26
 
21
27
  ```bash
22
- # 一键初始化
28
+ # 1) 一键初始化(创建 AutoSnippetRoot.boxspec.json 等)
23
29
  asd setup
24
30
 
25
- # 启动 Web 管理后台
31
+ # 2) 启动 Web 管理后台(会同时启动 watch,编辑器内指令才会生效)
26
32
  asd ui
27
33
  ```
28
34
 
29
- 浏览器会自动打开 Dashboard,可在 **使用说明** 页查看完整说明。
35
+ **首次运行 `asd ui`** 时,若未检测到 Dashboard 前端,会自动在 AutoSnippet 安装目录执行构建(约 1–2 分钟)。浏览器会自动打开 Dashboard,可在 **使用说明** 页查看完整说明。
36
+
37
+ ### 界面预览
38
+
39
+ ![Dashboard 概览](images/20260131014718_38_167.png)
40
+
41
+ ![依赖关系 / 搜索](images/20260131014843_41_167.png)
42
+
43
+ ![Recipes / 候选](images/20260131014812_40_167.png)
44
+
45
+ ---
46
+
47
+ ## 新项目:AI 扫描 + 人工审核 → 知识库与依赖 → 与 Cursor/AI 形成闭环
48
+
49
+ 新项目在完成「快速开始」后,可按以下方式**用 AI 扫描 + 人工审核**快速组建知识库和依赖关系,再配合 Cursor 与其他 AI 形成闭环:
50
+
51
+ 1. **组建知识库**:在项目根执行 **`asd ais <Target>`** 或 **`asd ais --all`**,对 SPM Target 做批量 AI 扫描;结果进入 Dashboard 的 **Candidates** 页。在 Dashboard 中逐条审核,通过则入库为 Recipe(或 Snippet+Recipe),不需要的删除。反复几轮即可把现有代码中的「标准用法」沉淀到 `Knowledge/recipes/`。
52
+ 2. **组建依赖关系**:在项目根执行 **`asd spm-map`**(或 Dashboard 内刷新依赖关系图),生成 `Knowledge/AutoSnippet.spmmap.json`,供后续查阅「谁依赖谁」、模块边界。
53
+ 3. **可选:语义索引**:执行 **`asd embed`**,为 Recipes 构建语义向量索引,便于 **as:guard** 语义检索、**as:search** 与 Dashboard 内语义搜索。
54
+ 4. **配合 Cursor**:在项目根执行 **`asd install:cursor-skill`**,将 AutoSnippet 的 skills 安装到项目的 `.cursor/skills/`。Cursor Agent 即可获得「项目 Recipe 上下文」「依赖结构」「创建流程」等说明,按项目规范回答与改代码。
55
+ 5. **闭环**:日常开发中,用 Cursor 或其他 AI 基于知识库与依赖结构写代码;写完的模块使用代码通过 **`// as:create`** 或 Dashboard **New Recipe** 提交到 web、加入知识库;用 **`// as:guard`** 按知识库做合规审查;插入标准代码可通过 **`// as:search`** 从知识库检索并插入,或通过 Xcode 内 **Snippet 联想(补全)** 获取。知识库与依赖随人工审核和提交持续更新,AI 始终基于最新上下文,形成「扫描 → 审核 → 沉淀 → Cursor/AI 使用 → 再沉淀」的闭环。
56
+
57
+ ---
58
+
59
+ ## 编辑器内指令
60
+
61
+ 在源码中写入以下 **as:** 指令并**保存**,由 **watch** 或 **CLI** 解析执行。**需先运行 `asd watch` 或 `asd ui`**(`asd ui` 会在后台启动 watch),编辑器内指令才会在保存时生效。
62
+
63
+ | 指令 | 作用 | 触发时机 |
64
+ |------|------|----------|
65
+ | **`// as:create`** | 用剪贴板 + 当前文件路径创建 Recipe,打开 Dashboard | 保存文件后 watch 检测到 |
66
+ | **`// as:guard`** [关键字] | 按知识库(Recipes)用 AI 审查当前文件,结果输出终端 | 保存文件后 watch 检测到 |
67
+ | **`// as:search`** [关键词] | 从知识库检索 Recipe/Snippet 并插入 | 保存后 watch 检测到 |
68
+ | **`// as:include`** &lt;Module/Header.h&gt; [path] | Snippet 体内的头文件标记,watch 在文件头部注入 `#import` | 保存文件后 watch 检测到 |
69
+ | **`// as:import`** ModuleName | Snippet 体内的 Swift 模块导入标记,watch 注入 `import` | 保存文件后 watch 检测到 |
70
+
71
+ ### // as:create
72
+
73
+ 在源码中写一行 **`// as:create`**,把要沉淀的代码**复制到剪贴板**,保存文件。watch 检测到后会**打开 Dashboard** 并带当前文件路径;若剪贴板有内容,会走「Use Copied Code」流程并自动解析头文件。适合:在编辑器里写完模块使用代码后,直接提交到 web、加入知识库。
74
+
75
+ ### // as:guard
76
+
77
+ 在源码中写 **`// as:guard`** 或 **`// as:guard 关键字`**,保存文件。watch 会按 **知识库(Recipes)** 用 AI 审查当前文件是否符合项目规范,**结果输出到终端**。若已执行 `asd embed`,会优先用语义检索选取相关 Recipe。
78
+
79
+ ### // as:search
80
+
81
+ 在源码中写 **`// as:search`** 或 **`// as:search 关键词`**,保存文件。watch 检测到后会**打开 Dashboard**,展示从知识库(Recipes)中按关键词检索到的候选;不写关键词则展示全部。在列表中点选一条 Recipe 并点击「插入」,该 Recipe 的代码块会**替换当前行**(即 `// as:search` 所在行)并写回文件,实现「选即插」。插入标准代码也可在 Xcode 中通过 **Snippet 联想(trigger 补全)** 直接选用已同步的 Snippet。
82
+
83
+ ### // as:include 与 // as:import(头文件/模块标记)
84
+
85
+ 用于 **Snippet 体内**(写入 `.codesnippet` 的 body),表示插入该 Snippet 时需要的头文件/模块;**watch** 在用户保存文件时,会在**文件头部**自动注入对应的 `#import` 或 `import`。
86
+
87
+ - **ObjC 头文件**:`// as:include <ModuleName/Header.h> [相对路径]`
88
+ - **Swift**:`// as:import ModuleName`
89
+
90
+ 保存时可勾选「引入头文件」,会写入上述标记;在项目根运行 `asd watch`(或 `asd ui`)后,在 Xcode 中选中 Snippet 的 headerVersion 并保存,即可在文件头部注入依赖。
91
+
92
+ ---
93
+
94
+ ## 术语
95
+
96
+ - **Snippet**:写入 Xcode 的代码片段,通过 trigger(补全键)或库面板使用。
97
+ - **Recipe(配方)**:存放在 `Knowledge/recipes/` 下的 Markdown 知识,供 AI 检索、Guard 审查与搜索。
98
+ - **项目根**:含 `AutoSnippetRoot.boxspec.json` 的目录。
30
99
 
31
100
  ---
32
101
 
@@ -37,143 +106,103 @@ asd ui
37
106
  | 提供商 | 默认模型 | 说明 |
38
107
  |--------|----------|------|
39
108
  | **Google Gemini** | `gemini-2.0-flash` | 用于 Snippet 提取、摘要、RAG 问答等 |
40
-
41
- 当前仅支持 **Google Gemini**。`asd create`、`asd ais`、Dashboard 的「按路径/剪贴板创建」与 AI Assistant 均使用该模型。
109
+ | **OpenAI** | `gpt-4o` | 支持 OpenAI 标准接口 |
110
+ | **DeepSeek** | `deepseek-chat` | 深度求索系列模型 |
111
+ | **Anthropic Claude** | `claude-3-5-sonnet-20240620` | 支持 Claude 系列模型 |
112
+ | **Ollama** | `llama3` | **本地 AI 支持**,默认地址 `http://localhost:11434/v1` |
42
113
 
43
114
  ### 配置指南
44
115
 
45
116
  **1. 必填:API Key**
46
117
 
47
- [Google AI Studio](https://aistudio.google.com/) 申请 API Key,然后通过环境变量传入(勿写入仓库):
118
+ 在**项目根目录**创建 `.env` 文件(可复制 `.env.example`),或通过环境变量传入 API Key
48
119
 
49
120
  ```bash
50
- export ASD_GOOGLE_API_KEY="你的 API Key"
121
+ export ASD_GOOGLE_API_KEY="你的 API Key" # 或 ASD_OPENAI_API_KEY、ASD_DEEPSEEK_API_KEY、ASD_CLAUDE_API_KEY
51
122
  ```
52
123
 
53
- 或在项目根目录创建 `.env` 文件(已加入 `.gitignore`,勿提交):
124
+ 在项目根执行 `asd ai-test` 可验证当前配置是否可用。未配置时,依赖 AI 的功能会报错或提示。
54
125
 
55
- ```bash
56
- # .env
57
- ASD_GOOGLE_API_KEY=你的API_Key
58
- ```
126
+ **2. 可选**:`ASD_AI_PROVIDER`、`ASD_AI_MODEL`、各提供商 `_BASE_URL` 等,见项目内 `.env.example`。
59
127
 
60
- **2. 可选:模型与提供商**
128
+ **3. 可选:代理**:设置 `https_proxy` / `http_proxy` 访问外网 API。国内直连 Google/OpenAI 易失败,建议在 `.env` 中配置代理(如 `https_proxy=http://127.0.0.1:7890`)或改用国内可用的 `ASD_AI_PROVIDER=deepseek` 等。
61
129
 
62
- | 环境变量 | 说明 | 默认值 |
63
- |----------|------|--------|
64
- | `ASD_GOOGLE_API_KEY` | Google Gemini API Key(必填) | — |
65
- | `ASD_AI_PROVIDER` | 提供商,目前仅 `google` | `google` |
66
- | `ASD_AI_MODEL` | 模型名 | `gemini-2.0-flash` |
130
+ **4. 若出现 `TypeError: fetch failed`**:多为网络/代理问题。请确认:① 在**项目根**(含 `AutoSnippetRoot.boxspec.json` 和 `.env`)执行 `asd ui`,确保 `.env` 被加载;② 国内使用 Google 时在 `.env` 中设置 `https_proxy` 与 `http_proxy`,并保证代理进程可用;③ 或改用 DeepSeek/OpenAI 等,在 `.env` 中设置 `ASD_AI_PROVIDER=deepseek` 并配置 `ASD_DEEPSEEK_API_KEY`。
67
131
 
68
- 示例:使用 Pro 模型
132
+ **5. 切换 DeepSeek 后报「API Key is missing for provider: deepseek」**:说明当前已使用 deepseek(可能来自 boxspec 的 `ai.provider` 或 `.env` 的 `ASD_AI_PROVIDER`),但**项目根** `.env` 里未配置 Key。请在**项目根**(即运行 `asd ui` 的目录)的 `.env` 中增加一行:`ASD_DEEPSEEK_API_KEY=你的DeepSeek密钥`,保存后重启 `asd ui`。Key 仅从项目根 `.env` 读取,不会用 AutoSnippet 安装目录下的 `.env`。
69
133
 
70
- ```bash
71
- export ASD_AI_MODEL="gemini-1.5-pro"
72
- ```
134
+ ---
135
+
136
+ ## Cursor 集成
73
137
 
74
- **3. 可选:代理**
138
+ 若使用 [Cursor](https://cursor.com) 编辑项目,可将 AutoSnippet 自带的 skills 安装到**当前项目**的 Cursor 环境(项目根 `.cursor/skills/`),让 Agent 识别 Recipe、知识库与创建流程。
75
139
 
76
- 若需走代理访问 Google API,可设置:
140
+ 在**项目根目录**执行:
77
141
 
78
142
  ```bash
79
- export https_proxy="http://127.0.0.1:7890"
80
- # 或
81
- export http_proxy="http://127.0.0.1:7890"
143
+ asd install:cursor-skill
82
144
  ```
83
145
 
146
+ 或 `npm run install:cursor-skill`(在 AutoSnippet 安装目录)。安装后重启 Cursor 或新开 Agent 对话即可生效。升级 AutoSnippet 后重新执行可更新 skill 内容。
147
+
84
148
  ---
85
149
 
86
150
  ## Web Dashboard(asd ui)
87
151
 
88
- 启动后访问 `http://localhost:3000`,主要能力:
152
+ 启动后访问 `http://localhost:3000`。**若已运行 `asd ui`,watch 会在后台启动,编辑器内指令(as:create、as:guard、头文件注入等)在保存时生效。**
153
+
154
+ - **macOS**:再次运行 `asd ui` 会复用已有 `localhost:3000` 标签并聚焦(Chromium 系浏览器)。
89
155
 
90
156
  | 页面 | 说明 |
91
157
  |------|------|
92
158
  | **Snippets** | 查看、编辑、删除代码片段;同步到 Xcode |
93
- | **Knowledge Base** | 管理 Markdown 技术文档(Skills),与 Snippet 关联 |
94
- | **SPM Explorer** | 按 Target 扫描源码,AI 提取候选;从路径/剪贴板创建知识 |
159
+ | **Recipes** | 管理配方(Recipes)文档,与 Snippet 关联 |
160
+ | **SPM Explorer** | 按 Target 扫描源码,AI 提取候选;从路径/剪贴板创建 Recipe |
95
161
  | **Candidates** | 审核 CLI 批量扫描(`asd ais`)产生的候选,入库或忽略 |
96
- | **AI Assistant** | 基于本地 Snippets/Skills RAG 问答 |
97
- | **使用说明** | 本说明的 Web 版,随 Dashboard 常驻 |
98
-
99
- ### 新建知识(与 CLI 对齐)
162
+ | **依赖关系图** | 展示 SPM 包依赖(packages + edges) |
163
+ | **AI Assistant** | 基于本地 Snippets/Recipes RAG 问答 |
164
+ | **使用说明** | 本说明的 Web 版 |
100
165
 
101
- - **按路径**:输入相对路径(如 `Sources/MyMod/Foo.m`)→ 扫描文件,AI 提取标题/摘要/触发键/头文件,审核后保存。
102
- - **按剪贴板**:复制代码后点击「Use Copied Code」→ AI 分析并填充;若由 `// as:create` 打开会带当前文件路径,自动解析头文件。
166
+ ### 新建 Recipe
103
167
 
104
- ### 头文件与标记
105
-
106
- 保存时可勾选「引入头文件」。会写入 `// as:include <TargetName/Header.h> path` 等标记,配合 `asd watch` 在编辑时自动注入 `#import`。
168
+ - **按路径**:输入相对路径(如 `Sources/MyMod/Foo.m`)→ **Scan File** → AI 提取标题/摘要/触发键/头文件,审核后保存到 `Knowledge/recipes/`。
169
+ - **按剪贴板**:复制代码后点击 **Use Copied Code** → AI 分析并填充;若由 `// as:create` 打开会带当前文件路径,自动解析头文件。
107
170
 
108
171
  ---
109
172
 
110
173
  ## 命令行
111
174
 
112
- ### 常用
175
+ 以下命令均在**项目根目录**执行。**编辑器内指令**已在上文优先说明;此处为 CLI 能力速查与补充。
176
+
177
+ ### 常用命令
113
178
 
114
179
  | 命令 | 说明 |
115
180
  |------|------|
116
- | `asd ui` | 启动 Web Dashboard |
117
- | `asd create` | 从带 `// as:code` 的文件用 **AI** 提取并创建 Snippet(默认 AI 模式) |
118
- | `asd create --clipboard` | 从剪贴板用 **AI** 创建;可选 `--path 相对路径` 解析头文件 |
119
- | `asd create --no-ai` | 关闭 AI,使用传统交互/预置输入 |
181
+ | `asd ui` | 启动 Web Dashboard(并后台启动 watch,使编辑器内指令生效) |
182
+ | `asd watch` / `asd w` | 仅启动 watch,不打开浏览器;用于头文件注入、`// as:create`、`// as:guard` |
183
+ | `asd create --clipboard` | 从剪贴板用 AI 创建 Snippet;可选 `--path`、`--lang` |
184
+ | `asd create` | 从带 `// as:code` 的文件用 AI 提取并创建 Snippet |
120
185
  | `asd install` / `asd i` | 将 Snippets 同步到 Xcode |
121
- | `asd ais [Target]` | AI 扫描 SPM Target,结果进 Candidates,在 Dashboard 审核 |
122
- | `asd watch` / `asd w` | 监听源码,执行头文件注入、ALink、`// as:create` |
186
+ | `asd ais [Target]` / `asd ais --all` | AI 扫描 SPM Target,结果进 Candidates,在 Dashboard 审核 |
187
+ | `asd search [keyword]` | 关键词搜索 Snippets Recipes;加 `-m` 为语义搜索(需先 `asd embed`) |
188
+ | `asd embed` | 重建语义索引;语义搜索与 Guard 语义检索依赖此命令 |
189
+ | `asd install:cursor-skill` | 将 AutoSnippet skills 安装到项目 `.cursor/skills/` |
123
190
 
124
- ### create 详解
191
+ ### create 补充
125
192
 
126
- **AI 模式(默认,与 Web 一致):**
193
+ - **剪贴板**:`asd create --clipboard`,可选 `asd create --clipboard --path Sources/MyMod/Foo.m`、`--lang swift`。
194
+ - **从文件**:源码中用 `// as:code` 包裹要提炼的片段,再执行 `asd create` 并选择该文件。
195
+ - **传统模式**:`asd create --no-ai`、`asd --preset preset.json create`。
127
196
 
128
- ```bash
129
- # 从文件:选中含 // as:code 的文件,AI 分析代码并带头文件
130
- asd create
131
-
132
- # 从剪贴板
133
- asd create --clipboard
134
- asd create -p --path Sources/MyMod/Foo.m # 带头文件解析
135
- asd create --clipboard --lang swift
136
- ```
197
+ ### 其他命令
137
198
 
138
- **传统模式(预置或交互):**
139
-
140
- ```bash
141
- asd create --no-ai
142
- asd --preset preset.json create
143
- ```
144
-
145
- **文件内标记:**
146
-
147
- ```text
148
- // as:code
149
- UIView *view = [[UIView alloc] init];
150
- // as:code
151
- ```
152
-
153
- ### ai-scan(Candidates)
154
-
155
- ```bash
156
- asd ais <TargetName> # 扫描单个 Target
157
- asd ais --all # 扫描全部
158
- asd ais --batch 5 # 每批 5 个未扫描的 Target
159
- ```
160
-
161
- 结果写入 `Knowledge/.autosnippet/candidates.json`,在 Dashboard **Candidates** 页审核后入库或删除。
162
-
163
- ### watch 监听
164
-
165
- - **头文件注入**:在 Xcode 中选中 Snippet 的 headerVersion,保存后自动在文件头部插入对应 `#import`。
166
- - **ALink**:输入 `#模块键#ALink` 并保存,可打开配置的链接或 README。
167
- - **// as:create**:在源码中写一行 `// as:create`,复制要提炼的代码到剪贴板并保存;watch 会打开 Dashboard 并带当前文件路径,用剪贴板 + 路径创建(自动解析头文件)。
168
-
169
- ### 标记格式
170
-
171
- - ObjC 头文件:`// as:include <ModuleName/Header.h> [相对路径]`
172
- - Swift:`// as:import ModuleName`
173
-
174
- ---
199
+ - `asd setup`:等价于 init + root,推荐在单仓库根执行一次。
200
+ - `asd root`:在当前目录创建/更新项目根标记(`AutoSnippetRoot.boxspec.json`)。
201
+ - `asd init`:在 SPM 模块目录创建模块工作空间。
202
+ - `asd share`:共享本地 Snippet。
203
+ - `asd u <word> [key] [value]`:按 trigger 更新 Snippet 字段。
175
204
 
176
- ## 全局选项
205
+ ### 全局选项
177
206
 
178
207
  - `--preset <path>`:预置输入 JSON(非交互/自动化)。
179
208
  - `--yes`:非交互;缺必要输入则报错退出。
@@ -181,19 +210,9 @@ asd ais --batch 5 # 每批 5 个未扫描的 Target
181
210
 
182
211
  ---
183
212
 
184
- ## 其他命令
185
-
186
- - `asd root`:在项目根创建/更新工作空间,聚合子模块 Snippet。
187
- - `asd init`:在 SPM 模块目录创建模块工作空间。
188
- - `asd setup`:等价于 `init` + `root`。
189
- - `asd share`:共享本地 Snippet。
190
- - `asd u <word> [key] [value]`:按 trigger 更新 Snippet 字段。
191
-
192
- ---
193
-
194
- ## 占位符
213
+ ## install 之后
195
214
 
196
- Snippet 代码中使用 `<#placeholder#>`,Xcode 会识别为占位符,用 Tab 切换。多相同占位符可用 ⌥⌘E 连续选择后统一修改。
215
+ 执行 `asd install` 后,Snippets 会同步到 Xcode 的 **Code Snippets** 库。在 Xcode 中通过触发词(completion)或库面板使用;若未生效可尝试重启 Xcode。Snippet 代码中可使用 `<#placeholder#>`,Xcode 会识别为占位符,用 Tab 切换。
197
216
 
198
217
  ---
199
218
 
@@ -203,4 +222,4 @@ asd ais --batch 5 # 每批 5 个未扫描的 Target
203
222
 
204
223
  ## 许可证
205
224
 
206
- MIT,见 [LICENSE](LICENSE)
225
+ MIT,见 [LICENSE](LICENSE).