autosnippet 1.4.7 → 1.5.0

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.
package/README.md CHANGED
@@ -39,7 +39,7 @@ asd ui # 启动 Dashboard(建议常驻)
39
39
 
40
40
  1. **组建知识库**:`asd ais <Target>` 或 `asd ais --all` → Dashboard Candidates 审核 → Recipe 入库
41
41
  2. **依赖关系**:`asd spm-map` 或 Dashboard 刷新
42
- 3. **Cursor 集成**:`asd install:cursor-skill --mcp`(安装 Skills + MCP,需 `asd ui` 运行)
42
+ 3. **Cursor 集成**:`asd install:cursor-skill --mcp`(安装 Skills + Cursor 规则 `.cursor/rules/` + MCP,需 `asd ui` 运行)
43
43
  4. **语义索引**:`asd ui` 启动时自动 embed;也可手动 `asd embed`
44
44
 
45
45
  ### 闭环
@@ -76,11 +76,17 @@ asd ui # 启动 Dashboard(建议常驻)
76
76
  | `asd ais [Target]` | AI 扫描 Target → Candidates |
77
77
  | `asd search [keyword] --copy` | 搜索并复制第一条到剪贴板 |
78
78
  | `asd search [keyword] --pick` | 交互选择后复制/插入 |
79
- | `asd install:cursor-skill --mcp` | 安装 Skills 并配置 MCP(需 `asd ui` 运行) |
79
+ | `asd install:cursor-skill --mcp` | 安装 Skills、Cursor 规则(`.cursor/rules/*.mdc`)并配置 MCP(需 `asd ui` 运行) |
80
80
  | `asd install:full` | 全量安装;`--parser` 含 Swift 解析器;`--lancedb` 仅 LanceDB |
81
81
  | `asd embed` | 手动构建语义向量索引(`asd ui` 启动时也会自动执行) |
82
82
  | `asd spm-map` | 刷新 SPM 依赖映射(依赖关系图数据来源) |
83
83
 
84
+ ### 用 Cursor 做批量扫描
85
+
86
+ 除 `asd ais [Target]`(项目内 AI)外,可用 **Cursor 作为批量扫描工具**:在 Cursor 里让 Agent 通过 **MCP 工具**(`autosnippet_get_targets` → `autosnippet_get_target_files` → 按文件提取 → `autosnippet_submit_candidates`)扫描指定 Target,用 Cursor 模型提取候选并提交到 Dashboard,再到 **Candidates** 页审核入库。
87
+
88
+ 简单一句:「扫描 BDNetwork ,生产 Recipes 到候选」。AutoSnippet 将所有能力都通过语义交给 Cursor 了。
89
+
84
90
  ## 全量安装与可选依赖
85
91
 
86
92
  克隆或需完整能力时,**任意目录**执行:
@@ -93,19 +99,30 @@ asd install:full --lancedb # 仅安装 LanceDB(向量检索更快)
93
99
 
94
100
  **Swift 解析器**:默认回退 `dump-package`;`--parser` 构建 ParsePackage 后 SPM 解析更准确,需本机已装 Swift。
95
101
 
