sapper-iq 1.1.19 → 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 +54 -41
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.1.19",
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
@@ -503,44 +535,13 @@ async function runSapper() {
503
535
  if (messages.length === 0) {
504
536
  messages = [{
505
537
  role: 'system',
506
- content: `You are Sapper, a coding assistant.
507
-
508
- GOLDEN RULE:
509
- - NEVER add features the user didn't ask for.
510
- - ALWAYS confirm with the user before writing/patching files or running shell commands.
511
- - KEEP responses concise and to the point.
512
- TOOLS (use these to interact with files):
513
-
514
- [TOOL:LIST]path[/TOOL]
515
- → List files in a directory
516
- → Example: [TOOL:LIST].[/TOOL]
517
-
518
- [TOOL:READ]path[/TOOL]
519
- → Read a file's contents
520
- → Example: [TOOL:READ]./package.json[/TOOL]
521
-
522
- [TOOL:WRITE]path]content[/TOOL]
523
- → Create or overwrite a file (needs user confirmation)
524
- → Example: [TOOL:WRITE]./index.js]console.log("hello")[/TOOL]
525
-
526
- [TOOL:PATCH]path]old_text|||new_text[/TOOL]
527
- → Replace specific text in a file (needs user confirmation)
528
- → Example: [TOOL:PATCH]./app.js]old code|||new code[/TOOL]
529
-
530
- [TOOL:SEARCH]pattern[/TOOL]
531
- → Search for text across all files
532
- → Example: [TOOL:SEARCH]function login[/TOOL]
533
-
534
- [TOOL:SHELL]command[/TOOL]
535
- → Run a terminal command (needs user confirmation)
536
- → Example: [TOOL:SHELL]npm install express[/TOOL]
537
-
538
- PATH RULES:
539
- - Always use relative paths: ./file.js, ./src/app.js
540
- - NEVER use absolute paths like /file.js
541
- - Use . for current directory
542
-
543
- `
538
+ content: `You are Sapper, an AGENT, You can use tools to take action:
539
+ - [TOOL:LIST]path[/TOOL] - List directory
540
+ - [TOOL:READ]path[/TOOL] - Read file
541
+ - [TOOL:SEARCH]pattern[/TOOL] - Search codebase
542
+ - [TOOL:WRITE]path]content[/TOOL] - Create/overwrite file
543
+ - [TOOL:PATCH]path]old|||new[/TOOL] - Edit file
544
+ - [TOOL:SHELL]command[/TOOL] - Run terminal command`
544
545
  }];
545
546
  }
546
547
 
@@ -623,14 +624,13 @@ PATH RULES:
623
624
  // 4. Add reminder to stay in Agent Mode (not chatbot mode)
624
625
  messages.push({
625
626
  role: 'system',
626
- content: `CONTEXT PRUNED. REMINDER: You are an AGENT, not a chatbot. You MUST use tools to take action:
627
+ content: `CONTEXT PRUNED. REMINDER: You are an AGENT, You can use tools to take action:
627
628
  - [TOOL:LIST]path[/TOOL] - List directory
628
629
  - [TOOL:READ]path[/TOOL] - Read file
629
630
  - [TOOL:SEARCH]pattern[/TOOL] - Search codebase
630
631
  - [TOOL:WRITE]path]content[/TOOL] - Create/overwrite file
631
632
  - [TOOL:PATCH]path]old|||new[/TOOL] - Edit file
632
- - [TOOL:SHELL]command[/TOOL] - Run terminal command
633
- Do NOT just display content. Actually WRITE files using the tool.`
633
+ - [TOOL:SHELL]command[/TOOL] - Run terminal command.`
634
634
  });
635
635
 
636
636
  // 5. Save to context file so it persists
@@ -797,6 +797,19 @@ Do NOT just display content. Actually WRITE files using the tool.`
797
797
  }
798
798
  }
799
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
+
800
813
  messages.push({ role: 'assistant', content: msg });
801
814
 
802
815
  // Fixed regex: [^\]]+ stops at first ] to correctly separate path from content