@cniot/mdd-editor 0.3.1 → 0.3.4

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/build/index.es.js CHANGED
@@ -30058,9 +30058,18 @@ function FtpBuild({ schema, moduleMap }) {
30058
30058
  }))));
30059
30059
  }
30060
30060
  const DEFAULT_BRIDGE_URL = "http://127.0.0.1:17678";
30061
- const trimEndSlash = (value = "") => value.replace(/\/+$/, "");
30061
+ const trimEndSlash$1 = (value = "") => value.replace(/\/+$/, "");
30062
30062
  const RELAY_CHANNEL = "mdd-ai-bridge";
30063
+ const relayCacheMap = /* @__PURE__ */ new Map();
30063
30064
  const isLoopbackURL = (value = "") => /^http:\/\/(127(?:\.\d{1,3}){3}|localhost)(?::\d+)?/i.test(value);
30065
+ class BridgeRequestError extends Error {
30066
+ constructor(message, options = {}) {
30067
+ super(message);
30068
+ this.name = "BridgeRequestError";
30069
+ this.status = options.status || 0;
30070
+ this.data = options.data || null;
30071
+ }
30072
+ }
30064
30073
  function shouldUseBridgeRelay(baseURL) {
30065
30074
  return typeof window !== "undefined" && !window.isSecureContext && isLoopbackURL(baseURL);
30066
30075
  }
