openmagic 0.19.0 → 0.21.0

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.js CHANGED
@@ -902,14 +902,16 @@ You MUST respond with valid JSON in this exact format:
902
902
  - \`delete\`: Delete a file. No search/replace/content needed.
903
903
 
904
904
  ## Rules
905
- 1. The \`search\` field must contain the EXACT text from the source file \u2014 copy it precisely, including whitespace and indentation
906
- 2. Keep modifications minimal \u2014 change only what's needed
907
- 3. If you need to read a file first, say so in the explanation and the developer can provide it
908
- 4. For style changes, prefer modifying existing CSS/Tailwind classes over adding inline styles
909
- 5. Always preserve the existing code style and conventions
910
- 6. If the change involves multiple files, include all modifications in the array
911
- 7. ALWAYS respond with the JSON format above, even for explanations (put them in the "explanation" field)
912
- 8. If you cannot make the requested change, set modifications to an empty array and explain why`;
905
+ 1. Copy the search string EXACTLY from the grounded source files \u2014 do not retype, reformat, or change whitespace/indentation
906
+ 2. Include 3-5 lines of surrounding context in the search field to ensure uniqueness
907
+ 3. Keep modifications minimal \u2014 change only what's needed
908
+ 4. If the grounded files don't contain the code you need to modify, return: {"modifications":[],"explanation":"NEED_FILE: exact/relative/path/to/file.ext"}
909
+ 5. For style changes: check the dependencies (package.json) to know if the project uses Tailwind, MUI, etc. Use the project's styling approach, not raw CSS
910
+ 6. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the full layout context
911
+ 7. Use the page URL route and componentHint to identify the correct source file to modify
912
+ 8. Always preserve existing code style, conventions, and indentation
913
+ 9. If the change involves multiple files, include all modifications in the array
914
+ 10. ALWAYS respond with valid JSON only \u2014 no text before or after the JSON object`;
913
915
  function buildContextParts(context) {
914
916
  const parts = {};
915
917
  if (context.selectedElement) {
@@ -1355,15 +1357,60 @@ var OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set([
1355
1357
  "zhipu",
1356
1358
  "doubao"
1357
1359
  ]);
1360
+ function extractJsonFromResponse(content) {
1361
+ const mdMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
1362
+ if (mdMatch?.[1]) {
1363
+ const candidate = mdMatch[1].trim();
1364
+ try {
1365
+ JSON.parse(candidate);
1366
+ return candidate;
1367
+ } catch {
1368
+ }
1369
+ }
1370
+ const start = content.indexOf("{");
1371
+ if (start === -1) return null;
1372
+ let depth = 0;
1373
+ let inString = false;
1374
+ let escape = false;
1375
+ for (let i = start; i < content.length; i++) {
1376
+ const ch = content[i];
1377
+ if (escape) {
1378
+ escape = false;
1379
+ continue;
1380
+ }
1381
+ if (ch === "\\" && inString) {
1382
+ escape = true;
1383
+ continue;
1384
+ }
1385
+ if (ch === '"') {
1386
+ inString = !inString;
1387
+ continue;
1388
+ }
1389
+ if (inString) continue;
1390
+ if (ch === "{") depth++;
1391
+ if (ch === "}") {
1392
+ depth--;
1393
+ if (depth === 0) {
1394
+ const candidate = content.substring(start, i + 1);
1395
+ try {
1396
+ JSON.parse(candidate);
1397
+ return candidate;
1398
+ } catch {
1399
+ return null;
1400
+ }
1401
+ }
1402
+ }
1403
+ }
1404
+ return null;
1405
+ }
1358
1406
  async function handleLlmChat(params, onChunk, onDone, onError) {
1359
1407
  const { provider, model, apiKey, messages, context } = params;
1360
1408
  const wrappedOnDone = (result) => {
1361
1409
  let modifications;
1362
1410
  try {
1363
- const jsonMatch = result.content.match(/```json\s*([\s\S]*?)```/) || result.content.match(/\{[\s\S]*"modifications"[\s\S]*\}/);
1364
- if (jsonMatch) {
1365
- const jsonStr = jsonMatch[1] || jsonMatch[0];
1366
- const parsed = JSON.parse(jsonStr);
1411
+ const json = extractJsonFromResponse(result.content);
1412
+ if (json) {
1413
+ const parsed = JSON.parse(json);
1367
1414
  modifications = parsed.modifications;
1368
1415
  }
1369
1416
  } catch {
@@ -1400,7 +1447,7 @@ async function handleLlmChat(params, onChunk, onDone, onError) {
1400
1447
  }
1401
1448
 
1402
1449
  // src/server.ts
1403
- var VERSION = "0.19.0";
1450
+ var VERSION = "0.21.0";
1404
1451
  var __dirname = dirname2(fileURLToPath(import.meta.url));
1405
1452
  function attachOpenMagic(httpServer, roots) {
1406
1453
  function handleRequest(req, res) {
@@ -1933,7 +1980,7 @@ process.on("uncaughtException", (err) => {
1933
1980
  process.exit(1);
1934
1981
  });
1935
1982
  var childProcesses = [];
1936
- var VERSION2 = "0.19.0";
1983
+ var VERSION2 = "0.21.0";
1937
1984
  function ask(question) {
1938
1985
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1939
1986
  return new Promise((resolve3) => {