@kenkaiiii/ggcoder 4.3.225 → 4.3.226
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/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +18 -5
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/assistant-stream-flush-parity.test.d.ts +2 -0
- package/dist/ui/assistant-stream-flush-parity.test.d.ts.map +1 -0
- package/dist/ui/assistant-stream-flush-parity.test.js +85 -0
- package/dist/ui/assistant-stream-flush-parity.test.js.map +1 -0
- package/dist/ui/components/ChatLayout.d.ts +8 -1
- package/dist/ui/components/ChatLayout.d.ts.map +1 -1
- package/dist/ui/components/ChatLayout.js +4 -2
- package/dist/ui/components/ChatLayout.js.map +1 -1
- package/dist/ui/components/ChatLivePane.d.ts.map +1 -1
- package/dist/ui/components/ChatLivePane.js +15 -1
- package/dist/ui/components/ChatLivePane.js.map +1 -1
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +1 -3
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/SelectList.d.ts.map +1 -1
- package/dist/ui/components/SelectList.js +5 -0
- package/dist/ui/components/SelectList.js.map +1 -1
- package/dist/ui/components/SlashStyledSelectList.d.ts.map +1 -1
- package/dist/ui/components/SlashStyledSelectList.js +5 -0
- package/dist/ui/components/SlashStyledSelectList.js.map +1 -1
- package/dist/ui/components/ToolGroupExecution.d.ts +5 -2
- package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolGroupExecution.js +3 -3
- package/dist/ui/components/ToolGroupExecution.js.map +1 -1
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js +4 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
- package/dist/ui/live-area-clamp.test.d.ts +2 -0
- package/dist/ui/live-area-clamp.test.d.ts.map +1 -0
- package/dist/ui/live-area-clamp.test.js +79 -0
- package/dist/ui/live-area-clamp.test.js.map +1 -0
- package/dist/ui/live-area-height.d.ts +35 -0
- package/dist/ui/live-area-height.d.ts.map +1 -0
- package/dist/ui/live-area-height.js +75 -0
- package/dist/ui/live-area-height.js.map +1 -0
- package/dist/ui/live-area-height.test.d.ts +2 -0
- package/dist/ui/live-area-height.test.d.ts.map +1 -0
- package/dist/ui/live-area-height.test.js +67 -0
- package/dist/ui/live-area-height.test.js.map +1 -0
- package/dist/ui/live-frame-height.test.d.ts +2 -0
- package/dist/ui/live-frame-height.test.d.ts.map +1 -0
- package/dist/ui/live-frame-height.test.js +91 -0
- package/dist/ui/live-frame-height.test.js.map +1 -0
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +13 -4
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/terminal-history.test.js +9 -9
- package/dist/ui/terminal-history.test.js.map +1 -1
- package/dist/ui/tool-group-summary.d.ts +9 -1
- package/dist/ui/tool-group-summary.d.ts.map +1 -1
- package/dist/ui/tool-group-summary.js +7 -6
- package/dist/ui/tool-group-summary.js.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +10 -2
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/spacing.d.ts +15 -5
- package/dist/ui/transcript/spacing.d.ts.map +1 -1
- package/dist/ui/transcript/spacing.js +35 -18
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.d.ts +17 -0
- package/dist/ui/utils/assistant-stream-split.d.ts.map +1 -1
- package/dist/ui/utils/assistant-stream-split.js +38 -1
- package/dist/ui/utils/assistant-stream-split.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.test.js +29 -6
- package/dist/ui/utils/assistant-stream-split.test.js.map +1 -1
- package/dist/ui/utils/terminal-input.d.ts +3 -0
- package/dist/ui/utils/terminal-input.d.ts.map +1 -0
- package/dist/ui/utils/terminal-input.js +28 -0
- package/dist/ui/utils/terminal-input.js.map +1 -0
- package/dist/ui/utils/terminal-input.test.d.ts +2 -0
- package/dist/ui/utils/terminal-input.test.d.ts.map +1 -0
- package/dist/ui/utils/terminal-input.test.js +15 -0
- package/dist/ui/utils/terminal-input.test.js.map +1 -0
- package/package.json +12 -4
|
@@ -34,18 +34,14 @@ const COMPACT_TRANSCRIPT_BOUNDARIES = new Set([
|
|
|
34
34
|
"assistant→user",
|
|
35
35
|
"user→queued",
|
|
36
36
|
"assistant→assistant",
|
|
37
|
-
"assistant→tool_start",
|
|
38
|
-
"assistant→tool_done",
|
|
39
|
-
"assistant→tool_group",
|
|
40
|
-
"tool_start→tool_done",
|
|
41
|
-
"tool_done→tool_start",
|
|
42
|
-
"tool_done→tool_done",
|
|
43
|
-
"tool_group→tool_start",
|
|
44
|
-
"tool_group→tool_done",
|
|
45
|
-
"tool_group→tool_group",
|
|
46
37
|
]);
|
|
47
|
-
export function shouldSeparateTranscriptItems({ previousKind, currentKind, }) {
|
|
48
|
-
return shouldSeparateTranscriptItemKinds({
|
|
38
|
+
export function shouldSeparateTranscriptItems({ previousKind, currentKind, spacingKinds, compactBoundaries, }) {
|
|
39
|
+
return shouldSeparateTranscriptItemKinds({
|
|
40
|
+
previousKind,
|
|
41
|
+
currentKind,
|
|
42
|
+
spacingKinds,
|
|
43
|
+
compactBoundaries,
|
|
44
|
+
});
|
|
49
45
|
}
|
|
50
46
|
export function shouldSeparateTranscriptItemKinds({ previousKind, currentKind, spacingKinds = TRANSCRIPT_SPACING_KIND_SET, compactBoundaries = COMPACT_TRANSCRIPT_BOUNDARIES, }) {
|
|
51
47
|
if (previousKind === undefined)
|
|
@@ -60,19 +56,29 @@ export function isTranscriptSpacingKind(kind) {
|
|
|
60
56
|
export function isTranscriptSpacingItem(item) {
|
|
61
57
|
return isTranscriptSpacingKind(item.kind);
|
|
62
58
|
}
|
|
63
|
-
export function shouldTopSpaceAfterPrintedTranscriptBoundary({ currentKind, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, }) {
|
|
59
|
+
export function shouldTopSpaceAfterPrintedTranscriptBoundary({ currentKind, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, spacingKinds, compactBoundaries, }) {
|
|
64
60
|
if (previousLiveItem !== undefined)
|
|
65
61
|
return false;
|
|
66
62
|
const previousKind = lastPendingHistoryItem?.kind ?? lastHistoryItem?.kind;
|
|
67
|
-
return shouldSeparateTranscriptItems({
|
|
63
|
+
return shouldSeparateTranscriptItems({
|
|
64
|
+
previousKind,
|
|
65
|
+
currentKind,
|
|
66
|
+
spacingKinds,
|
|
67
|
+
compactBoundaries,
|
|
68
|
+
});
|
|
68
69
|
}
|
|
69
|
-
export function shouldTopSpaceAssistantAfterToolBoundary({ text, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, }) {
|
|
70
|
+
export function shouldTopSpaceAssistantAfterToolBoundary({ text, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, spacingKinds, compactBoundaries, }) {
|
|
70
71
|
if (text.trim().length === 0)
|
|
71
72
|
return false;
|
|
72
73
|
const previousKind = previousLiveItem?.kind ?? lastPendingHistoryItem?.kind ?? lastHistoryItem?.kind;
|
|
73
|
-
return shouldSeparateTranscriptItems({
|
|
74
|
+
return shouldSeparateTranscriptItems({
|
|
75
|
+
previousKind,
|
|
76
|
+
currentKind: "assistant",
|
|
77
|
+
spacingKinds,
|
|
78
|
+
compactBoundaries,
|
|
79
|
+
});
|
|
74
80
|
}
|
|
75
|
-
export function getTranscriptItemMarginTop({ item, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, }) {
|
|
81
|
+
export function getTranscriptItemMarginTop({ item, previousLiveItem, lastPendingHistoryItem, lastHistoryItem, spacingKinds, compactBoundaries, }) {
|
|
76
82
|
const previousKind = previousLiveItem?.kind ?? lastPendingHistoryItem?.kind ?? lastHistoryItem?.kind;
|
|
77
83
|
if (item.kind === "assistant") {
|
|
78
84
|
return shouldTopSpaceAssistantAfterToolBoundary({
|
|
@@ -80,20 +86,31 @@ export function getTranscriptItemMarginTop({ item, previousLiveItem, lastPending
|
|
|
80
86
|
previousLiveItem,
|
|
81
87
|
lastPendingHistoryItem,
|
|
82
88
|
lastHistoryItem,
|
|
89
|
+
spacingKinds,
|
|
90
|
+
compactBoundaries,
|
|
83
91
|
})
|
|
84
92
|
? 1
|
|
85
93
|
: 0;
|
|
86
94
|
}
|
|
87
95
|
if (item.kind === "plan_transition")
|
|
88
96
|
return 0;
|
|
89
|
-
return shouldSeparateTranscriptItems({
|
|
97
|
+
return shouldSeparateTranscriptItems({
|
|
98
|
+
previousKind,
|
|
99
|
+
currentKind: item.kind,
|
|
100
|
+
spacingKinds,
|
|
101
|
+
compactBoundaries,
|
|
102
|
+
})
|
|
103
|
+
? 1
|
|
104
|
+
: 0;
|
|
90
105
|
}
|
|
91
|
-
export function shouldTopSpaceStreamingAssistant({ visibleStreamingText, lastLiveItem, lastPendingHistoryItem, lastHistoryItem, }) {
|
|
106
|
+
export function shouldTopSpaceStreamingAssistant({ visibleStreamingText, lastLiveItem, lastPendingHistoryItem, lastHistoryItem, spacingKinds, compactBoundaries, }) {
|
|
92
107
|
return shouldTopSpaceAssistantAfterToolBoundary({
|
|
93
108
|
text: visibleStreamingText,
|
|
94
109
|
previousLiveItem: lastLiveItem,
|
|
95
110
|
lastPendingHistoryItem,
|
|
96
111
|
lastHistoryItem,
|
|
112
|
+
spacingKinds,
|
|
113
|
+
compactBoundaries,
|
|
97
114
|
});
|
|
98
115
|
}
|
|
99
116
|
//# sourceMappingURL=spacing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spacing.js","sourceRoot":"","sources":["../../../src/ui/transcript/spacing.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,MAAM;IACN,WAAW;IACX,QAAQ;IACR,MAAM;IACN,MAAM;IACN,eAAe;IACf,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,MAAM;IACN,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,uBAAuB;IACvB,kBAAkB;IAClB,kBAAkB;IAClB,YAAY;IACZ,eAAe;IACf,YAAY;IACZ,WAAW;IACX,UAAU;IACV,WAAW;IACX,YAAY;IACZ,YAAY;CACuC,CAAC;AAEtD,MAAM,CAAC,MAAM,gCAAgC,GAAG,wBAAwB,CAAC;AAEzE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE9E,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAS;IACpD,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,qBAAqB;
|
|
1
|
+
{"version":3,"file":"spacing.js","sourceRoot":"","sources":["../../../src/ui/transcript/spacing.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,MAAM;IACN,WAAW;IACX,QAAQ;IACR,MAAM;IACN,MAAM;IACN,eAAe;IACf,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;IAChB,MAAM;IACN,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,uBAAuB;IACvB,kBAAkB;IAClB,kBAAkB;IAClB,YAAY;IACZ,eAAe;IACf,YAAY;IACZ,WAAW;IACX,UAAU;IACV,WAAW;IACX,YAAY;IACZ,YAAY;CACuC,CAAC;AAEtD,MAAM,CAAC,MAAM,gCAAgC,GAAG,wBAAwB,CAAC;AAEzE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE9E,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAS;IACpD,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,qBAAqB;CACtB,CAAC,CAAC;AAEH,MAAM,UAAU,6BAA6B,CAAC,EAC5C,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,iBAAiB,GAMlB;IACC,OAAO,iCAAiC,CAAC;QACvC,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,EAChD,YAAY,EACZ,WAAW,EACX,YAAY,GAAG,2BAA2B,EAC1C,iBAAiB,GAAG,6BAA6B,GAMlD;IACC,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACpF,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,YAAY,IAAI,WAAW,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,2BAA2B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAA2B;IACjE,OAAO,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,4CAA4C,CAAC,EAC3D,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,iBAAiB,GAQlB;IACC,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,YAAY,GAAG,sBAAsB,EAAE,IAAI,IAAI,eAAe,EAAE,IAAI,CAAC;IAC3E,OAAO,6BAA6B,CAAC;QACnC,YAAY;QACZ,WAAW;QACX,YAAY;QACZ,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wCAAwC,CAAC,EACvD,IAAI,EACJ,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,iBAAiB,GAQlB;IACC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,YAAY,GAChB,gBAAgB,EAAE,IAAI,IAAI,sBAAsB,EAAE,IAAI,IAAI,eAAe,EAAE,IAAI,CAAC;IAClF,OAAO,6BAA6B,CAAC;QACnC,YAAY;QACZ,WAAW,EAAE,WAAW;QACxB,YAAY;QACZ,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,EACzC,IAAI,EACJ,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,iBAAiB,GAQlB;IACC,MAAM,YAAY,GAChB,gBAAgB,EAAE,IAAI,IAAI,sBAAsB,EAAE,IAAI,IAAI,eAAe,EAAE,IAAI,CAAC;IAClF,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO,wCAAwC,CAAC;YAC9C,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACpD,gBAAgB;YAChB,sBAAsB;YACtB,eAAe;YACf,YAAY;YACZ,iBAAiB;SAClB,CAAC;YACA,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAC;IACR,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,6BAA6B,CAAC;QACnC,YAAY;QACZ,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,YAAY;QACZ,iBAAiB;KAClB,CAAC;QACA,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,EAC/C,oBAAoB,EACpB,YAAY,EACZ,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,iBAAiB,GAQlB;IACC,OAAO,wCAAwC,CAAC;QAC9C,IAAI,EAAE,oBAAoB;QAC1B,gBAAgB,EAAE,YAAY;QAC9B,sBAAsB;QACtB,eAAe;QACf,YAAY;QACZ,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -2,5 +2,22 @@ export interface AssistantStreamSplit {
|
|
|
2
2
|
flushedText: string;
|
|
3
3
|
remainingText: string;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Decide how much of the in-flight assistant text can be flushed to terminal
|
|
7
|
+
* scrollback while streaming, keeping the trailing in-progress block live.
|
|
8
|
+
*
|
|
9
|
+
* Flushing progressively (instead of dumping the whole response at the end)
|
|
10
|
+
* keeps the live region small so it never has to scroll the full response into
|
|
11
|
+
* scrollback in one shot — that single large write is what makes the TUI
|
|
12
|
+
* "jump up" when the agent finishes.
|
|
13
|
+
*
|
|
14
|
+
* Splits ONLY at paragraph boundaries (blank lines) that sit OUTSIDE code
|
|
15
|
+
* fences, and never trims interior whitespace, so each flushed chunk is a
|
|
16
|
+
* self-contained set of Markdown blocks that renders identically whether shown
|
|
17
|
+
* alone in history or as part of the whole response. (An earlier version split
|
|
18
|
+
* mid-sentence and trimmed whitespace, which broke live/history parity.)
|
|
19
|
+
*
|
|
20
|
+
* Guarantees `flushedText + remainingText === text`.
|
|
21
|
+
*/
|
|
5
22
|
export declare function splitAssistantStreamingText(text: string): AssistantStreamSplit;
|
|
6
23
|
//# sourceMappingURL=assistant-stream-split.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-stream-split.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"assistant-stream-split.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAOD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAe9E"}
|
|
@@ -1,4 +1,41 @@
|
|
|
1
|
+
function isInsideCodeFence(text) {
|
|
2
|
+
const fenceMatches = text.match(/^\s*(`{3,}|~{3,})/gm);
|
|
3
|
+
return (fenceMatches?.length ?? 0) % 2 === 1;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Decide how much of the in-flight assistant text can be flushed to terminal
|
|
7
|
+
* scrollback while streaming, keeping the trailing in-progress block live.
|
|
8
|
+
*
|
|
9
|
+
* Flushing progressively (instead of dumping the whole response at the end)
|
|
10
|
+
* keeps the live region small so it never has to scroll the full response into
|
|
11
|
+
* scrollback in one shot — that single large write is what makes the TUI
|
|
12
|
+
* "jump up" when the agent finishes.
|
|
13
|
+
*
|
|
14
|
+
* Splits ONLY at paragraph boundaries (blank lines) that sit OUTSIDE code
|
|
15
|
+
* fences, and never trims interior whitespace, so each flushed chunk is a
|
|
16
|
+
* self-contained set of Markdown blocks that renders identically whether shown
|
|
17
|
+
* alone in history or as part of the whole response. (An earlier version split
|
|
18
|
+
* mid-sentence and trimmed whitespace, which broke live/history parity.)
|
|
19
|
+
*
|
|
20
|
+
* Guarantees `flushedText + remainingText === text`.
|
|
21
|
+
*/
|
|
1
22
|
export function splitAssistantStreamingText(text) {
|
|
2
|
-
|
|
23
|
+
const boundary = /\n[ \t]*\n/g;
|
|
24
|
+
let best = -1;
|
|
25
|
+
let match;
|
|
26
|
+
while ((match = boundary.exec(text)) !== null) {
|
|
27
|
+
const boundaryEnd = match.index + match[0].length;
|
|
28
|
+
// Keep the trailing block live until it too ends in a blank line.
|
|
29
|
+
if (boundaryEnd >= text.length)
|
|
30
|
+
break;
|
|
31
|
+
// Never split inside an open code fence — the chunk would render as broken
|
|
32
|
+
// Markdown (unterminated fence) in history.
|
|
33
|
+
if (isInsideCodeFence(text.slice(0, boundaryEnd)))
|
|
34
|
+
continue;
|
|
35
|
+
best = boundaryEnd;
|
|
36
|
+
}
|
|
37
|
+
if (best <= 0)
|
|
38
|
+
return { flushedText: "", remainingText: text };
|
|
39
|
+
return { flushedText: text.slice(0, best), remainingText: text.slice(best) };
|
|
3
40
|
}
|
|
4
41
|
//# sourceMappingURL=assistant-stream-split.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-stream-split.js","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,2BAA2B,CAAC,IAAY;IACtD,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"assistant-stream-split.js","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.ts"],"names":[],"mappings":"AAKA,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACvD,OAAO,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAY;IACtD,MAAM,QAAQ,GAAG,aAAa,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAClD,kEAAkE;QAClE,IAAI,WAAW,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM;QACtC,2EAA2E;QAC3E,4CAA4C;QAC5C,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YAAE,SAAS;QAC5D,IAAI,GAAG,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC/D,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AAC/E,CAAC"}
|
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { splitAssistantStreamingText } from "./assistant-stream-split.js";
|
|
3
3
|
describe("splitAssistantStreamingText", () => {
|
|
4
|
-
it("keeps
|
|
4
|
+
it("keeps single-block text live (nothing to flush yet)", () => {
|
|
5
5
|
const cases = [
|
|
6
|
-
"Dr. Jones keeps a notebook full of odd theories and coffee stains.
|
|
7
|
-
"1. Dr. Jones keeps a spare notebook.\n2. Dr. Jones believes every mystery deserves coffee
|
|
8
|
-
"- Dr. Jones once labeled an entire filing cabinet important.\n- Dr. Jones explains
|
|
9
|
-
"Paragraph one has a line break.\n\nParagraph two must preserve that exact break.\n\nParagraph three too.",
|
|
10
|
-
"Here is code:\n\n```ts\nconst one = 1;\nconst two = 2;\n```\n\nDone.",
|
|
6
|
+
"Dr. Jones keeps a notebook full of odd theories and coffee stains.",
|
|
7
|
+
"1. Dr. Jones keeps a spare notebook.\n2. Dr. Jones believes every mystery deserves coffee.",
|
|
8
|
+
"- Dr. Jones once labeled an entire filing cabinet important.\n- Dr. Jones explains with metaphors.",
|
|
11
9
|
];
|
|
12
10
|
for (const text of cases) {
|
|
13
11
|
expect(splitAssistantStreamingText(text)).toEqual({ flushedText: "", remainingText: text });
|
|
14
12
|
}
|
|
15
13
|
});
|
|
14
|
+
it("flushes completed paragraphs and keeps the trailing block live", () => {
|
|
15
|
+
const text = "Paragraph one.\n\nParagraph two.\n\nParagraph three in progress";
|
|
16
|
+
const { flushedText, remainingText } = splitAssistantStreamingText(text);
|
|
17
|
+
expect(flushedText).toBe("Paragraph one.\n\nParagraph two.\n\n");
|
|
18
|
+
expect(remainingText).toBe("Paragraph three in progress");
|
|
19
|
+
});
|
|
20
|
+
it("is lossless: flushedText + remainingText === text", () => {
|
|
21
|
+
const text = "A.\n\nB.\n\nC still going";
|
|
22
|
+
const { flushedText, remainingText } = splitAssistantStreamingText(text);
|
|
23
|
+
expect(flushedText + remainingText).toBe(text);
|
|
24
|
+
});
|
|
25
|
+
it("never splits at a blank line inside an open code fence", () => {
|
|
26
|
+
// The blank line between the two consts is inside an unterminated fence and
|
|
27
|
+
// must not be a split point; only the paragraph break before the fence is.
|
|
28
|
+
const text = "Here is code:\n\n```ts\nconst one = 1;\n\nconst two = 2;";
|
|
29
|
+
const { flushedText, remainingText } = splitAssistantStreamingText(text);
|
|
30
|
+
expect(flushedText).toBe("Here is code:\n\n");
|
|
31
|
+
expect(remainingText).toBe("```ts\nconst one = 1;\n\nconst two = 2;");
|
|
32
|
+
});
|
|
33
|
+
it("flushes past a closed code fence", () => {
|
|
34
|
+
const text = "Intro.\n\n```ts\nconst x = 1;\n```\n\nTrailing in progress";
|
|
35
|
+
const { flushedText, remainingText } = splitAssistantStreamingText(text);
|
|
36
|
+
expect(flushedText).toBe("Intro.\n\n```ts\nconst x = 1;\n```\n\n");
|
|
37
|
+
expect(remainingText).toBe("Trailing in progress");
|
|
38
|
+
});
|
|
16
39
|
});
|
|
17
40
|
//# sourceMappingURL=assistant-stream-split.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-stream-split.test.js","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAE1E,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"assistant-stream-split.test.js","sourceRoot":"","sources":["../../../src/ui/utils/assistant-stream-split.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAE1E,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,KAAK,GAAG;YACZ,oEAAoE;YACpE,4FAA4F;YAC5F,oGAAoG;SACrG,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,IAAI,GAAG,iEAAiE,CAAC;QAC/E,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACjE,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,IAAI,GAAG,2BAA2B,CAAC;QACzC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,4EAA4E;QAC5E,2EAA2E;QAC3E,MAAM,IAAI,GAAG,0DAA0D,CAAC;QACxE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,IAAI,GAAG,4DAA4D,CAAC;QAC1E,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACnE,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-input.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/terminal-input.ts"],"names":[],"mappings":"AAWA,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBjE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Terminal focus reporting emits CSI I / CSI O when the terminal window gains
|
|
2
|
+
// or loses focus. In normal raw input these arrive as ESC [ I and ESC [ O, but
|
|
3
|
+
// some terminal/Ink/tmux combinations can split or strip the ESC byte so the
|
|
4
|
+
// application sees literal "[I" / "[O" chunks. If those reach text inputs or
|
|
5
|
+
// filterable selectors they become visible garbage like `[I[O[I`.
|
|
6
|
+
const ESC = String.fromCharCode(27);
|
|
7
|
+
const ESC_FOCUS_GAINED = `${ESC}[I`;
|
|
8
|
+
const ESC_FOCUS_LOST = `${ESC}[O`;
|
|
9
|
+
const ESC_LESS_FOCUS_GAINED = "[I";
|
|
10
|
+
const ESC_LESS_FOCUS_LOST = "[O";
|
|
11
|
+
export function stripTerminalFocusSequences(input) {
|
|
12
|
+
const withoutEscFocusReports = input
|
|
13
|
+
.replaceAll(ESC_FOCUS_GAINED, "")
|
|
14
|
+
.replaceAll(ESC_FOCUS_LOST, "");
|
|
15
|
+
let remaining = withoutEscFocusReports;
|
|
16
|
+
while (remaining.length > 0) {
|
|
17
|
+
if (remaining.startsWith(ESC_LESS_FOCUS_GAINED) || remaining.startsWith(ESC_LESS_FOCUS_LOST)) {
|
|
18
|
+
remaining = remaining.slice(2);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
return withoutEscFocusReports;
|
|
22
|
+
}
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
export function isTerminalFocusSequence(input) {
|
|
26
|
+
return stripTerminalFocusSequences(input).length === 0 && input.length > 0;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=terminal-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-input.js","sourceRoot":"","sources":["../../../src/ui/utils/terminal-input.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,kEAAkE;AAClE,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AACpC,MAAM,gBAAgB,GAAG,GAAG,GAAG,IAAI,CAAC;AACpC,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;AAClC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,MAAM,sBAAsB,GAAG,KAAK;SACjC,UAAU,CAAC,gBAAgB,EAAE,EAAE,CAAC;SAChC,UAAU,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAClC,IAAI,SAAS,GAAG,sBAAsB,CAAC;IAEvC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,SAAS,CAAC,UAAU,CAAC,qBAAqB,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC7F,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,2BAA2B,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-input.test.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/terminal-input.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { isTerminalFocusSequence, stripTerminalFocusSequences } from "./terminal-input.js";
|
|
3
|
+
describe("terminal focus-report input sanitizing", () => {
|
|
4
|
+
it("removes normal and ESC-less focus reports", () => {
|
|
5
|
+
expect(stripTerminalFocusSequences("\x1b[I\x1b[O\x1b[I")).toBe("");
|
|
6
|
+
expect(stripTerminalFocusSequences("[I[O[I")).toBe("");
|
|
7
|
+
expect(stripTerminalFocusSequences("a[I\x1b[Ob")).toBe("a[Ib");
|
|
8
|
+
});
|
|
9
|
+
it("detects chunks that are only focus reports", () => {
|
|
10
|
+
expect(isTerminalFocusSequence("[I[O[I")).toBe(true);
|
|
11
|
+
expect(isTerminalFocusSequence("\x1b[I")).toBe(true);
|
|
12
|
+
expect(isTerminalFocusSequence("model")).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=terminal-input.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-input.test.js","sourceRoot":"","sources":["../../../src/ui/utils/terminal-input.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE3F,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,2BAA2B,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kenkaiiii/ggcoder",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.226",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI coding agent with OAuth authentication for Anthropic, OpenAI, and Gemini",
|
|
6
6
|
"license": "MIT",
|
|
@@ -57,6 +57,14 @@
|
|
|
57
57
|
"import": "./dist/ui/terminal-history.js",
|
|
58
58
|
"types": "./dist/ui/terminal-history.d.ts"
|
|
59
59
|
},
|
|
60
|
+
"./ui/tool-group-summary": {
|
|
61
|
+
"import": "./dist/ui/tool-group-summary.js",
|
|
62
|
+
"types": "./dist/ui/tool-group-summary.d.ts"
|
|
63
|
+
},
|
|
64
|
+
"./ui/transcript/tool-presentation": {
|
|
65
|
+
"import": "./dist/ui/transcript/tool-presentation.js",
|
|
66
|
+
"types": "./dist/ui/transcript/tool-presentation.d.ts"
|
|
67
|
+
},
|
|
60
68
|
"./ui/terminal-history-format": {
|
|
61
69
|
"import": "./dist/ui/terminal-history-format.js",
|
|
62
70
|
"types": "./dist/ui/terminal-history-format.d.ts"
|
|
@@ -102,9 +110,9 @@
|
|
|
102
110
|
"strip-ansi": "^7.2.0",
|
|
103
111
|
"wrap-ansi": "^10.0.0",
|
|
104
112
|
"zod": "^4.4.3",
|
|
105
|
-
"@kenkaiiii/gg-agent": "4.3.
|
|
106
|
-
"@kenkaiiii/gg-
|
|
107
|
-
"@kenkaiiii/gg-
|
|
113
|
+
"@kenkaiiii/gg-agent": "4.3.226",
|
|
114
|
+
"@kenkaiiii/gg-pixel": "4.3.101",
|
|
115
|
+
"@kenkaiiii/gg-ai": "4.3.226"
|
|
108
116
|
},
|
|
109
117
|
"optionalDependencies": {
|
|
110
118
|
"@huggingface/transformers": "^3.6.0",
|