openmagic 0.20.0 → 0.22.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,15 +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 the grounded files don't contain the element you need to modify, return: {"modifications":[],"explanation":"NEED_FILE: path/to/file.tsx"} \u2014 the system will automatically read it and retry
908
- 4. For style changes, prefer modifying existing CSS/Tailwind classes over adding inline styles. Check the dependencies to know if the project uses Tailwind, MUI, etc.
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. Use the selected element's cssSelector, className, parentContainerStyles, and siblings to understand the layout context before making changes
913
- 9. Use the page URL and componentHint to identify the correct source file`;
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`;
914
915
  function buildContextParts(context) {
915
916
  const parts = {};
916
917
  if (context.selectedElement) {
@@ -1356,15 +1357,60 @@ var OPENAI_COMPATIBLE_PROVIDERS = /* @__PURE__ */ new Set([
1356
1357
  "zhipu",
1357
1358
  "doubao"
1358
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
+ }
1359
1406
  async function handleLlmChat(params, onChunk, onDone, onError) {
1360
1407
  const { provider, model, apiKey, messages, context } = params;
1361
1408
  const wrappedOnDone = (result) => {
1362
1409
  let modifications;
1363
1410
  try {
1364
- const jsonMatch = result.content.match(/```json\s*([\s\S]*?)```/) || result.content.match(/\{[\s\S]*"modifications"[\s\S]*\}/);
1365
- if (jsonMatch) {
1366
- const jsonStr = jsonMatch[1] || jsonMatch[0];
1367
- const parsed = JSON.parse(jsonStr);
1411
+ const json = extractJsonFromResponse(result.content);
1412
+ if (json) {
1413
+ const parsed = JSON.parse(json);
1368
1414
  modifications = parsed.modifications;
1369
1415
  }
1370
1416
  } catch {
@@ -1401,7 +1447,7 @@ async function handleLlmChat(params, onChunk, onDone, onError) {
1401
1447
  }
1402
1448
 
1403
1449
  // src/server.ts
1404
- var VERSION = "0.20.0";
1450
+ var VERSION = "0.22.0";
1405
1451
  var __dirname = dirname2(fileURLToPath(import.meta.url));
1406
1452
  function attachOpenMagic(httpServer, roots) {
1407
1453
  function handleRequest(req, res) {
@@ -1934,7 +1980,7 @@ process.on("uncaughtException", (err) => {
1934
1980
  process.exit(1);
1935
1981
  });
1936
1982
  var childProcesses = [];
1937
- var VERSION2 = "0.20.0";
1983
+ var VERSION2 = "0.22.0";
1938
1984
  function ask(question) {
1939
1985
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1940
1986
  return new Promise((resolve3) => {