@blockrun/runcode 2.2.1 → 2.2.3

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.
@@ -71,6 +71,17 @@ const DIRECT_COMMANDS = {
71
71
  ctx.onEvent({ kind: 'text_delta', text: 'Last commit undone. Changes preserved in staging.\n' });
72
72
  emitDone(ctx);
73
73
  },
74
+ '/help': (ctx) => {
75
+ ctx.onEvent({ kind: 'text_delta', text: `**RunCode Commands**\n\n` +
76
+ ` **Coding:** /commit /review /test /fix /debug /explain /search /find /refactor /scaffold\n` +
77
+ ` **Git:** /push /pr /undo /status /diff /log /branch /stash /unstash\n` +
78
+ ` **Analysis:** /security /lint /optimize /todo /deps /clean /migrate /doc\n` +
79
+ ` **Session:** /plan /execute /compact /retry /sessions /resume /context /tasks\n` +
80
+ ` **Info:** /model /wallet /cost /mcp /doctor /version /bug /help\n` +
81
+ ` **UI:** /clear /exit\n`
82
+ });
83
+ emitDone(ctx);
84
+ },
74
85
  '/bug': (ctx) => {
75
86
  ctx.onEvent({ kind: 'text_delta', text: 'Report issues at: https://github.com/BlockRunAI/runcode/issues\n' });
76
87
  emitDone(ctx);
@@ -99,12 +110,15 @@ const DIRECT_COMMANDS = {
99
110
  '/context': async (ctx) => {
100
111
  const { estimated, apiAnchored } = getAnchoredTokenCount(ctx.history);
101
112
  const contextWindow = getContextWindow(ctx.config.model);
102
- const usagePct = ((estimated / contextWindow) * 100).toFixed(1);
113
+ const pct = (estimated / contextWindow) * 100;
114
+ const usagePct = pct.toFixed(1);
115
+ const warning = pct > 80 ? ' ⚠ Near limit — consider /compact\n' : '';
103
116
  ctx.onEvent({ kind: 'text_delta', text: `**Session Context**\n` +
104
117
  ` Model: ${ctx.config.model}\n` +
105
118
  ` Mode: ${ctx.config.permissionMode || 'default'}\n` +
106
119
  ` Messages: ${ctx.history.length}\n` +
107
120
  ` Tokens: ~${estimated.toLocaleString()} / ${(contextWindow / 1000).toFixed(0)}k (${usagePct}%)${apiAnchored ? ' ✓' : ' ~'}\n` +
121
+ warning +
108
122
  ` Session: ${ctx.sessionId}\n` +
109
123
  ` Directory: ${ctx.config.workingDir || process.cwd()}\n`
110
124
  });
@@ -128,6 +142,12 @@ const DIRECT_COMMANDS = {
128
142
  }
129
143
  checks.push(fs.existsSync(path.join(BLOCKRUN_DIR, 'wallet.json')) ? '✓ wallet configured' : '⚠ no wallet — run: runcode setup');
130
144
  checks.push(fs.existsSync(path.join(BLOCKRUN_DIR, 'runcode-config.json')) ? '✓ config file exists' : '⚠ no config — using defaults');
145
+ // Check MCP
146
+ const { listMcpServers } = await import('../mcp/client.js');
147
+ const mcpServers = listMcpServers();
148
+ checks.push(mcpServers.length > 0
149
+ ? `✓ MCP: ${mcpServers.length} server(s), ${mcpServers.reduce((a, s) => a + s.toolCount, 0)} tools`
150
+ : '⚠ no MCP servers connected');
131
151
  checks.push(`✓ model: ${ctx.config.model}`);
132
152
  checks.push(`✓ history: ${ctx.history.length} messages, ~${estimateHistoryTokens(ctx.history).toLocaleString()} tokens`);
133
153
  checks.push(`✓ session: ${ctx.sessionId}`);
@@ -34,7 +34,7 @@ async function execute(input, ctx) {
34
34
  child.kill('SIGKILL');
35
35
  }
36
36
  catch { /* already dead */ }
37
- }, 3000);
37
+ }, 5000); // Give 5s for graceful shutdown before SIGKILL
38
38
  }, timeoutMs);
39
39
  // Handle abort signal
40
40
  const onAbort = () => {
@@ -26,7 +26,7 @@ async function execute(input, ctx) {
26
26
  if (!content.includes(oldStr)) {
27
27
  // Find lines containing fragments of old_string for helpful context
28
28
  const lines = content.split('\n');
29
- const searchTerms = oldStr.split('\n').map(l => l.trim()).filter(l => l.length > 8);
29
+ const searchTerms = oldStr.split('\n').map(l => l.trim()).filter(l => l.length > 3);
30
30
  const matchedLines = [];
31
31
  if (searchTerms.length > 0) {
32
32
  for (let i = 0; i < lines.length && matchedLines.length < 5; i++) {
@@ -95,7 +95,14 @@ class MarkdownRenderer {
95
95
  if (line.match(/^(\s*)[-*] /)) {
96
96
  return line.replace(/^(\s*)[-*] /, '$1• ');
97
97
  }
98
- // Numbered lists — leave as-is
98
+ // Numbered lists
99
+ if (/^\s*\d+\.\s/.test(line)) {
100
+ return this.renderInline(line);
101
+ }
102
+ // Blockquotes
103
+ if (line.startsWith('> ')) {
104
+ return chalk.dim('│ ') + chalk.italic(this.renderInline(line.slice(2)));
105
+ }
99
106
  // Tables — leave as-is (chalk doesn't help much)
100
107
  // Inline formatting
101
108
  return this.renderInline(line);
@@ -109,6 +116,8 @@ class MarkdownRenderer {
109
116
  .replace(/\*\*([^*]+)\*\*/g, (_, t) => chalk.bold(t))
110
117
  // Italic (only single * not preceded/followed by *)
111
118
  .replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, (_, t) => chalk.italic(t))
119
+ // Strikethrough
120
+ .replace(/~~([^~]+)~~/g, (_, t) => chalk.strikethrough(t))
112
121
  // Links
113
122
  .replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => chalk.blue.underline(label) + chalk.dim(` (${url})`))
114
123
  // Restore code markers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/runcode",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "description": "RunCode — AI coding agent powered by 41+ models. Pay per use with USDC.",
5
5
  "type": "module",
6
6
  "bin": {