102
+ ### Postinstall 脚本说明(npm install 时)
103
+
104
+ `npm install` 会执行以下**可选**脚本,均为本包内本地构建,**不访问网络、不执行动态代码**:
105
+
106
+ | 脚本 | 作用 |
107
+ |------|------|
108
+ | `scripts/ensure-parse-package.js` | 仅当 `ASD_BUILD_SWIFT_PARSER=1` 时构建 Swift 解析器并打印「正在安装…」;否则打印跳过说明并退出。 |
109
+ | `scripts/build-native-ui.js` | 仅在 macOS 上用本机 Swift 编译 `resources/native-ui/main.swift` → `resources/native-ui/native-ui`;失败则静默跳过。 |
110
+
111
+ 未安装或跳过不影响核心功能。详见 [npm lifecycle scripts](https://docs.npmjs.com/cli/v10/using-npm/scripts#life-cycle-scripts)。
112
+
96
113
  ## 配置
97
114
 
98
115
  - **AI**:项目根 `.env`,设置 `ASD_GOOGLE_API_KEY` 等(见 `.env.example`)。可选 `ASD_AI_PROVIDER`、代理等。
99
116
  - **LanceDB**:`asd install:full --lancedb`,在 boxspec 的 `context.storage.adapter` 中配置 `"lance"`。
100
- - **Native UI**(可选):macOS 上 `npm install` 会尝试构建 `bin/native-ui`(需本机 Swift);未构建时回退到 AppleScript/inquirer,功能正常。
117
+ - **Native UI**(可选):macOS 上 `npm install` 会尝试构建 `resources/native-ui/native-ui`(需本机 Swift);未构建时回退到 AppleScript/inquirer,功能正常。
101
118
 
102
119
  ## Recipe 格式
103
120
 
104
121
  完整 Recipe 为 Markdown 文件,需包含:
105
122
 
106
123
  - **Frontmatter**(`---` 包裹的 YAML):`title`、`trigger` 必填;可选 `category`、`language`、`headers` 等
107
- - **## Snippet / Code Reference**:下接代码块,供 Snippet 与检索使用
108
- - **## AI Context / Usage Guide**:使用说明,供 AI 与 Guard 检索
124
+ - **Snippet / Code Reference**:下接代码块,供 Snippet 与检索使用
125
+ - **AI Context / Usage Guide**:使用说明,供 AI 与 Guard 检索
109
126
 
110
127
  ## 术语
111
128
 
@@ -114,7 +131,6 @@ asd install:full --lancedb # 仅安装 LanceDB(向量检索更快)
114
131
  - **项目根**:含 `AutoSnippetRoot.boxspec.json` 的目录
115
132
 
116
133
  **详细介绍**:启动 `asd ui` 后访问 Dashboard → **使用说明** 页;或参阅 [使用文档](docs/使用文档.md)(含 Skills 一览、AI 配置、闭环详解等)。
117
- **发布流程**:CI 与 npm 发布见 [发布流程](docs/发布流程.md)(打 tag `v*` 触发自动发布)。
118
134
 
119
135
  ---
120
136
 
package/bin/ui.js CHANGED
@@ -787,10 +787,20 @@ function launch(projectRoot, port = 3000, options = {}) {
787
787
  }
788
788
  });
789
789
 
790
- // API: 获取 Target 将要扫描的文件列表(不调用 AI)
790
+ // API: 获取 Target 将要扫描的文件列表(不调用 AI)。支持 body.target 或 body.targetName(按名称查 target
791
791
  app.post('/api/spm/target-files', async (req, res) => {
792
792
  try {
793
- const { target } = req.body;
793
+ let target = req.body?.target;
794
+ if (!target && req.body?.targetName) {
795
+ const targets = await targetScanner.listAllTargets(projectRoot);
796
+ target = targets.find(t => t.name === req.body.targetName);
797
+ if (!target) {
798
+ return res.status(404).json({ error: `未找到 Target: ${req.body.targetName}` });
799
+ }
800
+ }
801
+ if (!target) {
802
+ return res.status(400).json({ error: '需要 body.target 或 body.targetName' });
803
+ }
794
804
  const files = await targetScanner.getTargetFilesContent(target);
795
805
  const scannedFiles = files.map(f => ({
796
806
  name: f.name,
@@ -842,6 +852,23 @@ function launch(projectRoot, port = 3000, options = {}) {
842
852
  }
843
853
  });
844
854
 
855
+ // API: 追加候选(供 Cursor/MCP 批量扫描:Cursor AI 提取后提交,无需项目内 AI)
856
+ app.post('/api/candidates/append', async (req, res) => {
857
+ try {
858
+ const { targetName, items, source, expiresInHours } = req.body;
859
+ if (!targetName || !Array.isArray(items) || items.length === 0) {
860
+ return res.status(400).json({ error: '需要 targetName 与 items(数组,至少一条)' });
861
+ }
862
+ const safeSource = (source && typeof source === 'string') ? source : 'cursor-scan';
863
+ const hours = typeof expiresInHours === 'number' ? expiresInHours : 24;
864
+ await candidateService.appendCandidates(projectRoot, String(targetName), items, safeSource, hours);
865
+ res.json({ ok: true, count: items.length, targetName: String(targetName) });
866
+ } catch (err) {
867
+ console.error(`[API Error]`, err);
868
+ res.status(500).json({ error: err.message });
869
+ }
870
+ });
871
+
845
872
  // API: 删除候选内容
846
873
  app.post('/api/candidates/delete', async (req, res) => {
847
874
  try {