@spotpatch/runtime 1.1.0 → 1.1.1

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
@@ -259,9 +259,6 @@ function readSuccessData(value) {
259
259
  function isCodeContext(value) {
260
260
  return isRecord2(value) && typeof value.relativePath === "string" && (value.language === "tsx" || value.language === "jsx") && typeof value.startLine === "number" && typeof value.endLine === "number" && typeof value.excerpt === "string" && (value.boundary === "component" || value.boundary === "nearby-lines");
261
261
  }
262
- function isEditorOpenResult(value) {
263
- return isRecord2(value) && typeof value.editor === "string" && import_shared3.SPOTPATCH_EDITOR_PREFERENCES.includes(value.editor);
264
- }
265
262
  function deepFreezeUnknown(value) {
266
263
  if (!isRecord2(value) && !Array.isArray(value)) {
267
264
  return;
@@ -489,7 +486,7 @@ function createRuntimeApi(options) {
489
486
  },
490
487
  async openEditor(request) {
491
488
  const data = await requestJson(import_shared3.SPOTPATCH_ENDPOINTS.openEditor, "POST", request);
492
- if (!isEditorOpenResult(data)) {
489
+ if (!isRecord2(data) || data.editor !== "auto" && data.editor !== "vscode" && data.editor !== "cursor") {
493
490
  throw new RuntimeApiError();
494
491
  }
495
492
  return Object.freeze({ editor: data.editor });
@@ -2142,15 +2139,6 @@ var STATUS_ZH = Object.freeze({
2142
2139
  reverted: "\u5DF2\u64A4\u9500",
2143
2140
  failed: "\u5931\u8D25"
2144
2141
  });
2145
- function editorName(editor, automatic) {
2146
- if (editor === "vscode") {
2147
- return "VS Code";
2148
- }
2149
- if (editor === "cursor") {
2150
- return "Cursor";
2151
- }
2152
- return automatic;
2153
- }
2154
2142
  var ERROR_MESSAGES_EN = Object.freeze({
2155
2143
  [import_shared6.ERROR_CODES.INVALID_REQUEST]: "The Agent request was rejected as invalid.",
2156
2144
  [import_shared6.ERROR_CODES.INVALID_TOKEN]: "The local SpotPatch session expired.",
@@ -2289,7 +2277,7 @@ var UI_MESSAGES = Object.freeze({
2289
2277
  brand: Object.freeze({
2290
2278
  name: "SpotPatch",
2291
2279
  context: "Live context",
2292
- repository: "GitHub",
2280
+ repository: "GitHub \u2197",
2293
2281
  repositoryTitle: "Star SpotPatch on GitHub"
2294
2282
  }),
2295
2283
  trigger: Object.freeze({
@@ -2343,8 +2331,8 @@ var UI_MESSAGES = Object.freeze({
2343
2331
  actions: Object.freeze({
2344
2332
  addElement: "Add element",
2345
2333
  reselect: "Start over",
2346
- openEditor: (editor) => editor === "auto" ? "Open source" : `Open in ${editorName(editor, "editor")}`,
2347
- openTarget: (index, editor) => `Open target ${String(index)} in ${editorName(editor, "the detected editor")}`,
2334
+ openEditor: "Open source",
2335
+ openTarget: (index) => `Open source for target ${String(index)}`,
2348
2336
  preview: "Preview prompt",
2349
2337
  copy: "Copy prompt",
2350
2338
  back: "Back to edit"
@@ -2400,9 +2388,9 @@ var UI_MESSAGES = Object.freeze({
2400
2388
  detachedTargetRemoved: "A removed page element was dropped from the selection.",
2401
2389
  contextWarning: "Browser context collection completed with a warning.",
2402
2390
  contextCollected: "Browser context collected.",
2403
- editorOpening: (editor) => `Opening ${editorName(editor, "the detected editor")}\u2026`,
2404
- editorOpened: (editor) => `Opened the source in ${editorName(editor, "the detected editor")}.`,
2405
- editorFailed: (editor) => `Could not open ${editorName(editor, "an editor")}. Start the editor or configure editor: "cursor" / "vscode".`,
2391
+ editorOpening: "Opening source\u2026",
2392
+ editorOpened: "Source opened in the editor.",
2393
+ editorFailed: "Could not open the editor. Start it or configure editor.",
2406
2394
  completeInstructions: "Add an instruction for every target and wait for context collection to finish.",
2407
2395
  promptCopied: "Prompt copied to the clipboard.",
2408
2396
  clipboardUnavailable: "Clipboard access is unavailable. Select the prompt manually.",
@@ -2418,7 +2406,7 @@ var UI_MESSAGES = Object.freeze({
2418
2406
  brand: Object.freeze({
2419
2407
  name: "SpotPatch",
2420
2408
  context: "\u5B9E\u65F6\u4E0A\u4E0B\u6587",
2421
- repository: "GitHub",
2409
+ repository: "GitHub \u2197",
2422
2410
  repositoryTitle: "\u5728 GitHub \u4E0A Star SpotPatch"
2423
2411
  }),
2424
2412
  trigger: Object.freeze({
@@ -2472,8 +2460,8 @@ var UI_MESSAGES = Object.freeze({
2472
2460
  actions: Object.freeze({
2473
2461
  addElement: "\u6DFB\u52A0\u5143\u7D20",
2474
2462
  reselect: "\u91CD\u65B0\u5F00\u59CB",
2475
- openEditor: (editor) => editor === "auto" ? "\u6253\u5F00\u6E90\u7801" : `\u5728 ${editorName(editor, "\u7F16\u8F91\u5668")} \u4E2D\u6253\u5F00`,
2476
- openTarget: (index, editor) => `\u5728${editorName(editor, "\u81EA\u52A8\u68C0\u6D4B\u7684\u7F16\u8F91\u5668")}\u4E2D\u6253\u5F00\u76EE\u6807 ${String(index)} \u7684\u6E90\u7801`,
2463
+ openEditor: "\u6253\u5F00\u6E90\u7801",
2464
+ openTarget: (index) => `\u6253\u5F00\u76EE\u6807 ${String(index)} \u7684\u6E90\u7801`,
2477
2465
  preview: "\u9884\u89C8 Prompt",
2478
2466
  copy: "\u590D\u5236 Prompt",
2479
2467
  back: "\u8FD4\u56DE\u7F16\u8F91"
@@ -2529,9 +2517,9 @@ var UI_MESSAGES = Object.freeze({
2529
2517
  detachedTargetRemoved: "\u9875\u9762\u4E2D\u7684\u76EE\u6807\u5DF2\u5378\u8F7D\uFF0C\u5DF2\u4ECE\u5F53\u524D\u9009\u62E9\u4E2D\u79FB\u9664\u3002",
2530
2518
  contextWarning: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\uFF0C\u4F46\u5B58\u5728\u8B66\u544A\u3002",
2531
2519
  contextCollected: "\u6D4F\u89C8\u5668\u4E0A\u4E0B\u6587\u91C7\u96C6\u5B8C\u6210\u3002",
2532
- editorOpening: (editor) => `\u6B63\u5728\u6253\u5F00${editorName(editor, "\u81EA\u52A8\u68C0\u6D4B\u7684\u7F16\u8F91\u5668")}\u2026\u2026`,
2533
- editorOpened: (editor) => `\u5DF2\u5728${editorName(editor, "\u81EA\u52A8\u68C0\u6D4B\u7684\u7F16\u8F91\u5668")}\u4E2D\u6253\u5F00\u6E90\u7801\u3002`,
2534
- editorFailed: (editor) => `\u65E0\u6CD5\u6253\u5F00${editorName(editor, "\u7F16\u8F91\u5668")}\u3002\u8BF7\u5148\u542F\u52A8\u7F16\u8F91\u5668\uFF0C\u6216\u914D\u7F6E editor: "cursor" / "vscode"\u3002`,
2520
+ editorOpening: "\u6B63\u5728\u6253\u5F00\u6E90\u7801\u2026\u2026",
2521
+ editorOpened: "\u6E90\u7801\u5DF2\u5728\u7F16\u8F91\u5668\u4E2D\u6253\u5F00\u3002",
2522
+ editorFailed: "\u65E0\u6CD5\u6253\u5F00\u7F16\u8F91\u5668\u3002\u8BF7\u5148\u542F\u52A8\u7F16\u8F91\u5668\u6216\u68C0\u67E5 editor \u914D\u7F6E\u3002",
2535
2523
  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",
2536
2524
  promptCopied: "Prompt \u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002",
2537
2525
  clipboardUnavailable: "\u65E0\u6CD5\u8BBF\u95EE\u526A\u8D34\u677F\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5E76\u590D\u5236 Prompt\u3002",
@@ -2826,36 +2814,27 @@ function createStyles(document) {
2826
2814
  gap: 8px;
2827
2815
  flex: none;
2828
2816
  }
2817
+ .spotpatch-repository,
2818
+ .spotpatch-locale,
2819
+ .spotpatch-close {
2820
+ height: 30px;
2821
+ border: 1px solid rgb(255 255 255 / 11%);
2822
+ border-radius: 9px;
2823
+ background: rgb(255 255 255 / 4%);
2824
+ }
2829
2825
  .spotpatch-repository {
2830
2826
  display: inline-flex;
2831
- height: 30px;
2832
2827
  align-items: center;
2833
- gap: 5px;
2834
- border: 1px solid rgb(68 202 224 / 20%);
2835
- border-radius: 9px;
2836
2828
  padding: 0 10px;
2837
2829
  color: #bcecf2;
2838
- background: rgb(8 145 178 / 7%);
2839
2830
  font-size: 11px;
2840
2831
  font-weight: 680;
2841
2832
  text-decoration: none;
2842
- transition: border-color 150ms ease, color 150ms ease, background 150ms ease, transform 150ms ease;
2843
- }
2844
- .spotpatch-repository::after { content: "\u2197"; font-size: 10px; }
2845
- .spotpatch-repository:hover {
2846
- border-color: rgb(68 202 224 / 42%);
2847
- color: #e6fbff;
2848
- background: rgb(8 145 178 / 12%);
2849
- transform: translateY(-1px);
2850
2833
  }
2851
2834
  .spotpatch-locale {
2852
2835
  min-width: 38px;
2853
- height: 30px;
2854
- border: 1px solid rgb(255 255 255 / 11%);
2855
- border-radius: 9px;
2856
2836
  padding: 0 9px;
2857
2837
  color: #c5cad5;
2858
- background: rgb(255 255 255 / 4%);
2859
2838
  cursor: pointer;
2860
2839
  font-size: 12px;
2861
2840
  font-weight: 650;
@@ -2863,20 +2842,17 @@ function createStyles(document) {
2863
2842
  .spotpatch-close {
2864
2843
  display: inline-grid;
2865
2844
  width: 30px;
2866
- height: 30px;
2867
2845
  padding: 0;
2868
2846
  place-items: center;
2869
- border: 1px solid rgb(255 255 255 / 11%);
2870
- border-radius: 9px;
2871
2847
  color: #9da5b4;
2872
- background: rgb(255 255 255 / 4%);
2873
2848
  cursor: pointer;
2874
2849
  font-size: 17px;
2875
2850
  line-height: 1;
2876
2851
  transition: border-color 150ms ease, color 150ms ease, background 150ms ease;
2877
2852
  }
2878
2853
  .spotpatch-close:hover,
2879
- .spotpatch-locale:hover { border-color: rgb(129 112 247 / 45%); color: #fff; background: rgb(109 93 246 / 10%); }
2854
+ .spotpatch-locale:hover,
2855
+ .spotpatch-repository:hover { border-color: rgb(129 112 247 / 45%); color: #fff; background: rgb(109 93 246 / 10%); }
2880
2856
  .spotpatch-title {
2881
2857
  margin: 0;
2882
2858
  color: #fff;
@@ -2926,10 +2902,14 @@ function createStyles(document) {
2926
2902
  background: #f59e0b;
2927
2903
  content: "";
2928
2904
  }
2929
- .spotpatch-context-state[data-state="ready"] { color: #9fe3c4; }
2930
- .spotpatch-context-state[data-state="ready"]::before { background: #34d399; }
2931
- .spotpatch-context-state[data-state="warning"] { color: #fecaca; }
2932
- .spotpatch-context-state[data-state="warning"]::before { background: #fb7185; }
2905
+ .spotpatch-context-state[data-state="ready"],
2906
+ .spotpatch-editor-feedback[data-state="success"] { color: #9fe3c4; }
2907
+ .spotpatch-context-state[data-state="ready"]::before,
2908
+ .spotpatch-editor-feedback[data-state="success"]::before { background: #34d399; }
2909
+ .spotpatch-context-state[data-state="warning"],
2910
+ .spotpatch-editor-feedback[data-state="error"] { color: #fecaca; }
2911
+ .spotpatch-context-state[data-state="warning"]::before,
2912
+ .spotpatch-editor-feedback[data-state="error"]::before { background: #fb7185; }
2933
2913
  .spotpatch-body {
2934
2914
  min-height: 0;
2935
2915
  overflow: auto;
@@ -3168,29 +3148,9 @@ function createStyles(document) {
3168
3148
  background: rgb(8 12 22 / 82%);
3169
3149
  }
3170
3150
  .spotpatch-editor-feedback {
3171
- display: flex;
3172
- width: 100%;
3173
- align-items: center;
3174
- gap: 7px;
3175
- margin-bottom: 1px;
3176
- color: #9ca5b5;
3177
- font-size: 11px;
3178
- line-height: 1.45;
3179
- }
3180
- .spotpatch-editor-feedback[hidden] { display: none; }
3181
- .spotpatch-editor-feedback::before {
3182
- width: 6px;
3183
- height: 6px;
3184
- flex: none;
3185
- border-radius: 999px;
3186
- background: #94a3b8;
3187
- content: "";
3151
+ flex-basis: 100%;
3152
+ white-space: normal;
3188
3153
  }
3189
- .spotpatch-editor-feedback[data-state="opening"]::before { background: #38bdf8; }
3190
- .spotpatch-editor-feedback[data-state="success"] { color: #9fe3c4; }
3191
- .spotpatch-editor-feedback[data-state="success"]::before { background: #34d399; }
3192
- .spotpatch-editor-feedback[data-state="error"] { color: #fecaca; }
3193
- .spotpatch-editor-feedback[data-state="error"]::before { background: #fb7185; }
3194
3154
  .spotpatch-actions button {
3195
3155
  display: inline-flex;
3196
3156
  min-height: 40px;
@@ -3256,8 +3216,6 @@ function createStyles(document) {
3256
3216
  .spotpatch-actions { padding-left: 16px; padding-right: 16px; }
3257
3217
  .spotpatch-target-select { grid-template-columns: 32px minmax(0, 1fr); }
3258
3218
  .spotpatch-target-state { display: none; }
3259
- .spotpatch-repository { width: 30px; overflow: hidden; padding: 0; justify-content: center; color: transparent; }
3260
- .spotpatch-repository::after { color: #bcecf2; content: "\u2197"; }
3261
3219
  }
3262
3220
  ${AGENT_PANEL_STYLES}
3263
3221
  `;
@@ -3267,7 +3225,7 @@ function summaryLine(summary, prefix) {
3267
3225
  const line = summary.split("\n").find((candidate) => candidate.startsWith(`${prefix}: `));
3268
3226
  return line?.slice(prefix.length + 2).trim();
3269
3227
  }
3270
- function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", editorPreference = "auto") {
3228
+ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto") {
3271
3229
  const localizer = createUiLocalizer(document, localePreference);
3272
3230
  let messages = localizer.messages();
3273
3231
  const host = document.createElement("spotpatch-root");
@@ -3389,17 +3347,14 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
3389
3347
  const actions = createMarkedElement(document, "footer");
3390
3348
  actions.className = "spotpatch-actions";
3391
3349
  const editorFeedback = createMarkedElement(document, "div");
3392
- editorFeedback.className = "spotpatch-editor-feedback";
3350
+ editorFeedback.className = "spotpatch-context-state spotpatch-editor-feedback";
3393
3351
  editorFeedback.dataset.state = "idle";
3394
3352
  editorFeedback.setAttribute("role", "status");
3395
3353
  editorFeedback.setAttribute("aria-live", "polite");
3396
3354
  editorFeedback.hidden = true;
3397
3355
  const addTargetButton = createButton(document, messages.actions.addElement);
3398
3356
  const reselectButton = createButton(document, messages.actions.reselect);
3399
- const openEditorButton = createButton(
3400
- document,
3401
- messages.actions.openEditor(editorPreference)
3402
- );
3357
+ const openEditorButton = createButton(document, messages.actions.openEditor);
3403
3358
  const previewButton = createButton(
3404
3359
  document,
3405
3360
  messages.actions.preview,
@@ -3447,20 +3402,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
3447
3402
  let currentTargets = [];
3448
3403
  let currentMaximum = 0;
3449
3404
  let currentEditorFeedbackState = "idle";
3450
- function defaultEditorFeedback(state) {
3451
- if (state === "opening") {
3452
- return messages.announcements.editorOpening(editorPreference);
3453
- }
3454
- if (state === "success") {
3455
- return messages.announcements.editorOpened(editorPreference);
3456
- }
3457
- return state === "error" ? messages.announcements.editorFailed(editorPreference) : "";
3458
- }
3459
- function renderEditorStatus(state, message = defaultEditorFeedback(state)) {
3405
+ function renderEditorStatus(state) {
3460
3406
  currentEditorFeedbackState = state;
3461
3407
  editorFeedback.dataset.state = state;
3462
3408
  editorFeedback.hidden = state === "idle";
3463
- editorFeedback.textContent = message;
3409
+ editorFeedback.textContent = state === "opening" ? messages.announcements.editorOpening : state === "success" ? messages.announcements.editorOpened : state === "error" ? messages.announcements.editorFailed : "";
3464
3410
  placeDialog();
3465
3411
  }
3466
3412
  function statusText(target) {
@@ -3544,11 +3490,8 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
3544
3490
  const open = createButton(document, "\u2197", "spotpatch-target-open");
3545
3491
  open.dataset.openTargetId = target.id;
3546
3492
  open.disabled = !target.canOpenEditor;
3547
- open.setAttribute(
3548
- "aria-label",
3549
- messages.actions.openTarget(index + 1, editorPreference)
3550
- );
3551
- open.title = messages.actions.openTarget(index + 1, editorPreference);
3493
+ open.setAttribute("aria-label", messages.actions.openTarget(index + 1));
3494
+ open.title = messages.actions.openTarget(index + 1);
3552
3495
  const remove = createButton(document, "\xD7", "spotpatch-target-remove");
3553
3496
  remove.dataset.removeTargetId = target.id;
3554
3497
  remove.disabled = !editingEnabled;
@@ -3746,7 +3689,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
3746
3689
  promptOutput.setAttribute("aria-label", messages.diagnostics.promptAriaLabel);
3747
3690
  addTargetButton.textContent = messages.actions.addElement;
3748
3691
  reselectButton.textContent = messages.actions.reselect;
3749
- openEditorButton.textContent = messages.actions.openEditor(editorPreference);
3692
+ openEditorButton.textContent = messages.actions.openEditor;
3750
3693
  previewButton.textContent = messages.actions.preview;
3751
3694
  copyButton.textContent = messages.actions.copy;
3752
3695
  backButton.textContent = messages.actions.back;
@@ -4380,13 +4323,7 @@ function resolveBrowserDependencies(dependencies) {
4380
4323
  }
4381
4324
  function createController(config, dependencies = {}) {
4382
4325
  const browser = resolveBrowserDependencies(dependencies);
4383
- const view = dependencies.view ?? createRuntimeView(
4384
- browser.document,
4385
- config.shortcut,
4386
- config.ai,
4387
- config.locale,
4388
- config.editor
4389
- );
4326
+ const view = dependencies.view ?? createRuntimeView(browser.document, config.shortcut, config.ai, config.locale);
4390
4327
  const api = dependencies.api ?? createRuntimeApi({
4391
4328
  apiBase: config.apiBase,
4392
4329
  fetch: browser.window.fetch.bind(browser.window),
@@ -4925,24 +4862,18 @@ ${summary}`;
4925
4862
  const selectionRevision = sessionRevision;
4926
4863
  const requestRevision = ++editorRequestRevision;
4927
4864
  transition({ type: "OPEN_EDITOR" });
4928
- const openingMessage = view.messages().announcements.editorOpening(config.editor);
4929
- view.renderEditorStatus("opening", openingMessage);
4930
- view.announce(openingMessage);
4865
+ view.renderEditorStatus("opening");
4931
4866
  void api.openEditor({
4932
4867
  fileId: marker.fileId,
4933
4868
  line: marker.line,
4934
4869
  column: marker.column
4935
- }).then((result) => {
4870
+ }).then(() => {
4936
4871
  if (mounted && state.status === "selected" && selectionRevision === sessionRevision && requestRevision === editorRequestRevision && activeTargetId === current.id && targets.includes(current)) {
4937
- const message = view.messages().announcements.editorOpened(result.editor);
4938
- view.renderEditorStatus("success", message);
4939
- view.announce(message);
4872
+ view.renderEditorStatus("success");
4940
4873
  }
4941
4874
  }).catch(() => {
4942
4875
  if (mounted && state.status === "selected" && selectionRevision === sessionRevision && requestRevision === editorRequestRevision && activeTargetId === current.id && targets.includes(current)) {
4943
- const message = view.messages().announcements.editorFailed(config.editor);
4944
- view.renderEditorStatus("error", message);
4945
- view.announce(message);
4876
+ view.renderEditorStatus("error");
4946
4877
  }
4947
4878
  });
4948
4879
  }