codeep 1.2.77 → 1.2.78
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/renderer/App.js +96 -42
- package/dist/renderer/ansi.d.ts +11 -0
- package/dist/renderer/ansi.js +42 -0
- package/package.json +1 -1
package/dist/renderer/App.js
CHANGED
|
@@ -4,14 +4,29 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Screen } from './Screen.js';
|
|
6
6
|
import { Input, LineEditor } from './Input.js';
|
|
7
|
-
import { fg, style, stringWidth } from './ansi.js';
|
|
7
|
+
import { fg, style, stringWidth, gradientText, gradientLine } from './ansi.js';
|
|
8
8
|
import { SYNTAX, highlightCode } from './highlight.js';
|
|
9
9
|
import { handleInlineStatusKey, handleInlineHelpKey, handleMenuKey, handleInlinePermissionKey, handleInlineSessionPickerKey, handleInlineConfirmKey, handleLoginKey, } from './handlers.js';
|
|
10
10
|
import clipboardy from 'clipboardy';
|
|
11
11
|
// Primary color: #f02a30 (Codeep red)
|
|
12
12
|
const PRIMARY_COLOR = fg.rgb(240, 42, 48);
|
|
13
|
-
//
|
|
14
|
-
|
|
13
|
+
// Gradient stops: deep red → codeep red → orange → amber
|
|
14
|
+
// Used for separator lines and accent elements
|
|
15
|
+
const GRADIENT_STOPS = [
|
|
16
|
+
[160, 20, 30], // deep red
|
|
17
|
+
[240, 42, 48], // Codeep red
|
|
18
|
+
[240, 100, 30], // orange-red
|
|
19
|
+
[240, 160, 20], // amber
|
|
20
|
+
];
|
|
21
|
+
// Dimmer gradient for subtle separators (half brightness)
|
|
22
|
+
const GRADIENT_STOPS_DIM = [
|
|
23
|
+
[80, 10, 15],
|
|
24
|
+
[140, 25, 28],
|
|
25
|
+
[140, 60, 18],
|
|
26
|
+
[140, 90, 12],
|
|
27
|
+
];
|
|
28
|
+
// 8-bit block spinner frames
|
|
29
|
+
const SPINNER_FRAMES = ['▖', '▘', '▝', '▗', '▌', '▀', '▐', '▄'];
|
|
15
30
|
// ASCII Logo
|
|
16
31
|
const LOGO_LINES = [
|
|
17
32
|
' ██████╗ ██████╗ ██████╗ ███████╗███████╗██████╗ ',
|
|
@@ -1295,8 +1310,8 @@ export class App {
|
|
|
1295
1310
|
}
|
|
1296
1311
|
y++;
|
|
1297
1312
|
}
|
|
1298
|
-
//
|
|
1299
|
-
this.screen.
|
|
1313
|
+
// Gradient separator
|
|
1314
|
+
this.screen.writeRaw(separatorLine, gradientLine(width, GRADIENT_STOPS_DIM));
|
|
1300
1315
|
// Input (don't render cursor when menu/settings is open)
|
|
1301
1316
|
this.renderInput(inputLine, width, this.menuOpen || this.settingsOpen);
|
|
1302
1317
|
// Status bar
|
|
@@ -1453,22 +1468,23 @@ export class App {
|
|
|
1453
1468
|
this.screen.showCursor(false);
|
|
1454
1469
|
return;
|
|
1455
1470
|
}
|
|
1456
|
-
// Agent running state - show special prompt
|
|
1471
|
+
// Agent running state - show special prompt with gradient
|
|
1457
1472
|
if (this.isAgentRunning) {
|
|
1458
1473
|
const spinner = SPINNER_FRAMES[this.spinnerFrame];
|
|
1459
1474
|
const stepLabel = this.agentMaxIterations > 0
|
|
1460
1475
|
? `step ${this.agentIteration}/${this.agentMaxIterations}`
|
|
1461
1476
|
: `step ${this.agentIteration}`;
|
|
1462
1477
|
const agentText = `${spinner} Agent working... ${stepLabel} | ${this.agentActions.length} actions (Esc to stop)`;
|
|
1463
|
-
this.screen.
|
|
1478
|
+
this.screen.write(0, y, gradientText(agentText, GRADIENT_STOPS) + style.bold);
|
|
1464
1479
|
this.screen.showCursor(false);
|
|
1465
1480
|
return;
|
|
1466
1481
|
}
|
|
1467
|
-
// Loading/streaming state with animated spinner
|
|
1482
|
+
// Loading/streaming state with animated spinner + gradient
|
|
1468
1483
|
if (this.isLoading || this.isStreaming) {
|
|
1469
1484
|
const spinner = SPINNER_FRAMES[this.spinnerFrame];
|
|
1470
|
-
const message = this.isStreaming ? 'Writing' : 'Thinking';
|
|
1471
|
-
|
|
1485
|
+
const message = this.isStreaming ? 'Writing...' : 'Thinking...';
|
|
1486
|
+
const spinnerText = `${spinner} ${message}`;
|
|
1487
|
+
this.screen.write(0, y, gradientText(spinnerText, GRADIENT_STOPS));
|
|
1472
1488
|
this.screen.showCursor(false);
|
|
1473
1489
|
return;
|
|
1474
1490
|
}
|
|
@@ -1890,15 +1906,15 @@ export class App {
|
|
|
1890
1906
|
acc.errors++;
|
|
1891
1907
|
return acc;
|
|
1892
1908
|
}, { reads: 0, writes: 0, edits: 0, deletes: 0, commands: 0, searches: 0, errors: 0 });
|
|
1893
|
-
// Top border with title
|
|
1894
|
-
const
|
|
1909
|
+
// Top border: gradient line with gradient title embedded
|
|
1910
|
+
const titleInner = ` ${spinner} AGENT `;
|
|
1895
1911
|
const titlePadLeft = 2;
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
this.screen.write(
|
|
1912
|
+
const lineLeft = gradientLine(titlePadLeft, GRADIENT_STOPS);
|
|
1913
|
+
const titleColored = gradientText(titleInner, GRADIENT_STOPS) + style.bold;
|
|
1914
|
+
const lineRight = gradientLine(Math.max(0, width - titlePadLeft - titleInner.length - 1), GRADIENT_STOPS);
|
|
1915
|
+
this.screen.write(0, y, lineLeft + titleColored + lineRight);
|
|
1900
1916
|
y++;
|
|
1901
|
-
// Current action line
|
|
1917
|
+
// Current action line
|
|
1902
1918
|
this.screen.writeLine(y, '');
|
|
1903
1919
|
if (this.agentWaitingForAI) {
|
|
1904
1920
|
this.screen.write(1, y, 'Thinking...', fg.gray);
|
|
@@ -1916,7 +1932,7 @@ export class App {
|
|
|
1916
1932
|
this.screen.write(1, y, 'Starting...', fg.gray);
|
|
1917
1933
|
}
|
|
1918
1934
|
y++;
|
|
1919
|
-
// Stats
|
|
1935
|
+
// Stats + 8-bit progress bar line
|
|
1920
1936
|
this.screen.writeLine(y, '');
|
|
1921
1937
|
let x = 1;
|
|
1922
1938
|
// File changes
|
|
@@ -1950,19 +1966,42 @@ export class App {
|
|
|
1950
1966
|
this.screen.write(x, y, txt, fg.cyan);
|
|
1951
1967
|
x += txt.length + 1;
|
|
1952
1968
|
}
|
|
1953
|
-
//
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1969
|
+
// 8-bit gradient progress bar (right side, if max iterations known)
|
|
1970
|
+
if (this.agentMaxIterations > 0) {
|
|
1971
|
+
const barWidth = 14;
|
|
1972
|
+
const progress = Math.min(this.agentIteration / this.agentMaxIterations, 1);
|
|
1973
|
+
const filled = Math.round(progress * barWidth);
|
|
1974
|
+
// Use block chars: █▓▒░ for gradient fill effect
|
|
1975
|
+
const BLOCKS = ['░', '▒', '▓', '█'];
|
|
1976
|
+
let bar = '';
|
|
1977
|
+
for (let i = 0; i < barWidth; i++) {
|
|
1978
|
+
if (i < filled - 1)
|
|
1979
|
+
bar += '█';
|
|
1980
|
+
else if (i === filled - 1)
|
|
1981
|
+
bar += '▓';
|
|
1982
|
+
else if (i === filled)
|
|
1983
|
+
bar += '▒';
|
|
1984
|
+
else
|
|
1985
|
+
bar += '░';
|
|
1986
|
+
}
|
|
1987
|
+
const barColored = gradientText(bar, GRADIENT_STOPS);
|
|
1988
|
+
const stepText = `${this.agentIteration}/${this.agentMaxIterations}`;
|
|
1989
|
+
const barX = width - barWidth - stepText.length - 3;
|
|
1990
|
+
this.screen.write(barX, y, barColored);
|
|
1991
|
+
this.screen.write(width - stepText.length - 1, y, stepText, fg.gray);
|
|
1992
|
+
}
|
|
1993
|
+
else {
|
|
1994
|
+
const stepText = `step ${this.agentIteration}`;
|
|
1995
|
+
this.screen.write(width - stepText.length - 1, y, stepText, fg.gray);
|
|
1996
|
+
}
|
|
1958
1997
|
y++;
|
|
1959
|
-
// Bottom border with help
|
|
1998
|
+
// Bottom border with help text
|
|
1960
1999
|
const helpText = ' Esc to stop ';
|
|
1961
2000
|
const helpPadLeft = Math.floor((width - helpText.length) / 2);
|
|
1962
|
-
const helpPadRight = Math.
|
|
1963
|
-
this.screen.write(0, y,
|
|
2001
|
+
const helpPadRight = Math.max(0, width - helpPadLeft - helpText.length);
|
|
2002
|
+
this.screen.write(0, y, gradientLine(helpPadLeft, GRADIENT_STOPS_DIM));
|
|
1964
2003
|
this.screen.write(helpPadLeft, y, helpText, fg.gray);
|
|
1965
|
-
this.screen.write(helpPadLeft + helpText.length, y,
|
|
2004
|
+
this.screen.write(helpPadLeft + helpText.length, y, gradientLine(helpPadRight, GRADIENT_STOPS_DIM));
|
|
1966
2005
|
}
|
|
1967
2006
|
/**
|
|
1968
2007
|
* Get color for action type
|
|
@@ -2016,29 +2055,44 @@ export class App {
|
|
|
2016
2055
|
* Render status bar
|
|
2017
2056
|
*/
|
|
2018
2057
|
renderStatusBar(y, width) {
|
|
2019
|
-
|
|
2020
|
-
|
|
2058
|
+
// Clear the line first
|
|
2059
|
+
this.screen.writeLine(y, '');
|
|
2021
2060
|
if (this.notification) {
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
const tokenInfo = stats && stats.totalTokens > 0
|
|
2027
|
-
? ` | ${stats.totalTokens < 1000 ? stats.totalTokens : (stats.totalTokens / 1000).toFixed(1) + 'K'} tokens`
|
|
2028
|
-
: '';
|
|
2029
|
-
leftText = ` ${this.messages.length} messages${tokenInfo}`;
|
|
2061
|
+
// Notification: gradient colored, full width
|
|
2062
|
+
const notifText = ` ${this.notification}`;
|
|
2063
|
+
this.screen.write(0, y, gradientText(notifText, GRADIENT_STOPS));
|
|
2064
|
+
return;
|
|
2030
2065
|
}
|
|
2066
|
+
const status = this.options.getStatus();
|
|
2067
|
+
const stats = status.tokenStats;
|
|
2068
|
+
const tokenInfo = stats && stats.totalTokens > 0
|
|
2069
|
+
? ` ${stats.totalTokens < 1000 ? stats.totalTokens : (stats.totalTokens / 1000).toFixed(1) + 'K'} tok`
|
|
2070
|
+
: '';
|
|
2071
|
+
// Left: message count (gray) + token info (dim)
|
|
2072
|
+
const msgPart = ` ${this.messages.length} msg`;
|
|
2073
|
+
this.screen.write(0, y, msgPart, fg.gray);
|
|
2074
|
+
if (tokenInfo) {
|
|
2075
|
+
this.screen.write(msgPart.length, y, tokenInfo, fg.gray + style.dim);
|
|
2076
|
+
}
|
|
2077
|
+
// Center: model name with gradient
|
|
2078
|
+
const modelName = status.model || '';
|
|
2079
|
+
if (modelName) {
|
|
2080
|
+
const modelColored = gradientText(modelName, GRADIENT_STOPS);
|
|
2081
|
+
const modelX = Math.floor((width - modelName.length) / 2);
|
|
2082
|
+
this.screen.write(modelX, y, modelColored);
|
|
2083
|
+
}
|
|
2084
|
+
// Right: context hint (gray)
|
|
2085
|
+
let rightText;
|
|
2031
2086
|
if (this.isStreaming) {
|
|
2032
|
-
rightText = '
|
|
2087
|
+
rightText = 'Esc cancel ';
|
|
2033
2088
|
}
|
|
2034
2089
|
else if (this.isLoading) {
|
|
2035
|
-
rightText = '
|
|
2090
|
+
rightText = 'working... ';
|
|
2036
2091
|
}
|
|
2037
2092
|
else {
|
|
2038
|
-
rightText = '
|
|
2093
|
+
rightText = '/help ';
|
|
2039
2094
|
}
|
|
2040
|
-
|
|
2041
|
-
this.screen.writeLine(y, leftText + padding + rightText, fg.gray);
|
|
2095
|
+
this.screen.write(width - rightText.length, y, rightText, fg.gray);
|
|
2042
2096
|
}
|
|
2043
2097
|
/**
|
|
2044
2098
|
* Get visible messages (including streaming)
|
package/dist/renderer/ansi.d.ts
CHANGED
|
@@ -81,6 +81,17 @@ export declare const style: {
|
|
|
81
81
|
* Helper to create styled text
|
|
82
82
|
*/
|
|
83
83
|
export declare function styled(text: string, ...styles: string[]): string;
|
|
84
|
+
/**
|
|
85
|
+
* Render text with a horizontal RGB gradient across multiple color stops.
|
|
86
|
+
* Each character gets its own fg.rgb() code.
|
|
87
|
+
* Stops: array of [r,g,b] colors distributed evenly across the text.
|
|
88
|
+
*/
|
|
89
|
+
export declare function gradientText(text: string, stops: Array<[number, number, number]>): string;
|
|
90
|
+
/**
|
|
91
|
+
* Render a full-width separator line with a gradient.
|
|
92
|
+
* Uses the given char (default '─') repeated across width.
|
|
93
|
+
*/
|
|
94
|
+
export declare function gradientLine(width: number, stops: Array<[number, number, number]>, char?: string): string;
|
|
84
95
|
/**
|
|
85
96
|
* Get terminal display width of a single character
|
|
86
97
|
* CJK, fullwidth, and emoji characters take 2 columns
|
package/dist/renderer/ansi.js
CHANGED
|
@@ -101,6 +101,48 @@ export function styled(text, ...styles) {
|
|
|
101
101
|
return text;
|
|
102
102
|
return styles.join('') + text + style.reset;
|
|
103
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Interpolate between two RGB colors at position t (0..1)
|
|
106
|
+
*/
|
|
107
|
+
function lerpColor(from, to, t) {
|
|
108
|
+
return [
|
|
109
|
+
Math.round(from[0] + (to[0] - from[0]) * t),
|
|
110
|
+
Math.round(from[1] + (to[1] - from[1]) * t),
|
|
111
|
+
Math.round(from[2] + (to[2] - from[2]) * t),
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Render text with a horizontal RGB gradient across multiple color stops.
|
|
116
|
+
* Each character gets its own fg.rgb() code.
|
|
117
|
+
* Stops: array of [r,g,b] colors distributed evenly across the text.
|
|
118
|
+
*/
|
|
119
|
+
export function gradientText(text, stops) {
|
|
120
|
+
if (stops.length === 0)
|
|
121
|
+
return text;
|
|
122
|
+
if (stops.length === 1)
|
|
123
|
+
return fg.rgb(...stops[0]) + text + style.reset;
|
|
124
|
+
const chars = [...text]; // handle multi-byte / emoji
|
|
125
|
+
const len = chars.length;
|
|
126
|
+
if (len === 0)
|
|
127
|
+
return text;
|
|
128
|
+
let result = '';
|
|
129
|
+
for (let i = 0; i < len; i++) {
|
|
130
|
+
const t = len === 1 ? 0 : i / (len - 1);
|
|
131
|
+
// Which segment between stops?
|
|
132
|
+
const seg = Math.min(Math.floor(t * (stops.length - 1)), stops.length - 2);
|
|
133
|
+
const segT = t * (stops.length - 1) - seg;
|
|
134
|
+
const [r, g, b] = lerpColor(stops[seg], stops[seg + 1], segT);
|
|
135
|
+
result += fg.rgb(r, g, b) + chars[i];
|
|
136
|
+
}
|
|
137
|
+
return result + style.reset;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Render a full-width separator line with a gradient.
|
|
141
|
+
* Uses the given char (default '─') repeated across width.
|
|
142
|
+
*/
|
|
143
|
+
export function gradientLine(width, stops, char = '─') {
|
|
144
|
+
return gradientText(char.repeat(width), stops);
|
|
145
|
+
}
|
|
104
146
|
/**
|
|
105
147
|
* Get terminal display width of a single character
|
|
106
148
|
* CJK, fullwidth, and emoji characters take 2 columns
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.78",
|
|
4
4
|
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|