@xynogen/pix-toolbox 0.1.4 → 0.1.7
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/package.json +2 -2
- package/src/toolbox.test.ts +32 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-toolbox",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Pi tool — gated tool toggle UI (/toolbox)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@xynogen/pix-pretty": "
|
|
37
|
+
"@xynogen/pix-pretty": "^1.7.9"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@earendil-works/pi-coding-agent": "*",
|
package/src/toolbox.test.ts
CHANGED
|
@@ -41,7 +41,7 @@ describe("buildRows", () => {
|
|
|
41
41
|
|
|
42
42
|
test("flags MCP tools", () => {
|
|
43
43
|
const rows = buildRows([mcpToolInfo("ctx_search")]);
|
|
44
|
-
expect(rows[0].mcp).toBe(true);
|
|
44
|
+
expect((rows[0] as ToolRow).mcp).toBe(true);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
test("empty input returns empty", () => {
|
|
@@ -191,14 +191,20 @@ afterAll(() => {
|
|
|
191
191
|
function makeHost(toolNames: string[]) {
|
|
192
192
|
const handlers: Record<string, Array<(p: unknown) => unknown>> = {};
|
|
193
193
|
let active: string[] = [...toolNames];
|
|
194
|
-
const commands: Array<{
|
|
194
|
+
const commands: Array<{
|
|
195
|
+
name: string;
|
|
196
|
+
handler: (...args: unknown[]) => unknown;
|
|
197
|
+
}> = [];
|
|
195
198
|
const pi = {
|
|
196
199
|
on(ev: string, fn: (p: unknown) => unknown) {
|
|
197
|
-
(handlers[ev]
|
|
200
|
+
if (!handlers[ev]) handlers[ev] = [];
|
|
201
|
+
handlers[ev].push(fn);
|
|
198
202
|
},
|
|
199
203
|
emit(ev: string, payload: unknown, ctx?: unknown) {
|
|
200
204
|
return Promise.all(
|
|
201
|
-
(handlers[ev] ?? []).map((f) =>
|
|
205
|
+
(handlers[ev] ?? []).map((f) =>
|
|
206
|
+
(f as (...args: unknown[]) => unknown)(payload, ctx),
|
|
207
|
+
),
|
|
202
208
|
);
|
|
203
209
|
},
|
|
204
210
|
getAllTools() {
|
|
@@ -220,12 +226,19 @@ function makeHost(toolNames: string[]) {
|
|
|
220
226
|
},
|
|
221
227
|
appendEntry() {},
|
|
222
228
|
registerTool() {},
|
|
223
|
-
registerCommand(
|
|
229
|
+
registerCommand(
|
|
230
|
+
name: string,
|
|
231
|
+
def: { handler: (...args: unknown[]) => unknown },
|
|
232
|
+
) {
|
|
224
233
|
commands.push({ name, handler: def.handler });
|
|
225
234
|
},
|
|
226
235
|
} as never;
|
|
227
236
|
const emit = (ev: string, payload: unknown, ctx?: unknown) =>
|
|
228
|
-
Promise.all(
|
|
237
|
+
Promise.all(
|
|
238
|
+
(handlers[ev] ?? []).map((f) =>
|
|
239
|
+
(f as (...args: unknown[]) => unknown)(payload, ctx),
|
|
240
|
+
),
|
|
241
|
+
);
|
|
229
242
|
return {
|
|
230
243
|
pi,
|
|
231
244
|
emit,
|
|
@@ -247,6 +260,7 @@ function makeCtx() {
|
|
|
247
260
|
}
|
|
248
261
|
|
|
249
262
|
describe("/toolbox command", () => {
|
|
263
|
+
type Note = { text: string; level?: string };
|
|
250
264
|
const ALL = ["read", "write", "bash", "grep", "find"];
|
|
251
265
|
|
|
252
266
|
async function boot() {
|
|
@@ -268,28 +282,31 @@ describe("/toolbox command", () => {
|
|
|
268
282
|
await host.command("toolbox")?.handler("", ctx);
|
|
269
283
|
expect(notes.length).toBe(1);
|
|
270
284
|
// only non-core tools shown, all start active
|
|
271
|
-
|
|
272
|
-
expect(
|
|
285
|
+
const n0 = notes[0] as Note;
|
|
286
|
+
expect(n0.text).toContain("✓ active grep");
|
|
287
|
+
expect(n0.text).toContain("✓ active find");
|
|
273
288
|
// core tools excluded from toolbox
|
|
274
|
-
expect(
|
|
275
|
-
expect(
|
|
289
|
+
expect(n0.text).not.toContain(" read");
|
|
290
|
+
expect(n0.text).not.toContain(" bash");
|
|
276
291
|
});
|
|
277
292
|
|
|
278
293
|
test("/toolbox list shows non-core tools with status", async () => {
|
|
279
294
|
const host = await boot();
|
|
280
295
|
const { ctx, notes } = makeCtx();
|
|
281
296
|
await host.command("toolbox")?.handler("list", ctx);
|
|
282
|
-
|
|
283
|
-
expect(
|
|
284
|
-
expect(
|
|
297
|
+
const ln0 = notes[0] as Note;
|
|
298
|
+
expect(ln0.text).toContain("grep");
|
|
299
|
+
expect(ln0.text).toContain("find");
|
|
300
|
+
expect(ln0.text).not.toContain(" bash");
|
|
285
301
|
});
|
|
286
302
|
|
|
287
303
|
test("/toolbox list <query> filters", async () => {
|
|
288
304
|
const host = await boot();
|
|
289
305
|
const { ctx, notes } = makeCtx();
|
|
290
306
|
await host.command("toolbox")?.handler("list fin", ctx);
|
|
291
|
-
|
|
292
|
-
expect(
|
|
307
|
+
const fn0 = notes[0] as Note;
|
|
308
|
+
expect(fn0.text).toContain("find");
|
|
309
|
+
expect(fn0.text).not.toContain("✓ active read");
|
|
293
310
|
});
|
|
294
311
|
|
|
295
312
|
test("opens interactive picker when ctx.ui.custom exists", async () => {
|