@heyhuynhgiabuu/pi-pretty 0.6.16 → 0.6.17

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 (76) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +6 -16
  3. package/dist/config.d.ts +1 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +61 -18
  6. package/dist/config.js.map +1 -1
  7. package/dist/expand.d.ts +0 -6
  8. package/dist/expand.d.ts.map +1 -1
  9. package/dist/expand.js +0 -13
  10. package/dist/expand.js.map +1 -1
  11. package/dist/image.js +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +18 -21
  15. package/dist/index.js.map +1 -1
  16. package/dist/render.d.ts +3 -5
  17. package/dist/render.d.ts.map +1 -1
  18. package/dist/render.js +9 -9
  19. package/dist/render.js.map +1 -1
  20. package/dist/tools/bash.d.ts +1 -1
  21. package/dist/tools/bash.d.ts.map +1 -1
  22. package/dist/tools/bash.js +18 -23
  23. package/dist/tools/bash.js.map +1 -1
  24. package/dist/tools/find.d.ts +2 -2
  25. package/dist/tools/find.d.ts.map +1 -1
  26. package/dist/tools/find.js +12 -8
  27. package/dist/tools/find.js.map +1 -1
  28. package/dist/tools/grep.d.ts +2 -2
  29. package/dist/tools/grep.d.ts.map +1 -1
  30. package/dist/tools/grep.js +5 -5
  31. package/dist/tools/grep.js.map +1 -1
  32. package/dist/tools/labels.d.ts +2 -0
  33. package/dist/tools/labels.d.ts.map +1 -0
  34. package/dist/tools/labels.js +7 -0
  35. package/dist/tools/labels.js.map +1 -0
  36. package/dist/tools/ls.d.ts +1 -1
  37. package/dist/tools/ls.d.ts.map +1 -1
  38. package/dist/tools/ls.js +1 -1
  39. package/dist/tools/ls.js.map +1 -1
  40. package/dist/tools/read.d.ts +1 -1
  41. package/dist/tools/read.d.ts.map +1 -1
  42. package/dist/tools/read.js +22 -40
  43. package/dist/tools/read.js.map +1 -1
  44. package/dist/tui-text.d.ts.map +1 -1
  45. package/dist/tui-text.js +1 -5
  46. package/dist/tui-text.js.map +1 -1
  47. package/dist/types.d.ts +3 -27
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +3 -3
  50. package/src/collapsed-hint.ts +1 -1
  51. package/src/config.ts +67 -22
  52. package/src/expand.ts +0 -14
  53. package/src/find-glob.ts +1 -1
  54. package/src/image.ts +1 -1
  55. package/src/index.ts +25 -34
  56. package/src/notices.ts +1 -1
  57. package/src/render.ts +37 -35
  58. package/src/tools/bash.ts +24 -48
  59. package/src/tools/find.ts +22 -36
  60. package/src/tools/grep.ts +12 -15
  61. package/src/tools/labels.ts +3 -0
  62. package/src/tools/ls.ts +16 -10
  63. package/src/tools/metrics.ts +1 -1
  64. package/src/tools/read.ts +39 -59
  65. package/src/tui-text.ts +1 -5
  66. package/src/types.ts +3 -35
  67. package/dist/multi-grep-fallback.d.ts +0 -30
  68. package/dist/multi-grep-fallback.d.ts.map +0 -1
  69. package/dist/multi-grep-fallback.js +0 -205
  70. package/dist/multi-grep-fallback.js.map +0 -1
  71. package/dist/tools/multi-grep.d.ts +0 -7
  72. package/dist/tools/multi-grep.d.ts.map +0 -1
  73. package/dist/tools/multi-grep.js +0 -298
  74. package/dist/tools/multi-grep.js.map +0 -1
  75. package/src/multi-grep-fallback.ts +0 -248
  76. package/src/tools/multi-grep.ts +0 -339
@@ -1 +1 @@
1
- {"version":3,"file":"tui-text.d.ts","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,KAAK,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK;IAAE,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC;AA8B3G;;;GAGG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAE7D"}
1
+ {"version":3,"file":"tui-text.d.ts","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,KAAK,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK;IAAE,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAC;AA0B3G;;;GAGG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAE7D"}
package/dist/tui-text.js CHANGED
@@ -13,10 +13,6 @@ exports.getTextCtor = getTextCtor;
13
13
  exports.resolveTextCtor = resolveTextCtor;
