@cydm/pie 1.0.42 → 1.0.44
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/dist/builtin/extensions/ask-user/index.js +1 -1
- package/dist/builtin/extensions/init/index.js +1 -1
- package/dist/builtin/extensions/plan-mode/index.js +1 -1
- package/dist/builtin/extensions/subagent/index.js +2 -2
- package/dist/builtin/extensions/todo/index.js +1 -1
- package/dist/chunks/{chunk-2GVFMYIV.js → chunk-7C5E245X.js} +8 -1
- package/dist/chunks/{chunk-VYAW6RAX.js → chunk-DSVPYK5S.js} +1 -1
- package/dist/chunks/{chunk-NTYHFBUA.js → chunk-WLFOBECN.js} +6 -1
- package/dist/cli.js +464 -190
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createAskUserCapability
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-7C5E245X.js";
|
|
5
5
|
import "../../../chunks/chunk-JVLAKTAS.js";
|
|
6
6
|
import "../../../chunks/chunk-NGQ3PUOC.js";
|
|
7
7
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
resolveCliProjectRoot
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-WLFOBECN.js";
|
|
5
5
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
6
6
|
|
|
7
7
|
// builtin/extensions/init/index.ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createCliHostCapabilities
|
|
4
|
-
} from "../../../chunks/chunk-
|
|
4
|
+
} from "../../../chunks/chunk-DSVPYK5S.js";
|
|
5
5
|
import {
|
|
6
6
|
createSharedFileSystemTools,
|
|
7
7
|
createSubagentCapability
|
|
8
|
-
} from "../../../chunks/chunk-
|
|
8
|
+
} from "../../../chunks/chunk-7C5E245X.js";
|
|
9
9
|
import "../../../chunks/chunk-JVLAKTAS.js";
|
|
10
10
|
import "../../../chunks/chunk-NGQ3PUOC.js";
|
|
11
11
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
executeManageTodoList,
|
|
8
8
|
executionStateToTodos,
|
|
9
9
|
restoreExecutionState
|
|
10
|
-
} from "../../../chunks/chunk-
|
|
10
|
+
} from "../../../chunks/chunk-7C5E245X.js";
|
|
11
11
|
import "../../../chunks/chunk-JVLAKTAS.js";
|
|
12
12
|
import "../../../chunks/chunk-NGQ3PUOC.js";
|
|
13
13
|
import "../../../chunks/chunk-LZQXQOPJ.js";
|
|
@@ -1286,6 +1286,7 @@ function formatSkillSummariesForPrompt(skills) {
|
|
|
1286
1286
|
const lines = [
|
|
1287
1287
|
"\n\nThe following skills provide specialized instructions for specific tasks.",
|
|
1288
1288
|
"Use read_file to load a skill's entry file when the task matches its description.",
|
|
1289
|
+
"Skills that include an inline <content> block are already fully loaded; no read_file is needed for them.",
|
|
1289
1290
|
"When a skill file references a relative path, resolve it against that skill's baseDir and use the resulting ordinary path with file or bash tools.",
|
|
1290
1291
|
"Skills are ordinary files in the current runtime filesystem; do not use special skill/resource tool protocols.",
|
|
1291
1292
|
"",
|
|
@@ -1295,7 +1296,13 @@ function formatSkillSummariesForPrompt(skills) {
|
|
|
1295
1296
|
lines.push(" <skill>");
|
|
1296
1297
|
lines.push(` <name>${escapeXml(skill.name)}</name>`);
|
|
1297
1298
|
lines.push(` <description>${escapeXml(skill.description)}</description>`);
|
|
1298
|
-
if (skill.
|
|
1299
|
+
if (skill.inlineContent !== void 0) {
|
|
1300
|
+
lines.push(" <content>");
|
|
1301
|
+
for (const contentLine of skill.inlineContent.replace(/\r\n/g, "\n").split("\n")) {
|
|
1302
|
+
lines.push(` ${escapeXml(contentLine)}`);
|
|
1303
|
+
}
|
|
1304
|
+
lines.push(" </content>");
|
|
1305
|
+
} else if (skill.filePath) {
|
|
1299
1306
|
lines.push(` <entry>${escapeXml(skill.filePath)}</entry>`);
|
|
1300
1307
|
}
|
|
1301
1308
|
if (skill.baseDir) {
|
|
@@ -7,7 +7,12 @@ function hasGitBoundary(directory) {
|
|
|
7
7
|
const gitPath = path.join(directory, ".git");
|
|
8
8
|
try {
|
|
9
9
|
const stat = fs.statSync(gitPath);
|
|
10
|
-
|
|
10
|
+
if (stat.isDirectory()) return true;
|
|
11
|
+
if (!stat.isFile()) return false;
|
|
12
|
+
const content = fs.readFileSync(gitPath, "utf8");
|
|
13
|
+
const firstLine = content.split("\n", 1)[0] ?? "";
|
|
14
|
+
const gitdir = firstLine.trim().replace(/^gitdir:/, "").trim();
|
|
15
|
+
return firstLine.trim().startsWith("gitdir:") && gitdir.length > 0;
|
|
11
16
|
} catch {
|
|
12
17
|
return false;
|
|
13
18
|
}
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
getThemesDir,
|
|
20
20
|
migrateConfigFromAgentDir,
|
|
21
21
|
truncateHeadTail
|
|
22
|
-
} from "./chunks/chunk-
|
|
22
|
+
} from "./chunks/chunk-DSVPYK5S.js";
|
|
23
23
|
import {
|
|
24
24
|
AGENTS_CONTEXT_FILE_NAME,
|
|
25
25
|
AgentSessionController,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
setExtensionEnabledInSettings,
|
|
70
70
|
shouldPreserveExecutionStateForUserText,
|
|
71
71
|
supersedeExecutionState
|
|
72
|
-
} from "./chunks/chunk-
|
|
72
|
+
} from "./chunks/chunk-7C5E245X.js";
|
|
73
73
|
import "./chunks/chunk-JVLAKTAS.js";
|
|
74
74
|
import {
|
|
75
75
|
Deref,
|
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
} from "./chunks/chunk-NGQ3PUOC.js";
|
|
110
110
|
import {
|
|
111
111
|
resolveCliProjectRoot
|
|
112
|
-
} from "./chunks/chunk-
|
|
112
|
+
} from "./chunks/chunk-WLFOBECN.js";
|
|
113
113
|
import {
|
|
114
114
|
__commonJS,
|
|
115
115
|
__require,
|
|
@@ -46314,6 +46314,24 @@ var SettingsManager = class {
|
|
|
46314
46314
|
getBellNotificationsEnabled() {
|
|
46315
46315
|
return this.settings.notifications?.bell !== false;
|
|
46316
46316
|
}
|
|
46317
|
+
setBellNotificationsEnabled(enabled) {
|
|
46318
|
+
this.settings.notifications = { ...this.settings.notifications, bell: enabled };
|
|
46319
|
+
this.writeSettings();
|
|
46320
|
+
}
|
|
46321
|
+
getDesktopNotificationsEnabled() {
|
|
46322
|
+
return this.settings.notifications?.desktop !== false;
|
|
46323
|
+
}
|
|
46324
|
+
setDesktopNotificationsEnabled(enabled) {
|
|
46325
|
+
this.settings.notifications = { ...this.settings.notifications, desktop: enabled };
|
|
46326
|
+
this.writeSettings();
|
|
46327
|
+
}
|
|
46328
|
+
getCalmModeEnabled() {
|
|
46329
|
+
return this.settings.calmMode === true;
|
|
46330
|
+
}
|
|
46331
|
+
setCalmModeEnabled(enabled) {
|
|
46332
|
+
this.settings.calmMode = enabled;
|
|
46333
|
+
this.writeSettings();
|
|
46334
|
+
}
|
|
46317
46335
|
// ==========================================================================
|
|
46318
46336
|
// Extension enablement (user ~/.pie/settings.json + project ./.pie/settings.json)
|
|
46319
46337
|
// ==========================================================================
|
|
@@ -49807,10 +49825,15 @@ var Text = class {
|
|
|
49807
49825
|
for (const line of wrappedLines) {
|
|
49808
49826
|
const lineWithMargins = leftMargin + line + rightMargin;
|
|
49809
49827
|
if (this.customBgFn) {
|
|
49810
|
-
|
|
49828
|
+
const clamped = visibleWidth(lineWithMargins) > width ? truncateToWidth(lineWithMargins, width, "") : lineWithMargins;
|
|
49829
|
+
contentLines.push(applyBackgroundToLine(clamped, width, this.customBgFn));
|
|
49811
49830
|
} else {
|
|
49812
49831
|
const visibleLen = visibleWidth(lineWithMargins);
|
|
49813
|
-
|
|
49832
|
+
if (visibleLen > width) {
|
|
49833
|
+
contentLines.push(truncateToWidth(lineWithMargins, width, ""));
|
|
49834
|
+
continue;
|
|
49835
|
+
}
|
|
49836
|
+
const paddingNeeded = width - visibleLen;
|
|
49814
49837
|
contentLines.push(lineWithMargins + " ".repeat(paddingNeeded));
|
|
49815
49838
|
}
|
|
49816
49839
|
}
|
|
@@ -50369,6 +50392,8 @@ var TUI = class extends Container {
|
|
|
50369
50392
|
// Track previous viewport top for resize-aware cursor moves
|
|
50370
50393
|
fullRedrawCount = 0;
|
|
50371
50394
|
stopped = false;
|
|
50395
|
+
/** Guard: never paint before terminal.start() has run (modes like DECAWM-off are set there). */
|
|
50396
|
+
started = false;
|
|
50372
50397
|
constructor(terminal, showHardwareCursor) {
|
|
50373
50398
|
super();
|
|
50374
50399
|
this.terminal = terminal;
|
|
@@ -50431,6 +50456,7 @@ var TUI = class extends Container {
|
|
|
50431
50456
|
}
|
|
50432
50457
|
start() {
|
|
50433
50458
|
this.stopped = false;
|
|
50459
|
+
this.started = true;
|
|
50434
50460
|
this.terminal.start(
|
|
50435
50461
|
(data) => this.handleInput(data),
|
|
50436
50462
|
() => this.requestRender()
|
|
@@ -50470,6 +50496,7 @@ var TUI = class extends Container {
|
|
|
50470
50496
|
this.previousViewportTop = 0;
|
|
50471
50497
|
}
|
|
50472
50498
|
if (this.renderRequested) return;
|
|
50499
|
+
if (!this.started || this.stopped) return;
|
|
50473
50500
|
this.renderRequested = true;
|
|
50474
50501
|
process.nextTick(() => {
|
|
50475
50502
|
this.renderRequested = false;
|
|
@@ -50809,7 +50836,7 @@ var SelectList = class {
|
|
|
50809
50836
|
render(width) {
|
|
50810
50837
|
const lines = [];
|
|
50811
50838
|
if (this.filteredItems.length === 0) {
|
|
50812
|
-
lines.push(this.theme.noMatch(" No matching commands"));
|
|
50839
|
+
lines.push(truncateToWidth(this.theme.noMatch(" No matching commands"), width));
|
|
50813
50840
|
return lines;
|
|
50814
50841
|
}
|
|
50815
50842
|
const { startIndex, endIndex } = this.getVisibleRange();
|
|
@@ -51133,8 +51160,8 @@ var Editor = class {
|
|
|
51133
51160
|
const rightPadding = leftPadding;
|
|
51134
51161
|
if (this.scrollOffset > 0) {
|
|
51135
51162
|
const indicator = `\u2500\u2500\u2500 \u2191 ${this.scrollOffset} more `;
|
|
51136
|
-
const
|
|
51137
|
-
result.push(this.borderColor(indicator + "
|
|
51163
|
+
const fill = "\u2500".repeat(Math.max(0, width - visibleWidth(indicator)));
|
|
51164
|
+
result.push(this.borderColor(truncateToWidth(indicator + fill, width, "")));
|
|
51138
51165
|
} else {
|
|
51139
51166
|
result.push(horizontal.repeat(width));
|
|
51140
51167
|
}
|
|
@@ -51164,13 +51191,13 @@ var Editor = class {
|
|
|
51164
51191
|
}
|
|
51165
51192
|
const padding = " ".repeat(Math.max(0, contentWidth - lineVisibleWidth));
|
|
51166
51193
|
const lineRightPadding = cursorInPadding ? rightPadding.slice(1) : rightPadding;
|
|
51167
|
-
result.push(`${leftPadding}${displayText}${padding}${lineRightPadding}
|
|
51194
|
+
result.push(truncateToWidth(`${leftPadding}${displayText}${padding}${lineRightPadding}`, width, ""));
|
|
51168
51195
|
}
|
|
51169
51196
|
const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length);
|
|
51170
51197
|
if (linesBelow > 0) {
|
|
51171
51198
|
const indicator = `\u2500\u2500\u2500 \u2193 ${linesBelow} more `;
|
|
51172
|
-
const
|
|
51173
|
-
result.push(this.borderColor(indicator + "
|
|
51199
|
+
const fill = "\u2500".repeat(Math.max(0, width - visibleWidth(indicator)));
|
|
51200
|
+
result.push(this.borderColor(truncateToWidth(indicator + fill, width, "")));
|
|
51174
51201
|
} else {
|
|
51175
51202
|
result.push(horizontal.repeat(width));
|
|
51176
51203
|
}
|
|
@@ -51728,26 +51755,55 @@ var Editor = class {
|
|
|
51728
51755
|
/**
|
|
51729
51756
|
* Move cursor to a target visual line, applying sticky column logic.
|
|
51730
51757
|
* Shared by moveCursor() and pageScroll().
|
|
51758
|
+
*
|
|
51759
|
+
* Column math is done in terminal columns (visibleWidth), not UTF-16 code
|
|
51760
|
+
* units, so CJK/emoji text keeps the cursor visually aligned when moving
|
|
51761
|
+
* up/down across wrapped segments.
|
|
51731
51762
|
*/
|
|
51732
51763
|
moveToVisualLine(visualLines, currentVisualLine, targetVisualLine) {
|
|
51733
51764
|
const currentVL = visualLines[currentVisualLine];
|
|
51734
51765
|
const targetVL = visualLines[targetVisualLine];
|
|
51735
51766
|
if (currentVL && targetVL) {
|
|
51736
|
-
const
|
|
51767
|
+
const sourceLine = this.state.lines[currentVL.logicalLine] || "";
|
|
51768
|
+
const sourceText = sourceLine.slice(currentVL.startUnit, currentVL.startUnit + currentVL.lengthUnits);
|
|
51769
|
+
const currentVisualCol = visibleWidth(sourceLine.slice(currentVL.startUnit, this.state.cursorCol));
|
|
51737
51770
|
const isLastSourceSegment = currentVisualLine === visualLines.length - 1 || visualLines[currentVisualLine + 1]?.logicalLine !== currentVL.logicalLine;
|
|
51738
|
-
const sourceMaxVisualCol = isLastSourceSegment ? currentVL.
|
|
51771
|
+
const sourceMaxVisualCol = isLastSourceSegment ? currentVL.widthCols : Math.max(0, currentVL.widthCols - this.lastGraphemeColumns(sourceText));
|
|
51772
|
+
const targetLine = this.state.lines[targetVL.logicalLine] || "";
|
|
51773
|
+
const targetText = targetLine.slice(targetVL.startUnit, targetVL.startUnit + targetVL.lengthUnits);
|
|
51739
51774
|
const isLastTargetSegment = targetVisualLine === visualLines.length - 1 || visualLines[targetVisualLine + 1]?.logicalLine !== targetVL.logicalLine;
|
|
51740
|
-
const targetMaxVisualCol = isLastTargetSegment ? targetVL.
|
|
51775
|
+
const targetMaxVisualCol = isLastTargetSegment ? targetVL.widthCols : Math.max(0, targetVL.widthCols - this.lastGraphemeColumns(targetText));
|
|
51741
51776
|
const moveToVisualCol = this.computeVerticalMoveColumn(
|
|
51742
51777
|
currentVisualCol,
|
|
51743
51778
|
sourceMaxVisualCol,
|
|
51744
51779
|
targetMaxVisualCol
|
|
51745
51780
|
);
|
|
51746
51781
|
this.state.cursorLine = targetVL.logicalLine;
|
|
51747
|
-
const targetCol = targetVL.
|
|
51748
|
-
|
|
51749
|
-
|
|
51782
|
+
const targetCol = targetVL.startUnit + this.columnToUnit(targetText, moveToVisualCol);
|
|
51783
|
+
this.state.cursorCol = Math.min(targetCol, targetLine.length);
|
|
51784
|
+
}
|
|
51785
|
+
}
|
|
51786
|
+
/** Map a terminal-column offset to the closest code-unit offset at or before it. */
|
|
51787
|
+
columnToUnit(text, col) {
|
|
51788
|
+
if (col <= 0) return 0;
|
|
51789
|
+
let units = 0;
|
|
51790
|
+
let cols = 0;
|
|
51791
|
+
for (const seg of segmenter2.segment(text)) {
|
|
51792
|
+
const width = visibleWidth(seg.segment);
|
|
51793
|
+
if (cols + width > col) break;
|
|
51794
|
+
cols += width;
|
|
51795
|
+
units += seg.segment.length;
|
|
51796
|
+
}
|
|
51797
|
+
return units;
|
|
51798
|
+
}
|
|
51799
|
+
/** Visible width (columns) of the last grapheme of a non-empty string. */
|
|
51800
|
+
lastGraphemeColumns(text) {
|
|
51801
|
+
if (!text) return 0;
|
|
51802
|
+
let width = 0;
|
|
51803
|
+
for (const seg of segmenter2.segment(text)) {
|
|
51804
|
+
width = visibleWidth(seg.segment);
|
|
51750
51805
|
}
|
|
51806
|
+
return width;
|
|
51751
51807
|
}
|
|
51752
51808
|
/**
|
|
51753
51809
|
* Compute the target visual column for vertical cursor movement.
|
|
@@ -51937,11 +51993,8 @@ var Editor = class {
|
|
|
51937
51993
|
}
|
|
51938
51994
|
}
|
|
51939
51995
|
/**
|
|
51940
|
-
*
|
|
51941
|
-
*
|
|
51942
|
-
* - logicalLine: index into this.state.lines
|
|
51943
|
-
* - startCol: starting column in the logical line
|
|
51944
|
-
* - length: length of this visual line segment
|
|
51996
|
+
* A wrapped segment of a logical line: both UTF-16 offsets (for editing)
|
|
51997
|
+
* and terminal columns (for visual cursor movement) are tracked.
|
|
51945
51998
|
*/
|
|
51946
51999
|
buildVisualLineMap(width) {
|
|
51947
52000
|
const visualLines = [];
|
|
@@ -51949,17 +52002,22 @@ var Editor = class {
|
|
|
51949
52002
|
const line = this.state.lines[i] || "";
|
|
51950
52003
|
const lineVisWidth = visibleWidth(line);
|
|
51951
52004
|
if (line.length === 0) {
|
|
51952
|
-
visualLines.push({ logicalLine: i, startCol: 0,
|
|
52005
|
+
visualLines.push({ logicalLine: i, startUnit: 0, lengthUnits: 0, startCol: 0, widthCols: 0 });
|
|
51953
52006
|
} else if (lineVisWidth <= width) {
|
|
51954
|
-
visualLines.push({ logicalLine: i,
|
|
52007
|
+
visualLines.push({ logicalLine: i, startUnit: 0, lengthUnits: line.length, startCol: 0, widthCols: lineVisWidth });
|
|
51955
52008
|
} else {
|
|
51956
52009
|
const chunks = wordWrapLine(line, width);
|
|
52010
|
+
let col = 0;
|
|
51957
52011
|
for (const chunk of chunks) {
|
|
52012
|
+
const chunkWidth = visibleWidth(chunk.text);
|
|
51958
52013
|
visualLines.push({
|
|
51959
52014
|
logicalLine: i,
|
|
51960
|
-
|
|
51961
|
-
|
|
52015
|
+
startUnit: chunk.startIndex,
|
|
52016
|
+
lengthUnits: chunk.endIndex - chunk.startIndex,
|
|
52017
|
+
startCol: col,
|
|
52018
|
+
widthCols: chunkWidth
|
|
51962
52019
|
});
|
|
52020
|
+
col += chunkWidth;
|
|
51963
52021
|
}
|
|
51964
52022
|
}
|
|
51965
52023
|
}
|
|
@@ -51973,9 +52031,9 @@ var Editor = class {
|
|
|
51973
52031
|
const vl = visualLines[i];
|
|
51974
52032
|
if (!vl) continue;
|
|
51975
52033
|
if (vl.logicalLine === this.state.cursorLine) {
|
|
51976
|
-
const
|
|
52034
|
+
const unitInSegment = this.state.cursorCol - vl.startUnit;
|
|
51977
52035
|
const isLastSegmentOfLine = i === visualLines.length - 1 || visualLines[i + 1]?.logicalLine !== vl.logicalLine;
|
|
51978
|
-
if (
|
|
52036
|
+
if (unitInSegment >= 0 && (unitInSegment < vl.lengthUnits || isLastSegmentOfLine && unitInSegment <= vl.lengthUnits)) {
|
|
51979
52037
|
return i;
|
|
51980
52038
|
}
|
|
51981
52039
|
}
|
|
@@ -52361,7 +52419,14 @@ var Input = class {
|
|
|
52361
52419
|
}
|
|
52362
52420
|
setValue(value) {
|
|
52363
52421
|
this.value = value;
|
|
52364
|
-
|
|
52422
|
+
const clamped = Math.min(this.cursor, value.length);
|
|
52423
|
+
let units = 0;
|
|
52424
|
+
for (const seg of segmenter3.segment(value)) {
|
|
52425
|
+
const segLength = seg.segment.length;
|
|
52426
|
+
if (units + segLength > clamped) break;
|
|
52427
|
+
units += segLength;
|
|
52428
|
+
}
|
|
52429
|
+
this.cursor = units;
|
|
52365
52430
|
}
|
|
52366
52431
|
handleInput(data) {
|
|
52367
52432
|
if (data.includes("\x1B[200~")) {
|
|
@@ -52646,48 +52711,54 @@ var Input = class {
|
|
|
52646
52711
|
if (availableWidth <= 0) {
|
|
52647
52712
|
return [prompt];
|
|
52648
52713
|
}
|
|
52649
|
-
|
|
52650
|
-
|
|
52651
|
-
|
|
52652
|
-
|
|
52653
|
-
|
|
52654
|
-
const
|
|
52714
|
+
const cursorAtEnd = this.cursor >= this.value.length;
|
|
52715
|
+
const scrollWidth = cursorAtEnd ? Math.max(0, availableWidth - 1) : availableWidth;
|
|
52716
|
+
const valueGraphemes = [];
|
|
52717
|
+
let totalWidth = 0;
|
|
52718
|
+
for (const seg of segmenter3.segment(this.value)) {
|
|
52719
|
+
const text = seg.segment;
|
|
52720
|
+
const gWidth = visibleWidth(text);
|
|
52721
|
+
valueGraphemes.push({ text, startUnit: seg.index, startCol: totalWidth, width: gWidth });
|
|
52722
|
+
totalWidth += gWidth;
|
|
52723
|
+
}
|
|
52724
|
+
let cursorCol = 0;
|
|
52725
|
+
let cursorGraphemeIndex = valueGraphemes.length;
|
|
52726
|
+
for (let i = 0; i < valueGraphemes.length; i++) {
|
|
52727
|
+
const g2 = valueGraphemes[i];
|
|
52728
|
+
if (g2.startUnit >= this.cursor) break;
|
|
52729
|
+
cursorCol = g2.startCol + g2.width;
|
|
52730
|
+
cursorGraphemeIndex = i + 1;
|
|
52731
|
+
}
|
|
52732
|
+
const cursorCellWidth = valueGraphemes[cursorGraphemeIndex]?.width ?? 1;
|
|
52733
|
+
const cursorEndCol = cursorAtEnd ? cursorCol + 1 : cursorCol + cursorCellWidth;
|
|
52734
|
+
let startCol = 0;
|
|
52735
|
+
if (cursorEndCol > availableWidth) {
|
|
52655
52736
|
const halfWidth = Math.floor(scrollWidth / 2);
|
|
52656
|
-
|
|
52657
|
-
|
|
52658
|
-
|
|
52659
|
-
|
|
52660
|
-
start++;
|
|
52661
|
-
continue;
|
|
52662
|
-
}
|
|
52663
|
-
break;
|
|
52664
|
-
}
|
|
52665
|
-
return start;
|
|
52666
|
-
};
|
|
52667
|
-
const findValidEnd = (end) => {
|
|
52668
|
-
while (end > 0) {
|
|
52669
|
-
const charCode = this.value.charCodeAt(end - 1);
|
|
52670
|
-
if (charCode >= 55296 && charCode < 56320) {
|
|
52671
|
-
end--;
|
|
52672
|
-
continue;
|
|
52673
|
-
}
|
|
52674
|
-
break;
|
|
52675
|
-
}
|
|
52676
|
-
return end;
|
|
52677
|
-
};
|
|
52678
|
-
if (this.cursor < halfWidth) {
|
|
52679
|
-
visibleText = this.value.slice(0, findValidEnd(scrollWidth));
|
|
52680
|
-
cursorDisplay = this.cursor;
|
|
52681
|
-
} else if (this.cursor > this.value.length - halfWidth) {
|
|
52682
|
-
const start = findValidStart(this.value.length - scrollWidth);
|
|
52683
|
-
visibleText = this.value.slice(start);
|
|
52684
|
-
cursorDisplay = this.cursor - start;
|
|
52737
|
+
if (cursorCol < halfWidth) {
|
|
52738
|
+
startCol = 0;
|
|
52739
|
+
} else if (cursorEndCol > totalWidth - halfWidth) {
|
|
52740
|
+
startCol = Math.max(0, totalWidth - scrollWidth);
|
|
52685
52741
|
} else {
|
|
52686
|
-
|
|
52687
|
-
|
|
52688
|
-
|
|
52742
|
+
startCol = cursorCol - halfWidth;
|
|
52743
|
+
}
|
|
52744
|
+
startCol = Math.max(0, Math.min(startCol, cursorEndCol - scrollWidth));
|
|
52745
|
+
}
|
|
52746
|
+
const windowEnd = startCol + scrollWidth;
|
|
52747
|
+
let visibleText = "";
|
|
52748
|
+
let cursorDisplay = 0;
|
|
52749
|
+
let cursorPlaced = false;
|
|
52750
|
+
for (const g2 of valueGraphemes) {
|
|
52751
|
+
if (g2.startCol >= startCol && g2.startCol + g2.width <= windowEnd) {
|
|
52752
|
+
if (!cursorPlaced && this.cursor <= g2.startUnit) {
|
|
52753
|
+
cursorDisplay = visibleText.length;
|
|
52754
|
+
cursorPlaced = true;
|
|
52755
|
+
}
|
|
52756
|
+
visibleText += g2.text;
|
|
52689
52757
|
}
|
|
52690
52758
|
}
|
|
52759
|
+
if (!cursorPlaced) {
|
|
52760
|
+
cursorDisplay = visibleText.length;
|
|
52761
|
+
}
|
|
52691
52762
|
const graphemes = [...segmenter3.segment(visibleText.slice(cursorDisplay))];
|
|
52692
52763
|
const cursorGrapheme = graphemes[0];
|
|
52693
52764
|
const beforeCursor = visibleText.slice(0, cursorDisplay);
|
|
@@ -53981,10 +54052,15 @@ var Markdown = class {
|
|
|
53981
54052
|
}
|
|
53982
54053
|
const lineWithMargins = leftMargin + line + rightMargin;
|
|
53983
54054
|
if (bgFn) {
|
|
53984
|
-
|
|
54055
|
+
const clamped = visibleWidth(lineWithMargins) > width ? truncateToWidth(lineWithMargins, width, "") : lineWithMargins;
|
|
54056
|
+
contentLines.push(applyBackgroundToLine(clamped, width, bgFn));
|
|
53985
54057
|
} else {
|
|
53986
54058
|
const visibleLen = visibleWidth(lineWithMargins);
|
|
53987
|
-
|
|
54059
|
+
if (visibleLen > width) {
|
|
54060
|
+
contentLines.push(truncateToWidth(lineWithMargins, width, ""));
|
|
54061
|
+
continue;
|
|
54062
|
+
}
|
|
54063
|
+
const paddingNeeded = width - visibleLen;
|
|
53988
54064
|
contentLines.push(lineWithMargins + " ".repeat(paddingNeeded));
|
|
53989
54065
|
}
|
|
53990
54066
|
}
|
|
@@ -54513,7 +54589,7 @@ var SettingsList = class {
|
|
|
54513
54589
|
lines.push("");
|
|
54514
54590
|
}
|
|
54515
54591
|
if (this.items.length === 0) {
|
|
54516
|
-
lines.push(this.theme.hint(" No settings available"));
|
|
54592
|
+
lines.push(truncateToWidth(this.theme.hint(" No settings available"), width));
|
|
54517
54593
|
if (this.searchEnabled) {
|
|
54518
54594
|
this.addHintLine(lines, width);
|
|
54519
54595
|
}
|
|
@@ -54554,7 +54630,7 @@ var SettingsList = class {
|
|
|
54554
54630
|
lines.push("");
|
|
54555
54631
|
const wrappedDesc = wrapTextWithAnsi(selectedItem.description, width - 4);
|
|
54556
54632
|
for (const line of wrappedDesc) {
|
|
54557
|
-
lines.push(this.theme.description(` ${line}`));
|
|
54633
|
+
lines.push(truncateToWidth(this.theme.description(` ${line}`), width));
|
|
54558
54634
|
}
|
|
54559
54635
|
}
|
|
54560
54636
|
this.addHintLine(lines, width);
|
|
@@ -54919,6 +54995,7 @@ var ProcessTerminal = class {
|
|
|
54919
54995
|
process.stdin.setEncoding("utf8");
|
|
54920
54996
|
process.stdin.resume();
|
|
54921
54997
|
process.stdout.write("\x1B[?2004h");
|
|
54998
|
+
process.stdout.write("\x1B[?7l");
|
|
54922
54999
|
process.stdout.on("resize", this.resizeHandler);
|
|
54923
55000
|
if (process.platform !== "win32") {
|
|
54924
55001
|
process.kill(process.pid, "SIGWINCH");
|
|
@@ -55030,6 +55107,7 @@ var ProcessTerminal = class {
|
|
|
55030
55107
|
}
|
|
55031
55108
|
stop() {
|
|
55032
55109
|
process.stdout.write("\x1B[?2004l");
|
|
55110
|
+
process.stdout.write("\x1B[?7h");
|
|
55033
55111
|
if (this._kittyProtocolActive && !process.env.PIE_DISABLE_KITTY_PROTOCOL) {
|
|
55034
55112
|
process.stdout.write("\x1B[<u");
|
|
55035
55113
|
this._kittyProtocolActive = false;
|
|
@@ -55093,7 +55171,26 @@ var ProcessTerminal = class {
|
|
|
55093
55171
|
setTitle(title) {
|
|
55094
55172
|
process.stdout.write(`\x1B]0;${title}\x07`);
|
|
55095
55173
|
}
|
|
55174
|
+
notify(title, body) {
|
|
55175
|
+
if (!process.stdout.isTTY) return;
|
|
55176
|
+
for (const sequence of buildDesktopNotificationSequences(title, body)) {
|
|
55177
|
+
process.stdout.write(sequence);
|
|
55178
|
+
}
|
|
55179
|
+
}
|
|
55096
55180
|
};
|
|
55181
|
+
var NOTIFICATION_UNSAFE_CHARS = /[\x00-\x1f\x7f-\x9f;]/g;
|
|
55182
|
+
function sanitizeNotificationText(text) {
|
|
55183
|
+
return text.replace(NOTIFICATION_UNSAFE_CHARS, "");
|
|
55184
|
+
}
|
|
55185
|
+
function buildDesktopNotificationSequences(title, body) {
|
|
55186
|
+
const sanitizedTitle = sanitizeNotificationText(title);
|
|
55187
|
+
const sanitizedBody = sanitizeNotificationText(body);
|
|
55188
|
+
return [
|
|
55189
|
+
`\x1B]9;${sanitizedTitle}: ${sanitizedBody}\x07`,
|
|
55190
|
+
`\x1B]777;notify;${sanitizedTitle};${sanitizedBody}\x07`,
|
|
55191
|
+
`\x1B]99;i=1:d=0;${sanitizedBody}\x07`
|
|
55192
|
+
];
|
|
55193
|
+
}
|
|
55097
55194
|
|
|
55098
55195
|
// src/extensions/runner.ts
|
|
55099
55196
|
function createLoggedProxy(obj, contextPrefix) {
|
|
@@ -61079,6 +61176,27 @@ var SettingsSelectorComponent = class extends Container {
|
|
|
61079
61176
|
}
|
|
61080
61177
|
)
|
|
61081
61178
|
},
|
|
61179
|
+
{
|
|
61180
|
+
id: "calm",
|
|
61181
|
+
label: "Calm Mode",
|
|
61182
|
+
description: "Show only questions and answers; hide tool runs and thinking",
|
|
61183
|
+
currentValue: config.calmMode ? "on" : "off",
|
|
61184
|
+
values: ["on", "off"]
|
|
61185
|
+
},
|
|
61186
|
+
{
|
|
61187
|
+
id: "notificationsBell",
|
|
61188
|
+
label: "Bell",
|
|
61189
|
+
description: "Ring the terminal bell when a turn needs you",
|
|
61190
|
+
currentValue: config.notificationsBell ? "on" : "off",
|
|
61191
|
+
values: ["on", "off"]
|
|
61192
|
+
},
|
|
61193
|
+
{
|
|
61194
|
+
id: "notificationsDesktop",
|
|
61195
|
+
label: "Desktop Notify",
|
|
61196
|
+
description: "Desktop notification (banner / dock badge) via terminal OSC",
|
|
61197
|
+
currentValue: config.notificationsDesktop ? "on" : "off",
|
|
61198
|
+
values: ["on", "off"]
|
|
61199
|
+
},
|
|
61082
61200
|
{
|
|
61083
61201
|
id: "extensions",
|
|
61084
61202
|
label: "Extensions",
|
|
@@ -61126,6 +61244,15 @@ var SettingsSelectorComponent = class extends Container {
|
|
|
61126
61244
|
case "thinking":
|
|
61127
61245
|
callbacks.onThinkingLevelChange(newValue);
|
|
61128
61246
|
break;
|
|
61247
|
+
case "calm":
|
|
61248
|
+
callbacks.onCalmToggle(newValue === "on");
|
|
61249
|
+
break;
|
|
61250
|
+
case "notificationsBell":
|
|
61251
|
+
callbacks.onBellNotificationsChange(newValue === "on");
|
|
61252
|
+
break;
|
|
61253
|
+
case "notificationsDesktop":
|
|
61254
|
+
callbacks.onDesktopNotificationsChange(newValue === "on");
|
|
61255
|
+
break;
|
|
61129
61256
|
}
|
|
61130
61257
|
},
|
|
61131
61258
|
callbacks.onCancel,
|
|
@@ -61698,6 +61825,7 @@ function handleExtensionsCommand(host, args) {
|
|
|
61698
61825
|
|
|
61699
61826
|
// src/slash-commands.ts
|
|
61700
61827
|
var BUILTIN_SLASH_COMMANDS = [
|
|
61828
|
+
{ name: "sessions", description: "Pick a saved session to switch to" },
|
|
61701
61829
|
{ name: "sessions/compact", description: "Summarize history and add a compact checkpoint to the session" },
|
|
61702
61830
|
{ name: "sessions/new", description: "Start a new session" },
|
|
61703
61831
|
{ name: "sessions/resume", description: "Resume a different session" },
|
|
@@ -61711,6 +61839,8 @@ var BUILTIN_SLASH_COMMANDS = [
|
|
|
61711
61839
|
{ name: "settings/model", description: "Select AI model" },
|
|
61712
61840
|
{ name: "settings/theme", description: "Change theme" },
|
|
61713
61841
|
{ name: "settings/thinking", description: "Set thinking level" },
|
|
61842
|
+
{ name: "settings/calm", description: "Toggle calm mode: show only questions and answers" },
|
|
61843
|
+
{ name: "calm", description: "Alias for /settings/calm" },
|
|
61714
61844
|
{ name: "settings/yolo", description: "Toggle or set YOLO mode" },
|
|
61715
61845
|
{ name: "settings/debugs/cache-test", description: "Run provider cache diagnostics with a dedicated 2-request probe" },
|
|
61716
61846
|
{ name: "settings/debugs/context", description: "Append a context summary to ~/.pie/logs/pie-cli.log" },
|
|
@@ -62181,11 +62311,8 @@ var SessionSelectorComponent = class extends Container {
|
|
|
62181
62311
|
var RESET = "\x1B[0m";
|
|
62182
62312
|
var INVERSE = "\x1B[7m";
|
|
62183
62313
|
var DIM = "\x1B[2m";
|
|
62184
|
-
function stripAnsi(str2) {
|
|
62185
|
-
return str2.replace(/\x1b\[[0-9;]*m/g, "");
|
|
62186
|
-
}
|
|
62187
62314
|
function visibleLength(str2) {
|
|
62188
|
-
return
|
|
62315
|
+
return visibleWidth(str2);
|
|
62189
62316
|
}
|
|
62190
62317
|
var TREE_CHARS = {
|
|
62191
62318
|
branch: "\u251C\u2500\u2500 ",
|
|
@@ -62625,6 +62752,7 @@ var TreeSelectorComponent = class {
|
|
|
62625
62752
|
var AssistantMessageComponent = class extends Container {
|
|
62626
62753
|
contentContainer;
|
|
62627
62754
|
hideThinkingBlock;
|
|
62755
|
+
calmMode = false;
|
|
62628
62756
|
markdownTheme;
|
|
62629
62757
|
lastMessage;
|
|
62630
62758
|
constructor(message, hideThinkingBlock = false, markdownTheme = getMarkdownTheme()) {
|
|
@@ -62646,12 +62774,26 @@ var AssistantMessageComponent = class extends Container {
|
|
|
62646
62774
|
setHideThinkingBlock(hide) {
|
|
62647
62775
|
this.hideThinkingBlock = hide;
|
|
62648
62776
|
}
|
|
62777
|
+
/**
|
|
62778
|
+
* Calm mode: suppress thinking traces entirely (no "Thinking..." label,
|
|
62779
|
+
* no surrounding spacers). Errors and text still render.
|
|
62780
|
+
*/
|
|
62781
|
+
setCalmMode(calm) {
|
|
62782
|
+
if (this.calmMode === calm) return;
|
|
62783
|
+
this.calmMode = calm;
|
|
62784
|
+
if (this.lastMessage) {
|
|
62785
|
+
this.updateContent(this.lastMessage);
|
|
62786
|
+
}
|
|
62787
|
+
}
|
|
62788
|
+
isCalmMode() {
|
|
62789
|
+
return this.calmMode;
|
|
62790
|
+
}
|
|
62649
62791
|
updateContent(message) {
|
|
62650
62792
|
this.lastMessage = message;
|
|
62651
62793
|
this.contentContainer.clear();
|
|
62652
|
-
const
|
|
62653
|
-
|
|
62654
|
-
|
|
62794
|
+
const hasTextContent = message.content.some((c) => c.type === "text" && c.text.trim());
|
|
62795
|
+
const hasThinkingContent = message.content.some((c) => c.type === "thinking" && c.thinking.trim());
|
|
62796
|
+
const hasVisibleContent = this.calmMode ? hasTextContent : hasTextContent || hasThinkingContent;
|
|
62655
62797
|
if (hasVisibleContent) {
|
|
62656
62798
|
this.contentContainer.addChild(new Spacer(1));
|
|
62657
62799
|
}
|
|
@@ -62660,6 +62802,9 @@ var AssistantMessageComponent = class extends Container {
|
|
|
62660
62802
|
if (content.type === "text" && content.text.trim()) {
|
|
62661
62803
|
this.contentContainer.addChild(new Markdown(content.text.trim(), 1, 0, this.markdownTheme));
|
|
62662
62804
|
} else if (content.type === "thinking" && content.thinking.trim()) {
|
|
62805
|
+
if (this.calmMode) {
|
|
62806
|
+
continue;
|
|
62807
|
+
}
|
|
62663
62808
|
const hasVisibleContentAfter = message.content.slice(i + 1).some((c) => c.type === "text" && c.text.trim() || c.type === "thinking" && c.thinking.trim());
|
|
62664
62809
|
if (this.hideThinkingBlock) {
|
|
62665
62810
|
this.contentContainer.addChild(new Text(theme.italic(theme.fg("thinkingText", "Thinking...")), 1, 0));
|
|
@@ -63874,76 +64019,7 @@ async function loadSession(host, sessionId) {
|
|
|
63874
64019
|
host.lastStatusText = void 0;
|
|
63875
64020
|
host.agentSessionController?.drainQueuedInputsForEditor();
|
|
63876
64021
|
host.updatePendingMessagesDisplay();
|
|
63877
|
-
|
|
63878
|
-
const toolResultMap = /* @__PURE__ */ new Map();
|
|
63879
|
-
for (const msg of messages) {
|
|
63880
|
-
if (msg.role === "toolResult") {
|
|
63881
|
-
const toolMsg = msg;
|
|
63882
|
-
toolResultMap.set(toolMsg.toolCallId, toolMsg);
|
|
63883
|
-
}
|
|
63884
|
-
}
|
|
63885
|
-
for (const msg of messagesToShow) {
|
|
63886
|
-
if (msg.role === "user") {
|
|
63887
|
-
let content = "";
|
|
63888
|
-
if (typeof msg.content === "string") {
|
|
63889
|
-
content = msg.content;
|
|
63890
|
-
} else if (Array.isArray(msg.content)) {
|
|
63891
|
-
content = msg.content.map(textFromContentBlock).join("");
|
|
63892
|
-
}
|
|
63893
|
-
host.chatContainer.addChild(new UserMessageComponent(content));
|
|
63894
|
-
} else if (msg.role === "assistant") {
|
|
63895
|
-
const assistantMsg = msg;
|
|
63896
|
-
const contentBlocks = [];
|
|
63897
|
-
if (Array.isArray(assistantMsg.content)) {
|
|
63898
|
-
for (const c of assistantMsg.content) {
|
|
63899
|
-
if (typeof c !== "object" || !c || !("type" in c)) continue;
|
|
63900
|
-
if (c.type === "text" && "text" in c) {
|
|
63901
|
-
const text = c.text;
|
|
63902
|
-
if (text.trim()) {
|
|
63903
|
-
contentBlocks.push({ type: "text", text });
|
|
63904
|
-
}
|
|
63905
|
-
} else if (c.type === "thinking" && "thinking" in c) {
|
|
63906
|
-
const thinking = c.thinking;
|
|
63907
|
-
if (thinking.trim()) {
|
|
63908
|
-
contentBlocks.push({ type: "thinking", thinking });
|
|
63909
|
-
}
|
|
63910
|
-
}
|
|
63911
|
-
}
|
|
63912
|
-
}
|
|
63913
|
-
if (contentBlocks.length > 0) {
|
|
63914
|
-
const msgComponent = new AssistantMessageComponent(void 0, host.thinkingLevel === "off");
|
|
63915
|
-
msgComponent.updateContent({
|
|
63916
|
-
role: "assistant",
|
|
63917
|
-
content: contentBlocks
|
|
63918
|
-
});
|
|
63919
|
-
host.chatContainer.addChild(msgComponent);
|
|
63920
|
-
}
|
|
63921
|
-
if (Array.isArray(assistantMsg.content)) {
|
|
63922
|
-
for (const c of assistantMsg.content) {
|
|
63923
|
-
if (typeof c === "object" && c && "type" in c && c.type === "toolCall") {
|
|
63924
|
-
const toolCall = c;
|
|
63925
|
-
const toolId = toolCall.id || toolCall.name;
|
|
63926
|
-
const toolComponent = new ToolExecutionComponent(
|
|
63927
|
-
toolCall.name,
|
|
63928
|
-
toolCall.arguments,
|
|
63929
|
-
{ expanded: host.toolOutputExpanded },
|
|
63930
|
-
host.ui
|
|
63931
|
-
);
|
|
63932
|
-
const toolResult = toolResultMap.get(toolId);
|
|
63933
|
-
if (toolResult) {
|
|
63934
|
-
toolComponent.updateResult({
|
|
63935
|
-
content: toolResult.content,
|
|
63936
|
-
isError: toolResult.isError || false,
|
|
63937
|
-
details: toolResult.details
|
|
63938
|
-
}, false);
|
|
63939
|
-
}
|
|
63940
|
-
host.chatContainer.addChild(toolComponent);
|
|
63941
|
-
host.pendingTools.set(toolId, toolComponent);
|
|
63942
|
-
}
|
|
63943
|
-
}
|
|
63944
|
-
}
|
|
63945
|
-
}
|
|
63946
|
-
}
|
|
64022
|
+
renderChatHistory(host, messages);
|
|
63947
64023
|
if (messages.length > 50) {
|
|
63948
64024
|
host.chatContainer.addChild(new Spacer(1));
|
|
63949
64025
|
host.chatContainer.addChild(
|
|
@@ -64170,36 +64246,81 @@ async function navigateToEntry(host, entryId) {
|
|
|
64170
64246
|
);
|
|
64171
64247
|
}
|
|
64172
64248
|
}
|
|
64173
|
-
function
|
|
64174
|
-
|
|
64175
|
-
|
|
64249
|
+
function renderChatHistory(host, messages) {
|
|
64250
|
+
const messagesToShow = messages.slice(-50);
|
|
64251
|
+
const toolResultMap = /* @__PURE__ */ new Map();
|
|
64252
|
+
for (const msg of messages) {
|
|
64253
|
+
if (msg.role === "toolResult") {
|
|
64254
|
+
const toolMsg = msg;
|
|
64255
|
+
toolResultMap.set(toolMsg.toolCallId, toolMsg);
|
|
64256
|
+
}
|
|
64257
|
+
}
|
|
64258
|
+
for (const msg of messagesToShow) {
|
|
64176
64259
|
if (msg.role === "user") {
|
|
64177
|
-
let
|
|
64260
|
+
let content = "";
|
|
64178
64261
|
if (typeof msg.content === "string") {
|
|
64179
|
-
|
|
64262
|
+
content = msg.content;
|
|
64180
64263
|
} else if (Array.isArray(msg.content)) {
|
|
64181
|
-
|
|
64182
|
-
}
|
|
64183
|
-
if (text.trim()) {
|
|
64184
|
-
host.chatContainer.addChild(new UserMessageComponent(text));
|
|
64264
|
+
content = msg.content.map(textFromContentBlock).join("");
|
|
64185
64265
|
}
|
|
64266
|
+
host.chatContainer.addChild(new UserMessageComponent(content));
|
|
64186
64267
|
} else if (msg.role === "assistant") {
|
|
64187
|
-
const
|
|
64188
|
-
const
|
|
64189
|
-
|
|
64190
|
-
|
|
64191
|
-
if (c
|
|
64192
|
-
if (c.type === "
|
|
64193
|
-
|
|
64194
|
-
|
|
64195
|
-
|
|
64196
|
-
|
|
64197
|
-
|
|
64198
|
-
|
|
64199
|
-
|
|
64268
|
+
const assistantMsg = msg;
|
|
64269
|
+
const contentBlocks = [];
|
|
64270
|
+
if (Array.isArray(assistantMsg.content)) {
|
|
64271
|
+
for (const c of assistantMsg.content) {
|
|
64272
|
+
if (typeof c !== "object" || !c || !("type" in c)) continue;
|
|
64273
|
+
if (c.type === "text" && "text" in c) {
|
|
64274
|
+
const text = c.text;
|
|
64275
|
+
if (text.trim()) {
|
|
64276
|
+
contentBlocks.push({ type: "text", text });
|
|
64277
|
+
}
|
|
64278
|
+
} else if (c.type === "thinking" && "thinking" in c) {
|
|
64279
|
+
const thinking = c.thinking;
|
|
64280
|
+
if (thinking.trim()) {
|
|
64281
|
+
contentBlocks.push({ type: "thinking", thinking });
|
|
64282
|
+
}
|
|
64283
|
+
}
|
|
64284
|
+
}
|
|
64285
|
+
}
|
|
64286
|
+
if (contentBlocks.length > 0) {
|
|
64287
|
+
const msgComponent = new AssistantMessageComponent(void 0, host.thinkingLevel === "off");
|
|
64288
|
+
msgComponent.setCalmMode(host.calmMode);
|
|
64289
|
+
msgComponent.updateContent({
|
|
64290
|
+
role: "assistant",
|
|
64291
|
+
content: contentBlocks
|
|
64292
|
+
});
|
|
64293
|
+
host.chatContainer.addChild(msgComponent);
|
|
64294
|
+
}
|
|
64295
|
+
if (Array.isArray(assistantMsg.content) && !host.calmMode) {
|
|
64296
|
+
for (const c of assistantMsg.content) {
|
|
64297
|
+
if (typeof c === "object" && c && "type" in c && c.type === "toolCall") {
|
|
64298
|
+
const toolCall = c;
|
|
64299
|
+
const toolId = toolCall.id || toolCall.name;
|
|
64300
|
+
const toolComponent = new ToolExecutionComponent(
|
|
64301
|
+
toolCall.name,
|
|
64302
|
+
toolCall.arguments,
|
|
64303
|
+
{ expanded: host.toolOutputExpanded },
|
|
64304
|
+
host.ui
|
|
64305
|
+
);
|
|
64306
|
+
const toolResult = toolResultMap.get(toolId);
|
|
64307
|
+
if (toolResult) {
|
|
64308
|
+
toolComponent.updateResult({
|
|
64309
|
+
content: toolResult.content,
|
|
64310
|
+
isError: toolResult.isError || false,
|
|
64311
|
+
details: toolResult.details
|
|
64312
|
+
}, false);
|
|
64313
|
+
}
|
|
64314
|
+
host.chatContainer.addChild(toolComponent);
|
|
64315
|
+
host.pendingTools.set(toolId, toolComponent);
|
|
64316
|
+
}
|
|
64317
|
+
}
|
|
64318
|
+
}
|
|
64200
64319
|
}
|
|
64201
64320
|
}
|
|
64202
|
-
|
|
64321
|
+
}
|
|
64322
|
+
function renderMessageHistory(host, messages) {
|
|
64323
|
+
renderChatHistory(host, messages);
|
|
64203
64324
|
}
|
|
64204
64325
|
async function handleForkCommand(host) {
|
|
64205
64326
|
try {
|
|
@@ -64565,7 +64686,10 @@ function showSettingsSelector(host) {
|
|
|
64565
64686
|
availableThemes: getAvailableThemes(),
|
|
64566
64687
|
currentModel: currentFullId,
|
|
64567
64688
|
availableModels,
|
|
64568
|
-
yoloMode: host.yoloMode
|
|
64689
|
+
yoloMode: host.yoloMode,
|
|
64690
|
+
calmMode: host.calmMode,
|
|
64691
|
+
notificationsBell: host.options.settingsManager.getBellNotificationsEnabled(),
|
|
64692
|
+
notificationsDesktop: host.options.settingsManager.getDesktopNotificationsEnabled()
|
|
64569
64693
|
},
|
|
64570
64694
|
{
|
|
64571
64695
|
onThinkingLevelChange: (level) => {
|
|
@@ -64598,6 +64722,17 @@ function showSettingsSelector(host) {
|
|
|
64598
64722
|
await host.handleYoloCommand();
|
|
64599
64723
|
done();
|
|
64600
64724
|
},
|
|
64725
|
+
onCalmToggle: (enabled) => {
|
|
64726
|
+
host.setCalmMode(enabled);
|
|
64727
|
+
},
|
|
64728
|
+
onBellNotificationsChange: (enabled) => {
|
|
64729
|
+
host.options.settingsManager.setBellNotificationsEnabled(enabled);
|
|
64730
|
+
host.showStatus(`Bell notifications ${enabled ? "on" : "off"}`);
|
|
64731
|
+
},
|
|
64732
|
+
onDesktopNotificationsChange: (enabled) => {
|
|
64733
|
+
host.options.settingsManager.setDesktopNotificationsEnabled(enabled);
|
|
64734
|
+
host.showStatus(`Desktop notifications ${enabled ? "on" : "off"}`);
|
|
64735
|
+
},
|
|
64601
64736
|
createExtensionsSubmenu: (onCancel) => createExtensionSelector(host, "user", onCancel),
|
|
64602
64737
|
onHelp: () => {
|
|
64603
64738
|
host.handleHotkeysCommand();
|
|
@@ -64791,6 +64926,23 @@ function handleThinkingCommand(host, level) {
|
|
|
64791
64926
|
}
|
|
64792
64927
|
host.setThinkingLevel(level);
|
|
64793
64928
|
}
|
|
64929
|
+
async function handleCalmCommand(host, args) {
|
|
64930
|
+
const mode = (args || "").trim().toLowerCase();
|
|
64931
|
+
if (mode === "status") {
|
|
64932
|
+
host.showStatus(`Calm mode is ${host.calmMode ? "on" : "off"}`);
|
|
64933
|
+
return;
|
|
64934
|
+
}
|
|
64935
|
+
if (mode && !["on", "off", "enable", "enabled", "disable", "disabled", "true", "false", "1", "0"].includes(mode)) {
|
|
64936
|
+
host.showStatus("Usage: /settings/calm [on|off|status]");
|
|
64937
|
+
return;
|
|
64938
|
+
}
|
|
64939
|
+
const nextCalmMode = mode ? ["on", "enable", "enabled", "true", "1"].includes(mode) : !host.calmMode;
|
|
64940
|
+
if (host.calmMode === nextCalmMode) {
|
|
64941
|
+
host.showStatus(`Calm mode already ${host.calmMode ? "on" : "off"}`);
|
|
64942
|
+
return;
|
|
64943
|
+
}
|
|
64944
|
+
host.setCalmMode(nextCalmMode);
|
|
64945
|
+
}
|
|
64794
64946
|
async function handleYoloCommand(host, args) {
|
|
64795
64947
|
const mode = (args || "").trim().toLowerCase();
|
|
64796
64948
|
if (mode === "status") {
|
|
@@ -65060,6 +65212,10 @@ function createExtensionContextForCommands(host) {
|
|
|
65060
65212
|
};
|
|
65061
65213
|
}
|
|
65062
65214
|
function registerBuiltinCommands(host) {
|
|
65215
|
+
commandTree.register(["sessions"], {
|
|
65216
|
+
description: "Pick a saved session to switch to (tree/fork/new below)",
|
|
65217
|
+
handler: () => host.handleResumeCommand()
|
|
65218
|
+
});
|
|
65063
65219
|
commandTree.register(["sessions", "compact"], {
|
|
65064
65220
|
description: "Summarize history and replace it with a compact checkpoint",
|
|
65065
65221
|
handler: () => host.handleCompactCommand()
|
|
@@ -65112,6 +65268,14 @@ function registerBuiltinCommands(host) {
|
|
|
65112
65268
|
description: "Toggle or set YOLO mode (on/off/status)",
|
|
65113
65269
|
handler: (_2, args) => host.handleYoloCommand(args)
|
|
65114
65270
|
});
|
|
65271
|
+
commandTree.register(["settings", "calm"], {
|
|
65272
|
+
description: "Toggle calm mode: show only questions and answers (on/off/status)",
|
|
65273
|
+
handler: (_2, args) => host.handleCalmCommand(args)
|
|
65274
|
+
});
|
|
65275
|
+
commandTree.register(["calm"], {
|
|
65276
|
+
description: "Alias for /settings/calm (questions and answers only)",
|
|
65277
|
+
handler: (_2, args) => host.handleCalmCommand(args)
|
|
65278
|
+
});
|
|
65115
65279
|
commandTree.register(["settings", "extensions"], {
|
|
65116
65280
|
description: "List extensions and manage enable/disable toggles",
|
|
65117
65281
|
handler: (_2, args) => host.handleExtensionsCommand(args)
|
|
@@ -65307,7 +65471,37 @@ function ringTerminalBell(options = {}) {
|
|
|
65307
65471
|
function ringTurnSettledBell(host) {
|
|
65308
65472
|
if ((host.agentSessionController?.pendingMessageCount ?? 0) > 0) return;
|
|
65309
65473
|
if (host.executionState.read().awaitingContinuation) return;
|
|
65310
|
-
host.ringAttentionBell?.();
|
|
65474
|
+
host.ringAttentionBell?.("turn-settled");
|
|
65475
|
+
}
|
|
65476
|
+
function attentionMessage(reason) {
|
|
65477
|
+
switch (reason) {
|
|
65478
|
+
case "interaction":
|
|
65479
|
+
return { title: "Pie", body: "Waiting for your input" };
|
|
65480
|
+
case "turn-settled":
|
|
65481
|
+
return { title: "Pie", body: "Response ready" };
|
|
65482
|
+
case "turn-failed":
|
|
65483
|
+
return { title: "Pie", body: "Turn failed" };
|
|
65484
|
+
case "stall-recovery":
|
|
65485
|
+
return { title: "Pie", body: "Recovered from a stalled turn" };
|
|
65486
|
+
}
|
|
65487
|
+
}
|
|
65488
|
+
var DEFAULT_NOTIFICATION_MIN_INTERVAL_MS = 1e3;
|
|
65489
|
+
var lastNotificationAtMs = 0;
|
|
65490
|
+
function sendDesktopNotification(reason, options = {}) {
|
|
65491
|
+
const {
|
|
65492
|
+
enabled = true,
|
|
65493
|
+
terminal,
|
|
65494
|
+
now = Date.now,
|
|
65495
|
+
minIntervalMs = DEFAULT_NOTIFICATION_MIN_INTERVAL_MS
|
|
65496
|
+
} = options;
|
|
65497
|
+
if (!enabled) return false;
|
|
65498
|
+
if (!terminal || typeof terminal.notify !== "function") return false;
|
|
65499
|
+
const atMs = now();
|
|
65500
|
+
if (atMs - lastNotificationAtMs < minIntervalMs) return false;
|
|
65501
|
+
lastNotificationAtMs = atMs;
|
|
65502
|
+
const { title, body } = attentionMessage(reason);
|
|
65503
|
+
terminal.notify(title, body);
|
|
65504
|
+
return true;
|
|
65311
65505
|
}
|
|
65312
65506
|
|
|
65313
65507
|
// src/runtime/interactive-runtime-events.ts
|
|
@@ -65515,7 +65709,7 @@ function handleSemanticAgentEvent(host, event) {
|
|
|
65515
65709
|
host.appendWarningSummary(outcome.terminalSummary);
|
|
65516
65710
|
}
|
|
65517
65711
|
host.sessionTrace.completeTurn(event.message, true);
|
|
65518
|
-
host.ringAttentionBell?.();
|
|
65712
|
+
host.ringAttentionBell?.("turn-failed");
|
|
65519
65713
|
host._semanticTurnIndex++;
|
|
65520
65714
|
break;
|
|
65521
65715
|
}
|
|
@@ -65556,6 +65750,7 @@ function handleMessageStart(host, event) {
|
|
|
65556
65750
|
if (event.message?.role === "assistant") {
|
|
65557
65751
|
host.clearContinuationTimeout("assistant_message_start");
|
|
65558
65752
|
host.streamingComponent = new AssistantMessageComponent(void 0, host.thinkingLevel === "off");
|
|
65753
|
+
host.streamingComponent.setCalmMode(host.calmMode);
|
|
65559
65754
|
host.chatContainer.addChild(host.streamingComponent);
|
|
65560
65755
|
host.sessionTrace.updateAssistantMessage(event.message);
|
|
65561
65756
|
}
|
|
@@ -65584,6 +65779,9 @@ function handleMessageUpdate(host, event) {
|
|
|
65584
65779
|
thinkingContent += content2.thinking || "";
|
|
65585
65780
|
} else if (content2.type === "toolCall") {
|
|
65586
65781
|
toolCallCount += 1;
|
|
65782
|
+
if (host.calmMode) {
|
|
65783
|
+
continue;
|
|
65784
|
+
}
|
|
65587
65785
|
const toolCall = content2;
|
|
65588
65786
|
const contentIndex = message.content.indexOf(content2);
|
|
65589
65787
|
const partialToolId = `__partial_tool__:${contentIndex}`;
|
|
@@ -65649,7 +65847,7 @@ function findToolRenderHint(host, toolName) {
|
|
|
65649
65847
|
function handleToolStart(host, event) {
|
|
65650
65848
|
host.logDebug("tool:start", { toolName: event.toolName, toolCallId: event.toolCallId });
|
|
65651
65849
|
host.sessionTrace.startTool(event.toolCallId, event.toolName, event.args);
|
|
65652
|
-
if (event.toolCallId) {
|
|
65850
|
+
if (event.toolCallId && !host.calmMode) {
|
|
65653
65851
|
const toolComponent = host.pendingTools.get(event.toolCallId);
|
|
65654
65852
|
if (toolComponent) {
|
|
65655
65853
|
toolComponent.updateArgs(event.args);
|
|
@@ -65740,6 +65938,22 @@ function handleMessageEnd(host, event) {
|
|
|
65740
65938
|
host.safeRequestRender();
|
|
65741
65939
|
}
|
|
65742
65940
|
|
|
65941
|
+
// src/runtime/interactive-calm.ts
|
|
65942
|
+
function applyCalmMode(host, enabled) {
|
|
65943
|
+
const streaming = host.streamingComponent;
|
|
65944
|
+
if (streaming) {
|
|
65945
|
+
streaming.setCalmMode(enabled);
|
|
65946
|
+
}
|
|
65947
|
+
host.chatContainer.clear();
|
|
65948
|
+
host.pendingTools.clear();
|
|
65949
|
+
host.lastStatusSpacer = void 0;
|
|
65950
|
+
host.lastStatusText = void 0;
|
|
65951
|
+
host.renderMessageHistory(host.sessionManager.getMessages());
|
|
65952
|
+
if (streaming) {
|
|
65953
|
+
host.chatContainer.addChild(streaming);
|
|
65954
|
+
}
|
|
65955
|
+
}
|
|
65956
|
+
|
|
65743
65957
|
// src/input/interactive-input-pipeline.ts
|
|
65744
65958
|
function shouldQueueUserInput(host) {
|
|
65745
65959
|
return host.submitLock || (host.agentSessionController?.hasQueuedMessages ?? false);
|
|
@@ -67880,6 +68094,13 @@ function isCommandLikeInput(text) {
|
|
|
67880
68094
|
// src/components/extension-widgets.ts
|
|
67881
68095
|
var ExtensionWidgetsComponent = class extends Container {
|
|
67882
68096
|
slots = /* @__PURE__ */ new Map();
|
|
68097
|
+
calmMode = false;
|
|
68098
|
+
/** Calm mode hides ambient extension widgets (slots keep their data). */
|
|
68099
|
+
setCalmMode(calm) {
|
|
68100
|
+
if (this.calmMode === calm) return;
|
|
68101
|
+
this.calmMode = calm;
|
|
68102
|
+
this.rebuild();
|
|
68103
|
+
}
|
|
67883
68104
|
setWidget(key, lines) {
|
|
67884
68105
|
const normalized = (lines ?? []).map((line) => String(line ?? "")).filter((line) => line.trim().length > 0);
|
|
67885
68106
|
if (normalized.length === 0) {
|
|
@@ -67896,6 +68117,9 @@ var ExtensionWidgetsComponent = class extends Container {
|
|
|
67896
68117
|
}
|
|
67897
68118
|
rebuild() {
|
|
67898
68119
|
this.clear();
|
|
68120
|
+
if (this.calmMode) {
|
|
68121
|
+
return;
|
|
68122
|
+
}
|
|
67899
68123
|
for (const lines of this.slots.values()) {
|
|
67900
68124
|
for (const line of lines) {
|
|
67901
68125
|
this.addChild(new Text(theme.fg("dim", `\xB7 ${line}`), 1, 0));
|
|
@@ -68007,14 +68231,24 @@ var FooterComponent = class {
|
|
|
68007
68231
|
if (visibleWidth(pwd) > width) {
|
|
68008
68232
|
const half = Math.floor(width / 2) - 2;
|
|
68009
68233
|
if (half > 1) {
|
|
68010
|
-
const
|
|
68011
|
-
const
|
|
68012
|
-
|
|
68234
|
+
const total = visibleWidth(pwd);
|
|
68235
|
+
const head = sliceByColumn(pwd, 0, half);
|
|
68236
|
+
const tail = sliceByColumn(pwd, Math.max(0, total - (half - 1)), half - 1);
|
|
68237
|
+
pwd = `${head}...${tail}`;
|
|
68013
68238
|
} else {
|
|
68014
68239
|
pwd = truncateToWidth(pwd, width);
|
|
68015
68240
|
}
|
|
68016
68241
|
}
|
|
68017
68242
|
const statsParts = [];
|
|
68243
|
+
if (state.planMode) {
|
|
68244
|
+
statsParts.push(theme.fg("accent", "[PLAN]"));
|
|
68245
|
+
}
|
|
68246
|
+
if (state.calmMode) {
|
|
68247
|
+
statsParts.push(theme.fg("dim", "[CALM]"));
|
|
68248
|
+
}
|
|
68249
|
+
if (state.yoloMode) {
|
|
68250
|
+
statsParts.push(theme.fg("warning", "[YOLO]"));
|
|
68251
|
+
}
|
|
68018
68252
|
if (state.inputTokens) statsParts.push(`\u2191${formatTokens(state.inputTokens)}`);
|
|
68019
68253
|
if (state.outputTokens) statsParts.push(`\u2193${formatTokens(state.outputTokens)}`);
|
|
68020
68254
|
if (state.cacheRead) statsParts.push(`R${formatTokens(state.cacheRead)}`);
|
|
@@ -68032,12 +68266,6 @@ var FooterComponent = class {
|
|
|
68032
68266
|
statsParts.push(percentStr);
|
|
68033
68267
|
}
|
|
68034
68268
|
}
|
|
68035
|
-
if (state.planMode) {
|
|
68036
|
-
statsParts.push(theme.fg("accent", "[PLAN]"));
|
|
68037
|
-
}
|
|
68038
|
-
if (state.yoloMode) {
|
|
68039
|
-
statsParts.push(theme.fg("warning", "[YOLO]"));
|
|
68040
|
-
}
|
|
68041
68269
|
const statusColor = {
|
|
68042
68270
|
ready: "dim",
|
|
68043
68271
|
thinking: "accent",
|
|
@@ -68078,8 +68306,8 @@ var FooterComponent = class {
|
|
|
68078
68306
|
const availableForRight = width - statsLeftWidth - minPadding;
|
|
68079
68307
|
if (availableForRight > 3) {
|
|
68080
68308
|
const plainRight = rightSide.replace(/\x1b\[[0-9;]*m/g, "");
|
|
68081
|
-
const truncated = plainRight
|
|
68082
|
-
const padding = " ".repeat(width - statsLeftWidth - truncated
|
|
68309
|
+
const truncated = truncateToWidth(plainRight, availableForRight, "");
|
|
68310
|
+
const padding = " ".repeat(Math.max(0, width - statsLeftWidth - visibleWidth(truncated)));
|
|
68083
68311
|
statsLine = statsLeft + padding + truncated;
|
|
68084
68312
|
} else {
|
|
68085
68313
|
statsLine = truncateToWidth(statsLeft, width);
|
|
@@ -68096,13 +68324,27 @@ var FooterComponent = class {
|
|
|
68096
68324
|
// src/components/todo-widget.ts
|
|
68097
68325
|
var TodoWidgetComponent = class extends Container {
|
|
68098
68326
|
state;
|
|
68327
|
+
calmMode = false;
|
|
68099
68328
|
constructor(state) {
|
|
68100
68329
|
super();
|
|
68101
68330
|
this.state = state;
|
|
68102
68331
|
void this.refresh();
|
|
68103
68332
|
}
|
|
68333
|
+
/** Calm mode hides the progress widget (questions/answers only). */
|
|
68334
|
+
setCalmMode(calm) {
|
|
68335
|
+
if (this.calmMode === calm) return;
|
|
68336
|
+
this.calmMode = calm;
|
|
68337
|
+
if (calm) {
|
|
68338
|
+
this.clear();
|
|
68339
|
+
} else {
|
|
68340
|
+
void this.refresh();
|
|
68341
|
+
}
|
|
68342
|
+
}
|
|
68104
68343
|
async refresh() {
|
|
68105
68344
|
this.clear();
|
|
68345
|
+
if (this.calmMode) {
|
|
68346
|
+
return;
|
|
68347
|
+
}
|
|
68106
68348
|
const lines = renderExecutionWidgetLines(this.state.getWidgetSteps());
|
|
68107
68349
|
if (lines.length === 0) {
|
|
68108
68350
|
return;
|
|
@@ -68390,6 +68632,7 @@ function setupUI(host) {
|
|
|
68390
68632
|
modelName: host.options.model ? `${host.options.model.provider}/${host.options.model.id}` : "unknown",
|
|
68391
68633
|
status: "ready",
|
|
68392
68634
|
planMode: host.planModeEnabled,
|
|
68635
|
+
calmMode: host.calmMode,
|
|
68393
68636
|
yoloMode: Boolean(host.yoloMode),
|
|
68394
68637
|
thinkingLevel: host.thinkingLevel,
|
|
68395
68638
|
contextWindow: host.options.model?.contextWindow ?? 0
|
|
@@ -68918,7 +69161,7 @@ async function recoverHardStalledTurn(host, stalledMs) {
|
|
|
68918
69161
|
void host.refreshTodoWidget();
|
|
68919
69162
|
host.footer.setState({ status: "ready" });
|
|
68920
69163
|
host.safeRequestRender();
|
|
68921
|
-
host.ringAttentionBell?.();
|
|
69164
|
+
host.ringAttentionBell?.("stall-recovery");
|
|
68922
69165
|
appendWarningSummary(host, "Recovered from a stalled turn (no progress for " + Math.round(stalledMs / 1e3) + "s). The previous turn was interrupted; review its partial output before continuing.");
|
|
68923
69166
|
if (abortOutcome.terminalSummary) {
|
|
68924
69167
|
appendWarningSummary(host, abortOutcome.terminalSummary);
|
|
@@ -69175,7 +69418,7 @@ function createInteractiveAgentSessionController(host) {
|
|
|
69175
69418
|
host.showStatus("Todo list preserved. Send 'continue' when you want to resume it.");
|
|
69176
69419
|
}
|
|
69177
69420
|
host.showError(event.failure.message);
|
|
69178
|
-
host.ringAttentionBell?.();
|
|
69421
|
+
host.ringAttentionBell?.("turn-failed");
|
|
69179
69422
|
host.setControllerBusy(false);
|
|
69180
69423
|
} else if (event.type === "turn_cancelled") {
|
|
69181
69424
|
const outcome = host.executionState.abort();
|
|
@@ -69554,7 +69797,7 @@ function installInteractiveInteractionHandler(host) {
|
|
|
69554
69797
|
host.activeInteractionCount++;
|
|
69555
69798
|
host.setWaitingForUser(true);
|
|
69556
69799
|
host.footer.setState({ lifecycleEvent: "waiting_for_user_input" });
|
|
69557
|
-
host.ringAttentionBell?.();
|
|
69800
|
+
host.ringAttentionBell?.("interaction");
|
|
69558
69801
|
host.safeRequestRender();
|
|
69559
69802
|
};
|
|
69560
69803
|
const endWaitingForUser = () => {
|
|
@@ -70164,6 +70407,8 @@ var InteractiveMode = class {
|
|
|
70164
70407
|
mentionPickerOptions = [];
|
|
70165
70408
|
attachmentResolver;
|
|
70166
70409
|
yoloMode = false;
|
|
70410
|
+
/** Calm mode: render only questions and answers (display-only; persisted). */
|
|
70411
|
+
calmMode = false;
|
|
70167
70412
|
originalTools = [];
|
|
70168
70413
|
isInterrupting = false;
|
|
70169
70414
|
isCompacting = false;
|
|
@@ -70214,9 +70459,17 @@ var InteractiveMode = class {
|
|
|
70214
70459
|
* interaction prompts, turn completion/failure, and stall recovery. The
|
|
70215
70460
|
* bell itself enforces a cross-call-site cooldown; the settings gate here
|
|
70216
70461
|
* is the single opt-out point (settings.json `notifications.bell`).
|
|
70462
|
+
*
|
|
70463
|
+
* A desktop notification (OSC 9/777/99, gated by `notifications.desktop`)
|
|
70464
|
+
* rides along so the host terminal app can badge its dock icon / post a
|
|
70465
|
+
* notification-center banner — the persistent marker the bell can't give.
|
|
70217
70466
|
*/
|
|
70218
|
-
ringAttentionBell() {
|
|
70467
|
+
ringAttentionBell(reason) {
|
|
70219
70468
|
ringTerminalBell({ enabled: this.options.settingsManager.getBellNotificationsEnabled() });
|
|
70469
|
+
sendDesktopNotification(reason ?? "turn-settled", {
|
|
70470
|
+
enabled: this.options.settingsManager.getDesktopNotificationsEnabled(),
|
|
70471
|
+
terminal: this.ui.terminal
|
|
70472
|
+
});
|
|
70220
70473
|
}
|
|
70221
70474
|
getContinuationTimeoutMs() {
|
|
70222
70475
|
return getContinuationTimeoutMs();
|
|
@@ -70266,6 +70519,7 @@ var InteractiveMode = class {
|
|
|
70266
70519
|
this.originalTools = [...options.allTools];
|
|
70267
70520
|
this.skillsSection = formatSkillsForPrompt(options.skills);
|
|
70268
70521
|
this.knowledgeSection = buildCliProjectContextSection(options.cwd);
|
|
70522
|
+
this.calmMode = options.settingsManager.getCalmModeEnabled();
|
|
70269
70523
|
}
|
|
70270
70524
|
options;
|
|
70271
70525
|
get runtimeEventHost() {
|
|
@@ -70664,6 +70918,25 @@ var InteractiveMode = class {
|
|
|
70664
70918
|
async handleYoloCommand(args) {
|
|
70665
70919
|
return handleYoloCommand(this, args);
|
|
70666
70920
|
}
|
|
70921
|
+
/**
|
|
70922
|
+
* Toggle calm mode and rebuild the chat so already-rendered rows follow
|
|
70923
|
+
* the new mode. Delivery, tool execution, and session storage are
|
|
70924
|
+
* unaffected — this is purely a presentation change.
|
|
70925
|
+
*/
|
|
70926
|
+
setCalmMode(enabled) {
|
|
70927
|
+
if (this.calmMode === enabled) return;
|
|
70928
|
+
this.calmMode = enabled;
|
|
70929
|
+
this.options.settingsManager.setCalmModeEnabled(enabled);
|
|
70930
|
+
this.footer.setState({ calmMode: enabled });
|
|
70931
|
+
applyCalmMode(this, enabled);
|
|
70932
|
+
this.todoWidget.setCalmMode(enabled);
|
|
70933
|
+
this.extensionWidgets.setCalmMode(enabled);
|
|
70934
|
+
this.showStatus(`Calm mode ${enabled ? "on \u2014 showing questions and answers only" : "off"}`);
|
|
70935
|
+
this.safeRequestRender();
|
|
70936
|
+
}
|
|
70937
|
+
async handleCalmCommand(args) {
|
|
70938
|
+
return handleCalmCommand(this, args);
|
|
70939
|
+
}
|
|
70667
70940
|
setThinkingLevel(level) {
|
|
70668
70941
|
return setThinkingLevel(this, level);
|
|
70669
70942
|
}
|
|
@@ -72925,6 +73198,7 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
72925
73198
|
}
|
|
72926
73199
|
flushEarlyLogs();
|
|
72927
73200
|
if (testCommand) {
|
|
73201
|
+
await interactive.run();
|
|
72928
73202
|
console.log(`[TEST] Auto-executing command: ${testCommand}`);
|
|
72929
73203
|
await new Promise((resolve7) => setTimeout(resolve7, 500));
|
|
72930
73204
|
await interactive.executeCommand(testCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cydm/pie",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.44",
|
|
4
4
|
"description": "Pie AI Agent CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"test": "npm run test:offline",
|
|
19
19
|
"pretest:offline": "npm run build --workspace @pie/agent-framework && npm run build --workspace @pie/shared-headless-capabilities && npm run build",
|
|
20
20
|
"posttest:offline": "node --test --import tsx test/remote-model-catalog.test.ts",
|
|
21
|
-
"test:offline": "node --test --import tsx test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-extension.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/hierarchical-command-system.test.ts test/extensions-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/daily-agent-smoke.terminal.test.ts",
|
|
21
|
+
"test:offline": "node --test --import tsx test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-extension.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/hierarchical-command-system.test.ts test/extensions-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/calm-mode.test.ts test/project-root.test.ts test/daily-agent-smoke.terminal.test.ts",
|
|
22
22
|
"test:all": "npm run test:offline && npm run test:terminal:vitest",
|
|
23
|
-
"test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/viewport-position-final.test.ts --no-file-parallelism",
|
|
23
|
+
"test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/viewport-position-final.test.ts test/resume-header.terminal.test.ts --no-file-parallelism",
|
|
24
24
|
"test:todo-tui": "PIE_REAL_TODO_TUI=1 node --test --import tsx test/todo-closure.terminal.test.ts",
|
|
25
25
|
"test:daily-tui": "npm run test:daily-tui:quick",
|
|
26
26
|
"test:daily-tui:quick": "PIE_REAL_DAILY_TUI=1 PIE_DAILY_TUI_LEVEL=quick node --test --import tsx test/daily-agent-smoke.terminal.test.ts",
|