autosnippet 1.4.8 → 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 +12 -7
- package/bin/ui.js +29 -2
- package/dashboard/dist/assets/{index-CdoJx4Qh.js → index-4u3vg5wW.js} +11 -11
- package/dashboard/dist/index.html +1 -1
- package/lib/infra/nativeUi.js +1 -1
- package/lib/infra/openBrowser.js +1 -1
- package/package.json +5 -3
- package/resources/native-ui/README.md +29 -0
- package/resources/native-ui/main.swift +433 -0
- package/scripts/build-native-ui.js +2 -2
- package/scripts/cursor-rules/autosnippet-conventions.mdc +23 -0
- package/scripts/install-cursor-skill.js +21 -2
- package/scripts/mcp-server.js +96 -12
- package/skills/autosnippet-batch-scan/SKILL.md +53 -0
- package/skills/autosnippet-when/SKILL.md +3 -1
- /package/{bin → resources}/openChrome.applescript +0 -0
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
|
|
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
|
克隆或需完整能力时,**任意目录**执行:
|
|
@@ -100,7 +106,7 @@ asd install:full --lancedb # 仅安装 LanceDB(向量检索更快)
|
|
|
100
106
|
| 脚本 | 作用 |
|
|
101
107
|
|------|------|
|
|
102
108
|
| `scripts/ensure-parse-package.js` | 仅当 `ASD_BUILD_SWIFT_PARSER=1` 时构建 Swift 解析器并打印「正在安装…」;否则打印跳过说明并退出。 |
|
|
103
|
-
| `scripts/build-native-ui.js` | 仅在 macOS 上用本机 Swift 编译 `
|
|
109
|
+
| `scripts/build-native-ui.js` | 仅在 macOS 上用本机 Swift 编译 `resources/native-ui/main.swift` → `resources/native-ui/native-ui`;失败则静默跳过。 |
|
|
104
110
|
|
|
105
111
|
未安装或跳过不影响核心功能。详见 [npm lifecycle scripts](https://docs.npmjs.com/cli/v10/using-npm/scripts#life-cycle-scripts)。
|
|
106
112
|
|
|
@@ -108,15 +114,15 @@ asd install:full --lancedb # 仅安装 LanceDB(向量检索更快)
|
|
|
108
114
|
|
|
109
115
|
- **AI**:项目根 `.env`,设置 `ASD_GOOGLE_API_KEY` 等(见 `.env.example`)。可选 `ASD_AI_PROVIDER`、代理等。
|
|
110
116
|
- **LanceDB**:`asd install:full --lancedb`,在 boxspec 的 `context.storage.adapter` 中配置 `"lance"`。
|
|
111
|
-
- **Native UI**(可选):macOS 上 `npm install` 会尝试构建 `
|
|
117
|
+
- **Native UI**(可选):macOS 上 `npm install` 会尝试构建 `resources/native-ui/native-ui`(需本机 Swift);未构建时回退到 AppleScript/inquirer,功能正常。
|
|
112
118
|
|
|
113
119
|
## Recipe 格式
|
|
114
120
|
|
|
115
121
|
完整 Recipe 为 Markdown 文件,需包含:
|
|
116
122
|
|
|
117
123
|
- **Frontmatter**(`---` 包裹的 YAML):`title`、`trigger` 必填;可选 `category`、`language`、`headers` 等
|
|
118
|
-
-
|
|
119
|
-
-
|
|
124
|
+
- **Snippet / Code Reference**:下接代码块,供 Snippet 与检索使用
|
|
125
|
+
- **AI Context / Usage Guide**:使用说明,供 AI 与 Guard 检索
|
|
120
126
|
|
|
121
127
|
## 术语
|
|
122
128
|
|
|
@@ -125,7 +131,6 @@ asd install:full --lancedb # 仅安装 LanceDB(向量检索更快)
|
|
|
125
131
|
- **项目根**:含 `AutoSnippetRoot.boxspec.json` 的目录
|
|
126
132
|
|
|
127
133
|
**详细介绍**:启动 `asd ui` 后访问 Dashboard → **使用说明** 页;或参阅 [使用文档](docs/使用文档.md)(含 Skills 一览、AI 配置、闭环详解等)。
|
|
128
|
-
**发布流程**:CI 与 npm 发布见 [发布流程](docs/发布流程.md)(打 tag `v*` 触发自动发布)。
|
|
129
134
|
|
|
130
135
|
---
|
|
131
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
|
-
|
|
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 {
|