pi-repoprompt-cli 0.2.8 → 0.2.9

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 CHANGED
@@ -56,10 +56,13 @@ Create `~/.pi/agent/extensions/repoprompt-cli/config.json`:
56
56
  ```json
57
57
  {
58
58
  "readcacheReadFile": true,
59
- "autoSelectReadSlices": true
59
+ "autoSelectReadSlices": true,
60
+ "collapsedMaxLines": 3
60
61
  }
61
62
  ```
62
63
 
64
+ `collapsedMaxLines` controls how many lines of `rp_exec` output Pi shows in collapsed view before you expand the result. It applies across RepoPrompt CLI commands, so it is the main knob for keeping reads, window listings, and other verbose CLI responses compact in the TUI. Recommended setting: `3` for maximally compressed but still informative output.
65
+
63
66
  ## Quick start
64
67
 
65
68
  1) Find your RepoPrompt window + tab (from a terminal):
@@ -28,10 +28,13 @@ Create:
28
28
  ```json
29
29
  {
30
30
  "readcacheReadFile": true,
31
- "autoSelectReadSlices": true
31
+ "autoSelectReadSlices": true,
32
+ "collapsedMaxLines": 3
32
33
  }
33
34
  ```
34
35
 
36
+ `collapsedMaxLines` controls how many lines of `rp_exec` output Pi shows in collapsed view before you expand the result. It applies across RepoPrompt CLI commands, so it is the main knob for keeping reads, window listings, and other verbose CLI responses compact in the TUI. Recommended setting: `3` for maximally compressed but still informative output.
37
+
35
38
  Note: when enabled, the extension may persist UTF-8 file snapshots to an on-disk content-addressed store under
36
39
  `<repo-root>/.pi/readcache/objects` to compute diffs/unchanged markers across calls. Common secret filenames (e.g. `.env*`, `*.pem`) are excluded,
37
40
  but this is best-effort
@@ -1,4 +1,5 @@
1
1
  {
2
2
  "readcacheReadFile": false,
3
- "autoSelectReadSlices": true
3
+ "autoSelectReadSlices": true,
4
+ "collapsedMaxLines": 3
4
5
  }
@@ -9,6 +9,7 @@ import type { RpCliConfig } from "./types.js";
9
9
  const DEFAULT_CONFIG: Required<RpCliConfig> = {
10
10
  readcacheReadFile: false,
11
11
  autoSelectReadSlices: true,
12
+ collapsedMaxLines: 15,
12
13
  };
13
14
 
