@spotpatch/runtime 1.1.1 → 1.2.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.cjs +281 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +282 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -86,6 +86,7 @@ import {
|
|
|
86
86
|
AGENT_CHECK_STATUSES,
|
|
87
87
|
AGENT_FILE_CHANGE_KINDS,
|
|
88
88
|
AGENT_JOB_STATUSES,
|
|
89
|
+
AGENT_WORKSPACE_STATES,
|
|
89
90
|
ERROR_CODES
|
|
90
91
|
} from "@spotpatch/shared";
|
|
91
92
|
var ERROR_CODE_VALUES = new Set(Object.values(ERROR_CODES));
|
|
@@ -93,6 +94,7 @@ var CAPABILITY_STATE_VALUES = new Set(AGENT_CAPABILITY_STATES);
|
|
|
93
94
|
var CHECK_STATUS_VALUES = new Set(AGENT_CHECK_STATUSES);
|
|
94
95
|
var FILE_CHANGE_KIND_VALUES = new Set(AGENT_FILE_CHANGE_KINDS);
|
|
95
96
|
var JOB_STATUS_VALUES = new Set(AGENT_JOB_STATUSES);
|
|
97
|
+
var WORKSPACE_STATE_VALUES = new Set(AGENT_WORKSPACE_STATES);
|
|
96
98
|
var PROFILE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
97
99
|
var JOB_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
98
100
|
var ISO_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/;
|
|
@@ -146,6 +148,35 @@ function isAgentCapabilitySnapshot(value) {
|
|
|
146
148
|
}
|
|
147
149
|
return isProfileId(value.providerProfileId) && isBoundedString(value.providerLabel, 100) && isProfileId(value.modelProfileId) && isBoundedString(value.modelLabel, 100) && (value.protocol === "responses" || value.protocol === "chat-completions") && typeof value.state === "string" && CAPABILITY_STATE_VALUES.has(value.state) && typeof value.authenticated === "boolean" && typeof value.modelAvailable === "boolean" && typeof value.toolCalling === "boolean" && typeof value.toolResultContinuation === "boolean" && typeof value.streaming === "boolean" && (value.checkedAt === void 0 || isIsoTimestamp(value.checkedAt)) && (value.errorCode === void 0 || isAgentErrorCode(value.errorCode));
|
|
148
150
|
}
|
|
151
|
+
function isAgentWorkspaceHealthSnapshot(value) {
|
|
152
|
+
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
153
|
+
"state",
|
|
154
|
+
"checkedAt",
|
|
155
|
+
"changes",
|
|
156
|
+
"canIncludeLocalChanges",
|
|
157
|
+
"errorCode"
|
|
158
|
+
]) || typeof value.state !== "string" || !WORKSPACE_STATE_VALUES.has(value.state) || !isIsoTimestamp(value.checkedAt) || typeof value.canIncludeLocalChanges !== "boolean" || value.errorCode !== void 0 && !isAgentErrorCode(value.errorCode) || !isRecord(value.changes) || !hasOnlyKeys(value.changes, [
|
|
159
|
+
"staged",
|
|
160
|
+
"unstaged",
|
|
161
|
+
"untracked",
|
|
162
|
+
"conflicted",
|
|
163
|
+
"total"
|
|
164
|
+
])) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
const changes = value.changes;
|
|
168
|
+
const { staged, unstaged, untracked, conflicted, total } = changes;
|
|
169
|
+
if (!isNonnegativeInteger(staged) || !isNonnegativeInteger(unstaged) || !isNonnegativeInteger(untracked) || !isNonnegativeInteger(conflicted) || !isNonnegativeInteger(total) || total < staged || total < unstaged || total < untracked || total < conflicted || total > staged + unstaged + untracked) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (value.state === "ready") {
|
|
173
|
+
return total === 0 && !value.canIncludeLocalChanges && value.errorCode === void 0;
|
|
174
|
+
}
|
|
175
|
+
if (value.state === "consent-required") {
|
|
176
|
+
return total > 0 && conflicted === 0 && value.canIncludeLocalChanges && value.errorCode === void 0;
|
|
177
|
+
}
|
|
178
|
+
return !value.canIncludeLocalChanges && value.errorCode !== void 0;
|
|
179
|
+
}
|
|
149
180
|
function isAgentJobSnapshot(value) {
|
|
150
181
|
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
151
182
|
"jobId",
|
|
@@ -486,6 +517,17 @@ function createRuntimeApi(options) {
|
|
|
486
517
|
request
|
|
487
518
|
);
|
|
488
519
|
},
|
|
520
|
+
async agentWorkspaceHealth() {
|
|
521
|
+
const data = await requestJson(
|
|
522
|
+
SPOTPATCH_ENDPOINTS.agentWorkspaceHealth,
|
|
523
|
+
"POST",
|
|
524
|
+
emptyAction
|
|
525
|
+
);
|
|
526
|
+
if (!isAgentWorkspaceHealthSnapshot(data)) {
|
|
527
|
+
throw new RuntimeApiError();
|
|
528
|
+
}
|
|
529
|
+
return deepFreeze(data);
|
|
530
|
+
},
|
|
489
531
|
async createAgentJob(request) {
|
|
490
532
|
const serverRequest = omitBrowserCodeContext(request);
|
|
491
533
|
return parseJobSnapshot(
|
|
@@ -1563,12 +1605,64 @@ var AGENT_PANEL_STYLES = `
|
|
|
1563
1605
|
min-height: 46px;
|
|
1564
1606
|
margin-top: 7px;
|
|
1565
1607
|
border: 1px solid var(--spotpatch-border);
|
|
1566
|
-
border-radius:
|
|
1567
|
-
padding:
|
|
1608
|
+
border-radius: 12px;
|
|
1609
|
+
padding: 10px 38px 10px 13px;
|
|
1568
1610
|
color: #e8ebf2;
|
|
1569
|
-
|
|
1611
|
+
color-scheme: dark;
|
|
1612
|
+
background: linear-gradient(180deg, rgb(255 255 255 / 4%), rgb(255 255 255 / 2%));
|
|
1570
1613
|
font-size: 15px;
|
|
1614
|
+
font-weight: 560;
|
|
1615
|
+
line-height: 1.35;
|
|
1571
1616
|
outline: none;
|
|
1617
|
+
transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
|
|
1618
|
+
}
|
|
1619
|
+
.spotpatch-agent select:hover { border-color: rgb(148 163 184 / 38%); background-color: rgb(255 255 255 / 5%); }
|
|
1620
|
+
.spotpatch-agent select:focus-visible { border-color: rgb(139 124 247 / 76%); box-shadow: 0 0 0 3px rgb(109 93 246 / 18%); }
|
|
1621
|
+
.spotpatch-agent select option { min-height: 42px; color: #e8ebf2; background: #10151e; }
|
|
1622
|
+
@supports (appearance: base-select) {
|
|
1623
|
+
.spotpatch-agent select,
|
|
1624
|
+
::picker(select) { appearance: base-select; }
|
|
1625
|
+
.spotpatch-agent select { padding: 10px 13px; }
|
|
1626
|
+
.spotpatch-agent select::picker-icon {
|
|
1627
|
+
color: #9da6b5;
|
|
1628
|
+
transition: rotate 180ms cubic-bezier(.2, .8, .2, 1), color 160ms ease;
|
|
1629
|
+
}
|
|
1630
|
+
.spotpatch-agent select:open::picker-icon { rotate: 180deg; color: #c4b5fd; }
|
|
1631
|
+
.spotpatch-agent select::picker(select) {
|
|
1632
|
+
top: calc(anchor(bottom) + 7px);
|
|
1633
|
+
left: anchor(left);
|
|
1634
|
+
width: anchor-size(width);
|
|
1635
|
+
max-height: min(280px, 40vh);
|
|
1636
|
+
margin: 0;
|
|
1637
|
+
overflow: hidden;
|
|
1638
|
+
border: 1px solid rgb(139 124 247 / 28%);
|
|
1639
|
+
border-radius: 12px;
|
|
1640
|
+
padding: 6px;
|
|
1641
|
+
color: #e8ebf2;
|
|
1642
|
+
background: #10151e;
|
|
1643
|
+
box-shadow: 0 18px 50px rgb(0 0 0 / 38%), 0 0 0 1px rgb(255 255 255 / 3%);
|
|
1644
|
+
opacity: 0;
|
|
1645
|
+
transform: translateY(-5px) scale(.985);
|
|
1646
|
+
transform-origin: top center;
|
|
1647
|
+
transition: opacity 150ms ease, transform 180ms cubic-bezier(.2, .8, .2, 1), overlay 180ms allow-discrete, display 180ms allow-discrete;
|
|
1648
|
+
}
|
|
1649
|
+
::picker(select):popover-open { opacity: 1; transform: translateY(0) scale(1); }
|
|
1650
|
+
@starting-style {
|
|
1651
|
+
::picker(select):popover-open { opacity: 0; transform: translateY(-5px) scale(.985); }
|
|
1652
|
+
}
|
|
1653
|
+
.spotpatch-agent select option {
|
|
1654
|
+
min-height: 42px;
|
|
1655
|
+
border-radius: 8px;
|
|
1656
|
+
padding: 10px 12px;
|
|
1657
|
+
color: #dfe4ee;
|
|
1658
|
+
background: transparent;
|
|
1659
|
+
cursor: pointer;
|
|
1660
|
+
transition: color 120ms ease, background-color 120ms ease;
|
|
1661
|
+
}
|
|
1662
|
+
.spotpatch-agent select option:hover,
|
|
1663
|
+
.spotpatch-agent select option:focus { color: #fff; background: rgb(109 93 246 / 16%); }
|
|
1664
|
+
.spotpatch-agent select option:checked { color: #fff; background: rgb(109 93 246 / 24%); }
|
|
1665
|
+
.spotpatch-agent select option::checkmark { color: #8b7cf7; }
|
|
1572
1666
|
}
|
|
1573
1667
|
.spotpatch-agent select:focus-visible,
|
|
1574
1668
|
.spotpatch-consent input:focus-visible {
|
|
@@ -1586,11 +1680,22 @@ var AGENT_PANEL_STYLES = `
|
|
|
1586
1680
|
line-height: 1.6;
|
|
1587
1681
|
}
|
|
1588
1682
|
.spotpatch-consent input { width: 16px; height: 16px; flex: none; margin: 3px 0 0; accent-color: var(--spotpatch-accent); }
|
|
1683
|
+
.spotpatch-workspace-consent {
|
|
1684
|
+
margin-top: 12px;
|
|
1685
|
+
border: 1px solid rgb(251 191 36 / 18%);
|
|
1686
|
+
border-radius: 10px;
|
|
1687
|
+
padding: 11px 12px;
|
|
1688
|
+
background: rgb(120 53 15 / 9%);
|
|
1689
|
+
}
|
|
1690
|
+
.spotpatch-workspace-consent strong { display: block; color: #fde68a; font-size: 13px; font-weight: 620; }
|
|
1691
|
+
.spotpatch-workspace-consent small { display: block; margin-top: 2px; color: #aeb6c4; font-size: 12px; line-height: 1.5; }
|
|
1692
|
+
.spotpatch-agent-health-list { display: grid; gap: 8px; margin-top: 14px; }
|
|
1693
|
+
.spotpatch-agent-workspace,
|
|
1589
1694
|
.spotpatch-agent-capability {
|
|
1590
1695
|
display: flex;
|
|
1591
1696
|
align-items: center;
|
|
1592
1697
|
gap: 8px;
|
|
1593
|
-
margin:
|
|
1698
|
+
margin: 0;
|
|
1594
1699
|
color: #929bab;
|
|
1595
1700
|
font-size: 13px;
|
|
1596
1701
|
}
|
|
@@ -1607,6 +1712,21 @@ var AGENT_PANEL_STYLES = `
|
|
|
1607
1712
|
.spotpatch-agent-capability[data-state="ready"]::before { background: var(--spotpatch-success); }
|
|
1608
1713
|
.spotpatch-agent-capability[data-state="error"] { color: #fecaca; }
|
|
1609
1714
|
.spotpatch-agent-capability[data-state="error"]::before { background: var(--spotpatch-danger); }
|
|
1715
|
+
.spotpatch-agent-workspace::before {
|
|
1716
|
+
width: 6px;
|
|
1717
|
+
height: 6px;
|
|
1718
|
+
flex: none;
|
|
1719
|
+
border-radius: 999px;
|
|
1720
|
+
background: #64748b;
|
|
1721
|
+
content: "";
|
|
1722
|
+
}
|
|
1723
|
+
.spotpatch-agent-workspace[data-state="checking"]::before { background: var(--spotpatch-warning); }
|
|
1724
|
+
.spotpatch-agent-workspace[data-state="ready"] { color: #a7f3d0; }
|
|
1725
|
+
.spotpatch-agent-workspace[data-state="ready"]::before { background: var(--spotpatch-success); }
|
|
1726
|
+
.spotpatch-agent-workspace[data-state="consent-required"] { color: #fde68a; }
|
|
1727
|
+
.spotpatch-agent-workspace[data-state="consent-required"]::before { background: #fbbf24; }
|
|
1728
|
+
.spotpatch-agent-workspace[data-state="blocked"] { color: #fecaca; }
|
|
1729
|
+
.spotpatch-agent-workspace[data-state="blocked"]::before { background: var(--spotpatch-danger); }
|
|
1610
1730
|
.spotpatch-agent-job { padding: 16px; }
|
|
1611
1731
|
.spotpatch-agent-job-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
|
|
1612
1732
|
.spotpatch-agent-model { min-width: 0; overflow: hidden; color: #d6dafe; font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -1695,10 +1815,26 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1695
1815
|
consentCheckbox.type = "checkbox";
|
|
1696
1816
|
const consentText = createMarkedElement(document, "span");
|
|
1697
1817
|
consent.append(consentCheckbox, consentText);
|
|
1818
|
+
const workspaceConsent = createMarkedElement(document, "label");
|
|
1819
|
+
workspaceConsent.className = "spotpatch-consent spotpatch-workspace-consent";
|
|
1820
|
+
workspaceConsent.hidden = true;
|
|
1821
|
+
const workspaceConsentCheckbox = createMarkedElement(document, "input");
|
|
1822
|
+
workspaceConsentCheckbox.type = "checkbox";
|
|
1823
|
+
const workspaceConsentContent = createMarkedElement(document, "span");
|
|
1824
|
+
const workspaceConsentTitle = createMarkedElement(document, "strong");
|
|
1825
|
+
const workspaceConsentHelp = createMarkedElement(document, "small");
|
|
1826
|
+
workspaceConsentContent.append(workspaceConsentTitle, workspaceConsentHelp);
|
|
1827
|
+
workspaceConsent.append(workspaceConsentCheckbox, workspaceConsentContent);
|
|
1828
|
+
const healthList = createMarkedElement(document, "div");
|
|
1829
|
+
healthList.className = "spotpatch-agent-health-list";
|
|
1830
|
+
const workspace = createMarkedElement(document, "p");
|
|
1831
|
+
workspace.className = "spotpatch-agent-workspace";
|
|
1832
|
+
workspace.dataset.state = "idle";
|
|
1698
1833
|
const capability = createMarkedElement(document, "p");
|
|
1699
1834
|
capability.className = "spotpatch-agent-capability";
|
|
1700
1835
|
capability.dataset.state = "idle";
|
|
1701
|
-
|
|
1836
|
+
healthList.append(workspace, capability);
|
|
1837
|
+
setup.append(selectors, consent, workspaceConsent, healthList);
|
|
1702
1838
|
const job = createMarkedElement(document, "div");
|
|
1703
1839
|
job.className = "spotpatch-agent-job";
|
|
1704
1840
|
job.hidden = true;
|
|
@@ -1757,6 +1893,9 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1757
1893
|
let latestCapabilityState = "idle";
|
|
1758
1894
|
let latestCapabilityMessage = messages.agent.connectionNotTested;
|
|
1759
1895
|
let latestCapabilityErrorCode;
|
|
1896
|
+
let latestWorkspaceState = "idle";
|
|
1897
|
+
let latestWorkspaceSnapshot;
|
|
1898
|
+
let latestWorkspaceErrorCode;
|
|
1760
1899
|
for (const provider of providers) {
|
|
1761
1900
|
addOption(document, providerSelect, provider.id, provider.label);
|
|
1762
1901
|
}
|
|
@@ -1784,7 +1923,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1784
1923
|
testButton.hidden = !setupVisible;
|
|
1785
1924
|
runButton.hidden = !setupVisible;
|
|
1786
1925
|
testButton.disabled = !editingEnabled || capabilityProbing || selectedProvider() === void 0;
|
|
1787
|
-
runButton.disabled = !editingEnabled || capabilityProbing || !contextReady || !consentCheckbox.checked || selectedProvider() === void 0 || modelSelect.value.length === 0;
|
|
1926
|
+
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;
|
|
1788
1927
|
if (!jobPresented || !selectionVisible) {
|
|
1789
1928
|
cancelButton.hidden = true;
|
|
1790
1929
|
applyButton.hidden = true;
|
|
@@ -1792,8 +1931,25 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1792
1931
|
resetButton.hidden = true;
|
|
1793
1932
|
}
|
|
1794
1933
|
};
|
|
1795
|
-
|
|
1796
|
-
|
|
1934
|
+
const renderWorkspaceMessage = () => {
|
|
1935
|
+
if (latestWorkspaceState === "idle") {
|
|
1936
|
+
workspace.textContent = messages.agent.workspaceNotChecked;
|
|
1937
|
+
} else if (latestWorkspaceState === "checking") {
|
|
1938
|
+
workspace.textContent = messages.agent.checkingWorkspace;
|
|
1939
|
+
} else if (latestWorkspaceState === "ready") {
|
|
1940
|
+
workspace.textContent = messages.agent.workspaceReady;
|
|
1941
|
+
} else if (latestWorkspaceState === "consent-required") {
|
|
1942
|
+
const changes = latestWorkspaceSnapshot?.changes;
|
|
1943
|
+
workspace.textContent = messages.agent.workspaceDirty(
|
|
1944
|
+
changes?.staged ?? 0,
|
|
1945
|
+
changes?.unstaged ?? 0,
|
|
1946
|
+
changes?.untracked ?? 0
|
|
1947
|
+
);
|
|
1948
|
+
} else {
|
|
1949
|
+
workspace.textContent = latestWorkspaceErrorCode === void 0 ? messages.errors.INTERNAL_ERROR : messages.errors[latestWorkspaceErrorCode];
|
|
1950
|
+
}
|
|
1951
|
+
};
|
|
1952
|
+
function handleProviderChange() {
|
|
1797
1953
|
populateModels();
|
|
1798
1954
|
consentCheckbox.checked = false;
|
|
1799
1955
|
capability.dataset.state = "idle";
|
|
@@ -1803,8 +1959,8 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1803
1959
|
latestCapabilityErrorCode = void 0;
|
|
1804
1960
|
capabilityReady = false;
|
|
1805
1961
|
refreshActions();
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1962
|
+
}
|
|
1963
|
+
function handleModelChange() {
|
|
1808
1964
|
capability.dataset.state = "idle";
|
|
1809
1965
|
capability.textContent = messages.agent.connectionNotTested;
|
|
1810
1966
|
latestCapabilityState = "idle";
|
|
@@ -1812,8 +1968,12 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1812
1968
|
latestCapabilityErrorCode = void 0;
|
|
1813
1969
|
capabilityReady = false;
|
|
1814
1970
|
refreshActions();
|
|
1815
|
-
}
|
|
1971
|
+
}
|
|
1972
|
+
populateModels();
|
|
1973
|
+
providerSelect.addEventListener("change", handleProviderChange);
|
|
1974
|
+
modelSelect.addEventListener("change", handleModelChange);
|
|
1816
1975
|
consentCheckbox.addEventListener("change", refreshActions);
|
|
1976
|
+
workspaceConsentCheckbox.addEventListener("change", refreshActions);
|
|
1817
1977
|
function renderCurrentJob() {
|
|
1818
1978
|
if (latestSnapshot === void 0) {
|
|
1819
1979
|
return;
|
|
@@ -1868,6 +2028,8 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1868
2028
|
modelText.textContent = messages.agent.model;
|
|
1869
2029
|
providerSelect.setAttribute("aria-label", messages.agent.providerAriaLabel);
|
|
1870
2030
|
modelSelect.setAttribute("aria-label", messages.agent.modelAriaLabel);
|
|
2031
|
+
workspaceConsentTitle.textContent = messages.agent.includeLocalChanges;
|
|
2032
|
+
workspaceConsentHelp.textContent = messages.agent.includeLocalChangesHelp;
|
|
1871
2033
|
diff.setAttribute("aria-label", messages.agent.diffAriaLabel);
|
|
1872
2034
|
testButton.textContent = messages.agent.testConnection;
|
|
1873
2035
|
applyButton.textContent = messages.agent.apply;
|
|
@@ -1888,6 +2050,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1888
2050
|
} else {
|
|
1889
2051
|
capability.textContent = latestCapabilityMessage;
|
|
1890
2052
|
}
|
|
2053
|
+
renderWorkspaceMessage();
|
|
1891
2054
|
refreshActions();
|
|
1892
2055
|
renderCurrentJob();
|
|
1893
2056
|
}
|
|
@@ -1898,6 +2061,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1898
2061
|
providerSelect,
|
|
1899
2062
|
modelSelect,
|
|
1900
2063
|
consentCheckbox,
|
|
2064
|
+
workspaceConsentCheckbox,
|
|
1901
2065
|
testButton,
|
|
1902
2066
|
runButton,
|
|
1903
2067
|
cancelButton,
|
|
@@ -1907,6 +2071,9 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1907
2071
|
consentGranted() {
|
|
1908
2072
|
return consentCheckbox.checked;
|
|
1909
2073
|
},
|
|
2074
|
+
workspaceConsentGranted() {
|
|
2075
|
+
return workspaceConsentCheckbox.checked;
|
|
2076
|
+
},
|
|
1910
2077
|
readSelection() {
|
|
1911
2078
|
const provider = selectedProvider();
|
|
1912
2079
|
const model = provider?.models.find(
|
|
@@ -1927,6 +2094,20 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1927
2094
|
capability.textContent = capabilitySnapshot?.state === "agent-ready" ? `${message} \xB7 ${messages.agent.toolsReady}` : message;
|
|
1928
2095
|
refreshActions();
|
|
1929
2096
|
},
|
|
2097
|
+
renderWorkspaceHealth(state, snapshot, errorCode) {
|
|
2098
|
+
latestWorkspaceState = state;
|
|
2099
|
+
latestWorkspaceSnapshot = snapshot;
|
|
2100
|
+
latestWorkspaceErrorCode = errorCode ?? snapshot?.errorCode;
|
|
2101
|
+
workspace.dataset.state = state;
|
|
2102
|
+
if (state !== "checking") {
|
|
2103
|
+
workspaceConsent.hidden = state !== "consent-required";
|
|
2104
|
+
}
|
|
2105
|
+
if (state === "idle" || state === "ready" || state === "blocked") {
|
|
2106
|
+
workspaceConsentCheckbox.checked = false;
|
|
2107
|
+
}
|
|
2108
|
+
renderWorkspaceMessage();
|
|
2109
|
+
refreshActions();
|
|
2110
|
+
},
|
|
1930
2111
|
renderJob(snapshot, result, activities, errorCode) {
|
|
1931
2112
|
jobPresented = true;
|
|
1932
2113
|
setup.hidden = true;
|
|
@@ -1934,6 +2115,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1934
2115
|
providerSelect.disabled = true;
|
|
1935
2116
|
modelSelect.disabled = true;
|
|
1936
2117
|
consentCheckbox.disabled = true;
|
|
2118
|
+
workspaceConsentCheckbox.disabled = true;
|
|
1937
2119
|
latestSnapshot = snapshot;
|
|
1938
2120
|
latestResult = result;
|
|
1939
2121
|
latestActivities = activities;
|
|
@@ -1951,6 +2133,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1951
2133
|
providerSelect.disabled = false;
|
|
1952
2134
|
modelSelect.disabled = false;
|
|
1953
2135
|
consentCheckbox.disabled = false;
|
|
2136
|
+
workspaceConsentCheckbox.disabled = false;
|
|
1954
2137
|
activity.replaceChildren();
|
|
1955
2138
|
files.replaceChildren();
|
|
1956
2139
|
checks.replaceChildren();
|
|
@@ -1968,6 +2151,7 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1968
2151
|
providerSelect.disabled = !enabled || jobPresented;
|
|
1969
2152
|
modelSelect.disabled = !enabled || jobPresented;
|
|
1970
2153
|
consentCheckbox.disabled = !enabled || jobPresented;
|
|
2154
|
+
workspaceConsentCheckbox.disabled = !enabled || jobPresented;
|
|
1971
2155
|
refreshActions();
|
|
1972
2156
|
},
|
|
1973
2157
|
setProviderConsent(granted) {
|
|
@@ -1986,6 +2170,10 @@ function createAgentPanel(document, ai, localizer) {
|
|
|
1986
2170
|
},
|
|
1987
2171
|
dispose() {
|
|
1988
2172
|
unsubscribeLocale();
|
|
2173
|
+
providerSelect.removeEventListener("change", handleProviderChange);
|
|
2174
|
+
modelSelect.removeEventListener("change", handleModelChange);
|
|
2175
|
+
consentCheckbox.removeEventListener("change", refreshActions);
|
|
2176
|
+
workspaceConsentCheckbox.removeEventListener("change", refreshActions);
|
|
1989
2177
|
}
|
|
1990
2178
|
});
|
|
1991
2179
|
}
|
|
@@ -2155,8 +2343,16 @@ var ERROR_MESSAGES_EN = Object.freeze({
|
|
|
2155
2343
|
[ERROR_CODES2.AGENT_BUSY]: "Another write Agent job is still active.",
|
|
2156
2344
|
[ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "The Agent stopped at a configured time, turn, output, or size limit.",
|
|
2157
2345
|
[ERROR_CODES2.AGENT_CANCELLED]: "The Agent job was cancelled.",
|
|
2158
|
-
[ERROR_CODES2.WORKTREE_DIRTY]: "
|
|
2346
|
+
[ERROR_CODES2.WORKTREE_DIRTY]: "Local changes require explicit inclusion consent before running AI.",
|
|
2347
|
+
[ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "The Vite root is not the top level of an initialized Git repository.",
|
|
2348
|
+
[ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "Finish the active merge, rebase, cherry-pick, or revert before running AI.",
|
|
2349
|
+
[ERROR_CODES2.WORKTREE_CONFLICTED]: "Resolve all merge conflicts before running AI; SpotPatch will not guess a resolution.",
|
|
2350
|
+
[ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "Local untracked files exceed the safe isolation limit. Reduce their count or total size.",
|
|
2351
|
+
[ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "An untracked item is missing, linked, or not a regular file and cannot be isolated safely.",
|
|
2352
|
+
[ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "Local changes include conflicts, unsupported files, or exceed the safe baseline limit.",
|
|
2159
2353
|
[ERROR_CODES2.TOOL_DENIED]: "A model tool request violated the local safety policy.",
|
|
2354
|
+
[ERROR_CODES2.TOOL_INPUT_INVALID]: "The model sent invalid tool arguments or reused a tool call ID inconsistently.",
|
|
2355
|
+
[ERROR_CODES2.TOOL_PATH_DENIED]: "The model tried to access a protected, non-text, linked, or out-of-project path.",
|
|
2160
2356
|
[ERROR_CODES2.PATCH_REJECTED]: "The proposed patch did not pass local policy.",
|
|
2161
2357
|
[ERROR_CODES2.VALIDATION_FAILED]: "Required project checks failed. The change cannot be applied.",
|
|
2162
2358
|
[ERROR_CODES2.APPLY_CONFLICT]: "Project files changed after the Agent baseline; no overwrite was performed.",
|
|
@@ -2180,8 +2376,16 @@ var ERROR_MESSAGES_ZH = Object.freeze({
|
|
|
2180
2376
|
[ERROR_CODES2.AGENT_BUSY]: "\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u4E00\u4E2A\u5199\u5165\u4EFB\u52A1\u6B63\u5728\u8FD0\u884C\u3002",
|
|
2181
2377
|
[ERROR_CODES2.AGENT_LIMIT_EXCEEDED]: "Agent \u8FBE\u5230\u65F6\u95F4\u3001\u8F6E\u6B21\u3001\u8F93\u51FA\u6216\u53D8\u66F4\u89C4\u6A21\u9650\u5236\u3002",
|
|
2182
2378
|
[ERROR_CODES2.AGENT_CANCELLED]: "Agent \u4EFB\u52A1\u5DF2\u53D6\u6D88\u3002",
|
|
2183
|
-
[ERROR_CODES2.WORKTREE_DIRTY]: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\
|
|
2379
|
+
[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",
|
|
2380
|
+
[ERROR_CODES2.WORKTREE_NOT_REPOSITORY]: "Vite \u6839\u76EE\u5F55\u4E0D\u662F\u5DF2\u521D\u59CB\u5316 Git \u4ED3\u5E93\u7684\u9876\u5C42\u76EE\u5F55\u3002",
|
|
2381
|
+
[ERROR_CODES2.WORKTREE_OPERATION_IN_PROGRESS]: "\u8BF7\u5148\u5B8C\u6210\u5F53\u524D merge\u3001rebase\u3001cherry-pick \u6216 revert\uFF0C\u518D\u8FD0\u884C AI\u3002",
|
|
2382
|
+
[ERROR_CODES2.WORKTREE_CONFLICTED]: "\u8BF7\u5148\u89E3\u51B3\u5168\u90E8\u5408\u5E76\u51B2\u7A81\uFF1BSpotPatch \u4E0D\u4F1A\u731C\u6D4B\u51B2\u7A81\u89E3\u51B3\u65B9\u5F0F\u3002",
|
|
2383
|
+
[ERROR_CODES2.WORKTREE_LOCAL_CHANGES_TOO_LARGE]: "\u672C\u5730\u672A\u8DDF\u8E2A\u6587\u4EF6\u8D85\u8FC7\u5B89\u5168\u9694\u79BB\u4E0A\u9650\uFF0C\u8BF7\u51CF\u5C11\u6587\u4EF6\u6570\u91CF\u6216\u603B\u4F53\u79EF\u3002",
|
|
2384
|
+
[ERROR_CODES2.WORKTREE_UNTRACKED_UNSUPPORTED]: "\u67D0\u4E2A\u672A\u8DDF\u8E2A\u9879\u5DF2\u4E22\u5931\u3001\u662F\u7B26\u53F7\u94FE\u63A5\u6216\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF0C\u65E0\u6CD5\u5B89\u5168\u9694\u79BB\u3002",
|
|
2385
|
+
[ERROR_CODES2.WORKTREE_LOCAL_CHANGES_UNSUPPORTED]: "\u672C\u5730\u4FEE\u6539\u5B58\u5728\u51B2\u7A81\u3001\u4E0D\u652F\u6301\u7684\u6587\u4EF6\uFF0C\u6216\u8D85\u8FC7\u5B89\u5168\u57FA\u7EBF\u9650\u5236\u3002",
|
|
2184
2386
|
[ERROR_CODES2.TOOL_DENIED]: "\u6A21\u578B\u5DE5\u5177\u8BF7\u6C42\u8FDD\u53CD\u672C\u5730\u5B89\u5168\u7B56\u7565\u3002",
|
|
2387
|
+
[ERROR_CODES2.TOOL_INPUT_INVALID]: "\u6A21\u578B\u53D1\u9001\u4E86\u65E0\u6548\u5DE5\u5177\u53C2\u6570\uFF0C\u6216\u4E0D\u4E00\u81F4\u5730\u590D\u7528\u4E86\u5DE5\u5177\u8C03\u7528 ID\u3002",
|
|
2388
|
+
[ERROR_CODES2.TOOL_PATH_DENIED]: "\u6A21\u578B\u5C1D\u8BD5\u8BBF\u95EE\u53D7\u4FDD\u62A4\u3001\u975E\u6587\u672C\u3001\u7B26\u53F7\u94FE\u63A5\u6216\u9879\u76EE\u5916\u8DEF\u5F84\u3002",
|
|
2185
2389
|
[ERROR_CODES2.PATCH_REJECTED]: "\u5EFA\u8BAE\u8865\u4E01\u672A\u901A\u8FC7\u672C\u5730\u7B56\u7565\u68C0\u67E5\u3002",
|
|
2186
2390
|
[ERROR_CODES2.VALIDATION_FAILED]: "\u9879\u76EE\u5FC5\u9700\u68C0\u67E5\u5931\u8D25\uFF0C\u4E0D\u80FD\u5E94\u7528\u672C\u6B21\u53D8\u66F4\u3002",
|
|
2187
2391
|
[ERROR_CODES2.APPLY_CONFLICT]: "Agent \u5EFA\u7ACB\u57FA\u7EBF\u540E\u9879\u76EE\u6587\u4EF6\u5DF2\u53D8\u5316\uFF0C\u672A\u6267\u884C\u8986\u76D6\u3002",
|
|
@@ -2346,6 +2550,13 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2346
2550
|
providerUnavailable: "Provider configuration is unavailable.",
|
|
2347
2551
|
consent: (provider) => `I understand selected context and allowed source may be sent to ${provider}; its data policy is my responsibility.`,
|
|
2348
2552
|
connectionNotTested: "Connection not tested",
|
|
2553
|
+
workspaceNotChecked: "Local workspace not checked",
|
|
2554
|
+
checkingWorkspace: "Checking Git workspace and isolated execution\u2026",
|
|
2555
|
+
workspaceReady: "Local workspace is ready for isolated execution",
|
|
2556
|
+
workspaceDirty: (staged, unstaged, untracked) => `Local changes found \xB7 ${String(staged)} staged \xB7 ${String(unstaged)} unstaged \xB7 ${String(untracked)} untracked`,
|
|
2557
|
+
includeLocalChanges: "Allow the Agent to continue from my current local changes",
|
|
2558
|
+
includeLocalChangesHelp: "The Agent may edit these files. SpotPatch preserves the baseline and applies or reverts only the Agent delta.",
|
|
2559
|
+
localChangesConsentRequired: "Confirm inclusion of current local changes before running AI.",
|
|
2349
2560
|
capabilityVerified: "Agent capability verified",
|
|
2350
2561
|
capabilityVerifiedAnnouncement: "AI provider capability verified.",
|
|
2351
2562
|
testingCapability: "Testing authentication, tools, continuation, and streaming\u2026",
|
|
@@ -2354,7 +2565,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2354
2565
|
reverting: "Reverting the applied Agent change.",
|
|
2355
2566
|
consentRequired: "Confirm remote provider data transmission before running AI.",
|
|
2356
2567
|
toolsReady: "tools and streaming ready",
|
|
2357
|
-
testConnection: "
|
|
2568
|
+
testConnection: "Check environment",
|
|
2358
2569
|
verifyAndRun: "Verify & run",
|
|
2359
2570
|
verifying: "Verifying\u2026",
|
|
2360
2571
|
run: "Run AI",
|
|
@@ -2475,6 +2686,13 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2475
2686
|
providerUnavailable: "\u6A21\u578B\u670D\u52A1\u914D\u7F6E\u4E0D\u53EF\u7528\u3002",
|
|
2476
2687
|
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`,
|
|
2477
2688
|
connectionNotTested: "\u5C1A\u672A\u6D4B\u8BD5\u8FDE\u63A5",
|
|
2689
|
+
workspaceNotChecked: "\u5C1A\u672A\u68C0\u67E5\u672C\u5730\u5DE5\u4F5C\u533A",
|
|
2690
|
+
checkingWorkspace: "\u6B63\u5728\u68C0\u67E5 Git \u5DE5\u4F5C\u533A\u4E0E\u9694\u79BB\u6267\u884C\u73AF\u5883\u2026\u2026",
|
|
2691
|
+
workspaceReady: "\u672C\u5730\u5DE5\u4F5C\u533A\u5DF2\u6EE1\u8DB3\u9694\u79BB\u6267\u884C\u6761\u4EF6",
|
|
2692
|
+
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)}`,
|
|
2693
|
+
includeLocalChanges: "\u5141\u8BB8 Agent \u57FA\u4E8E\u6211\u5F53\u524D\u7684\u672C\u5730\u4FEE\u6539\u7EE7\u7EED",
|
|
2694
|
+
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",
|
|
2695
|
+
localChangesConsentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u786E\u8BA4\u5141\u8BB8\u7EB3\u5165\u5F53\u524D\u672C\u5730\u4FEE\u6539\u3002",
|
|
2478
2696
|
capabilityVerified: "Agent \u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7",
|
|
2479
2697
|
capabilityVerifiedAnnouncement: "AI \u6A21\u578B\u670D\u52A1\u80FD\u529B\u9A8C\u8BC1\u901A\u8FC7\u3002",
|
|
2480
2698
|
testingCapability: "\u6B63\u5728\u9A8C\u8BC1\u9274\u6743\u3001\u5DE5\u5177\u8C03\u7528\u3001\u8FDE\u7EED\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u2026\u2026",
|
|
@@ -2483,7 +2701,7 @@ var UI_MESSAGES = Object.freeze({
|
|
|
2483
2701
|
reverting: "\u6B63\u5728\u64A4\u9500\u5DF2\u5E94\u7528\u7684 Agent \u53D8\u66F4\u3002",
|
|
2484
2702
|
consentRequired: "\u8FD0\u884C AI \u524D\uFF0C\u8BF7\u5148\u786E\u8BA4\u5141\u8BB8\u5411\u8FDC\u7A0B\u6A21\u578B\u670D\u52A1\u4F20\u8F93\u6570\u636E\u3002",
|
|
2485
2703
|
toolsReady: "\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u5F0F\u54CD\u5E94\u5DF2\u5C31\u7EEA",
|
|
2486
|
-
testConnection: "\
|
|
2704
|
+
testConnection: "\u68C0\u67E5\u8FD0\u884C\u73AF\u5883",
|
|
2487
2705
|
verifyAndRun: "\u9A8C\u8BC1\u5E76\u8FD0\u884C",
|
|
2488
2706
|
verifying: "\u9A8C\u8BC1\u4E2D\u2026\u2026",
|
|
2489
2707
|
run: "\u8FD0\u884C AI",
|
|
@@ -3733,6 +3951,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3733
3951
|
agentProviderSelect: agentPanel.providerSelect,
|
|
3734
3952
|
agentModelSelect: agentPanel.modelSelect,
|
|
3735
3953
|
agentConsentCheckbox: agentPanel.consentCheckbox,
|
|
3954
|
+
agentWorkspaceConsentCheckbox: agentPanel.workspaceConsentCheckbox,
|
|
3736
3955
|
agentTestButton: agentPanel.testButton,
|
|
3737
3956
|
agentRunButton: agentPanel.runButton,
|
|
3738
3957
|
agentCancelButton: agentPanel.cancelButton,
|
|
@@ -3844,6 +4063,10 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3844
4063
|
previewButton.classList.toggle("spotpatch-primary", !agentReady);
|
|
3845
4064
|
placeDialog();
|
|
3846
4065
|
},
|
|
4066
|
+
renderAgentWorkspaceHealth(state, snapshot, errorCode) {
|
|
4067
|
+
agentPanel.renderWorkspaceHealth(state, snapshot, errorCode);
|
|
4068
|
+
placeDialog();
|
|
4069
|
+
},
|
|
3847
4070
|
renderAgentJob(snapshot, result, activities, errorCode) {
|
|
3848
4071
|
agentPanel.renderJob(snapshot, result, activities, errorCode);
|
|
3849
4072
|
placeDialog();
|
|
@@ -3864,6 +4087,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
|
|
|
3864
4087
|
},
|
|
3865
4088
|
locale: localizer.locale,
|
|
3866
4089
|
messages: localizer.messages,
|
|
4090
|
+
agentWorkspaceConsentGranted: agentPanel.workspaceConsentGranted,
|
|
3867
4091
|
subscribeLocale: localizer.subscribe,
|
|
3868
4092
|
dispose() {
|
|
3869
4093
|
diagnostics.removeEventListener("toggle", placeDialog);
|
|
@@ -3967,6 +4191,22 @@ function createAgentWorkflow(options) {
|
|
|
3967
4191
|
let appliedDuringCurrentJob = false;
|
|
3968
4192
|
let actionPending = false;
|
|
3969
4193
|
const selectedProfiles = () => options.view.readAgentSelection();
|
|
4194
|
+
const refreshWorkspaceHealth = async (workflowRevision) => {
|
|
4195
|
+
options.view.renderAgentWorkspaceHealth("checking");
|
|
4196
|
+
try {
|
|
4197
|
+
const health = await options.api.agentWorkspaceHealth();
|
|
4198
|
+
if (workflowRevision !== revision) {
|
|
4199
|
+
return health;
|
|
4200
|
+
}
|
|
4201
|
+
options.view.renderAgentWorkspaceHealth(health.state, health, health.errorCode);
|
|
4202
|
+
return health;
|
|
4203
|
+
} catch (error) {
|
|
4204
|
+
if (workflowRevision === revision) {
|
|
4205
|
+
options.view.renderAgentWorkspaceHealth("blocked", void 0, errorCode(error));
|
|
4206
|
+
}
|
|
4207
|
+
throw error;
|
|
4208
|
+
}
|
|
4209
|
+
};
|
|
3970
4210
|
const renderJob = (explicitErrorCode) => {
|
|
3971
4211
|
if (snapshot === void 0) {
|
|
3972
4212
|
return;
|
|
@@ -4142,6 +4382,10 @@ function createAgentWorkflow(options) {
|
|
|
4142
4382
|
},
|
|
4143
4383
|
beginSelection() {
|
|
4144
4384
|
resetState();
|
|
4385
|
+
const workflowRevision = revision;
|
|
4386
|
+
if (options.ai.enabled) {
|
|
4387
|
+
void refreshWorkspaceHealth(workflowRevision).catch(() => void 0);
|
|
4388
|
+
}
|
|
4145
4389
|
},
|
|
4146
4390
|
cancel() {
|
|
4147
4391
|
if (snapshot?.canCancel === true) {
|
|
@@ -4174,12 +4418,17 @@ function createAgentWorkflow(options) {
|
|
|
4174
4418
|
providerOrModelChanged() {
|
|
4175
4419
|
revision += 1;
|
|
4176
4420
|
restoreProviderState();
|
|
4421
|
+
const workflowRevision = revision;
|
|
4422
|
+
void refreshWorkspaceHealth(workflowRevision).catch(() => void 0);
|
|
4177
4423
|
},
|
|
4178
4424
|
reset() {
|
|
4179
4425
|
const mustReselect = appliedDuringCurrentJob;
|
|
4180
4426
|
resetState();
|
|
4181
4427
|
if (mustReselect) {
|
|
4182
4428
|
options.onReselectRequired();
|
|
4429
|
+
} else if (options.ai.enabled) {
|
|
4430
|
+
const workflowRevision = revision;
|
|
4431
|
+
void refreshWorkspaceHealth(workflowRevision).catch(() => void 0);
|
|
4183
4432
|
}
|
|
4184
4433
|
},
|
|
4185
4434
|
revert() {
|
|
@@ -4206,15 +4455,27 @@ function createAgentWorkflow(options) {
|
|
|
4206
4455
|
providerConsents.add(selection.providerProfileId);
|
|
4207
4456
|
const workflowRevision = ++revision;
|
|
4208
4457
|
options.view.setAgentEditingEnabled(false);
|
|
4209
|
-
void
|
|
4458
|
+
void Promise.all([
|
|
4459
|
+
probe(workflowRevision),
|
|
4460
|
+
refreshWorkspaceHealth(workflowRevision)
|
|
4461
|
+
]).then(async ([, health]) => {
|
|
4210
4462
|
if (workflowRevision !== revision) {
|
|
4211
4463
|
return;
|
|
4212
4464
|
}
|
|
4465
|
+
if (health.state === "blocked") {
|
|
4466
|
+
throw new RuntimeApiError(
|
|
4467
|
+
health.errorCode ?? ERROR_CODES3.WORKTREE_LOCAL_CHANGES_UNSUPPORTED
|
|
4468
|
+
);
|
|
4469
|
+
}
|
|
4470
|
+
if (health.state === "consent-required" && !options.view.agentWorkspaceConsentGranted()) {
|
|
4471
|
+
throw new RuntimeApiError(ERROR_CODES3.WORKTREE_DIRTY);
|
|
4472
|
+
}
|
|
4213
4473
|
const created = await options.api.createAgentJob({
|
|
4214
4474
|
annotation,
|
|
4215
4475
|
providerProfileId: selection.providerProfileId,
|
|
4216
4476
|
modelProfileId: selection.modelProfileId,
|
|
4217
|
-
providerDataConsent: true
|
|
4477
|
+
providerDataConsent: true,
|
|
4478
|
+
workingTreeMode: health.state === "consent-required" ? "include-local-changes" : "require-clean"
|
|
4218
4479
|
});
|
|
4219
4480
|
if (workflowRevision !== revision) {
|
|
4220
4481
|
return;
|
|
@@ -4243,7 +4504,10 @@ function createAgentWorkflow(options) {
|
|
|
4243
4504
|
return;
|
|
4244
4505
|
}
|
|
4245
4506
|
const workflowRevision = ++revision;
|
|
4246
|
-
void
|
|
4507
|
+
void Promise.all([
|
|
4508
|
+
probe(workflowRevision),
|
|
4509
|
+
refreshWorkspaceHealth(workflowRevision)
|
|
4510
|
+
]).catch((error) => {
|
|
4247
4511
|
if (workflowRevision === revision) {
|
|
4248
4512
|
options.view.renderAgentCapability(
|
|
4249
4513
|
"error",
|