@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 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
- // AI described a plan (numbered steps 2+) but did nothing at all — force execution
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 the steps but did not output any tags. Output the actual <edit_file> or <write_file> tags NOW to apply the changes. No explanationjust the tags.' });
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
- // AI gave a non-trivial response with zero operations of any kind
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 > 200) {
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
- if ((hasCodeFence || hasStepList) && hasWouldNeed) {
2793
- history.push({ role: 'system', content: 'You explained what to do but did not output any tags. Apply the changes NOW using <edit_file> or <write_file> tags. Do not re-explain — just output the tags.' });
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
  }
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taj-special/dravix-code",
3
- "version": "1.1.25",
3
+ "version": "1.1.27",
4
4
  "description": "AI-powered coding assistant CLI — Dravix Code",
5
5
  "type": "module",
6
6
  "bin": {