@@ -30071,7 +30080,7 @@ async function request(baseURL, path, options = {}) {
30071
30080
  if (shouldUseBridgeRelay(baseURL)) {
30072
30081
  return requestViaRelay(baseURL, path, options);
30073
30082
  }
30074
- const res = await fetch(`${trimEndSlash(baseURL)}${path}`, {
30083
+ const res = await fetch(`${trimEndSlash$1(baseURL)}${path}`, {
30075
30084
  ...options,
30076
30085
  headers: {
30077
30086
  "Content-Type": "application/json",
@@ -30086,13 +30095,20 @@ async function request(baseURL, path, options = {}) {
30086
30095
  data = { message: text };
30087
30096
  }
30088
30097
  if (!res.ok) {
30089
- throw new Error((data == null ? void 0 : data.message) || `\u8BF7\u6C42\u672C\u5730 AI Bridge \u5931\u8D25: ${res.status}`);
30098
+ throw new BridgeRequestError((data == null ? void 0 : data.message) || `\u8BF7\u6C42\u672C\u5730 AI Bridge \u5931\u8D25: ${res.status}`, {
30099
+ status: res.status,
30100
+ data
30101
+ });
30090
30102
  }
30091
30103
  return data;
30092
30104
  }
30093
- function requestViaRelay(baseURL, path, options = {}) {
30094
- const relayURL = `${trimEndSlash(baseURL)}/relay`;
30095
- const requestId = createRequestId();
30105
+ function getRelayCache(baseURL) {
30106
+ const relayOrigin = trimEndSlash$1(baseURL);
30107
+ const relayURL = `${relayOrigin}/relay`;
30108
+ const cached = relayCacheMap.get(relayOrigin);
30109
+ if ((cached == null ? void 0 : cached.window) && !cached.window.closed) {
30110
+ return cached;
30111
+ }
30096
30112
  const relayWindow = window.open(
30097
30113
  relayURL,
30098
30114
  "mdd-ai-bridge-relay",
@@ -30101,16 +30117,41 @@ function requestViaRelay(baseURL, path, options = {}) {
30101
30117
  if (!relayWindow) {
30102
30118
  throw new Error("\u6D4F\u89C8\u5668\u62E6\u622A\u4E86\u672C\u5730 Bridge \u7A97\u53E3\uFF0C\u8BF7\u5141\u8BB8\u5F39\u7A97\u540E\u91CD\u8BD5");
30103
30119
  }
30120
+ const next = {
30121
+ origin: relayOrigin,
30122
+ window: relayWindow,
30123
+ ready: false
30124
+ };
30125
+ relayCacheMap.set(relayOrigin, next);
30126
+ return next;
30127
+ }
30128
+ function requestViaRelay(baseURL, path, options = {}) {
30129
+ const relayCache = getRelayCache(baseURL);
30130
+ const requestId = createRequestId();
30104
30131
  return new Promise((resolve, reject) => {
30105
30132
  let settled = false;
30106
- let ready = false;
30133
+ let fallbackPosted = false;
30134
+ let readyPosted = false;
30107
30135
  const cleanup = () => {
30108
30136
  window.removeEventListener("message", handleMessage);
30109
30137
  clearTimeout(timeoutTimer);
30110
30138
  clearTimeout(fallbackTimer);
30111
30139
  };
30112
- const postRequest = () => {
30113
- relayWindow.postMessage(
30140
+ const postRequest = (source = "ready") => {
30141
+ if (source === "ready") {
30142
+ if (readyPosted)
30143
+ return;
30144
+ readyPosted = true;
30145
+ } else {
30146
+ if (fallbackPosted)
30147
+ return;
30148
+ fallbackPosted = true;
30149
+ }
30150
+ if (!relayCache.window || relayCache.window.closed) {
30151
+ finish(reject, new Error("\u672C\u5730 Bridge relay \u7A97\u53E3\u5DF2\u5173\u95ED\uFF0C\u8BF7\u91CD\u8BD5"));
30152
+ return;
30153
+ }
30154
+ relayCache.window.postMessage(
30114
30155
  {
30115
30156
  channel: RELAY_CHANNEL,
30116
30157
  type: "request",
@@ -30118,7 +30159,7 @@ function requestViaRelay(baseURL, path, options = {}) {
30118
30159
  path,
30119
30160
  options
30120
30161
  },
30121
- trimEndSlash(baseURL)
30162
+ relayCache.origin
30122
30163
  );
30123
30164
  };
30124
30165
  const finish = (callback, value) => {
@@ -30130,16 +30171,16 @@ function requestViaRelay(baseURL, path, options = {}) {
30130
30171
  };
30131
30172
  const handleMessage = (event) => {
30132
30173
  var _a2;
30133
- if (event.origin !== trimEndSlash(baseURL))
30174
+ if (event.origin !== relayCache.origin)
30134
30175
  return;
30135
- if (event.source !== relayWindow)
30176
+ if (event.source !== relayCache.window)
30136
30177
  return;
30137
30178
  const message = event.data || {};
30138
30179
  if (message.channel !== RELAY_CHANNEL)
30139
30180
  return;
30140
- if (message.type === "ready" && !ready) {
30141
- ready = true;
30142
- postRequest();
30181
+ if (message.type === "ready") {
30182
+ relayCache.ready = true;
30183
+ postRequest("ready");
30143
30184
  return;
30144
30185
  }
30145
30186
  if (message.type !== "response" || message.id !== requestId)
@@ -30147,7 +30188,13 @@ function requestViaRelay(baseURL, path, options = {}) {
30147
30188
  if (!message.ok) {
30148
30189
  finish(
30149
30190
  reject,
30150
- new Error(((_a2 = message.data) == null ? void 0 : _a2.message) || `\u8BF7\u6C42\u672C\u5730 AI Bridge \u5931\u8D25: ${message.status || 0}`)
30191
+ new BridgeRequestError(
30192
+ ((_a2 = message.data) == null ? void 0 : _a2.message) || `\u8BF7\u6C42\u672C\u5730 AI Bridge \u5931\u8D25: ${message.status || 0}`,
30193
+ {
30194
+ status: message.status || 0,
30195
+ data: message.data
30196
+ }
30197
+ )
30151
30198
  );
30152
30199
  return;
30153
30200
  }
@@ -30157,10 +30204,13 @@ function requestViaRelay(baseURL, path, options = {}) {
30157
30204
  finish(reject, new Error("\u672C\u5730 AI Bridge relay \u54CD\u5E94\u8D85\u65F6\uFF0C\u8BF7\u786E\u8BA4\u670D\u52A1\u5DF2\u542F\u52A8"));
30158
30205
  }, 3e4);
30159
30206
  const fallbackTimer = setTimeout(() => {
30160
- if (!ready)
30161
- postRequest();
30207
+ if (!relayCache.ready)
30208
+ postRequest("fallback");
30162
30209
  }, 500);
30163
30210
  window.addEventListener("message", handleMessage);
30211
+ if (relayCache.ready) {
30212
+ setTimeout(() => postRequest("ready"), 0);
30213
+ }
30164
30214
  });
30165
30215
  }
30166
30216
  function normalizeBridgeConfig(config2) {
@@ -30352,6 +30402,10 @@ function getPageCode(schemaJson = {}, pageMeta = {}) {
30352
30402
  const searchParams = new URLSearchParams(window.location.search || "");
30353
30403
  return pageMeta.code || searchParams.get("code") || (schemaJson == null ? void 0 : schemaJson.code) || ((_a2 = schemaJson == null ? void 0 : schemaJson.body) == null ? void 0 : _a2.code) || `local-${((_b2 = schemaJson == null ? void 0 : schemaJson.body) == null ? void 0 : _b2.type) || "mdd"}`;
30354
30404
  }
30405
+ const MIN_BRIDGE_VERSION = "0.1.4";
30406
+ const START_COMMAND = `npm i -g @cniot/mdd-ai-bridge
30407
+ mdd-ai-bridge`;
30408
+ const trimEndSlash = (value = "") => value.replace(/\/+$/, "");
30355
30409
  const parseSchema = (value) => {
30356
30410
  if (!value)
30357
30411
  return null;
@@ -30373,6 +30427,102 @@ const applySchemaToEditor = (schema, schemaJson) => {
30373
30427
  }
30374
30428
  schema.emit(EVENT_KEY.SCHEMA_UPDATE_FORCE, schemaJson);
30375
30429
  };
30430
+ const compareVersion = (a = "", b = "") => {
30431
+ const left = String(a).split(".").map((item) => Number(item) || 0);
30432
+ const right = String(b).split(".").map((item) => Number(item) || 0);
30433
+ const max = Math.max(left.length, right.length);
30434
+ for (let i = 0; i < max; i += 1) {
30435
+ if ((left[i] || 0) > (right[i] || 0))
30436
+ return 1;
30437
+ if ((left[i] || 0) < (right[i] || 0))
30438
+ return -1;
30439
+ }
30440
+ return 0;
30441
+ };
30442
+ const isBridgeVersionReady = (version2) => Boolean(version2) && compareVersion(version2, MIN_BRIDGE_VERSION) >= 0;
30443
+ const copyText = async (text) => {
30444
+ var _a2;
30445
+ if (typeof navigator !== "undefined" && ((_a2 = navigator == null ? void 0 : navigator.clipboard) == null ? void 0 : _a2.writeText)) {
30446
+ await navigator.clipboard.writeText(text);
30447
+ return;
30448
+ }
30449
+ const textarea = document.createElement("textarea");
30450
+ textarea.value = text;
30451
+ textarea.setAttribute("readonly", "readonly");
30452
+ textarea.style.position = "fixed";
30453
+ textarea.style.left = "-9999px";
30454
+ document.body.appendChild(textarea);
30455
+ textarea.select();
30456
+ document.execCommand("copy");
30457
+ document.body.removeChild(textarea);
30458
+ };
30459
+ const getJsonErrorDetail = (error) => {
30460
+ var _a2;
30461
+ const jsonError = (_a2 = error == null ? void 0 : error.data) == null ? void 0 : _a2.jsonError;
30462
+ if (jsonError) {
30463
+ return {
30464
+ title: `${jsonError.file || "JSON"} \u89E3\u6790\u5931\u8D25${jsonError.line ? `\uFF1A\u7B2C ${jsonError.line} \u884C${jsonError.column ? `\uFF0C\u7B2C ${jsonError.column} \u5217` : ""}` : ""}`,
30465
+ message: jsonError.message || error.message || "",
30466
+ snippet: jsonError.snippet || ""
30467
+ };
30468
+ }
30469
+ return {
30470
+ title: "\u540C\u6B65\u5931\u8D25",
30471
+ message: (error == null ? void 0 : error.message) || "\u540C\u6B65\u672C\u5730 AI \u4FEE\u6539\u5931\u8D25",
30472
+ snippet: ""
30473
+ };
30474
+ };
30475
+ const getChangeTypeText = (type) => {
30476
+ switch (type) {
30477
+ case "added":
30478
+ return "\u65B0\u589E";
30479
+ case "removed":
30480
+ return "\u5220\u9664";
30481
+ case "type":
30482
+ return "\u7C7B\u578B\u53D8\u5316";
30483
+ case "changed":
30484
+ return "\u4FEE\u6539";
30485
+ default:
30486
+ return type || "\u4FEE\u6539";
30487
+ }
30488
+ };
30489
+ function PullDiffDetail({ diffSummary }) {
30490
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h;
30491
+ if (!(diffSummary == null ? void 0 : diffSummary.hasBaseline))
30492
+ return null;
30493
+ const schemaChanges = ((_a2 = diffSummary.schema) == null ? void 0 : _a2.changes) || ((_b2 = diffSummary.schema) == null ? void 0 : _b2.paths) || [];
30494
+ const diffText = diffSummary.diffText || "";
30495
+ const hasDetail = schemaChanges.length > 0 || ((_c2 = diffSummary.script) == null ? void 0 : _c2.changed) || ((_d = diffSummary.style) == null ? void 0 : _d.changed) || diffText;
30496
+ if (!hasDetail)
30497
+ return null;
30498
+ return /* @__PURE__ */ React$1.createElement("details", {
30499
+ className: "mdd-local-ai-diff"
30500
+ }, /* @__PURE__ */ React$1.createElement("summary", null, "\u67E5\u770B\u5177\u4F53\u6539\u52A8\u4E0E diff"), /* @__PURE__ */ React$1.createElement("div", {
30501
+ className: "mdd-local-ai-diff-content"
30502
+ }, schemaChanges.length > 0 ? /* @__PURE__ */ React$1.createElement("div", {
30503
+ className: "mdd-local-ai-diff-section"
30504
+ }, /* @__PURE__ */ React$1.createElement("div", {
30505
+ className: "mdd-local-ai-diff-title"
30506
+ }, "Schema \u6539\u52A8\u4F4D\u7F6E"), /* @__PURE__ */ React$1.createElement("ul", {
30507
+ className: "mdd-local-ai-diff-list"
30508
+ }, schemaChanges.map((item, index2) => {
30509
+ const path = typeof item === "string" ? item : item.path;
30510
+ const type = typeof item === "string" ? "changed" : item.type;
30511
+ return /* @__PURE__ */ React$1.createElement("li", {
30512
+ key: `${path}-${index2}`
30513
+ }, /* @__PURE__ */ React$1.createElement("code", null, path), /* @__PURE__ */ React$1.createElement("span", null, getChangeTypeText(type)));
30514
+ }))) : null, ((_e = diffSummary.script) == null ? void 0 : _e.changed) ? /* @__PURE__ */ React$1.createElement("div", {
30515
+ className: "mdd-local-ai-diff-section"
30516
+ }, /* @__PURE__ */ React$1.createElement("div", {
30517
+ className: "mdd-local-ai-diff-title"
30518
+ }, "Script \u6539\u52A8"), /* @__PURE__ */ React$1.createElement("div", null, diffSummary.script.message), ((_f = diffSummary.script.addedFunctions) == null ? void 0 : _f.length) ? /* @__PURE__ */ React$1.createElement("div", null, "\u65B0\u589E\uFF1A", diffSummary.script.addedFunctions.join("\u3001")) : null, ((_g = diffSummary.script.removedFunctions) == null ? void 0 : _g.length) ? /* @__PURE__ */ React$1.createElement("div", null, "\u79FB\u9664\uFF1A", diffSummary.script.removedFunctions.join("\u3001")) : null) : null, ((_h = diffSummary.style) == null ? void 0 : _h.changed) ? /* @__PURE__ */ React$1.createElement("div", {
30519
+ className: "mdd-local-ai-diff-section"
30520
+ }, /* @__PURE__ */ React$1.createElement("div", {
30521
+ className: "mdd-local-ai-diff-title"
30522
+ }, "Style \u6539\u52A8"), /* @__PURE__ */ React$1.createElement("div", null, diffSummary.style.message)) : null, diffText ? /* @__PURE__ */ React$1.createElement("pre", {
30523
+ className: "mdd-local-ai-diff-pre"
30524
+ }, diffText) : null));
30525
+ }
30376
30526
  function LocalAIDrawer(props) {
30377
30527
  var _a2;
30378
30528
  const { schema, scriptInfo, pageMeta = {}, bridgeConfig, onApply } = props;
@@ -30380,8 +30530,11 @@ function LocalAIDrawer(props) {
30380
30530
  const [baseURL, setBaseURL] = React$1.useState(config2.baseURL || DEFAULT_BRIDGE_URL);
30381
30531
  const [status, setStatus] = React$1.useState("\u672A\u8FDE\u63A5");
30382
30532
  const [workspacePath, setWorkspacePath] = React$1.useState("");
30533
+ const [bridgeInfo, setBridgeInfo] = React$1.useState(null);
30383
30534
  const [loadingAction, setLoadingAction] = React$1.useState("");
30384
30535
  const [lastSummary, setLastSummary] = React$1.useState("");
30536
+ const [pullError, setPullError] = React$1.useState(null);
30537
+ const [lastDiffSummary, setLastDiffSummary] = React$1.useState(null);
30385
30538
  const schemaJson = ((_a2 = schema == null ? void 0 : schema.getAllJSON) == null ? void 0 : _a2.call(schema)) || {};
30386
30539
  const pageCode = getPageCode(schemaJson, pageMeta);
30387
30540
  const getPayload = React$1.useCallback(() => {
@@ -30407,13 +30560,51 @@ function LocalAIDrawer(props) {
30407
30560
  })
30408
30561
  };
30409
30562
  }, [pageCode, pageMeta, schema, scriptInfo]);
30563
+ const expectedWorkspacePath = React$1.useMemo(() => {
30564
+ if (workspacePath)
30565
+ return workspacePath;
30566
+ const root2 = (bridgeInfo == null ? void 0 : bridgeInfo.workspaceRoot) || "~/.mdd-ai-workspace";
30567
+ return `${root2.replace(/\/$/, "")}/pages/${pageCode}`;
30568
+ }, [bridgeInfo, pageCode, workspacePath]);
30569
+ const aiPrompt = React$1.useMemo(
30570
+ () => `\u8BF7\u5E2E\u6211\u4FEE\u6539\u8FD9\u4E2A MDD \u9875\u9762\uFF1A
30571
+
30572
+ \u5DE5\u4F5C\u533A\uFF1A${expectedWorkspacePath}
30573
+ \u9875\u9762 Code\uFF1A${pageCode}
30574
+
30575
+ \u8BF7\u5148\u9605\u8BFB\u540C\u76EE\u5F55\u4E0B\u7684 AGENTS.md \u548C PROMPT.md\uFF0C\u518D\u6309\u9700\u6C42\u4FEE\u6539\uFF1A
30576
+ - mdd.schema.json\uFF1A\u9875\u9762 schema
30577
+ - mdd.script.jsx\uFF1A\u9875\u9762\u811A\u672C
30578
+ - mdd.style.less\uFF1A\u9875\u9762\u6837\u5F0F
30579
+
30580
+ \u6CE8\u610F\uFF1A
30581
+ 1. \u4E0D\u8981\u4FEE\u6539 page.ir.json / page.meta.json \u4F5C\u4E3A\u6700\u7EC8\u7ED3\u679C\u3002
30582
+ 2. JSON \u5FC5\u987B\u4FDD\u6301\u5408\u6CD5\uFF0C\u5C3D\u91CF\u53EA\u6539\u548C\u9700\u6C42\u76F8\u5173\u7684\u4F4D\u7F6E\u3002
30583
+ 3. MDD hook / engine API \u4E0D\u786E\u5B9A\u65F6\uFF0C\u5148\u8BFB context \u76EE\u5F55\u91CC\u7684 api-cheatsheet.md\u3001engine-runtime.md\u3001hooks-cookbook.md\u3002
30584
+
30585
+ \u6211\u7684\u9700\u6C42\u662F\uFF1A`,
30586
+ [expectedWorkspacePath, pageCode]
30587
+ );
30588
+ const handleCopy = React$1.useCallback(async (text, successText) => {
30589
+ try {
30590
+ await copyText(text);
30591
+ CnMessage.success(successText);
30592
+ } catch (e) {
30593
+ CnMessage.error("\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u590D\u5236");
30594
+ }
30595
+ }, []);
30410
30596
  const checkHealth = React$1.useCallback(async () => {
30411
30597
  setLoadingAction("health");
30412
30598
  try {
30413
30599
  const res = await health(baseURL);
30414
- setStatus((res == null ? void 0 : res.ok) ? "\u5DF2\u8FDE\u63A5" : "\u8FDE\u63A5\u5F02\u5E38");
30415
- if (res == null ? void 0 : res.workspaceRoot) {
30416
- setWorkspacePath(res.workspaceRoot);
30600
+ setBridgeInfo(res || null);
30601
+ if ((res == null ? void 0 : res.ok) && isBridgeVersionReady(res.version)) {
30602
+ setStatus(`\u5DF2\u8FDE\u63A5\uFF08Bridge v${res.version}\uFF09`);
30603
+ } else if (res == null ? void 0 : res.ok) {
30604
+ setStatus(`Bridge \u7248\u672C\u504F\u65E7${(res == null ? void 0 : res.version) ? `\uFF08v${res.version}\uFF09` : ""}`);
30605
+ setLastSummary(`\u5EFA\u8BAE\u5347\u7EA7\u672C\u5730 bridge \u5230 ${MIN_BRIDGE_VERSION} \u6216\u66F4\u9AD8\u7248\u672C\uFF1Anpm i -g @cniot/mdd-ai-bridge@latest`);
30606
+ } else {
30607
+ setStatus("\u8FDE\u63A5\u5F02\u5E38");
30417
30608
  }
30418
30609
  } catch (e) {
30419
30610
  setStatus("\u672A\u8FDE\u63A5");
@@ -30424,9 +30615,18 @@ function LocalAIDrawer(props) {
30424
30615
  }, [baseURL]);
30425
30616
  const handlePush = async () => {
30426
30617
  setLoadingAction("push");
30618
+ setPullError(null);
30619
+ setLastDiffSummary(null);
30427
30620
  try {
30428
30621
  const res = await pushPage(baseURL, pageCode, getPayload());
30429
30622
  setWorkspacePath((res == null ? void 0 : res.dir) || "");
30623
+ setBridgeInfo((prev) => {
30624
+ var _a3;
30625
+ return {
30626
+ ...prev || {},
30627
+ workspaceRoot: ((_a3 = res == null ? void 0 : res.context) == null ? void 0 : _a3.workspaceRoot) || (prev == null ? void 0 : prev.workspaceRoot)
30628
+ };
30629
+ });
30430
30630
  setStatus("\u5DF2\u540C\u6B65\u5230\u672C\u5730");
30431
30631
  setLastSummary(`\u5DF2\u5199\u5165\u672C\u5730\u5DE5\u4F5C\u533A: ${(res == null ? void 0 : res.dir) || pageCode}`);
30432
30632
  CnMessage.success("\u5DF2\u53D1\u9001\u5230\u672C\u5730 AI \u5DE5\u4F5C\u533A");
@@ -30438,6 +30638,7 @@ function LocalAIDrawer(props) {
30438
30638
  };
30439
30639
  const handlePull = async () => {
30440
30640
  setLoadingAction("pull");
30641
+ setPullError(null);
30441
30642
  try {
30442
30643
  const res = await pullPage(baseURL, pageCode);
30443
30644
  const nextSchema = parseSchema(res == null ? void 0 : res.schemaInfo);
@@ -30453,9 +30654,13 @@ function LocalAIDrawer(props) {
30453
30654
  raw: res
30454
30655
  });
30455
30656
  setLastSummary((res == null ? void 0 : res.summary) || "\u5DF2\u4ECE\u672C\u5730\u5DE5\u4F5C\u533A\u540C\u6B65\u4FEE\u6539");
30657
+ setLastDiffSummary((res == null ? void 0 : res.diffSummary) || null);
30456
30658
  CnMessage.success("\u5DF2\u540C\u6B65\u672C\u5730 AI \u4FEE\u6539");
30457
30659
  } catch (e) {
30458
- CnMessage.error(e.message || "\u540C\u6B65\u672C\u5730 AI \u4FEE\u6539\u5931\u8D25");
30660
+ const detail = getJsonErrorDetail(e);
30661
+ setPullError(detail);
30662
+ setLastDiffSummary(null);
30663
+ CnMessage.error(detail.title || "\u540C\u6B65\u672C\u5730 AI \u4FEE\u6539\u5931\u8D25");
30459
30664
  } finally {
30460
30665
  setLoadingAction("");
30461
30666
  }
@@ -30465,6 +30670,7 @@ function LocalAIDrawer(props) {
30465
30670
  try {
30466
30671
  const res = await getPageStatus(baseURL, pageCode);
30467
30672
  setWorkspacePath((res == null ? void 0 : res.dir) || "");
30673
+ setLastDiffSummary(null);
30468
30674
  setLastSummary((res == null ? void 0 : res.exists) ? `\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u5B58\u5728: ${res.dir}` : "\u672C\u5730\u8FD8\u6CA1\u6709\u8FD9\u4E2A\u9875\u9762\u7684\u5DE5\u4F5C\u533A");
30469
30675
  CnMessage.success((res == null ? void 0 : res.exists) ? "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u5B58\u5728" : "\u672C\u5730\u5DE5\u4F5C\u533A\u4E0D\u5B58\u5728");
30470
30676
  } catch (e) {
@@ -30485,6 +30691,9 @@ function LocalAIDrawer(props) {
30485
30691
  setLoadingAction("");
30486
30692
  }
30487
30693
  };
30694
+ const handleOpenBridgeHome = React$1.useCallback(() => {
30695
+ window.open(`${trimEndSlash(baseURL)}/`, "_blank", "noopener,noreferrer");
30696
+ }, [baseURL]);
30488
30697
  React$1.useEffect(() => {
30489
30698
  if (shouldUseBridgeRelay(baseURL)) {
30490
30699
  setStatus("\u70B9\u51FB\u6309\u94AE\u540E\u901A\u8FC7\u672C\u5730 relay \u8FDE\u63A5");
@@ -30495,24 +30704,47 @@ function LocalAIDrawer(props) {
30495
30704
  return /* @__PURE__ */ React$1.createElement("div", {
30496
30705
  className: "mdd-local-ai"
30497
30706
  }, /* @__PURE__ */ React$1.createElement(CnCard, {
30498
- className: "mdd-local-ai-card"
30707
+ className: "mdd-local-ai-card mdd-local-ai-hero"
30708
+ }, /* @__PURE__ */ React$1.createElement("div", {
30709
+ className: "mdd-local-ai-hero-head"
30710
+ }, /* @__PURE__ */ React$1.createElement("div", null, /* @__PURE__ */ React$1.createElement("div", {
30711
+ className: "mdd-local-ai-heading"
30712
+ }, "\u672C\u5730 AI \u5DE5\u4F5C\u533A"), /* @__PURE__ */ React$1.createElement("div", {
30713
+ className: "mdd-local-ai-subtitle"
30714
+ }, "\u628A\u5F53\u524D\u9875\u9762\u540C\u6B65\u6210\u672C\u5730\u6587\u4EF6\uFF0C\u518D\u4EA4\u7ED9 Cursor\u3001Qoder\u3001Codex CLI \u4FEE\u6539\u3002")), /* @__PURE__ */ React$1.createElement("span", {
30715
+ className: (bridgeInfo == null ? void 0 : bridgeInfo.version) ? "mdd-local-ai-status is-ready" : "mdd-local-ai-status"
30716
+ }, (bridgeInfo == null ? void 0 : bridgeInfo.version) ? `Bridge v${bridgeInfo.version}` : status)), /* @__PURE__ */ React$1.createElement("div", {
30717
+ className: "mdd-local-ai-bridge-row"
30499
30718
  }, /* @__PURE__ */ React$1.createElement("div", {
30500
- className: "mdd-local-ai-row"
30719
+ className: "mdd-local-ai-field"
30501
30720
  }, /* @__PURE__ */ React$1.createElement("span", {
30502
30721
  className: "mdd-local-ai-label"
30503
- }, "Bridge"), /* @__PURE__ */ React$1.createElement(Input$1, {
30722
+ }, "Bridge \u5730\u5740"), /* @__PURE__ */ React$1.createElement(Input$1, {
30504
30723
  size: "small",
30505
30724
  value: baseURL,
30506
30725
  onChange: setBaseURL,
30507
30726
  placeholder: DEFAULT_BRIDGE_URL,
30508
- style: { width: 320 }
30509
- }), /* @__PURE__ */ React$1.createElement(CnButton, {
30727
+ className: "mdd-local-ai-input"
30728
+ })), /* @__PURE__ */ React$1.createElement(CnButton, {
30510
30729
  size: "small",
30511
30730
  loading: loadingAction === "health",
30512
30731
  onClick: checkHealth
30513
- }, "\u68C0\u6D4B\u8FDE\u63A5")), /* @__PURE__ */ React$1.createElement("div", {
30732
+ }, "\u68C0\u6D4B\u8FDE\u63A5"), /* @__PURE__ */ React$1.createElement(CnButton, {
30733
+ size: "small",
30734
+ onClick: handleOpenBridgeHome
30735
+ }, "\u8BBF\u95EE\u672C\u5730 AI \u4E3B\u9875")), /* @__PURE__ */ React$1.createElement("div", {
30514
30736
  className: "mdd-local-ai-meta"
30515
- }, /* @__PURE__ */ React$1.createElement("div", null, "\u72B6\u6001\uFF1A", status), /* @__PURE__ */ React$1.createElement("div", null, "\u9875\u9762\uFF1A", pageCode), workspacePath ? /* @__PURE__ */ React$1.createElement("div", null, "\u76EE\u5F55\uFF1A", workspacePath) : null)), /* @__PURE__ */ React$1.createElement("div", {
30737
+ }, /* @__PURE__ */ React$1.createElement("div", {
30738
+ className: "mdd-local-ai-meta-item"
30739
+ }, /* @__PURE__ */ React$1.createElement("span", null, "\u72B6\u6001"), /* @__PURE__ */ React$1.createElement("strong", null, status)), /* @__PURE__ */ React$1.createElement("div", {
30740
+ className: "mdd-local-ai-meta-item"
30741
+ }, /* @__PURE__ */ React$1.createElement("span", null, "\u9875\u9762"), /* @__PURE__ */ React$1.createElement("strong", null, pageCode)), /* @__PURE__ */ React$1.createElement("div", {
30742
+ className: "mdd-local-ai-meta-item mdd-local-ai-meta-path"
30743
+ }, /* @__PURE__ */ React$1.createElement("span", null, "\u76EE\u5F55"), /* @__PURE__ */ React$1.createElement("strong", null, workspacePath || expectedWorkspacePath)))), /* @__PURE__ */ React$1.createElement("div", {
30744
+ className: "mdd-local-ai-section"
30745
+ }, /* @__PURE__ */ React$1.createElement("div", {
30746
+ className: "mdd-local-ai-section-title"
30747
+ }, "\u5DE5\u4F5C\u533A\u64CD\u4F5C"), /* @__PURE__ */ React$1.createElement("div", {
30516
30748
  className: "mdd-local-ai-actions"
30517
30749
  }, /* @__PURE__ */ React$1.createElement(CnButton, {
30518
30750
  type: "primary",
@@ -30527,9 +30759,34 @@ function LocalAIDrawer(props) {
30527
30759
  }, "\u67E5\u770B\u72B6\u6001"), /* @__PURE__ */ React$1.createElement(CnButton, {
30528
30760
  loading: loadingAction === "open",
30529
30761
  onClick: handleOpen
30530
- }, "\u6253\u5F00\u76EE\u5F55")), lastSummary ? /* @__PURE__ */ React$1.createElement("div", {
30762
+ }, "\u6253\u5F00\u76EE\u5F55"))), /* @__PURE__ */ React$1.createElement("div", {
30763
+ className: "mdd-local-ai-section"
30764
+ }, /* @__PURE__ */ React$1.createElement("div", {
30765
+ className: "mdd-local-ai-section-title"
30766
+ }, "\u8F85\u52A9\u64CD\u4F5C"), /* @__PURE__ */ React$1.createElement("div", {
30767
+ className: "mdd-local-ai-copy-actions"
30768
+ }, /* @__PURE__ */ React$1.createElement(CnButton, {
30769
+ size: "small",
30770
+ onClick: () => handleCopy(START_COMMAND, "\u5DF2\u590D\u5236\u542F\u52A8\u547D\u4EE4")
30771
+ }, "\u590D\u5236\u542F\u52A8\u547D\u4EE4"), /* @__PURE__ */ React$1.createElement(CnButton, {
30772
+ size: "small",
30773
+ onClick: () => handleCopy(expectedWorkspacePath, "\u5DF2\u590D\u5236\u5DE5\u4F5C\u533A\u8DEF\u5F84")
30774
+ }, "\u590D\u5236\u5DE5\u4F5C\u533A\u8DEF\u5F84"), /* @__PURE__ */ React$1.createElement(CnButton, {
30775
+ size: "small",
30776
+ onClick: () => handleCopy(aiPrompt, "\u5DF2\u590D\u5236 AI \u63D0\u793A\u8BCD")
30777
+ }, "\u590D\u5236 AI \u63D0\u793A\u8BCD"))), lastSummary ? /* @__PURE__ */ React$1.createElement("div", {
30531
30778
  className: "mdd-local-ai-summary"
30532
- }, lastSummary) : null, /* @__PURE__ */ React$1.createElement(CnCard, {
30779
+ }, lastSummary) : null, /* @__PURE__ */ React$1.createElement(PullDiffDetail, {
30780
+ diffSummary: lastDiffSummary
30781
+ }), pullError ? /* @__PURE__ */ React$1.createElement("div", {
30782
+ className: "mdd-local-ai-error"
30783
+ }, /* @__PURE__ */ React$1.createElement("div", {
30784
+ className: "mdd-local-ai-error-title"
30785
+ }, pullError.title), /* @__PURE__ */ React$1.createElement("div", {
30786
+ className: "mdd-local-ai-error-message"
30787
+ }, pullError.message), pullError.snippet ? /* @__PURE__ */ React$1.createElement("pre", {
30788
+ className: "mdd-local-ai-error-snippet"
30789
+ }, pullError.snippet) : null) : null, /* @__PURE__ */ React$1.createElement(CnCard, {
30533
30790
  className: "mdd-local-ai-card"
30534
30791
  }, /* @__PURE__ */ React$1.createElement("div", {
30535
30792
  className: "mdd-local-ai-title"
@@ -31074,7 +31331,7 @@ function getDefaultIndexStyle() {
31074
31331
  `;
31075
31332
  }
31076
31333
  const name = "@cniot/mdd-editor";
31077
- const version = "0.3.1";
31334
+ const version = "0.3.3";
31078
31335
  const description = "\u6A21\u578B\u9A71\u52A8\u7F16\u8F91\u5668";
31079
31336
  const scripts = {
31080
31337
  build: "vite build"