14
15
  const CONFIG_LOCATIONS = [
@@ -1260,12 +1260,80 @@ function renderRpExecOutput(text: string, theme: Theme): string {
1260
1260
  }
1261
1261
 
1262
1262
  // Collapsed output settings
1263
- const COLLAPSED_MAX_LINES = 15;
1263
+ const DEFAULT_COLLAPSED_MAX_LINES = 15;
1264
1264
  const COLLAPSED_MAX_CHARS = 2000;
1265
1265
 
1266
+ function stripNoiseForCollapsedView(lines: string[]): string[] {
1267
+ const filtered: string[] = [];
1268
+ let consecutiveEmpty = 0;
1269
+
1270
+ for (const line of lines) {
1271
+ const trimmed = line.trim();
1272
+
1273
+ if (trimmed.startsWith("```")) {
1274
+ continue;
1275
+ }
1276
+
1277
+ if (trimmed.length === 0) {
1278
+ consecutiveEmpty += 1;
1279
+ if (consecutiveEmpty > 1) {
1280
+ continue;
1281
+ }
1282
+ filtered.push("");
1283
+ continue;
1284
+ }
1285
+
1286
+ consecutiveEmpty = 0;
1287
+ filtered.push(line);
1288
+ }
1289
+
1290
+ while (filtered.length > 0 && filtered[filtered.length - 1]?.trim().length === 0) {
1291
+ filtered.pop();
1292
+ }
1293
+
1294
+ return filtered;
1295
+ }
1296
+
1297
+ function prepareCollapsedView(
1298
+ text: string,
1299
+ theme: Theme,
1300
+ maxLines: number = DEFAULT_COLLAPSED_MAX_LINES
1301
+ ): { content: string; truncated: boolean; totalLines: number } {
1302
+ const lines = stripNoiseForCollapsedView(text.split("\n"));
1303
+ const totalLines = lines.length;
1304
+
1305
+ if (maxLines <= 0) {
1306
+ return {
1307
+ content: "",
1308
+ truncated: totalLines > 0,
1309
+ totalLines,
1310
+ };
1311
+ }
1312
+
1313
+ const normalizedText = lines.join("\n");
1314
+
1315
+ if (lines.length <= maxLines && normalizedText.length <= COLLAPSED_MAX_CHARS) {
1316
+ return {
1317
+ content: renderRpExecOutput(normalizedText, theme),
1318
+ truncated: false,
1319
+ totalLines,
1320
+ };
1321
+ }
1322
+
1323
+ return {
1324
+ content: renderRpExecOutput(lines.slice(0, maxLines).join("\n"), theme),
1325
+ truncated: true,
1326
+ totalLines,
1327
+ };
1328
+ }
1329
+
1266
1330
  export default function (pi: ExtensionAPI) {
1267
1331
  let config = loadConfig();
1268
1332
 
1333
+ pi.on("before_agent_start", async () => {
1334
+ config = loadConfig();
1335
+ });
1336
+
1269
1337
  // Replay-aware read_file caching state (optional; guarded by config.readcacheReadFile)
1270
1338
  const readcacheRuntimeState = createReplayRuntimeState();
1271
1339
 
@@ -3114,25 +3182,45 @@ export default function (pi: ExtensionAPI) {
3114
3182
 
3115
3183
  // Success case
3116
3184
  const truncatedNote = truncated ? theme.fg("warning", " (truncated)") : "";
3117
- const successPrefix = theme.fg("success", "✓");
3185
+ const successPrefix = theme.fg("success", "✓ ");
3186
+ const prefixFirstLine = (value: string, prefix: string): string => {
3187
+ if (!value) {
3188
+ return prefix.trimEnd();
3189
+ }
3190
+ const idx = value.indexOf("\n");
3191
+ if (idx < 0) {
3192
+ return `${prefix}${value}`;
3193
+ }
3194
+ return `${prefix}${value.slice(0, idx)}${value.slice(idx)}`;
3195
+ };
3118
3196
 
3119
- // Collapsed view: show line count
3120
3197
  if (!options.expanded) {
3121
- const lines = textContent.split("\n");
3122
- if (lines.length > COLLAPSED_MAX_LINES || textContent.length > COLLAPSED_MAX_CHARS) {
3123
- const preview = renderRpExecOutput(
3124
- lines.slice(0, COLLAPSED_MAX_LINES).join("\n"),
3125
- theme
3126
- );
3127
- const remaining = lines.length - COLLAPSED_MAX_LINES;
3198
+ const collapsedMaxLines = config.collapsedMaxLines;
3199
+ const maxLines = collapsedMaxLines ?? DEFAULT_COLLAPSED_MAX_LINES;
3200
+ const { content, truncated: collapsedTruncated, totalLines } = prepareCollapsedView(
3201
+ textContent,
3202
+ theme,
3203
+ collapsedMaxLines
3204
+ );
3205
+
3206
+ if (maxLines === 0) {
3207
+ const hidden = theme.fg("muted", "(output hidden)");
3208
+ const moreText = totalLines > 0 ? theme.fg("muted", `\n… (${totalLines} more lines)`) : "";
3209
+ return new Text(`${successPrefix}${truncatedNote}${hidden}${moreText}`, 0, 0);
3210
+ }
3211
+
3212
+ if (collapsedTruncated) {
3213
+ const remaining = totalLines - maxLines;
3128
3214
  const moreText = remaining > 0 ? theme.fg("muted", `\n… (${remaining} more lines)`) : "";
3129
- return new Text(`${successPrefix}${truncatedNote}\n${preview}${moreText}`, 0, 0);
3215
+ return new Text(`${prefixFirstLine(content, `${successPrefix}${truncatedNote}`)}${moreText}`, 0, 0);
3130
3216
  }
3217
+
3218
+ return new Text(prefixFirstLine(content, `${successPrefix}${truncatedNote}`), 0, 0);
3131
3219
  }
3132
3220
 
3133
3221
  // Expanded view or short output: render with syntax highlighting
3134
3222
  const highlighted = renderRpExecOutput(textContent, theme);
3135
- return new Text(`${successPrefix}${truncatedNote}\n${highlighted}`, 0, 0);
3223
+ return new Text(prefixFirstLine(highlighted, `${successPrefix}${truncatedNote}`), 0, 0);
3136
3224
  },
3137
3225
  });
3138
3226
  }
@@ -7,6 +7,9 @@ export interface RpCliConfig {
7
7
  // Optional context UX: automatically update RepoPrompt selection based on read_file calls
8
8
  // (tracks read slices/full files so chat has context without manual selection)
9
9
  autoSelectReadSlices?: boolean; // default: true
10
+
11
+ // Lines shown in collapsed rp_exec output previews
12
+ collapsedMaxLines?: number; // default: 15
10
13
  }
11
14
 
12
15
  export interface RpCliBindingEntryData {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-repoprompt-cli",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Integrates RepoPrompt with Pi via RepoPrompt's `rp-cli` executable",
5
5
  "keywords": ["pi-package", "pi", "pi-coding-agent", "repoprompt"],
6
6
  "license": "MIT",