codeep 1.2.79 → 1.2.81

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.
@@ -1500,7 +1500,7 @@ export class App {
1500
1500
  const placeholder = this.isMultilineMode
1501
1501
  ? 'Multi-line mode Enter=newline · Esc=send'
1502
1502
  : 'Message or /command';
1503
- this.screen.write(promptSymbol.length, y, placeholder, fg.gray + style.dim);
1503
+ this.screen.write(promptSymbol.length, y, placeholder, fg.gray);
1504
1504
  if (!hideCursor) {
1505
1505
  this.screen.setCursor(promptSymbol.length, y);
1506
1506
  this.screen.showCursor(true);
@@ -2067,25 +2067,34 @@ export class App {
2067
2067
  }
2068
2068
  const status = this.options.getStatus();
2069
2069
  const stats = status.tokenStats;
2070
- // Left segment: msg count · token count
2070
+ // Left: model (gradient) · msg count · token count
2071
+ const modelName = status.model || '';
2071
2072
  const msgCount = `${this.messages.length} msg`;
2072
2073
  const tokenStr = stats && stats.totalTokens > 0
2073
2074
  ? `${stats.totalTokens < 1000 ? stats.totalTokens : (stats.totalTokens / 1000).toFixed(1) + 'K'} tok`
2074
2075
  : '';
2075
- const leftParts = [msgCount, tokenStr].filter(Boolean);
2076
- const leftText = ' ' + leftParts.join(' · ');
2077
- this.screen.write(0, y, leftText, fg.gray + style.dim);
2078
- // Center: model name with gradient (only if it fits)
2079
- const modelName = status.model || '';
2080
- if (modelName && width > 40) {
2081
- const modelX = Math.floor((width - modelName.length) / 2);
2082
- this.screen.write(modelX, y, gradientText(modelName, GRADIENT_STOPS));
2083
- }
2084
- // Right: Esc hint only when active, nothing when idle
2076
+ let leftX = 1;
2077
+ if (modelName) {
2078
+ this.screen.write(leftX, y, gradientText(modelName, GRADIENT_STOPS));
2079
+ leftX += modelName.length + 2;
2080
+ this.screen.write(leftX - 1, y, '·', fg.gray);
2081
+ leftX += 1;
2082
+ }
2083
+ this.screen.write(leftX, y, msgCount, fg.gray);
2084
+ leftX += msgCount.length;
2085
+ if (tokenStr) {
2086
+ this.screen.write(leftX, y, ' · ', fg.gray);
2087
+ this.screen.write(leftX + 3, y, tokenStr, fg.gray);
2088
+ }
2089
+ // Right: context-sensitive hints
2090
+ let rightText;
2085
2091
  if (this.isStreaming || this.isLoading) {
2086
- const rightText = 'Esc ';
2087
- this.screen.write(width - rightText.length, y, rightText, fg.gray + style.dim);
2092
+ rightText = 'Esc to stop ';
2093
+ }
2094
+ else {
2095
+ rightText = '/help · ↑↓ history ';
2088
2096
  }
2097
+ this.screen.write(width - rightText.length, y, rightText, fg.gray);
2089
2098
  }
2090
2099
  /**
2091
2100
  * Get visible messages (including streaming)
@@ -2130,40 +2139,46 @@ export class App {
2130
2139
  */
2131
2140
  formatMessage(role, content, maxWidth) {
2132
2141
  const lines = [];
2133
- const roleStyle = role === 'user' ? fg.green : role === 'assistant' ? PRIMARY_COLOR : fg.yellow;
2134
- const roleLabel = role === 'user' ? '> ' : role === 'assistant' ? ' ' : '# ';
2135
- // Parse content for code blocks
2142
+ // Role-specific prefix user gets gradient bar, assistant gets dim header, system gets diamond
2143
+ const contIndent = ' ';
2144
+ let firstPrefix;
2145
+ const firstStyle = '';
2146
+ if (role === 'user') {
2147
+ firstPrefix = gradientText('\u258c ', GRADIENT_STOPS) + style.reset;
2148
+ }
2149
+ else if (role === 'assistant') {
2150
+ lines.push({ text: fg.rgb(80, 80, 80) + '\u254c\u254c codeep' + style.reset, style: '', raw: true });
2151
+ firstPrefix = ' ';
2152
+ }
2153
+ else {
2154
+ firstPrefix = fg.gray + style.dim + '\u25c6 ' + style.reset;
2155
+ }
2136
2156
  const codeBlockRegex = /```([^\n]*)\n([\s\S]*?)```/g;
2137
2157
  let lastIndex = 0;
2138
2158
  let match;
2139
2159
  let isFirstLine = true;
2140
2160
  while ((match = codeBlockRegex.exec(content)) !== null) {
2141
- // Add text before code block
2142
2161
  const textBefore = content.slice(lastIndex, match.index);
2143
2162
  if (textBefore) {
2144
- const textLines = this.formatTextLines(textBefore, maxWidth, isFirstLine ? roleLabel : ' ', isFirstLine ? roleStyle : '');
2163
+ const prefix = isFirstLine ? firstPrefix : (role === 'user' ? contIndent : ' ');
2164
+ const textLines = this.formatTextLines(textBefore, maxWidth, prefix, firstStyle, role === 'user' && isFirstLine);
2145
2165
  lines.push(...textLines);
2146
2166
  isFirstLine = false;
2147
2167
  }
2148
- // Add code block with syntax highlighting
2149
2168
  this.codeBlockCounter++;
2150
2169
  const rawLang = (match[1] || 'text').trim();
2151
- // Handle filepath:name.ext format - extract extension as language
2152
2170
  let lang = rawLang;
2153
2171
  if (rawLang.includes(':') || rawLang.includes('.')) {
2154
- const ext = rawLang.split('.').pop() || rawLang;
2155
- lang = ext;
2172
+ lang = rawLang.split('.').pop() || rawLang;
2156
2173
  }
2157
- const code = match[2];
2158
- const codeLines = this.formatCodeBlock(code, lang, maxWidth, this.codeBlockCounter);
2159
- lines.push(...codeLines);
2174
+ lines.push(...this.formatCodeBlock(match[2], lang, maxWidth, this.codeBlockCounter));
2160
2175
  lastIndex = match.index + match[0].length;
2161
2176
  isFirstLine = false;
2162
2177
  }
2163
- // Add remaining text after last code block
2164
2178
  const textAfter = content.slice(lastIndex);
2165
2179
  if (textAfter) {
2166
- const textLines = this.formatTextLines(textAfter, maxWidth, isFirstLine ? roleLabel : ' ', isFirstLine ? roleStyle : '');
2180
+ const prefix = isFirstLine ? firstPrefix : (role === 'user' ? contIndent : ' ');
2181
+ const textLines = this.formatTextLines(textAfter, maxWidth, prefix, firstStyle, role === 'user' && isFirstLine);
2167
2182
  lines.push(...textLines);
2168
2183
  }
2169
2184
  lines.push({ text: '', style: '' });
@@ -2229,13 +2244,14 @@ export class App {
2229
2244
  /**
2230
2245
  * Format plain text lines with markdown support
2231
2246
  */
2232
- formatTextLines(text, maxWidth, firstPrefix, firstStyle) {
2247
+ formatTextLines(text, maxWidth, firstPrefix, firstStyle, rawPrefix = false) {
2233
2248
  const lines = [];
2234
2249
  const contentLines = text.split('\n');
2235
2250
  for (let i = 0; i < contentLines.length; i++) {
2236
2251
  const line = contentLines[i];
2237
2252
  const prefix = i === 0 ? firstPrefix : ' ';
2238
2253
  const prefixStyle = i === 0 ? firstStyle : '';
2254
+ const isRaw = i === 0 ? rawPrefix : false;
2239
2255
  // Heading: ## or ### etc.
2240
2256
  const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
2241
2257
  if (headingMatch) {
@@ -2266,7 +2282,7 @@ export class App {
2266
2282
  const bullet = listMatch[2];
2267
2283
  const content = listMatch[3];
2268
2284
  const { formatted, hasFormatting } = this.applyInlineMarkdown(content);
2269
- const bulletChar = bullet === '-' || bullet === '*' ? '' : bullet;
2285
+ const bulletChar = bullet === '-' || bullet === '*' ? '\u25b8' : bullet;
2270
2286
  if (hasFormatting) {
2271
2287
  lines.push({
2272
2288
  text: prefix + indent + fg.gray + bulletChar + '\x1b[0m' + ' ' + formatted,
@@ -2310,9 +2326,11 @@ export class App {
2310
2326
  if (stringWidth(line) > maxWidth - prefix.length) {
2311
2327
  const wrapped = this.wordWrap(line, maxWidth - prefix.length);
2312
2328
  for (let j = 0; j < wrapped.length; j++) {
2329
+ const lineIsRaw = j === 0 ? isRaw : false;
2313
2330
  lines.push({
2314
2331
  text: (j === 0 ? prefix : ' ') + wrapped[j],
2315
2332
  style: j === 0 ? prefixStyle : '',
2333
+ ...(lineIsRaw ? { raw: true } : {}),
2316
2334
  });
2317
2335
  }
2318
2336
  }
@@ -2320,6 +2338,7 @@ export class App {
2320
2338
  lines.push({
2321
2339
  text: prefix + line,
2322
2340
  style: prefixStyle,
2341
+ ...(isRaw ? { raw: true } : {}),
2323
2342
  });
2324
2343
  }
2325
2344
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.2.79",
3
+ "version": "1.2.81",
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",