14
14
  /** No-op stub that satisfies the Text interface so rendering doesn't crash. */
15
15
  class StubText {
16
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
- constructor(_t, _x, _y) {
18
- // no-op
19
- }
20
16
  setText(_v) {
21
17
  // no-op — pi-tui not available
22
18
  }
@@ -24,7 +20,7 @@ class StubText {
24
20
  let _ctor = null;
25
21
  let _resolved = false;
26
22
  function resolve() {
27
- if (_resolved)
23
+ if (_ctor)
28
24
  return _ctor;
29
25
  _resolved = true;
30
26
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"tui-text.js","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAqCH,kCAEC;AAMD,0CAEC;AA1CD,+EAA+E;AAC/E,MAAM,QAAQ;IACb,6DAA6D;IAC7D,YAAY,EAAW,EAAE,EAAW,EAAE,EAAW;QAChD,QAAQ;IACT,CAAC;IACD,OAAO,CAAC,EAAU;QACjB,+BAA+B;IAChC,CAAC;CACD;AAED,IAAI,KAAK,GAAoB,IAAI,CAAC;AAClC,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,OAAO;IACf,IAAI,SAAS;QAAE,OAAO,KAAM,CAAC;IAC7B,SAAS,GAAG,IAAI,CAAC;IACjB,IAAI,CAAC;QACJ,8DAA8D;QAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAuB,CAAC;QACzE,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,KAAK,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACR,KAAK,GAAG,QAAQ,CAAC;QACjB,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW;IAC1B,OAAO,OAAO,EAAE,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,QAAmB;IAClD,OAAO,QAAQ,IAAI,OAAO,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"tui-text.js","sourceRoot":"","sources":["../src/tui-text.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAiCH,kCAEC;AAMD,0CAEC;AAtCD,+EAA+E;AAC/E,MAAM,QAAQ;IACb,OAAO,CAAC,EAAU;QACjB,+BAA+B;IAChC,CAAC;CACD;AAED,IAAI,KAAK,GAAoB,IAAI,CAAC;AAClC,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,SAAS,OAAO;IACf,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,SAAS,GAAG,IAAI,CAAC;IACjB,IAAI,CAAC;QACJ,8DAA8D;QAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,wBAAwB,CAAuB,CAAC;QACzE,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,KAAK,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACR,KAAK,GAAG,QAAQ,CAAC;QACjB,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW;IAC1B,OAAO,OAAO,EAAE,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,QAAmB;IAClD,OAAO,QAAQ,IAAI,OAAO,EAAE,CAAC;AAC9B,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * pi-pretty shared types.
3
3
  */
4
- import type { TextContent, ImageContent } from "@earendil-works/pi-ai";
4
+ import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
5
5
  import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
6
- export type { FileFinder, FileItem, GrepResult, SearchResult, GrepMatch, GrepCursor } from "@ff-labs/fff-node";
6
+ export type { FileFinder, FileItem, GrepCursor, GrepMatch, GrepResult, SearchResult } from "@ff-labs/fff-node";
7
7
  export type ToolContent = TextContent | ImageContent;
8
- export type { TextContent, ImageContent };
8
+ export type { ImageContent, TextContent };
9
9
  export interface ThemeLike {
10
10
  fg: (key: string, text: string) => string;
11
11
  bold: (text: string) => string;
@@ -91,13 +91,6 @@ export interface GrepInput {
91
91
  literal?: boolean;
92
92
  ignoreCase?: boolean;
93
93
  }
94
- export interface MultiGrepInput {
95
- patterns: string[];
96
- path?: string;
97
- constraints?: string;
98
- context?: number;
99
- limit?: number;
100
- }
101
94
  /**
102
95
  * Minimal structural type for an SDK-produced tool definition.
103
96
  * Accepts both the real SDK's ToolDefinition<> return type and test mocks.
@@ -117,22 +110,6 @@ export interface SdkTools {
117
110
  createGrepTool?: (cwd: string) => SdkToolDef;
118
111
  getAgentDir?: () => string;
119
112
  }
120
- export interface MultiGrepFallbackParams {
121
- cwd: string;
122
- patterns: string[];
123
- path?: string;
124
- constraints?: string;
125
- context?: number;
126
- limit: number;
127
- ignoreCase: boolean;
128
- signal?: AbortSignal;
129
- }
130
- export interface MultiGrepFallbackResult {
131
- text: string;
132
- matchCount: number;
133
- limitReached: boolean;
134
- }
135
- export type MultiGrepFallback = (params: MultiGrepFallbackParams) => Promise<MultiGrepFallbackResult>;
136
113
  /** Minimal FFF service shape for tools that only need fileSearch. */
137
114
  export interface FffServiceLike {
138
115
  readonly isAvailable: boolean;
@@ -164,6 +141,5 @@ export interface PiPrettyDeps {
164
141
  sdk?: SdkTools;
165
142
  TextComponent?: new (text?: string, x?: number, y?: number) => ComponentLike;
166
143
  fffModule?: typeof import("@ff-labs/fff-node");
167
- multiGrepRipgrepFallback?: MultiGrepFallback;
168
144
  }
169
145
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAMvE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM/G,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AACrD,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAK1C,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC7B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACxB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,IAAI,MAAM,CAAC;CACnB;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,UAAU,CAAC,IAAI,IAAI,CAAC;CACpB;AAMD,MAAM,MAAM,WAAW,GACpB;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/F,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzD,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC;AAM3F,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAMD;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,QAAQ;IACxB,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;IAC7C,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;IAC3C,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;CAC3B;AAMD,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAMtG,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,SAAS,IAAI,OAAO,mBAAmB,EAAE,UAAU,GAAG,IAAI,CAAC;CAC3D;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC3D,cAAc,IAAI,WAAW,CAAC;CAC9B;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACvD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC;IAChB,cAAc,IAAI,OAAO,CAAC;IAC1B,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC3B,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACrC;AAMD,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,YAAY;IAC5B,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,aAAa,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,aAAa,CAAC;IAC7E,SAAS,CAAC,EAAE,cAAc,mBAAmB,CAAC,CAAC;IAC/C,wBAAwB,CAAC,EAAE,iBAAiB,CAAC;CAC7C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyhuynhgiabuu/pi-pretty",
3
- "version": "0.6.16",
3
+ "version": "0.6.17",
4
4
  "description": "Pretty terminal output for pi — syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.",
5
5
  "keywords": [
6
6
  "pi",
@@ -42,8 +42,8 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@biomejs/biome": "^2.3.5",
45
- "@earendil-works/pi-ai": "^0.80.0",
46
- "@earendil-works/pi-coding-agent": "^0.80.3",
45
+ "@earendil-works/pi-ai": "^0.80.6",
46
+ "@earendil-works/pi-coding-agent": "^0.80.6",
47
47
  "@earendil-works/pi-tui": "*",
48
48
  "@types/node": "^20.0.0",
49
49
  "typescript": "^5.0.0",
@@ -11,4 +11,4 @@ export function collapsedExpandBlock(countLabel: string): string {
11
11
  /** When line count / metrics already appear on the header line (bash). */
12
12
  export function collapsedExpandFooter(): string {
13
13
  return `${TOOL_RESULT_INDENT}${FG_DIM}${COLLAPSED_EXPAND_LABEL}${RST}\n`;
14
- }
14
+ }
package/src/config.ts CHANGED
@@ -13,7 +13,6 @@ import { basename, extname, join } from "node:path";
13
13
  export const TOOL_RESULT_INDENT = " ";
14
14
 
15
15
  export let RST = "\x1b[0m";
16
- const BOLD = "\x1b[1m";
17
16
 
18
17
  export const FG_LNUM = "\x1b[38;2;100;100;100m";
19
18
  export const FG_DIM = "\x1b[38;2;80;80;80m";
@@ -32,9 +31,10 @@ export let BG_ERROR = BG_DEFAULT;
32
31
  // Theme
33
32
  // ---------------------------------------------------------------------------
34
33
 
35
- import type { ThemeLike } from "./types.js";
36
-
37
- type BgThemeLike = { getBgAnsi?: (key: string) => string };
34
+ type BgThemeLike = {
35
+ getBgAnsi?: (key: string) => string;
36
+ bg?: (key: string, text: string) => string;
37
+ };
38
38
 
39
39
  const ESC_RE = "\u001b";
40
40
 
@@ -45,8 +45,14 @@ function parseAnsiRgb(ansi: string): { r: number; g: number; b: number } | null
45
45
 
46
46
  function getThemeBgAnsi(theme: BgThemeLike, key: string): string | null {
47
47
  try {
48
- const bgAnsi = theme.getBgAnsi?.(key);
49
- return bgAnsi && parseAnsiRgb(bgAnsi) ? bgAnsi : null;
48
+ const direct = theme.getBgAnsi?.(key);
49
+ if (direct && parseAnsiRgb(direct)) return direct;
50
+
51
+ const marker = "\0";
52
+ const styled = theme.bg?.(key, marker);
53
+ const markerIndex = styled?.indexOf(marker) ?? -1;
54
+ const ansi = markerIndex > 0 ? styled?.slice(0, markerIndex) : null;
55
+ return ansi && parseAnsiRgb(ansi) ? ansi : null;
50
56
  } catch {
51
57
  return null;
52
58
  }
@@ -105,8 +111,12 @@ export function resolveBaseBackground(theme: BgThemeLike | null | undefined): vo
105
111
  const home = process.env.HOME;
106
112
  const configDir = process.env.PRETTY_CONFIG_DIR ?? (home ? join(home, ".pi/agent") : undefined);
107
113
  if (applyPrettyConfigBg(configDir)) return;
108
- if (!theme?.getBgAnsi) return;
109
- BG_BASE = getThemeBgAnsi(theme, "toolSuccessBg") ?? getThemeBgAnsi(theme, "toolBg") ?? getThemeBgAnsi(theme, "background") ?? BG_DEFAULT;
114
+ if (!theme?.getBgAnsi && !theme?.bg) return;
115
+ BG_BASE =
116
+ getThemeBgAnsi(theme, "toolSuccessBg") ??
117
+ getThemeBgAnsi(theme, "toolBg") ??
118
+ getThemeBgAnsi(theme, "background") ??
119
+ BG_DEFAULT;
110
120
  BG_ERROR = getThemeBgAnsi(theme, "toolErrorBg") ?? BG_BASE;
111
121
  RST = "\x1b[0m";
112
122
  }
@@ -117,8 +127,10 @@ export function resolveBaseBackground(theme: BgThemeLike | null | undefined): vo
117
127
 
118
128
  export function termWidth(): number {
119
129
  if (process.stdout.columns) return Math.max(1, Math.min(process.stdout.columns, 210));
120
- const raw = (process.stderr as NodeJS.WriteStream & { columns?: number }).columns ||
121
- Number.parseInt(process.env.COLUMNS ?? "", 10) || 200;
130
+ const raw =
131
+ (process.stderr as NodeJS.WriteStream & { columns?: number }).columns ||
132
+ Number.parseInt(process.env.COLUMNS ?? "", 10) ||
133
+ 200;
122
134
  return Math.max(1, Math.min(raw - 4, 210));
123
135
  }
124
136
 
@@ -209,18 +221,51 @@ export function dirIcon(): string {
209
221
  import type { BundledLanguage } from "shiki";
210
222
 
211
223
  const EXT_LANG: Record<string, BundledLanguage> = {
212
- ts: "typescript", tsx: "tsx", js: "javascript", jsx: "jsx",
213
- mjs: "javascript", cjs: "javascript",
214
- py: "python", rb: "ruby", rs: "rust", go: "go", java: "java",
215
- c: "c", cpp: "cpp", h: "c", hpp: "cpp",
216
- cs: "csharp", swift: "swift", kt: "kotlin",
217
- html: "html", css: "css", scss: "scss", less: "css",
218
- json: "json", jsonc: "jsonc", yaml: "yaml", yml: "yaml",
219
- toml: "toml", md: "markdown", mdx: "mdx", sql: "sql",
220
- sh: "bash", bash: "bash", zsh: "bash", lua: "lua", php: "php",
221
- dart: "dart", xml: "xml", graphql: "graphql", svelte: "svelte", vue: "vue",
222
- dockerfile: "dockerfile", makefile: "make",
223
- zig: "zig", nim: "nim", elixir: "elixir",
224
+ ts: "typescript",
225
+ tsx: "tsx",
226
+ js: "javascript",
227
+ jsx: "jsx",
228
+ mjs: "javascript",
229
+ cjs: "javascript",
230
+ py: "python",
231
+ rb: "ruby",
232
+ rs: "rust",
233
+ go: "go",
234
+ java: "java",
235
+ c: "c",
236
+ cpp: "cpp",
237
+ h: "c",
238
+ hpp: "cpp",
239
+ cs: "csharp",
240
+ swift: "swift",
241
+ kt: "kotlin",
242
+ html: "html",
243
+ css: "css",
244
+ scss: "scss",
245
+ less: "css",
246
+ json: "json",
247
+ jsonc: "jsonc",
248
+ yaml: "yaml",
249
+ yml: "yaml",
250
+ toml: "toml",
251
+ md: "markdown",
252
+ mdx: "mdx",
253
+ sql: "sql",
254
+ sh: "bash",
255
+ bash: "bash",
256
+ zsh: "bash",
257
+ lua: "lua",
258
+ php: "php",
259
+ dart: "dart",
260
+ xml: "xml",
261
+ graphql: "graphql",
262
+ svelte: "svelte",
263
+ vue: "vue",
264
+ dockerfile: "dockerfile",
265
+ makefile: "make",
266
+ zig: "zig",
267
+ nim: "nim",
268
+ elixir: "elixir",
224
269
  };
225
270
 
226
271
  export function detectLang(fp: string): BundledLanguage | undefined {
package/src/expand.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
1
  import { MAX_PREVIEW_LINES } from "./config.js";
3
2
 
4
3
  /** Render context from pi tool UI (Ctrl+O toggles `expanded` per tool block). */
@@ -9,16 +8,3 @@ export function previewLineCount(ctx: ToolRenderCtx, totalLines: number): number
9
8
  if (ctx.expanded) return totalLines;
10
9
  return Math.min(totalLines, MAX_PREVIEW_LINES);
11
10
  }
12
-
13
- /**
14
- * Default tool output to collapsed so body content is hidden until Ctrl+O (app.tools.expand).
15
- * Matches Pi keybinding `app.tools.expand` / `app.tools.expandAll` (see pi.dev/docs keybindings).
16
- */
17
- export function registerDefaultCollapsedToolOutput(pi: ExtensionAPI): void {
18
- pi.on("session_start", (_event, ctx) => {
19
- // Pi interactive mode: default new tool blocks collapsed (Ctrl+O toggles per block).
20
- (ctx as { setConfig?: (c: { toolOutputExpanded?: boolean }) => void }).setConfig?.({
21
- toolOutputExpanded: false,
22
- });
23
- });
24
- }
package/src/find-glob.ts CHANGED
@@ -18,4 +18,4 @@ export function isLikelyGlobPattern(pattern: string): boolean {
18
18
  const p = pattern.trim();
19
19
  if (!p) return false;
20
20
  return /[*?[\]]/.test(p) || p === "**/*" || p.startsWith("**/");
21
- }
21
+ }
package/src/image.ts CHANGED
@@ -96,7 +96,7 @@ function tmuxAllowsPassthrough(): boolean | null {
96
96
  function getTmuxPassthroughWarning(protocol: ImageProtocol): string | null {
97
97
  if (!isTmuxSession() || protocol === "none") return null;
98
98
  if (tmuxAllowsPassthrough() === false) {
99
- return 'tmux allow-passthrough is off. Run: tmux set -g allow-passthrough on';
99
+ return "tmux allow-passthrough is off. Run: tmux set -g allow-passthrough on";
100
100
  }
101
101
  return null;
102
102
  }
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * pi-pretty — Pretty terminal output for pi built-in tools.
3
3
  *
4
- * Enhances read, bash, ls, find, grep, multi_grep with:
4
+ * Enhances read, bash, ls, find, and grep with:
5
5
  * • Syntax-highlighted file content (Shiki)
6
6
  * • Colored bash exit status + output
7
7
  * • Tree-view directory listings with file-type icons
@@ -12,30 +12,28 @@
12
12
  // Re-export for tests
13
13
  export { __imageInternals } from "./image.js";
14
14
 
15
- import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
16
-
17
- import type { PiPrettyDeps } from "./types.js";
18
- import { getSharedFffService, type FffService } from "./fff.js";
19
- import { registerReadTool } from "./tools/read.js";
15
+ import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@earendil-works/pi-coding-agent";
16
+ import { createFffAutocompleteProvider } from "./autocomplete.js";
17
+ import { getDefaultAgentDir } from "./config.js";
18
+ import { type FffService, getSharedFffService } from "./fff.js";
20
19
  import { registerBashTool } from "./tools/bash.js";
21
- import { registerLsTool } from "./tools/ls.js";
22
20
  import { registerFindTool } from "./tools/find.js";
23
21
  import { registerGrepTool } from "./tools/grep.js";
24
- import { registerMultiGrepTool } from "./tools/multi-grep.js";
25
- import { runMultiGrepRipgrepFallback } from "./multi-grep-fallback.js";
26
- import { getDefaultAgentDir } from "./config.js";
27
- import { createFffAutocompleteProvider } from "./autocomplete.js";
28
- import { registerDefaultCollapsedToolOutput } from "./expand.js";
22
+ import { registerLsTool } from "./tools/ls.js";
23
+ import { registerReadTool } from "./tools/read.js";
24
+ import type { PiPrettyDeps } from "./types.js";
29
25
 
30
26
  // ---------------------------------------------------------------------------
31
27
  // Config
32
28
  // ---------------------------------------------------------------------------
33
29
 
34
- function envDisabledTools(): Set<string> {
30
+ const DEFAULT_DISABLED_TOOLS = new Set(["ls"]);
31
+
32
+ function envTools(name: "PRETTY_DISABLE_TOOLS" | "PRETTY_ENABLE_TOOLS"): Set<string> {
35
33
  return new Set(
36
- (process.env.PRETTY_DISABLE_TOOLS ?? "")
34
+ (process.env[name] ?? "")
37
35
  .split(",")
38
- .map((s) => s.trim().toLowerCase())
36
+ .map((tool) => tool.trim().toLowerCase())
39
37
  .filter(Boolean),
40
38
  );
41
39
  }
@@ -47,9 +45,15 @@ function envDisabledTools(): Set<string> {
47
45
  export type { PiPrettyDeps };
48
46
 
49
47
  export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrettyDeps): Promise<void> {
50
- const disabledTools = envDisabledTools();
51
- const isToolEnabled = (name: string) => !disabledTools.has(name.toLowerCase());
52
- registerDefaultCollapsedToolOutput(pi);
48
+ const disabledTools = envTools("PRETTY_DISABLE_TOOLS");
49
+ const enabledTools = envTools("PRETTY_ENABLE_TOOLS");
50
+ const isToolEnabled = (name: string) => {
51
+ const normalizedName = name.toLowerCase();
52
+ return (
53
+ !disabledTools.has(normalizedName) &&
54
+ (!DEFAULT_DISABLED_TOOLS.has(normalizedName) || enabledTools.has(normalizedName))
55
+ );
56
+ };
53
57
  const cwd = process.cwd();
54
58
 
55
59
  // ------------------------------------------------------------------
@@ -62,10 +66,7 @@ export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrett
62
66
 
63
67
  const maybeGetAgentDir = deps?.sdk?.getAgentDir;
64
68
  const agentDir = typeof maybeGetAgentDir === "function" ? maybeGetAgentDir() : getDefaultAgentDir();
65
- let fffService: FffService | null = getSharedFffService(deps?.fffModule, agentDir);
66
-
67
- // Ripgrep fallback for multi_grep
68
- const multiGrepFallback = deps?.multiGrepRipgrepFallback ?? runMultiGrepRipgrepFallback;
69
+ const fffService: FffService | null = getSharedFffService(deps?.fffModule, agentDir);
69
70
 
70
71
  // Text component for custom rendering (DI-friendly)
71
72
  const TextComp = deps?.TextComponent;
@@ -78,8 +79,8 @@ export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrett
78
79
  pi.registerCommand("fff-health", {
79
80
  description: "Show FFF file finder health and indexer status",
80
81
  handler: async (_args: string, ctx: ExtensionCommandContext) => {
81
- const fff = fffService!;
82
- if (!fff.isAvailable) {
82
+ const fff = fffService;
83
+ if (!fff || !fff.isAvailable) {
83
84
  ctx.ui.notify("FFF not initialized", "warning");
84
85
  return;
85
86
  }
@@ -229,16 +230,6 @@ export default async function piPrettyExtension(pi: ExtensionAPI, deps?: PiPrett
229
230
  if (isToolEnabled("grep") && createGrepTool) {
230
231
  registerGrepTool(pi, cwd, fffService, createGrepTool(cwd), TextComp);
231
232
  }
232
- if (isToolEnabled("multi_grep") && (fffService || createGrepTool)) {
233
- registerMultiGrepTool(
234
- pi,
235
- cwd,
236
- fffService,
237
- createGrepTool ? createGrepTool(cwd) : undefined,
238
- multiGrepFallback,
239
- TextComp,
240
- );
241
- }
242
233
 
243
234
  // Fallback padding for SDK-rendered tool bodies. The SDK reads
244
235
  // result.content[0].text and slices collapsed output to roughly the first
package/src/notices.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Stable user-facing strings for FFF/grep tool footers (not source-line titles). */
2
2
 
3
- export const NOTICE_PARTIAL_FILE_INDEX = "FFF index incomplete; results may be missing files";
3
+ export const NOTICE_PARTIAL_FILE_INDEX = "FFF index incomplete; results may be missing files";
package/src/render.ts CHANGED
@@ -5,41 +5,40 @@
5
5
  * They are async only when Shiki syntax highlighting is involved.
6
6
  */
7
7
 
8
- import type { BundledLanguage } from "shiki";
9
- import { codeToANSI } from "@shikijs/cli";
10
8
  import { basename, dirname } from "node:path";
11
-
9
+ import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
10
+ import { codeToANSI } from "@shikijs/cli";
11
+ import type { BundledLanguage } from "shiki";
12
12
  import {
13
- TOOL_RESULT_INDENT,
14
- RST,
15
- FG_LNUM,
13
+ BG_BASE,
14
+ BG_ERROR,
15
+ CACHE_LIMIT,
16
+ detectLang,
17
+ dirIcon,
18
+ FG_BLUE,
16
19
  FG_DIM,
17
- FG_RULE,
18
20
  FG_GREEN,
21
+ FG_LNUM,
19
22
  FG_RED,
23
+ FG_RULE,
20
24
  FG_YELLOW,
21
- FG_BLUE,
22
- BG_BASE,
23
- BG_ERROR,
24
- dirIcon,
25
- detectLang,
26
- termWidth,
27
- MAX_PREVIEW_LINES,
28
25
  MAX_HL_CHARS,
29
- CACHE_LIMIT,
26
+ MAX_PREVIEW_LINES,
27
+ RST,
30
28
  resolveBaseBackground,
29
+ TOOL_RESULT_INDENT,
30
+ termWidth,
31
31
  } from "./config.js";
32
32
  import {
33
- normalizeLineEndings,
34
- humanSize,
35
- formatElapsedMs,
36
- formatCharCount,
37
- ELAPSED_KEY,
38
33
  CHARS_KEY,
39
34
  compactErrorLines,
35
+ ELAPSED_KEY,
36
+ formatCharCount,
37
+ formatElapsedMs,
38
+ humanSize,
39
+ normalizeLineEndings,
40
40
  } from "./helpers.js";
41
- import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
42
- import type { ThemeLike, RenderCtxLike as RenderContext } from "./types.js";
41
+ import type { RenderCtxLike as RenderContext, ThemeLike } from "./types.js";
43
42
 
44
43
  // ---------------------------------------------------------------------------
45
44
  // Lazy imports — avoid top-level require() that blocks module loading
@@ -73,7 +72,7 @@ function resolveTheme(): BundledTheme {
73
72
  }
74
73
  }
75
74
 
76
- let THEME: BundledTheme = resolveTheme();
75
+ const THEME: BundledTheme = resolveTheme();
77
76
  const _cache = new Map<string, string[]>();
78
77
 
79
78
  function _touch(k: string, v: string[]): string[] {
@@ -174,8 +173,7 @@ export function fillToolBackground(text: string, bg = BG_BASE, width?: number):
174
173
  return bg ? bg + stripped : stripped;
175
174
  }
176
175
  const plainLead = line.replace(/\x1b\[[0-9;]*m/g, "");
177
- const skipPad =
178
- line.startsWith(TOOL_RESULT_INDENT) || plainLead.startsWith(TOOL_RESULT_INDENT);
176
+ const skipPad = line.startsWith(TOOL_RESULT_INDENT) || plainLead.startsWith(TOOL_RESULT_INDENT);
179
177
  const fitted = _truncateToWidth(line, width, "", !skipPad);
180
178
  const stripped = preserveBoxBackground(fitted);
181
179
  return bg ? bg + stripped : stripped;
@@ -205,6 +203,11 @@ export function renderToolMetrics(result: AgentToolResult<Record<string, unknown
205
203
  return `${FG_DIM}· ${[elapsed, chars].filter(Boolean).join(" · ")}${RST}`;
206
204
  }
207
205
 
206
+ export function renderToolDuration(result: AgentToolResult<Record<string, unknown>>): string {
207
+ const details = result.details as Record<string, unknown> | undefined;
208
+ return formatElapsedMs(details?.[ELAPSED_KEY] as number | undefined);
209
+ }
210
+
208
211
  // ---------------------------------------------------------------------------
209
212
  // Error renderer
210
213
  // ---------------------------------------------------------------------------
@@ -246,14 +249,7 @@ export async function renderFileContent(
246
249
  // Bash — colored exit status
247
250
  // ---------------------------------------------------------------------------
248
251
 
249
- export function renderBashOutput(text: string, exitCode: number | null): { summary: string; body: string } {
250
- const isOk = exitCode === 0;
251
- const statusIcon = isOk ? "✓" : "✗";
252
- const codeStr =
253
- exitCode !== null
254
- ? `${isOk ? FG_GREEN : FG_RED}${statusIcon} exit ${exitCode}${RST}`
255
- : `${FG_YELLOW}⚡ killed${RST}`;
256
-
252
+ export function renderBashOutput(text: string): string {
257
253
  const lines = text.split("\n");
258
254
  const maxShow = MAX_PREVIEW_LINES;
259
255
  const show = lines.slice(0, maxShow);
@@ -262,7 +258,7 @@ export function renderBashOutput(text: string, exitCode: number | null): { summa
262
258
  let body = show.join("\n");
263
259
  if (remaining > 0) body += `\n${TOOL_RESULT_INDENT}${FG_DIM}… ${remaining} more lines${RST}`;
264
260
 
265
- return { summary: codeStr, body };
261
+ return body;
266
262
  }
267
263
 
268
264
  // ---------------------------------------------------------------------------
@@ -414,7 +410,13 @@ export function makeRenderResult() {
414
410
  const preview = lines.slice(0, maxShow).join("\n");
415
411
  const more = lines.length > maxShow ? `\n${FG_DIM}... ${lines.length - maxShow} more lines${RST}` : "";
416
412
  const metrics = renderToolMetrics(result);
417
- text.setText(fillToolBackground(`${TOOL_RESULT_INDENT}${preview}${more}${metrics ? `\n${TOOL_RESULT_INDENT}${metrics}` : ""}`, undefined, renderWidth));
413
+ text.setText(
414
+ fillToolBackground(
415
+ `${TOOL_RESULT_INDENT}${preview}${more}${metrics ? `\n${TOOL_RESULT_INDENT}${metrics}` : ""}`,
416
+ undefined,
417
+ renderWidth,
418
+ ),
419
+ );
418
420
  } else {
419
421
  text.setText(fillToolBackground(`${TOOL_RESULT_INDENT}${theme.fg("dim", "(no text output)")}`));
420
422
  }