sapper-iq 1.1.20 → 1.1.22

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 +48 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.1.20",
3
+ "version": "1.1.22",
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
@@ -403,7 +435,9 @@ const tools = {
403
435
  },
404
436
  list: (path) => {
405
437
  try {
406
- const dir = path.trim() || '.';
438
+ let dir = path.trim() || '.';
439
+ // If AI sends "/" (root), treat as current directory "."
440
+ if (dir === '/') dir = '.';
407
441
  const entries = fs.readdirSync(dir);
408
442
  // Filter out ignored directories
409
443
  const filtered = entries.filter(entry => {
@@ -765,6 +799,19 @@ async function runSapper() {
765
799
  }
766
800
  }
767
801
  console.log();
802
+
803
+ // If response has markdown, show rendered version
804
+ const hasMarkdown = /\*\*|__|`|^#|^[-*] /m.test(msg);
805
+ if (hasMarkdown && !msg.includes('[TOOL:')) {
806
+ console.log(chalk.gray('─'.repeat(40)));
807
+ const rendered = renderMarkdown(msg);
808
+ const lines = rendered.split('\n');
809
+ for (const line of lines) {
810
+ console.log(chalk.magenta('│ ') + line);
811
+ }
812
+ console.log();
813
+ }
814
+
768
815
  messages.push({ role: 'assistant', content: msg });
769
816
 
770
817
  // Fixed regex: [^\]]+ stops at first ] to correctly separate path from content