@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.
Files changed (2) hide show
  1. package/package.json +2 -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.4",
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": "*",
@@ -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<{ name: string; handler: Function }> = [];
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] ??= []).push(fn);
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) => (f as Function)(payload, ctx)),
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(name: string, def: { handler: Function }) {
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((handlers[ev] ?? []).map((f) => (f as Function)(payload, ctx)));
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
- expect(notes[0].text).toContain("✓ active grep");
272
- expect(notes[0].text).toContain("✓ active find");
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(notes[0].text).not.toContain(" read");
275
- expect(notes[0].text).not.toContain(" bash");
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
- expect(notes[0].text).toContain("grep");
283
- expect(notes[0].text).toContain("find");
284
- expect(notes[0].text).not.toContain(" bash");
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
- expect(notes[0].text).toContain("find");
292
- expect(notes[0].text).not.toContain("✓ active read");
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 () => {