@owlburtoe/pi-cc-tools 1.0.1 → 1.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/README.md +15 -0
- package/config/config.example.json +1 -0
- package/extensions/index.ts +64 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,7 @@ Set in `.pi/settings.json` or `~/.pi/settings.json`:
|
|
|
32
32
|
"previewLines": 8,
|
|
33
33
|
"bashOutputMode": "opencode",
|
|
34
34
|
"bashCollapsedLines": 10,
|
|
35
|
+
"bashStackConsecutive": true,
|
|
35
36
|
"diffCollapsedLines": 24,
|
|
36
37
|
"themeAdaptive": true,
|
|
37
38
|
"diffTheme": "github-dark",
|
|
@@ -135,6 +136,20 @@ Color selections are persisted as `spinnerColor` / `spinnerStatusColor` in `~/.p
|
|
|
135
136
|
| `mcpOutputMode` | `hidden`, `summary`, `preview` | `preview` |
|
|
136
137
|
| `bashOutputMode` | `opencode`, `summary`, `preview` | `opencode` |
|
|
137
138
|
|
|
139
|
+
`bashOutputMode` behavior:
|
|
140
|
+
|
|
141
|
+
| Value | Behavior |
|
|
142
|
+
|-------|----------|
|
|
143
|
+
| `opencode` | Compact status while collapsed, with `Ctrl+O` hint for output preview |
|
|
144
|
+
| `summary` | Status only; no output preview or expansion hint |
|
|
145
|
+
| `preview` | Show a small output preview even while collapsed |
|
|
146
|
+
|
|
147
|
+
### Boolean settings
|
|
148
|
+
|
|
149
|
+
| Setting | Default | Description |
|
|
150
|
+
|---------|---------|-------------|
|
|
151
|
+
| `bashStackConsecutive` | `true` | Remove the extra synthetic spacer between adjacent bash tool rows so command bursts render as a tight stack |
|
|
152
|
+
|
|
138
153
|
### Numeric settings
|
|
139
154
|
|
|
140
155
|
| Setting | Default | Description |
|
package/extensions/index.ts
CHANGED
|
@@ -84,6 +84,8 @@ interface SettingsFile {
|
|
|
84
84
|
expandedPreviewMaxLines?: number;
|
|
85
85
|
bashOutputMode?: "opencode" | "summary" | "preview";
|
|
86
86
|
bashCollapsedLines?: number;
|
|
87
|
+
/** When true (default), consecutive bash tool rows render without the extra inter-tool spacer. */
|
|
88
|
+
bashStackConsecutive?: boolean;
|
|
87
89
|
showTruncationHints?: boolean;
|
|
88
90
|
diffCollapsedLines?: number;
|
|
89
91
|
diffTheme?: string;
|
|
@@ -329,6 +331,44 @@ function isToolExecutionLike(value: unknown): value is { toolName: string; toolC
|
|
|
329
331
|
return typeof candidate.toolName === "string" && typeof candidate.toolCallId === "string";
|
|
330
332
|
}
|
|
331
333
|
|
|
334
|
+
function isBashToolExecution(value: unknown): boolean {
|
|
335
|
+
return isToolExecutionLike(value) && (value as any).toolName === "bash";
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function shouldStackConsecutiveBash(): boolean {
|
|
339
|
+
return readSettings().bashStackConsecutive !== false;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function hasConsecutiveBashToolChildren(children: unknown[]): boolean {
|
|
343
|
+
let previousWasBash = false;
|
|
344
|
+
for (const child of children) {
|
|
345
|
+
const currentIsBash = isBashToolExecution(child);
|
|
346
|
+
if (currentIsBash && previousWasBash) return true;
|
|
347
|
+
previousWasBash = currentIsBash;
|
|
348
|
+
}
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function dropLeadingSpacerLine(lines: string[]): string[] {
|
|
353
|
+
return lines.length > 0 && isBlankLine(lines[0]) ? lines.slice(1) : lines;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function renderWithStackedConsecutiveBash(container: any, width: number): string[] | null {
|
|
357
|
+
if (!shouldStackConsecutiveBash()) return null;
|
|
358
|
+
const children = Array.isArray(container?.children) ? container.children : null;
|
|
359
|
+
if (!children || !hasConsecutiveBashToolChildren(children)) return null;
|
|
360
|
+
|
|
361
|
+
const rendered: string[] = [];
|
|
362
|
+
let previousWasBash = false;
|
|
363
|
+
for (const child of children) {
|
|
364
|
+
const currentIsBash = isBashToolExecution(child);
|
|
365
|
+
const childLines = typeof child?.render === "function" ? child.render(width) : [];
|
|
366
|
+
rendered.push(...(currentIsBash && previousWasBash ? dropLeadingSpacerLine(childLines) : childLines));
|
|
367
|
+
previousWasBash = currentIsBash;
|
|
368
|
+
}
|
|
369
|
+
return rendered;
|
|
370
|
+
}
|
|
371
|
+
|
|
332
372
|
function isTerminalImageLine(line: string): boolean {
|
|
333
373
|
return line.includes(KITTY_IMAGE_PREFIX) || line.includes(ITERM2_IMAGE_PREFIX);
|
|
334
374
|
}
|
|
@@ -359,6 +399,11 @@ function patchGlobalToolBorders(): void {
|
|
|
359
399
|
|
|
360
400
|
const originalRender = proto.render;
|
|
361
401
|
proto.render = function patchedContainerRender(width: number): string[] {
|
|
402
|
+
if (!isToolExecutionLike(this)) {
|
|
403
|
+
const stacked = renderWithStackedConsecutiveBash(this, width);
|
|
404
|
+
if (stacked) return stacked;
|
|
405
|
+
}
|
|
406
|
+
|
|
362
407
|
if (isToolExecutionLike(this)) {
|
|
363
408
|
const cached = (this as any)[TOOL_RENDER_CACHE];
|
|
364
409
|
if (cached?.width === width && cached?.mode === toolBackgroundMode) {
|
|
@@ -1324,6 +1369,10 @@ function bashCollapsedLimit(): number {
|
|
|
1324
1369
|
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : 10;
|
|
1325
1370
|
}
|
|
1326
1371
|
|
|
1372
|
+
function bashOutputMode(): "opencode" | "summary" | "preview" {
|
|
1373
|
+
return getMode(readSettings().bashOutputMode, ["opencode", "summary", "preview"] as const, "opencode");
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1327
1376
|
function diffCollapsedLimit(): number {
|
|
1328
1377
|
const value = readSettings().diffCollapsedLines;
|
|
1329
1378
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 24;
|
|
@@ -4245,15 +4294,26 @@ export default function (pi: ExtensionAPI) {
|
|
|
4245
4294
|
}
|
|
4246
4295
|
clearBlinkTimer(ctx);
|
|
4247
4296
|
setToolStatus(ctx, ctx.isError ? "error" : "success");
|
|
4248
|
-
const exitMatch = output.match(/exit code
|
|
4297
|
+
const exitMatch = output.match(/(?:exit code:|exited with code)\s+(\d+)/i);
|
|
4249
4298
|
const exitCode = exitMatch ? Number.parseInt(exitMatch[1], 10) : null;
|
|
4250
|
-
|
|
4299
|
+
const isError = ctx.isError || (exitCode !== null && exitCode !== 0);
|
|
4300
|
+
let text = isError
|
|
4301
|
+
? theme.fg("error", exitCode !== null ? `Exit ${exitCode}` : "Failed")
|
|
4302
|
+
: theme.fg("success", "Done");
|
|
4251
4303
|
text += theme.fg("muted", ` (${nonEmpty.length} lines)`);
|
|
4252
4304
|
if (details?.truncation?.truncated) text += theme.fg("warning", " [truncated]");
|
|
4305
|
+
|
|
4306
|
+
const mode = bashOutputMode();
|
|
4307
|
+
if (mode === "summary") return makeText(ctx.lastComponent, withBranch(text, theme));
|
|
4308
|
+
if (mode === "preview") {
|
|
4309
|
+
if (nonEmpty.length === 0) return makeText(ctx.lastComponent, withBranch(text, theme));
|
|
4310
|
+
const preview = buildPreviewText(nonEmpty.map((line) => theme.fg(isError ? "error" : "dim", line)), expanded, theme, bashCollapsedLimit());
|
|
4311
|
+
return makeText(ctx.lastComponent, withBranch(`${text}\n${preview}`, theme));
|
|
4312
|
+
}
|
|
4313
|
+
|
|
4253
4314
|
if (!expanded && nonEmpty.length > 0) return makeText(ctx.lastComponent, withBranch(`${text}${theme.fg("muted", " • Ctrl+O to expand")}`, theme));
|
|
4254
4315
|
if (!expanded) return makeText(ctx.lastComponent, withBranch(text, theme));
|
|
4255
|
-
|
|
4256
|
-
text += `\n${buildPreviewText(nonEmpty.map((line) => theme.fg("dim", line)), false, theme, collapsed)}`;
|
|
4316
|
+
text += `\n${buildPreviewText(nonEmpty.map((line) => theme.fg(isError ? "error" : "dim", line)), true, theme, bashCollapsedLimit())}`;
|
|
4257
4317
|
return makeText(ctx.lastComponent, withBranch(text, theme));
|
|
4258
4318
|
},
|
|
4259
4319
|
});
|
package/package.json
CHANGED