openmagic 0.11.0 → 0.12.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
@@ -81,7 +81,8 @@ import {
81
81
  statSync,
82
82
  readdirSync,
83
83
  copyFileSync,
84
- mkdirSync as mkdirSync2
84
+ mkdirSync as mkdirSync2,
85
+ realpathSync
85
86
  } from "fs";
86
87
  import { join as join2, resolve, relative, dirname, extname } from "path";
87
88
  var IGNORED_DIRS = /* @__PURE__ */ new Set([
@@ -117,10 +118,17 @@ var IGNORED_EXTENSIONS = /* @__PURE__ */ new Set([
117
118
  ]);
118
119
  function isPathSafe(filePath, roots) {
119
120
  const resolved = resolve(filePath);
121
+ let real;
122
+ try {
123
+ real = realpathSync(resolved);
124
+ } catch {
125
+ real = resolved;
126
+ }
120
127
  return roots.some((root) => {
121
128
  const resolvedRoot = resolve(root);
122
129
  const rel = relative(resolvedRoot, resolved);
123
- return !rel.startsWith("..") && !rel.startsWith("/") && !rel.startsWith("\\");
130
+ const realRel = relative(resolvedRoot, real);
131
+ return !rel.startsWith("..") && !rel.startsWith("/") && !rel.startsWith("\\") && (!realRel.startsWith("..") && !realRel.startsWith("/") && !realRel.startsWith("\\"));
124
132
  });
125
133
  }
126
134
  function readFileSafe(filePath, roots) {
@@ -902,6 +910,18 @@ You MUST respond with valid JSON in this exact format:
902
910
  6. If the change involves multiple files, include all modifications in the array
903
911
  7. ALWAYS respond with the JSON format above, even for explanations (put them in the "explanation" field)
904
912
  8. If you cannot make the requested change, set modifications to an empty array and explain why`;
913
+ function buildContextParts(context) {
914
+ const parts = {};
915
+ if (context.selectedElement) parts.selectedElement = context.selectedElement.outerHTML;
916
+ if (context.files?.length) {
917
+ parts.filePath = context.files[0].path;
918
+ parts.fileContent = context.files[0].content;
919
+ }
920
+ if (context.projectTree) parts.projectTree = context.projectTree;
921
+ if (context.networkLogs) parts.networkLogs = context.networkLogs.map((l) => `${l.method} ${l.url} \u2192 ${l.status || "pending"}`).join("\n");
922
+ if (context.consoleLogs) parts.consoleLogs = context.consoleLogs.map((l) => `[${l.level}] ${l.args.join(" ")}`).join("\n");
923
+ return parts;
924
+ }
905
925
  function buildUserMessage(userPrompt, context) {
906
926
  const parts = [];
907
927
  if (context.projectTree) {
@@ -957,24 +977,7 @@ async function chatOpenAICompatible(provider, model, apiKey, messages, context,
957
977
  for (let i = 0; i < messages.length; i++) {
958
978
  const msg = messages[i];
959
979
  if (msg.role === "user" && typeof msg.content === "string" && i === lastUserIdx) {
960
- const contextParts = {};
961
- if (context.selectedElement) {
962
- contextParts.selectedElement = context.selectedElement.outerHTML;
963
- }
964
- if (context.files && context.files.length > 0) {
965
- contextParts.filePath = context.files[0].path;
966
- contextParts.fileContent = context.files[0].content;
967
- }
968
- if (context.projectTree) {
969
- contextParts.projectTree = context.projectTree;
970
- }
971
- if (context.networkLogs) {
972
- contextParts.networkLogs = context.networkLogs.map((l) => `${l.method} ${l.url} \u2192 ${l.status || "pending"}`).join("\n");
973
- }
974
- if (context.consoleLogs) {
975
- contextParts.consoleLogs = context.consoleLogs.map((l) => `[${l.level}] ${l.args.join(" ")}`).join("\n");
976
- }
977
- const enrichedContent = buildUserMessage(msg.content, contextParts);
980
+ const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));
978
981
  const modelInfo2 = providerConfig.models.find((m) => m.id === model);
979
982
  if (context.screenshot && modelInfo2?.vision) {
980
983
  apiMessages.push({
@@ -1088,24 +1091,7 @@ async function chatAnthropic(model, apiKey, messages, context, onChunk, onDone,
1088
1091
  const msg = messages[i];
1089
1092
  if (msg.role === "system") continue;
1090
1093
  if (msg.role === "user" && typeof msg.content === "string" && i === lastUserIdx) {
1091
- const contextParts = {};
1092
- if (context.selectedElement) {
1093
- contextParts.selectedElement = context.selectedElement.outerHTML;
1094
- }
1095
- if (context.files && context.files.length > 0) {
1096
- contextParts.filePath = context.files[0].path;
1097
- contextParts.fileContent = context.files[0].content;
1098
- }
1099
- if (context.projectTree) {
1100
- contextParts.projectTree = context.projectTree;
1101
- }
1102
- if (context.networkLogs) {
1103
- contextParts.networkLogs = context.networkLogs.map((l) => `${l.method} ${l.url} \u2192 ${l.status || "pending"}`).join("\n");
1104
- }
1105
- if (context.consoleLogs) {
1106
- contextParts.consoleLogs = context.consoleLogs.map((l) => `[${l.level}] ${l.args.join(" ")}`).join("\n");
1107
- }
1108
- const enrichedContent = buildUserMessage(msg.content, contextParts);
1094
+ const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));
1109
1095
  if (context.screenshot) {
1110
1096
  const base64Data = context.screenshot.replace(
1111
1097
  /^data:image\/\w+;base64,/,
@@ -1218,18 +1204,7 @@ async function chatGoogle(model, apiKey, messages, context, onChunk, onDone, onE
1218
1204
  if (msg.role === "system") continue;
1219
1205
  const role = msg.role === "assistant" ? "model" : "user";
1220
1206
  if (msg.role === "user" && typeof msg.content === "string" && i === lastUserIdx) {
1221
- const contextParts = {};
1222
- if (context.selectedElement) {
1223
- contextParts.selectedElement = context.selectedElement.outerHTML;
1224
- }
1225
- if (context.files && context.files.length > 0) {
1226
- contextParts.filePath = context.files[0].path;
1227
- contextParts.fileContent = context.files[0].content;
1228
- }
1229
- if (context.projectTree) {
1230
- contextParts.projectTree = context.projectTree;
1231
- }
1232
- const enrichedContent = buildUserMessage(msg.content, contextParts);
1207
+ const enrichedContent = buildUserMessage(msg.content, buildContextParts(context));
1233
1208
  const parts = [
1234
1209
  { text: enrichedContent }
1235
1210
  ];
@@ -1916,7 +1891,7 @@ process.on("uncaughtException", (err) => {
1916
1891
  process.exit(1);
1917
1892
  });
1918
1893
  var childProcesses = [];
1919
- var VERSION2 = "0.11.0";
1894
+ var VERSION2 = "0.12.0";
1920
1895
  function ask(question) {
1921
1896
  const rl = createInterface({ input: process.stdin, output: process.stdout });
1922
1897
  return new Promise((resolve3) => {