pi-ui-extend 0.1.32 → 0.1.34
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 +1 -1
- package/dist/app/app.d.ts +2 -0
- package/dist/app/app.js +28 -0
- package/dist/app/commands/command-session-actions.js +29 -1
- package/dist/app/constants.d.ts +1 -1
- package/dist/app/constants.js +2 -2
- package/dist/app/icons.d.ts +4 -9
- package/dist/app/icons.js +12 -35
- package/dist/app/model/model-usage-status.d.ts +2 -1
- package/dist/app/model/model-usage-status.js +33 -25
- package/dist/app/rendering/conversation-entry-renderer.d.ts +1 -0
- package/dist/app/rendering/conversation-tool-renderer.d.ts +1 -0
- package/dist/app/rendering/conversation-tool-renderer.js +12 -18
- package/dist/app/rendering/conversation-viewport.d.ts +4 -0
- package/dist/app/rendering/conversation-viewport.js +144 -13
- package/dist/app/rendering/dcp-stats.js +42 -16
- package/dist/app/rendering/render-controller.js +4 -0
- package/dist/app/rendering/status-line-renderer.d.ts +8 -1
- package/dist/app/rendering/status-line-renderer.js +36 -1
- package/dist/app/rendering/tab-line-renderer.js +2 -2
- package/dist/app/rendering/tool-block-renderer.d.ts +1 -0
- package/dist/app/rendering/tool-block-renderer.js +37 -11
- package/dist/app/runtime.js +1 -1
- package/dist/app/screen/mouse-controller.d.ts +5 -1
- package/dist/app/screen/mouse-controller.js +16 -0
- package/dist/app/screen/scroll-controller.d.ts +20 -0
- package/dist/app/screen/scroll-controller.js +127 -10
- package/dist/app/session/lazy-session-manager.js +35 -5
- package/dist/app/session/pix-system-message.d.ts +1 -0
- package/dist/app/session/pix-system-message.js +14 -3
- package/dist/app/session/queued-message-controller.d.ts +11 -4
- package/dist/app/session/queued-message-controller.js +74 -59
- package/dist/app/session/queued-message-entries.d.ts +2 -1
- package/dist/app/session/queued-message-entries.js +12 -1
- package/dist/app/session/session-event-controller.d.ts +42 -1
- package/dist/app/session/session-event-controller.js +500 -31
- package/dist/app/session/session-history.js +23 -4
- package/dist/app/session/tabs-controller.d.ts +11 -1
- package/dist/app/session/tabs-controller.js +102 -21
- package/dist/app/types.d.ts +14 -1
- package/dist/bundled-extensions/question/contract.d.ts +25 -0
- package/dist/bundled-extensions/question/contract.js +94 -0
- package/dist/bundled-extensions/question/index.d.ts +7 -0
- package/dist/bundled-extensions/question/index.js +28 -0
- package/dist/bundled-extensions/question/render.d.ts +4 -0
- package/dist/bundled-extensions/question/render.js +27 -0
- package/dist/bundled-extensions/question/result.d.ts +6 -0
- package/dist/bundled-extensions/question/result.js +84 -0
- package/dist/bundled-extensions/question/tool-description.d.ts +7 -0
- package/dist/bundled-extensions/question/tool-description.js +11 -0
- package/dist/bundled-extensions/question/tui.d.ts +2 -0
- package/dist/bundled-extensions/question/tui.js +577 -0
- package/dist/bundled-extensions/question/types.d.ts +103 -0
- package/dist/bundled-extensions/question/types.js +1 -0
- package/dist/bundled-extensions/session-title/config.d.ts +17 -0
- package/dist/bundled-extensions/session-title/config.js +150 -0
- package/dist/bundled-extensions/session-title/index.d.ts +5 -0
- package/dist/bundled-extensions/session-title/index.js +384 -0
- package/dist/bundled-extensions/session-title/title-generation.d.ts +26 -0
- package/dist/bundled-extensions/session-title/title-generation.js +141 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +14 -0
- package/dist/bundled-extensions/terminal-bell/index.js +491 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -1
- package/dist/default-pix-config.js +2 -1
- package/dist/icon-theme.d.ts +7 -0
- package/dist/icon-theme.js +36 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +4 -0
- package/dist/schemas/pi-tools-suite-schema.js +5 -0
- package/dist/schemas/pix-schema.d.ts +1 -0
- package/dist/schemas/pix-schema.js +1 -0
- package/external/pi-tools-suite/README.md +7 -7
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +16 -16
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +18 -4
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +4 -0
- package/external/pi-tools-suite/src/async-subagents/tools/result.ts +14 -26
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +0 -1
- package/external/pi-tools-suite/src/dcp/config.ts +14 -14
- package/external/pi-tools-suite/src/dcp/index.ts +31 -43
- package/external/pi-tools-suite/src/dcp/state-persistence.ts +151 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +25 -18
- package/external/pi-tools-suite/src/tool-descriptions.ts +34 -54
- package/package.json +3 -2
- package/schemas/pi-tools-suite.json +14 -0
- package/schemas/pix.json +7 -0
- package/extensions/question/contract.ts +0 -100
- package/extensions/question/index.ts +0 -34
- package/extensions/question/render.ts +0 -28
- package/extensions/question/result.ts +0 -86
- package/extensions/question/tool-description.ts +0 -11
- package/extensions/question/tui.ts +0 -629
- package/extensions/question/types.ts +0 -123
- package/extensions/session-title/config.ts +0 -164
- package/extensions/session-title/index.ts +0 -502
- package/extensions/terminal-bell/index.ts +0 -345
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
2
|
+
import type { QuestionTheme, QuestionToolInput, QuestionToolResult } from "./types.js";
|
|
3
|
+
export declare function renderQuestionCall(args: Partial<QuestionToolInput>, theme: QuestionTheme): Text;
|
|
4
|
+
export declare function renderQuestionResult(result: Partial<QuestionToolResult>, theme: QuestionTheme, args?: Partial<QuestionToolInput>): Text;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Text, truncateToWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
export function renderQuestionCall(args, theme) {
|
|
3
|
+
const questions = Array.isArray(args.questions) ? args.questions : [];
|
|
4
|
+
const count = questions.length;
|
|
5
|
+
const labels = questions.map((question) => question?.label || question?.id).filter((label) => typeof label === "string" && label.length > 0).join(", ");
|
|
6
|
+
let text = theme.fg("toolTitle", (theme.bold ?? ((value) => value))("question "));
|
|
7
|
+
text += theme.fg("muted", `${count} question${count === 1 ? "" : "s"}`);
|
|
8
|
+
if (labels)
|
|
9
|
+
text += theme.fg("dim", ` (${truncateToWidth(labels, 48)})`);
|
|
10
|
+
return new Text(text, 0, 0);
|
|
11
|
+
}
|
|
12
|
+
export function renderQuestionResult(result, theme, args) {
|
|
13
|
+
const details = result.details;
|
|
14
|
+
if (!details) {
|
|
15
|
+
const firstContent = result.content?.[0];
|
|
16
|
+
return new Text(firstContent?.type === "text" ? firstContent.text : "", 0, 0);
|
|
17
|
+
}
|
|
18
|
+
if (details.canceled)
|
|
19
|
+
return new Text(theme.fg("warning", details.reason === "ui_unavailable" ? "Canceled: UI unavailable" : "Canceled"), 0, 0);
|
|
20
|
+
const labels = new Map((Array.isArray(args?.questions) ? args.questions : []).map((question) => [question.id, question.label]));
|
|
21
|
+
return new Text(details.answers.map((answer) => {
|
|
22
|
+
const questionLabel = labels.get(answer.id) ?? answer.id;
|
|
23
|
+
if (answer.wasCustom)
|
|
24
|
+
return `${theme.fg("success", "✓ ")}${theme.fg("accent", `${questionLabel}:`)} ${theme.fg("muted", "custom ")}${answer.label}`;
|
|
25
|
+
return `${theme.fg("success", "✓ ")}${theme.fg("accent", `${questionLabel}:`)} ${answer.index}. ${answer.label}`;
|
|
26
|
+
}).join("\n"), 0, 0);
|
|
27
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CanceledQuestionResult, NormalizedQuestion, QuestionResultDetails, QuestionSelection, QuestionToolResult, SuccessfulQuestionResult } from "./types.js";
|
|
2
|
+
export declare function createSuccessfulQuestionResult(questions: NormalizedQuestion[], selections: QuestionSelection[]): SuccessfulQuestionResult;
|
|
3
|
+
export declare function createCanceledQuestionResult(reason: CanceledQuestionResult["reason"], questions?: NormalizedQuestion[]): CanceledQuestionResult;
|
|
4
|
+
export declare function createFallbackPrompt(questions: NormalizedQuestion[]): string;
|
|
5
|
+
export declare function summarizeQuestionResult(result: QuestionResultDetails, questions?: NormalizedQuestion[]): string;
|
|
6
|
+
export declare function createQuestionToolResult(details: QuestionResultDetails, questions?: NormalizedQuestion[]): QuestionToolResult;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { throwInvalid } from "./contract.js";
|
|
2
|
+
export function createSuccessfulQuestionResult(questions, selections) {
|
|
3
|
+
const selectionsById = new Map(selections.map((selection) => [selection.id, selection]));
|
|
4
|
+
return {
|
|
5
|
+
answers: questions.map((question) => {
|
|
6
|
+
const selection = selectionsById.get(question.id);
|
|
7
|
+
if (!selection)
|
|
8
|
+
throwInvalid(`Missing answer for question "${question.id}".`, "Retry after collecting one answer for each normalized question.");
|
|
9
|
+
if ("customText" in selection) {
|
|
10
|
+
const customText = selection.customText.trim();
|
|
11
|
+
if (!customText)
|
|
12
|
+
throwInvalid(`Custom Answer for question "${question.id}" is empty after trimming.`, "Retry with non-empty Custom Answer text or choose a predefined Choice.");
|
|
13
|
+
return {
|
|
14
|
+
id: question.id,
|
|
15
|
+
value: customText,
|
|
16
|
+
label: customText,
|
|
17
|
+
wasCustom: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const choiceIndex = question.choices.findIndex((choice) => choice.value === selection.choiceValue);
|
|
21
|
+
if (choiceIndex === -1)
|
|
22
|
+
throwInvalid(`Question "${question.id}" has no predefined Choice with value "${selection.choiceValue}".`, "Retry with one of the normalized predefined Choice values for that question.");
|
|
23
|
+
const choice = question.choices[choiceIndex];
|
|
24
|
+
return {
|
|
25
|
+
id: question.id,
|
|
26
|
+
value: choice.value,
|
|
27
|
+
label: choice.label,
|
|
28
|
+
wasCustom: false,
|
|
29
|
+
index: choiceIndex + 1,
|
|
30
|
+
};
|
|
31
|
+
}),
|
|
32
|
+
canceled: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function createCanceledQuestionResult(reason, questions = []) {
|
|
36
|
+
return {
|
|
37
|
+
answers: [],
|
|
38
|
+
canceled: true,
|
|
39
|
+
reason,
|
|
40
|
+
...(reason === "ui_unavailable" && questions.length > 0 ? { fallbackPrompt: createFallbackPrompt(questions) } : {}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function createFallbackPrompt(questions) {
|
|
44
|
+
const lines = [
|
|
45
|
+
"Interactive UI is unavailable. Ask the user these structured questions in normal chat instead, then use the user's replies without inventing answers.",
|
|
46
|
+
];
|
|
47
|
+
questions.forEach((question, index) => {
|
|
48
|
+
lines.push("", `${index + 1}. ${question.label}: ${question.prompt}`);
|
|
49
|
+
question.choices.forEach((choice, choiceIndex) => {
|
|
50
|
+
const suffix = choice.description ? ` — ${choice.description}` : "";
|
|
51
|
+
lines.push(` ${choiceIndex + 1}. ${choice.label}${suffix}`);
|
|
52
|
+
});
|
|
53
|
+
lines.push(` ${question.choices.length + 1}. Something else… (custom answer)`);
|
|
54
|
+
});
|
|
55
|
+
return lines.join("\n");
|
|
56
|
+
}
|
|
57
|
+
export function summarizeQuestionResult(result, questions = []) {
|
|
58
|
+
if (result.canceled) {
|
|
59
|
+
if (result.reason === "ui_unavailable") {
|
|
60
|
+
return result.fallbackPrompt
|
|
61
|
+
? `No interactive UI is available, so question was canceled. Do not assume an answer. Ask the user in normal chat instead.\n\n${result.fallbackPrompt}`
|
|
62
|
+
: "No interactive UI is available, so question was canceled. Do not assume an answer.";
|
|
63
|
+
}
|
|
64
|
+
return "The user canceled question. Do not assume an answer.";
|
|
65
|
+
}
|
|
66
|
+
if (result.answers.length === 0)
|
|
67
|
+
return "question returned no answers.";
|
|
68
|
+
const questionLabels = new Map(questions.map((question) => [question.id, question.label]));
|
|
69
|
+
return `question answers: ${result.answers.map((answer) => {
|
|
70
|
+
const questionLabel = questionLabels.get(answer.id) ?? answer.id;
|
|
71
|
+
if (answer.wasCustom)
|
|
72
|
+
return `${questionLabel}: ${answer.label} (custom answer)`;
|
|
73
|
+
return `${questionLabel}: ${answer.label} (choice ${answer.index})`;
|
|
74
|
+
}).join("; ")}.`;
|
|
75
|
+
}
|
|
76
|
+
export function createQuestionToolResult(details, questions = []) {
|
|
77
|
+
return {
|
|
78
|
+
content: [{
|
|
79
|
+
type: "text",
|
|
80
|
+
text: summarizeQuestionResult(details, questions),
|
|
81
|
+
}],
|
|
82
|
+
details,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const QUESTION_TOOL_DESCRIPTION = {
|
|
2
|
+
name: "question",
|
|
3
|
+
label: "Question",
|
|
4
|
+
description: "Ask the user one to five structured questions, each with two to five choices plus an implicit custom answer path.",
|
|
5
|
+
promptSnippet: "Gather structured user feedback with predefined choices and an always-available custom answer path.",
|
|
6
|
+
promptGuidelines: [
|
|
7
|
+
"Use question when gathering user feedback, choosing between alternatives, confirming direction, or resolving ambiguity, as long as you can provide at least two meaningful choices.",
|
|
8
|
+
"question accepts 1–5 questions; each question needs 2–5 meaningful choices and automatically includes a custom answer path.",
|
|
9
|
+
"Do not use question when the user's input is purely open-ended or when a normal conversational reply is clearer.",
|
|
10
|
+
],
|
|
11
|
+
};
|