@r3b1s/pi-repair-layer 0.4.1 → 0.4.3
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 +6 -0
- package/docs/research.md +13 -3
- package/docs/tool-owner-integration.md +31 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,12 @@ same repair pipeline to tools in your own extension.
|
|
|
8
8
|
|
|
9
9
|
No LLM calls. No network requests. No uploaded telemetry.
|
|
10
10
|
|
|
11
|
+
### Example: Deepseek v4 Pro
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
### Example: GLM 5.2
|
|
15
|
+

|
|
16
|
+
|
|
11
17
|
## Contents
|
|
12
18
|
|
|
13
19
|
- [Why use it?](#why-use-it)
|
package/docs/research.md
CHANGED
|
@@ -257,9 +257,19 @@ the requested module:
|
|
|
257
257
|
|
|
258
258
|
**Why it matters:** the optional-integration recipe treats an import failure
|
|
259
259
|
as "package absent" only when the code is one of these two values **and** the
|
|
260
|
-
message names `@r3b1s/pi-repair-layer
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
message names `@r3b1s/pi-repair-layer` **as a quoted module specifier** —
|
|
261
|
+
matched as an opening quote immediately followed by the name
|
|
262
|
+
(`'@r3b1s/pi-repair-layer`, no trailing quote so both the bare-package and
|
|
263
|
+
`/pi`-subpath forms match); anything else rethrows so a broken install (a
|
|
264
|
+
*transitive* module missing, e.g. `typebox`) is not silently misread as
|
|
265
|
+
absent. The quote anchor matters because the jiti and compiled-binary shapes
|
|
266
|
+
carry the importer path: a present-but-broken install throws
|
|
267
|
+
`Cannot find module 'typebox/value' from '.../node_modules/@r3b1s/pi-repair-layer/...'`,
|
|
268
|
+
which contains `@r3b1s/pi-repair-layer` only as a path segment (preceded by
|
|
269
|
+
`/`, not a quote). A bare-substring match would misread that as absence; the
|
|
270
|
+
quoted-specifier match rethrows it loudly. All three observed absent-package
|
|
271
|
+
shapes still begin with quote-then-name and pass the discrimination.
|
|
272
|
+
(Refined 2026-07-21; matcher verified by unit test against all three shapes.)
|
|
263
273
|
|
|
264
274
|
### Claim 12 — Git installs and other scopes do not resolve the shared npm siblings
|
|
265
275
|
|
|
@@ -191,6 +191,21 @@ const definition: ToolDefinition<typeof parameters> = {
|
|
|
191
191
|
},
|
|
192
192
|
};
|
|
193
193
|
|
|
194
|
+
// Opening quote + name, no trailing quote: matches both the bare-package ESM
|
|
195
|
+
// error (`'@r3b1s/pi-repair-layer'`) and the jiti/binary subpath error
|
|
196
|
+
// (`'@r3b1s/pi-repair-layer/pi'`), while a `node_modules/...` path segment
|
|
197
|
+
// (preceded by `/`, not a quote) does not read as absence.
|
|
198
|
+
const REPAIR_PACKAGE_SPECIFIER_QUOTED = "'@r3b1s/pi-repair-layer";
|
|
199
|
+
|
|
200
|
+
export function isRepairPackageAbsent(error: unknown): boolean {
|
|
201
|
+
const code = (error as { code?: unknown } | null)?.code;
|
|
202
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
203
|
+
return (
|
|
204
|
+
(code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") &&
|
|
205
|
+
message.includes(REPAIR_PACKAGE_SPECIFIER_QUOTED)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
194
209
|
async function loadRepairAdapter(): Promise<
|
|
195
210
|
typeof adaptToolDefinition | undefined
|
|
196
211
|
> {
|
|
@@ -198,12 +213,7 @@ async function loadRepairAdapter(): Promise<
|
|
|
198
213
|
const repair = await import("@r3b1s/pi-repair-layer/pi");
|
|
199
214
|
return repair.adaptToolDefinition;
|
|
200
215
|
} catch (error) {
|
|
201
|
-
|
|
202
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
203
|
-
const packageAbsent =
|
|
204
|
-
(code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND") &&
|
|
205
|
-
message.includes("@r3b1s/pi-repair-layer");
|
|
206
|
-
if (!packageAbsent) throw error;
|
|
216
|
+
if (!isRepairPackageAbsent(error)) throw error;
|
|
207
217
|
return undefined;
|
|
208
218
|
}
|
|
209
219
|
}
|
|
@@ -225,12 +235,16 @@ The details are load-bearing:
|
|
|
225
235
|
`code: "MODULE_NOT_FOUND"` (jiti's require path) or
|
|
226
236
|
`code: "ERR_MODULE_NOT_FOUND"` (native ESM and the compiled pi binary). But
|
|
227
237
|
a *present-but-broken* install — pi-repair-layer resolvable while one of its
|
|
228
|
-
own transitive modules is not — throws the same codes
|
|
229
|
-
*transitive* module
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
238
|
+
own transitive modules (e.g. `typebox`) is not — throws the same codes
|
|
239
|
+
naming the *transitive* module, and its message embeds
|
|
240
|
+
`.../node_modules/@r3b1s/pi-repair-layer/...` as a path segment. Match the
|
|
241
|
+
package name only where it appears as an imported specifier — an opening
|
|
242
|
+
quote immediately followed by the name (`'@r3b1s/pi-repair-layer`) — so that
|
|
243
|
+
path segment does not read as absence. No trailing quote: jiti and the
|
|
244
|
+
compiled binary name the full subpath (`'@r3b1s/pi-repair-layer/pi'`) while
|
|
245
|
+
native ESM names the bare package (`'@r3b1s/pi-repair-layer'`); both start
|
|
246
|
+
with quote-then-name. This keeps a broken install loud (it rethrows) instead
|
|
247
|
+
of silently running unwrapped while the user believes repairs are active.
|
|
234
248
|
- **Rethrow everything else.** Any other error is a real failure, not
|
|
235
249
|
absence.
|
|
236
250
|
- **Emit one stderr line when falling back.** The two branches differ in
|
|
@@ -337,7 +351,11 @@ touches is deliberately small and covered by the compatibility contract in
|
|
|
337
351
|
current major; documented exports follow semantic versioning.
|
|
338
352
|
- Absence detection semantics are part of the contract: a missing package
|
|
339
353
|
surfaces with `code` `MODULE_NOT_FOUND` or `ERR_MODULE_NOT_FOUND` and a
|
|
340
|
-
message naming the requested module.
|
|
354
|
+
message naming the requested module. The recipe matches that name as a
|
|
355
|
+
quoted specifier (`'@r3b1s/pi-repair-layer`, opening quote + name), not a
|
|
356
|
+
bare substring, so the package name appearing as a `node_modules` path
|
|
357
|
+
segment in a present-but-broken install rethrows loudly rather than reading
|
|
358
|
+
as absence.
|
|
341
359
|
- Unrecognized preprocessor `kind`s are ignored — never fatal, no mutation, no
|
|
342
360
|
claimed change — and results are still schema-validated. Repair options
|
|
343
361
|
written against a newer minor version therefore degrade to the recognized
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@r3b1s/pi-repair-layer",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Tool-input repair layer for the pi coding agent: validate-then-repair for built-in tool calls, ported from the behavior of commandcode's repair layer",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|