@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.js CHANGED
@@ -646,7 +646,7 @@ import { isSensitiveName, redactSensitiveText, sanitizeUrl } from "@spotpatch/sh
646
646
  var MAX_ATTRIBUTE_CHARACTERS = 500;
647
647
  var MAX_SVG_PATH_CHARACTERS = 256;
648
648
  function truncate(value, maxCharacters) {
649
- return value.length <= maxCharacters ? value : `${value.slice(0, Math.max(0, maxCharacters - 1))}\u2026`;
649
+ return value.length <= maxCharacters ? value : `${value.slice(0, Math.max(0, maxCharacters - 1))}…`;
650
650
  }
651
651
  function isSensitiveAttributeName(name) {
652
652
  return isSensitiveName(name);
@@ -659,7 +659,7 @@ function sanitizeAttributeValue(name, value, baseUrl) {
659
659
  return sanitizeUrl(value, baseUrl);
660
660
  }
661
661
  if (name === "d" && value.length > MAX_SVG_PATH_CHARACTERS) {
662
- return `${value.slice(0, MAX_SVG_PATH_CHARACTERS)}\u2026`;
662
+ return `${value.slice(0, MAX_SVG_PATH_CHARACTERS)}…`;
663
663
  }
664
664
  return truncate(redactSensitiveText(value), MAX_ATTRIBUTE_CHARACTERS);
665
665
  }
@@ -964,7 +964,7 @@ function serializeElement(element2, depth, state, lines) {
964
964
  const text2 = normalizedText(child.textContent ?? "");
965
965
  if (text2.length > 0) {
966
966
  state.nodeCount += 1;
967
- const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`;
967
+ const truncated = text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}…`;
968
968
  lines.push(`${" ".repeat(depth + 1)}${escapeHtml(truncated)}`);
969
969
  }
970
970
  continue;
@@ -979,7 +979,7 @@ function serializeElement(element2, depth, state, lines) {
979
979
  serializeElement(child, depth + 1, state, lines);
980
980
  }
981
981
  if (state.truncated && depth === 0) {
982
- lines.push(" \u2026");
982
+ lines.push(" …");
983
983
  }
984
984
  lines.push(`${indent}</${tagName}>`);
985
985
  }
@@ -996,7 +996,7 @@ function truncateContext(value, maxCharacters) {
996
996
  if (value.length <= maxCharacters) {
997
997
  return value;
998
998
  }
999
- return `${value.slice(0, Math.max(0, maxCharacters - 1)).trimEnd()}\u2026`;
999
+ return `${value.slice(0, Math.max(0, maxCharacters - 1)).trimEnd()}…`;
1000
1000
  }
