@abdwhb-png/pi-test-harness 0.7.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/CHANGELOG.md +161 -0
- package/LICENSE +21 -0
- package/README.md +673 -0
- package/dist/diagnostics.d.ts +11 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +61 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/events.d.ts +6 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +33 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/mock-pi-script.mjs +176 -0
- package/dist/mock-pi.d.ts +32 -0
- package/dist/mock-pi.d.ts.map +1 -0
- package/dist/mock-pi.js +150 -0
- package/dist/mock-pi.js.map +1 -0
- package/dist/mock-tools.d.ts +51 -0
- package/dist/mock-tools.d.ts.map +1 -0
- package/dist/mock-tools.js +192 -0
- package/dist/mock-tools.js.map +1 -0
- package/dist/mock-ui.d.ts +13 -0
- package/dist/mock-ui.d.ts.map +1 -0
- package/dist/mock-ui.js +159 -0
- package/dist/mock-ui.js.map +1 -0
- package/dist/pi-loader-parity.d.ts +36 -0
- package/dist/pi-loader-parity.d.ts.map +1 -0
- package/dist/pi-loader-parity.js +60 -0
- package/dist/pi-loader-parity.js.map +1 -0
- package/dist/playbook.d.ts +44 -0
- package/dist/playbook.d.ts.map +1 -0
- package/dist/playbook.js +143 -0
- package/dist/playbook.js.map +1 -0
- package/dist/sandbox.d.ts +27 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +269 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/session.d.ts +13 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +187 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +46 -0
- package/dist/utils.js.map +1 -0
- package/package.json +84 -0
- package/skills/pi-test-harness/SKILL.md +451 -0
- package/skills/pi-test-harness/evals/evals.json +26 -0
- package/skills/pi-test-harness/references/api-reference.md +480 -0
- package/skills/pi-test-harness/references/mock-pi-cli.md +135 -0
- package/skills/pi-test-harness/references/mock-tools.md +176 -0
- package/skills/pi-test-harness/references/mock-ui.md +170 -0
- package/skills/pi-test-harness/references/playbook-dsl.md +209 -0
- package/skills/pi-test-harness/references/sandbox-install.md +113 -0
- package/src/diagnostics.ts +90 -0
- package/src/events.ts +43 -0
- package/src/index.ts +42 -0
- package/src/mock-pi-script.mjs +176 -0
- package/src/mock-pi.ts +169 -0
- package/src/mock-tools.ts +252 -0
- package/src/mock-ui.ts +196 -0
- package/src/pi-loader-parity.ts +61 -0
- package/src/playbook.ts +189 -0
- package/src/sandbox.ts +334 -0
- package/src/session.ts +249 -0
- package/src/types.ts +203 -0
- package/src/utils.ts +46 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @abdwhb-png/pi-test-harness
|
|
2
|
+
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`fork`](https://github.com/abdwhb-png/pi-test-harness) Thanks [@abdwhb](https://github.com/abdwhb)! — Fork from `@marcfargas/pi-test-harness@0.6.1`. Pi 0.83.0 compatibility milestone.
|
|
8
|
+
|
|
9
|
+
**Breaking: Pi `^0.83.0` required.** Drops support for Pi `<0.83.0`.
|
|
10
|
+
|
|
11
|
+
- **`ModelRuntime` isolation** — `createTestSession()` creates an isolated `ModelRuntime` with `authPath` under the working directory and `modelsPath: null`. No credentials file is read from `~/.pi/agent`. A dummy API key is set on the openai provider to satisfy AgentSession auth checks (the model is never called — playbook replaces `streamFunction`).
|
|
12
|
+
|
|
13
|
+
- **Public Agent APIs** — The harness now accesses `session.agent.streamFunction`, `session.agent.state.tools`, and `session.agent.waitForIdle()` through the public typed API surface of Pi 0.83's `Agent` class. No more `(agent as any).streamFn` casts.
|
|
14
|
+
|
|
15
|
+
- **AgentSession typed** — `TestSession.session` is typed as `AgentSession` from `@earendil-works/pi-coding-agent`.
|
|
16
|
+
|
|
17
|
+
- **Hook pipeline — single source of truth** — AgentSession 0.83 installs `beforeToolCall`/`afterToolCall` hooks on the Agent, which drive the extension `tool_call`/`tool_result` events. The harness mock no longer re-emits these hooks manually. Each hook fires exactly once per tool call. Tool result modification via `tool_result` hook return values works correctly because the subscriber reads the finalized result from `tool_execution_end`.
|
|
18
|
+
|
|
19
|
+
- **Removed `ExtensionRunner` dependency from mock-tools** — `interceptToolExecution()` no longer takes an `extensionRunner` parameter. Mock wrappers only replace `tool.execute()`; hook dispatch is handled by AgentSession.
|
|
20
|
+
|
|
21
|
+
- **`ExtensionUIContext` — 0.83 members** — `createMockUIContext()` returns a properly typed `ExtensionUIContext` with all 0.83 members: `setWorkingVisible`, `setWorkingIndicator`, `setHiddenThinkingLabel`, `addAutocompleteProvider`, `getEditorComponent`. No `any` casts on the return type.
|
|
22
|
+
|
|
23
|
+
- **`SandboxOptions.npmCommand`** — New option to specify a custom npm command for `verifySandboxInstall()`. Default resolves to the platform npm. Use `["sfw", "npm"]` to route through Socket Firewall, or provide any `execFileSync`-compatible argv. A nonexistent command produces a clear `ENOENT` error.
|
|
24
|
+
|
|
25
|
+
- **`ToolBlockedError` kept for compat** — Still exported but no longer thrown in the normal mock flow. AgentSession 0.83 blocks tools via `beforeToolCall` before `execute()` is reached. Consumers can use `ToolBlockedError` for instanceof checks on errors from event callbacks.
|
|
26
|
+
|
|
27
|
+
- **`session_shutdown` note** — `session.dispose()` does NOT fire `session_shutdown`. That event fires at Node.js process exit. Extension-owned resources (e.g., SQLite handles) remain open until then.
|
|
28
|
+
|
|
29
|
+
- **Package identity** — Renamed to `@abdwhb-png/pi-test-harness@0.7.0`. Repository/homepage/bugs point to `abdwhb-png/pi-test-harness`. Peer dependencies narrowed to `^0.83.0`. Dev dependencies pinned to exact `0.83.0`.
|
|
30
|
+
|
|
31
|
+
- **CI** — Verify job runs `sfw npm ci` and `sfw npm audit`. Integration tests Node 22 and 24 on Linux and Windows with Pi 0.83. Release workflow changed to manual (`workflow_dispatch`).
|
|
32
|
+
|
|
33
|
+
- **Consumer smoke** — Uses `sfw npm install` with exact `0.83.0` peers, runs a real say-only session, and asserts consumption.
|
|
34
|
+
|
|
35
|
+
## 0.6.1
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- [`0236306`](https://github.com/marcfargas/pi-test-harness/commit/02363061622b5255fe2905867ec68e7bc0270d8b) Thanks [@marcfargas](https://github.com/marcfargas)! - Fix release metadata after the 0.6.0 migration release.
|
|
40
|
+
|
|
41
|
+
## 0.6.0
|
|
42
|
+
|
|
43
|
+
### Minor Changes
|
|
44
|
+
|
|
45
|
+
- [`10eb126`](https://github.com/marcfargas/pi-test-harness/commit/10eb1268fb82eb567ee8ba3e47fb942c5ee40795) Thanks [@marcfargas](https://github.com/marcfargas)! - Migrate the harness to the current `@earendil-works/*` Pi packages and require Pi `>=0.74.0`.
|
|
46
|
+
|
|
47
|
+
This drops direct support for the deprecated `@mariozechner/*` Pi package names, updates the harness for current Pi session/tool APIs, and adds CI coverage across Linux and Windows against the latest patch releases of the last two supported Pi minor lines.
|
|
48
|
+
|
|
49
|
+
## 0.5.0
|
|
50
|
+
|
|
51
|
+
### Minor Changes
|
|
52
|
+
|
|
53
|
+
- [#3](https://github.com/marcfargas/pi-test-harness/pull/3) [`225e123`](https://github.com/marcfargas/pi-test-harness/commit/225e123ce6ce2790f739aa3083ad1add3f09e752) Thanks [@marcfargas](https://github.com/marcfargas)! - Add `ToolBlockedError` and `safeRmSync` to the public API.
|
|
54
|
+
|
|
55
|
+
**`ToolBlockedError`** — a typed error class thrown when an extension hook blocks a mocked tool call. Use `instanceof ToolBlockedError` to distinguish hook blocks from real execution errors in tests, instead of matching error message strings.
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { ToolBlockedError } from "@marcfargas/pi-test-harness";
|
|
59
|
+
|
|
60
|
+
// Test that a blocked call doesn't crash, just records an error
|
|
61
|
+
const result = t.events.toolResultsFor("bash")[0];
|
|
62
|
+
expect(result.isError).toBe(true);
|
|
63
|
+
|
|
64
|
+
// Or catch it where propagateErrors is relevant
|
|
65
|
+
try {
|
|
66
|
+
await t.run(when("Try write", [calls("bash", {}), says("Done.")]));
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (err instanceof ToolBlockedError) {
|
|
69
|
+
// Expected — extension hook blocked the call
|
|
70
|
+
} else throw err;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**`safeRmSync(filePath)`** — removes a file, swallowing `EPERM` and `EBUSY` errors only. Intended for `afterEach` cleanup of extension-owned SQLite files on Windows, where `session_shutdown` (which closes DB connections) fires at process exit rather than on `session.dispose()`.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { safeRmSync } from "@marcfargas/pi-test-harness";
|
|
78
|
+
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
t?.dispose();
|
|
81
|
+
safeRmSync(dbPath);
|
|
82
|
+
safeRmSync(dbPath + "-wal");
|
|
83
|
+
safeRmSync(dbPath + "-shm");
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Patch Changes
|
|
88
|
+
|
|
89
|
+
- [#3](https://github.com/marcfargas/pi-test-harness/pull/3) [`225e123`](https://github.com/marcfargas/pi-test-harness/commit/225e123ce6ce2790f739aa3083ad1add3f09e752) Thanks [@marcfargas](https://github.com/marcfargas)! - Fix tool event collection and block detection.
|
|
90
|
+
|
|
91
|
+
- **`toolResultsFor()` / `toolCallsFor()` now work without `mockTools`**. Previously these always returned `[]` when `mockTools` was not configured, because real tools were not wrapped for collection. Now all tools are always wrapped, regardless of whether mocks are configured.
|
|
92
|
+
|
|
93
|
+
- **Fix double-wrapping on multiple `run()` calls**. Calling `run()` twice in one test would wrap already-wrapped tools again, causing double-counted results and incorrect step numbers. The original tools are now captured once at session creation and reused on every `run()` call.
|
|
94
|
+
|
|
95
|
+
- **Fix block detection regression in `wrapForCollection`**. The `ToolBlockedError` class is thrown by the harness's own mock block path, but pi's native hook chain throws a plain `Error` with a message. Block detection now uses a hybrid check (`instanceof ToolBlockedError` + message fallback) so both paths are correctly classified as blocks rather than test failures.
|
|
96
|
+
|
|
97
|
+
## 0.4.1
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- [`58693d2`](https://github.com/marcfargas/pi-test-harness/commit/58693d2bab91651fe647dffe740643ab3af13cbf) Thanks [@marcfargas](https://github.com/marcfargas)! - Address code review findings for v0.4.0 standalone release.
|
|
102
|
+
|
|
103
|
+
- **Breaking**: Remove deprecated `call()`/`say()` DSL aliases (use `calls()`/`says()` instead)
|
|
104
|
+
- Fix diagnostic messages to reference current `calls()`/`says()` API names
|
|
105
|
+
- Fix release workflow for npm Trusted Publishers (`--provenance`)
|
|
106
|
+
- Record all mock UI method calls for assertion consistency (`setFooter`, `setHeader`, etc.)
|
|
107
|
+
- Scope playbook `toolCallCounter` to factory closure for concurrency safety
|
|
108
|
+
- Add `verifySandboxInstall()` test suite (4 tests with dummy extension fixture)
|
|
109
|
+
- Update package description to mention all three test layers
|
|
110
|
+
|
|
111
|
+
## 0.4.0
|
|
112
|
+
|
|
113
|
+
### Minor Changes
|
|
114
|
+
|
|
115
|
+
- [`688e5fa`](https://github.com/marcfargas/pi-mf-extensions/commit/688e5faa29a1c2673699d5e120b95b619e451ae6) Thanks [@marcfargas](https://github.com/marcfargas)! - Ship compiled `.js` + `.d.ts` output instead of raw TypeScript sources
|
|
116
|
+
|
|
117
|
+
Previously, the package shipped only `.ts` source files and relied on consumers having a TypeScript-aware loader (jiti, vitest). Node 24's `--experimental-strip-types` refuses to process `.ts` files inside `node_modules/`, making the package unusable with `node --test` or any Node-native test runner.
|
|
118
|
+
|
|
119
|
+
Now:
|
|
120
|
+
|
|
121
|
+
- Package exports point to pre-compiled `dist/index.js` (with `dist/index.d.ts` for types)
|
|
122
|
+
- Source `.ts` files are still included for debugging/source maps
|
|
123
|
+
- Build step (`tsc -p tsconfig.build.json`) runs automatically before publish via `prepublishOnly`
|
|
124
|
+
|
|
125
|
+
## 0.3.0
|
|
126
|
+
|
|
127
|
+
### Minor Changes
|
|
128
|
+
|
|
129
|
+
- Rename DSL: `call()` → `calls()`, `say()` → `says()`.
|
|
130
|
+
|
|
131
|
+
The new names read more naturally as playbook declarations:
|
|
132
|
+
`when("Deploy", [calls("bash", ...), says("Done.")])` reads as
|
|
133
|
+
"when prompted 'Deploy', the model calls bash then says 'Done.'"
|
|
134
|
+
|
|
135
|
+
The old `call()` and `say()` are kept as deprecated aliases (removal in v0.4).
|
|
136
|
+
|
|
137
|
+
## 0.2.0
|
|
138
|
+
|
|
139
|
+
### Minor Changes
|
|
140
|
+
|
|
141
|
+
- Initial release.
|
|
142
|
+
|
|
143
|
+
- Playbook DSL (`when`, `call`, `say`) for scripting agent conversations without LLM calls
|
|
144
|
+
- `createTestSession()` — creates real pi `AgentSession` with extension loading, hooks, and events
|
|
145
|
+
- Mock tool execution — intercept `tool.execute()` per-tool with static, dynamic, or full result handlers
|
|
146
|
+
- Mock UI context — configurable responses for `confirm`, `select`, `input`, `editor` with call recording
|
|
147
|
+
- Event collection — query helpers for tool calls, tool results, blocked calls, UI interactions, and messages
|
|
148
|
+
- Late-bound params and `.then()` callbacks for dynamic multi-step tool flows
|
|
149
|
+
- Playbook diagnostics — clear error messages on exhausted/unconsumed actions with step-level detail
|
|
150
|
+
- Error propagation control — abort on real tool throw (default) or capture as error results
|
|
151
|
+
- `verifySandboxInstall()` — npm pack → temp install → verify extensions and tools load correctly
|
|
152
|
+
|
|
153
|
+
### Patch Changes
|
|
154
|
+
|
|
155
|
+
- Fix mocked tools bypassing extension hooks (tool_call/tool_result).
|
|
156
|
+
|
|
157
|
+
- Mocked tools now fire `emitToolCall`/`emitToolResult` via the extension runner,
|
|
158
|
+
so extension blocking (e.g., plan mode) works correctly in tests
|
|
159
|
+
- Blocked tool results are recorded in `toolResults` before throwing
|
|
160
|
+
- `wrapForCollection` now propagates `isError` from real tool results (was hardcoded `false`)
|
|
161
|
+
- Hook-blocked tools no longer treated as test failures with `propagateErrors: true`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marc Fargas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|