pi-resource-search 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -1,33 +1,61 @@
1
1
  # pi-resource-search
2
2
 
3
- Pi 扩展:在输入 `/关键词` 时搜索当前可用的命令、Skill、Extension 和已配置 Package。
3
+ Pi `/` 补全更容易找到资源。
4
4
 
5
- ## 使用
5
+ 输入 `/关键词` 后,扩展会按名称、描述和资源类型进行模糊匹配,列出当前 Pi 已发现的相关命令、Skill、扩展和已配置包。
6
6
 
7
- 安装或通过本地路径加载后,执行 `/reload`,在输入框中输入:
7
+ ## 示例
8
8
 
9
- - `/hand`:查找 handoff 等相关资源
9
+ - `/hand`:查找 `handoff` 等相关资源
10
10
  - `/cache`:查找缓存相关资源
11
- - `/review`:查找审查相关资源
11
+ - `/review`:查找代码审查相关资源
12
12
 
13
- 选择 Skill 会插入 `/skill:名称`。Package 和 Extension 结果仅用于识别,不会自动安装或执行。
13
+ 选中结果后:
14
+
15
+ - **Command**:插入并执行对应的 Pi 命令;
16
+ - **Skill**:插入 `/skill:名称`,由 Pi 加载该 Skill;
17
+ - **Extension**:仅显示扩展入口和所属包,不会伪装成可执行命令;
18
+ - **Package**:仅显示已配置的 Pi 包,不会自动安装或修改配置。
19
+
20
+ 没有匹配结果时,Pi 会继续使用原生的 `/` 命令和路径补全。
21
+
22
+ ## 安装
23
+
24
+ ```bash
25
+ pi install npm:pi-resource-search
26
+ ```
27
+
28
+ 安装后执行 `/reload`。如果扩展刚刚安装或更新,建议重新启动 Pi。
14
29
 
15
30
  ## 特点
16
31
 
17
- - 使用 Pi 原生 autocomplete provider,不修改 Pi 核心。
18
- - 仅读取配置、Package 清单和 Skill frontmatter。
19
- - 支持 Windows、macOS Linux 的用户目录。
20
- - 不执行被扫描 Package 的代码,不写入 Skill 或 Package 文件。
32
+ - 使用 Pi 原生 autocomplete API;
33
+ - 支持 Windows、macOS Linux;
34
+ - 支持 `PI_CODING_AGENT_DIR` 自定义 Pi 配置目录;
35
+ - 仅读取 Pi 配置、Package 清单和 Skill frontmatter;
36
+ - 不执行被扫描包的代码;
37
+ - 不修改 Skill、Package 或 Pi 配置文件;
38
+ - 不要求安装 `pi-cn`,可独立工作。
21
39
 
22
- ## 本地测试
40
+ ## 注意事项
41
+
42
+ 扩展搜索的是当前 Pi 已发现或已配置的资源,不是 npm 全网包搜索。新增 Skill 或 Package 后,执行 `/reload` 刷新索引。
43
+
44
+ 如果其他扩展也修改 `/` 补全,结果顺序可能受扩展加载顺序影响;本扩展会尽量保留 Pi 原生结果。
45
+
46
+ ## 本地开发
23
47
 
24
48
  ```bash
25
- pi -e .
26
49
  npm install
27
50
  npm run typecheck
28
51
  npm pack --dry-run
52
+ pi -e .
29
53
  ```
30
54
 
31
55
  ## 兼容性
32
56
 
33
57
  需要 Pi `>=0.85.0`。
58
+
59
+ ## 许可证
60
+
61
+ MIT
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
5
5
  import {
6
- fuzzyFilter,
6
+ fuzzyMatch,
7
7
  type AutocompleteItem,
8
8
  type AutocompleteProvider,
9
9
  type AutocompleteSuggestions,
@@ -123,6 +123,36 @@ function queryToken(text: string): string | undefined {
123
123
  return text.match(/(?:^|[ \t])\/([^\s/]*)$/)?.[1];
124
124
  }
125
125
 
126
+ // 命中档位:名称前缀 > 名称子串 > 名称模糊 > 描述/类型模糊
127
+ // 档位差固定 1000 分,保证名称命中永远排在描述命中前面
128
+ const TIER_NAME_PREFIX = 0;
129
+ const TIER_NAME_SUBSTRING = 1;
130
+ const TIER_NAME_FUZZY = 2;
131
+ const TIER_TEXT_FUZZY = 3;
132
+
133
+ function scoreResource(resource: Resource, query: string): number | undefined {
134
+ const q = query.toLowerCase();
135
+ const name = resource.name.toLowerCase();
136
+ if (name.startsWith(q)) return TIER_NAME_PREFIX * 1000 + (name.length - q.length);
137
+ const index = name.indexOf(q);
138
+ if (index >= 0) return TIER_NAME_SUBSTRING * 1000 + index;
139
+ const nameMatch = fuzzyMatch(q, name);
140
+ if (nameMatch.matches) return TIER_NAME_FUZZY * 1000 + nameMatch.score;
141
+ const textMatch = fuzzyMatch(q, `${resource.description} ${resource.kind}`);
142
+ if (textMatch.matches) return TIER_TEXT_FUZZY * 1000 + textMatch.score;
143
+ return undefined;
144
+ }
145
+
146
+ export function rankResources(resources: Resource[], query: string): Resource[] {
147
+ const scored: { resource: Resource; score: number }[] = [];
148
+ for (const resource of resources) {
149
+ const score = scoreResource(resource, query);
150
+ if (score !== undefined) scored.push({ resource, score });
151
+ }
152
+ scored.sort((a, b) => a.score - b.score);
153
+ return scored.map((entry) => entry.resource);
154
+ }
155
+
126
156
  function toItem(resource: Resource): AutocompleteItem {
127
157
  return { value: resource.value, label: `${resource.kind} ${resource.name}`, description: resource.description };
128
158
  }
@@ -145,7 +175,7 @@ function createProvider(pi: ExtensionAPI, current: AutocompleteProvider, resourc
145
175
  }
146
176
 
147
177
  const all = [...commands, ...resources];
148
- const matches = fuzzyFilter(all, query, (item) => `${item.name} ${item.description} ${item.kind}`).slice(0, MAX_RESULTS);
178
+ const matches = rankResources(all, query).slice(0, MAX_RESULTS);
149
179
  if (options.signal.aborted) return null;
150
180
  const native = await current.getSuggestions(lines, cursorLine, cursorCol, options);
151
181
  if (options.signal.aborted) return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-resource-search",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Search Pi commands, skills, extensions, and installed packages from /keyword autocomplete.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -10,6 +10,14 @@
10
10
  "autocomplete"
11
11
  ],
12
12
  "license": "MIT",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/hagertygodoy398-tech/pi-resource-search.git"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/hagertygodoy398-tech/pi-resource-search/issues"
19
+ },
20
+ "homepage": "https://github.com/hagertygodoy398-tech/pi-resource-search#readme",
13
21
  "type": "module",
14
22
  "files": [
15
23
  "extensions",