@spotpatch/runtime 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1806,6 +1806,13 @@ var AGENT_PANEL_STYLES = `
1806
1806
  line-height: 1.5;
1807
1807
  }
1808
1808
  .spotpatch-consent input { width: 14px; height: 14px; flex: none; margin: 2px 0 0; accent-color: var(--spotpatch-accent); }
1809
+ .spotpatch-trusted-consent {
1810
+ border: 1px solid rgb(251 191 36 / 20%);
1811
+ border-radius: 10px;
1812
+ padding: 9px 10px;
1813
+ color: #e5e7eb;
1814
+ background: rgb(120 53 15 / 10%);
1815
+ }
1809
1816
  .spotpatch-workspace-consent {
1810
1817
  margin-top: 9px;
1811
1818
  border: 1px solid rgb(251 191 36 / 18%);
@@ -1995,16 +2002,14 @@ function createAgentPanel(document, ai, localizer) {
1995
2002
  job.append(jobMeta, phase, error, activity, resultPanel);
1996
2003
  root.append(header, setup, job);
1997
2004
  const testButton = createButton(document, messages.agent.testConnection);
1998
- const runButton = createButton(
1999
- document,
2000
- messages.agent.verifyAndRun,
2001
- "spotpatch-run"
2002
- );
2005
+ const runButton = createButton(document, messages.agent.run, "spotpatch-run");
2003
2006
  const cancelButton = createButton(document, messages.agent.cancel);
2004
2007
  const applyButton = createButton(document, messages.agent.apply, "spotpatch-primary");
2005
2008
  const revertButton = createButton(document, messages.agent.revert);
2006
2009
  const resetButton = createButton(document, messages.agent.revise);
2007
2010
  const providers = ai.enabled ? ai.providers : [];
2011
+ const trustedFastMode = ai.enabled && ai.applyMode === "trusted-auto";
2012
+ consent.classList.toggle("spotpatch-trusted-consent", trustedFastMode);
2008
2013
  const providerById = new Map(providers.map((provider) => [provider.id, provider]));
2009
2014
  let contextReady = false;
2010
2015
  let editingEnabled = true;
@@ -2029,27 +2034,34 @@ function createAgentPanel(document, ai, localizer) {
2029
2034
  providerSelect.value = ai.defaultProvider;
2030
2035
  }
2031
2036
  const selectedProvider = () => providerById.get(providerSelect.value);
2037
+ const consentMessage = (provider) => {
2038
+ if (provider === void 0) {
2039
+ return messages.agent.providerUnavailable;
2040
+ }
2041
+ return trustedFastMode ? messages.agent.trustedFastConsent(provider.label) : messages.agent.consent(provider.label);
2042
+ };
2043
+ const localChangesConsentGranted = () => trustedFastMode ? consentCheckbox.checked : workspaceConsentCheckbox.checked;
2032
2044
  const populateModels = () => {
2033
2045
  const provider = selectedProvider();
2034
2046
  modelSelect.replaceChildren();
2035
2047
  if (provider === void 0) {
2036
- consentText.textContent = messages.agent.providerUnavailable;
2048
+ consentText.textContent = consentMessage(provider);
2037
2049
  return;
2038
2050
  }
2039
2051
  for (const model of provider.models) {
2040
2052
  addOption(document, modelSelect, model.id, model.label);
2041
2053
  }
2042
2054
  modelSelect.value = provider.defaultModel;
2043
- consentText.textContent = messages.agent.consent(provider.label);
2055
+ consentText.textContent = consentMessage(provider);
2044
2056
  };
2045
2057
  const refreshActions = () => {
2046
2058
  const setupVisible = ai.enabled && selectionVisible && !jobPresented;
2047
- runButton.textContent = capabilityProbing ? messages.agent.verifying : capabilityReady ? messages.agent.run : messages.agent.verifyAndRun;
2059
+ runButton.textContent = capabilityProbing ? messages.agent.verifying : messages.agent.run;
2048
2060
  runButton.classList.toggle("spotpatch-primary", capabilityReady);
2049
2061
  testButton.hidden = !setupVisible;
2050
2062
  runButton.hidden = !setupVisible;
2051
2063
  testButton.disabled = !editingEnabled || capabilityProbing || selectedProvider() === void 0;
2052
- runButton.disabled = !editingEnabled || capabilityProbing || !contextReady || !consentCheckbox.checked || latestWorkspaceState === "idle" || latestWorkspaceState === "checking" || latestWorkspaceState === "blocked" || latestWorkspaceState === "consent-required" && !workspaceConsentCheckbox.checked || selectedProvider() === void 0 || modelSelect.value.length === 0;
2064
+ runButton.disabled = !editingEnabled || capabilityProbing || !contextReady || !consentCheckbox.checked || latestWorkspaceState === "idle" || latestWorkspaceState === "checking" || latestWorkspaceState === "blocked" || latestWorkspaceState === "consent-required" && !localChangesConsentGranted() || selectedProvider() === void 0 || modelSelect.value.length === 0;
2053
2065
  if (!jobPresented || !selectionVisible) {
2054
2066
  cancelButton.hidden = true;
2055
2067
  applyButton.hidden = true;
@@ -2149,7 +2161,7 @@ function createAgentPanel(document, ai, localizer) {
2149
2161
  function applyMessages() {
2150
2162
  messages = localizer.messages();
2151
2163
  title.textContent = messages.agent.title;
2152
- badge.textContent = ai.enabled && ai.applyMode === "auto" ? messages.agent.autoGated : messages.agent.review;
2164
+ badge.textContent = trustedFastMode ? messages.agent.trustedFast : ai.enabled && ai.applyMode === "auto" ? messages.agent.autoGated : messages.agent.review;
2153
2165
  providerText.textContent = messages.agent.provider;
2154
2166
  modelText.textContent = messages.agent.model;
2155
2167
  providerSelect.setAttribute("aria-label", messages.agent.providerAriaLabel);
@@ -2162,7 +2174,7 @@ function createAgentPanel(document, ai, localizer) {
2162
2174
  revertButton.textContent = messages.agent.revert;
2163
2175
  resetButton.textContent = messages.agent.revise;
2164
2176
  const provider = selectedProvider();
2165
- consentText.textContent = provider === void 0 ? messages.agent.providerUnavailable : messages.agent.consent(provider.label);
2177
+ consentText.textContent = consentMessage(provider);
2166
2178
  if (latestCapabilityState === "idle") {
2167
2179
  capability.textContent = messages.agent.connectionNotTested;
2168
2180
  } else if (latestCapabilityState === "probing") {
@@ -2198,7 +2210,7 @@ function createAgentPanel(document, ai, localizer) {
2198
2210
  return consentCheckbox.checked;
2199
2211
  },
2200
2212
  workspaceConsentGranted() {
2201
- return workspaceConsentCheckbox.checked;
2213
+ return localChangesConsentGranted();
2202
2214
  },
2203
2215
  readSelection() {
2204
2216
  const provider = selectedProvider();
@@ -2226,7 +2238,7 @@ function createAgentPanel(document, ai, localizer) {
2226
2238
  latestWorkspaceErrorCode = errorCode ?? snapshot?.errorCode;
2227
2239
  workspace.dataset.state = state;
2228
2240
  if (state !== "checking") {
2229
- workspaceConsent.hidden = state !== "consent-required";
2241
+ workspaceConsent.hidden = trustedFastMode || state !== "consent-required";
2230
2242
  }
2231
2243
  if (state === "idle" || state === "ready" || state === "blocked") {
2232
2244
  workspaceConsentCheckbox.checked = false;
@@ -2496,7 +2508,7 @@ var ERROR_MESSAGES_EN = Object.freeze({
2496
2508
  [ERROR_CODES2.PROVIDER_AUTH_FAILED]: "The provider rejected authentication. Check the server-side Key.",
2497
2509
  [ERROR_CODES2.PROVIDER_PROTOCOL_UNSUPPORTED]: "The relay does not match the configured OpenAI-compatible protocol.",
2498
2510
  [ERROR_CODES2.MODEL_NOT_ALLOWED]: "The selected model profile is not allowed.",
2499
- [ERROR_CODES2.MODEL_TOOL_CALL_UNSUPPORTED]: "The selected model did not complete the required tool-call probe.",
2511
+ [ERROR_CODES2.MODEL_TOOL_CALL_UNSUPPORTED]: "The selected model did not start or continue the required tool call.",
2500
2512
  [ERROR_CODES2.PROVIDER_RATE_LIMITED]: "The provider is rate limited. Wait and try again.",
2501
2513
  [ERROR_CODES2.AGENT_BUSY]: "Another write Agent job is still active.",
2502
2514
  [ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "The Agent stopped at a configured time, turn, output, or size limit.",
@@ -2531,7 +2543,7 @@ var ERROR_MESSAGES_ZH = Object.freeze({
2531
2543
  [ERROR_CODES2.PROVIDER_AUTH_FAILED]: "\u6A21\u578B\u670D\u52A1\u9274\u6743\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u7AEF Key\u3002",
2532
2544
  [ERROR_CODES2.PROVIDER_PROTOCOL_UNSUPPORTED]: "\u4E2D\u8F6C\u670D\u52A1\u4E0E\u914D\u7F6E\u7684 OpenAI \u517C\u5BB9\u534F\u8BAE\u4E0D\u4E00\u81F4\u3002",
2533
2545
  [ERROR_CODES2.MODEL_NOT_ALLOWED]: "\u5F53\u524D\u6A21\u578B\u914D\u7F6E\u672A\u83B7\u6388\u6743\u3002",
2534
- [ERROR_CODES2.MODEL_TOOL_CALL_UNSUPPORTED]: "\u5F53\u524D\u6A21\u578B\u672A\u901A\u8FC7\u5FC5\u8981\u7684\u5DE5\u5177\u8C03\u7528\u80FD\u529B\u63A2\u6D4B\u3002",
2546
+ [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",
2535
2547
  [ERROR_CODES2.PROVIDER_RATE_LIMITED]: "\u6A21\u578B\u670D\u52A1\u6B63\u5728\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
2536
2548
  [ERROR_CODES2.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
2537
2549
  [ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
@@ -2705,13 +2717,15 @@ var UI_MESSAGES = Object.freeze({
2705
2717
  title: "AI code agent",
2706
2718
  review: "Review",
2707
2719
  autoGated: "Auto gated",
2720
+ trustedFast: "Trusted fast",
2708
2721
  provider: "Provider",
2709
2722
  model: "Model",
2710
2723
  providerAriaLabel: "AI provider",
2711
2724
  modelAriaLabel: "AI model",
2712
2725
  providerUnavailable: "Provider configuration is unavailable.",
2713
2726
  consent: (provider) => `I understand selected context and allowed source may be sent to ${provider}; its data policy is my responsibility.`,
2714
- connectionNotTested: "Connection not tested",
2727
+ trustedFastConsent: (provider) => `Enable trusted fast mode for ${provider}: send allowed project context, include current local changes, and directly apply AI changes after required checks, including file deletions and configuration changes.`,
2728
+ connectionNotTested: "Optional connection check not run",
2715
2729
  workspaceNotChecked: "Local workspace not checked",
2716
2730
  checkingWorkspace: "Checking Git workspace and isolated execution\u2026",
2717
2731
  workspaceReady: "Local workspace is ready for isolated execution",
@@ -2728,7 +2742,6 @@ var UI_MESSAGES = Object.freeze({
2728
2742
  consentRequired: "Confirm remote provider data transmission before running AI.",
2729
2743
  toolsReady: "tools and streaming ready",
2730
2744
  testConnection: "Check environment",
2731
- verifyAndRun: "Verify & run",
2732
2745
  verifying: "Verifying\u2026",
2733
2746
  run: "Run AI",
2734
2747
  cancel: "Cancel agent",
@@ -2841,13 +2854,15 @@ var UI_MESSAGES = Object.freeze({
2841
2854
  title: "AI \u4EE3\u7801 Agent",
2842
2855
  review: "\u5BA1\u9605\u6A21\u5F0F",
2843
2856
  autoGated: "\u53D7\u63A7\u81EA\u52A8\u6A21\u5F0F",
2857
+ trustedFast: "\u53EF\u4FE1\u5FEB\u901F\u6A21\u5F0F",
2844
2858
  provider: "\u6A21\u578B\u670D\u52A1",
2845
2859
  model: "\u6A21\u578B",
2846
2860
  providerAriaLabel: "AI \u6A21\u578B\u670D\u52A1",
2847
2861
  modelAriaLabel: "AI \u6A21\u578B",
2848
2862
  providerUnavailable: "\u6A21\u578B\u670D\u52A1\u914D\u7F6E\u4E0D\u53EF\u7528\u3002",
2849
2863
  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`,
