sapper-iq 1.1.20 → 1.1.21

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.
Files changed (2) hide show
  1. package/package.json +4 -2
  2. package/sapper.mjs +45 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.1.20",
3
+ "version": "1.1.21",
4
4
  "description": "AI-powered development assistant that executes commands and builds projects",
5
5
  "main": "sapper.mjs",
6
6
  "bin": {
@@ -11,8 +11,10 @@
11
11
  "start": "node sapper.mjs"
12
12
  },
13
13
  "dependencies": {
14
- "ollama": "^0.5.0",
15
14
  "chalk": "^5.3.0",
15
+ "marked": "^15.0.12",
16
+ "marked-terminal": "^7.3.0",
17
+ "ollama": "^0.5.0",
16
18
  "ora": "^8.0.1"
17
19
  },
18
20
  "engines": {
package/sapper.mjs CHANGED
@@ -7,6 +7,8 @@ import ora from 'ora';
7
7
  import readline from 'readline';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { dirname, join } from 'path';
10
+ import { marked } from 'marked';
11
+ import TerminalRenderer from 'marked-terminal';
10
12
 
11
13
  const __filename = fileURLToPath(import.meta.url);
12
14
  const __dirname = dirname(__filename);
@@ -178,6 +180,36 @@ function statusBadge(text, type = 'info') {
178
180
  return badges[type] || badges.info;
179
181
  }
180
182
 
183
+ // Configure marked with terminal renderer
184
+ marked.setOptions({
185
+ renderer: new TerminalRenderer({
186
+ code: chalk.cyan,
187
+ blockquote: chalk.gray.italic,
188
+ html: chalk.gray,
189
+ heading: chalk.bold.cyan,
190
+ firstHeading: chalk.bold.cyan,
191
+ hr: chalk.gray('─'.repeat(40)),
192
+ listitem: chalk.yellow('• ') + '%s',
193
+ table: chalk.white,
194
+ paragraph: chalk.white,
195
+ strong: chalk.bold.white,
196
+ em: chalk.italic,
197
+ codespan: chalk.cyan,
198
+ del: chalk.strikethrough,
199
+ link: chalk.underline.blue,
200
+ href: chalk.gray
201
+ })
202
+ });
203
+
204
+ // Render markdown to terminal
205
+ function renderMarkdown(text) {
206
+ try {
207
+ return marked(text).trim();
208
+ } catch (e) {
209
+ return text; // Fallback to raw text
210
+ }
211
+ }
212
+
181
213
  let stepMode = false;
182
214
  let debugMode = false; // Toggle with /debug command
183
215
  let abortStream = false; // Flag to interrupt AI response
@@ -765,6 +797,19 @@ async function runSapper() {
765
797
  }
766
798
  }
767
799
  console.log();
800
+
801
+ // If response has markdown, show rendered version
802
+ const hasMarkdown = /\*\*|__|`|^#|^[-*] /m.test(msg);
803
+ if (hasMarkdown && !msg.includes('[TOOL:')) {
804
+ console.log(chalk.gray('─'.repeat(40)));
805
+ const rendered = renderMarkdown(msg);
806
+ const lines = rendered.split('\n');
807
+ for (const line of lines) {
808
+ console.log(chalk.magenta('│ ') + line);
809
+ }
810
+ console.log();
811
+ }
812
+
768
813
  messages.push({ role: 'assistant', content: msg });
769
814
 
770
815
  // Fixed regex: [^\]]+ stops at first ] to correctly separate path from content