sapper-iq 1.0.25 → 1.0.26
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 +32 -8
package/package.json
CHANGED
package/sapper.mjs
CHANGED
|
@@ -64,16 +64,30 @@ function recreateReadline() {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// Directories to ignore when listing files
|
|
68
|
+
const IGNORE_DIRS = new Set([
|
|
69
|
+
'node_modules', '.git', '.svn', '.hg', 'dist', 'build',
|
|
70
|
+
'.next', '.nuxt', '__pycache__', '.cache', 'coverage',
|
|
71
|
+
'.idea', '.vscode', 'vendor', 'target', '.gradle'
|
|
72
|
+
]);
|
|
73
|
+
|
|
67
74
|
const tools = {
|
|
68
75
|
read: (path) => {
|
|
69
76
|
try { return fs.readFileSync(path.trim(), 'utf8'); }
|
|
70
77
|
catch (error) { return `Error reading file: ${error.message}`; }
|
|
71
78
|
},
|
|
72
|
-
write: (path, content) => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
write: async (path, content) => {
|
|
80
|
+
const trimmedPath = path.trim();
|
|
81
|
+
console.log(chalk.yellow.bold(`\n[WRITE] Sapper wants to write to: `) + chalk.white(trimmedPath));
|
|
82
|
+
console.log(chalk.gray(`Content preview (first 200 chars):\n${content?.substring(0, 200)}${content?.length > 200 ? '...' : ''}`));
|
|
83
|
+
const confirm = await safeQuestion(chalk.yellow('Allow write? (y/n): '));
|
|
84
|
+
if (confirm.toLowerCase() === 'y') {
|
|
85
|
+
try {
|
|
86
|
+
fs.writeFileSync(trimmedPath, content);
|
|
87
|
+
return `Successfully saved changes to ${trimmedPath}`;
|
|
88
|
+
} catch (error) { return `Error writing file: ${error.message}`; }
|
|
89
|
+
}
|
|
90
|
+
return "Write blocked by user.";
|
|
77
91
|
},
|
|
78
92
|
mkdir: (path) => {
|
|
79
93
|
try {
|
|
@@ -100,8 +114,18 @@ const tools = {
|
|
|
100
114
|
return "Command blocked by user.";
|
|
101
115
|
},
|
|
102
116
|
list: (path) => {
|
|
103
|
-
try {
|
|
104
|
-
|
|
117
|
+
try {
|
|
118
|
+
const dir = path.trim() || '.';
|
|
119
|
+
const entries = fs.readdirSync(dir);
|
|
120
|
+
// Filter out ignored directories
|
|
121
|
+
const filtered = entries.filter(entry => {
|
|
122
|
+
if (IGNORE_DIRS.has(entry)) return false;
|
|
123
|
+
// Also skip hidden files/folders (starting with .) except current dir
|
|
124
|
+
if (entry.startsWith('.') && entry !== '.') return false;
|
|
125
|
+
return true;
|
|
126
|
+
});
|
|
127
|
+
return filtered.length > 0 ? filtered.join('\n') : '(empty or all files filtered)';
|
|
128
|
+
} catch (e) { return `Error: ${e.message}`; }
|
|
105
129
|
}
|
|
106
130
|
};
|
|
107
131
|
|
|
@@ -258,7 +282,7 @@ WORKFLOW:
|
|
|
258
282
|
if (type.toLowerCase() === 'list') result = tools.list(path);
|
|
259
283
|
else if (type.toLowerCase() === 'read') result = tools.read(path);
|
|
260
284
|
else if (type.toLowerCase() === 'mkdir') result = tools.mkdir(path);
|
|
261
|
-
else if (type.toLowerCase() === 'write') result = tools.write(path, content);
|
|
285
|
+
else if (type.toLowerCase() === 'write') result = await tools.write(path, content);
|
|
262
286
|
else if (type.toLowerCase() === 'shell') result = await tools.shell(path);
|
|
263
287
|
|
|
264
288
|
messages.push({ role: 'user', content: `RESULT (${path}): ${result}` });
|