2850
- connectionNotTested: "\u5C1A\u672A\u6D4B\u8BD5\u8FDE\u63A5",
2864
+ trustedFastConsent: (provider) => `\u4E3A ${provider} \u542F\u7528\u53EF\u4FE1\u5FEB\u901F\u6A21\u5F0F\uFF1A\u53D1\u9001\u83B7\u51C6\u7684\u9879\u76EE\u4E0A\u4E0B\u6587\u3001\u7EB3\u5165\u5F53\u524D\u672C\u5730\u4FEE\u6539\uFF0C\u5E76\u5728\u5FC5\u9700\u68C0\u67E5\u901A\u8FC7\u540E\u76F4\u63A5\u5E94\u7528 AI \u53D8\u66F4\uFF0C\u5305\u62EC\u5220\u9664\u6587\u4EF6\u4E0E\u914D\u7F6E\u53D8\u66F4\u3002`,
2865
+ connectionNotTested: "\u5C1A\u672A\u6267\u884C\u53EF\u9009\u8FDE\u63A5\u68C0\u67E5",
2851
2866
  workspaceNotChecked: "\u5C1A\u672A\u68C0\u67E5\u672C\u5730\u5DE5\u4F5C\u533A",
2852
2867
  checkingWorkspace: "\u6B63\u5728\u68C0\u67E5 Git \u5DE5\u4F5C\u533A\u4E0E\u9694\u79BB\u6267\u884C\u73AF\u5883\u2026\u2026",
