@taj-special/dravix-code 1.1.25 → 1.1.27
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/dist/cli/repl.js +20 -10
- package/dist/services/context.js +30 -1
- package/package.json +1 -1
package/dist/cli/repl.js
CHANGED
|
@@ -2122,6 +2122,12 @@ export async function startRepl(cwd) {
|
|
|
2122
2122
|
|
|
2123
2123
|
## CRITICAL RULES — Follow these on every response
|
|
2124
2124
|
|
|
2125
|
+
### Creating files
|
|
2126
|
+
- NEVER show code in code blocks when the user asks to create files or a project.
|
|
2127
|
+
- ALWAYS use <write_file path="filename"> tags to create actual files.
|
|
2128
|
+
- Code blocks are for short explanations only — they do NOT create files.
|
|
2129
|
+
- Output ALL required files in ONE response using <write_file> tags.
|
|
2130
|
+
|
|
2125
2131
|
### File operations
|
|
2126
2132
|
- **write_file** = CREATE only. Use it ONLY when a file does NOT exist yet.
|
|
2127
2133
|
- **edit_file** = MODIFY existing files. For ANY change to an existing file, always use edit_file with <find>/<replace>.
|
|
@@ -2773,24 +2779,28 @@ export async function startRepl(cwd) {
|
|
|
2773
2779
|
}
|
|
2774
2780
|
const allOps = parseOps(normalized);
|
|
2775
2781
|
// ── Detect incomplete plan: AI described steps but didn't output tags ──
|
|
2776
|
-
// Pattern: response has numbered items like "2. something" or "3. something"
|
|
2777
|
-
// but very few actual file operation tags were output → force continuation
|
|
2778
2782
|
if (!readFileContinue && !streamCancelled) {
|
|
2779
2783
|
const hasAnyReadOp = allOps.some(op => op.type === 'read_file' || op.type === 'read_folder' || op.type === 'search_code');
|
|
2780
2784
|
const writeOps = allOps.filter(op => op.type !== 'read_file' && op.type !== 'read_folder' && op.type !== 'search_code').length;
|
|
2781
2785
|
const plannedSteps = (normalized.match(/^\s*[2-9]\.\s+\S/mg) ?? []).length;
|
|
2782
|
-
|
|
2786
|
+
const hasCodeFence = normalized.includes('```');
|
|
2787
|
+
const hasStepList = (normalized.match(/^\s*\d+[.)]\s+\S/mg) ?? []).length >= 2;
|
|
2788
|
+
// Case 1: AI listed numbered steps (2+) but produced zero file ops
|
|
2783
2789
|
if (plannedSteps >= 1 && writeOps === 0 && !hasAnyReadOp) {
|
|
2784
|
-
history.push({ role: 'system', content: 'You described
|
|
2790
|
+
history.push({ role: 'system', content: 'CRITICAL ERROR: You described steps but produced NO file operation tags. You MUST output <write_file> or <edit_file> tags to create/modify actual files. Do NOT show code in ``` blocks — use <write_file path="filename"> tags instead. Output all the tags NOW. No explanation.' });
|
|
2791
|
+
readFileContinue = true;
|
|
2792
|
+
// Case 2: AI showed code blocks + numbered list but no tags — regardless of language
|
|
2793
|
+
}
|
|
2794
|
+
else if (hasCodeFence && hasStepList && writeOps === 0 && allOps.length === 0) {
|
|
2795
|
+
history.push({ role: 'system', content: 'CRITICAL ERROR: You are showing code in ``` blocks instead of using <write_file> tags. This is wrong. ``` blocks do NOT create files — only <write_file> tags create files. Replace every ``` code block with a <write_file path="filename"> tag and output ALL files now.' });
|
|
2785
2796
|
readFileContinue = true;
|
|
2786
|
-
//
|
|
2797
|
+
// Case 3: Long response with code blocks but zero file ops — catch any language
|
|
2787
2798
|
}
|
|
2788
|
-
else if (writeOps === 0 && allOps.length === 0 && normalized.trim().length >
|
|
2789
|
-
const hasCodeFence = normalized.includes('```');
|
|
2790
|
-
const hasStepList = (normalized.match(/^\s*\d+[.)]\s+\S/mg) ?? []).length >= 2;
|
|
2799
|
+
else if (hasCodeFence && writeOps === 0 && allOps.length === 0 && normalized.trim().length > 400) {
|
|
2791
2800
|
const hasWouldNeed = /(?:should|would need to|need to|you(?:'d)? need to|we(?:'d)? need to)\s+(?:edit|modify|update|change|create|add|remove)/i.test(normalized);
|
|
2792
|
-
|
|
2793
|
-
|
|
2801
|
+
const looksLikeFileDump = normalized.split('```').length > 3; // 2+ code blocks
|
|
2802
|
+
if (hasWouldNeed || looksLikeFileDump) {
|
|
2803
|
+
history.push({ role: 'system', content: 'CRITICAL ERROR: You showed code in ``` blocks instead of using <write_file> tags. ``` blocks are for explanations only — they do NOT create actual files. Output all files using <write_file path="..."> tags RIGHT NOW. No text, no explanation — only tags.' });
|
|
2794
2804
|
readFileContinue = true;
|
|
2795
2805
|
}
|
|
2796
2806
|
}
|
package/dist/services/context.js
CHANGED
|
@@ -115,6 +115,29 @@ export function extractRelevantSections(fileContent, userMessage, contextLines =
|
|
|
115
115
|
out.push(`[Use <read_file lines="N-M"/> to read any section not shown above]`);
|
|
116
116
|
return out.join('\n');
|
|
117
117
|
}
|
|
118
|
+
// Detect top-level subdirectories that look like separate standalone projects
|
|
119
|
+
function detectSeparateProjects(root, files) {
|
|
120
|
+
const topDirFiles = new Map();
|
|
121
|
+
for (const f of files) {
|
|
122
|
+
const slash = f.indexOf('/');
|
|
123
|
+
if (slash === -1)
|
|
124
|
+
continue;
|
|
125
|
+
const dir = f.slice(0, slash);
|
|
126
|
+
if (!topDirFiles.has(dir))
|
|
127
|
+
topDirFiles.set(dir, []);
|
|
128
|
+
topDirFiles.get(dir).push(path.basename(f).toLowerCase());
|
|
129
|
+
}
|
|
130
|
+
const PROJECT_FILES = new Set([
|
|
131
|
+
'package.json', 'composer.json', 'config.php', 'index.php', 'index.js',
|
|
132
|
+
'index.ts', 'main.py', 'app.py', 'bot.php', 'main.go', 'pom.xml',
|
|
133
|
+
]);
|
|
134
|
+
const projectDirs = [];
|
|
135
|
+
for (const [dir, dirFiles] of topDirFiles) {
|
|
136
|
+
if (dirFiles.some(f => PROJECT_FILES.has(f)))
|
|
137
|
+
projectDirs.push(dir);
|
|
138
|
+
}
|
|
139
|
+
return projectDirs;
|
|
140
|
+
}
|
|
118
141
|
export function buildContext(root) {
|
|
119
142
|
const files = getProjectFiles(root);
|
|
120
143
|
const git = getGitStatus(root);
|
|
@@ -122,11 +145,17 @@ export function buildContext(root) {
|
|
|
122
145
|
const shell = process.platform === 'win32' ? 'Windows — PowerShell'
|
|
123
146
|
: process.platform === 'darwin' ? 'macOS — bash/zsh'
|
|
124
147
|
: 'Linux — bash';
|
|
148
|
+
const separateProjects = detectSeparateProjects(root, files);
|
|
149
|
+
const parentDirWarning = separateProjects.length >= 2
|
|
150
|
+
? `\n⚠ PARENT DIRECTORY — contains ${separateProjects.length} separate projects: ${separateProjects.join(', ')}\n` +
|
|
151
|
+
`RULE: NEVER modify files inside existing project folders (${separateProjects.join(', ')}) unless the user explicitly asks to work on that specific project.\n` +
|
|
152
|
+
`When creating a NEW project, ALWAYS create a NEW dedicated subfolder.`
|
|
153
|
+
: '';
|
|
125
154
|
return `Project: ${projectName}
|
|
126
155
|
Working dir: ${root}
|
|
127
156
|
OS: ${shell}
|
|
128
157
|
Git status:
|
|
129
158
|
${git || '(clean)'}
|
|
130
159
|
Files:
|
|
131
|
-
${files.length > 0 ? files.join('\n') : '(empty project)'}`;
|
|
160
|
+
${files.length > 0 ? files.join('\n') : '(empty project)'}${parentDirWarning}`;
|
|
132
161
|
}
|