@fungi.computer/parakeet-testing 0.1.4 → 0.2.1
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/dist/index.d.ts +29 -0
- package/dist/index.js +164 -0
- package/docs/api/README.md +50 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SessionActivity, SessionExtensionSlots } from "@fungi.computer/shiitake/client";
|
|
2
2
|
import { type Json } from "@fungi.computer/shiitake/extensions";
|
|
3
|
+
import type { WhistlePrompt } from "@fungi.computer/whistle";
|
|
3
4
|
import type { WhistleCatalogV1 } from "@fungi.computer/whistle/catalog";
|
|
4
5
|
/** Activity facts for a Session with nothing queued or running. */
|
|
5
6
|
export declare const idleActivity: SessionActivity;
|
|
@@ -40,3 +41,31 @@ export declare const slashParityFlow: {
|
|
|
40
41
|
readonly choose: "Fern bed";
|
|
41
42
|
readonly notice: "Watered the fern bed.";
|
|
42
43
|
};
|
|
44
|
+
/** The state of one decision a fixture holds, shaped like the Parakeet reducer's. */
|
|
45
|
+
export type AwaitingFixtureState = Readonly<{
|
|
46
|
+
highlight: number;
|
|
47
|
+
toggled: ReadonlySet<string>;
|
|
48
|
+
other: string;
|
|
49
|
+
phase: "choose" | "other" | "confirm" | "sending" | "refused";
|
|
50
|
+
refusal?: string;
|
|
51
|
+
details: boolean;
|
|
52
|
+
}>;
|
|
53
|
+
/** One decision shown at one moment, held identically by every renderer's test. */
|
|
54
|
+
export type AwaitingFixture = Readonly<{
|
|
55
|
+
/** What the fixture shows, for test names. */
|
|
56
|
+
name: string;
|
|
57
|
+
kind: "question" | "approval";
|
|
58
|
+
prompt: Extract<WhistlePrompt, {
|
|
59
|
+
type: "decision";
|
|
60
|
+
}>;
|
|
61
|
+
state: AwaitingFixtureState;
|
|
62
|
+
/** One-based place among all waiting decisions. */
|
|
63
|
+
position: number;
|
|
64
|
+
/** Every waiting decision. */
|
|
65
|
+
total: number;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* The decisions every renderer must draw the same way. Each Parakeet renderer
|
|
69
|
+
* renders every fixture and holds its output to `decisionView`.
|
|
70
|
+
*/
|
|
71
|
+
export declare const awaitingFixtures: readonly AwaitingFixture[];
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseExtensionJson, } from "@fungi.computer/shiitake/extensions";
|
|
2
|
+
import { parsePrompt } from "@fungi.computer/whistle/wire";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
/** Activity facts for a Session with nothing queued or running. */
|
|
4
5
|
export const idleActivity = {
|
|
@@ -125,3 +126,166 @@ export const slashParityFlow = {
|
|
|
125
126
|
choose: "Fern bed",
|
|
126
127
|
notice: "Watered the fern bed.",
|
|
127
128
|
};
|
|
129
|
+
function decision(input) {
|
|
130
|
+
const prompt = parsePrompt({ type: "decision", ...input });
|
|
131
|
+
if (prompt.type !== "decision")
|
|
132
|
+
throw new Error("Expected a decision prompt");
|
|
133
|
+
return prompt;
|
|
134
|
+
}
|
|
135
|
+
const storage = decision({
|
|
136
|
+
message: "Which store should hold the notes?",
|
|
137
|
+
options: [
|
|
138
|
+
{
|
|
139
|
+
value: "SQLite",
|
|
140
|
+
label: "SQLite",
|
|
141
|
+
description: "Keep notes on this computer.",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
value: "PostgreSQL",
|
|
145
|
+
label: "PostgreSQL",
|
|
146
|
+
description: "Use the shared database.",
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
other: {
|
|
150
|
+
label: "Other…",
|
|
151
|
+
placeholder: "Write your own answer",
|
|
152
|
+
maxLength: 4_000,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
const deliverables = decision({
|
|
156
|
+
message: "Which deliverables should ship?",
|
|
157
|
+
summary: "Question 1 of 2",
|
|
158
|
+
options: [
|
|
159
|
+
{ value: "Docs", label: "Docs", description: "Explain usage." },
|
|
160
|
+
{ value: "Tests", label: "Tests", description: "Verify behavior." },
|
|
161
|
+
{ value: "Examples", label: "Examples", description: "Show it working." },
|
|
162
|
+
],
|
|
163
|
+
multiple: true,
|
|
164
|
+
other: {
|
|
165
|
+
label: "Other…",
|
|
166
|
+
placeholder: "Write your own answer",
|
|
167
|
+
maxLength: 4_000,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
const approval = decision({
|
|
171
|
+
message: "Allow `git add hello.js`?",
|
|
172
|
+
summary: "Research Agent wants to run this outside the sandbox, as you.",
|
|
173
|
+
facts: [
|
|
174
|
+
{ label: "Folder", value: "~/src/garden" },
|
|
175
|
+
{ label: "Why", value: "“Git metadata is read-only”" },
|
|
176
|
+
],
|
|
177
|
+
options: [
|
|
178
|
+
{ value: "approve", label: "Approve once" },
|
|
179
|
+
{ value: "always", label: "Always allow “git add” in this project…" },
|
|
180
|
+
{ value: "deny", label: "Deny" },
|
|
181
|
+
],
|
|
182
|
+
other: {
|
|
183
|
+
label: "Deny and say why…",
|
|
184
|
+
placeholder: "A short reason for the Agent (optional)",
|
|
185
|
+
maxLength: 512,
|
|
186
|
+
blank: "deny",
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
const confirmation = decision({
|
|
190
|
+
message: "Always allow “git add” in this project?",
|
|
191
|
+
summary: "Git hooks in this project can run code as you, and this Agent can add hooks.",
|
|
192
|
+
body: "Any Workspace Agent here can then run `git add …` without asking.",
|
|
193
|
+
options: [
|
|
194
|
+
{ value: "back", label: "Back" },
|
|
195
|
+
{ value: "always-allow", label: "Always allow “git add” and run it now" },
|
|
196
|
+
],
|
|
197
|
+
escape: "back",
|
|
198
|
+
});
|
|
199
|
+
const start = {
|
|
200
|
+
highlight: 0,
|
|
201
|
+
toggled: new Set(),
|
|
202
|
+
other: "",
|
|
203
|
+
phase: "choose",
|
|
204
|
+
details: false,
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* The decisions every renderer must draw the same way. Each Parakeet renderer
|
|
208
|
+
* renders every fixture and holds its output to `decisionView`.
|
|
209
|
+
*/
|
|
210
|
+
export const awaitingFixtures = [
|
|
211
|
+
{
|
|
212
|
+
name: "single",
|
|
213
|
+
kind: "question",
|
|
214
|
+
prompt: storage,
|
|
215
|
+
state: start,
|
|
216
|
+
position: 1,
|
|
217
|
+
total: 1,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "multiple toggled",
|
|
221
|
+
kind: "question",
|
|
222
|
+
prompt: deliverables,
|
|
223
|
+
state: { ...start, highlight: 2, toggled: new Set(["Docs", "Examples"]) },
|
|
224
|
+
position: 1,
|
|
225
|
+
total: 1,
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
name: "other typing",
|
|
229
|
+
kind: "question",
|
|
230
|
+
prompt: storage,
|
|
231
|
+
state: { ...start, highlight: 2, other: "MySQL", phase: "other" },
|
|
232
|
+
position: 1,
|
|
233
|
+
total: 1,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
name: "2 of 3",
|
|
237
|
+
kind: "question",
|
|
238
|
+
prompt: storage,
|
|
239
|
+
state: { ...start, highlight: 1 },
|
|
240
|
+
position: 2,
|
|
241
|
+
total: 3,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: "sending",
|
|
245
|
+
kind: "question",
|
|
246
|
+
prompt: storage,
|
|
247
|
+
state: { ...start, phase: "sending" },
|
|
248
|
+
position: 1,
|
|
249
|
+
total: 1,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: "refused",
|
|
253
|
+
kind: "question",
|
|
254
|
+
prompt: storage,
|
|
255
|
+
state: {
|
|
256
|
+
...start,
|
|
257
|
+
phase: "refused",
|
|
258
|
+
refusal: "That question is already closed.",
|
|
259
|
+
},
|
|
260
|
+
position: 1,
|
|
261
|
+
total: 1,
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "approval",
|
|
265
|
+
kind: "approval",
|
|
266
|
+
prompt: approval,
|
|
267
|
+
state: start,
|
|
268
|
+
position: 1,
|
|
269
|
+
total: 1,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "approval confirm",
|
|
273
|
+
kind: "approval",
|
|
274
|
+
prompt: confirmation,
|
|
275
|
+
state: start,
|
|
276
|
+
position: 1,
|
|
277
|
+
total: 2,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: "approval refused",
|
|
281
|
+
kind: "approval",
|
|
282
|
+
prompt: approval,
|
|
283
|
+
state: {
|
|
284
|
+
...start,
|
|
285
|
+
phase: "refused",
|
|
286
|
+
refusal: "This request changed. Look again before answering.",
|
|
287
|
+
},
|
|
288
|
+
position: 1,
|
|
289
|
+
total: 1,
|
|
290
|
+
},
|
|
291
|
+
];
|
package/docs/api/README.md
CHANGED
|
@@ -19,6 +19,45 @@ type SlashParityCase = Readonly<{
|
|
|
19
19
|
|
|
20
20
|
One input every renderer must complete identically.
|
|
21
21
|
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### AwaitingFixtureState
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
type AwaitingFixtureState = Readonly<{
|
|
28
|
+
highlight: number;
|
|
29
|
+
toggled: ReadonlySet<string>;
|
|
30
|
+
other: string;
|
|
31
|
+
phase: "choose" | "other" | "confirm" | "sending" | "refused";
|
|
32
|
+
refusal?: string;
|
|
33
|
+
details: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The state of one decision a fixture holds, shaped like the Parakeet reducer's.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### AwaitingFixture
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
type AwaitingFixture = Readonly<{
|
|
45
|
+
name: string;
|
|
46
|
+
kind: "question" | "approval";
|
|
47
|
+
prompt: Extract<
|
|
48
|
+
WhistlePrompt,
|
|
49
|
+
{
|
|
50
|
+
type: "decision";
|
|
51
|
+
}
|
|
52
|
+
>;
|
|
53
|
+
state: AwaitingFixtureState;
|
|
54
|
+
position: number;
|
|
55
|
+
total: number;
|
|
56
|
+
}>;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
One decision shown at one moment, held identically by every renderer's test.
|
|
60
|
+
|
|
22
61
|
## Variables
|
|
23
62
|
|
|
24
63
|
### idleActivity
|
|
@@ -81,6 +120,17 @@ The flow every renderer runs: `/water`, choose the fern bed, see the result.
|
|
|
81
120
|
| <a id="property-choose"></a> `choose` | `"Fern bed"` | `"Fern bed"` |
|
|
82
121
|
| <a id="property-notice"></a> `notice` | `"Watered the fern bed."` | `"Watered the fern bed."` |
|
|
83
122
|
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### awaitingFixtures
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const awaitingFixtures: readonly AwaitingFixture[];
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The decisions every renderer must draw the same way. Each Parakeet renderer
|
|
132
|
+
renders every fixture and holds its output to `decisionView`.
|
|
133
|
+
|
|
84
134
|
## Functions
|
|
85
135
|
|
|
86
136
|
### queuedActivity()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/parakeet-testing",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"author": "Levi <levi@technomancy.dev>",
|
|
5
5
|
"description": "Test-only garden extension and slash-parity fixtures for a typed Shiitake Session, shared by every Parakeet-protocol renderer's tests",
|
|
6
6
|
"type": "module",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@fungi.computer/shiitake": "0.
|
|
23
|
-
"@fungi.computer/whistle": "0.
|
|
22
|
+
"@fungi.computer/shiitake": "0.7.0",
|
|
23
|
+
"@fungi.computer/whistle": "0.3.0",
|
|
24
24
|
"zod": "4.4.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|