codeep 1.1.18 → 1.1.20

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.
@@ -393,7 +393,11 @@ export declare class App {
393
393
  */
394
394
  private formatMessage;
395
395
  /**
396
- * Format plain text lines
396
+ * Apply inline markdown formatting (bold, italic, inline code) to a line
397
+ */
398
+ private applyInlineMarkdown;
399
+ /**
400
+ * Format plain text lines with markdown support
397
401
  */
398
402
  private formatTextLines;
399
403
  /**
@@ -1565,7 +1565,7 @@ export class App {
1565
1565
  bottomPanelHeight = previewLines + 6; // title + preview + extra line indicator + options
1566
1566
  }
1567
1567
  else if (this.isAgentRunning) {
1568
- bottomPanelHeight = 6; // Agent progress box (5 lines + 1 margin)
1568
+ bottomPanelHeight = 5; // Agent progress box (4 lines + 1 margin)
1569
1569
  }
1570
1570
  else if (this.permissionOpen) {
1571
1571
  bottomPanelHeight = 10; // Permission dialog
@@ -2172,7 +2172,6 @@ export class App {
2172
2172
  renderInlineAgentProgress(startY, width) {
2173
2173
  let y = startY;
2174
2174
  const spinner = SPINNER_FRAMES[this.spinnerFrame];
2175
- const boxWidth = width - 2; // Use full width minus small margin
2176
2175
  // Calculate stats
2177
2176
  const stats = {
2178
2177
  reads: this.agentActions.filter(a => a.type === 'read').length,
@@ -2184,93 +2183,71 @@ export class App {
2184
2183
  errors: this.agentActions.filter(a => a.result === 'error').length,
2185
2184
  };
2186
2185
  // Top border with title
2187
- // Helper to draw a box line with content
2188
- const drawBoxLine = (content, contentStyle = fg.white) => {
2189
- this.screen.write(0, y, '│', PRIMARY_COLOR);
2190
- this.screen.write(2, y, content, contentStyle);
2191
- this.screen.write(boxWidth - 1, y, '│', PRIMARY_COLOR);
2192
- y++;
2193
- };
2194
- // Top border with title
2195
2186
  const title = ` ${spinner} AGENT `;
2196
- const titlePadLeft = 3;
2197
- const titlePadRight = boxWidth - titlePadLeft - title.length - 1;
2198
- this.screen.write(0, y, '╭' + '─'.repeat(titlePadLeft), PRIMARY_COLOR);
2199
- this.screen.write(titlePadLeft + 1, y, title, PRIMARY_COLOR + style.bold);
2200
- this.screen.write(titlePadLeft + 1 + title.length, y, '─'.repeat(Math.max(0, titlePadRight)) + '╮', PRIMARY_COLOR);
2187
+ const titlePadLeft = 2;
2188
+ const titlePadRight = width - titlePadLeft - title.length - 1;
2189
+ this.screen.write(0, y, '─'.repeat(titlePadLeft), PRIMARY_COLOR);
2190
+ this.screen.write(titlePadLeft, y, title, PRIMARY_COLOR + style.bold);
2191
+ this.screen.write(titlePadLeft + title.length, y, '─'.repeat(Math.max(0, titlePadRight)), PRIMARY_COLOR);
2201
2192
  y++;
2202
- // Current action line
2203
- this.screen.write(0, y, '│', PRIMARY_COLOR);
2193
+ // Current action line (no side borders)
2204
2194
  if (this.agentActions.length > 0) {
2205
2195
  const lastAction = this.agentActions[this.agentActions.length - 1];
2206
2196
  const actionLabel = this.getActionLabel(lastAction.type);
2207
2197
  const actionColor = this.getActionColor(lastAction.type);
2208
- const maxTargetLen = boxWidth - actionLabel.length - 6;
2198
+ const maxTargetLen = width - actionLabel.length - 4;
2209
2199
  const target = this.formatActionTarget(lastAction.target, maxTargetLen);
2210
- this.screen.write(2, y, actionLabel, actionColor + style.bold);
2211
- this.screen.write(2 + actionLabel.length + 1, y, target, fg.white);
2200
+ this.screen.write(1, y, actionLabel, actionColor + style.bold);
2201
+ this.screen.write(1 + actionLabel.length + 1, y, target, fg.white);
2212
2202
  }
2213
2203
  else {
2214
- this.screen.write(2, y, 'Starting...', fg.gray);
2204
+ this.screen.write(1, y, 'Starting...', fg.gray);
2215
2205
  }
2216
- this.screen.write(boxWidth - 1, y, '│', PRIMARY_COLOR);
2217
- y++;
2218
- // Separator
2219
- this.screen.write(0, y, '├' + '─'.repeat(boxWidth - 2) + '┤', fg.gray);
2220
2206
  y++;
2221
- // File changes line
2222
- this.screen.write(0, y, '│', PRIMARY_COLOR);
2223
- this.screen.write(2, y, 'Files:', fg.cyan);
2224
- let fileX = 9;
2207
+ // Stats line: Files and step info
2208
+ let x = 1;
2209
+ // File changes
2225
2210
  if (stats.writes > 0) {
2226
2211
  const txt = `+${stats.writes}`;
2227
- this.screen.write(fileX, y, txt, fg.green);
2228
- fileX += txt.length + 1;
2212
+ this.screen.write(x, y, txt, fg.green);
2213
+ x += txt.length + 1;
2229
2214
  }
2230
2215
  if (stats.edits > 0) {
2231
2216
  const txt = `~${stats.edits}`;
2232
- this.screen.write(fileX, y, txt, fg.yellow);
2233
- fileX += txt.length + 1;
2217
+ this.screen.write(x, y, txt, fg.yellow);
2218
+ x += txt.length + 1;
2234
2219
  }
2235
2220
  if (stats.deletes > 0) {
2236
2221
  const txt = `-${stats.deletes}`;
2237
- this.screen.write(fileX, y, txt, fg.red);
2238
- fileX += txt.length + 1;
2239
- }
2240
- if (stats.writes === 0 && stats.edits === 0 && stats.deletes === 0) {
2241
- this.screen.write(fileX, y, 'no changes yet', fg.gray);
2242
- }
2243
- this.screen.write(boxWidth - 1, y, '│', PRIMARY_COLOR);
2244
- y++;
2245
- // Stats line
2246
- this.screen.write(0, y, '│', PRIMARY_COLOR);
2247
- this.screen.write(2, y, 'Stats:', fg.cyan);
2248
- let statX = 9;
2249
- const statParts = [];
2250
- if (stats.reads > 0)
2251
- statParts.push({ text: `${stats.reads}R`, color: fg.blue });
2252
- if (stats.commands > 0)
2253
- statParts.push({ text: `${stats.commands}C`, color: fg.magenta });
2254
- if (stats.searches > 0)
2255
- statParts.push({ text: `${stats.searches}S`, color: fg.cyan });
2256
- statParts.push({ text: `step ${this.agentIteration}`, color: fg.white });
2257
- for (let i = 0; i < statParts.length; i++) {
2258
- if (i > 0) {
2259
- this.screen.write(statX, y, '|', fg.gray);
2260
- statX += 2;
2261
- }
2262
- this.screen.write(statX, y, statParts[i].text, statParts[i].color);
2263
- statX += statParts[i].text.length + 1;
2264
- }
2265
- this.screen.write(boxWidth - 1, y, '│', PRIMARY_COLOR);
2222
+ this.screen.write(x, y, txt, fg.red);
2223
+ x += txt.length + 1;
2224
+ }
2225
+ if (stats.reads > 0) {
2226
+ const txt = `${stats.reads}R`;
2227
+ this.screen.write(x, y, txt, fg.blue);
2228
+ x += txt.length + 1;
2229
+ }
2230
+ if (stats.commands > 0) {
2231
+ const txt = `${stats.commands}C`;
2232
+ this.screen.write(x, y, txt, fg.magenta);
2233
+ x += txt.length + 1;
2234
+ }
2235
+ if (stats.searches > 0) {
2236
+ const txt = `${stats.searches}S`;
2237
+ this.screen.write(x, y, txt, fg.cyan);
2238
+ x += txt.length + 1;
2239
+ }
2240
+ // Step info on the right
2241
+ const stepText = `step ${this.agentIteration}`;
2242
+ this.screen.write(width - stepText.length - 1, y, stepText, fg.gray);
2266
2243
  y++;
2267
2244
  // Bottom border with help
2268
2245
  const helpText = ' Esc to stop ';
2269
- const helpPadLeft = Math.floor((boxWidth - helpText.length - 2) / 2);
2270
- const helpPadRight = Math.ceil((boxWidth - helpText.length - 2) / 2);
2271
- this.screen.write(0, y, '╰' + '─'.repeat(helpPadLeft), PRIMARY_COLOR);
2272
- this.screen.write(helpPadLeft + 1, y, helpText, fg.gray);
2273
- this.screen.write(helpPadLeft + 1 + helpText.length, y, '─'.repeat(helpPadRight) + '╯', PRIMARY_COLOR);
2246
+ const helpPadLeft = Math.floor((width - helpText.length) / 2);
2247
+ const helpPadRight = Math.ceil((width - helpText.length) / 2);
2248
+ this.screen.write(0, y, '─'.repeat(helpPadLeft), fg.gray);
2249
+ this.screen.write(helpPadLeft, y, helpText, fg.gray);
2250
+ this.screen.write(helpPadLeft + helpText.length, y, '─'.repeat(helpPadRight), fg.gray);
2274
2251
  }
2275
2252
  /**
2276
2253
  * Get color for action type
@@ -2408,7 +2385,64 @@ export class App {
2408
2385
  return lines;
2409
2386
  }
2410
2387
  /**
2411
- * Format plain text lines
2388
+ * Apply inline markdown formatting (bold, italic, inline code) to a line
2389
+ */
2390
+ applyInlineMarkdown(text) {
2391
+ let result = '';
2392
+ let hasFormatting = false;
2393
+ let i = 0;
2394
+ while (i < text.length) {
2395
+ // Inline code: `code`
2396
+ if (text[i] === '`' && text[i + 1] !== '`') {
2397
+ const end = text.indexOf('`', i + 1);
2398
+ if (end !== -1) {
2399
+ const code = text.slice(i + 1, end);
2400
+ result += fg.rgb(209, 154, 102) + code + '\x1b[0m';
2401
+ hasFormatting = true;
2402
+ i = end + 1;
2403
+ continue;
2404
+ }
2405
+ }
2406
+ // Bold + italic: ***text***
2407
+ if (text.slice(i, i + 3) === '***') {
2408
+ const end = text.indexOf('***', i + 3);
2409
+ if (end !== -1) {
2410
+ const inner = text.slice(i + 3, end);
2411
+ result += style.bold + style.italic + fg.white + inner + '\x1b[0m';
2412
+ hasFormatting = true;
2413
+ i = end + 3;
2414
+ continue;
2415
+ }
2416
+ }
2417
+ // Bold: **text**
2418
+ if (text.slice(i, i + 2) === '**') {
2419
+ const end = text.indexOf('**', i + 2);
2420
+ if (end !== -1) {
2421
+ const inner = text.slice(i + 2, end);
2422
+ result += style.bold + fg.white + inner + '\x1b[0m';
2423
+ hasFormatting = true;
2424
+ i = end + 2;
2425
+ continue;
2426
+ }
2427
+ }
2428
+ // Italic: *text*
2429
+ if (text[i] === '*' && text[i + 1] !== '*') {
2430
+ const end = text.indexOf('*', i + 1);
2431
+ if (end !== -1 && end > i + 1) {
2432
+ const inner = text.slice(i + 1, end);
2433
+ result += style.italic + inner + '\x1b[0m';
2434
+ hasFormatting = true;
2435
+ i = end + 1;
2436
+ continue;
2437
+ }
2438
+ }
2439
+ result += text[i];
2440
+ i++;
2441
+ }
2442
+ return { formatted: result, hasFormatting };
2443
+ }
2444
+ /**
2445
+ * Format plain text lines with markdown support
2412
2446
  */
2413
2447
  formatTextLines(text, maxWidth, firstPrefix, firstStyle) {
2414
2448
  const lines = [];
@@ -2417,21 +2451,79 @@ export class App {
2417
2451
  const line = contentLines[i];
2418
2452
  const prefix = i === 0 ? firstPrefix : ' ';
2419
2453
  const prefixStyle = i === 0 ? firstStyle : '';
2420
- if (line.length > maxWidth - prefix.length) {
2421
- const wrapped = this.wordWrap(line, maxWidth - prefix.length);
2422
- for (let j = 0; j < wrapped.length; j++) {
2454
+ // Heading: ## or ### etc.
2455
+ const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
2456
+ if (headingMatch) {
2457
+ const level = headingMatch[1].length;
2458
+ const headingText = headingMatch[2];
2459
+ const headingColor = level <= 2 ? fg.rgb(97, 175, 239) : fg.rgb(198, 120, 221);
2460
+ lines.push({
2461
+ text: prefix + headingColor + style.bold + headingText + '\x1b[0m',
2462
+ style: prefixStyle,
2463
+ raw: true,
2464
+ });
2465
+ continue;
2466
+ }
2467
+ // Horizontal rule: --- or *** or ___
2468
+ if (/^[-*_]{3,}\s*$/.test(line)) {
2469
+ const ruleWidth = Math.min(maxWidth - 4, 40);
2470
+ lines.push({
2471
+ text: prefix + fg.gray + '─'.repeat(ruleWidth) + '\x1b[0m',
2472
+ style: prefixStyle,
2473
+ raw: true,
2474
+ });
2475
+ continue;
2476
+ }
2477
+ // List items: - item or * item or numbered 1. item
2478
+ const listMatch = line.match(/^(\s*)([-*]|\d+\.)\s+(.+)$/);
2479
+ if (listMatch) {
2480
+ const indent = listMatch[1];
2481
+ const bullet = listMatch[2];
2482
+ const content = listMatch[3];
2483
+ const { formatted, hasFormatting } = this.applyInlineMarkdown(content);
2484
+ const bulletChar = bullet === '-' || bullet === '*' ? '•' : bullet;
2485
+ if (hasFormatting) {
2486
+ lines.push({
2487
+ text: prefix + indent + fg.gray + bulletChar + '\x1b[0m' + ' ' + formatted,
2488
+ style: prefixStyle,
2489
+ raw: true,
2490
+ });
2491
+ }
2492
+ else {
2423
2493
  lines.push({
2424
- text: (j === 0 ? prefix : ' ') + wrapped[j],
2425
- style: j === 0 ? prefixStyle : '',
2494
+ text: prefix + indent + bulletChar + ' ' + content,
2495
+ style: prefixStyle,
2426
2496
  });
2427
2497
  }
2498
+ continue;
2428
2499
  }
2429
- else {
2500
+ // Regular text with possible inline markdown
2501
+ const { formatted, hasFormatting } = this.applyInlineMarkdown(line);
2502
+ if (hasFormatting) {
2430
2503
  lines.push({
2431
- text: prefix + line,
2504
+ text: prefix + formatted,
2432
2505
  style: prefixStyle,
2506
+ raw: true,
2433
2507
  });
2434
2508
  }
2509
+ else {
2510
+ // Plain text - word wrap as before
2511
+ if (line.length > maxWidth - prefix.length) {
2512
+ const wrapped = this.wordWrap(line, maxWidth - prefix.length);
2513
+ for (let j = 0; j < wrapped.length; j++) {
2514
+ lines.push({
2515
+ text: (j === 0 ? prefix : ' ') + wrapped[j],
2516
+ style: j === 0 ? prefixStyle : '',
2517
+ });
2518
+ }
2519
+ }
2520
+ else {
2521
+ lines.push({
2522
+ text: prefix + line,
2523
+ style: prefixStyle,
2524
+ });
2525
+ }
2526
+ }
2435
2527
  }
2436
2528
  return lines;
2437
2529
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeep",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
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",