codeep 1.2.82 → 1.2.84

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.
@@ -5,7 +5,7 @@
5
5
  import { StatusInfo } from './components/Status';
6
6
  import { SelectItem } from './components/SelectScreen';
7
7
  export interface Message {
8
- role: 'user' | 'assistant' | 'system';
8
+ role: 'user' | 'assistant' | 'system' | 'welcome';
9
9
  content: string;
10
10
  }
11
11
  export interface ConfirmOptions {
@@ -402,6 +402,7 @@ export declare class App {
402
402
  /**
403
403
  * Format message into lines with syntax highlighting for code blocks
404
404
  */
405
+ private formatWelcomeMessage;
405
406
  private formatMessage;
406
407
  /**
407
408
  * Apply inline markdown formatting (bold, italic, inline code) to a line
@@ -4,27 +4,12 @@
4
4
  */
5
5
  import { Screen } from './Screen.js';
6
6
  import { Input, LineEditor } from './Input.js';
7
- import { fg, style, stringWidth, gradientText, gradientLine } from './ansi.js';
7
+ import { fg, style, stringWidth } 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
- // 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
13
  // 8-bit block spinner frames
29
14
  const SPINNER_FRAMES = ['▖', '▘', '▝', '▗', '▌', '▀', '▐', '▄'];
30
15
  // ASCII Logo
@@ -303,7 +288,7 @@ export class App {
303
288
  */
304
289
  getChatHistory() {
305
290
  return this.messages
306
- .filter(m => m.role !== 'system')
291
+ .filter(m => m.role !== 'system' && m.role !== 'welcome')
307
292
  .map(m => ({ role: m.role, content: m.content }));
308
293
  }
309
294
  /**
@@ -1311,7 +1296,7 @@ export class App {
1311
1296
  y++;
1312
1297
  }
1313
1298
  // Gradient separator
1314
- this.screen.writeRaw(separatorLine, gradientLine(width, GRADIENT_STOPS_DIM));
1299
+ this.screen.writeRaw(separatorLine, fg.rgb(60, 10, 12) + '─'.repeat(width) + style.reset);
1315
1300
  // Input (don't render cursor when menu/settings is open)
1316
1301
  this.renderInput(inputLine, width, this.menuOpen || this.settingsOpen);
1317
1302
  // Status bar
@@ -1475,7 +1460,7 @@ export class App {
1475
1460
  ? `step ${this.agentIteration}/${this.agentMaxIterations}`
1476
1461
  : `step ${this.agentIteration}`;
1477
1462
  const agentText = `${spinner} Agent working... ${stepLabel} | ${this.agentActions.length} actions (Esc to stop)`;
1478
- this.screen.write(0, y, gradientText(agentText, GRADIENT_STOPS) + style.bold);
1463
+ this.screen.write(0, y, PRIMARY_COLOR + style.bold + agentText + style.reset);
1479
1464
  this.screen.showCursor(false);
1480
1465
  return;
1481
1466
  }
@@ -1484,7 +1469,7 @@ export class App {
1484
1469
  const spinner = SPINNER_FRAMES[this.spinnerFrame];
1485
1470
  const message = this.isStreaming ? 'Writing...' : 'Thinking...';
1486
1471
  const spinnerText = `${spinner} ${message}`;
1487
- this.screen.write(0, y, gradientText(spinnerText, GRADIENT_STOPS));
1472
+ this.screen.write(0, y, PRIMARY_COLOR + spinnerText + style.reset);
1488
1473
  this.screen.showCursor(false);
1489
1474
  return;
1490
1475
  }
@@ -1911,9 +1896,10 @@ export class App {
1911
1896
  // Top border: gradient line with gradient title embedded
1912
1897
  const titleInner = ` ${spinner} AGENT `;
1913
1898
  const titlePadLeft = 2;
1914
- const lineLeft = gradientLine(titlePadLeft, GRADIENT_STOPS);
1915
- const titleColored = gradientText(titleInner, GRADIENT_STOPS) + style.bold;
1916
- const lineRight = gradientLine(Math.max(0, width - titlePadLeft - titleInner.length - 1), GRADIENT_STOPS);
1899
+ const lineChar = PRIMARY_COLOR + '─' + style.reset;
1900
+ const lineLeft = lineChar.repeat(titlePadLeft);
1901
+ const titleColored = PRIMARY_COLOR + style.bold + titleInner + style.reset;
1902
+ const lineRight = lineChar.repeat(Math.max(0, width - titlePadLeft - titleInner.length - 1));
1917
1903
  this.screen.write(0, y, lineLeft + titleColored + lineRight);
1918
1904
  y++;
1919
1905
  // Current action line
@@ -1986,7 +1972,7 @@ export class App {
1986
1972
  else
1987
1973
  bar += '░';
1988
1974
  }
1989
- const barColored = gradientText(bar, GRADIENT_STOPS);
1975
+ const barColored = PRIMARY_COLOR + bar + style.reset;
1990
1976
  const stepText = `${this.agentIteration}/${this.agentMaxIterations}`;
1991
1977
  const barX = width - barWidth - stepText.length - 3;
1992
1978
  this.screen.write(barX, y, barColored);
@@ -2001,9 +1987,9 @@ export class App {
2001
1987
  const helpText = ' Esc to stop ';
2002
1988
  const helpPadLeft = Math.floor((width - helpText.length) / 2);
2003
1989
  const helpPadRight = Math.max(0, width - helpPadLeft - helpText.length);
2004
- this.screen.write(0, y, gradientLine(helpPadLeft, GRADIENT_STOPS_DIM));
1990
+ this.screen.write(0, y, fg.rgb(60, 10, 12) + '─'.repeat(helpPadLeft) + style.reset);
2005
1991
  this.screen.write(helpPadLeft, y, helpText, fg.gray);
2006
- this.screen.write(helpPadLeft + helpText.length, y, gradientLine(helpPadRight, GRADIENT_STOPS_DIM));
1992
+ this.screen.write(helpPadLeft + helpText.length, y, fg.rgb(60, 10, 12) + '─'.repeat(helpPadRight) + style.reset);
2007
1993
  }
2008
1994
  /**
2009
1995
  * Get color for action type
@@ -2062,7 +2048,7 @@ export class App {
2062
2048
  if (this.notification) {
2063
2049
  // Notification: gradient colored, full width
2064
2050
  const notifText = ` ${this.notification}`;
2065
- this.screen.write(0, y, gradientText(notifText, GRADIENT_STOPS));
2051
+ this.screen.write(0, y, PRIMARY_COLOR + notifText + style.reset);
2066
2052
  return;
2067
2053
  }
2068
2054
  const status = this.options.getStatus();
@@ -2075,7 +2061,7 @@ export class App {
2075
2061
  : '';
2076
2062
  let leftX = 1;
2077
2063
  if (modelName) {
2078
- this.screen.write(leftX, y, gradientText(modelName, GRADIENT_STOPS));
2064
+ this.screen.write(leftX, y, PRIMARY_COLOR + modelName + style.reset);
2079
2065
  leftX += modelName.length + 2;
2080
2066
  this.screen.write(leftX - 1, y, '·', fg.gray);
2081
2067
  leftX += 1;
@@ -2117,7 +2103,9 @@ export class App {
2117
2103
  allLines.push({ text: '', style: '' });
2118
2104
  }
2119
2105
  for (const msg of this.messages) {
2120
- const msgLines = this.formatMessage(msg.role, msg.content, width);
2106
+ const msgLines = msg.role === 'welcome'
2107
+ ? this.formatWelcomeMessage(msg.content)
2108
+ : this.formatMessage(msg.role, msg.content, width);
2121
2109
  allLines.push(...msgLines);
2122
2110
  }
2123
2111
  if (this.isStreaming && this.streamingContent) {
@@ -2137,17 +2125,74 @@ export class App {
2137
2125
  /**
2138
2126
  * Format message into lines with syntax highlighting for code blocks
2139
2127
  */
2128
+ formatWelcomeMessage(content) {
2129
+ const lines = [];
2130
+ const DIM = fg.rgb(80, 80, 80);
2131
+ const LABEL = fg.rgb(100, 100, 100);
2132
+ const SEP = DIM + ' · ' + style.reset;
2133
+ for (const line of content.split('\n')) {
2134
+ if (line.trim() === '') {
2135
+ lines.push({ text: '', style: '' });
2136
+ continue;
2137
+ }
2138
+ // Version line: "Codeep vX.X.X · Provider · Model"
2139
+ if (line.startsWith('Codeep ')) {
2140
+ const parts = line.split(' · ');
2141
+ const colored = PRIMARY_COLOR + style.bold + (parts[0] || '') + style.reset
2142
+ + SEP + fg.rgb(180, 180, 180) + (parts[1] || '') + style.reset
2143
+ + SEP + fg.rgb(130, 130, 130) + (parts[2] || '') + style.reset;
2144
+ lines.push({ text: colored, style: '', raw: true });
2145
+ continue;
2146
+ }
2147
+ // Project line
2148
+ if (/^\s+Project\s/.test(line)) {
2149
+ const value = line.replace(/^\s+Project\s+/, '');
2150
+ lines.push({ text: LABEL + ' Project ' + style.reset + fg.rgb(100, 180, 220) + value + style.reset, style: '', raw: true });
2151
+ continue;
2152
+ }
2153
+ // Access line
2154
+ if (/^\s+Access\s/.test(line)) {
2155
+ const value = line.replace(/^\s+Access\s+/, '');
2156
+ const parts = value.split(' · ');
2157
+ const accessColored = fg.rgb(100, 200, 120) + style.bold + (parts[0] || '') + style.reset;
2158
+ const rest = parts.slice(1).map(p => fg.rgb(80, 160, 100) + p + style.reset).join(SEP);
2159
+ lines.push({ text: LABEL + ' Access ' + style.reset + accessColored + (rest ? SEP + rest : ''), style: '', raw: true });
2160
+ continue;
2161
+ }
2162
+ // Mode line
2163
+ if (/^\s+Mode\s/.test(line)) {
2164
+ const value = line.replace(/^\s+Mode\s+/, '');
2165
+ lines.push({ text: LABEL + ' Mode ' + style.reset + fg.rgb(160, 160, 160) + value + style.reset, style: '', raw: true });
2166
+ continue;
2167
+ }
2168
+ // Agent Mode warning
2169
+ if (line.includes('⚠')) {
2170
+ lines.push({ text: ' ' + fg.rgb(220, 160, 40) + line.trim() + style.reset, style: '', raw: true });
2171
+ continue;
2172
+ }
2173
+ // Shortcuts line
2174
+ if (line.includes('/help')) {
2175
+ const parts = line.trim().split(' · ');
2176
+ const colored = parts.map(p => fg.rgb(150, 150, 150) + p.trim() + style.reset).join(DIM + ' · ' + style.reset);
2177
+ lines.push({ text: ' ' + colored, style: '', raw: true });
2178
+ continue;
2179
+ }
2180
+ lines.push({ text: line, style: '' });
2181
+ }
2182
+ lines.push({ text: '', style: '' });
2183
+ return lines;
2184
+ }
2140
2185
  formatMessage(role, content, maxWidth) {
2141
2186
  const lines = [];
2142
- // Role-specific prefix — user gets gradient bar, assistant gets dim header, system gets diamond
2187
+ // Role-specific prefix — user gets primary color bar, assistant gets dim header, system gets diamond
2143
2188
  const contIndent = ' ';
2144
2189
  let firstPrefix;
2145
2190
  const firstStyle = '';
2146
2191
  if (role === 'user') {
2147
- firstPrefix = gradientText('\u258c ', GRADIENT_STOPS) + style.reset;
2192
+ firstPrefix = PRIMARY_COLOR + '\u258c ' + style.reset;
2148
2193
  }
2149
2194
  else if (role === 'assistant') {
2150
- lines.push({ text: fg.rgb(80, 80, 80) + '\u254c\u254c codeep' + style.reset, style: '', raw: true });
2195
+ lines.push({ text: PRIMARY_COLOR + '\u254c\u254c' + style.reset + fg.rgb(120, 120, 120) + ' codeep' + style.reset, style: '', raw: true });
2151
2196
  firstPrefix = ' ';
2152
2197
  }
2153
2198
  else {
@@ -2208,7 +2253,7 @@ export class App {
2208
2253
  const end = text.indexOf('***', i + 3);
2209
2254
  if (end !== -1) {
2210
2255
  const inner = text.slice(i + 3, end);
2211
- result += style.bold + style.italic + fg.white + inner + '\x1b[0m';
2256
+ result += style.bold + style.italic + PRIMARY_COLOR + inner + '\x1b[0m';
2212
2257
  hasFormatting = true;
2213
2258
  i = end + 3;
2214
2259
  continue;
@@ -2219,7 +2264,7 @@ export class App {
2219
2264
  const end = text.indexOf('**', i + 2);
2220
2265
  if (end !== -1) {
2221
2266
  const inner = text.slice(i + 2, end);
2222
- result += style.bold + fg.white + inner + '\x1b[0m';
2267
+ result += style.bold + PRIMARY_COLOR + inner + '\x1b[0m';
2223
2268
  hasFormatting = true;
2224
2269
  i = end + 2;
2225
2270
  continue;
@@ -381,23 +381,23 @@ Commands (in chat):
381
381
  const version = getCurrentVersion();
382
382
  const model = config.get('model');
383
383
  const agentMode = config.get('agentMode') || 'off';
384
- const welcomeLines = [`Codeep v${version}${providerInfo?.name}${model}`, ''];
384
+ const welcomeLines = [`Codeep v${version} · ${providerInfo?.name} · ${model}`, ''];
385
385
  if (projectContext) {
386
- welcomeLines.push(`Project: ${projectPath}`);
386
+ welcomeLines.push(` Project ${projectPath}`);
387
387
  welcomeLines.push(hasWriteAccess
388
- ? 'Access: Read & Write (Agent enabled)'
389
- : 'Access: Read Only (/grant to enable Agent)');
388
+ ? ' Access Read & Write · Agent enabled'
389
+ : ' Access Read Only · /grant to enable Agent');
390
390
  }
391
391
  else {
392
- welcomeLines.push('Mode: Chat only (no project context)');
392
+ welcomeLines.push(' Mode Chat only · no project context');
393
393
  }
394
394
  if (agentMode === 'on' && hasWriteAccess) {
395
395
  welcomeLines.push('');
396
- welcomeLines.push('⚠ Agent Mode ON: Messages will auto-execute as agent tasks');
396
+ welcomeLines.push(' Agent Mode ON — messages auto-execute as agent tasks');
397
397
  }
398
398
  welcomeLines.push('');
399
- welcomeLines.push('Shortcuts: /help commands • Ctrl+L clearEsc cancel');
400
- app.addMessage({ role: 'system', content: welcomeLines.join('\n') });
399
+ welcomeLines.push(' /help · Ctrl+L clear · Esc cancel');
400
+ app.addMessage({ role: 'welcome', content: welcomeLines.join('\n') });
401
401
  app.start();
402
402
  // Check for updates in background — show notify if new version available
403
403
  checkForUpdates().then(info => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.2.82",
3
+ "version": "1.2.84",
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",