@spotpatch/runtime 1.15.2 → 1.15.3

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/index.cjs CHANGED
@@ -632,7 +632,7 @@ var import_shared4 = require("@spotpatch/shared");
632
632
  var MAX_ATTRIBUTE_CHARACTERS = 500;
633
633
  var MAX_SVG_PATH_CHARACTERS = 256;
634
634
  function truncate(value, maxCharacters) {
635
- return value.length <= maxCharacters ? value : `${value.slice(0, Math.max(0, maxCharacters - 1))}\u2026`;
635
+ return value.length <= maxCharacters ? value : `${value.slice(0, Math.max(0, maxCharacters - 1))}…`;
636
636
  }
637
637
  function isSensitiveAttributeName(name) {
638
638
  return (0, import_shared4.isSensitiveName)(name);
@@ -645,7 +645,7 @@ function sanitizeAttributeValue(name, value, baseUrl) {
645
645
  return (0, import_shared4.sanitizeUrl)(value, baseUrl);
646
646
  }
647
647
  if (name === "d" && value.length > MAX_SVG_PATH_CHARACTERS) {
648
- return `${value.slice(0, MAX_SVG_PATH_CHARACTERS)}\u2026`;
648
+ return `${value.slice(0, MAX_SVG_PATH_CHARACTERS)}…`;
649
649
  }
650
650
  return truncate((0, import_shared4.redactSensitiveText)(value), MAX_ATTRIBUTE_CHARACTERS);
651
651
  }
@@ -950,7 +950,7 @@ function serializeElement(element2, depth, state, lines) {
950
950
  const text2 = normalizedText(child.textContent ?? "");
951
951
  if (text2.length > 0) {
952
952
  state.nodeCount += 1;
953
- const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`;
953
+ const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}…`;
954
954
  lines.push(`${" ".repeat(depth + 1)}${escapeHtml(truncated)}`);
955
955
  }
956
956
  continue;
@@ -965,7 +965,7 @@ function serializeElement(element2, depth, state, lines) {
965
965
  serializeElement(child, depth + 1, state, lines);
966
966
  }
967
967
  if (state.truncated && depth === 0) {
968
- lines.push(" \u2026");
968
+ lines.push(" …");
969
969
  }
970
970
  lines.push(`${indent}</${tagName}>`);
971
971
  }
@@ -982,7 +982,7 @@ function truncateContext(value, maxCharacters) {
982
982
  if (value.length <= maxCharacters) {
983
983
  return value;
984
984
  }
985
- return `${value.slice(0, Math.max(0, maxCharacters - 1)).trimEnd()}\u2026`;
985
+ return `${value.slice(0, Math.max(0, maxCharacters - 1)).trimEnd()}…`;
986
986
  }
