pi-patch-keeper 1.0.8 → 1.0.10

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.en.md CHANGED
@@ -23,6 +23,13 @@ Prevents "force-typed" extensions from silently swallowing every section written
23
23
  | `/patch-keeper` | Show order, suspected force packages, fallback packages, codemode status |
24
24
  | `/patch-keeper fix` | Move known force-typed packages to the end (backup written first) |
25
25
 
26
+ ## Install
27
+
28
+ ```bash
29
+ pi install npm:pi-patch-keeper
30
+ pi install ./pi-patch-keeper
31
+ ```
32
+
26
33
  ## Defaults
27
34
 
28
35
  | Key | Default |
@@ -32,7 +39,13 @@ Prevents "force-typed" extensions from silently swallowing every section written
32
39
  | Notify | only on problems |
33
40
  | Scope | `npm:` packages |
34
41
 
35
- Optional config: `~/.pi/patch-keeper-state.json`
42
+ Optional config: `~/.pi/patch-keeper.json`
43
+
44
+ ## Discipline
45
+
46
+ - Never `return { systemPrompt }` — otherwise it becomes the problem it guards against.
47
+ - Writes only two places: `packages` order in `settings.json` (backup first) and the fingerprint in `~/.pi/patch-keeper.json`; failures are reported, never thrown.
48
+ - Any error is reported as a hint, never thrown; silent when clean.
36
49
 
37
50
  ## Limits
38
51
 
package/README.md CHANGED
@@ -40,7 +40,7 @@ pi 的 system prompt 由各扩展写入的 section 拼装。若某扩展在 `bef
40
40
  ## 纪律
41
41
 
42
42
  - **绝不** `return { systemPrompt }` —— 否则自己就是它要防的问题。
43
- - 唯一的写操作是修 `settings.json` 的 `packages`,且写前备份。
43
+ - 写操作两处:修 `settings.json` 的 `packages`(写前备份)与更新 `~/.pi/patch-keeper.json` 的指纹;失败都只提示。
44
44
  - 任何异常只提示、不抛错;无问题不打扰。
45
45
 
46
46
  ## 安装
@@ -52,6 +52,6 @@ pi install ./pi-patch-keeper
52
52
 
53
53
  ## 限制
54
54
 
55
- - 静态扫描只看扩展入口前 4000 字符内 `before_agent_start` 附近的写法,动态构造的 force 检测不到。
55
+ - 静态扫描从各入口的 `before_agent_start` 命中处起看 4000 字符(只看前 3 个入口文件),动态构造的 force 检测不到。
56
56
  - user 扩展(不在 `packages` 数组里)不在扫描范围。
57
57
  - 只处理顺序问题;不修改任何第三方扩展的源码。
package/index.ts CHANGED
@@ -93,7 +93,7 @@ export function normalizeForceOrder(packages: string[], tail: string[] = DEFAULT
93
93
  }
94
94
 
95
95
  /** 读扩展入口源码并分类:无条件 force / section 优先(旧宿主兜底)/ 无。 */
96
- function classifyPackages(packages: string[], tail: string[]): { force: string[]; fallback: string[] } {
96
+ export function classifyForcePackages(packages: string[], tail: string[]): { force: string[]; fallback: string[] } {
97
97
  const force: string[] = [];
98
98
  const fallback: string[] = [];
99
99
  for (const name of packages) {
@@ -127,12 +127,12 @@ function classifyPackages(packages: string[], tail: string[]): { force: string[]
127
127
 
128
128
  /** 疑似无条件 force(会吞掉其后 section)。 */
129
129
  export function scanForcePackages(packages: string[], tail: string[] = DEFAULT_FORCE_TAIL): string[] {
130
- return classifyPackages(packages, tail).force;
130
+ return classifyForcePackages(packages, tail).force;
131
131
  }
132
132
 
133
133
  /** 兼容兜底型(section 优先,仅旧宿主 force)。 */
134
134
  export function scanForceFallbacks(packages: string[], tail: string[] = DEFAULT_FORCE_TAIL): string[] {
135
- return classifyPackages(packages, tail).fallback;
135
+ return classifyForcePackages(packages, tail).fallback;
136
136
  }
137
137
 
138
138
  /** codemode 单点检查:禁用 builtin:codemode 时必须有替代实现,反之亦然。 */
@@ -210,9 +210,8 @@ function report(): string[] {
210
210
  const lines: string[] = [];
211
211
  const fo = forceOrderIssues(packages, tail);
212
212
  lines.push(`force顺序 : ${fo.length ? fo[0] : "OK"}`);
213
- const fe = scanForcePackages(packages, tail);
213
+ const { force: fe, fallback: fb } = classifyForcePackages(packages, tail);
214
214
  lines.push(`疑似force: ${fe.length ? fe.join(" / ") : "无(静态扫描)"}`);
215
- const fb = scanForceFallbacks(packages, tail);
216
215
  lines.push(`兼容兜底 : ${fb.length ? fb.join(" / ") : "无"}`);
217
216
  const cm = consistencyCheck((s.extensions as string[]) ?? [], packages);
218
217
  lines.push(`codemode : ${cm.length ? cm[0] : "单点一致"}`);
@@ -244,7 +243,7 @@ export default function patchKeeper(pi: ExtensionAPI): void {
244
243
  const arg = (args || "").trim().toLowerCase();
245
244
  if (arg === "fix") {
246
245
  const r = fixForceOrder();
247
- ctx.ui.notify(r ? `patch-keeper: ${r}` : "patch-keeper: force 顺序已正确,无需修复", r ? "info" : "info");
246
+ ctx.ui.notify(r ? `patch-keeper: ${r}` : "patch-keeper: force 顺序已正确,无需修复", "info");
248
247
  return;
249
248
  }
250
249
  ctx.ui.notify(`扩展加载顺序\n${report().join("\n")}`, "info");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-patch-keeper",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Detect and fix pi extension load-order hazards: force-typed extensions silently swallow later system-prompt sections.",
5
5
  "type": "module",
6
6
  "license": "MIT",