@heyhuynhgiabuu/pi-pretty 0.5.3 → 0.6.1

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/src/types.ts ADDED
@@ -0,0 +1,227 @@
1
+ /**
2
+ * pi-pretty shared types.
3
+ */
4
+
5
+ import type { TextContent, ImageContent } from "@earendil-works/pi-ai";
6
+ import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
7
+
8
+ // ---------------------------------------------------------------------------
9
+ // Re-export FFF types needed by tools
10
+ // ---------------------------------------------------------------------------
11
+
12
+ export type { FileFinder, FileItem, GrepResult, SearchResult, GrepMatch, GrepCursor } from "@ff-labs/fff-node";
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Content / Result types
16
+ // ---------------------------------------------------------------------------
17
+
18
+ export type ToolContent = TextContent | ImageContent;
19
+ export type { TextContent, ImageContent };
20
+ // ---------------------------------------------------------------------------
21
+ // Theme / rendering context types
22
+ // ---------------------------------------------------------------------------
23
+
24
+ export interface ThemeLike {
25
+ fg: (key: string, text: string) => string;
26
+ bold: (text: string) => string;
27
+ getBgAnsi?: (key: string) => string;
28
+ }
29
+
30
+ export interface RenderCtxLike {
31
+ lastComponent?: ComponentLike;
32
+ isError?: boolean;
33
+ state: Record<string, string | undefined>;
34
+ expanded?: boolean;
35
+ }
36
+
37
+ export interface TextLike {
38
+ setText(v: string): void;
39
+ getText?(): string;
40
+ }
41
+
42
+ /** Minimal Component interface matching pi-tui's Component. */
43
+ export interface ComponentLike {
44
+ setText(v: string): void;
45
+ render(width: number): string[];
46
+ invalidate?(): void;
47
+ }
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Render detail types
51
+ // ---------------------------------------------------------------------------
52
+
53
+ export type ReadDetails =
54
+ | { _type: "readImage"; filePath: string; data: string; mimeType: string }
55
+ | { _type: "readFile"; filePath: string; content: string; offset: number; lineCount: number };
56
+
57
+ export interface BashDetails extends Record<string, unknown> {
58
+ _type: "bashResult";
59
+ text: string;
60
+ exitCode: number | null;
61
+ command: string;
62
+ }
63
+
64
+ export interface LsDetails extends Record<string, unknown> {
65
+ _type: "lsResult";
66
+ text: string;
67
+ path: string;
68
+ entryCount: number;
69
+ }
70
+
71
+ export interface FindDetails extends Record<string, unknown> {
72
+ _type: "findResult";
73
+ text: string;
74
+ pattern: string;
75
+ matchCount: number;
76
+ }
77
+
78
+ export interface GrepDetails extends Record<string, unknown> {
79
+ _type: "grepResult";
80
+ text: string;
81
+ pattern: string;
82
+ matchCount: number;
83
+ }
84
+
85
+ export type AnyDetails = ReadDetails | BashDetails | LsDetails | FindDetails | GrepDetails;
86
+
87
+ // ---------------------------------------------------------------------------
88
+ // Tool input types
89
+ // ---------------------------------------------------------------------------
90
+
91
+ export interface ReadInput {
92
+ path: string;
93
+ offset?: number;
94
+ limit?: number;
95
+ }
96
+
97
+ export interface BashInput {
98
+ command: string;
99
+ timeout?: number;
100
+ }
101
+
102
+ export interface LsInput {
103
+ path?: string;
104
+ }
105
+
106
+ export interface FindInput {
107
+ pattern: string;
108
+ path?: string;
109
+ limit?: number;
110
+ }
111
+
112
+ export interface GrepInput {
113
+ pattern: string;
114
+ path?: string;
115
+ glob?: string;
116
+ context?: number;
117
+ limit?: number;
118
+ literal?: boolean;
119
+ ignoreCase?: boolean;
120
+ }
121
+
122
+ export interface MultiGrepInput {
123
+ patterns: string[];
124
+ path?: string;
125
+ constraints?: string;
126
+ context?: number;
127
+ limit?: number;
128
+ }
129
+
130
+ // ---------------------------------------------------------------------------
131
+ // SDK tool definition shape (DI-friendly — accepts both mock and real SDK)
132
+ // ---------------------------------------------------------------------------
133
+
134
+ /**
135
+ * Minimal structural type for an SDK-produced tool definition.
136
+ * Accepts both the real SDK's ToolDefinition<> return type and test mocks.
137
+ */
138
+ export interface SdkToolDef {
139
+ name?: string;
140
+ description?: string;
141
+ label?: string;
142
+ parameters?: unknown;
143
+ execute: (...args: any[]) => Promise<AgentToolResult<any>>;
144
+ }
145
+
146
+ export interface SdkTools {
147
+ createReadTool?: (cwd: string) => SdkToolDef;
148
+ createBashTool?: (cwd: string) => SdkToolDef;
149
+ createLsTool?: (cwd: string) => SdkToolDef;
150
+ createFindTool?: (cwd: string) => SdkToolDef;
151
+ createGrepTool?: (cwd: string) => SdkToolDef;
152
+ getAgentDir?: () => string;
153
+ }
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // Multi-grep fallback types
157
+ // ---------------------------------------------------------------------------
158
+
159
+ export interface MultiGrepFallbackParams {
160
+ cwd: string;
161
+ patterns: string[];
162
+ path?: string;
163
+ constraints?: string;
164
+ context?: number;
165
+ limit: number;
166
+ ignoreCase: boolean;
167
+ signal?: AbortSignal;
168
+ }
169
+
170
+ export interface MultiGrepFallbackResult {
171
+ text: string;
172
+ matchCount: number;
173
+ limitReached: boolean;
174
+ }
175
+
176
+ export type MultiGrepFallback = (params: MultiGrepFallbackParams) => Promise<MultiGrepFallbackResult>;
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // FFF service interfaces
180
+ // ---------------------------------------------------------------------------
181
+
182
+ /** Minimal FFF service shape for tools that only need fileSearch. */
183
+ export interface FffServiceLike {
184
+ readonly isAvailable: boolean;
185
+ readonly partialIndex: boolean;
186
+ getFinder(): import("@ff-labs/fff-node").FileFinder | null;
187
+ }
188
+
189
+ /** Full FFF service for grep tools that also need cursor store. */
190
+ export interface FffServiceWithCursor extends FffServiceLike {
191
+ getCursorStore(): CursorStore;
192
+ }
193
+
194
+ /** FFF lifecycle interface (used by session lifecycle code). */
195
+ export interface FffService extends FffServiceWithCursor {
196
+ ensureFinder(cwd: string): Promise<void>;
197
+ destroy(): void;
198
+ isModuleLoaded(): boolean;
199
+ tryLoadModule(): Promise<boolean>;
200
+ }
201
+
202
+ export interface CursorStore {
203
+ store(cursor: unknown): string;
204
+ get(id: string): unknown | undefined;
205
+ }
206
+
207
+ // ---------------------------------------------------------------------------
208
+ // Constraint parsing
209
+ // ---------------------------------------------------------------------------
210
+
211
+ export interface ConstraintParseResult {
212
+ ok: boolean;
213
+ globs: string[];
214
+ tokens: string[];
215
+ error?: string;
216
+ }
217
+
218
+ // ---------------------------------------------------------------------------
219
+ // DI
220
+ // ---------------------------------------------------------------------------
221
+
222
+ export interface PiPrettyDeps {
223
+ sdk?: SdkTools;
224
+ TextComponent?: new (text?: string, x?: number, y?: number) => ComponentLike;
225
+ fffModule?: typeof import("@ff-labs/fff-node");
226
+ multiGrepRipgrepFallback?: MultiGrepFallback;
227
+ }
@@ -184,7 +184,7 @@ describe("bash renderCall expansion", () => {
184
184
  });
185
185
 
186
186
  const lines = stripAnsi(rendered.getText()).split("\n");
187
- expect(lines[0]).toMatch(/^bash false/);
187
+ expect(lines[1]).toMatch(/^ bash false/);
188
188
  });
189
189
  });
190
190
 
@@ -215,7 +215,7 @@ describe("bash renderCall expansion", () => {
215
215
  });
216
216
  });
217
217
 
218
- it("does not emit internal ANSI background padding or resets for bash results", () => {
218
+ it("applies tool background correctly to bash results without unnecessary resets", () => {
219
219
  withStdoutColumns(64, () => {
220
220
  const bashTool = loadBashTool();
221
221
  const rendered = bashTool.renderResult(
@@ -234,7 +234,7 @@ describe("bash renderCall expansion", () => {
234
234
  },
235
235
  );
236
236
 
237
- expect(rendered.getText()).not.toMatch(/\x1b\[48;/);
237
+ expect(rendered.getText()).toMatch(/\x1b\[48;/); // tool background is applied
238
238
  expect(rendered.getText()).not.toContain("\x1b[0m");
239
239
  expect(rendered.getText()).not.toContain("\x1b[49m");
240
240
  for (const line of rendered.getText().split("\n")) {