@hheei/pi-ext-ui 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +6 -2
- package/dist/apply-patch-glyph.d.ts +10 -0
- package/dist/apply-patch-glyph.js +29 -0
- package/dist/apply-patch-preview.d.ts +30 -0
- package/dist/apply-patch-preview.js +89 -0
- package/dist/apply-patch-view.d.ts +47 -0
- package/dist/apply-patch-view.js +198 -0
- package/dist/collapsible-tool-frame.d.ts +1 -0
- package/dist/collapsible-tool-frame.js +1 -0
- package/dist/diff-view.d.ts +46 -0
- package/dist/diff-view.js +184 -0
- package/dist/extension.d.ts +2 -0
- package/dist/extension.js +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/renderer.d.ts +42 -0
- package/dist/renderer.js +1274 -0
- package/dist/tool-view.d.ts +53 -0
- package/dist/tool-view.js +270 -0
- package/dist/turn-copy.d.ts +11 -0
- package/dist/turn-copy.js +20 -0
- package/package.json +49 -5
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type Component, type TuiMouseEvent, type TuiMouseEventResult } from "@earendil-works/pi-tui";
|
|
3
|
+
export type FoldLevel = 0 | 1 | 2;
|
|
4
|
+
export type ToolStatusKind = "streaming" | "running" | "ok" | "warn" | "error" | "none";
|
|
5
|
+
export type RailColorToken = "muted" | "dim" | "accent" | "success" | "warning" | "error";
|
|
6
|
+
export interface RailSection {
|
|
7
|
+
readonly railToken: RailColorToken;
|
|
8
|
+
readonly content: string | readonly string[] | Component;
|
|
9
|
+
readonly maxLines?: number | undefined;
|
|
10
|
+
}
|
|
11
|
+
export interface ToolViewHeaderSpec {
|
|
12
|
+
readonly title: string;
|
|
13
|
+
readonly status?: ToolStatusKind | undefined;
|
|
14
|
+
readonly summary?: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
export interface ToolViewCopySpec {
|
|
17
|
+
readonly primary: string;
|
|
18
|
+
readonly full?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export interface ToolViewSpec {
|
|
21
|
+
readonly theme: Theme;
|
|
22
|
+
readonly header: ToolViewHeaderSpec;
|
|
23
|
+
readonly collapsedRows?: readonly string[] | Component | undefined;
|
|
24
|
+
readonly sections?: readonly RailSection[] | undefined;
|
|
25
|
+
readonly copy?: ToolViewCopySpec | undefined;
|
|
26
|
+
readonly stateHolder?: unknown;
|
|
27
|
+
readonly outputPad?: number | undefined;
|
|
28
|
+
readonly defaultLevel?: FoldLevel | undefined;
|
|
29
|
+
readonly globalExpanded?: boolean | undefined;
|
|
30
|
+
readonly invalidate?: (() => void) | undefined;
|
|
31
|
+
readonly copyToClipboard?: ((text: string) => Promise<void>) | undefined;
|
|
32
|
+
readonly copyFeedbackDurationMs?: number | undefined;
|
|
33
|
+
}
|
|
34
|
+
/** Public composition entry point for extensions that need the shared view behavior. */
|
|
35
|
+
export declare function createToolView(spec: ToolViewSpec): ToolView;
|
|
36
|
+
export declare function transitionFoldLevel(current: FoldLevel, ctrlKey: boolean): FoldLevel;
|
|
37
|
+
export declare class ToolView implements Component {
|
|
38
|
+
#private;
|
|
39
|
+
constructor(spec: ToolViewSpec);
|
|
40
|
+
get foldLevel(): FoldLevel;
|
|
41
|
+
get effectiveLevel(): FoldLevel;
|
|
42
|
+
get collapsed(): boolean;
|
|
43
|
+
setFoldLevel(next: FoldLevel): void;
|
|
44
|
+
setCollapsed(collapsed: boolean): void;
|
|
45
|
+
toggle(ctrlKey?: boolean): void;
|
|
46
|
+
/** The result renderer of the same tool execution hides this row in place. */
|
|
47
|
+
hide(): void;
|
|
48
|
+
render(width: number): string[];
|
|
49
|
+
handleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined;
|
|
50
|
+
invalidate(): void;
|
|
51
|
+
}
|
|
52
|
+
export type { ToolViewSpec as CollapsibleToolFrameOptions };
|
|
53
|
+
export { ToolView as CollapsibleToolFrame };
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { copyToClipboard as copyToSystemClipboard, } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
3
|
+
/** Public composition entry point for extensions that need the shared view behavior. */
|
|
4
|
+
export function createToolView(spec) {
|
|
5
|
+
return new ToolView(spec);
|
|
6
|
+
}
|
|
7
|
+
const FOLD_LEVEL_STATE_KEY = "__piExtUiFoldLevel";
|
|
8
|
+
const COPIED_UNTIL_STATE_KEY = "__piExtUiCopiedUntil";
|
|
9
|
+
const COPY_FEEDBACK_TIMER_KEY = "__piExtUiCopyTimer";
|
|
10
|
+
const DEFAULT_MAX_SECTION_LINES = 9;
|
|
11
|
+
const DEFAULT_MAX_COLLAPSED_ROWS = 6;
|
|
12
|
+
const DEFAULT_COPY_FEEDBACK_MS = 1200;
|
|
13
|
+
function isRecord(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
export function transitionFoldLevel(current, ctrlKey) {
|
|
17
|
+
if (current === 0) {
|
|
18
|
+
return ctrlKey ? 2 : 1;
|
|
19
|
+
}
|
|
20
|
+
if (current === 1) {
|
|
21
|
+
return ctrlKey ? 2 : 0;
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
function readFoldLevel(stateHolder, fallback) {
|
|
26
|
+
if (!isRecord(stateHolder))
|
|
27
|
+
return fallback;
|
|
28
|
+
const raw = stateHolder[FOLD_LEVEL_STATE_KEY];
|
|
29
|
+
return raw === 0 || raw === 1 || raw === 2 ? raw : fallback;
|
|
30
|
+
}
|
|
31
|
+
function writeFoldLevel(stateHolder, level) {
|
|
32
|
+
if (!isRecord(stateHolder))
|
|
33
|
+
return;
|
|
34
|
+
stateHolder[FOLD_LEVEL_STATE_KEY] = level;
|
|
35
|
+
}
|
|
36
|
+
function isCopiedActive(stateHolder, localCopiedUntil) {
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
if (localCopiedUntil > now)
|
|
39
|
+
return true;
|
|
40
|
+
if (!isRecord(stateHolder))
|
|
41
|
+
return false;
|
|
42
|
+
const until = stateHolder[COPIED_UNTIL_STATE_KEY];
|
|
43
|
+
return typeof until === "number" && until > now;
|
|
44
|
+
}
|
|
45
|
+
function formatStatusGlyph(status, theme) {
|
|
46
|
+
switch (status ?? "ok") {
|
|
47
|
+
case "streaming":
|
|
48
|
+
return `${theme.fg("muted", "⋯")} `;
|
|
49
|
+
case "running":
|
|
50
|
+
return `${theme.fg("accent", "◐")} `;
|
|
51
|
+
case "ok":
|
|
52
|
+
return `${theme.fg("success", "✓")} `;
|
|
53
|
+
case "warn":
|
|
54
|
+
return `${theme.fg("warning", "!")} `;
|
|
55
|
+
case "error":
|
|
56
|
+
return `${theme.fg("error", "✗")} `;
|
|
57
|
+
case "none":
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const truncate = (text, width) => truncateToWidth(text, width, "…");
|
|
62
|
+
function resolveLines(source, width) {
|
|
63
|
+
if (typeof source === "string") {
|
|
64
|
+
return source === "" ? [] : source.replace(/\r/g, "").replace(/\t/g, " ").split("\n");
|
|
65
|
+
}
|
|
66
|
+
if (Array.isArray(source)) {
|
|
67
|
+
return source.flatMap((item) => typeof item === "string" ? item.replace(/\r/g, "").replace(/\t/g, " ").split("\n") : []);
|
|
68
|
+
}
|
|
69
|
+
return source.render(width);
|
|
70
|
+
}
|
|
71
|
+
export class ToolView {
|
|
72
|
+
#spec;
|
|
73
|
+
#localLevel;
|
|
74
|
+
#localCopiedUntil = 0;
|
|
75
|
+
#localTimer;
|
|
76
|
+
#lastWidth = 80;
|
|
77
|
+
constructor(spec) {
|
|
78
|
+
this.#spec = spec;
|
|
79
|
+
const initial = spec.defaultLevel ?? 0;
|
|
80
|
+
this.#localLevel = readFoldLevel(spec.stateHolder, initial);
|
|
81
|
+
}
|
|
82
|
+
get foldLevel() {
|
|
83
|
+
return readFoldLevel(this.#spec.stateHolder, this.#localLevel);
|
|
84
|
+
}
|
|
85
|
+
get effectiveLevel() {
|
|
86
|
+
const base = this.foldLevel;
|
|
87
|
+
if (base === 0)
|
|
88
|
+
return 0;
|
|
89
|
+
if (this.#spec.globalExpanded === true)
|
|
90
|
+
return 2;
|
|
91
|
+
return base;
|
|
92
|
+
}
|
|
93
|
+
get collapsed() {
|
|
94
|
+
return this.foldLevel === 0;
|
|
95
|
+
}
|
|
96
|
+
setFoldLevel(next) {
|
|
97
|
+
const prev = this.foldLevel;
|
|
98
|
+
this.#localLevel = next;
|
|
99
|
+
writeFoldLevel(this.#spec.stateHolder, next);
|
|
100
|
+
if (prev !== next) {
|
|
101
|
+
this.#spec.invalidate?.();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
setCollapsed(collapsed) {
|
|
105
|
+
this.setFoldLevel(collapsed ? 0 : 1);
|
|
106
|
+
}
|
|
107
|
+
toggle(ctrlKey = false) {
|
|
108
|
+
this.setFoldLevel(transitionFoldLevel(this.foldLevel, ctrlKey));
|
|
109
|
+
}
|
|
110
|
+
#triggerCopy(shiftKey) {
|
|
111
|
+
const copySpec = this.#spec.copy;
|
|
112
|
+
if (copySpec === undefined)
|
|
113
|
+
return;
|
|
114
|
+
const payload = shiftKey && copySpec.full !== undefined && copySpec.full !== ""
|
|
115
|
+
? copySpec.full
|
|
116
|
+
: copySpec.primary;
|
|
117
|
+
const writeClip = this.#spec.copyToClipboard ?? copyToSystemClipboard;
|
|
118
|
+
const durationMs = this.#spec.copyFeedbackDurationMs ?? DEFAULT_COPY_FEEDBACK_MS;
|
|
119
|
+
const until = Date.now() + durationMs;
|
|
120
|
+
this.#localCopiedUntil = until;
|
|
121
|
+
if (isRecord(this.#spec.stateHolder)) {
|
|
122
|
+
const prevTimer = this.#spec.stateHolder[COPY_FEEDBACK_TIMER_KEY];
|
|
123
|
+
if (prevTimer !== undefined) {
|
|
124
|
+
clearTimeout(prevTimer);
|
|
125
|
+
}
|
|
126
|
+
this.#spec.stateHolder[COPIED_UNTIL_STATE_KEY] = until;
|
|
127
|
+
}
|
|
128
|
+
if (this.#localTimer !== undefined) {
|
|
129
|
+
clearTimeout(this.#localTimer);
|
|
130
|
+
}
|
|
131
|
+
void writeClip(payload).catch(() => { });
|
|
132
|
+
this.#spec.invalidate?.();
|
|
133
|
+
const timer = setTimeout(() => {
|
|
134
|
+
this.#localCopiedUntil = 0;
|
|
135
|
+
if (isRecord(this.#spec.stateHolder)) {
|
|
136
|
+
this.#spec.stateHolder[COPIED_UNTIL_STATE_KEY] = 0;
|
|
137
|
+
this.#spec.stateHolder[COPY_FEEDBACK_TIMER_KEY] = undefined;
|
|
138
|
+
}
|
|
139
|
+
this.#localTimer = undefined;
|
|
140
|
+
this.#spec.invalidate?.();
|
|
141
|
+
}, durationMs);
|
|
142
|
+
timer.unref?.();
|
|
143
|
+
this.#localTimer = timer;
|
|
144
|
+
if (isRecord(this.#spec.stateHolder)) {
|
|
145
|
+
this.#spec.stateHolder[COPY_FEEDBACK_TIMER_KEY] = timer;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
#renderHeader(width, level) {
|
|
149
|
+
const { theme, header, copy } = this.#spec;
|
|
150
|
+
const safeWidth = Math.max(1, width);
|
|
151
|
+
const pinGlyph = level === 0 ? "▸" : "▾";
|
|
152
|
+
const pin = theme.fg("dim", pinGlyph);
|
|
153
|
+
const statusPart = formatStatusGlyph(header.status, theme);
|
|
154
|
+
const titlePart = theme.fg("toolTitle", theme.bold(header.title));
|
|
155
|
+
const summaryRaw = header.summary?.trim() ?? "";
|
|
156
|
+
const summaryPart = summaryRaw === "" ? "" : ` ${theme.fg("dim", summaryRaw)}`;
|
|
157
|
+
const leftContent = `${pin} ${statusPart}${titlePart}${summaryPart}`;
|
|
158
|
+
if (copy === undefined || safeWidth < 6) {
|
|
159
|
+
return truncate(leftContent, safeWidth);
|
|
160
|
+
}
|
|
161
|
+
const copied = isCopiedActive(this.#spec.stateHolder, this.#localCopiedUntil);
|
|
162
|
+
const copyIcon = copied ? theme.fg("success", "✓") : theme.fg("dim", "");
|
|
163
|
+
// Leave 1 column on the right for Pi's fullscreen scrollbar so the copy icon doesn't collide
|
|
164
|
+
const rightMargin = 1;
|
|
165
|
+
const copySlotWidth = 2 + rightMargin;
|
|
166
|
+
const maxLeftWidth = Math.max(1, safeWidth - copySlotWidth);
|
|
167
|
+
const truncatedLeft = truncate(leftContent, maxLeftWidth);
|
|
168
|
+
const leftVis = visibleWidth(truncatedLeft);
|
|
169
|
+
const gap = " ".repeat(Math.max(1, safeWidth - leftVis - rightMargin - 1));
|
|
170
|
+
return truncate(truncatedLeft + gap + copyIcon + " ".repeat(rightMargin), safeWidth);
|
|
171
|
+
}
|
|
172
|
+
#hidden = false;
|
|
173
|
+
/** The result renderer of the same tool execution hides this row in place. */
|
|
174
|
+
hide() {
|
|
175
|
+
this.#hidden = true;
|
|
176
|
+
}
|
|
177
|
+
render(width) {
|
|
178
|
+
if (this.#hidden)
|
|
179
|
+
return [];
|
|
180
|
+
const pad = Math.max(0, this.#spec.outputPad ?? 0);
|
|
181
|
+
const safeWidth = Math.max(1, width - pad * 2);
|
|
182
|
+
this.#lastWidth = width;
|
|
183
|
+
const level = this.effectiveLevel;
|
|
184
|
+
const { theme, collapsedRows, sections } = this.#spec;
|
|
185
|
+
const output = [this.#renderHeader(safeWidth, level)];
|
|
186
|
+
const finalize = (lines) => {
|
|
187
|
+
if (pad > 0) {
|
|
188
|
+
const leftPad = " ".repeat(pad);
|
|
189
|
+
return lines.map((line) => `${leftPad}${line}`);
|
|
190
|
+
}
|
|
191
|
+
return lines;
|
|
192
|
+
};
|
|
193
|
+
const innerWidth = Math.max(1, safeWidth - 2);
|
|
194
|
+
if (level === 0) {
|
|
195
|
+
if (collapsedRows !== undefined) {
|
|
196
|
+
const rail = `${theme.fg("dim", "▎")} `;
|
|
197
|
+
const rows = resolveLines(collapsedRows, innerWidth);
|
|
198
|
+
const visibleRows = rows.length > DEFAULT_MAX_COLLAPSED_ROWS
|
|
199
|
+
? rows.slice(0, DEFAULT_MAX_COLLAPSED_ROWS)
|
|
200
|
+
: rows;
|
|
201
|
+
for (const row of visibleRows) {
|
|
202
|
+
output.push(truncate(rail + row, safeWidth));
|
|
203
|
+
}
|
|
204
|
+
if (rows.length > visibleRows.length) {
|
|
205
|
+
const hint = theme.fg("dim", `… (${String(rows.length - visibleRows.length)} more)`);
|
|
206
|
+
output.push(truncate(rail + hint, safeWidth));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return finalize(output);
|
|
210
|
+
}
|
|
211
|
+
if (sections === undefined || sections.length === 0) {
|
|
212
|
+
return finalize(output);
|
|
213
|
+
}
|
|
214
|
+
for (const section of sections) {
|
|
215
|
+
const rail = `${theme.fg(section.railToken, "▎")} `;
|
|
216
|
+
const rawLines = resolveLines(section.content, innerWidth);
|
|
217
|
+
const cap = level === 1 ? (section.maxLines ?? DEFAULT_MAX_SECTION_LINES) : Number.POSITIVE_INFINITY;
|
|
218
|
+
const visibleLines = Number.isFinite(cap) && rawLines.length > cap ? rawLines.slice(0, cap) : rawLines;
|
|
219
|
+
const omittedCount = rawLines.length - visibleLines.length;
|
|
220
|
+
for (const line of visibleLines) {
|
|
221
|
+
output.push(truncate(rail + line, safeWidth));
|
|
222
|
+
}
|
|
223
|
+
if (omittedCount > 0) {
|
|
224
|
+
const hint = theme.fg("dim", `… (${String(omittedCount)} more lines)`);
|
|
225
|
+
output.push(truncate(rail + hint, safeWidth));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return finalize(output);
|
|
229
|
+
}
|
|
230
|
+
handleMouse(event) {
|
|
231
|
+
if (event.type === "wheel") {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
if (event.type !== "click" || event.button !== "left" || event.y !== 0) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
const effectiveWidth = event.width > 0 ? event.width : this.#lastWidth;
|
|
238
|
+
const pad = Math.max(0, this.#spec.outputPad ?? 0);
|
|
239
|
+
const innerX = event.x - pad;
|
|
240
|
+
const innerWidth = Math.max(1, effectiveWidth - pad * 2);
|
|
241
|
+
if (innerX < 0 || innerX >= innerWidth) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
if (this.#spec.copy !== undefined &&
|
|
245
|
+
innerWidth >= 6 &&
|
|
246
|
+
innerX >= innerWidth - 3 &&
|
|
247
|
+
innerX < innerWidth - 1) {
|
|
248
|
+
this.#triggerCopy(event.shift === true);
|
|
249
|
+
return { handled: true, render: true };
|
|
250
|
+
}
|
|
251
|
+
this.toggle(event.ctrl === true);
|
|
252
|
+
return { handled: true, render: true };
|
|
253
|
+
}
|
|
254
|
+
invalidate() {
|
|
255
|
+
const { collapsedRows, sections } = this.#spec;
|
|
256
|
+
if (collapsedRows !== undefined &&
|
|
257
|
+
typeof collapsedRows === "object" &&
|
|
258
|
+
"invalidate" in collapsedRows) {
|
|
259
|
+
collapsedRows.invalidate();
|
|
260
|
+
}
|
|
261
|
+
if (sections !== undefined) {
|
|
262
|
+
for (const section of sections) {
|
|
263
|
+
if (typeof section.content === "object" && "invalidate" in section.content) {
|
|
264
|
+
section.content.invalidate();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
export { ToolView as CollapsibleToolFrame };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TurnToolCallSummary {
|
|
2
|
+
readonly toolName: string;
|
|
3
|
+
readonly commandOrArgs?: string | undefined;
|
|
4
|
+
readonly summary: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TurnFlowData {
|
|
7
|
+
readonly userPrompt: string;
|
|
8
|
+
readonly toolCalls?: readonly TurnToolCallSummary[] | undefined;
|
|
9
|
+
readonly assistantReply: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function formatTurnFlow(data: TurnFlowData): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { stripTerminalSequences } from "@earendil-works/pi-tui";
|
|
2
|
+
export function formatTurnFlow(data) {
|
|
3
|
+
const blocks = [];
|
|
4
|
+
const cleanUser = stripTerminalSequences(data.userPrompt).trim();
|
|
5
|
+
blocks.push(`[User]\n${cleanUser}`);
|
|
6
|
+
if (data.toolCalls !== undefined && data.toolCalls.length > 0) {
|
|
7
|
+
const toolLines = [];
|
|
8
|
+
for (const call of data.toolCalls) {
|
|
9
|
+
const header = call.commandOrArgs !== undefined && call.commandOrArgs.trim() !== ""
|
|
10
|
+
? `${call.toolName} ${stripTerminalSequences(call.commandOrArgs).trim()}`
|
|
11
|
+
: call.toolName;
|
|
12
|
+
const detail = stripTerminalSequences(call.summary).trim();
|
|
13
|
+
toolLines.push(detail !== "" ? `${header}\n${detail}` : header);
|
|
14
|
+
}
|
|
15
|
+
blocks.push(`[Tools]\n${toolLines.join("\n\n")}`);
|
|
16
|
+
}
|
|
17
|
+
const cleanAssistant = stripTerminalSequences(data.assistantReply).trim();
|
|
18
|
+
blocks.push(`[Assistant]\n${cleanAssistant}`);
|
|
19
|
+
return blocks.join("\n\n");
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@hheei/pi-ext-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Collapsible tool rendering frame and tool renderer pilot for Pi.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"pi": {
|
|
17
|
+
"extensions": [
|
|
18
|
+
"dist/extension.js"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json",
|
|
23
|
+
"prepack": "pnpm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"pi",
|
|
27
|
+
"pi-package",
|
|
28
|
+
"pi-extension",
|
|
29
|
+
"hepi",
|
|
30
|
+
"ui",
|
|
31
|
+
"collapsible"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/hheei/hepi-mono.git",
|
|
37
|
+
"directory": "packages/pi-ext-ui"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@earendil-works/pi-coding-agent": ">=1.0.0",
|
|
44
|
+
"@earendil-works/pi-tui": ">=1.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
48
|
+
"@earendil-works/pi-tui": "1.1.0"
|
|
49
|
+
}
|
|
50
|
+
}
|