2853
2868
  workspaceReady: "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u6EE1\u8DB3\u9694\u79BB\u6267\u884C\u6761\u4EF6",
@@ -2864,7 +2879,6 @@ var UI_MESSAGES = Object.freeze({
2864
2879
  consentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u5148\u786E\u8BA4\u5141\u8BB8\u5411\u8FDC\u7A0B\u6A21\u578B\u670D\u52A1\u4F20\u8F93\u6570\u636E\u3002",
2865
2880
  toolsReady: "\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u5DF2\u5C31\u7EEA",
2866
2881
  testConnection: "\u68C0\u67E5\u8FD0\u884C\u73AF\u5883",
2867
- verifyAndRun: "\u9A8C\u8BC1\u5E76\u8FD0\u884C",
2868
2882
  verifying: "\u9A8C\u8BC1\u4E2D\u2026\u2026",
2869
2883
  run: "\u8FD0\u884C AI",
2870
2884
  cancel: "\u53D6\u6D88 Agent",
@@ -4694,6 +4708,7 @@ function createAgentWorkflow(options) {
4694
4708
  if (!options.ai.enabled || snapshot !== void 0) {
4695
4709
  return;
4696
4710
  }
4711
+ const trustedFastMode = options.ai.applyMode === "trusted-auto";
4697
4712
  const selection = selectedProfiles();
4698
4713
  const annotation = options.getAnnotation();
4699
4714
  if (selection === void 0 || annotation === void 0) {
@@ -4709,10 +4724,7 @@ function createAgentWorkflow(options) {
4709
4724
  providerConsents.add(selection.providerProfileId);
4710
4725
  const workflowRevision = ++revision;
4711
4726
  options.view.setAgentEditingEnabled(false);
4712
- void Promise.all([
4713
- probe(workflowRevision),
4714
- refreshWorkspaceHealth(workflowRevision)
4715
- ]).then(async ([, health]) => {
4727
+ void refreshWorkspaceHealth(workflowRevision).then(async (health) => {
4716
4728
  if (workflowRevision !== revision) {
4717
4729
  return;
4718
4730
  }
@@ -4729,6 +4741,7 @@ function createAgentWorkflow(options) {
4729
4741
  providerProfileId: selection.providerProfileId,
4730
4742
  modelProfileId: selection.modelProfileId,
4731
4743
  providerDataConsent: true,
4744
+ ...trustedFastMode ? { trustedFastModeConsent: true } : {},
4732
4745
  workingTreeMode: health.state === "consent-required" ? "include-local-changes" : "require-clean"
4733
4746
  });
4734
4747
  if (workflowRevision !== revision) {