987
987
  function escapeCssIdentifier(value) {
988
988
  return Array.from(value).map(
@@ -1038,7 +1038,7 @@ function collectElementContext(options) {
1038
1038
  selector: createSelector(options.element),
1039
1039
  sanitizedHtml: truncateContext(lines.join("\n"), options.maxCharacters),
1040
1040
  ...text2.length === 0 ? {} : {
1041
- textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`
1041
+ textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}…`
1042
1042
  },
1043
1043
  ...role === null ? {} : { role },
1044
1044
  rect: Object.freeze({
@@ -1207,36 +1207,36 @@ var PROMPT_MESSAGES = Object.freeze({
1207
1207
  none: "None"
1208
1208
  }),
1209
1209
  "zh-CN": Object.freeze({
1210
- adapter: "\u9002\u914D\u5668",
1211
- boundary: "\u4EE3\u7801\u8FB9\u754C",
1212
- code: "\u9644\u8FD1\u4EE3\u7801",
1213
- component: "\u7EC4\u4EF6",
1214
- computedStyles: "\u5173\u952E\u8BA1\u7B97\u6837\u5F0F",
1215
- confidence: "\u7F6E\u4FE1\u5EA6",
1216
- devicePixelRatio: "\u8BBE\u5907\u50CF\u7D20\u6BD4",
1217
- element: "\u9009\u4E2D\u5143\u7D20",
1218
- file: "\u6587\u4EF6",
1219
- modificationConstraint: "\u8BF7\u5148\u5224\u65AD\u6839\u56E0\uFF0C\u518D\u628A\u6BCF\u4E2A\u76EE\u6807\u5404\u81EA\u7684\u4FEE\u6539\u8BF4\u660E\u4F5C\u4E3A\u4E00\u4E2A\u539F\u5B50\u4EFB\u52A1\uFF0C\u5B8C\u6210\u4E00\u81F4\u4E14\u6700\u5C0F\u8303\u56F4\u7684\u4FEE\u6539\u3002\u4E0D\u8981\u5408\u5E76\u3001\u5FFD\u7565\u6216\u6269\u5927\u76EE\u6807\u8BF4\u660E\uFF0C\u4E0D\u8981\u6539\u52A8\u65E0\u5173\u7EC4\u4EF6\uFF1B\u5982\u679C\u4E0A\u4E0B\u6587\u4E0D\u8DB3\uFF0C\u8BF7\u660E\u786E\u8BF4\u660E\u9700\u8981\u54EA\u4E9B\u4FE1\u606F\u3002",
1220
- modificationRequirements: "\u4FEE\u6539\u8981\u6C42",
1221
- origin: "\u5B9A\u4F4D\u6765\u6E90",
1222
- pageEnvironment: "\u9875\u9762\u73AF\u5883",
1223
- pathname: "\u8DEF\u5F84",
1224
- reactContext: "React \u4E0A\u4E0B\u6587",
1210
+ adapter: "适配器",
1211
+ boundary: "代码边界",
1212
+ code: "附近代码",
1213
+ component: "组件",
1214
+ computedStyles: "关键计算样式",
1215
+ confidence: "置信度",
1216
+ devicePixelRatio: "设备像素比",
1217
+ element: "选中元素",
1218
+ file: "文件",
1219
+ modificationConstraint: "请先判断根因,再把每个目标各自的修改说明作为一个原子任务,完成一致且最小范围的修改。不要合并、忽略或扩大目标说明,不要改动无关组件;如果上下文不足,请明确说明需要哪些信息。",
1220
+ modificationRequirements: "修改要求",
1221
+ origin: "定位来源",
1222
+ pageEnvironment: "页面环境",
1223
+ pathname: "路径",
1224
+ reactContext: "React 上下文",
1225
1225
  reactVersion: "React",
1226
- requestedChange: "\u4FEE\u6539\u8BF4\u660E",
1227
- selectedTargets: (count) => `\u5DF2\u9009\u76EE\u6807\uFF08${String(count)}\uFF09`,
1228
- source: "\u6E90\u7801\u5B9A\u4F4D",
1229
- stack: "\u7EC4\u4EF6\u6808",
1230
- styles: "\u76F8\u5173\u6837\u5F0F",
1231
- supported: "\u652F\u6301",
1232
- target: (index) => `\u76EE\u6807 ${String(index)}`,
1233
- title: "\u6807\u9898",
1234
- unavailable: "\u4E0D\u53EF\u7528",
1235
- unsupported: "\u4E0D\u652F\u6301",
1226
+ requestedChange: "修改说明",
1227
+ selectedTargets: (count) => `已选目标(${String(count)})`,
1228
+ source: "源码定位",
1229
+ stack: "组件栈",
1230
+ styles: "相关样式",
1231
+ supported: "支持",
1232
+ target: (index) => `目标 ${String(index)}`,
1233
+ title: "标题",
1234
+ unavailable: "不可用",
1235
+ unsupported: "不支持",
1236
1236
  url: "URL",
1237
- viewport: "\u89C6\u53E3",
1238
- warnings: "\u91C7\u96C6\u8B66\u544A",
1239
- none: "\u65E0"
1237
+ viewport: "视口",
1238
+ warnings: "采集警告",
1239
+ none: "无"
1240
1240
  })
1241
1241
  });
1242
1242
  function longestBacktickRun(value) {
@@ -1339,7 +1339,7 @@ function renderPrompt(annotation, draft) {
1339
1339
  `- ${messages.url}: <${pageUrl}>
1340
1340
  - ${messages.pathname}: ${(0, import_shared4.redactSensitiveText)(annotation.page.pathname)}
1341
1341
  - ${messages.title}: ${draft.pageTitle.length === 0 ? messages.unavailable : draft.pageTitle}
1342
- - ${messages.viewport}: ${String(annotation.page.viewportWidth)} \xD7 ${String(annotation.page.viewportHeight)}
1342
+ - ${messages.viewport}: ${String(annotation.page.viewportWidth)} × ${String(annotation.page.viewportHeight)}
1343
1343
  - ${messages.devicePixelRatio}: ${String(annotation.page.devicePixelRatio)}`,
1344
1344
  `## ${messages.selectedTargets(annotation.targets.length)}`,
1345
1345
  annotation.targets.map((target2, index) => {
@@ -1362,7 +1362,7 @@ function shrinkCode(target2, draft) {
1362
1362
  if (line.length <= 120) {
1363
1363
  draft.codeLines = [];
1364
1364
  } else {
1365
- draft.codeLines = [`${line.slice(0, 119)}\u2026`];
1365
+ draft.codeLines = [`${line.slice(0, 119)}…`];
1366
1366
  }
1367
1367
  return true;
1368
1368
  }
@@ -1954,7 +1954,7 @@ var AGENT_PANEL_STYLES = `
1954
1954
  }
1955
1955
  .spotpatch-agent-activity { display: grid; gap: 5px; margin: 9px 0 0; padding: 0; list-style: none; }
1956
1956
  .spotpatch-agent-activity li { display: flex; gap: 8px; color: #929bab; font: 11.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; }
1957
- .spotpatch-agent-activity li::before { color: #64748b; content: "\u2022"; }
1957
+ .spotpatch-agent-activity li::before { color: #64748b; content: "•"; }
1958
1958
  .spotpatch-agent-activity li[data-state="active"]::before { color: #fbbf24; }
1959
1959
  .spotpatch-agent-activity li[data-state="success"]::before { color: #34d399; }
1960
1960
  .spotpatch-agent-activity li[data-state="failure"]::before { color: #fb7185; }
@@ -2234,7 +2234,7 @@ function createAgentPanel(document, ai, localizer) {
2234
2234
  }
2235
2235
  const snapshot = latestSnapshot;
2236
2236
  const result = latestResult;
2237
- jobModel.textContent = `${snapshot.providerLabel} \xB7 ${snapshot.modelLabel}`;
2237
+ jobModel.textContent = `${snapshot.providerLabel} · ${snapshot.modelLabel}`;
2238
2238
  jobStatus.textContent = messages.agent.status(snapshot.status);
2239
2239
  phase.textContent = snapshot.phaseMessage;
2240
2240
  const jobErrorCode = latestErrorCode ?? snapshot.errorCode;
@@ -2260,7 +2260,7 @@ function createAgentPanel(document, ai, localizer) {
2260
2260
  for (const check of result?.checks ?? []) {
2261
2261
  const details = createMarkedElement(document, "details");
2262
2262
  const checkTitle = createMarkedElement(document, "summary");
2263
- checkTitle.textContent = `${check.label}: ${check.status} \xB7 ${String(check.durationMs)} ms`;
2263
+ checkTitle.textContent = `${check.label}: ${check.status} · ${String(check.durationMs)} ms`;
2264
2264
  const output = createMarkedElement(document, "pre");
2265
2265
  output.textContent = check.output.length === 0 ? messages.agent.noOutput : check.output;
2266
2266
  details.append(checkTitle, output);
@@ -2299,7 +2299,7 @@ function createAgentPanel(document, ai, localizer) {
2299
2299
  } else if (latestCapabilityState === "probing") {
2300
2300
  capability.textContent = messages.agent.testingCapability;
2301
2301
  } else if (latestCapabilityState === "ready") {
2302
- capability.textContent = `${messages.agent.capabilityVerified} \xB7 ${messages.agent.toolsReady}`;
2302
+ capability.textContent = `${messages.agent.capabilityVerified} · ${messages.agent.toolsReady}`;
2303
2303
  } else if (latestCapabilityErrorCode !== void 0) {
2304
2304
  capability.textContent = messages.errors[latestCapabilityErrorCode];
2305
2305
  } else if (selectedProvider() === void 0) {
@@ -2350,7 +2350,7 @@ function createAgentPanel(document, ai, localizer) {
2350
2350
  capabilityProbing = state === "probing";
2351
2351
  capabilityReady = state === "ready" && capabilitySnapshot?.state === "agent-ready";
2352
2352
  capability.dataset.state = state;
2353
- capability.textContent = capabilitySnapshot?.state === "agent-ready" ? `${message} \xB7 ${messages.agent.toolsReady}` : message;
2353
+ capability.textContent = capabilitySnapshot?.state === "agent-ready" ? `${message} · ${messages.agent.toolsReady}` : message;
2354
2354
  refreshActions();
2355
2355
  },
2356
2356
  renderWorkspaceHealth(state, snapshot, errorCode) {
@@ -2582,19 +2582,19 @@ var STATUS_EN = Object.freeze({
2582
2582
  failed: "Failed"
2583
2583
  });
2584
2584
  var STATUS_ZH = Object.freeze({
2585
- queued: "\u5DF2\u6392\u961F",
2586
- preparing: "\u51C6\u5907\u4E2D",
2587
- running: "\u6267\u884C\u4E2D",
2588
- validating: "\u9A8C\u8BC1\u4E2D",
2589
- "awaiting-review": "\u7B49\u5F85\u5BA1\u9605",
2590
- applying: "\u5E94\u7528\u4E2D",
2591
- applied: "\u5DF2\u5E94\u7528",
2592
- completed: "\u5DF2\u5B8C\u6210",
2593
- cancelling: "\u53D6\u6D88\u4E2D",
2594
- cancelled: "\u5DF2\u53D6\u6D88",
2595
- reverting: "\u64A4\u9500\u4E2D",
2596
- reverted: "\u5DF2\u64A4\u9500",
2597
- failed: "\u5931\u8D25"
2585
+ queued: "已排队",
2586
+ preparing: "准备中",
2587
+ running: "执行中",
2588
+ validating: "验证中",
2589
+ "awaiting-review": "等待审阅",
2590
+ applying: "应用中",
2591
+ applied: "已应用",
2592
+ completed: "已完成",
2593
+ cancelling: "取消中",
2594
+ cancelled: "已取消",
2595
+ reverting: "撤销中",
2596
+ reverted: "已撤销",
2597
+ failed: "失败"
2598
2598
  });
2599
2599
  var EXECUTION_ACTIVITY_EN = Object.freeze({
2600
2600
  prepare: "Preparing context",
@@ -2610,17 +2610,17 @@ var EXECUTION_ACTIVITY_EN = Object.freeze({
2610
2610
  unknown: "Processing the current task"
2611
2611
  });
2612
2612
  var EXECUTION_ACTIVITY_ZH = Object.freeze({
2613
- prepare: "\u6B63\u5728\u51C6\u5907\u4E0A\u4E0B\u6587",
2614
- dispatch: "\u6B63\u5728\u6D3E\u53D1\u4E0A\u4E0B\u6587",
2615
- discover: "\u6B63\u5728\u67E5\u627E\u9879\u76EE\u6587\u4EF6",
2616
- search: "\u6B63\u5728\u641C\u7D22\u6E90\u7801",
2617
- read: "\u6B63\u5728\u8BFB\u53D6",
2618
- patch: "\u6B63\u5728\u751F\u6210\u6700\u5C0F\u4FEE\u6539\u8865\u4E01",
2619
- check: "\u6B63\u5728\u8FD0\u884C",
2620
- audit: "\u6B63\u5728\u5BA1\u8BA1\u5019\u9009\u4FEE\u6539",
2621
- apply: "\u6B63\u5728\u5E94\u7528\u5DF2\u9A8C\u8BC1\u4FEE\u6539",
2622
- sync: "\u6B63\u5728\u5C06\u7ED3\u679C\u56DE\u6D41 SpotPatch",
2623
- unknown: "\u6B63\u5728\u5904\u7406\u5F53\u524D\u4EFB\u52A1"
2613
+ prepare: "正在准备上下文",
2614
+ dispatch: "正在派发上下文",
2615
+ discover: "正在查找项目文件",
2616
+ search: "正在搜索源码",
2617
+ read: "正在读取",
2618
+ patch: "正在生成最小修改补丁",
2619
+ check: "正在运行",
2620
+ audit: "正在审计候选修改",
2621
+ apply: "正在应用已验证修改",
2622
+ sync: "正在将结果回流 SpotPatch",
2623
+ unknown: "正在处理当前任务"
2624
2624
  });
2625
2625
  var EXECUTION_LANE_LABELS = Object.freeze({
2626
2626
  prepare: "prepare",
@@ -2639,10 +2639,10 @@ function executionActivityAction(labels, kind, detail) {
2639
2639
  return detail === void 0 || detail.length === 0 ? labels[kind] : `${labels[kind]} ${detail}`;
2640
2640
  }
2641
2641
  function executionActivityLane(kind, detail) {
2642
- return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} \xB7 ${detail}`;
2642
+ return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} · ${detail}`;
2643
2643
  }
2644
2644
  var EXTERNAL_HANDOFF_ERROR_EN = "The external Agent handoff request failed.";
2645
- var EXTERNAL_HANDOFF_ERROR_ZH = "\u5916\u90E8 Agent \u4EA4\u63A5\u8BF7\u6C42\u5931\u8D25\u3002";
2645
+ var EXTERNAL_HANDOFF_ERROR_ZH = "外部 Agent 交接请求失败。";
2646
2646
  var ERROR_MESSAGES_EN = Object.freeze({
2647
2647
  [import_shared6.ERROR_CODES.INVALID_REQUEST]: "The Agent request was rejected as invalid.",
2648
2648
  [import_shared6.ERROR_CODES.INVALID_TOKEN]: "The local SpotPatch session expired.",
@@ -2700,26 +2700,26 @@ var ERROR_MESSAGES_EN = Object.freeze({
2700
2700
  [import_shared6.ERROR_CODES.INTERNAL_ERROR]: "The Agent failed without exposing private details."
2701
2701
  });
2702
2702
  var ERROR_MESSAGES_ZH = Object.freeze({
2703
- [import_shared6.ERROR_CODES.INVALID_REQUEST]: "Agent \u8BF7\u6C42\u65E0\u6548\uFF0C\u5DF2\u88AB\u62D2\u7EDD\u3002",
2704
- [import_shared6.ERROR_CODES.INVALID_TOKEN]: "\u672C\u5730 SpotPatch \u4F1A\u8BDD\u5DF2\u5931\u6548\u3002",
2705
- [import_shared6.ERROR_CODES.ORIGIN_NOT_ALLOWED]: "\u5F53\u524D\u9875\u9762\u6765\u6E90\u672A\u83B7\u6388\u6743\u3002",
2706
- [import_shared6.ERROR_CODES.SOURCE_NOT_FOUND]: "\u9009\u4E2D\u76EE\u6807\u5BF9\u5E94\u7684\u6E90\u7801\u5DF2\u4E0D\u53EF\u7528\u3002",
2707
- [import_shared6.ERROR_CODES.SOURCE_OUTSIDE_ROOT]: "\u9009\u4E2D\u6E90\u7801\u4F4D\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\u4E4B\u5916\u3002",
2708
- [import_shared6.ERROR_CODES.SOURCE_TOO_LARGE]: "\u9009\u4E2D\u6E90\u7801\u8D85\u8FC7\u5B89\u5168\u5927\u5C0F\u9650\u5236\u3002",
2709
- [import_shared6.ERROR_CODES.EDITOR_OPEN_FAILED]: "\u7F16\u8F91\u5668\u6253\u5F00\u8BF7\u6C42\u5931\u8D25\u3002",
2710
- [import_shared6.ERROR_CODES.DATA_FLOW_DISABLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u672A\u542F\u7528\u3002",
2711
- [import_shared6.ERROR_CODES.DATA_FLOW_SOURCE_STALE]: "\u9009\u4E2D\u6E90\u7801\u5DF2\u7ECF\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u7EC4\u4EF6\u3002",
2712
- [import_shared6.ERROR_CODES.DATA_FLOW_ANALYSIS_CANCELLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u5DF2\u53D6\u6D88\u3002",
2713
- [import_shared6.ERROR_CODES.AI_DISABLED]: "Vite \u914D\u7F6E\u672A\u542F\u7528 AI \u6267\u884C\u3002",
2714
- [import_shared6.ERROR_CODES.PROVIDER_NOT_CONFIGURED]: "\u542F\u52A8 Vite \u7684\u8FDB\u7A0B\u4E2D\u7F3A\u5C11\u6A21\u578B\u670D\u52A1 Key \u73AF\u5883\u53D8\u91CF\u3002",
2715
- [import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "\u6A21\u578B\u670D\u52A1\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u7AEF Key\u3002",
2716
- [import_shared6.ERROR_CODES.PROVIDER_PROTOCOL_UNSUPPORTED]: "\u4E2D\u8F6C\u670D\u52A1\u4E0E\u914D\u7F6E\u7684 OpenAI \u517C\u5BB9\u534F\u8BAE\u4E0D\u4E00\u81F4\u3002",
2717
- [import_shared6.ERROR_CODES.MODEL_NOT_ALLOWED]: "\u5F53\u524D\u6A21\u578B\u914D\u7F6E\u672A\u83B7\u6388\u6743\u3002",
2718
- [import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "\u5F53\u524D\u6A21\u578B\u672A\u5B8C\u6210\u5FC5\u8981\u7684\u5DE5\u5177\u8C03\u7528\u6216\u7ED3\u679C\u7EED\u63A5\u3002",
2719
- [import_shared6.ERROR_CODES.PROVIDER_RATE_LIMITED]: "\u6A21\u578B\u670D\u52A1\u6B63\u5728\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
2720
- [import_shared6.ERROR_CODES.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
2721
- [import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
2722
- [import_shared6.ERROR_CODES.AGENT_CANCELLED]: "Agent \u4EFB\u52A1\u5DF2\u53D6\u6D88\u3002",
2703
+ [import_shared6.ERROR_CODES.INVALID_REQUEST]: "Agent 请求无效,已被拒绝。",
2704
+ [import_shared6.ERROR_CODES.INVALID_TOKEN]: "本地 SpotPatch 会话已失效。",
2705
+ [import_shared6.ERROR_CODES.ORIGIN_NOT_ALLOWED]: "当前页面来源未获授权。",
2706
+ [import_shared6.ERROR_CODES.SOURCE_NOT_FOUND]: "选中目标对应的源码已不可用。",
2707
+ [import_shared6.ERROR_CODES.SOURCE_OUTSIDE_ROOT]: "选中源码位于项目根目录之外。",
2708
+ [import_shared6.ERROR_CODES.SOURCE_TOO_LARGE]: "选中源码超过安全大小限制。",
2709
+ [import_shared6.ERROR_CODES.EDITOR_OPEN_FAILED]: "编辑器打开请求失败。",
2710
+ [import_shared6.ERROR_CODES.DATA_FLOW_DISABLED]: "组件数据链路分析未启用。",
2711
+ [import_shared6.ERROR_CODES.DATA_FLOW_SOURCE_STALE]: "选中源码已经变化,请重新选择组件。",
2712
+ [import_shared6.ERROR_CODES.DATA_FLOW_ANALYSIS_CANCELLED]: "组件数据链路分析已取消。",
2713
+ [import_shared6.ERROR_CODES.AI_DISABLED]: "Vite 配置未启用 AI 执行。",
2714
+ [import_shared6.ERROR_CODES.PROVIDER_NOT_CONFIGURED]: "启动 Vite 的进程中缺少模型服务 Key 环境变量。",
2715
+ [import_shared6.ERROR_CODES.PROVIDER_AUTH_FAILED]: "模型服务鉴权失败,请检查服务端 Key。",
2716
+ [import_shared6.ERROR_CODES.PROVIDER_PROTOCOL_UNSUPPORTED]: "中转服务与配置的 OpenAI 兼容协议不一致。",
2717
+ [import_shared6.ERROR_CODES.MODEL_NOT_ALLOWED]: "当前模型配置未获授权。",
2718
+ [import_shared6.ERROR_CODES.MODEL_TOOL_CALL_UNSUPPORTED]: "当前模型未完成必要的工具调用或结果续接。",
2719
+ [import_shared6.ERROR_CODES.PROVIDER_RATE_LIMITED]: "模型服务正在限流,请稍后重试。",
2720
+ [import_shared6.ERROR_CODES.AGENT_BUSY]: "当前项目已有一个写入任务正在运行。",
2721
+ [import_shared6.ERROR_CODES.AGENT_LIMIT_EXCEEDED]: "Agent 达到时间、轮次、输出或变更规模限制。",
2722
+ [import_shared6.ERROR_CODES.AGENT_CANCELLED]: "Agent 任务已取消。",
2723
2723
  [import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_DISABLED]: EXTERNAL_HANDOFF_ERROR_ZH,
2724
2724
  [import_shared6.ERROR_CODES.EXTERNAL_HANDOFF_UNAVAILABLE]: EXTERNAL_HANDOFF_ERROR_ZH,
2725
2725
  [import_shared6.ERROR_CODES.HANDOFF_VALIDATION_FAILED]: EXTERNAL_HANDOFF_ERROR_ZH,
@@ -2738,22 +2738,22 @@ var ERROR_MESSAGES_ZH = Object.freeze({
2738
2738
  [import_shared6.ERROR_CODES.SESSION_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_ZH,
2739
2739
  [import_shared6.ERROR_CODES.SESSION_AMBIGUOUS]: EXTERNAL_HANDOFF_ERROR_ZH,
2740
2740
  [import_shared6.ERROR_CODES.SESSION_CLOSED]: EXTERNAL_HANDOFF_ERROR_ZH,
2741
- [import_shared6.ERROR_CODES.WORKTREE_DIRTY]: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u660E\u786E\u540C\u610F\u5C06\u5F53\u524D\u672C\u5730\u4FEE\u6539\u7EB3\u5165\u9694\u79BB\u57FA\u7EBF\u3002",
2742
- [import_shared6.ERROR_CODES.WORKTREE_NOT_REPOSITORY]: "Vite \u6839\u76EE\u5F55\u4E0D\u662F\u5DF2\u521D\u59CB\u5316 Git \u4ED3\u5E93\u7684\u9876\u5C42\u76EE\u5F55\u3002",
2743
- [import_shared6.ERROR_CODES.WORKTREE_OPERATION_IN_PROGRESS]: "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D merge\u3001rebase\u3001cherry-pick \u6216 revert\uFF0C\u518D\u8FD0\u884C AI\u3002",
2744
- [import_shared6.ERROR_CODES.WORKTREE_CONFLICTED]: "\u8BF7\u5148\u89E3\u51B3\u5168\u90E8 Git \u51B2\u7A81\uFF0C\u518D\u8FD0\u884C AI\u3002",
2745
- [import_shared6.ERROR_CODES.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "\u672A\u8DDF\u8E2A\u6587\u4EF6\u8D85\u8FC7\u5B89\u5168\u6570\u91CF\u6216\u4F53\u79EF\u4E0A\u9650\uFF0C\u8BF7\u5148\u7CBE\u7B80\u3002",
2746
- [import_shared6.ERROR_CODES.WORKTREE_UNTRACKED_UNSUPPORTED]: "\u672A\u8DDF\u8E2A\u9879\u5DF2\u4E22\u5931\u3001\u662F\u7B26\u53F7\u94FE\u63A5\u6216\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u3002",
2747
- [import_shared6.ERROR_CODES.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "\u5F53\u524D\u672C\u5730\u4FEE\u6539\u65E0\u6CD5\u5B89\u5168\u9694\u79BB\u3002",
2748
- [import_shared6.ERROR_CODES.TOOL_DENIED]: "\u5DE5\u5177\u8BF7\u6C42\u8FDD\u53CD\u672C\u5730\u5B89\u5168\u7B56\u7565\u3002",
2749
- [import_shared6.ERROR_CODES.TOOL_INPUT_INVALID]: "\u5DE5\u5177\u8BF7\u6C42\u65E0\u6548\u3002",
2750
- [import_shared6.ERROR_CODES.TOOL_ARGUMENTS_INVALID]: "\u5DE5\u5177\u53C2\u6570\u65E0\u6548\u3002",
2751
- [import_shared6.ERROR_CODES.TOOL_CALL_ID_CONFLICT]: "\u672C\u8F6E\u5DE5\u5177 ID \u51B2\u7A81\u3002",
2752
- [import_shared6.ERROR_CODES.TOOL_PATH_DENIED]: "\u6A21\u578B\u8BF7\u6C42\u4E86\u53D7\u4FDD\u62A4\u6216\u9879\u76EE\u5916\u8DEF\u5F84\u3002",
2753
- [import_shared6.ERROR_CODES.PATCH_REJECTED]: "\u8865\u4E01\u8FDD\u53CD\u672C\u5730\u7B56\u7565\u3002",
2754
- [import_shared6.ERROR_CODES.VALIDATION_FAILED]: "\u5FC5\u9700\u68C0\u67E5\u5931\u8D25\uFF0C\u65E0\u6CD5\u5E94\u7528\u53D8\u66F4\u3002",
2755
- [import_shared6.ERROR_CODES.APPLY_CONFLICT]: "Agent \u89E6\u53CA\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u672A\u8986\u76D6\u3002",
2756
- [import_shared6.ERROR_CODES.INTERNAL_ERROR]: "Agent \u5931\u8D25\uFF0C\u672A\u66B4\u9732\u79C1\u6709\u7EC6\u8282\u3002"
2741
+ [import_shared6.ERROR_CODES.WORKTREE_DIRTY]: "运行 AI 前,请明确同意将当前本地修改纳入隔离基线。",
2742
+ [import_shared6.ERROR_CODES.WORKTREE_NOT_REPOSITORY]: "Vite 根目录不是已初始化 Git 仓库的顶层目录。",
2743
+ [import_shared6.ERROR_CODES.WORKTREE_OPERATION_IN_PROGRESS]: "请先完成当前 merge、rebase、cherry-pick 或 revert,再运行 AI。",
2744
+ [import_shared6.ERROR_CODES.WORKTREE_CONFLICTED]: "请先解决全部 Git 冲突,再运行 AI。",
2745
+ [import_shared6.ERROR_CODES.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "未跟踪文件超过安全数量或体积上限,请先精简。",
2746
+ [import_shared6.ERROR_CODES.WORKTREE_UNTRACKED_UNSUPPORTED]: "未跟踪项已丢失、是符号链接或不是普通文件。",
2747
+ [import_shared6.ERROR_CODES.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "当前本地修改无法安全隔离。",
2748
+ [import_shared6.ERROR_CODES.TOOL_DENIED]: "工具请求违反本地安全策略。",
2749
+ [import_shared6.ERROR_CODES.TOOL_INPUT_INVALID]: "工具请求无效。",
2750
+ [import_shared6.ERROR_CODES.TOOL_ARGUMENTS_INVALID]: "工具参数无效。",
2751
+ [import_shared6.ERROR_CODES.TOOL_CALL_ID_CONFLICT]: "本轮工具 ID 冲突。",
2752
+ [import_shared6.ERROR_CODES.TOOL_PATH_DENIED]: "模型请求了受保护或项目外路径。",
2753
+ [import_shared6.ERROR_CODES.PATCH_REJECTED]: "补丁违反本地策略。",
2754
+ [import_shared6.ERROR_CODES.VALIDATION_FAILED]: "必需检查失败,无法应用变更。",
2755
+ [import_shared6.ERROR_CODES.APPLY_CONFLICT]: "Agent 触及文件已变化,未覆盖。",
2756
+ [import_shared6.ERROR_CODES.INTERNAL_ERROR]: "Agent 失败,未暴露私有细节。"
2757
2757
  });
2758
2758
  var SUMMARY_MESSAGES_EN = Object.freeze({
2759
2759
  adapter: "React adapter",
@@ -2796,54 +2796,54 @@ var SUMMARY_MESSAGES_EN = Object.freeze({
2796
2796
  warning: "Warning"
2797
2797
  });
2798
2798
  var SUMMARY_MESSAGES_ZH = Object.freeze({
2799
- adapter: "React \u9002\u914D\u5668",
2799
+ adapter: "React 适配器",
2800
2800
  api: "API",
2801
2801
  apiStatuses: Object.freeze({
2802
- connected: "\u5DF2\u8FDE\u63A5",
2803
- failed: "\u5931\u8D25",
2804
- loading: "\u52A0\u8F7D\u4E2D",
2805
- "not-required": "\u65E0\u9700\u8BF7\u6C42"
2802
+ connected: "已连接",
2803
+ failed: "失败",
2804
+ loading: "加载中",
2805
+ "not-required": "无需请求"
2806
2806
  }),
2807
- available: "\u53EF\u7528",
2808
- boundary: "\u4EE3\u7801\u8FB9\u754C",
2807
+ available: "可用",
2808
+ boundary: "代码边界",
2809
2809
  boundaries: Object.freeze({
2810
- component: "\u5B8C\u6574\u7EC4\u4EF6",
2811
- "nearby-lines": "\u9644\u8FD1\u4EE3\u7801"
2810
+ component: "完整组件",
2811
+ "nearby-lines": "附近代码"
2812
2812
  }),
2813
- browserContext: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587",
2813
+ browserContext: "浏览器上下文",
2814
2814
  collectionStatuses: Object.freeze({
2815
- failed: "\u5931\u8D25",
2816
- loading: "\u91C7\u96C6\u4E2D",
2817
- ready: "\u5DF2\u5C31\u7EEA"
2815
+ failed: "失败",
2816
+ loading: "采集中",
2817
+ ready: "已就绪"
2818
2818
  }),
2819
- component: "\u7EC4\u4EF6",
2820
- confidence: "\u7F6E\u4FE1\u5EA6",
2819
+ component: "组件",
2820
+ confidence: "置信度",
2821
2821
  confidenceLabels: Object.freeze({
2822
- exact: "\u7CBE\u786E\u5143\u7D20\u6E90\u7801",
2823
- probable: "\u53EF\u80FD\u7684\u6240\u5C5E\u7EC4\u4EF6",
2824
- approximate: "\u6700\u8FD1\u4E1A\u52A1\u5BB9\u5668",
2825
- unknown: "\u672A\u627E\u5230\u6E90\u7801"
2822
+ exact: "精确元素源码",
2823
+ probable: "可能的所属组件",
2824
+ approximate: "最近业务容器",
2825
+ unknown: "未找到源码"
2826
2826
  }),
2827
- cssWarnings: "CSS \u8B66\u544A",
2828
- lineLocation: (line, column) => `\u7B2C ${String(line)} \u884C${column === void 0 ? "" : `\uFF0C\u7B2C ${String(column)} \u5217`}`,
2829
- origin: "\u5B9A\u4F4D\u6765\u6E90",
2830
- source: "\u6E90\u7801",
2831
- sourceContext: "\u6E90\u7801\u4E0A\u4E0B\u6587",
2832
- stack: "\u7EC4\u4EF6\u6808",
2833
- target: (index, active) => `\u76EE\u6807 ${String(index)}${active ? "\uFF08\u5F53\u524D\uFF09" : ""}`,
2834
- unavailable: "\u4E0D\u53EF\u7528",
2835
- unsupported: "\u4E0D\u652F\u6301",
2836
- warning: "\u8B66\u544A"
2827
+ cssWarnings: "CSS 警告",
2828
+ lineLocation: (line, column) => `第 ${String(line)} 行${column === void 0 ? "" : `,第 ${String(column)} 列`}`,
2829
+ origin: "定位来源",
2830
+ source: "源码",
2831
+ sourceContext: "源码上下文",
2832
+ stack: "组件栈",
2833
+ target: (index, active) => `目标 ${String(index)}${active ? "(当前)" : ""}`,
2834
+ unavailable: "不可用",
2835
+ unsupported: "不支持",
2836
+ warning: "警告"
2837
2837
  });
2838
2838
  var UI_MESSAGES = Object.freeze({
2839
2839
  "en-US": Object.freeze({
2840
2840
  localeName: "EN",
2841
- alternateLocaleName: "\u4E2D",
2841
+ alternateLocaleName: "中",
2842
2842
  switchLocale: "Switch interface language to Chinese",
2843
2843
  brand: Object.freeze({
2844
2844
  name: "SpotPatch",
2845
2845
  context: "Live context",
2846
- repository: "GitHub \u2197",
2846
+ repository: "GitHub ↗",
2847
2847
  repositoryTitle: "Star SpotPatch on GitHub"
2848
2848
  }),
2849
2849
  trigger: Object.freeze({
@@ -2877,14 +2877,14 @@ var UI_MESSAGES = Object.freeze({
2877
2877
  count: (selected, maximum) => `${String(selected)} of ${String(maximum)}`,
2878
2878
  complete: (complete, total) => `${String(complete)} of ${String(total)} described`,
2879
2879
  instructionBudget: (used, maximum) => `${String(used)} / ${String(maximum)} characters`,
2880
- instructionBudgetExceeded: (used, maximum) => `${String(used)} / ${String(maximum)} characters \u2014 reduce the request`,
2880
+ instructionBudgetExceeded: (used, maximum) => `${String(used)} / ${String(maximum)} characters — reduce the request`,
2881
2881
  statusReady: "Ready",
2882
2882
  statusPartial: "Partial",
2883
2883
  statusCollecting: "Collecting",
2884
2884
  instructionReady: "Instruction added",
2885
2885
  instructionMissing: "Needs instruction",
2886
2886
  instructionLabel: (name) => `Change for ${name}`,
2887
- instructionPlaceholder: "Describe the desired result for this target, including constraints\u2026",
2887
+ instructionPlaceholder: "Describe the desired result for this target, including constraints…",
2888
2888
  instructionCount: (used, maximum) => `${String(used)} / ${String(maximum)}`,
2889
2889
  activate: (index) => `Edit target ${String(index)}`,
2890
2890
  remove: (index) => `Remove target ${String(index)}`,
@@ -2894,7 +2894,7 @@ var UI_MESSAGES = Object.freeze({
2894
2894
  }),
2895
2895
  diagnostics: Object.freeze({
2896
2896
  title: "Captured context",
2897
- resolving: "Resolving source\u2026",
2897
+ resolving: "Resolving source…",
2898
2898
  noExactSource: "No exact source marker",
2899
2899
  promptAriaLabel: "Generated prompt"
2900
2900
  }),
@@ -2923,22 +2923,22 @@ var UI_MESSAGES = Object.freeze({
2923
2923
  trustedFastConsent: (provider) => `Enable trusted direct mode for ${provider}: send allowed project context, include current local changes, skip project validation checks, and immediately apply AI changes, including file deletions and configuration changes.`,
2924
2924
  connectionNotTested: "Optional connection check not run",
2925
2925
  workspaceNotChecked: "Local workspace not checked",
2926
- checkingWorkspace: "Checking Git workspace and isolated execution\u2026",
2926
+ checkingWorkspace: "Checking Git workspace and isolated execution…",
2927
2927
  workspaceReady: "Local workspace is ready for isolated execution",
2928
- workspaceDirty: (staged, unstaged, untracked) => `Local changes found \xB7 ${String(staged)} staged \xB7 ${String(unstaged)} unstaged \xB7 ${String(untracked)} untracked`,
2928
+ workspaceDirty: (staged, unstaged, untracked) => `Local changes found · ${String(staged)} staged · ${String(unstaged)} unstaged · ${String(untracked)} untracked`,
2929
2929
  includeLocalChanges: "Allow the Agent to continue from my current local changes",
2930
2930
  includeLocalChangesHelp: "The Agent may edit these files. SpotPatch preserves the baseline and applies or reverts only the Agent delta.",
2931
2931
  localChangesConsentRequired: "Confirm inclusion of current local changes before running AI.",
2932
2932
  capabilityVerified: "Agent capability verified",
2933
2933
  capabilityVerifiedAnnouncement: "AI provider capability verified.",
2934
- testingCapability: "Testing authentication, tools, continuation, and streaming\u2026",
2934
+ testingCapability: "Testing authentication, tools, continuation, and streaming…",
2935
2935
  applying: "Applying changes to the project.",
2936
2936
  cancelling: "Cancelling Agent job.",
2937
2937
  reverting: "Reverting the applied Agent change.",
2938
2938
  consentRequired: "Confirm remote provider data transmission before running AI.",
2939
2939
  toolsReady: "tools and streaming ready",
2940
2940
  testConnection: "Check environment",
2941
- verifying: "Verifying\u2026",
2941
+ verifying: "Verifying…",
2942
2942
  run: "Run AI",
2943
2943
  cancel: "Cancel agent",
2944
2944
  discard: "Discard changes",
@@ -2989,7 +2989,7 @@ var UI_MESSAGES = Object.freeze({
2989
2989
  detachedTargetPreserved: "The page element was unloaded; its collected context remains selected.",
2990
2990
  contextWarning: "Browser context collection completed with a warning.",
2991
2991
  contextCollected: "Browser context collected.",
2992
- editorOpening: "Opening source\u2026",
2992
+ editorOpening: "Opening source…",
2993
2993
  editorOpened: "Source opened in the editor.",
2994
2994
  editorFailed: "Could not open the editor. Start it or configure editor.",
2995
2995
  completeInstructions: "Add an instruction for every target and wait for context collection to finish.",
@@ -3001,166 +3001,166 @@ var UI_MESSAGES = Object.freeze({
3001
3001
  errors: ERROR_MESSAGES_EN
3002
3002
  }),
3003
3003
  "zh-CN": Object.freeze({
3004
- localeName: "\u4E2D",
3004
+ localeName: "中",
3005
3005
  alternateLocaleName: "EN",
3006
- switchLocale: "\u5C06\u754C\u9762\u8BED\u8A00\u5207\u6362\u4E3A\u82F1\u6587",
3006
+ switchLocale: "将界面语言切换为英文",
3007
3007
  brand: Object.freeze({
3008
3008
  name: "SpotPatch",
3009
- context: "\u5B9E\u65F6\u4E0A\u4E0B\u6587",
3010
- repository: "GitHub \u2197",
3011
- repositoryTitle: "\u5728 GitHub \u4E0A Star SpotPatch"
3009
+ context: "实时上下文",
3010
+ repository: "GitHub ↗",
3011
+ repositoryTitle: "在 GitHub 上 Star SpotPatch"
3012
3012
  }),
3013
3013
  trigger: Object.freeze({
3014
- select: "\u9009\u62E9\u5143\u7D20",
3015
- stop: "\u505C\u6B62\u9009\u62E9",
3016
- title: (shortcut) => `\u5207\u6362 SpotPatch\uFF08${shortcut}\uFF09`
3014
+ select: "选择元素",
3015
+ stop: "停止选择",
3016
+ title: (shortcut) => `切换 SpotPatch(${shortcut})`
3017
3017
  }),
3018
3018
  dialog: Object.freeze({
3019
- close: "\u5173\u95ED SpotPatch",
3020
- editTitle: "\u89C4\u5212\u672C\u6B21\u4FEE\u6539",
3021
- editSubtitle: "\u4E3A\u6BCF\u4E2A\u9009\u4E2D\u76EE\u6807\u5206\u522B\u5199\u6E05\u695A\u4FEE\u6539\u8981\u6C42\u3002",
3022
- previewTitle: "\u5BA1\u9605\u4FEE\u6539\u8BF7\u6C42",
3023
- previewSubtitle: "\u53D1\u9001\u7ED9 AI \u524D\uFF0C\u8BF7\u6838\u5BF9\u5B8C\u6574\u4E0A\u4E0B\u6587\u4E0E\u6BCF\u9879\u76EE\u6807\u8BF4\u660E\u3002"
3019
+ close: "关闭 SpotPatch",
3020
+ editTitle: "规划本次修改",
3021
+ editSubtitle: "为每个选中目标分别写清楚修改要求。",
3022
+ previewTitle: "审阅修改请求",
3023
+ previewSubtitle: "发送给 AI 前,请核对完整上下文与每项目标说明。"
3024
3024
  }),
3025
3025
  floatingSurface: Object.freeze({
3026
- dragHandle: "\u62D6\u62FD\u4EE5\u79FB\u52A8 SpotPatch \u5DE5\u4F5C\u53F0",
3027
- resetPosition: "\u91CD\u7F6E\u5DE5\u4F5C\u53F0\u4F4D\u7F6E",
3028
- positionReset: "SpotPatch \u5DF2\u6062\u590D\u5230\u53F3\u4E0B\u89D2\u3002"
3026
+ dragHandle: "拖拽以移动 SpotPatch 工作台",
3027
+ resetPosition: "重置工作台位置",
3028
+ positionReset: "SpotPatch 已恢复到右下角。"
3029
3029
  }),
3030
3030
  context: Object.freeze({
3031
- collecting: "\u6B63\u5728\u91C7\u96C6\u4E0A\u4E0B\u6587",
3032
- ready: "\u4E0A\u4E0B\u6587\u5DF2\u5C31\u7EEA",
3033
- partial: "\u90E8\u5206\u4E0A\u4E0B\u6587\u53EF\u7528",
3034
- sourceUnavailable: "\u6E90\u7801\u4F4D\u7F6E\u4E0D\u53EF\u7528",
3035
- selectedElement: "\u5DF2\u9009\u5143\u7D20",
3036
- selectedCount: (count) => `\u5DF2\u9009\u62E9 ${String(count)} \u4E2A\u5143\u7D20`
3031
+ collecting: "正在采集上下文",
3032
+ ready: "上下文已就绪",
3033
+ partial: "部分上下文可用",
3034
+ sourceUnavailable: "源码位置不可用",
3035
+ selectedElement: "已选元素",
3036
+ selectedCount: (count) => `已选择 ${String(count)} 个元素`
3037
3037
  }),
3038
3038
  targets: Object.freeze({
3039
- title: "\u4FEE\u6539\u76EE\u6807",
3040
- ariaLabel: "\u5DF2\u9009\u76EE\u6807\u4E0E\u9010\u9879\u76EE\u6807\u8BF4\u660E",
3039
+ title: "修改目标",
3040
+ ariaLabel: "已选目标与逐项目标说明",
3041
3041
  count: (selected, maximum) => `${String(selected)} / ${String(maximum)}`,
3042
- complete: (complete, total) => `\u5DF2\u63CF\u8FF0 ${String(complete)} / ${String(total)}`,
3043
- instructionBudget: (used, maximum) => `\u8BF4\u660E\u5B57\u7B26 ${String(used)} / ${String(maximum)}`,
3044
- instructionBudgetExceeded: (used, maximum) => `\u8BF4\u660E\u5B57\u7B26 ${String(used)} / ${String(maximum)}\uFF0C\u8BF7\u7CBE\u7B80\u540E\u7EE7\u7EED`,
3045
- statusReady: "\u5DF2\u5C31\u7EEA",
3046
- statusPartial: "\u90E8\u5206\u53EF\u7528",
3047
- statusCollecting: "\u91C7\u96C6\u4E2D",
3048
- instructionReady: "\u5DF2\u586B\u5199\u4FEE\u6539\u8BF4\u660E",
3049
- instructionMissing: "\u5F85\u586B\u5199\u4FEE\u6539\u8BF4\u660E",
3050
- instructionLabel: (name) => `${name} \u7684\u4FEE\u6539\u8BF4\u660E`,
3051
- instructionPlaceholder: "\u63CF\u8FF0\u8FD9\u4E2A\u76EE\u6807\u671F\u671B\u8FBE\u5230\u7684\u7ED3\u679C\uFF0C\u4EE5\u53CA\u4E0D\u80FD\u7834\u574F\u7684\u7EA6\u675F\u2026\u2026",
3042
+ complete: (complete, total) => `已描述 ${String(complete)} / ${String(total)}`,
3043
+ instructionBudget: (used, maximum) => `说明字符 ${String(used)} / ${String(maximum)}`,
3044
+ instructionBudgetExceeded: (used, maximum) => `说明字符 ${String(used)} / ${String(maximum)},请精简后继续`,
3045
+ statusReady: "已就绪",
3046
+ statusPartial: "部分可用",
3047
+ statusCollecting: "采集中",
3048
+ instructionReady: "已填写修改说明",
3049
+ instructionMissing: "待填写修改说明",
3050
+ instructionLabel: (name) => `${name} 的修改说明`,
3051
+ instructionPlaceholder: "描述这个目标期望达到的结果,以及不能破坏的约束……",
3052
3052
  instructionCount: (used, maximum) => `${String(used)} / ${String(maximum)}`,
3053
- activate: (index) => `\u7F16\u8F91\u76EE\u6807 ${String(index)}`,
3054
- remove: (index) => `\u79FB\u9664\u76EE\u6807 ${String(index)}`,
3055
- removeTitle: "\u79FB\u9664\u76EE\u6807",
3056
- addTitle: "\u7EE7\u7EED\u4E3A\u672C\u6B21\u8BF7\u6C42\u9009\u62E9\u5143\u7D20",
3057
- limitTitle: (maximum) => `\u5DF2\u8FBE\u5230 ${String(maximum)} \u4E2A\u76EE\u6807\u7684\u4E0A\u9650`
3053
+ activate: (index) => `编辑目标 ${String(index)}`,
3054
+ remove: (index) => `移除目标 ${String(index)}`,
3055
+ removeTitle: "移除目标",
3056
+ addTitle: "继续为本次请求选择元素",
3057
+ limitTitle: (maximum) => `已达到 ${String(maximum)} 个目标的上限`
3058
3058
  }),
3059
3059
  diagnostics: Object.freeze({
3060
- title: "\u5DF2\u91C7\u96C6\u4E0A\u4E0B\u6587",
3061
- resolving: "\u6B63\u5728\u89E3\u6790\u6E90\u7801\u2026\u2026",
3062
- noExactSource: "\u6CA1\u6709\u7CBE\u786E\u6E90\u7801\u6807\u8BB0",
3063
- promptAriaLabel: "\u751F\u6210\u7684 Prompt"
3060
+ title: "已采集上下文",
3061
+ resolving: "正在解析源码……",
3062
+ noExactSource: "没有精确源码标记",
3063
+ promptAriaLabel: "生成的 Prompt"
3064
3064
  }),
3065
3065
  summary: SUMMARY_MESSAGES_ZH,
3066
3066
  actions: Object.freeze({
3067
- addElement: "\u6DFB\u52A0\u5143\u7D20",
3068
- reselect: "\u91CD\u65B0\u5F00\u59CB",
3069
- openEditor: "\u6253\u5F00\u6E90\u7801",
3070
- openTarget: (index) => `\u6253\u5F00\u76EE\u6807 ${String(index)} \u7684\u6E90\u7801`,
3071
- preview: "\u9884\u89C8 Prompt",
3072
- copy: "\u590D\u5236 Prompt",
3073
- back: "\u8FD4\u56DE\u7F16\u8F91"
3067
+ addElement: "添加元素",
3068
+ reselect: "重新开始",
3069
+ openEditor: "打开源码",
3070
+ openTarget: (index) => `打开目标 ${String(index)} 的源码`,
3071
+ preview: "预览 Prompt",
3072
+ copy: "复制 Prompt",
3073
+ back: "返回编辑"
3074
3074
  }),
3075
3075
  agent: Object.freeze({
3076
- title: "AI \u4EE3\u7801 Agent",
3077
- mode: "\u6267\u884C\u65B9\u5F0F",
3078
- review: "\u5BA1\u9605\u6A21\u5F0F",
3079
- autoGated: "\u53D7\u63A7\u81EA\u52A8\u6A21\u5F0F",
3080
- trustedFast: "\u53EF\u4FE1\u6781\u901F\u6A21\u5F0F",
3081
- provider: "\u6A21\u578B\u670D\u52A1",
3082
- model: "\u6A21\u578B",
3083
- providerAriaLabel: "AI \u6A21\u578B\u670D\u52A1",
3084
- modelAriaLabel: "AI \u6A21\u578B",
3085
- providerUnavailable: "\u6A21\u578B\u670D\u52A1\u914D\u7F6E\u4E0D\u53EF\u7528\u3002",
3086
- consent: (provider) => `\u6211\u4E86\u89E3\u9009\u4E2D\u4E0A\u4E0B\u6587\u4E0E\u83B7\u51C6\u6E90\u7801\u53EF\u80FD\u53D1\u9001\u5230 ${provider}\uFF0C\u5E76\u81EA\u884C\u8D1F\u8D23\u5176\u6570\u636E\u7B56\u7565\u3002`,
3087
- trustedFastConsent: (provider) => `\u4E3A ${provider} \u542F\u7528\u53EF\u4FE1\u6781\u901F\u6A21\u5F0F\uFF1A\u53D1\u9001\u83B7\u51C6\u7684\u9879\u76EE\u4E0A\u4E0B\u6587\u3001\u7EB3\u5165\u5F53\u524D\u672C\u5730\u4FEE\u6539\u3001\u8DF3\u8FC7\u9879\u76EE\u9A8C\u8BC1\u68C0\u67E5\uFF0C\u5E76\u7ACB\u5373\u5E94\u7528 AI \u53D8\u66F4\uFF0C\u5305\u62EC\u5220\u9664\u6587\u4EF6\u4E0E\u914D\u7F6E\u53D8\u66F4\u3002`,
3088
- connectionNotTested: "\u5C1A\u672A\u6267\u884C\u53EF\u9009\u8FDE\u63A5\u68C0\u67E5",
3089
- workspaceNotChecked: "\u5C1A\u672A\u68C0\u67E5\u672C\u5730\u5DE5\u4F5C\u533A",
3090
- checkingWorkspace: "\u6B63\u5728\u68C0\u67E5 Git \u5DE5\u4F5C\u533A\u4E0E\u9694\u79BB\u6267\u884C\u73AF\u5883\u2026\u2026",
3091
- workspaceReady: "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u6EE1\u8DB3\u9694\u79BB\u6267\u884C\u6761\u4EF6",
3092
- workspaceDirty: (staged, unstaged, untracked) => `\u53D1\u73B0\u672C\u5730\u4FEE\u6539 \xB7 \u6682\u5B58 ${String(staged)} \xB7 \u672A\u6682\u5B58 ${String(unstaged)} \xB7 \u672A\u8DDF\u8E2A ${String(untracked)}`,
3093
- includeLocalChanges: "\u5141\u8BB8 Agent \u57FA\u4E8E\u6211\u5F53\u524D\u7684\u672C\u5730\u4FEE\u6539\u7EE7\u7EED",
3094
- includeLocalChangesHelp: "Agent \u53EF\u80FD\u7EE7\u7EED\u4FEE\u6539\u8FD9\u4E9B\u6587\u4EF6\uFF1BSpotPatch \u4F1A\u4FDD\u7559\u539F\u57FA\u7EBF\uFF0C\u4EC5\u5E94\u7528\u6216\u64A4\u9500 Agent \u81EA\u5DF1\u7684\u589E\u91CF\u3002",
3095
- localChangesConsentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u786E\u8BA4\u5141\u8BB8\u7EB3\u5165\u5F53\u524D\u672C\u5730\u4FEE\u6539\u3002",
3096
- capabilityVerified: "Agent \u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7",
3097
- capabilityVerifiedAnnouncement: "AI \u6A21\u578B\u670D\u52A1\u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7\u3002",
3098
- testingCapability: "\u6B63\u5728\u9A8C\u8BC1\u9274\u6743\u3001\u5DE5\u5177\u8C03\u7528\u3001\u8FDE\u7EED\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u2026\u2026",
3099
- applying: "\u6B63\u5728\u5C06\u53D8\u66F4\u5E94\u7528\u5230\u9879\u76EE\u3002",
3100
- cancelling: "\u6B63\u5728\u53D6\u6D88 Agent \u4EFB\u52A1\u3002",
3101
- reverting: "\u6B63\u5728\u64A4\u9500\u5DF2\u5E94\u7528\u7684 Agent \u53D8\u66F4\u3002",
3102
- consentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u5148\u786E\u8BA4\u5141\u8BB8\u5411\u8FDC\u7A0B\u6A21\u578B\u670D\u52A1\u4F20\u8F93\u6570\u636E\u3002",
3103
- toolsReady: "\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u5DF2\u5C31\u7EEA",
3104
- testConnection: "\u68C0\u67E5\u8FD0\u884C\u73AF\u5883",
3105
- verifying: "\u9A8C\u8BC1\u4E2D\u2026\u2026",
3106
- run: "\u8FD0\u884C AI",
3107
- cancel: "\u53D6\u6D88 Agent",
3108
- discard: "\u653E\u5F03\u53D8\u66F4",
3109
- apply: "\u5E94\u7528\u53D8\u66F4",
3110
- revert: "\u64A4\u9500\u53D8\u66F4",
3111
- revise: "\u4FEE\u6539\u8BF7\u6C42",
3112
- diffAriaLabel: "\u5EFA\u8BAE\u7684\u6E90\u7801\u5DEE\u5F02",
3113
- noOutput: "\u6CA1\u6709\u8F93\u51FA\u3002",
3076
+ title: "AI 代码 Agent",
3077
+ mode: "执行方式",
3078
+ review: "审阅模式",
3079
+ autoGated: "受控自动模式",
3080
+ trustedFast: "可信极速模式",
3081
+ provider: "模型服务",
3082
+ model: "模型",
3083
+ providerAriaLabel: "AI 模型服务",
3084
+ modelAriaLabel: "AI 模型",
3085
+ providerUnavailable: "模型服务配置不可用。",
3086
+ consent: (provider) => `我了解选中上下文与获准源码可能发送到 ${provider},并自行负责其数据策略。`,
3087
+ trustedFastConsent: (provider) => `为 ${provider} 启用可信极速模式:发送获准的项目上下文、纳入当前本地修改、跳过项目验证检查,并立即应用 AI 变更,包括删除文件与配置变更。`,
3088
+ connectionNotTested: "尚未执行可选连接检查",
3089
+ workspaceNotChecked: "尚未检查本地工作区",
3090
+ checkingWorkspace: "正在检查 Git 工作区与隔离执行环境……",
3091
+ workspaceReady: "本地工作区已满足隔离执行条件",
3092
+ workspaceDirty: (staged, unstaged, untracked) => `发现本地修改 · 暂存 ${String(staged)} · 未暂存 ${String(unstaged)} · 未跟踪 ${String(untracked)}`,
3093
+ includeLocalChanges: "允许 Agent 基于我当前的本地修改继续",
3094
+ includeLocalChangesHelp: "Agent 可能继续修改这些文件;SpotPatch 会保留原基线,仅应用或撤销 Agent 自己的增量。",
3095
+ localChangesConsentRequired: "运行 AI 前,请确认允许纳入当前本地修改。",
3096
+ capabilityVerified: "Agent 能力验证通过",
3097
+ capabilityVerifiedAnnouncement: "AI 模型服务能力验证通过。",
3098
+ testingCapability: "正在验证鉴权、工具调用、连续调用与流式响应……",
3099
+ applying: "正在将变更应用到项目。",
3100
+ cancelling: "正在取消 Agent 任务。",
3101
+ reverting: "正在撤销已应用的 Agent 变更。",
3102
+ consentRequired: "运行 AI 前,请先确认允许向远程模型服务传输数据。",
3103
+ toolsReady: "工具调用与流式响应已就绪",
3104
+ testConnection: "检查运行环境",
3105
+ verifying: "验证中……",
3106
+ run: "运行 AI",
3107
+ cancel: "取消 Agent",
3108
+ discard: "放弃变更",
3109
+ apply: "应用变更",
3110
+ revert: "撤销变更",
3111
+ revise: "修改请求",
3112
+ diffAriaLabel: "建议的源码差异",
3113
+ noOutput: "没有输出。",
3114
3114
  status: (status) => STATUS_ZH[status]
3115
3115
  }),
3116
3116
  execution: Object.freeze({
3117
3117
  claude: "Claude",
3118
3118
  codex: "Codex",
3119
- receivingTitle: "\u6B63\u5728\u63A5\u6536\u4E0A\u4E0B\u6587",
3120
- dispatchingTitle: (identity) => `\u6B63\u5728\u4EA4\u63A5\u7ED9 ${identity}`,
3121
- runningTitle: (target2) => `\u6B63\u5728\u4FEE\u6539 ${target2}`,
3122
- expandedRunningTitle: (identity) => `${identity} \u6B63\u5728\u6267\u884C\u4FEE\u6539`,
3123
- completedTitle: "\u4FEE\u6539\u5B8C\u6210",
3124
- expandedCompletedTitle: "\u4FEE\u6539\u5DF2\u5B8C\u6210",
3125
- failedTitle: "\u6267\u884C\u5931\u8D25",
3126
- receivingStatus: "\u63A5\u6536\u4E2D",
3127
- dispatchingStatus: "\u6D3E\u53D1\u4E2D",
3128
- runningStatus: "\u6267\u884C\u4E2D",
3129
- checkingStatus: "\u68C0\u67E5\u4E2D",
3130
- completedStatus: "\u5B8C\u6210",
3131
- failedStatus: "\u5931\u8D25",
3132
- resultReturned: "\u7ED3\u679C\u5DF2\u56DE\u6D41 SpotPatch",
3133
- resultSummary: (files) => `${String(files)} \u4E2A\u6587\u4EF6`,
3119
+ receivingTitle: "正在接收上下文",
3120
+ dispatchingTitle: (identity) => `正在交接给 ${identity}`,
3121
+ runningTitle: (target2) => `正在修改 ${target2}`,
3122
+ expandedRunningTitle: (identity) => `${identity} 正在执行修改`,
3123
+ completedTitle: "修改完成",
3124
+ expandedCompletedTitle: "修改已完成",
3125
+ failedTitle: "执行失败",
3126
+ receivingStatus: "接收中",
3127
+ dispatchingStatus: "派发中",
3128
+ runningStatus: "执行中",
3129
+ checkingStatus: "检查中",
3130
+ completedStatus: "完成",
3131
+ failedStatus: "失败",
3132
+ resultReturned: "结果已回流 SpotPatch",
3133
+ resultSummary: (files) => `${String(files)} 个文件`,
3134
3134
  activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_ZH, kind, detail),
3135
3135
  activityLane: executionActivityLane
3136
3136
  }),
3137
3137
  announcements: Object.freeze({
3138
- adapterDisabled: "React \u9002\u914D\u5668\u5F02\u5E38\uFF0C\u672C\u6B21\u4F1A\u8BDD\u5DF2\u505C\u7528 React \u68C0\u67E5\u3002",
3139
- selectionEnabled: "\u5143\u7D20\u9009\u62E9\u5DF2\u542F\u7528\u3002",
3140
- chooseAnother: "\u8BF7\u9009\u62E9\u53E6\u4E00\u4E2A\u5143\u7D20\u3002",
3141
- reselectAfterChange: "\u6587\u4EF6\u53D8\u66F4\u540E\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5F53\u524D\u9875\u9762\u5143\u7D20\u3002",
3142
- sourceLoaded: "\u6E90\u7801\u4E0A\u4E0B\u6587\u5DF2\u52A0\u8F7D\u3002",
3143
- sourceFailed: "\u6E90\u7801\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5931\u8D25\u3002",
3144
- addCancelled: "\u5DF2\u53D6\u6D88\u8FFD\u52A0\u9009\u62E9\u3002",
3145
- selectionLimit: (maximum) => `\u5DF2\u8FBE\u5230 ${String(maximum)} \u4E2A\u5143\u7D20\u7684\u9009\u62E9\u4E0A\u9650\u3002`,
3146
- chooseAdditional: (selected, maximum) => `\u8BF7\u9009\u62E9\u53E6\u4E00\u4E2A\u5143\u7D20\uFF0C\u5F53\u524D\u5DF2\u9009 ${String(selected)} / ${String(maximum)}\u3002`,
3147
- duplicate: "\u8BE5\u6E90\u7801\u76EE\u6807\u5DF2\u7ECF\u5728\u5F53\u524D\u9009\u62E9\u4E2D\u3002",
3148
- sourceProbable: "\u627E\u5230\u53EF\u80FD\u7684 React \u7EC4\u4EF6\uFF0C\u4F46\u6CA1\u6709\u83B7\u6388\u6743\u7684\u6E90\u7801\u6807\u8BB0\u3002",
3149
- sourceMissing: "\u9009\u4E2D\u5143\u7D20\u6CA1\u6709\u83B7\u6388\u6743\u7684\u6E90\u7801\u6807\u8BB0\u3002",
3150
- noSelectable: "\u5F53\u524D\u4F4D\u7F6E\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u5143\u7D20\u3002",
3151
- allTargetsRemoved: "\u5DF2\u79FB\u9664\u5168\u90E8\u76EE\u6807\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5143\u7D20\u3002",
3152
- targetRemoved: "\u5DF2\u79FB\u9664\u9009\u4E2D\u76EE\u6807\u3002",
3153
- detachedTargetPreserved: "\u9875\u9762\u5143\u7D20\u5DF2\u5378\u8F7D\uFF0C\u5DF2\u91C7\u96C6\u7684\u4E0A\u4E0B\u6587\u4ECD\u4FDD\u7559\u5728\u9009\u62E9\u4E2D\u3002",
3154
- contextWarning: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\uFF0C\u4F46\u5B58\u5728\u8B66\u544A\u3002",
3155
- contextCollected: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
3156
- editorOpening: "\u6B63\u5728\u6253\u5F00\u6E90\u7801\u2026\u2026",
3157
- editorOpened: "\u6E90\u7801\u5DF2\u5728\u7F16\u8F91\u5668\u4E2D\u6253\u5F00\u3002",
3158
- editorFailed: "\u65E0\u6CD5\u6253\u5F00\u7F16\u8F91\u5668\u3002\u8BF7\u5148\u542F\u52A8\u7F16\u8F91\u5668\u6216\u68C0\u67E5 editor \u914D\u7F6E\u3002",
3159
- completeInstructions: "\u8BF7\u4E3A\u6BCF\u4E2A\u76EE\u6807\u586B\u5199\u4FEE\u6539\u8BF4\u660E\uFF0C\u5E76\u7B49\u5F85\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
3160
- promptCopied: "Prompt \u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002",
3161
- clipboardUnavailable: "\u65E0\u6CD5\u8BBF\u95EE\u526A\u8D34\u677F\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5E76\u590D\u5236 Prompt\u3002",
3162
- copyFailed: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5E76\u590D\u5236 Prompt\u3002",
3163
- appliedTargetsDetached: "\u53D8\u66F4\u5DF2\u5E94\u7528\uFF1BHMR \u540E\u8BF7\u91CD\u65B0\u9009\u62E9\u9875\u9762\u5143\u7D20\u518D\u53D1\u8D77\u65B0\u8BF7\u6C42\u3002"
3138
+ adapterDisabled: "React 适配器异常,本次会话已停用 React 检查。",
3139
+ selectionEnabled: "元素选择已启用。",
3140
+ chooseAnother: "请选择另一个元素。",
3141
+ reselectAfterChange: "文件变更后,请重新选择当前页面元素。",
3142
+ sourceLoaded: "源码上下文已加载。",
3143
+ sourceFailed: "源码上下文加载失败。",
3144
+ addCancelled: "已取消追加选择。",
3145
+ selectionLimit: (maximum) => `已达到 ${String(maximum)} 个元素的选择上限。`,
3146
+ chooseAdditional: (selected, maximum) => `请选择另一个元素,当前已选 ${String(selected)} / ${String(maximum)}。`,
3147
+ duplicate: "该源码目标已经在当前选择中。",
3148
+ sourceProbable: "找到可能的 React 组件,但没有获授权的源码标记。",
3149
+ sourceMissing: "选中元素没有获授权的源码标记。",
3150
+ noSelectable: "当前位置没有可选择的元素。",
3151
+ allTargetsRemoved: "已移除全部目标,请重新选择元素。",
3152
+ targetRemoved: "已移除选中目标。",
3153
+ detachedTargetPreserved: "页面元素已卸载,已采集的上下文仍保留在选择中。",
3154
+ contextWarning: "浏览器上下文采集完成,但存在警告。",
3155
+ contextCollected: "浏览器上下文采集完成。",
3156
+ editorOpening: "正在打开源码……",
3157
+ editorOpened: "源码已在编辑器中打开。",
3158
+ editorFailed: "无法打开编辑器。请先启动编辑器或检查 editor 配置。",
3159
+ completeInstructions: "请为每个目标填写修改说明,并等待上下文采集完成。",
3160
+ promptCopied: "Prompt 已复制到剪贴板。",
3161
+ clipboardUnavailable: "无法访问剪贴板,请手动选择并复制 Prompt。",
3162
+ copyFailed: "复制失败,请手动选择并复制 Prompt。",
3163
+ appliedTargetsDetached: "变更已应用;HMR 后请重新选择页面元素再发起新请求。"
3164
3164
  }),
3165
3165
  errors: ERROR_MESSAGES_ZH
3166
3166
  })
@@ -4162,7 +4162,7 @@ function createStyles(document) {
4162
4162
  .spotpatch-diagnostics > summary::-webkit-details-marker { display: none; }
4163
4163
  .spotpatch-diagnostics > summary::before {
4164
4164
  color: #778193;
4165
- content: "\u203A";
4165
+ content: "›";
4166
4166
  font-size: 16px;
4167
4167
  line-height: 1;
4168
4168
  transform: rotate(0deg);
@@ -4250,7 +4250,7 @@ function createStyles(document) {
4250
4250
  box-shadow: 0 8px 20px -8px rgb(139 123 255 / 55%);
4251
4251
  }
4252
4252
  .spotpatch-actions .spotpatch-primary:hover:not(:disabled) { color: var(--spotpatch-text-on-accent); filter: brightness(1.08); }
4253
- .spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "\u2197"; font-size: 12px; }
4253
+ .spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "↗"; font-size: 12px; }
4254
4254
  .spotpatch-actions .spotpatch-secondary-action {
4255
4255
  min-height: 30px;
4256
4256
  border-style: dashed;
@@ -4344,7 +4344,7 @@ function createFallbackExecutionIsland(document) {
4344
4344
  root,
4345
4345
  setExpanded: () => void 0,
4346
4346
  render(projection) {
4347
- const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" \xB7 ");
4347
+ const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" · ");
4348
4348
  copy.textContent = text2;
4349
4349
  root.setAttribute("aria-label", text2);
4350
4350
  },
@@ -4446,8 +4446,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4446
4446
  repositoryLink.target = "_blank";
4447
4447
  repositoryLink.rel = "noopener noreferrer";
4448
4448
  const localeButton = createButton(document, "", "spotpatch-locale");
4449
- const resetPositionButton = createButton(document, "\u2316", "spotpatch-reset-position");
4450
- const closeButton = createButton(document, "\xD7", "spotpatch-close");
4449
+ const resetPositionButton = createButton(document, "⌖", "spotpatch-reset-position");
4450
+ const closeButton = createButton(document, "×", "spotpatch-close");
4451
4451
  headerControls.append(repositoryLink, localeButton, resetPositionButton, closeButton);
4452
4452
  brandRow.append(brand, headerControls);
4453
4453
  const title = createMarkedElement(document, "h2");
@@ -4571,7 +4571,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4571
4571
  addTargetButton.classList.add("spotpatch-icon-action");
4572
4572
  addTargetButton.dataset.compactIcon = "+";
4573
4573
  agentPanel.testButton.classList.add("spotpatch-icon-action");
4574
- agentPanel.testButton.dataset.compactIcon = "\u2713";
4574
+ agentPanel.testButton.dataset.compactIcon = "✓";
4575
4575
  openEditorButton.classList.add("spotpatch-secondary-action");
4576
4576
  reselectButton.classList.add("spotpatch-secondary-action");
4577
4577
  secondaryActions.append(openEditorButton, reselectButton);
@@ -4690,7 +4690,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4690
4690
  }
4691
4691
  function currentTargetContext() {
4692
4692
  const target2 = currentTargetSummary();
4693
- return target2.source.length === 0 ? target2.label : `${target2.label} \xB7 ${target2.source}`;
4693
+ return target2.source.length === 0 ? target2.label : `${target2.label} · ${target2.source}`;
4694
4694
  }
4695
4695
  function beginObservedExecution() {
4696
4696
  observedExecutionStartedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -5025,7 +5025,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5025
5025
  name.textContent = target2.label;
5026
5026
  const source2 = createMarkedElement(document, "span");
5027
5027
  source2.className = "spotpatch-target-source";
5028
- source2.textContent = `${statusText(target2)} \xB7 ${target2.source}`;
5028
+ source2.textContent = `${statusText(target2)} · ${target2.source}`;
5029
5029
  copy.append(name, source2);
5030
5030
  const instructionComplete = target2.instruction.trim().length > 0;
5031
5031
  const state = createMarkedElement(document, "span");
@@ -5033,12 +5033,12 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5033
5033
  state.dataset.complete = String(instructionComplete);
5034
5034
  state.textContent = instructionComplete ? messages.targets.instructionReady : messages.targets.instructionMissing;
5035
5035
  select.append(number, copy, state);
5036
- const open = createButton(document, "\u2197", "spotpatch-target-open");
5036
+ const open = createButton(document, "↗", "spotpatch-target-open");
5037
5037
  open.dataset.openTargetId = target2.id;
5038
5038
  open.disabled = !target2.canOpenEditor;
5039
5039
  open.setAttribute("aria-label", messages.actions.openTarget(index + 1));
5040
5040
  open.title = messages.actions.openTarget(index + 1);
5041
- const remove = createButton(document, "\xD7", "spotpatch-target-remove");
5041
+ const remove = createButton(document, "×", "spotpatch-target-remove");
5042
5042
  remove.dataset.removeTargetId = target2.id;
5043
5043
  remove.disabled = !editingEnabled;
5044
5044
  remove.setAttribute("aria-label", messages.targets.remove(index + 1));
@@ -5141,7 +5141,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5141
5141
  box.style.width = `${String(target2.rect.width)}px`;
5142
5142
  box.style.height = `${String(target2.rect.height)}px`;
5143
5143
  const label = createMarkedElement(document, "span");
5144
- label.textContent = `${String(index + 1)} \xB7 ${target2.label}`;
5144
+ label.textContent = `${String(index + 1)} · ${target2.label}`;
5145
5145
  box.append(label);
5146
5146
  selectionHighlights.append(box);
5147
5147
  }
@@ -5640,7 +5640,7 @@ function activityFromEvent(event) {
5640
5640
  key: `tool:${String(event.data.turn)}:${event.data.toolCallId}`,
5641
5641
  kind: toolActivityKind(event.data.toolName),
5642
5642
  ...detail === void 0 ? {} : { detail },
5643
- label: `${event.data.toolName}${detail === void 0 ? "" : ` \xB7 ${detail}`} \xB7 ${event.data.state}`,
5643
+ label: `${event.data.toolName}${detail === void 0 ? "" : ` · ${detail}`} · ${event.data.state}`,
5644
5644
  state: event.data.state === "started" ? "active" : event.data.state === "succeeded" ? "success" : "failure"
5645
5645
  });
5646
5646
  }
@@ -5649,7 +5649,7 @@ function activityFromEvent(event) {
5649
5649
  key: `check:${event.data.result.checkId}:${String(event.sequence)}`,
5650
5650
  kind: "check",
5651
5651
  detail: event.data.result.label,
5652
- label: `${event.data.result.label} \xB7 ${event.data.result.status}`,
5652
+ label: `${event.data.result.label} · ${event.data.result.status}`,
5653
5653
  state: event.data.result.status === "passed" ? "success" : event.data.result.status === "failed" || event.data.result.status === "timed-out" ? "failure" : "info"
5654
5654
  });
5655
5655
  }