@ikuma.cloud/pix-mcp 0.0.10 → 0.0.12
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 +3 -2
- package/package.json +1 -1
- package/src/index.ts +7 -6
- package/src/prompt-argument-input.ts +83 -0
package/README.md
CHANGED
|
@@ -301,8 +301,9 @@ commands behind:
|
|
|
301
301
|
|
|
302
302
|
In TUI mode, `/mcp-prompt` without arguments opens a native prompt selector
|
|
303
303
|
that shows the focused prompt's title and description, followed by native input
|
|
304
|
-
dialogs.
|
|
305
|
-
|
|
304
|
+
dialogs. Each dialog shows the argument description when the server provides
|
|
305
|
+
one. Required and optional arguments are requested in declaration order; leaving
|
|
306
|
+
an optional input empty omits it. The rendered prompt is placed in Pi's
|
|
306
307
|
editor so you can review or modify it before sending. Image blocks are stored in
|
|
307
308
|
private temporary files and inserted as `@` references. Escape cancels without
|
|
308
309
|
retrieving the prompt. The explicit `list` and `run` forms remain available in
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
formatResult,
|
|
26
26
|
removeEditablePromptGuard,
|
|
27
27
|
} from "./output.ts";
|
|
28
|
+
import { inputPromptArgument } from "./prompt-argument-input.ts";
|
|
28
29
|
import { pickPrompt } from "./prompt-picker.ts";
|
|
29
30
|
import { pickResource } from "./resource-picker.ts";
|
|
30
31
|
import {
|
|
@@ -457,14 +458,14 @@ export default function mcp(pi: ExtensionAPI) {
|
|
|
457
458
|
};
|
|
458
459
|
ensureCurrent();
|
|
459
460
|
|
|
460
|
-
const dialogOptions = ctx.signal ? { signal: ctx.signal } : undefined;
|
|
461
461
|
const argumentTokens: PromptArgumentToken[] = [];
|
|
462
462
|
for (const argument of item.prompt.arguments ?? []) {
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
argument.required ? "
|
|
466
|
-
|
|
467
|
-
|
|
463
|
+
const description = compact(argument.description ?? "", 160);
|
|
464
|
+
const value = await inputPromptArgument(ctx, {
|
|
465
|
+
label: `${argument.name} (${argument.required ? "required" : "optional"})`,
|
|
466
|
+
...(description ? { description } : {}),
|
|
467
|
+
guidance: argument.required ? "Enter a value" : "Leave empty to omit",
|
|
468
|
+
});
|
|
468
469
|
if (value === undefined) return;
|
|
469
470
|
ctx.signal?.throwIfAborted();
|
|
470
471
|
ensureCurrent();
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExtensionInputComponent,
|
|
3
|
+
type ExtensionCommandContext,
|
|
4
|
+
type Theme,
|
|
5
|
+
} from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import type { TUI } from "@earendil-works/pi-tui";
|
|
7
|
+
|
|
8
|
+
export interface PromptArgumentInputOptions {
|
|
9
|
+
label: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
guidance: string;
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class PromptArgumentInputComponent extends ExtensionInputComponent {
|
|
16
|
+
readonly #tui: TUI;
|
|
17
|
+
readonly #signal: AbortSignal | undefined;
|
|
18
|
+
readonly #onAbort: () => void;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
tui: TUI,
|
|
22
|
+
theme: Theme,
|
|
23
|
+
done: (value: string | undefined) => void,
|
|
24
|
+
options: PromptArgumentInputOptions,
|
|
25
|
+
) {
|
|
26
|
+
let finished = false;
|
|
27
|
+
const finish = (value: string | undefined) => {
|
|
28
|
+
if (finished) return;
|
|
29
|
+
finished = true;
|
|
30
|
+
done(value);
|
|
31
|
+
};
|
|
32
|
+
const details = [
|
|
33
|
+
...(options.description ? [theme.fg("dim", options.description)] : []),
|
|
34
|
+
theme.fg("muted", options.guidance),
|
|
35
|
+
].join("\n");
|
|
36
|
+
super(
|
|
37
|
+
options.label,
|
|
38
|
+
undefined,
|
|
39
|
+
(value) => finish(value),
|
|
40
|
+
() => finish(undefined),
|
|
41
|
+
{ tui, description: details },
|
|
42
|
+
);
|
|
43
|
+
this.#tui = tui;
|
|
44
|
+
this.#signal = options.signal;
|
|
45
|
+
this.#onAbort = () => finish(undefined);
|
|
46
|
+
options.signal?.addEventListener("abort", this.#onAbort, { once: true });
|
|
47
|
+
if (options.signal?.aborted) this.#onAbort();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override handleInput(data: string): void {
|
|
51
|
+
super.handleInput(data);
|
|
52
|
+
this.#tui.requestRender();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override dispose(): void {
|
|
56
|
+
this.#signal?.removeEventListener("abort", this.#onAbort);
|
|
57
|
+
super.dispose();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createPromptArgumentInput(
|
|
62
|
+
tui: TUI,
|
|
63
|
+
theme: Theme,
|
|
64
|
+
done: (value: string | undefined) => void,
|
|
65
|
+
options: PromptArgumentInputOptions,
|
|
66
|
+
): ExtensionInputComponent {
|
|
67
|
+
return new PromptArgumentInputComponent(tui, theme, done, options);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Pi 0.87.1's ctx.ui.input renders every title line as accent and ignores its
|
|
71
|
+
// placeholder. Reuse its native component through custom UI to style details.
|
|
72
|
+
export async function inputPromptArgument(
|
|
73
|
+
ctx: ExtensionCommandContext,
|
|
74
|
+
options: Omit<PromptArgumentInputOptions, "signal">,
|
|
75
|
+
): Promise<string | undefined> {
|
|
76
|
+
if (ctx.signal?.aborted) return;
|
|
77
|
+
return ctx.ui.custom<string | undefined>((tui, theme, _keybindings, done) =>
|
|
78
|
+
createPromptArgumentInput(tui, theme, done, {
|
|
79
|
+
...options,
|
|
80
|
+
...(ctx.signal ? { signal: ctx.signal } : {}),
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
}
|