@trim21/personal-pi-extensions 0.1.511 → 0.1.512

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trim21/personal-pi-extensions",
3
- "version": "0.1.511",
3
+ "version": "0.1.512",
4
4
  "type": "module",
5
5
  "description": "Custom pi coding-agent extensions: bwrap sandbox, workspace guard, opencode edit, and more",
6
6
  "keywords": [
@@ -425,9 +425,14 @@ export interface LspService {
425
425
  start(): void;
426
426
  /**
427
427
  * 重启指定服务器:关闭其全部 client、清除对应失败记录并解除禁用;
428
- * 其余服务器不受影响。配置在下次工具调用时重新读取。
428
+ * 其余服务器不受影响。配置缓存失效,下次工具调用按当前 cwd 重新读盘。
429
429
  */
430
430
  reload(serverID: string): Promise<void>;
431
+ /**
432
+ * 重启全部服务器(/lsp-reload 无参):关闭所有 client、清空失败记录并
433
+ * 解除禁用;配置缓存失效,下次工具调用重新读盘。
434
+ */
435
+ reloadAll(): Promise<void>;
431
436
  /** 已知服务器 id(running 或 broken 的去重集合),供命令补全与提示。 */
432
437
  serverIDs(): string[];
433
438
  /** 注入 status 渲染回调;传入 undefined 表示不再渲染。 */
@@ -997,6 +1002,24 @@ export function createLspService(
997
1002
  updateStatusText();
998
1003
  }
999
1004
 
1005
+ async function reloadAll(): Promise<void> {
1006
+ state.closing = true;
1007
+ state.config = undefined;
1008
+ state.configCwd = undefined;
1009
+ await Promise.all(state.clients.map((client) => client.shutdown())).catch(() => {
1010
+ // 个别进程退出失败不阻止清理流程
1011
+ });
1012
+ state.clients = [];
1013
+ state.clientExtensions.clear();
1014
+ state.brokenFailAt.clear();
1015
+ state.brokenNotifiedAt.clear();
1016
+ state.servers.clear();
1017
+ await stopWatcher();
1018
+ state.closing = false;
1019
+ state.disabled = false;
1020
+ updateStatusText();
1021
+ }
1022
+
1000
1023
  function serverIDs(): string[] {
1001
1024
  return [...new Set([...state.servers.values()].map((server) => server.serverID))];
1002
1025
  }
@@ -1012,6 +1035,7 @@ export function createLspService(
1012
1035
  stop,
1013
1036
  start,
1014
1037
  reload,
1038
+ reloadAll,
1015
1039
  serverIDs,
1016
1040
  attachStatus,
1017
1041
  refreshStatus: updateStatusText,
@@ -1172,7 +1196,8 @@ export function createLspManager(
1172
1196
  });
1173
1197
 
1174
1198
  pi.registerCommand("lsp-reload", {
1175
- description: "Restart a specific LSP server: /lsp-reload <server-id>",
1199
+ description:
1200
+ "Restart LSP servers: /lsp-reload <server-id> for one, no argument reloads config and restarts all",
1176
1201
  getArgumentCompletions: (prefix) =>
1177
1202
  (service?.serverIDs() ?? [])
1178
1203
  .toSorted()
@@ -1184,12 +1209,10 @@ export function createLspManager(
1184
1209
  return;
1185
1210
  }
1186
1211
  const serverID = args.trim();
1187
- const known = service.serverIDs().toSorted();
1188
1212
  if (!serverID) {
1189
- ctx.ui.notify(
1190
- `usage: /lsp-reload <server-id>${known.length > 0 ? ` (known: ${known.join(", ")})` : ""}`,
1191
- "warning",
1192
- );
1213
+ // 无参:重读配置并重启全部服务器
1214
+ await service.reloadAll();
1215
+ ctx.ui.notify("LSP reloaded: all servers will restart on the next tool call", "info");
1193
1216
  return;
1194
1217
  }
1195
1218
  await service.reload(serverID);
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lsp-config
3
- description: Use when 编写、检查或排查 LSP 语言服务器配置 —— 项目本地 .pi/lsp.json 或全局 ~/.pi/agent/lsp.json:配置 typescript-language-server / pyright / ruff / gopls / clangd 等服务器的 bin、include、rootMarkers、initializationOptions、tsserver.path、watch 与诊断超时;或排查服务器起不来(binary not found / provides no tsserver.js)、typescript alias 依赖下 tsserver 找不到、诊断一直为空等问题。
3
+ description: Use when 编写、检查或排查 LSP 语言服务器配置 —— 项目本地 .pi/lsp.json 或全局 ~/.pi/agent/lsp.json:配置 typescript-language-server / pyright / ruff / gopls / clangd 等服务器的 bin、include、workingDir、initializationOptions、tsserver.path、watch 与诊断超时;或排查服务器起不来(binary not found / provides no tsserver.js)、typescript alias 依赖下 tsserver 找不到、诊断一直为空等问题。
4
4
  ---
5
5
 
6
6
  # 配置 LSP 服务器(.pi/lsp.json)
@@ -14,14 +14,14 @@ description: Use when 编写、检查或排查 LSP 语言服务器配置 ——
14
14
 
15
15
  合并是**纯函数**(`mergeConfig(global, local)`),规则:
16
16
 
17
- | 段 | 合并方式 |
18
- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19
- | 顶层其余字段 | 本地覆盖全局(浅合并) |
20
- | `servers` | 按服务器 id **整条覆盖**:本地写某个 id 会替换全局同 id 的整条记录,**不是字段级合并**。只改一个字段(如补 `initializationOptions`)也必须把 `include`/`rootMarkers`/`bin`/`args`/`cwd`/`languageIdByExtension` 全部带上,否则丢全局字段 |
21
- | `watch` | 字段级合并:全局为基底、本地逐字段覆盖;`ignore` 两侧**并集去重**(全局在前),本地写 watch 段不会清掉全局 ignore |
22
- | 某段全局本地都未出现 | 保持缺失(调用方用 `...(watch && { watch })` 省略键,不要输出空对象) |
17
+ | 段 | 合并方式 |
18
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | 顶层其余字段 | 本地覆盖全局(浅合并) |
20
+ | `servers` | 按服务器 id **整条覆盖**:本地写某个 id 会替换全局同 id 的整条记录,**不是字段级合并**。只改一个字段(如补 `initializationOptions`)也必须把 `include`/`workingDir`/`bin`/`args`/`languageIdByExtension` 全部带上,否则丢全局字段 |
21
+ | `watch` | 字段级合并:全局为基底、本地逐字段覆盖;`ignore` 两侧**并集去重**(全局在前),本地写 watch 段不会清掉全局 ignore |
22
+ | 某段全局本地都未出现 | 保持缺失(调用方用 `...(watch && { watch })` 省略键,不要输出空对象) |
23
23
 
24
- 配置经 typebox **严格校验**(`Type.Object` 默认拒绝多余字段):未知的 `version`、多余键、非法时长格式都会在读取时抛错。`version` 当前为 1。
24
+ 配置经 typebox 校验:字段类型不符、非法时长格式等在读取时**直接抛错**;schema 外的未知字段(含已删除的遗留字段如 `rootMarkers`)**不拒绝**,以 warning notify 逐个上报。`version` 当前为 1。
25
25
 
26
26
  ## 顶层字段速查
27
27
 
@@ -41,10 +41,9 @@ diagnosticsFullWaitTimeoutMs / diagnosticsRequestTimeoutMs / initializeTimeoutMs
41
41
  | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
42
42
  | `include` | 文件 glob(相对项目根或调用 cwd,任一命中即可);缺省匹配所有文件 |
43
43
  | `kind` | `language`(缺省)或 `linter`。rename / inspect 等符号级功能**只面向 `language`**;linter 只参与诊断 |
44
- | `rootMarkers` | 项目根标记文件名(从文件目录向上查找);缺省把调用 cwd 当根 |
44
+ | `workingDir` | 服务器工作目录(即 LSP root):绝对路径或相对调用 cwd 的路径;缺省即调用 cwd。文件必须位于该目录内才会由本服务器处理;spawn 工作目录与 rootUri 均用它 |
45
45
  | `bin` | 可执行文件:绝对路径、相对调用 cwd 的路径、或仅名字(项目工作区优先,PATH 兜底) |
46
46
  | `args` | 启动参数数组 |
47
- | `cwd` | 启动工作目录,支持 `{root}` / `{cwd}` 模板;缺省 `{root}` |
48
47
  | `env` | 追加的环境变量:string 值支持 `{root}`/`{cwd}` 与 `${VAR}` 插值;`{ "sh": ["cmd","arg"] }` 启动时执行命令取 stdout(非零退出/空输出 → 启动失败并报错) |
49
48
  | `languageIdByExtension` | 扩展名(含点)→ languageId;缺省回退内置映射(见 `src/lib/lsp/language.ts`,覆盖主流语言) |
50
49
  | `startupTimeoutMs` / `diagnosticsWaitMs` | 覆盖该服务器的初始化握手 / 写文件后诊断等待(缺省用全局配置与 client 默认) |
@@ -70,10 +69,8 @@ typescript-language-server **不内置 TypeScript**(零依赖)。启动时
70
69
  "servers": {
71
70
  "typescript": {
72
71
  "include": ["**/*.{ts,tsx,js,jsx,mjs,cjs,mts,cts}"],
73
- "rootMarkers": ["package-lock.json", "pnpm-lock.yaml", "yarn.lock"],
74
72
  "bin": "typescript-language-server",
75
73
  "args": ["--stdio"],
76
- "cwd": "{root}",
77
74
  "languageIdByExtension": {
78
75
  ".ts": "typescript",
79
76
  ".tsx": "typescriptreact",
@@ -94,11 +91,11 @@ typescript-language-server **不内置 TypeScript**(零依赖)。启动时
94
91
 
95
92
  - 启动失败(binary 缺失 / initialize 拒绝)会**主动 notify 报错**(server id、root、原因、提示 `/lsp-reload <id>`),不需要等请求方触发
96
93
  - 失败进入 60s 冷却:冷却内该服务器被跳过,**冷却过后下次触碰自动重试**——修复配置后不用重启 agent,等冷却过即可,或立即 `/lsp-reload <id>` 重启指定服务器(同时清除失败记录)
97
- - 命令:`/lsp-reload <id>`(重启单个)、`/lsp-stop`(停全部并禁用)、`/lsp-start`(重新启用)
94
+ - 命令:`/lsp-reload <id>`(重启单个)、`/lsp-reload`(无参:重读配置并重启全部)、`/lsp-stop`(停全部并禁用)、`/lsp-start`(重新启用)
98
95
 
99
96
  ## 生效时机
100
97
 
101
- - `servers` 配置在每次工具调用时惰性重读:**还没启动**的服务器,改 `bin`/`initializationOptions` 等下次触碰即生效;**已启动**的进程要用 `/lsp-reload <id>`(或重启 agent)才换新配置
98
+ - 配置在 `session_start` 预读并**按 cwd 缓存**:cwd 变化或 `/lsp-reload`(单个或无参)时重读。改配置后用 `/lsp-reload` 让全部或单个服务器换新配置(已启动的进程随之重启)
102
99
  - `session_start` 时若 enabled 服务器数为 0 则不创建 service,之后从无到有地启用需要重启 agent
103
100
 
104
101
  ## 常见排查
@@ -108,4 +105,4 @@ typescript-language-server **不内置 TypeScript**(零依赖)。启动时
108
105
  | notify `failed to start …: binary not found` | `bin` 不在 PATH(测试场景二进制缺失时整组跳过) |
109
106
  | `… provides no tsserver.js. No other valid TypeScript installation was found` | workspace 的 `node_modules/typescript` 是 alias stub:配 `initializationOptions.tsserver.path` 指 `.pnpm` 实体,或换标准 typescript 依赖 |
110
107
  | 诊断一直为空且无任何报错 | 服务器没匹配到文件(`include`/扩展名)、在 broken 冷却中、或文件在调用 cwd 之外(LSP 只在工作目录内启用) |
111
- | 读取配置直接抛错 | typebox 严格校验拒绝:多余字段 / 未知 `version` / 非法时长格式 |
108
+ | 读取配置直接抛错 | typebox 严格校验拒绝:字段类型不符 / 非法时长格式(未知字段只是 warning,不拒绝) |