@r3b1s/pi-repair-layer 0.2.0 → 0.3.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 +159 -293
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/{index.ts → dist/index.js} +2 -1
- package/dist/index.js.map +1 -0
- package/dist/src/core.d.ts +8 -0
- package/dist/src/core.d.ts.map +1 -0
- package/dist/src/core.js +7 -0
- package/dist/src/core.js.map +1 -0
- package/dist/src/envelope.d.ts +21 -0
- package/dist/src/envelope.d.ts.map +1 -0
- package/dist/src/envelope.js +158 -0
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/grammar-recovery.d.ts +105 -0
- package/dist/src/grammar-recovery.d.ts.map +1 -0
- package/dist/src/grammar-recovery.js +1052 -0
- package/dist/src/grammar-recovery.js.map +1 -0
- package/dist/src/grammar.d.ts +2 -0
- package/dist/src/grammar.d.ts.map +1 -0
- package/dist/src/grammar.js +2 -0
- package/dist/src/grammar.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +558 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lifecycle.d.ts +34 -0
- package/dist/src/lifecycle.d.ts.map +1 -0
- package/dist/src/lifecycle.js +133 -0
- package/dist/src/lifecycle.js.map +1 -0
- package/dist/src/pi.d.ts +19 -0
- package/dist/src/pi.d.ts.map +1 -0
- package/dist/src/pi.js +38 -0
- package/dist/src/pi.js.map +1 -0
- package/dist/src/pipeline.d.ts +10 -0
- package/dist/src/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline.js +166 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/policy.d.ts +16 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/policy.js +31 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/preprocess.d.ts +37 -0
- package/dist/src/preprocess.d.ts.map +1 -0
- package/dist/src/preprocess.js +216 -0
- package/dist/src/preprocess.js.map +1 -0
- package/dist/src/repair-engine.d.ts +91 -0
- package/dist/src/repair-engine.d.ts.map +1 -0
- package/dist/src/repair-engine.js +457 -0
- package/dist/src/repair-engine.js.map +1 -0
- package/dist/src/settings.d.ts +38 -0
- package/dist/src/settings.d.ts.map +1 -0
- package/dist/src/settings.js +87 -0
- package/dist/src/settings.js.map +1 -0
- package/dist/src/tables.d.ts +16 -0
- package/dist/src/tables.d.ts.map +1 -0
- package/dist/src/tables.js +302 -0
- package/dist/src/tables.js.map +1 -0
- package/dist/src/types.d.ts +52 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/value-strips.d.ts +52 -0
- package/dist/src/value-strips.d.ts.map +1 -0
- package/dist/src/value-strips.js +191 -0
- package/dist/src/value-strips.js.map +1 -0
- package/docs/how-it-works.md +227 -0
- package/docs/operations.md +141 -0
- package/docs/research.md +247 -0
- package/docs/tool-owner-integration.md +327 -0
- package/package.json +31 -6
- package/src/grammar-recovery.ts +0 -1269
- package/src/index.ts +0 -621
- package/src/repair-engine.ts +0 -498
- package/src/settings.ts +0 -95
- package/src/tables.ts +0 -184
- package/src/value-strips.ts +0 -218
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Integrating repairs into extension-owned tools
|
|
2
|
+
|
|
3
|
+
This guide shows how a pi extension can apply pi-repair-layer's public repair
|
|
4
|
+
pipeline to tools that extension owns. The usual integration is one wrapper
|
|
5
|
+
around the tool definition. A lower-level core API is available when the tool
|
|
6
|
+
owner needs to control the surrounding lifecycle.
|
|
7
|
+
|
|
8
|
+
## The ownership boundary
|
|
9
|
+
|
|
10
|
+
pi validates tool arguments after calling that tool's `prepareArguments`.
|
|
11
|
+
Because arguments that fail validation never reach `tool_call`, repair must run
|
|
12
|
+
in `prepareArguments` to recover them safely.
|
|
13
|
+
|
|
14
|
+
Only the extension that owns a tool definition can reliably install that hook.
|
|
15
|
+
Installing pi-repair-layer repairs pi's built-in tools, but it does not discover,
|
|
16
|
+
replace, or wrap tools registered by other extensions. Those extensions must
|
|
17
|
+
explicitly use one of the APIs below.
|
|
18
|
+
|
|
19
|
+
## Install the package
|
|
20
|
+
|
|
21
|
+
Add pi-repair-layer as a dependency of the extension that owns the tool:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add @r3b1s/pi-repair-layer
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The public APIs are compiled ESM with TypeScript declarations:
|
|
28
|
+
|
|
29
|
+
- `@r3b1s/pi-repair-layer/pi` provides the pi tool-definition adapter.
|
|
30
|
+
- `@r3b1s/pi-repair-layer/core` provides the pure pipeline, configuration
|
|
31
|
+
types, lifecycle helpers, and repair-note formatting.
|
|
32
|
+
- `@r3b1s/pi-repair-layer/grammar` provides pure leaked-grammar parsing and
|
|
33
|
+
recovery helpers.
|
|
34
|
+
|
|
35
|
+
Do not import files from `src/`; they are not part of the compatibility
|
|
36
|
+
contract. Node 22 or later is required. The verified pi integration baseline is
|
|
37
|
+
0.80.6.
|
|
38
|
+
|
|
39
|
+
## Recommended: wrap the tool definition
|
|
40
|
+
|
|
41
|
+
`adaptToolDefinition` returns a copy of the supplied definition with a repair
|
|
42
|
+
aware `prepareArguments`. It preserves the tool's schema and executor and
|
|
43
|
+
chains any `prepareArguments` already supplied by the owner.
|
|
44
|
+
|
|
45
|
+
Once wrapped, bounded envelope recovery and schema-located repairs such as
|
|
46
|
+
dropping an invalid optional `null` or parsing a JSON-stringified array are
|
|
47
|
+
automatic. Exact aliases, cleanup of values that already satisfy the schema,
|
|
48
|
+
and tool-specific shape changes require explicit preprocessors because only the
|
|
49
|
+
tool owner knows where those transformations are semantically safe.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
53
|
+
import { adaptToolDefinition } from "@r3b1s/pi-repair-layer/pi";
|
|
54
|
+
import { Type } from "typebox";
|
|
55
|
+
|
|
56
|
+
const parameters = Type.Object({
|
|
57
|
+
path: Type.String(),
|
|
58
|
+
labels: Type.Optional(Type.Array(Type.String())),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export default function myExtension(pi: ExtensionAPI) {
|
|
62
|
+
pi.registerTool(
|
|
63
|
+
adaptToolDefinition(
|
|
64
|
+
{
|
|
65
|
+
name: "inspect_asset",
|
|
66
|
+
label: "Inspect asset",
|
|
67
|
+
description: "Inspect an asset and optionally apply labels",
|
|
68
|
+
parameters,
|
|
69
|
+
async execute(_toolCallId, params) {
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: `Inspecting ${params.path}`,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
details: undefined,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
policy: "adaptive",
|
|
83
|
+
preprocessors: [
|
|
84
|
+
{
|
|
85
|
+
kind: "alias",
|
|
86
|
+
selector: "/path",
|
|
87
|
+
aliases: ["file_path", "filePath"],
|
|
88
|
+
accepts: "string",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
kind: "filesystem-path",
|
|
92
|
+
selector: "/path",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
kind: "string-or-array",
|
|
96
|
+
selector: "/labels",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
With this configuration, `{file_path: "/tmp/a"}` becomes
|
|
106
|
+
`{path: "/tmp/a"}`, a markdown auto-link in `path` is unwrapped, and a single
|
|
107
|
+
string in `labels` becomes a one-item array. Each mutation has a stable rule ID
|
|
108
|
+
and explanatory note, and the final result must pass the supplied schema.
|
|
109
|
+
|
|
110
|
+
The adapter fails closed by throwing `UnrepairableToolInputError` with a
|
|
111
|
+
model-readable retry message. `unrepairable: "passthrough"` is available for a
|
|
112
|
+
deliberate compatibility migration, but it can expose the input to pi's native
|
|
113
|
+
conversion and should not be the default.
|
|
114
|
+
|
|
115
|
+
## Configure only known-safe transforms
|
|
116
|
+
|
|
117
|
+
Preprocessors use JSON-Pointer-like selectors. `"/path"` selects a field,
|
|
118
|
+
`"/edits/*/oldText"` selects a field in every array item, and `""` selects the
|
|
119
|
+
root. Pointer escapes `~0` and `~1` represent `~` and `/` in field names.
|
|
120
|
+
|
|
121
|
+
Available preprocessors are:
|
|
122
|
+
|
|
123
|
+
| Kind | Intended use |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `alias` | Move an explicitly listed alternative key to its canonical location. |
|
|
126
|
+
| `filesystem-path` | Unwrap a markdown auto-link in one path string. |
|
|
127
|
+
| `filesystem-path-array` | Apply path cleanup to string items in one array. |
|
|
128
|
+
| `string-or-array` | Wrap one configured string as a one-item array. |
|
|
129
|
+
| `scalar` | Convert a configured string/number/boolean scalar to the declared scalar type. |
|
|
130
|
+
| `anchor-bleed` | Strip model-gated `^`/`$` artifacts from one configured string. |
|
|
131
|
+
| `grammar-tokens` | Strip model-gated argument tokens at configured keys/values. |
|
|
132
|
+
| `structural` | Apply an owner-supplied shape transformation with a stable rule ID and note. |
|
|
133
|
+
|
|
134
|
+
Alias values can be guarded with `accepts: "string"`, `"number"`,
|
|
135
|
+
`"boolean"`, `"array"`, or `"object"`. By default, an existing canonical
|
|
136
|
+
value wins. Set `emptyEquivalentToMissing: true` only when an empty canonical
|
|
137
|
+
value is invalid or genuinely means “not supplied.”
|
|
138
|
+
|
|
139
|
+
Model-specific transforms require both a matching `modelId` and configured
|
|
140
|
+
`modelFamilies`:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
{
|
|
144
|
+
policy: "adaptive",
|
|
145
|
+
modelId: "provider/model-id",
|
|
146
|
+
preprocessors: [{
|
|
147
|
+
kind: "anchor-bleed",
|
|
148
|
+
selector: "/path",
|
|
149
|
+
modelFamilies: [/kimi-k2/i, /glm/i],
|
|
150
|
+
}],
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Adapter options are captured when the definition is wrapped. If the tool must
|
|
155
|
+
follow model changes during a session, either re-register it with the new model
|
|
156
|
+
ID or use the pure-core pattern below from an owner-managed `prepareArguments`
|
|
157
|
+
that reads current model state for each call.
|
|
158
|
+
|
|
159
|
+
Do not apply path cleanup to arbitrary content or anchor cleanup to regex
|
|
160
|
+
fields. The pipeline deliberately does not guess aliases, fuzzily rename keys,
|
|
161
|
+
or delete unknown fields.
|
|
162
|
+
|
|
163
|
+
### Policy profiles
|
|
164
|
+
|
|
165
|
+
- `conservative` permits bounded lossless envelope recovery, exact configured
|
|
166
|
+
preprocessing, and schema-guided repair. It observes model-gated valid-value
|
|
167
|
+
artifacts without mutating them.
|
|
168
|
+
- `adaptive` additionally permits schema-validated truncated-object completion
|
|
169
|
+
and configured model-gated value cleanup. This is the default.
|
|
170
|
+
- `recover` has the same tool-argument behavior as adaptive and additionally
|
|
171
|
+
enables gated assistant-text grammar promotion when the installable extension
|
|
172
|
+
is handling `message_end`.
|
|
173
|
+
|
|
174
|
+
The adapter itself does not register grammar hooks or turn assistant text into
|
|
175
|
+
tool calls.
|
|
176
|
+
|
|
177
|
+
## Existing `prepareArguments` hooks
|
|
178
|
+
|
|
179
|
+
If the definition already has `prepareArguments`, keep it on the definition.
|
|
180
|
+
The adapter calls it after envelope recovery and before configured
|
|
181
|
+
preprocessors and schema repair:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
pi.registerTool(
|
|
185
|
+
adaptToolDefinition({
|
|
186
|
+
...definition,
|
|
187
|
+
prepareArguments(input) {
|
|
188
|
+
return migrateMyExtensionVersion(input);
|
|
189
|
+
},
|
|
190
|
+
}),
|
|
191
|
+
);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The owner shim should perform only compatibility work belonging to that tool.
|
|
195
|
+
If it throws, the pipeline preserves the recovered envelope and continues to a
|
|
196
|
+
fail-closed validity decision.
|
|
197
|
+
|
|
198
|
+
## Optional: receive structured outcomes
|
|
199
|
+
|
|
200
|
+
Use `onOutcome` for metrics or owner-managed feedback. It runs once with the
|
|
201
|
+
same result returned by the pipeline:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
adaptToolDefinition(definition, {
|
|
205
|
+
onOutcome(result) {
|
|
206
|
+
if (result.outcome === "repaired") {
|
|
207
|
+
recordValueFreeMetric({
|
|
208
|
+
tool: definition.name,
|
|
209
|
+
policy: result.policy,
|
|
210
|
+
rules: result.changes.map((change) => change.ruleId),
|
|
211
|
+
stages: result.changes.map((change) => change.stage),
|
|
212
|
+
fingerprint: result.fingerprint,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`result.args` contains the actual arguments. Do not write it to telemetry or
|
|
220
|
+
session metadata. Rule IDs, stages, policy, outcome, and non-value failure
|
|
221
|
+
fingerprints are suitable for value-free reporting. Callback errors are
|
|
222
|
+
isolated and do not alter the repair verdict.
|
|
223
|
+
|
|
224
|
+
## Optional: attach `<repair_note>` feedback
|
|
225
|
+
|
|
226
|
+
The adapter repairs arguments, but it cannot attach feedback by itself because
|
|
227
|
+
`prepareArguments` runs before pi creates or exposes the validated call through
|
|
228
|
+
`tool_call`. Tool owners that want model-facing notes can use the exported
|
|
229
|
+
bounded `RepairLifecycle` to bridge that gap:
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import {
|
|
233
|
+
attachRepairNotes,
|
|
234
|
+
RepairLifecycle,
|
|
235
|
+
} from "@r3b1s/pi-repair-layer/core";
|
|
236
|
+
import { adaptToolDefinition } from "@r3b1s/pi-repair-layer/pi";
|
|
237
|
+
|
|
238
|
+
const lifecycle = new RepairLifecycle();
|
|
239
|
+
const toolName = definition.name;
|
|
240
|
+
|
|
241
|
+
pi.registerTool(
|
|
242
|
+
adaptToolDefinition(definition, {
|
|
243
|
+
policy: "adaptive",
|
|
244
|
+
preprocessors,
|
|
245
|
+
onOutcome(result) {
|
|
246
|
+
if (result.outcome !== "repaired") return;
|
|
247
|
+
lifecycle.enqueue(toolName, result.args, {
|
|
248
|
+
rules: result.changes.map((change) => change.ruleId),
|
|
249
|
+
notes: result.changes.map((change) => change.note),
|
|
250
|
+
stages: [...new Set(result.changes.map((change) => change.stage))],
|
|
251
|
+
profile: result.policy,
|
|
252
|
+
outcome: "repaired",
|
|
253
|
+
fingerprint: result.fingerprint,
|
|
254
|
+
});
|
|
255
|
+
},
|
|
256
|
+
}),
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
pi.on("tool_call", async (event) => {
|
|
260
|
+
lifecycle.correlate(event.toolName, event.input, event.toolCallId);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
pi.on("tool_result", async (event) => {
|
|
264
|
+
const feedback = lifecycle.take(event.toolCallId);
|
|
265
|
+
if (!feedback || feedback.notes.length === 0) return undefined;
|
|
266
|
+
return {
|
|
267
|
+
content: attachRepairNotes(event.content, feedback.notes),
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
pi.on("session_shutdown", async () => {
|
|
272
|
+
lifecycle.clear();
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The lifecycle uses stable argument serialization, FIFO matching for identical
|
|
277
|
+
concurrent calls, bounded queues, and a TTL. `attachRepairNotes` preserves other
|
|
278
|
+
content and avoids inserting an identical tagged note twice. A custom TUI
|
|
279
|
+
indicator remains the owning extension's responsibility.
|
|
280
|
+
|
|
281
|
+
## Lower level: call the pure core
|
|
282
|
+
|
|
283
|
+
Use `runRepairPipeline` when the adapter does not fit the tool framework or when
|
|
284
|
+
repair is needed outside a pi session:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import { runRepairPipeline } from "@r3b1s/pi-repair-layer/core";
|
|
288
|
+
|
|
289
|
+
const result = runRepairPipeline({
|
|
290
|
+
input: rawArguments,
|
|
291
|
+
config: {
|
|
292
|
+
toolName: "inspect_asset",
|
|
293
|
+
schema: parameters,
|
|
294
|
+
policy: "adaptive",
|
|
295
|
+
preprocessors,
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
if (result.outcome === "unrepairable") {
|
|
300
|
+
throw new Error(result.retryMessage);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const validatedArguments = result.args;
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
The core registers no pi events and performs no filesystem, UI, telemetry,
|
|
307
|
+
network, or persistence work. It does not mutate caller-owned input. A
|
|
308
|
+
`repaired` outcome always means the final arguments passed the supplied schema;
|
|
309
|
+
an `unrepairable` outcome returns the original input and no claimed changes.
|
|
310
|
+
|
|
311
|
+
## Test the integration
|
|
312
|
+
|
|
313
|
+
At minimum, an owning extension should test:
|
|
314
|
+
|
|
315
|
+
1. Strictly valid input remains unchanged.
|
|
316
|
+
2. Every configured alias and selector repair produces valid arguments.
|
|
317
|
+
3. Unconfigured content and similar-but-unknown keys remain unchanged.
|
|
318
|
+
4. Unrepairable input throws before the executor runs.
|
|
319
|
+
5. An existing owner `prepareArguments` is still called.
|
|
320
|
+
6. If result feedback is enabled, concurrent identical calls receive one note
|
|
321
|
+
each and stale notes do not leak to later calls.
|
|
322
|
+
7. Telemetry and persisted entries contain no argument values or note text.
|
|
323
|
+
|
|
324
|
+
For a working compile-time example, see
|
|
325
|
+
[`test/fixtures/public-consumer.ts`](../test/fixtures/public-consumer.ts). The
|
|
326
|
+
package smoke test installs the packed tarball into a clean project and imports
|
|
327
|
+
every documented subpath.
|
package/package.json
CHANGED
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@r3b1s/pi-repair-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
7
7
|
"url": "https://github.com/r3b1s/pi-repair-layer.git"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"dist",
|
|
11
|
+
"docs",
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE"
|
|
14
14
|
],
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./core": {
|
|
24
|
+
"types": "./dist/src/core.d.ts",
|
|
25
|
+
"import": "./dist/src/core.js"
|
|
26
|
+
},
|
|
27
|
+
"./pi": {
|
|
28
|
+
"types": "./dist/src/pi.d.ts",
|
|
29
|
+
"import": "./dist/src/pi.js"
|
|
30
|
+
},
|
|
31
|
+
"./grammar": {
|
|
32
|
+
"types": "./dist/src/grammar.d.ts",
|
|
33
|
+
"import": "./dist/src/grammar.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
17
36
|
"license": "MIT",
|
|
18
37
|
"publishConfig": {
|
|
19
38
|
"access": "public"
|
|
@@ -27,7 +46,7 @@
|
|
|
27
46
|
],
|
|
28
47
|
"pi": {
|
|
29
48
|
"extensions": [
|
|
30
|
-
"./
|
|
49
|
+
"./dist/index.js"
|
|
31
50
|
]
|
|
32
51
|
},
|
|
33
52
|
"dependencies": {
|
|
@@ -37,6 +56,7 @@
|
|
|
37
56
|
"@biomejs/biome": "2.4.8",
|
|
38
57
|
"@earendil-works/pi-ai": "^0.80.6",
|
|
39
58
|
"@earendil-works/pi-coding-agent": "0.80.6",
|
|
59
|
+
"@earendil-works/pi-tui": "0.80.6",
|
|
40
60
|
"@types/node": "^24.0.0",
|
|
41
61
|
"eslint": "^9.25.1",
|
|
42
62
|
"typescript": "^5.9.3",
|
|
@@ -44,17 +64,22 @@
|
|
|
44
64
|
"vitest": "^4.1.10"
|
|
45
65
|
},
|
|
46
66
|
"peerDependencies": {
|
|
47
|
-
"@earendil-works/pi-coding-agent": "*"
|
|
67
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
68
|
+
"@earendil-works/pi-tui": "*"
|
|
48
69
|
},
|
|
49
70
|
"engines": {
|
|
50
71
|
"node": ">=22"
|
|
51
72
|
},
|
|
52
73
|
"scripts": {
|
|
53
74
|
"check": "tsc --noEmit",
|
|
75
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
54
76
|
"lint": "biome check . && eslint src/ test/ index.ts",
|
|
55
77
|
"test": "vitest run",
|
|
78
|
+
"test:fuzz": "vitest run test/envelope-fuzz.test.ts",
|
|
79
|
+
"test:fuzz:large": "PI_REPAIR_FUZZ_CASES=10000 vitest run test/envelope-fuzz.test.ts",
|
|
56
80
|
"test:watch": "vitest",
|
|
57
81
|
"format": "biome check --write .",
|
|
82
|
+
"test:package": "node scripts/package-smoke.mjs",
|
|
58
83
|
"clean": "rm -rf dist node_modules coverage"
|
|
59
84
|
}
|
|
60
85
|
}
|