1001
1001
  function escapeCssIdentifier(value) {
1002
1002
  return Array.from(value).map(
@@ -1052,7 +1052,7 @@ function collectElementContext(options) {
1052
1052
  selector: createSelector(options.element),
1053
1053
  sanitizedHtml: truncateContext(lines.join("\n"), options.maxCharacters),
1054
1054
  ...text2.length === 0 ? {} : {
1055
- textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}\u2026`
1055
+ textPreview: text2.length <= DOM_COLLECTION_LIMITS.maxTextCharacters ? text2 : `${text2.slice(0, DOM_COLLECTION_LIMITS.maxTextCharacters)}…`
1056
1056
  },
1057
1057
  ...role === null ? {} : { role },
1058
1058
  rect: Object.freeze({
@@ -1205,36 +1205,36 @@ var PROMPT_MESSAGES = Object.freeze({
1205
1205
  none: "None"
1206
1206
  }),
1207
1207
  "zh-CN": Object.freeze({
1208
- adapter: "\u9002\u914D\u5668",
1209
- boundary: "\u4EE3\u7801\u8FB9\u754C",
1210
- code: "\u9644\u8FD1\u4EE3\u7801",
1211
- component: "\u7EC4\u4EF6",
1212
- computedStyles: "\u5173\u952E\u8BA1\u7B97\u6837\u5F0F",
1213
- confidence: "\u7F6E\u4FE1\u5EA6",
1214
- devicePixelRatio: "\u8BBE\u5907\u50CF\u7D20\u6BD4",
1215
- element: "\u9009\u4E2D\u5143\u7D20",
1216
- file: "\u6587\u4EF6",
1217
- 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",
1218
- modificationRequirements: "\u4FEE\u6539\u8981\u6C42",
1219
- origin: "\u5B9A\u4F4D\u6765\u6E90",
1220
- pageEnvironment: "\u9875\u9762\u73AF\u5883",
1221
- pathname: "\u8DEF\u5F84",
1222
- reactContext: "React \u4E0A\u4E0B\u6587",
1208
+ adapter: "适配器",
1209
+ boundary: "代码边界",
1210
+ code: "附近代码",
1211
+ component: "组件",
1212
+ computedStyles: "关键计算样式",
1213
+ confidence: "置信度",
1214
+ devicePixelRatio: "设备像素比",
1215
+ element: "选中元素",
1216
+ file: "文件",
1217
+ modificationConstraint: "请先判断根因,再把每个目标各自的修改说明作为一个原子任务,完成一致且最小范围的修改。不要合并、忽略或扩大目标说明,不要改动无关组件;如果上下文不足,请明确说明需要哪些信息。",
1218
+ modificationRequirements: "修改要求",
1219
+ origin: "定位来源",
1220
+ pageEnvironment: "页面环境",
1221
+ pathname: "路径",
1222
+ reactContext: "React 上下文",
1223
1223
  reactVersion: "React",
1224
- requestedChange: "\u4FEE\u6539\u8BF4\u660E",
1225
- selectedTargets: (count) => `\u5DF2\u9009\u76EE\u6807\uFF08${String(count)}\uFF09`,
1226
- source: "\u6E90\u7801\u5B9A\u4F4D",
1227
- stack: "\u7EC4\u4EF6\u6808",
1228
- styles: "\u76F8\u5173\u6837\u5F0F",
1229
- supported: "\u652F\u6301",
1230
- target: (index) => `\u76EE\u6807 ${String(index)}`,
1231
- title: "\u6807\u9898",
1232
- unavailable: "\u4E0D\u53EF\u7528",
1233
- unsupported: "\u4E0D\u652F\u6301",
1224
+ requestedChange: "修改说明",
1225
+ selectedTargets: (count) => `已选目标(${String(count)})`,
1226
+ source: "源码定位",
1227
+ stack: "组件栈",
1228
+ styles: "相关样式",
1229
+ supported: "支持",
1230
+ target: (index) => `目标 ${String(index)}`,
1231
+ title: "标题",
1232
+ unavailable: "不可用",
1233
+ unsupported: "不支持",
1234
1234
  url: "URL",
1235
- viewport: "\u89C6\u53E3",
1236
- warnings: "\u91C7\u96C6\u8B66\u544A",
1237
- none: "\u65E0"
1235
+ viewport: "视口",
1236
+ warnings: "采集警告",
1237
+ none: "无"
1238
1238
  })
1239
1239
  });
1240
1240
  function longestBacktickRun(value) {
@@ -1337,7 +1337,7 @@ function renderPrompt(annotation, draft) {
1337
1337
  `- ${messages.url}: <${pageUrl}>
1338
1338
  - ${messages.pathname}: ${redactSensitiveText(annotation.page.pathname)}
1339
1339
  - ${messages.title}: ${draft.pageTitle.length === 0 ? messages.unavailable : draft.pageTitle}
1340
- - ${messages.viewport}: ${String(annotation.page.viewportWidth)} \xD7 ${String(annotation.page.viewportHeight)}
1340
+ - ${messages.viewport}: ${String(annotation.page.viewportWidth)} × ${String(annotation.page.viewportHeight)}
1341
1341
  - ${messages.devicePixelRatio}: ${String(annotation.page.devicePixelRatio)}`,
1342
1342
  `## ${messages.selectedTargets(annotation.targets.length)}`,
1343
1343
  annotation.targets.map((target2, index) => {
@@ -1360,7 +1360,7 @@ function shrinkCode(target2, draft) {
1360
1360
  if (line.length <= 120) {
1361
1361
  draft.codeLines = [];
1362
1362
  } else {
1363
- draft.codeLines = [`${line.slice(0, 119)}\u2026`];
1363
+ draft.codeLines = [`${line.slice(0, 119)}…`];
1364
1364
  }
1365
1365
  return true;
1366
1366
  }
@@ -1945,7 +1945,7 @@ var AGENT_PANEL_STYLES = `
1945
1945
  }
1946
1946
  .spotpatch-agent-activity { display: grid; gap: 5px; margin: 9px 0 0; padding: 0; list-style: none; }
1947
1947
  .spotpatch-agent-activity li { display: flex; gap: 8px; color: #929bab; font: 11.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; }
1948
- .spotpatch-agent-activity li::before { color: #64748b; content: "\u2022"; }
1948
+ .spotpatch-agent-activity li::before { color: #64748b; content: "•"; }
1949
1949
  .spotpatch-agent-activity li[data-state="active"]::before { color: #fbbf24; }
1950
1950
  .spotpatch-agent-activity li[data-state="success"]::before { color: #34d399; }
1951
1951
  .spotpatch-agent-activity li[data-state="failure"]::before { color: #fb7185; }
@@ -2225,7 +2225,7 @@ function createAgentPanel(document, ai, localizer) {
2225
2225
  }
2226
2226
  const snapshot = latestSnapshot;
2227
2227
  const result = latestResult;
2228
- jobModel.textContent = `${snapshot.providerLabel} \xB7 ${snapshot.modelLabel}`;
2228
+ jobModel.textContent = `${snapshot.providerLabel} · ${snapshot.modelLabel}`;
2229
2229
  jobStatus.textContent = messages.agent.status(snapshot.status);
2230
2230
  phase.textContent = snapshot.phaseMessage;
2231
2231
  const jobErrorCode = latestErrorCode ?? snapshot.errorCode;
@@ -2251,7 +2251,7 @@ function createAgentPanel(document, ai, localizer) {
2251
2251
  for (const check of result?.checks ?? []) {
2252
2252
  const details = createMarkedElement(document, "details");
2253
2253
  const checkTitle = createMarkedElement(document, "summary");
2254
- checkTitle.textContent = `${check.label}: ${check.status} \xB7 ${String(check.durationMs)} ms`;
2254
+ checkTitle.textContent = `${check.label}: ${check.status} · ${String(check.durationMs)} ms`;
2255
2255
  const output = createMarkedElement(document, "pre");
2256
2256
  output.textContent = check.output.length === 0 ? messages.agent.noOutput : check.output;
2257
2257
  details.append(checkTitle, output);
@@ -2290,7 +2290,7 @@ function createAgentPanel(document, ai, localizer) {
2290
2290
  } else if (latestCapabilityState === "probing") {
2291
2291
  capability.textContent = messages.agent.testingCapability;
2292
2292
  } else if (latestCapabilityState === "ready") {
2293
- capability.textContent = `${messages.agent.capabilityVerified} \xB7 ${messages.agent.toolsReady}`;
2293
+ capability.textContent = `${messages.agent.capabilityVerified} · ${messages.agent.toolsReady}`;
2294
2294
  } else if (latestCapabilityErrorCode !== void 0) {
2295
2295
  capability.textContent = messages.errors[latestCapabilityErrorCode];
2296
2296
  } else if (selectedProvider() === void 0) {
@@ -2341,7 +2341,7 @@ function createAgentPanel(document, ai, localizer) {
2341
2341
  capabilityProbing = state === "probing";
2342
2342
  capabilityReady = state === "ready" && capabilitySnapshot?.state === "agent-ready";
2343
2343
  capability.dataset.state = state;
2344
- capability.textContent = capabilitySnapshot?.state === "agent-ready" ? `${message} \xB7 ${messages.agent.toolsReady}` : message;
2344
+ capability.textContent = capabilitySnapshot?.state === "agent-ready" ? `${message} · ${messages.agent.toolsReady}` : message;
2345
2345
  refreshActions();
2346
2346
  },
2347
2347
  renderWorkspaceHealth(state, snapshot, errorCode) {
@@ -2452,19 +2452,19 @@ var STATUS_EN = Object.freeze({
2452
2452
  failed: "Failed"
2453
2453
  });
2454
2454
  var STATUS_ZH = Object.freeze({
2455
- queued: "\u5DF2\u6392\u961F",
2456
- preparing: "\u51C6\u5907\u4E2D",
2457
- running: "\u6267\u884C\u4E2D",
2458
- validating: "\u9A8C\u8BC1\u4E2D",
2459
- "awaiting-review": "\u7B49\u5F85\u5BA1\u9605",
2460
- applying: "\u5E94\u7528\u4E2D",
2461
- applied: "\u5DF2\u5E94\u7528",
2462
- completed: "\u5DF2\u5B8C\u6210",
2463
- cancelling: "\u53D6\u6D88\u4E2D",
2464
- cancelled: "\u5DF2\u53D6\u6D88",
2465
- reverting: "\u64A4\u9500\u4E2D",
2466
- reverted: "\u5DF2\u64A4\u9500",
2467
- failed: "\u5931\u8D25"
2455
+ queued: "已排队",
2456
+ preparing: "准备中",
2457
+ running: "执行中",
2458
+ validating: "验证中",
2459
+ "awaiting-review": "等待审阅",
2460
+ applying: "应用中",
2461
+ applied: "已应用",
2462
+ completed: "已完成",
2463
+ cancelling: "取消中",
2464
+ cancelled: "已取消",
2465
+ reverting: "撤销中",
2466
+ reverted: "已撤销",
2467
+ failed: "失败"
2468
2468
  });
2469
2469
  var EXECUTION_ACTIVITY_EN = Object.freeze({
2470
2470
  prepare: "Preparing context",
@@ -2480,17 +2480,17 @@ var EXECUTION_ACTIVITY_EN = Object.freeze({
2480
2480
  unknown: "Processing the current task"
2481
2481
  });
2482
2482
  var EXECUTION_ACTIVITY_ZH = Object.freeze({
2483
- prepare: "\u6B63\u5728\u51C6\u5907\u4E0A\u4E0B\u6587",
2484
- dispatch: "\u6B63\u5728\u6D3E\u53D1\u4E0A\u4E0B\u6587",
2485
- discover: "\u6B63\u5728\u67E5\u627E\u9879\u76EE\u6587\u4EF6",
2486
- search: "\u6B63\u5728\u641C\u7D22\u6E90\u7801",
2487
- read: "\u6B63\u5728\u8BFB\u53D6",
2488
- patch: "\u6B63\u5728\u751F\u6210\u6700\u5C0F\u4FEE\u6539\u8865\u4E01",
2489
- check: "\u6B63\u5728\u8FD0\u884C",
2490
- audit: "\u6B63\u5728\u5BA1\u8BA1\u5019\u9009\u4FEE\u6539",
2491
- apply: "\u6B63\u5728\u5E94\u7528\u5DF2\u9A8C\u8BC1\u4FEE\u6539",
2492
- sync: "\u6B63\u5728\u5C06\u7ED3\u679C\u56DE\u6D41 SpotPatch",
2493
- unknown: "\u6B63\u5728\u5904\u7406\u5F53\u524D\u4EFB\u52A1"
2483
+ prepare: "正在准备上下文",
2484
+ dispatch: "正在派发上下文",
2485
+ discover: "正在查找项目文件",
2486
+ search: "正在搜索源码",
2487
+ read: "正在读取",
2488
+ patch: "正在生成最小修改补丁",
2489
+ check: "正在运行",
2490
+ audit: "正在审计候选修改",
2491
+ apply: "正在应用已验证修改",
2492
+ sync: "正在将结果回流 SpotPatch",
2493
+ unknown: "正在处理当前任务"
2494
2494
  });
2495
2495
  var EXECUTION_LANE_LABELS = Object.freeze({
2496
2496
  prepare: "prepare",
@@ -2509,10 +2509,10 @@ function executionActivityAction(labels, kind, detail) {
2509
2509
  return detail === void 0 || detail.length === 0 ? labels[kind] : `${labels[kind]} ${detail}`;
2510
2510
  }
2511
2511
  function executionActivityLane(kind, detail) {
2512
- return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} \xB7 ${detail}`;
2512
+ return detail === void 0 || detail.length === 0 ? EXECUTION_LANE_LABELS[kind] : `${EXECUTION_LANE_LABELS[kind]} · ${detail}`;
2513
2513
  }
2514
2514
  var EXTERNAL_HANDOFF_ERROR_EN = "The external Agent handoff request failed.";
2515
- var EXTERNAL_HANDOFF_ERROR_ZH = "\u5916\u90E8 Agent \u4EA4\u63A5\u8BF7\u6C42\u5931\u8D25\u3002";
2515
+ var EXTERNAL_HANDOFF_ERROR_ZH = "外部 Agent 交接请求失败。";
2516
2516
  var ERROR_MESSAGES_EN = Object.freeze({
2517
2517
  [ERROR_CODES2.INVALID_REQUEST]: "The Agent request was rejected as invalid.",
2518
2518
  [ERROR_CODES2.INVALID_TOKEN]: "The local SpotPatch session expired.",
@@ -2570,26 +2570,26 @@ var ERROR_MESSAGES_EN = Object.freeze({
2570
2570
  [ERROR_CODES2.INTERNAL_ERROR]: "The Agent failed without exposing private details."
2571
2571
  });
2572
2572
  var ERROR_MESSAGES_ZH = Object.freeze({
2573
- [ERROR_CODES2.INVALID_REQUEST]: "Agent \u8BF7\u6C42\u65E0\u6548\uFF0C\u5DF2\u88AB\u62D2\u7EDD\u3002",
2574
- [ERROR_CODES2.INVALID_TOKEN]: "\u672C\u5730 SpotPatch \u4F1A\u8BDD\u5DF2\u5931\u6548\u3002",
2575
- [ERROR_CODES2.ORIGIN_NOT_ALLOWED]: "\u5F53\u524D\u9875\u9762\u6765\u6E90\u672A\u83B7\u6388\u6743\u3002",
2576
- [ERROR_CODES2.SOURCE_NOT_FOUND]: "\u9009\u4E2D\u76EE\u6807\u5BF9\u5E94\u7684\u6E90\u7801\u5DF2\u4E0D\u53EF\u7528\u3002",
2577
- [ERROR_CODES2.SOURCE_OUTSIDE_ROOT]: "\u9009\u4E2D\u6E90\u7801\u4F4D\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\u4E4B\u5916\u3002",
2578
- [ERROR_CODES2.SOURCE_TOO_LARGE]: "\u9009\u4E2D\u6E90\u7801\u8D85\u8FC7\u5B89\u5168\u5927\u5C0F\u9650\u5236\u3002",
2579
- [ERROR_CODES2.EDITOR_OPEN_FAILED]: "\u7F16\u8F91\u5668\u6253\u5F00\u8BF7\u6C42\u5931\u8D25\u3002",
2580
- [ERROR_CODES2.DATA_FLOW_DISABLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u672A\u542F\u7528\u3002",
2581
- [ERROR_CODES2.DATA_FLOW_SOURCE_STALE]: "\u9009\u4E2D\u6E90\u7801\u5DF2\u7ECF\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u7EC4\u4EF6\u3002",
2582
- [ERROR_CODES2.DATA_FLOW_ANALYSIS_CANCELLED]: "\u7EC4\u4EF6\u6570\u636E\u94FE\u8DEF\u5206\u6790\u5DF2\u53D6\u6D88\u3002",
2583
- [ERROR_CODES2.AI_DISABLED]: "Vite \u914D\u7F6E\u672A\u542F\u7528 AI \u6267\u884C\u3002",
2584
- [ERROR_CODES2.PROVIDER_NOT_CONFIGURED]: "\u542F\u52A8 Vite \u7684\u8FDB\u7A0B\u4E2D\u7F3A\u5C11\u6A21\u578B\u670D\u52A1 Key \u73AF\u5883\u53D8\u91CF\u3002",
2585
- [ERROR_CODES2.PROVIDER_AUTH_FAILED]: "\u6A21\u578B\u670D\u52A1\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u7AEF Key\u3002",
2586
- [ERROR_CODES2.PROVIDER_PROTOCOL_UNSUPPORTED]: "\u4E2D\u8F6C\u670D\u52A1\u4E0E\u914D\u7F6E\u7684 OpenAI \u517C\u5BB9\u534F\u8BAE\u4E0D\u4E00\u81F4\u3002",
2587
- [ERROR_CODES2.MODEL_NOT_ALLOWED]: "\u5F53\u524D\u6A21\u578B\u914D\u7F6E\u672A\u83B7\u6388\u6743\u3002",
2588
- [ERROR_CODES2.MODEL_TOOL_CALL_UNSUPPORTED]: "\u5F53\u524D\u6A21\u578B\u672A\u5B8C\u6210\u5FC5\u8981\u7684\u5DE5\u5177\u8C03\u7528\u6216\u7ED3\u679C\u7EED\u63A5\u3002",
2589
- [ERROR_CODES2.PROVIDER_RATE_LIMITED]: "\u6A21\u578B\u670D\u52A1\u6B63\u5728\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
2590
- [ERROR_CODES2.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
2591
- [ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
2592
- [ERROR_CODES2.AGENT_CANCELLED]: "Agent \u4EFB\u52A1\u5DF2\u53D6\u6D88\u3002",
2573
+ [ERROR_CODES2.INVALID_REQUEST]: "Agent 请求无效,已被拒绝。",
2574
+ [ERROR_CODES2.INVALID_TOKEN]: "本地 SpotPatch 会话已失效。",
2575
+ [ERROR_CODES2.ORIGIN_NOT_ALLOWED]: "当前页面来源未获授权。",
2576
+ [ERROR_CODES2.SOURCE_NOT_FOUND]: "选中目标对应的源码已不可用。",
2577
+ [ERROR_CODES2.SOURCE_OUTSIDE_ROOT]: "选中源码位于项目根目录之外。",
2578
+ [ERROR_CODES2.SOURCE_TOO_LARGE]: "选中源码超过安全大小限制。",
2579
+ [ERROR_CODES2.EDITOR_OPEN_FAILED]: "编辑器打开请求失败。",
2580
+ [ERROR_CODES2.DATA_FLOW_DISABLED]: "组件数据链路分析未启用。",
2581
+ [ERROR_CODES2.DATA_FLOW_SOURCE_STALE]: "选中源码已经变化,请重新选择组件。",
2582
+ [ERROR_CODES2.DATA_FLOW_ANALYSIS_CANCELLED]: "组件数据链路分析已取消。",
2583
+ [ERROR_CODES2.AI_DISABLED]: "Vite 配置未启用 AI 执行。",
2584
+ [ERROR_CODES2.PROVIDER_NOT_CONFIGURED]: "启动 Vite 的进程中缺少模型服务 Key 环境变量。",
2585
+ [ERROR_CODES2.PROVIDER_AUTH_FAILED]: "模型服务鉴权失败,请检查服务端 Key。",
2586
+ [ERROR_CODES2.PROVIDER_PROTOCOL_UNSUPPORTED]: "中转服务与配置的 OpenAI 兼容协议不一致。",
2587
+ [ERROR_CODES2.MODEL_NOT_ALLOWED]: "当前模型配置未获授权。",
2588
+ [ERROR_CODES2.MODEL_TOOL_CALL_UNSUPPORTED]: "当前模型未完成必要的工具调用或结果续接。",
2589
+ [ERROR_CODES2.PROVIDER_RATE_LIMITED]: "模型服务正在限流,请稍后重试。",
2590
+ [ERROR_CODES2.AGENT_BUSY]: "当前项目已有一个写入任务正在运行。",
2591
+ [ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "Agent 达到时间、轮次、输出或变更规模限制。",
2592
+ [ERROR_CODES2.AGENT_CANCELLED]: "Agent 任务已取消。",
2593
2593
  [ERROR_CODES2.EXTERNAL_HANDOFF_DISABLED]: EXTERNAL_HANDOFF_ERROR_ZH,
2594
2594
  [ERROR_CODES2.EXTERNAL_HANDOFF_UNAVAILABLE]: EXTERNAL_HANDOFF_ERROR_ZH,
2595
2595
  [ERROR_CODES2.HANDOFF_VALIDATION_FAILED]: EXTERNAL_HANDOFF_ERROR_ZH,
@@ -2608,22 +2608,22 @@ var ERROR_MESSAGES_ZH = Object.freeze({
2608
2608
  [ERROR_CODES2.SESSION_NOT_FOUND]: EXTERNAL_HANDOFF_ERROR_ZH,
2609
2609
  [ERROR_CODES2.SESSION_AMBIGUOUS]: EXTERNAL_HANDOFF_ERROR_ZH,
2610
2610
  [ERROR_CODES2.SESSION_CLOSED]: EXTERNAL_HANDOFF_ERROR_ZH,
2611
- [ERROR_CODES2.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",
2612
- [ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "Vite \u6839\u76EE\u5F55\u4E0D\u662F\u5DF2\u521D\u59CB\u5316 Git \u4ED3\u5E93\u7684\u9876\u5C42\u76EE\u5F55\u3002",
2613
- [ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D merge\u3001rebase\u3001cherry-pick \u6216 revert\uFF0C\u518D\u8FD0\u884C AI\u3002",
2614
- [ERROR_CODES2.WORKTREE_CONFLICTED]: "\u8BF7\u5148\u89E3\u51B3\u5168\u90E8 Git \u51B2\u7A81\uFF0C\u518D\u8FD0\u884C AI\u3002",
2615
- [ERROR_CODES2.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",
2616
- [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "\u672A\u8DDF\u8E2A\u9879\u5DF2\u4E22\u5931\u3001\u662F\u7B26\u53F7\u94FE\u63A5\u6216\u4E0D\u662F\u666E\u901A\u6587\u4EF6\u3002",
2617
- [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "\u5F53\u524D\u672C\u5730\u4FEE\u6539\u65E0\u6CD5\u5B89\u5168\u9694\u79BB\u3002",
2618
- [ERROR_CODES2.TOOL_DENIED]: "\u5DE5\u5177\u8BF7\u6C42\u8FDD\u53CD\u672C\u5730\u5B89\u5168\u7B56\u7565\u3002",
2619
- [ERROR_CODES2.TOOL_INPUT_INVALID]: "\u5DE5\u5177\u8BF7\u6C42\u65E0\u6548\u3002",
2620
- [ERROR_CODES2.TOOL_ARGUMENTS_INVALID]: "\u5DE5\u5177\u53C2\u6570\u65E0\u6548\u3002",
2621
- [ERROR_CODES2.TOOL_CALL_ID_CONFLICT]: "\u672C\u8F6E\u5DE5\u5177 ID \u51B2\u7A81\u3002",
2622
- [ERROR_CODES2.TOOL_PATH_DENIED]: "\u6A21\u578B\u8BF7\u6C42\u4E86\u53D7\u4FDD\u62A4\u6216\u9879\u76EE\u5916\u8DEF\u5F84\u3002",
2623
- [ERROR_CODES2.PATCH_REJECTED]: "\u8865\u4E01\u8FDD\u53CD\u672C\u5730\u7B56\u7565\u3002",
2624
- [ERROR_CODES2.VALIDATION_FAILED]: "\u5FC5\u9700\u68C0\u67E5\u5931\u8D25\uFF0C\u65E0\u6CD5\u5E94\u7528\u53D8\u66F4\u3002",
2625
- [ERROR_CODES2.APPLY_CONFLICT]: "Agent \u89E6\u53CA\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u672A\u8986\u76D6\u3002",
2626
- [ERROR_CODES2.INTERNAL_ERROR]: "Agent \u5931\u8D25\uFF0C\u672A\u66B4\u9732\u79C1\u6709\u7EC6\u8282\u3002"
2611
+ [ERROR_CODES2.WORKTREE_DIRTY]: "运行 AI 前,请明确同意将当前本地修改纳入隔离基线。",
2612
+ [ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "Vite 根目录不是已初始化 Git 仓库的顶层目录。",
2613
+ [ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "请先完成当前 merge、rebase、cherry-pick 或 revert,再运行 AI。",
2614
+ [ERROR_CODES2.WORKTREE_CONFLICTED]: "请先解决全部 Git 冲突,再运行 AI。",
2615
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "未跟踪文件超过安全数量或体积上限,请先精简。",
2616
+ [ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "未跟踪项已丢失、是符号链接或不是普通文件。",
2617
+ [ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "当前本地修改无法安全隔离。",
2618
+ [ERROR_CODES2.TOOL_DENIED]: "工具请求违反本地安全策略。",
2619
+ [ERROR_CODES2.TOOL_INPUT_INVALID]: "工具请求无效。",
2620
+ [ERROR_CODES2.TOOL_ARGUMENTS_INVALID]: "工具参数无效。",
2621
+ [ERROR_CODES2.TOOL_CALL_ID_CONFLICT]: "本轮工具 ID 冲突。",
2622
+ [ERROR_CODES2.TOOL_PATH_DENIED]: "模型请求了受保护或项目外路径。",
2623
+ [ERROR_CODES2.PATCH_REJECTED]: "补丁违反本地策略。",
2624
+ [ERROR_CODES2.VALIDATION_FAILED]: "必需检查失败,无法应用变更。",
2625
+ [ERROR_CODES2.APPLY_CONFLICT]: "Agent 触及文件已变化,未覆盖。",
2626
+ [ERROR_CODES2.INTERNAL_ERROR]: "Agent 失败,未暴露私有细节。"
2627
2627
  });
2628
2628
  var SUMMARY_MESSAGES_EN = Object.freeze({
2629
2629
  adapter: "React adapter",
@@ -2666,54 +2666,54 @@ var SUMMARY_MESSAGES_EN = Object.freeze({
2666
2666
  warning: "Warning"
2667
2667
  });
2668
2668
  var SUMMARY_MESSAGES_ZH = Object.freeze({
2669
- adapter: "React \u9002\u914D\u5668",
2669
+ adapter: "React 适配器",
2670
2670
  api: "API",
2671
2671
  apiStatuses: Object.freeze({
2672
- connected: "\u5DF2\u8FDE\u63A5",
2673
- failed: "\u5931\u8D25",
2674
- loading: "\u52A0\u8F7D\u4E2D",
2675
- "not-required": "\u65E0\u9700\u8BF7\u6C42"
2672
+ connected: "已连接",
2673
+ failed: "失败",
2674
+ loading: "加载中",
2675
+ "not-required": "无需请求"
2676
2676
  }),
2677
- available: "\u53EF\u7528",
2678
- boundary: "\u4EE3\u7801\u8FB9\u754C",
2677
+ available: "可用",
2678
+ boundary: "代码边界",
2679
2679
  boundaries: Object.freeze({
2680
- component: "\u5B8C\u6574\u7EC4\u4EF6",
2681
- "nearby-lines": "\u9644\u8FD1\u4EE3\u7801"
2680
+ component: "完整组件",
2681
+ "nearby-lines": "附近代码"
2682
2682
  }),
2683
- browserContext: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587",
2683
+ browserContext: "浏览器上下文",
2684
2684
  collectionStatuses: Object.freeze({
2685
- failed: "\u5931\u8D25",
2686
- loading: "\u91C7\u96C6\u4E2D",
2687
- ready: "\u5DF2\u5C31\u7EEA"
2685
+ failed: "失败",
2686
+ loading: "采集中",
2687
+ ready: "已就绪"
2688
2688
  }),
2689
- component: "\u7EC4\u4EF6",
2690
- confidence: "\u7F6E\u4FE1\u5EA6",
2689
+ component: "组件",
2690
+ confidence: "置信度",
2691
2691
  confidenceLabels: Object.freeze({
2692
- exact: "\u7CBE\u786E\u5143\u7D20\u6E90\u7801",
2693
- probable: "\u53EF\u80FD\u7684\u6240\u5C5E\u7EC4\u4EF6",
2694
- approximate: "\u6700\u8FD1\u4E1A\u52A1\u5BB9\u5668",
2695
- unknown: "\u672A\u627E\u5230\u6E90\u7801"
2692
+ exact: "精确元素源码",
2693
+ probable: "可能的所属组件",
2694
+ approximate: "最近业务容器",
2695
+ unknown: "未找到源码"
2696
2696
  }),
2697
- cssWarnings: "CSS \u8B66\u544A",
2698
- lineLocation: (line, column) => `\u7B2C ${String(line)} \u884C${column === void 0 ? "" : `\uFF0C\u7B2C ${String(column)} \u5217`}`,
2699
- origin: "\u5B9A\u4F4D\u6765\u6E90",
2700
- source: "\u6E90\u7801",
2701
- sourceContext: "\u6E90\u7801\u4E0A\u4E0B\u6587",
2702
- stack: "\u7EC4\u4EF6\u6808",
2703
- target: (index, active) => `\u76EE\u6807 ${String(index)}${active ? "\uFF08\u5F53\u524D\uFF09" : ""}`,
2704
- unavailable: "\u4E0D\u53EF\u7528",
2705
- unsupported: "\u4E0D\u652F\u6301",
2706
- warning: "\u8B66\u544A"
2697
+ cssWarnings: "CSS 警告",
2698
+ lineLocation: (line, column) => `第 ${String(line)} 行${column === void 0 ? "" : `,第 ${String(column)} 列`}`,
2699
+ origin: "定位来源",
2700
+ source: "源码",
2701
+ sourceContext: "源码上下文",
2702
+ stack: "组件栈",
2703
+ target: (index, active) => `目标 ${String(index)}${active ? "(当前)" : ""}`,
2704
+ unavailable: "不可用",
2705
+ unsupported: "不支持",
2706
+ warning: "警告"
2707
2707
  });
2708
2708
  var UI_MESSAGES = Object.freeze({
2709
2709
  "en-US": Object.freeze({
2710
2710
  localeName: "EN",
2711
- alternateLocaleName: "\u4E2D",
2711
+ alternateLocaleName: "中",
2712
2712
  switchLocale: "Switch interface language to Chinese",
2713
2713
  brand: Object.freeze({
2714
2714
  name: "SpotPatch",
2715
2715
  context: "Live context",
2716
- repository: "GitHub \u2197",
2716
+ repository: "GitHub ↗",
2717
2717
  repositoryTitle: "Star SpotPatch on GitHub"
2718
2718
  }),
2719
2719
  trigger: Object.freeze({
@@ -2747,14 +2747,14 @@ var UI_MESSAGES = Object.freeze({
2747
2747
  count: (selected, maximum) => `${String(selected)} of ${String(maximum)}`,
2748
2748
  complete: (complete, total) => `${String(complete)} of ${String(total)} described`,
2749
2749
  instructionBudget: (used, maximum) => `${String(used)} / ${String(maximum)} characters`,
2750
- instructionBudgetExceeded: (used, maximum) => `${String(used)} / ${String(maximum)} characters \u2014 reduce the request`,
2750
+ instructionBudgetExceeded: (used, maximum) => `${String(used)} / ${String(maximum)} characters — reduce the request`,
2751
2751
  statusReady: "Ready",
2752
2752
  statusPartial: "Partial",
2753
2753
  statusCollecting: "Collecting",
2754
2754
  instructionReady: "Instruction added",
2755
2755
  instructionMissing: "Needs instruction",
2756
2756
  instructionLabel: (name) => `Change for ${name}`,
2757
- instructionPlaceholder: "Describe the desired result for this target, including constraints\u2026",
2757
+ instructionPlaceholder: "Describe the desired result for this target, including constraints…",
2758
2758
  instructionCount: (used, maximum) => `${String(used)} / ${String(maximum)}`,
2759
2759
  activate: (index) => `Edit target ${String(index)}`,
2760
2760
  remove: (index) => `Remove target ${String(index)}`,
@@ -2764,7 +2764,7 @@ var UI_MESSAGES = Object.freeze({
2764
2764
  }),
2765
2765
  diagnostics: Object.freeze({
2766
2766
  title: "Captured context",
2767
- resolving: "Resolving source\u2026",
2767
+ resolving: "Resolving source…",
2768
2768
  noExactSource: "No exact source marker",
2769
2769
  promptAriaLabel: "Generated prompt"
2770
2770
  }),
@@ -2793,22 +2793,22 @@ var UI_MESSAGES = Object.freeze({
2793
2793
  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.`,
2794
2794
  connectionNotTested: "Optional connection check not run",
2795
2795
  workspaceNotChecked: "Local workspace not checked",
2796
- checkingWorkspace: "Checking Git workspace and isolated execution\u2026",
2796
+ checkingWorkspace: "Checking Git workspace and isolated execution…",
2797
2797
  workspaceReady: "Local workspace is ready for isolated execution",
2798
- workspaceDirty: (staged, unstaged, untracked) => `Local changes found \xB7 ${String(staged)} staged \xB7 ${String(unstaged)} unstaged \xB7 ${String(untracked)} untracked`,
2798
+ workspaceDirty: (staged, unstaged, untracked) => `Local changes found · ${String(staged)} staged · ${String(unstaged)} unstaged · ${String(untracked)} untracked`,
2799
2799
  includeLocalChanges: "Allow the Agent to continue from my current local changes",
2800
2800
  includeLocalChangesHelp: "The Agent may edit these files. SpotPatch preserves the baseline and applies or reverts only the Agent delta.",
2801
2801
  localChangesConsentRequired: "Confirm inclusion of current local changes before running AI.",
2802
2802
  capabilityVerified: "Agent capability verified",
2803
2803
  capabilityVerifiedAnnouncement: "AI provider capability verified.",
2804
- testingCapability: "Testing authentication, tools, continuation, and streaming\u2026",
2804
+ testingCapability: "Testing authentication, tools, continuation, and streaming…",
2805
2805
  applying: "Applying changes to the project.",
2806
2806
  cancelling: "Cancelling Agent job.",
2807
2807
  reverting: "Reverting the applied Agent change.",
2808
2808
  consentRequired: "Confirm remote provider data transmission before running AI.",
2809
2809
  toolsReady: "tools and streaming ready",
2810
2810
  testConnection: "Check environment",
2811
- verifying: "Verifying\u2026",
2811
+ verifying: "Verifying…",
2812
2812
  run: "Run AI",
2813
2813
  cancel: "Cancel agent",
2814
2814
  discard: "Discard changes",
@@ -2859,7 +2859,7 @@ var UI_MESSAGES = Object.freeze({
2859
2859
  detachedTargetPreserved: "The page element was unloaded; its collected context remains selected.",
2860
2860
  contextWarning: "Browser context collection completed with a warning.",
2861
2861
  contextCollected: "Browser context collected.",
2862
- editorOpening: "Opening source\u2026",
2862
+ editorOpening: "Opening source…",
2863
2863
  editorOpened: "Source opened in the editor.",
2864
2864
  editorFailed: "Could not open the editor. Start it or configure editor.",
2865
2865
  completeInstructions: "Add an instruction for every target and wait for context collection to finish.",
@@ -2871,166 +2871,166 @@ var UI_MESSAGES = Object.freeze({
2871
2871
  errors: ERROR_MESSAGES_EN
2872
2872
  }),
2873
2873
  "zh-CN": Object.freeze({
2874
- localeName: "\u4E2D",
2874
+ localeName: "中",
2875
2875
  alternateLocaleName: "EN",
2876
- switchLocale: "\u5C06\u754C\u9762\u8BED\u8A00\u5207\u6362\u4E3A\u82F1\u6587",
2876
+ switchLocale: "将界面语言切换为英文",
2877
2877
  brand: Object.freeze({
2878
2878
  name: "SpotPatch",
2879
- context: "\u5B9E\u65F6\u4E0A\u4E0B\u6587",
2880
- repository: "GitHub \u2197",
2881
- repositoryTitle: "\u5728 GitHub \u4E0A Star SpotPatch"
2879
+ context: "实时上下文",
2880
+ repository: "GitHub ↗",
2881
+ repositoryTitle: "在 GitHub 上 Star SpotPatch"
2882
2882
  }),
2883
2883
  trigger: Object.freeze({
2884
- select: "\u9009\u62E9\u5143\u7D20",
2885
- stop: "\u505C\u6B62\u9009\u62E9",
2886
- title: (shortcut) => `\u5207\u6362 SpotPatch\uFF08${shortcut}\uFF09`
2884
+ select: "选择元素",
2885
+ stop: "停止选择",
2886
+ title: (shortcut) => `切换 SpotPatch(${shortcut})`
2887
2887
  }),
2888
2888
  dialog: Object.freeze({
2889
- close: "\u5173\u95ED SpotPatch",
2890
- editTitle: "\u89C4\u5212\u672C\u6B21\u4FEE\u6539",
2891
- editSubtitle: "\u4E3A\u6BCF\u4E2A\u9009\u4E2D\u76EE\u6807\u5206\u522B\u5199\u6E05\u695A\u4FEE\u6539\u8981\u6C42\u3002",
2892
- previewTitle: "\u5BA1\u9605\u4FEE\u6539\u8BF7\u6C42",
2893
- previewSubtitle: "\u53D1\u9001\u7ED9 AI \u524D\uFF0C\u8BF7\u6838\u5BF9\u5B8C\u6574\u4E0A\u4E0B\u6587\u4E0E\u6BCF\u9879\u76EE\u6807\u8BF4\u660E\u3002"
2889
+ close: "关闭 SpotPatch",
2890
+ editTitle: "规划本次修改",
2891
+ editSubtitle: "为每个选中目标分别写清楚修改要求。",
2892
+ previewTitle: "审阅修改请求",
2893
+ previewSubtitle: "发送给 AI 前,请核对完整上下文与每项目标说明。"
2894
2894
  }),
2895
2895
  floatingSurface: Object.freeze({
2896
- dragHandle: "\u62D6\u62FD\u4EE5\u79FB\u52A8 SpotPatch \u5DE5\u4F5C\u53F0",
2897
- resetPosition: "\u91CD\u7F6E\u5DE5\u4F5C\u53F0\u4F4D\u7F6E",
2898
- positionReset: "SpotPatch \u5DF2\u6062\u590D\u5230\u53F3\u4E0B\u89D2\u3002"
2896
+ dragHandle: "拖拽以移动 SpotPatch 工作台",
2897
+ resetPosition: "重置工作台位置",
2898
+ positionReset: "SpotPatch 已恢复到右下角。"
2899
2899
  }),
2900
2900
  context: Object.freeze({
2901
- collecting: "\u6B63\u5728\u91C7\u96C6\u4E0A\u4E0B\u6587",
2902
- ready: "\u4E0A\u4E0B\u6587\u5DF2\u5C31\u7EEA",
2903
- partial: "\u90E8\u5206\u4E0A\u4E0B\u6587\u53EF\u7528",
2904
- sourceUnavailable: "\u6E90\u7801\u4F4D\u7F6E\u4E0D\u53EF\u7528",
2905
- selectedElement: "\u5DF2\u9009\u5143\u7D20",
2906
- selectedCount: (count) => `\u5DF2\u9009\u62E9 ${String(count)} \u4E2A\u5143\u7D20`
2901
+ collecting: "正在采集上下文",
2902
+ ready: "上下文已就绪",
2903
+ partial: "部分上下文可用",
2904
+ sourceUnavailable: "源码位置不可用",
2905
+ selectedElement: "已选元素",
2906
+ selectedCount: (count) => `已选择 ${String(count)} 个元素`
2907
2907
  }),
2908
2908
  targets: Object.freeze({
2909
- title: "\u4FEE\u6539\u76EE\u6807",
2910
- ariaLabel: "\u5DF2\u9009\u76EE\u6807\u4E0E\u9010\u9879\u76EE\u6807\u8BF4\u660E",
2909
+ title: "修改目标",
2910
+ ariaLabel: "已选目标与逐项目标说明",
2911
2911
  count: (selected, maximum) => `${String(selected)} / ${String(maximum)}`,
2912
- complete: (complete, total) => `\u5DF2\u63CF\u8FF0 ${String(complete)} / ${String(total)}`,
2913
- instructionBudget: (used, maximum) => `\u8BF4\u660E\u5B57\u7B26 ${String(used)} / ${String(maximum)}`,
2914
- instructionBudgetExceeded: (used, maximum) => `\u8BF4\u660E\u5B57\u7B26 ${String(used)} / ${String(maximum)}\uFF0C\u8BF7\u7CBE\u7B80\u540E\u7EE7\u7EED`,
2915
- statusReady: "\u5DF2\u5C31\u7EEA",
2916
- statusPartial: "\u90E8\u5206\u53EF\u7528",
2917
- statusCollecting: "\u91C7\u96C6\u4E2D",
2918
- instructionReady: "\u5DF2\u586B\u5199\u4FEE\u6539\u8BF4\u660E",
2919
- instructionMissing: "\u5F85\u586B\u5199\u4FEE\u6539\u8BF4\u660E",
2920
- instructionLabel: (name) => `${name} \u7684\u4FEE\u6539\u8BF4\u660E`,
2921
- 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",
2912
+ complete: (complete, total) => `已描述 ${String(complete)} / ${String(total)}`,
2913
+ instructionBudget: (used, maximum) => `说明字符 ${String(used)} / ${String(maximum)}`,
2914
+ instructionBudgetExceeded: (used, maximum) => `说明字符 ${String(used)} / ${String(maximum)},请精简后继续`,
2915
+ statusReady: "已就绪",
2916
+ statusPartial: "部分可用",
2917
+ statusCollecting: "采集中",
2918
+ instructionReady: "已填写修改说明",
2919
+ instructionMissing: "待填写修改说明",
2920
+ instructionLabel: (name) => `${name} 的修改说明`,
2921
+ instructionPlaceholder: "描述这个目标期望达到的结果,以及不能破坏的约束……",
2922
2922
  instructionCount: (used, maximum) => `${String(used)} / ${String(maximum)}`,
2923
- activate: (index) => `\u7F16\u8F91\u76EE\u6807 ${String(index)}`,
2924
- remove: (index) => `\u79FB\u9664\u76EE\u6807 ${String(index)}`,
2925
- removeTitle: "\u79FB\u9664\u76EE\u6807",
2926
- addTitle: "\u7EE7\u7EED\u4E3A\u672C\u6B21\u8BF7\u6C42\u9009\u62E9\u5143\u7D20",
2927
- limitTitle: (maximum) => `\u5DF2\u8FBE\u5230 ${String(maximum)} \u4E2A\u76EE\u6807\u7684\u4E0A\u9650`
2923
+ activate: (index) => `编辑目标 ${String(index)}`,
2924
+ remove: (index) => `移除目标 ${String(index)}`,
2925
+ removeTitle: "移除目标",
2926
+ addTitle: "继续为本次请求选择元素",
2927
+ limitTitle: (maximum) => `已达到 ${String(maximum)} 个目标的上限`
2928
2928
  }),
2929
2929
  diagnostics: Object.freeze({
2930
- title: "\u5DF2\u91C7\u96C6\u4E0A\u4E0B\u6587",
2931
- resolving: "\u6B63\u5728\u89E3\u6790\u6E90\u7801\u2026\u2026",
2932
- noExactSource: "\u6CA1\u6709\u7CBE\u786E\u6E90\u7801\u6807\u8BB0",
2933
- promptAriaLabel: "\u751F\u6210\u7684 Prompt"
2930
+ title: "已采集上下文",
2931
+ resolving: "正在解析源码……",
2932
+ noExactSource: "没有精确源码标记",
2933
+ promptAriaLabel: "生成的 Prompt"
2934
2934
  }),
2935
2935
  summary: SUMMARY_MESSAGES_ZH,
2936
2936
  actions: Object.freeze({
2937
- addElement: "\u6DFB\u52A0\u5143\u7D20",
2938
- reselect: "\u91CD\u65B0\u5F00\u59CB",
2939
- openEditor: "\u6253\u5F00\u6E90\u7801",
2940
- openTarget: (index) => `\u6253\u5F00\u76EE\u6807 ${String(index)} \u7684\u6E90\u7801`,
2941
- preview: "\u9884\u89C8 Prompt",
2942
- copy: "\u590D\u5236 Prompt",
2943
- back: "\u8FD4\u56DE\u7F16\u8F91"
2937
+ addElement: "添加元素",
2938
+ reselect: "重新开始",
2939
+ openEditor: "打开源码",
2940
+ openTarget: (index) => `打开目标 ${String(index)} 的源码`,
2941
+ preview: "预览 Prompt",
2942
+ copy: "复制 Prompt",
2943
+ back: "返回编辑"
2944
2944
  }),
2945
2945
  agent: Object.freeze({
2946
- title: "AI \u4EE3\u7801 Agent",
2947
- mode: "\u6267\u884C\u65B9\u5F0F",
2948
- review: "\u5BA1\u9605\u6A21\u5F0F",
2949
- autoGated: "\u53D7\u63A7\u81EA\u52A8\u6A21\u5F0F",
2950
- trustedFast: "\u53EF\u4FE1\u6781\u901F\u6A21\u5F0F",
2951
- provider: "\u6A21\u578B\u670D\u52A1",
2952
- model: "\u6A21\u578B",
2953
- providerAriaLabel: "AI \u6A21\u578B\u670D\u52A1",
2954
- modelAriaLabel: "AI \u6A21\u578B",
2955
- providerUnavailable: "\u6A21\u578B\u670D\u52A1\u914D\u7F6E\u4E0D\u53EF\u7528\u3002",
2956
- 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`,
2957
- 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`,
2958
- connectionNotTested: "\u5C1A\u672A\u6267\u884C\u53EF\u9009\u8FDE\u63A5\u68C0\u67E5",
2959
- workspaceNotChecked: "\u5C1A\u672A\u68C0\u67E5\u672C\u5730\u5DE5\u4F5C\u533A",
2960
- checkingWorkspace: "\u6B63\u5728\u68C0\u67E5 Git \u5DE5\u4F5C\u533A\u4E0E\u9694\u79BB\u6267\u884C\u73AF\u5883\u2026\u2026",
2961
- workspaceReady: "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u6EE1\u8DB3\u9694\u79BB\u6267\u884C\u6761\u4EF6",
2962
- 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)}`,
2963
- includeLocalChanges: "\u5141\u8BB8 Agent \u57FA\u4E8E\u6211\u5F53\u524D\u7684\u672C\u5730\u4FEE\u6539\u7EE7\u7EED",
2964
- 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",
2965
- localChangesConsentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u786E\u8BA4\u5141\u8BB8\u7EB3\u5165\u5F53\u524D\u672C\u5730\u4FEE\u6539\u3002",
2966
- capabilityVerified: "Agent \u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7",
2967
- capabilityVerifiedAnnouncement: "AI \u6A21\u578B\u670D\u52A1\u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7\u3002",
2968
- testingCapability: "\u6B63\u5728\u9A8C\u8BC1\u9274\u6743\u3001\u5DE5\u5177\u8C03\u7528\u3001\u8FDE\u7EED\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u2026\u2026",
2969
- applying: "\u6B63\u5728\u5C06\u53D8\u66F4\u5E94\u7528\u5230\u9879\u76EE\u3002",
2970
- cancelling: "\u6B63\u5728\u53D6\u6D88 Agent \u4EFB\u52A1\u3002",
2971
- reverting: "\u6B63\u5728\u64A4\u9500\u5DF2\u5E94\u7528\u7684 Agent \u53D8\u66F4\u3002",
2972
- consentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u5148\u786E\u8BA4\u5141\u8BB8\u5411\u8FDC\u7A0B\u6A21\u578B\u670D\u52A1\u4F20\u8F93\u6570\u636E\u3002",
2973
- toolsReady: "\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u5DF2\u5C31\u7EEA",
2974
- testConnection: "\u68C0\u67E5\u8FD0\u884C\u73AF\u5883",
2975
- verifying: "\u9A8C\u8BC1\u4E2D\u2026\u2026",
2976
- run: "\u8FD0\u884C AI",
2977
- cancel: "\u53D6\u6D88 Agent",
2978
- discard: "\u653E\u5F03\u53D8\u66F4",
2979
- apply: "\u5E94\u7528\u53D8\u66F4",
2980
- revert: "\u64A4\u9500\u53D8\u66F4",
2981
- revise: "\u4FEE\u6539\u8BF7\u6C42",
2982
- diffAriaLabel: "\u5EFA\u8BAE\u7684\u6E90\u7801\u5DEE\u5F02",
2983
- noOutput: "\u6CA1\u6709\u8F93\u51FA\u3002",
2946
+ title: "AI 代码 Agent",
2947
+ mode: "执行方式",
2948
+ review: "审阅模式",
2949
+ autoGated: "受控自动模式",
2950
+ trustedFast: "可信极速模式",
2951
+ provider: "模型服务",
2952
+ model: "模型",
2953
+ providerAriaLabel: "AI 模型服务",
2954
+ modelAriaLabel: "AI 模型",
2955
+ providerUnavailable: "模型服务配置不可用。",
2956
+ consent: (provider) => `我了解选中上下文与获准源码可能发送到 ${provider},并自行负责其数据策略。`,
2957
+ trustedFastConsent: (provider) => `为 ${provider} 启用可信极速模式:发送获准的项目上下文、纳入当前本地修改、跳过项目验证检查,并立即应用 AI 变更,包括删除文件与配置变更。`,
2958
+ connectionNotTested: "尚未执行可选连接检查",
2959
+ workspaceNotChecked: "尚未检查本地工作区",
2960
+ checkingWorkspace: "正在检查 Git 工作区与隔离执行环境……",
2961
+ workspaceReady: "本地工作区已满足隔离执行条件",
2962
+ workspaceDirty: (staged, unstaged, untracked) => `发现本地修改 · 暂存 ${String(staged)} · 未暂存 ${String(unstaged)} · 未跟踪 ${String(untracked)}`,
2963
+ includeLocalChanges: "允许 Agent 基于我当前的本地修改继续",
2964
+ includeLocalChangesHelp: "Agent 可能继续修改这些文件;SpotPatch 会保留原基线,仅应用或撤销 Agent 自己的增量。",
2965
+ localChangesConsentRequired: "运行 AI 前,请确认允许纳入当前本地修改。",
2966
+ capabilityVerified: "Agent 能力验证通过",
2967
+ capabilityVerifiedAnnouncement: "AI 模型服务能力验证通过。",
2968
+ testingCapability: "正在验证鉴权、工具调用、连续调用与流式响应……",
2969
+ applying: "正在将变更应用到项目。",
2970
+ cancelling: "正在取消 Agent 任务。",
2971
+ reverting: "正在撤销已应用的 Agent 变更。",
2972
+ consentRequired: "运行 AI 前,请先确认允许向远程模型服务传输数据。",
2973
+ toolsReady: "工具调用与流式响应已就绪",
2974
+ testConnection: "检查运行环境",
2975
+ verifying: "验证中……",
2976
+ run: "运行 AI",
2977
+ cancel: "取消 Agent",
2978
+ discard: "放弃变更",
2979
+ apply: "应用变更",
2980
+ revert: "撤销变更",
2981
+ revise: "修改请求",
2982
+ diffAriaLabel: "建议的源码差异",
2983
+ noOutput: "没有输出。",
2984
2984
  status: (status) => STATUS_ZH[status]
2985
2985
  }),
2986
2986
  execution: Object.freeze({
2987
2987
  claude: "Claude",
2988
2988
  codex: "Codex",
2989
- receivingTitle: "\u6B63\u5728\u63A5\u6536\u4E0A\u4E0B\u6587",
2990
- dispatchingTitle: (identity) => `\u6B63\u5728\u4EA4\u63A5\u7ED9 ${identity}`,
2991
- runningTitle: (target2) => `\u6B63\u5728\u4FEE\u6539 ${target2}`,
2992
- expandedRunningTitle: (identity) => `${identity} \u6B63\u5728\u6267\u884C\u4FEE\u6539`,
2993
- completedTitle: "\u4FEE\u6539\u5B8C\u6210",
2994
- expandedCompletedTitle: "\u4FEE\u6539\u5DF2\u5B8C\u6210",
2995
- failedTitle: "\u6267\u884C\u5931\u8D25",
2996
- receivingStatus: "\u63A5\u6536\u4E2D",
2997
- dispatchingStatus: "\u6D3E\u53D1\u4E2D",
2998
- runningStatus: "\u6267\u884C\u4E2D",
2999
- checkingStatus: "\u68C0\u67E5\u4E2D",
3000
- completedStatus: "\u5B8C\u6210",
3001
- failedStatus: "\u5931\u8D25",
3002
- resultReturned: "\u7ED3\u679C\u5DF2\u56DE\u6D41 SpotPatch",
3003
- resultSummary: (files) => `${String(files)} \u4E2A\u6587\u4EF6`,
2989
+ receivingTitle: "正在接收上下文",
2990
+ dispatchingTitle: (identity) => `正在交接给 ${identity}`,
2991
+ runningTitle: (target2) => `正在修改 ${target2}`,
2992
+ expandedRunningTitle: (identity) => `${identity} 正在执行修改`,
2993
+ completedTitle: "修改完成",
2994
+ expandedCompletedTitle: "修改已完成",
2995
+ failedTitle: "执行失败",
2996
+ receivingStatus: "接收中",
2997
+ dispatchingStatus: "派发中",
2998
+ runningStatus: "执行中",
2999
+ checkingStatus: "检查中",
3000
+ completedStatus: "完成",
3001
+ failedStatus: "失败",
3002
+ resultReturned: "结果已回流 SpotPatch",
3003
+ resultSummary: (files) => `${String(files)} 个文件`,
3004
3004
  activityAction: (kind, detail) => executionActivityAction(EXECUTION_ACTIVITY_ZH, kind, detail),
3005
3005
  activityLane: executionActivityLane
3006
3006
  }),
3007
3007
  announcements: Object.freeze({
3008
- adapterDisabled: "React \u9002\u914D\u5668\u5F02\u5E38\uFF0C\u672C\u6B21\u4F1A\u8BDD\u5DF2\u505C\u7528 React \u68C0\u67E5\u3002",
3009
- selectionEnabled: "\u5143\u7D20\u9009\u62E9\u5DF2\u542F\u7528\u3002",
3010
- chooseAnother: "\u8BF7\u9009\u62E9\u53E6\u4E00\u4E2A\u5143\u7D20\u3002",
3011
- reselectAfterChange: "\u6587\u4EF6\u53D8\u66F4\u540E\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5F53\u524D\u9875\u9762\u5143\u7D20\u3002",
3012
- sourceLoaded: "\u6E90\u7801\u4E0A\u4E0B\u6587\u5DF2\u52A0\u8F7D\u3002",
3013
- sourceFailed: "\u6E90\u7801\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5931\u8D25\u3002",
3014
- addCancelled: "\u5DF2\u53D6\u6D88\u8FFD\u52A0\u9009\u62E9\u3002",
3015
- selectionLimit: (maximum) => `\u5DF2\u8FBE\u5230 ${String(maximum)} \u4E2A\u5143\u7D20\u7684\u9009\u62E9\u4E0A\u9650\u3002`,
3016
- chooseAdditional: (selected, maximum) => `\u8BF7\u9009\u62E9\u53E6\u4E00\u4E2A\u5143\u7D20\uFF0C\u5F53\u524D\u5DF2\u9009 ${String(selected)} / ${String(maximum)}\u3002`,
3017
- duplicate: "\u8BE5\u6E90\u7801\u76EE\u6807\u5DF2\u7ECF\u5728\u5F53\u524D\u9009\u62E9\u4E2D\u3002",
3018
- sourceProbable: "\u627E\u5230\u53EF\u80FD\u7684 React \u7EC4\u4EF6\uFF0C\u4F46\u6CA1\u6709\u83B7\u6388\u6743\u7684\u6E90\u7801\u6807\u8BB0\u3002",
3019
- sourceMissing: "\u9009\u4E2D\u5143\u7D20\u6CA1\u6709\u83B7\u6388\u6743\u7684\u6E90\u7801\u6807\u8BB0\u3002",
3020
- noSelectable: "\u5F53\u524D\u4F4D\u7F6E\u6CA1\u6709\u53EF\u9009\u62E9\u7684\u5143\u7D20\u3002",
3021
- allTargetsRemoved: "\u5DF2\u79FB\u9664\u5168\u90E8\u76EE\u6807\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u5143\u7D20\u3002",
3022
- targetRemoved: "\u5DF2\u79FB\u9664\u9009\u4E2D\u76EE\u6807\u3002",
3023
- detachedTargetPreserved: "\u9875\u9762\u5143\u7D20\u5DF2\u5378\u8F7D\uFF0C\u5DF2\u91C7\u96C6\u7684\u4E0A\u4E0B\u6587\u4ECD\u4FDD\u7559\u5728\u9009\u62E9\u4E2D\u3002",
3024
- contextWarning: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\uFF0C\u4F46\u5B58\u5728\u8B66\u544A\u3002",
3025
- contextCollected: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
3026
- editorOpening: "\u6B63\u5728\u6253\u5F00\u6E90\u7801\u2026\u2026",
3027
- editorOpened: "\u6E90\u7801\u5DF2\u5728\u7F16\u8F91\u5668\u4E2D\u6253\u5F00\u3002",
3028
- editorFailed: "\u65E0\u6CD5\u6253\u5F00\u7F16\u8F91\u5668\u3002\u8BF7\u5148\u542F\u52A8\u7F16\u8F91\u5668\u6216\u68C0\u67E5 editor \u914D\u7F6E\u3002",
3029
- 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",
3030
- promptCopied: "Prompt \u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002",
3031
- clipboardUnavailable: "\u65E0\u6CD5\u8BBF\u95EE\u526A\u8D34\u677F\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5E76\u590D\u5236 Prompt\u3002",
3032
- copyFailed: "\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5E76\u590D\u5236 Prompt\u3002",
3033
- appliedTargetsDetached: "\u53D8\u66F4\u5DF2\u5E94\u7528\uFF1BHMR \u540E\u8BF7\u91CD\u65B0\u9009\u62E9\u9875\u9762\u5143\u7D20\u518D\u53D1\u8D77\u65B0\u8BF7\u6C42\u3002"
3008
+ adapterDisabled: "React 适配器异常,本次会话已停用 React 检查。",
3009
+ selectionEnabled: "元素选择已启用。",
3010
+ chooseAnother: "请选择另一个元素。",
3011
+ reselectAfterChange: "文件变更后,请重新选择当前页面元素。",
3012
+ sourceLoaded: "源码上下文已加载。",
3013
+ sourceFailed: "源码上下文加载失败。",
3014
+ addCancelled: "已取消追加选择。",
3015
+ selectionLimit: (maximum) => `已达到 ${String(maximum)} 个元素的选择上限。`,
3016
+ chooseAdditional: (selected, maximum) => `请选择另一个元素,当前已选 ${String(selected)} / ${String(maximum)}。`,
3017
+ duplicate: "该源码目标已经在当前选择中。",
3018
+ sourceProbable: "找到可能的 React 组件,但没有获授权的源码标记。",
3019
+ sourceMissing: "选中元素没有获授权的源码标记。",
3020
+ noSelectable: "当前位置没有可选择的元素。",
3021
+ allTargetsRemoved: "已移除全部目标,请重新选择元素。",
3022
+ targetRemoved: "已移除选中目标。",
3023
+ detachedTargetPreserved: "页面元素已卸载,已采集的上下文仍保留在选择中。",
3024
+ contextWarning: "浏览器上下文采集完成,但存在警告。",
3025
+ contextCollected: "浏览器上下文采集完成。",
3026
+ editorOpening: "正在打开源码……",
3027
+ editorOpened: "源码已在编辑器中打开。",
3028
+ editorFailed: "无法打开编辑器。请先启动编辑器或检查 editor 配置。",
3029
+ completeInstructions: "请为每个目标填写修改说明,并等待上下文采集完成。",
3030
+ promptCopied: "Prompt 已复制到剪贴板。",
3031
+ clipboardUnavailable: "无法访问剪贴板,请手动选择并复制 Prompt。",
3032
+ copyFailed: "复制失败,请手动选择并复制 Prompt。",
3033
+ appliedTargetsDetached: "变更已应用;HMR 后请重新选择页面元素再发起新请求。"
3034
3034
  }),
3035
3035
  errors: ERROR_MESSAGES_ZH
3036
3036
  })
@@ -4032,7 +4032,7 @@ function createStyles(document) {
4032
4032
  .spotpatch-diagnostics > summary::-webkit-details-marker { display: none; }
4033
4033
  .spotpatch-diagnostics > summary::before {
4034
4034
  color: #778193;
4035
- content: "\u203A";
4035
+ content: "›";
4036
4036
  font-size: 16px;
4037
4037
  line-height: 1;
4038
4038
  transform: rotate(0deg);
@@ -4120,7 +4120,7 @@ function createStyles(document) {
4120
4120
  box-shadow: 0 8px 20px -8px rgb(139 123 255 / 55%);
4121
4121
  }
4122
4122
  .spotpatch-actions .spotpatch-primary:hover:not(:disabled) { color: var(--spotpatch-text-on-accent); filter: brightness(1.08); }
4123
- .spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "\u2197"; font-size: 12px; }
4123
+ .spotpatch-actions .spotpatch-primary::after { margin-left: 8px; content: "↗"; font-size: 12px; }
4124
4124
  .spotpatch-actions .spotpatch-secondary-action {
4125
4125
  min-height: 30px;
4126
4126
  border-style: dashed;
@@ -4214,7 +4214,7 @@ function createFallbackExecutionIsland(document) {
4214
4214
  root,
4215
4215
  setExpanded: () => void 0,
4216
4216
  render(projection) {
4217
- const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" \xB7 ");
4217
+ const text2 = [projection.headline, projection.action, projection.meta].filter((value) => value.length > 0).join(" · ");
4218
4218
  copy.textContent = text2;
4219
4219
  root.setAttribute("aria-label", text2);
4220
4220
  },
@@ -4316,8 +4316,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4316
4316
  repositoryLink.target = "_blank";
4317
4317
  repositoryLink.rel = "noopener noreferrer";
4318
4318
  const localeButton = createButton(document, "", "spotpatch-locale");
4319
- const resetPositionButton = createButton(document, "\u2316", "spotpatch-reset-position");
4320
- const closeButton = createButton(document, "\xD7", "spotpatch-close");
4319
+ const resetPositionButton = createButton(document, "⌖", "spotpatch-reset-position");
4320
+ const closeButton = createButton(document, "×", "spotpatch-close");
4321
4321
  headerControls.append(repositoryLink, localeButton, resetPositionButton, closeButton);
4322
4322
  brandRow.append(brand, headerControls);
4323
4323
  const title = createMarkedElement(document, "h2");
@@ -4441,7 +4441,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4441
4441
  addTargetButton.classList.add("spotpatch-icon-action");
4442
4442
  addTargetButton.dataset.compactIcon = "+";
4443
4443
  agentPanel.testButton.classList.add("spotpatch-icon-action");
4444
- agentPanel.testButton.dataset.compactIcon = "\u2713";
4444
+ agentPanel.testButton.dataset.compactIcon = "✓";
4445
4445
  openEditorButton.classList.add("spotpatch-secondary-action");
4446
4446
  reselectButton.classList.add("spotpatch-secondary-action");
4447
4447
  secondaryActions.append(openEditorButton, reselectButton);
@@ -4560,7 +4560,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4560
4560
  }
4561
4561
  function currentTargetContext() {
4562
4562
  const target2 = currentTargetSummary();
4563
- return target2.source.length === 0 ? target2.label : `${target2.label} \xB7 ${target2.source}`;
4563
+ return target2.source.length === 0 ? target2.label : `${target2.label} · ${target2.source}`;
4564
4564
  }
4565
4565
  function beginObservedExecution() {
4566
4566
  observedExecutionStartedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -4895,7 +4895,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4895
4895
  name.textContent = target2.label;
4896
4896
  const source2 = createMarkedElement(document, "span");
4897
4897
  source2.className = "spotpatch-target-source";
4898
- source2.textContent = `${statusText(target2)} \xB7 ${target2.source}`;
4898
+ source2.textContent = `${statusText(target2)} · ${target2.source}`;
4899
4899
  copy.append(name, source2);
4900
4900
  const instructionComplete = target2.instruction.trim().length > 0;
4901
4901
  const state = createMarkedElement(document, "span");
@@ -4903,12 +4903,12 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4903
4903
  state.dataset.complete = String(instructionComplete);
4904
4904
  state.textContent = instructionComplete ? messages.targets.instructionReady : messages.targets.instructionMissing;
4905
4905
  select.append(number, copy, state);
4906
- const open = createButton(document, "\u2197", "spotpatch-target-open");
4906
+ const open = createButton(document, "↗", "spotpatch-target-open");
4907
4907
  open.dataset.openTargetId = target2.id;
4908
4908
  open.disabled = !target2.canOpenEditor;
4909
4909
  open.setAttribute("aria-label", messages.actions.openTarget(index + 1));
4910
4910
  open.title = messages.actions.openTarget(index + 1);
4911
- const remove = createButton(document, "\xD7", "spotpatch-target-remove");
4911
+ const remove = createButton(document, "×", "spotpatch-target-remove");
4912
4912
  remove.dataset.removeTargetId = target2.id;
4913
4913
  remove.disabled = !editingEnabled;
4914
4914
  remove.setAttribute("aria-label", messages.targets.remove(index + 1));
@@ -5011,7 +5011,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5011
5011
  box.style.width = `${String(target2.rect.width)}px`;
5012
5012
  box.style.height = `${String(target2.rect.height)}px`;
5013
5013
  const label = createMarkedElement(document, "span");
5014
- label.textContent = `${String(index + 1)} \xB7 ${target2.label}`;
5014
+ label.textContent = `${String(index + 1)} · ${target2.label}`;
5015
5015
  box.append(label);
5016
5016
  selectionHighlights.append(box);
5017
5017
  }
@@ -5512,7 +5512,7 @@ function activityFromEvent(event) {
5512
5512
  key: `tool:${String(event.data.turn)}:${event.data.toolCallId}`,
5513
5513
  kind: toolActivityKind(event.data.toolName),
5514
5514
  ...detail === void 0 ? {} : { detail },
5515
- label: `${event.data.toolName}${detail === void 0 ? "" : ` \xB7 ${detail}`} \xB7 ${event.data.state}`,
5515
+ label: `${event.data.toolName}${detail === void 0 ? "" : ` · ${detail}`} · ${event.data.state}`,
5516
5516
  state: event.data.state === "started" ? "active" : event.data.state === "succeeded" ? "success" : "failure"
5517
5517
  });
5518
5518
  }
@@ -5521,7 +5521,7 @@ function activityFromEvent(event) {
5521
5521
  key: `check:${event.data.result.checkId}:${String(event.sequence)}`,
5522
5522
  kind: "check",
5523
5523
  detail: event.data.result.label,
5524
- label: `${event.data.result.label} \xB7 ${event.data.result.status}`,
5524
+ label: `${event.data.result.label} · ${event.data.result.status}`,
5525
5525
  state: event.data.result.status === "passed" ? "success" : event.data.result.status === "failed" || event.data.result.status === "timed-out" ? "failure" : "info"
5526
5526
  });
5527
5527
  }