sapper-iq 1.1.26 ā 1.1.28
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.
- package/package.json +1 -1
- package/sapper.mjs +81 -17
package/package.json
CHANGED
package/sapper.mjs
CHANGED
|
@@ -498,9 +498,9 @@ async function runSapper() {
|
|
|
498
498
|
|
|
499
499
|
// Quick tips box
|
|
500
500
|
console.log(box(
|
|
501
|
-
`${chalk.yellow('š”')}
|
|
501
|
+
`${chalk.yellow('š”')} Use ${chalk.cyan('@file')} to attach files (e.g., "fix @app.js")\n` +
|
|
502
502
|
`${chalk.yellow('š”')} Type ${chalk.cyan('/scan')} to load entire codebase\n` +
|
|
503
|
-
`${chalk.yellow('š”')} Type ${chalk.cyan('
|
|
503
|
+
`${chalk.yellow('š”')} Type ${chalk.cyan('/help')} for all commands`,
|
|
504
504
|
'Quick Tips', 'gray'
|
|
505
505
|
));
|
|
506
506
|
console.log();
|
|
@@ -552,13 +552,23 @@ async function runSapper() {
|
|
|
552
552
|
if (messages.length === 0) {
|
|
553
553
|
messages = [{
|
|
554
554
|
role: 'system',
|
|
555
|
-
content: `You are Sapper,
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
555
|
+
content: `You are Sapper, a high-level Autonomous Software Engineer.
|
|
556
|
+
Your goal is to solve the user's request by interacting with the filesystem and shell.
|
|
557
|
+
|
|
558
|
+
RULES:
|
|
559
|
+
1. EXPLORE FIRST: Use LIST and READ to understand the codebase before making changes.
|
|
560
|
+
2. THINK IN STEPS: Explain what you found and what you plan to do before executing tools.
|
|
561
|
+
3. BE PRECISE: When using PATCH, ensure the 'oldText' matches exactly.
|
|
562
|
+
4. VERIFY: After writing code, use the SHELL tool to run tests or linting.
|
|
563
|
+
5. NO HALLUCINATIONS: If a file doesn't exist, don't guess its content. List the directory instead.
|
|
564
|
+
|
|
565
|
+
TOOL SYNTAX:
|
|
566
|
+
- [TOOL:LIST]dir[/TOOL] - List directory contents
|
|
567
|
+
- [TOOL:READ]file_path[/TOOL] - Read file contents
|
|
568
|
+
- [TOOL:SEARCH]pattern[/TOOL] - Search codebase for pattern
|
|
569
|
+
- [TOOL:WRITE]path:::content[/TOOL] - Create/overwrite file
|
|
570
|
+
- [TOOL:PATCH]path:::old|||new[/TOOL] - Edit existing file
|
|
571
|
+
- [TOOL:SHELL]command[/TOOL] - Run shell command`
|
|
562
572
|
}];
|
|
563
573
|
}
|
|
564
574
|
|
|
@@ -641,13 +651,22 @@ async function runSapper() {
|
|
|
641
651
|
// 4. Add reminder to stay in Agent Mode (not chatbot mode)
|
|
642
652
|
messages.push({
|
|
643
653
|
role: 'system',
|
|
644
|
-
content: `CONTEXT PRUNED. REMINDER: You are
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
654
|
+
content: `CONTEXT PRUNED. REMINDER: You are Sapper, an Autonomous Software Engineer.
|
|
655
|
+
|
|
656
|
+
RULES:
|
|
657
|
+
1. EXPLORE FIRST: Use LIST and READ before making changes.
|
|
658
|
+
2. THINK IN STEPS: Explain your plan before executing tools.
|
|
659
|
+
3. BE PRECISE: When using PATCH, ensure 'oldText' matches exactly.
|
|
660
|
+
4. VERIFY: Run tests or linting after writing code.
|
|
661
|
+
5. NO HALLUCINATIONS: Don't guess file contents.
|
|
662
|
+
|
|
663
|
+
TOOL SYNTAX:
|
|
664
|
+
- [TOOL:LIST]dir[/TOOL]
|
|
665
|
+
- [TOOL:READ]file_path[/TOOL]
|
|
666
|
+
- [TOOL:SEARCH]pattern[/TOOL]
|
|
667
|
+
- [TOOL:WRITE]path:::content[/TOOL]
|
|
668
|
+
- [TOOL:PATCH]path:::old|||new[/TOOL]
|
|
669
|
+
- [TOOL:SHELL]command[/TOOL]`
|
|
651
670
|
});
|
|
652
671
|
|
|
653
672
|
// 5. Save to context file so it persists
|
|
@@ -662,6 +681,7 @@ async function runSapper() {
|
|
|
662
681
|
if (input.toLowerCase() === '/help') {
|
|
663
682
|
console.log();
|
|
664
683
|
const helpContent =
|
|
684
|
+
`${chalk.cyan('@file')} ${chalk.gray('ā')} Attach file to prompt (e.g., @src/app.js)\n` +
|
|
665
685
|
`${chalk.cyan('/scan')} ${chalk.gray('ā')} Scan codebase into context\n` +
|
|
666
686
|
`${chalk.cyan('/recall')} ${chalk.gray('ā')} Search memory for relevant context\n` +
|
|
667
687
|
`${chalk.cyan('/reset /clear')} ${chalk.gray('ā')} Clear all context\n` +
|
|
@@ -770,7 +790,51 @@ async function runSapper() {
|
|
|
770
790
|
continue;
|
|
771
791
|
}
|
|
772
792
|
|
|
773
|
-
|
|
793
|
+
// Process @file attachments in prompt (e.g., "analyze @package.json" or "fix @src/index.js")
|
|
794
|
+
let processedInput = input;
|
|
795
|
+
const fileAttachments = [];
|
|
796
|
+
const attachRegex = /@([\w.\/\-_]+)/g;
|
|
797
|
+
let attachMatch;
|
|
798
|
+
|
|
799
|
+
while ((attachMatch = attachRegex.exec(input)) !== null) {
|
|
800
|
+
const filePath = attachMatch[1];
|
|
801
|
+
try {
|
|
802
|
+
if (fs.existsSync(filePath)) {
|
|
803
|
+
const stats = fs.statSync(filePath);
|
|
804
|
+
if (stats.isFile()) {
|
|
805
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
806
|
+
console.log(chalk.yellow(`ā ļø @${filePath} is too large (${Math.round(stats.size/1024)}KB), skipping`));
|
|
807
|
+
} else {
|
|
808
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
809
|
+
fileAttachments.push({ path: filePath, content, size: stats.size });
|
|
810
|
+
console.log(chalk.green(`š Attached: ${filePath} (${Math.round(stats.size/1024)}KB)`));
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
} else {
|
|
814
|
+
// Not a file - might be an @mention for something else, ignore
|
|
815
|
+
}
|
|
816
|
+
} catch (e) {
|
|
817
|
+
console.log(chalk.yellow(`ā ļø Could not read @${filePath}: ${e.message}`));
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// Build the final message with attachments
|
|
822
|
+
if (fileAttachments.length > 0) {
|
|
823
|
+
let attachedContent = '\n\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n';
|
|
824
|
+
attachedContent += `š ATTACHED FILES (${fileAttachments.length})\n`;
|
|
825
|
+
attachedContent += 'āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n';
|
|
826
|
+
|
|
827
|
+
for (const file of fileAttachments) {
|
|
828
|
+
attachedContent += `āāāā ${file.path} āāā\n`;
|
|
829
|
+
attachedContent += file.content;
|
|
830
|
+
if (!file.content.endsWith('\n')) attachedContent += '\n';
|
|
831
|
+
attachedContent += `āāāā END ${file.path} āāā\n\n`;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
processedInput = input + attachedContent;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
messages.push({ role: 'user', content: processedInput });
|
|
774
838
|
|
|
775
839
|
let toolRounds = 0; // Prevent infinite loops
|
|
776
840
|
const MAX_TOOL_ROUNDS = 20;
|