forkit-connect 0.1.11 → 0.1.13
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/launcher.js +336 -123
- package/dist/v1/service.d.ts +3 -0
- package/dist/v1/service.js +59 -10
- package/dist/v1/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/launcher.js
CHANGED
|
@@ -1801,7 +1801,9 @@ function renderLauncherHtml(launcherToken) {
|
|
|
1801
1801
|
.quick-review-chip:focus-visible,
|
|
1802
1802
|
.quick-review-primary:focus-visible,
|
|
1803
1803
|
.quick-review-options-button:focus-visible,
|
|
1804
|
+
.review-mode-button:focus-visible,
|
|
1804
1805
|
.quick-review-field select:focus-visible,
|
|
1806
|
+
.discovery-review-field select:focus-visible,
|
|
1805
1807
|
.quick-review-options-menu button:focus-visible {
|
|
1806
1808
|
outline: 2px solid rgba(157, 238, 245, 0.72);
|
|
1807
1809
|
outline-offset: 2px;
|
|
@@ -1993,12 +1995,66 @@ function renderLauncherHtml(launcherToken) {
|
|
|
1993
1995
|
gap: 10px;
|
|
1994
1996
|
}
|
|
1995
1997
|
|
|
1998
|
+
.review-mode-group {
|
|
1999
|
+
display: grid;
|
|
2000
|
+
gap: 8px;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
.review-mode-label {
|
|
2004
|
+
font-size: 0.74rem;
|
|
2005
|
+
text-transform: uppercase;
|
|
2006
|
+
letter-spacing: 0.12em;
|
|
2007
|
+
font-weight: 700;
|
|
2008
|
+
color: rgba(241, 235, 223, 0.62);
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
.review-mode-toggle {
|
|
2012
|
+
display: inline-grid;
|
|
2013
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
2014
|
+
gap: 8px;
|
|
2015
|
+
padding: 6px;
|
|
2016
|
+
border-radius: 18px;
|
|
2017
|
+
border: 1px solid rgba(241, 235, 223, 0.08);
|
|
2018
|
+
background: rgba(255,255,255,0.04);
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
.review-mode-button {
|
|
2022
|
+
min-height: 42px;
|
|
2023
|
+
border: 1px solid rgba(241, 235, 223, 0.08);
|
|
2024
|
+
border-radius: 14px;
|
|
2025
|
+
background: transparent;
|
|
2026
|
+
color: rgba(241, 235, 223, 0.72);
|
|
2027
|
+
font: inherit;
|
|
2028
|
+
font-size: 0.88rem;
|
|
2029
|
+
font-weight: 600;
|
|
2030
|
+
cursor: pointer;
|
|
2031
|
+
transition: border-color 160ms ease, background 160ms ease, color 160ms ease, transform 160ms ease;
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
.review-mode-button:hover {
|
|
2035
|
+
border-color: rgba(157, 238, 245, 0.26);
|
|
2036
|
+
color: #fff8ef;
|
|
2037
|
+
transform: translateY(-1px);
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2040
|
+
.review-mode-button.active {
|
|
2041
|
+
border-color: rgba(157, 238, 245, 0.34);
|
|
2042
|
+
background: linear-gradient(135deg, rgba(55, 68, 86, 0.62), rgba(31, 36, 56, 0.92));
|
|
2043
|
+
color: #fff8ef;
|
|
2044
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
1996
2047
|
.quick-review-scope-grid {
|
|
1997
2048
|
display: grid;
|
|
1998
2049
|
grid-template-columns: 1fr 1fr;
|
|
1999
2050
|
gap: 10px;
|
|
2000
2051
|
}
|
|
2001
2052
|
|
|
2053
|
+
.quick-review-scope-grid[hidden],
|
|
2054
|
+
.discovery-review-scope-grid[hidden] {
|
|
2055
|
+
display: none;
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2002
2058
|
.quick-review-field {
|
|
2003
2059
|
display: grid;
|
|
2004
2060
|
gap: 6px;
|
|
@@ -6465,7 +6521,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
6465
6521
|
</div>
|
|
6466
6522
|
<div class="quick-review-status" id="quick-review-status">Waiting for review.</div>
|
|
6467
6523
|
<div class="quick-review-scope" id="quick-review-scope" hidden>
|
|
6468
|
-
<div class="quick-review-
|
|
6524
|
+
<div class="review-mode-group" id="quick-review-mode">
|
|
6525
|
+
<span class="review-mode-label">Register as</span>
|
|
6526
|
+
<div class="review-mode-toggle" role="group" aria-label="Quick review registration path">
|
|
6527
|
+
<button class="review-mode-button active" id="quick-review-mode-solo" type="button" aria-pressed="true">Solo</button>
|
|
6528
|
+
<button class="review-mode-button" id="quick-review-mode-workspace" type="button" aria-pressed="false">Governed workspace</button>
|
|
6529
|
+
</div>
|
|
6530
|
+
</div>
|
|
6531
|
+
<div class="quick-review-scope-grid" id="quick-review-scope-grid" hidden>
|
|
6469
6532
|
<div class="quick-review-field">
|
|
6470
6533
|
<label for="quick-review-workspace">Workspace</label>
|
|
6471
6534
|
<select id="quick-review-workspace"></select>
|
|
@@ -6869,7 +6932,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
6869
6932
|
<p class="discovery-review-detail" id="discovery-review-detail">Registering creates or updates a Forkit Passport. Nothing is published automatically.</p>
|
|
6870
6933
|
<div class="discovery-review-status" id="discovery-review-status">Select an item to continue.</div>
|
|
6871
6934
|
<div class="discovery-review-scope" id="discovery-review-scope" hidden>
|
|
6872
|
-
<div class="discovery-review-
|
|
6935
|
+
<div class="review-mode-group" id="discovery-review-mode">
|
|
6936
|
+
<span class="review-mode-label">Register as</span>
|
|
6937
|
+
<div class="review-mode-toggle" role="group" aria-label="Discovery review registration path">
|
|
6938
|
+
<button class="review-mode-button active" id="discovery-review-mode-solo" type="button" aria-pressed="true">Solo</button>
|
|
6939
|
+
<button class="review-mode-button" id="discovery-review-mode-workspace" type="button" aria-pressed="false">Governed workspace</button>
|
|
6940
|
+
</div>
|
|
6941
|
+
</div>
|
|
6942
|
+
<div class="discovery-review-scope-grid" id="discovery-review-scope-grid" hidden>
|
|
6873
6943
|
<div class="discovery-review-field">
|
|
6874
6944
|
<label for="discovery-review-workspace">Workspace</label>
|
|
6875
6945
|
<select id="discovery-review-workspace"></select>
|
|
@@ -7522,11 +7592,11 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7522
7592
|
}
|
|
7523
7593
|
|
|
7524
7594
|
function canReviewDefer(item) {
|
|
7525
|
-
return Boolean(item && (item.kind === 'model' || item.kind === 'runtime') && item.inboxGroup !== 'ignored');
|
|
7595
|
+
return Boolean(item && (item.kind === 'model' || item.kind === 'agent' || item.kind === 'runtime') && item.inboxGroup !== 'ignored');
|
|
7526
7596
|
}
|
|
7527
7597
|
|
|
7528
7598
|
function canReviewIgnore(item) {
|
|
7529
|
-
return Boolean(item && (item.kind === 'model' || item.kind === 'runtime') && item.inboxGroup !== 'ignored');
|
|
7599
|
+
return Boolean(item && (item.kind === 'model' || item.kind === 'agent' || item.kind === 'runtime') && item.inboxGroup !== 'ignored');
|
|
7530
7600
|
}
|
|
7531
7601
|
|
|
7532
7602
|
function getQuickReviewItems() {
|
|
@@ -7554,6 +7624,53 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7554
7624
|
status.className = 'quick-review-status' + (tone ? ' ' + tone : '');
|
|
7555
7625
|
}
|
|
7556
7626
|
|
|
7627
|
+
function canChooseReviewScope(item) {
|
|
7628
|
+
return Boolean(canReviewRegister(item) && !shouldOpenReviewContext(item));
|
|
7629
|
+
}
|
|
7630
|
+
|
|
7631
|
+
function getReviewRegistrationMode(prefix) {
|
|
7632
|
+
const scope = document.getElementById(prefix + '-scope');
|
|
7633
|
+
if (!scope) return 'solo';
|
|
7634
|
+
return String(scope.dataset.mode || '').trim() === 'workspace' ? 'workspace' : 'solo';
|
|
7635
|
+
}
|
|
7636
|
+
|
|
7637
|
+
function setReviewRegistrationMode(prefix, mode) {
|
|
7638
|
+
const normalized = mode === 'workspace' ? 'workspace' : 'solo';
|
|
7639
|
+
const scope = document.getElementById(prefix + '-scope');
|
|
7640
|
+
const scopeGrid = document.getElementById(prefix + '-scope-grid');
|
|
7641
|
+
if (scope) {
|
|
7642
|
+
scope.dataset.mode = normalized;
|
|
7643
|
+
}
|
|
7644
|
+
if (scopeGrid) {
|
|
7645
|
+
scopeGrid.hidden = normalized !== 'workspace';
|
|
7646
|
+
}
|
|
7647
|
+
['solo', 'workspace'].forEach((candidate) => {
|
|
7648
|
+
const button = document.getElementById(prefix + '-mode-' + candidate);
|
|
7649
|
+
if (!button) return;
|
|
7650
|
+
const active = candidate === normalized;
|
|
7651
|
+
button.classList.toggle('active', active);
|
|
7652
|
+
button.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
7653
|
+
});
|
|
7654
|
+
return normalized;
|
|
7655
|
+
}
|
|
7656
|
+
|
|
7657
|
+
function getPassiveReviewScopeSummary(item) {
|
|
7658
|
+
if (!item) return 'Review';
|
|
7659
|
+
if (item.kind === 'runtime') {
|
|
7660
|
+
return item.statusTone === 'error' ? 'Runtime fix' : 'Runtime review';
|
|
7661
|
+
}
|
|
7662
|
+
if (isContinuationReviewItem(item)) {
|
|
7663
|
+
return 'Private review';
|
|
7664
|
+
}
|
|
7665
|
+
if (item.passportGaid) {
|
|
7666
|
+
return 'Linked passport';
|
|
7667
|
+
}
|
|
7668
|
+
if (item.matchedPassportGaid) {
|
|
7669
|
+
return 'Existing passport';
|
|
7670
|
+
}
|
|
7671
|
+
return 'Full review';
|
|
7672
|
+
}
|
|
7673
|
+
|
|
7557
7674
|
function resetReviewResolutionActions(prefix) {
|
|
7558
7675
|
setReviewResolutionActions(prefix, []);
|
|
7559
7676
|
}
|
|
@@ -7789,15 +7906,19 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7789
7906
|
}
|
|
7790
7907
|
}
|
|
7791
7908
|
|
|
7792
|
-
function updateQuickReviewScopeSummary(
|
|
7909
|
+
function updateQuickReviewScopeSummary(scopeMode) {
|
|
7793
7910
|
const workspaceSelect = document.getElementById('quick-review-workspace');
|
|
7794
7911
|
const projectSelect = document.getElementById('quick-review-project');
|
|
7795
7912
|
const workspaceId = workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
|
|
7796
7913
|
const projectId = projectSelect ? String(projectSelect.value || '').trim() : '';
|
|
7797
7914
|
const workspaceLabel = readSelectedOptionLabel(workspaceSelect);
|
|
7798
7915
|
const projectLabel = readSelectedOptionLabel(projectSelect);
|
|
7916
|
+
if (scopeMode !== 'workspace') {
|
|
7917
|
+
setText('quick-review-scope-summary', 'Account scope');
|
|
7918
|
+
return;
|
|
7919
|
+
}
|
|
7799
7920
|
if (!workspaceId) {
|
|
7800
|
-
setText('quick-review-scope-summary',
|
|
7921
|
+
setText('quick-review-scope-summary', 'Choose governed workspace');
|
|
7801
7922
|
return;
|
|
7802
7923
|
}
|
|
7803
7924
|
if (!projectId) {
|
|
@@ -7807,14 +7928,41 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7807
7928
|
setText('quick-review-scope-summary', [workspaceLabel, projectLabel].filter(Boolean).join(' · ') || 'Governed project');
|
|
7808
7929
|
}
|
|
7809
7930
|
|
|
7810
|
-
|
|
7931
|
+
function syncQuickReviewRegistrationMode(item, mode) {
|
|
7932
|
+
const reviewScopeMode = setReviewRegistrationMode('quick-review', mode);
|
|
7933
|
+
const workspaceSelect = document.getElementById('quick-review-workspace');
|
|
7934
|
+
const projectSelect = document.getElementById('quick-review-project');
|
|
7935
|
+
const primaryButton = document.getElementById('quick-review-primary');
|
|
7936
|
+
const workspaceId = reviewScopeMode === 'workspace' && workspaceSelect
|
|
7937
|
+
? String(workspaceSelect.value || '').trim()
|
|
7938
|
+
: '';
|
|
7939
|
+
const projectId = reviewScopeMode === 'workspace' && projectSelect
|
|
7940
|
+
? String(projectSelect.value || '').trim()
|
|
7941
|
+
: '';
|
|
7942
|
+
if (primaryButton && item) {
|
|
7943
|
+
primaryButton.textContent = getReviewPrimaryLabel(item, reviewScopeMode);
|
|
7944
|
+
primaryButton.disabled = item.inboxGroup === 'ignored' || (reviewScopeMode === 'workspace' && (!workspaceId || !projectId));
|
|
7945
|
+
}
|
|
7946
|
+
if (item) {
|
|
7947
|
+
setText('quick-review-action-summary', getReviewActionSummary(item, reviewScopeMode));
|
|
7948
|
+
}
|
|
7949
|
+
updateQuickReviewScopeSummary(reviewScopeMode);
|
|
7950
|
+
return reviewScopeMode;
|
|
7951
|
+
}
|
|
7952
|
+
|
|
7953
|
+
async function loadQuickReviewProjects(workspaceId, selectedProjectId, scopeMode) {
|
|
7811
7954
|
const projectSelect = document.getElementById('quick-review-project');
|
|
7812
7955
|
const primaryButton = document.getElementById('quick-review-primary');
|
|
7813
7956
|
if (!projectSelect) return;
|
|
7814
7957
|
if (!workspaceId) {
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7958
|
+
if (scopeMode === 'workspace') {
|
|
7959
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Choose a workspace first' }], '');
|
|
7960
|
+
if (primaryButton) primaryButton.disabled = true;
|
|
7961
|
+
} else {
|
|
7962
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
|
|
7963
|
+
if (primaryButton) primaryButton.disabled = false;
|
|
7964
|
+
}
|
|
7965
|
+
updateQuickReviewScopeSummary(scopeMode);
|
|
7818
7966
|
return;
|
|
7819
7967
|
}
|
|
7820
7968
|
setScopeOptions(projectSelect, [{ id: '', label: 'Loading projects...' }], '');
|
|
@@ -7834,14 +7982,14 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7834
7982
|
if (primaryButton) {
|
|
7835
7983
|
primaryButton.disabled = !projects.length;
|
|
7836
7984
|
}
|
|
7837
|
-
updateQuickReviewScopeSummary(
|
|
7985
|
+
updateQuickReviewScopeSummary(scopeMode);
|
|
7838
7986
|
} catch {
|
|
7839
7987
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
7840
7988
|
setQuickReviewStatus('Project list is unavailable right now.', 'warn');
|
|
7841
7989
|
if (primaryButton) {
|
|
7842
7990
|
primaryButton.disabled = true;
|
|
7843
7991
|
}
|
|
7844
|
-
updateQuickReviewScopeSummary(
|
|
7992
|
+
updateQuickReviewScopeSummary(scopeMode);
|
|
7845
7993
|
}
|
|
7846
7994
|
}
|
|
7847
7995
|
|
|
@@ -7901,17 +8049,22 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7901
8049
|
ignoreButton.hidden = !canReviewIgnore(item);
|
|
7902
8050
|
}
|
|
7903
8051
|
|
|
7904
|
-
const
|
|
7905
|
-
if (!
|
|
8052
|
+
const showScopeChoice = canChooseReviewScope(item);
|
|
8053
|
+
if (!showScopeChoice) {
|
|
7906
8054
|
if (scopeWrap) scopeWrap.hidden = true;
|
|
8055
|
+
setReviewRegistrationMode('quick-review', 'solo');
|
|
7907
8056
|
quickReviewScopeCacheKey = null;
|
|
7908
|
-
setText('quick-review-scope-summary', item
|
|
8057
|
+
setText('quick-review-scope-summary', getPassiveReviewScopeSummary(item));
|
|
7909
8058
|
return;
|
|
7910
8059
|
}
|
|
7911
8060
|
|
|
7912
8061
|
if (scopeWrap) scopeWrap.hidden = false;
|
|
7913
8062
|
if (!workspaceSelect || !projectSelect) return;
|
|
7914
8063
|
const cacheKey = item.id + ':' + String(item.workspaceId || '') + ':' + String(item.projectId || '');
|
|
8064
|
+
syncQuickReviewRegistrationMode(
|
|
8065
|
+
item,
|
|
8066
|
+
quickReviewScopeCacheKey === cacheKey ? getReviewRegistrationMode('quick-review') : 'solo',
|
|
8067
|
+
);
|
|
7915
8068
|
if (quickReviewScopeCacheKey === cacheKey) {
|
|
7916
8069
|
return;
|
|
7917
8070
|
}
|
|
@@ -7924,40 +8077,43 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7924
8077
|
const response = await apiFetch('/api/scope/access');
|
|
7925
8078
|
const payload = await response.json();
|
|
7926
8079
|
scopeAccessSnapshot = payload;
|
|
7927
|
-
const governedMode = Boolean(payload && payload.operatingMode === 'governed');
|
|
7928
8080
|
const workspaces = payload.ok && Array.isArray(payload.workspaces) ? payload.workspaces : [];
|
|
7929
8081
|
const options = [
|
|
7930
8082
|
{ id: '', label: 'Register solo / account scope' },
|
|
7931
8083
|
...workspaces.map((workspace) => ({ id: workspace.id, label: workspace.name || workspace.id })),
|
|
7932
8084
|
];
|
|
7933
|
-
const selectedWorkspace = item.workspaceId || '';
|
|
8085
|
+
const selectedWorkspace = item.workspaceId || payload.currentWorkspaceId || '';
|
|
8086
|
+
const selectedProject = item.projectId || payload.currentProjectId || '';
|
|
7934
8087
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
7935
|
-
await loadQuickReviewProjects(selectedWorkspace,
|
|
7936
|
-
const reviewScopeMode =
|
|
7937
|
-
selectedWorkspace,
|
|
7938
|
-
item.projectId || payload.currentProjectId || '',
|
|
7939
|
-
);
|
|
8088
|
+
await loadQuickReviewProjects(selectedWorkspace, selectedProject, getReviewRegistrationMode('quick-review'));
|
|
8089
|
+
const reviewScopeMode = syncQuickReviewRegistrationMode(item, getReviewRegistrationMode('quick-review'));
|
|
7940
8090
|
setQuickReviewStatus(
|
|
7941
8091
|
payload.ok
|
|
7942
8092
|
? (reviewScopeMode === 'workspace'
|
|
7943
|
-
?
|
|
7944
|
-
|
|
7945
|
-
|
|
8093
|
+
? (selectedWorkspace
|
|
8094
|
+
? 'Choose the governed workspace and project for this registration.'
|
|
8095
|
+
: workspaces.length
|
|
8096
|
+
? 'Choose a workspace and project for governed registration.'
|
|
8097
|
+
: 'No governed workspaces are available yet. Switch back to solo or create one first.')
|
|
8098
|
+
: 'Solo registration is ready. Choose governed workspace only when needed.')
|
|
8099
|
+
: (reviewScopeMode === 'workspace'
|
|
8100
|
+
? (payload.message || 'Workspace access is unavailable right now. Switch to solo registration or retry later.')
|
|
8101
|
+
: 'Solo registration is still available. Governed workspace access is unavailable right now.'),
|
|
7946
8102
|
payload.ok ? '' : 'warn',
|
|
7947
8103
|
);
|
|
7948
|
-
updateQuickReviewScopeSummary(governedMode);
|
|
7949
|
-
if (primaryButton) {
|
|
7950
|
-
primaryButton.textContent = getReviewPrimaryLabel(item, reviewScopeMode);
|
|
7951
|
-
}
|
|
7952
|
-
setText('quick-review-action-summary', getReviewActionSummary(item, reviewScopeMode));
|
|
7953
8104
|
} catch {
|
|
7954
8105
|
setScopeOptions(workspaceSelect, [{ id: '', label: 'Workspace list unavailable' }], '');
|
|
7955
8106
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
8107
|
+
const reviewScopeMode = syncQuickReviewRegistrationMode(item, getReviewRegistrationMode('quick-review'));
|
|
8108
|
+
setQuickReviewStatus(
|
|
8109
|
+
reviewScopeMode === 'workspace'
|
|
8110
|
+
? 'Workspace access is unavailable right now. Switch to solo registration or retry later.'
|
|
8111
|
+
: 'Solo registration is still available. Governed workspace access is unavailable right now.',
|
|
8112
|
+
'warn',
|
|
8113
|
+
);
|
|
8114
|
+
if (reviewScopeMode === 'workspace') {
|
|
8115
|
+
setText('quick-review-scope-summary', 'Scope unavailable');
|
|
7959
8116
|
}
|
|
7960
|
-
setText('quick-review-scope-summary', 'Scope unavailable');
|
|
7961
8117
|
}
|
|
7962
8118
|
}
|
|
7963
8119
|
|
|
@@ -7977,10 +8133,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
7977
8133
|
const workspaceSelect = document.getElementById('quick-review-workspace');
|
|
7978
8134
|
const projectSelect = document.getElementById('quick-review-project');
|
|
7979
8135
|
const primaryButton = document.getElementById('quick-review-primary');
|
|
7980
|
-
const
|
|
7981
|
-
const
|
|
7982
|
-
const
|
|
7983
|
-
if (
|
|
8136
|
+
const reviewScopeMode = getReviewRegistrationMode('quick-review');
|
|
8137
|
+
const workspaceId = reviewScopeMode === 'workspace' && workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
|
|
8138
|
+
const projectId = reviewScopeMode === 'workspace' && projectSelect ? String(projectSelect.value || '').trim() : '';
|
|
8139
|
+
if (reviewScopeMode === 'workspace' && (!workspaceId || !projectId)) {
|
|
7984
8140
|
setQuickReviewStatus('Select a project for the chosen workspace, or switch back to account scope.', 'warn');
|
|
7985
8141
|
return;
|
|
7986
8142
|
}
|
|
@@ -8057,13 +8213,39 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8057
8213
|
}
|
|
8058
8214
|
}
|
|
8059
8215
|
|
|
8060
|
-
|
|
8216
|
+
function syncDiscoveryReviewRegistrationMode(item, mode) {
|
|
8217
|
+
const reviewScopeMode = setReviewRegistrationMode('discovery-review', mode);
|
|
8218
|
+
const workspaceSelect = document.getElementById('discovery-review-workspace');
|
|
8219
|
+
const projectSelect = document.getElementById('discovery-review-project');
|
|
8220
|
+
const workspaceId = reviewScopeMode === 'workspace' && workspaceSelect
|
|
8221
|
+
? String(workspaceSelect.value || '').trim()
|
|
8222
|
+
: '';
|
|
8223
|
+
const projectId = reviewScopeMode === 'workspace' && projectSelect
|
|
8224
|
+
? String(projectSelect.value || '').trim()
|
|
8225
|
+
: '';
|
|
8226
|
+
if (item) {
|
|
8227
|
+
setDiscoveryReviewButtons({
|
|
8228
|
+
primaryLabel: getReviewPrimaryLabel(item, reviewScopeMode),
|
|
8229
|
+
primaryEnabled: item.inboxGroup !== 'ignored' && !(reviewScopeMode === 'workspace' && (!workspaceId || !projectId)),
|
|
8230
|
+
deferEnabled: canReviewDefer(item),
|
|
8231
|
+
ignoreEnabled: canReviewIgnore(item),
|
|
8232
|
+
});
|
|
8233
|
+
}
|
|
8234
|
+
return reviewScopeMode;
|
|
8235
|
+
}
|
|
8236
|
+
|
|
8237
|
+
async function loadDiscoveryReviewProjects(workspaceId, selectedProjectId, scopeMode) {
|
|
8061
8238
|
const projectSelect = document.getElementById('discovery-review-project');
|
|
8062
8239
|
const primaryButton = document.getElementById('discovery-review-primary');
|
|
8063
8240
|
if (!projectSelect) return;
|
|
8064
8241
|
if (!workspaceId) {
|
|
8065
|
-
|
|
8066
|
-
|
|
8242
|
+
if (scopeMode === 'workspace') {
|
|
8243
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Choose a workspace first' }], '');
|
|
8244
|
+
if (primaryButton) primaryButton.disabled = true;
|
|
8245
|
+
} else {
|
|
8246
|
+
setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
|
|
8247
|
+
if (primaryButton) primaryButton.disabled = false;
|
|
8248
|
+
}
|
|
8067
8249
|
return;
|
|
8068
8250
|
}
|
|
8069
8251
|
setScopeOptions(projectSelect, [{ id: '', label: 'Loading projects...' }], '');
|
|
@@ -8104,6 +8286,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8104
8286
|
setText('discovery-review-meta', 'Choose a model, agent, or runtime to review it here.');
|
|
8105
8287
|
setText('discovery-review-detail', 'Registering creates or updates a Forkit Passport. Nothing is published automatically.');
|
|
8106
8288
|
if (scopeWrap) scopeWrap.hidden = true;
|
|
8289
|
+
setReviewRegistrationMode('discovery-review', 'solo');
|
|
8107
8290
|
setDiscoveryReviewStatus('Select an item to continue.', '');
|
|
8108
8291
|
resetReviewResolutionActions('discovery-review');
|
|
8109
8292
|
setDiscoveryReviewButtons({ primaryLabel: 'Review', primaryEnabled: false, deferEnabled: false, ignoreEnabled: false });
|
|
@@ -8111,8 +8294,7 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8111
8294
|
}
|
|
8112
8295
|
|
|
8113
8296
|
const typeLabel = item.typeLabel || item.kind;
|
|
8114
|
-
const
|
|
8115
|
-
const primaryLabel = getReviewPrimaryLabel(item, 'solo');
|
|
8297
|
+
const showScopeChoice = canChooseReviewScope(item);
|
|
8116
8298
|
|
|
8117
8299
|
setText('discovery-review-kicker', typeLabel);
|
|
8118
8300
|
setText('discovery-review-title', item.name);
|
|
@@ -8127,8 +8309,9 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8127
8309
|
ignoreEnabled: canReviewIgnore(item),
|
|
8128
8310
|
});
|
|
8129
8311
|
|
|
8130
|
-
if (!
|
|
8312
|
+
if (!showScopeChoice) {
|
|
8131
8313
|
if (scopeWrap) scopeWrap.hidden = true;
|
|
8314
|
+
setReviewRegistrationMode('discovery-review', 'solo');
|
|
8132
8315
|
reviewScopeCacheKey = null;
|
|
8133
8316
|
return;
|
|
8134
8317
|
}
|
|
@@ -8137,6 +8320,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8137
8320
|
if (!workspaceSelect || !projectSelect) return;
|
|
8138
8321
|
|
|
8139
8322
|
const cacheKey = item.id + ':' + String(item.workspaceId || '') + ':' + String(item.projectId || '');
|
|
8323
|
+
syncDiscoveryReviewRegistrationMode(
|
|
8324
|
+
item,
|
|
8325
|
+
reviewScopeCacheKey === cacheKey ? getReviewRegistrationMode('discovery-review') : 'solo',
|
|
8326
|
+
);
|
|
8140
8327
|
if (reviewScopeCacheKey === cacheKey) {
|
|
8141
8328
|
return;
|
|
8142
8329
|
}
|
|
@@ -8150,43 +8337,40 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8150
8337
|
const response = await apiFetch('/api/scope/access');
|
|
8151
8338
|
const payload = await response.json();
|
|
8152
8339
|
scopeAccessSnapshot = payload;
|
|
8153
|
-
const governedMode = Boolean(payload && payload.operatingMode === 'governed');
|
|
8154
8340
|
const workspaces = payload.ok && Array.isArray(payload.workspaces) ? payload.workspaces : [];
|
|
8155
8341
|
const options = [
|
|
8156
8342
|
{ id: '', label: 'Register solo / account scope' },
|
|
8157
8343
|
...workspaces.map((workspace) => ({ id: workspace.id, label: workspace.name || workspace.id })),
|
|
8158
8344
|
];
|
|
8159
|
-
const selectedWorkspace = item.workspaceId || '';
|
|
8345
|
+
const selectedWorkspace = item.workspaceId || payload.currentWorkspaceId || '';
|
|
8346
|
+
const selectedProject = item.projectId || payload.currentProjectId || '';
|
|
8160
8347
|
setScopeOptions(workspaceSelect, options, selectedWorkspace);
|
|
8161
|
-
await loadDiscoveryReviewProjects(selectedWorkspace,
|
|
8162
|
-
const reviewScopeMode =
|
|
8163
|
-
selectedWorkspace,
|
|
8164
|
-
item.projectId || payload.currentProjectId || '',
|
|
8165
|
-
);
|
|
8348
|
+
await loadDiscoveryReviewProjects(selectedWorkspace, selectedProject, getReviewRegistrationMode('discovery-review'));
|
|
8349
|
+
const reviewScopeMode = syncDiscoveryReviewRegistrationMode(item, getReviewRegistrationMode('discovery-review'));
|
|
8166
8350
|
setDiscoveryReviewStatus(
|
|
8167
8351
|
payload.ok
|
|
8168
8352
|
? (reviewScopeMode === 'workspace'
|
|
8169
|
-
?
|
|
8170
|
-
|
|
8171
|
-
|
|
8353
|
+
? (selectedWorkspace
|
|
8354
|
+
? 'Choose the governed workspace and project for this registration.'
|
|
8355
|
+
: workspaces.length
|
|
8356
|
+
? 'Choose a workspace and project for governed registration.'
|
|
8357
|
+
: 'No governed workspaces are available yet. Switch back to solo or create one first.')
|
|
8358
|
+
: 'Solo registration is ready. Choose governed workspace only when needed.')
|
|
8359
|
+
: (reviewScopeMode === 'workspace'
|
|
8360
|
+
? (payload.message || 'Workspace access is unavailable right now. Switch to solo registration or retry later.')
|
|
8361
|
+
: 'Solo registration is still available. Governed workspace access is unavailable right now.'),
|
|
8172
8362
|
payload.ok ? '' : 'warn',
|
|
8173
8363
|
);
|
|
8174
|
-
setDiscoveryReviewButtons({
|
|
8175
|
-
primaryLabel: getReviewPrimaryLabel(item, reviewScopeMode),
|
|
8176
|
-
primaryEnabled: item.inboxGroup !== 'ignored',
|
|
8177
|
-
deferEnabled: canReviewDefer(item),
|
|
8178
|
-
ignoreEnabled: canReviewIgnore(item),
|
|
8179
|
-
});
|
|
8180
8364
|
} catch {
|
|
8181
8365
|
setScopeOptions(workspaceSelect, [{ id: '', label: 'Workspace list unavailable' }], '');
|
|
8182
8366
|
setScopeOptions(projectSelect, [{ id: '', label: 'Project list unavailable' }], '');
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8367
|
+
const reviewScopeMode = syncDiscoveryReviewRegistrationMode(item, getReviewRegistrationMode('discovery-review'));
|
|
8368
|
+
setDiscoveryReviewStatus(
|
|
8369
|
+
reviewScopeMode === 'workspace'
|
|
8370
|
+
? 'Workspace access is unavailable right now. Switch to solo registration or retry later.'
|
|
8371
|
+
: 'Solo registration is still available. Governed workspace access is unavailable right now.',
|
|
8372
|
+
'warn',
|
|
8373
|
+
);
|
|
8190
8374
|
}
|
|
8191
8375
|
}
|
|
8192
8376
|
|
|
@@ -8204,9 +8388,10 @@ function renderLauncherHtml(launcherToken) {
|
|
|
8204
8388
|
const workspaceSelect = document.getElementById('discovery-review-workspace');
|
|
8205
8389
|
const projectSelect = document.getElementById('discovery-review-project');
|
|
8206
8390
|
const primaryButton = document.getElementById('discovery-review-primary');
|
|
8207
|
-
const
|
|
8208
|
-
const
|
|
8209
|
-
|
|
8391
|
+
const reviewScopeMode = getReviewRegistrationMode('discovery-review');
|
|
8392
|
+
const workspaceId = reviewScopeMode === 'workspace' && workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
|
|
8393
|
+
const projectId = reviewScopeMode === 'workspace' && projectSelect ? String(projectSelect.value || '').trim() : '';
|
|
8394
|
+
if (reviewScopeMode === 'workspace' && (!workspaceId || !projectId)) {
|
|
8210
8395
|
setDiscoveryReviewStatus('Select a project for the chosen workspace, or switch back to account scope.', 'warn');
|
|
8211
8396
|
return;
|
|
8212
8397
|
}
|
|
@@ -10140,50 +10325,62 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10140
10325
|
void submitQuickReviewIgnore();
|
|
10141
10326
|
});
|
|
10142
10327
|
}
|
|
10328
|
+
const quickReviewModeSolo = document.getElementById('quick-review-mode-solo');
|
|
10329
|
+
if (quickReviewModeSolo) {
|
|
10330
|
+
quickReviewModeSolo.addEventListener('click', () => {
|
|
10331
|
+
const item = getQuickReviewItem();
|
|
10332
|
+
if (!item || !canChooseReviewScope(item)) return;
|
|
10333
|
+
syncQuickReviewRegistrationMode(item, 'solo');
|
|
10334
|
+
setQuickReviewStatus('Solo registration is ready. Choose governed workspace only when needed.', '');
|
|
10335
|
+
});
|
|
10336
|
+
}
|
|
10337
|
+
const quickReviewModeWorkspace = document.getElementById('quick-review-mode-workspace');
|
|
10338
|
+
if (quickReviewModeWorkspace) {
|
|
10339
|
+
quickReviewModeWorkspace.addEventListener('click', () => {
|
|
10340
|
+
const item = getQuickReviewItem();
|
|
10341
|
+
if (!item || !canChooseReviewScope(item)) return;
|
|
10342
|
+
syncQuickReviewRegistrationMode(item, 'workspace');
|
|
10343
|
+
const selectedWorkspaceId = quickReviewWorkspaceSelect
|
|
10344
|
+
? String(quickReviewWorkspaceSelect.value || '').trim()
|
|
10345
|
+
: '';
|
|
10346
|
+
const selectedProjectId = quickReviewProjectSelect
|
|
10347
|
+
? String(quickReviewProjectSelect.value || '').trim()
|
|
10348
|
+
: '';
|
|
10349
|
+
void loadQuickReviewProjects(selectedWorkspaceId, selectedProjectId, 'workspace');
|
|
10350
|
+
setQuickReviewStatus(
|
|
10351
|
+
selectedWorkspaceId
|
|
10352
|
+
? 'Choose the governed project for this registration.'
|
|
10353
|
+
: 'Choose a workspace and project for governed registration.',
|
|
10354
|
+
'',
|
|
10355
|
+
);
|
|
10356
|
+
});
|
|
10357
|
+
}
|
|
10143
10358
|
const quickReviewWorkspaceSelect = document.getElementById('quick-review-workspace');
|
|
10144
10359
|
if (quickReviewWorkspaceSelect) {
|
|
10145
10360
|
quickReviewWorkspaceSelect.addEventListener('change', () => {
|
|
10146
10361
|
const item = getQuickReviewItem();
|
|
10147
10362
|
const selectedWorkspaceId = String(quickReviewWorkspaceSelect.value || '').trim();
|
|
10148
|
-
const
|
|
10149
|
-
|
|
10150
|
-
void loadQuickReviewProjects(selectedWorkspaceId, '', governedMode);
|
|
10151
|
-
updateQuickReviewScopeSummary(governedMode);
|
|
10363
|
+
const reviewScopeMode = getReviewRegistrationMode('quick-review');
|
|
10364
|
+
void loadQuickReviewProjects(selectedWorkspaceId, '', reviewScopeMode);
|
|
10152
10365
|
setQuickReviewStatus(
|
|
10153
|
-
|
|
10154
|
-
?
|
|
10366
|
+
reviewScopeMode === 'workspace'
|
|
10367
|
+
? (selectedWorkspaceId
|
|
10368
|
+
? 'Choose the governed project for this registration.'
|
|
10369
|
+
: 'Choose a workspace and project for governed registration.')
|
|
10155
10370
|
: 'Solo registration stays available. Choose governed scope only when needed.',
|
|
10156
10371
|
'',
|
|
10157
10372
|
);
|
|
10158
|
-
const primaryButton = document.getElementById('quick-review-primary');
|
|
10159
|
-
if (primaryButton && item) {
|
|
10160
|
-
primaryButton.textContent = getReviewPrimaryLabel(item, selectedWorkspaceId ? 'workspace' : 'solo');
|
|
10161
|
-
}
|
|
10162
10373
|
if (item) {
|
|
10163
|
-
|
|
10374
|
+
syncQuickReviewRegistrationMode(item, reviewScopeMode);
|
|
10164
10375
|
}
|
|
10165
10376
|
});
|
|
10166
10377
|
}
|
|
10167
10378
|
const quickReviewProjectSelect = document.getElementById('quick-review-project');
|
|
10168
10379
|
if (quickReviewProjectSelect) {
|
|
10169
10380
|
quickReviewProjectSelect.addEventListener('change', () => {
|
|
10170
|
-
const primaryButton = document.getElementById('quick-review-primary');
|
|
10171
|
-
const selectedWorkspaceId = quickReviewWorkspaceSelect
|
|
10172
|
-
? String(quickReviewWorkspaceSelect.value || '').trim()
|
|
10173
|
-
: '';
|
|
10174
|
-
const selectedProjectId = String(quickReviewProjectSelect.value || '').trim();
|
|
10175
|
-
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10176
|
-
updateQuickReviewScopeSummary(governedMode);
|
|
10177
|
-
if (primaryButton) {
|
|
10178
|
-
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId);
|
|
10179
|
-
const item = getQuickReviewItem();
|
|
10180
|
-
if (item) {
|
|
10181
|
-
primaryButton.textContent = getReviewPrimaryLabel(item, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo');
|
|
10182
|
-
}
|
|
10183
|
-
}
|
|
10184
10381
|
const item = getQuickReviewItem();
|
|
10185
10382
|
if (item) {
|
|
10186
|
-
|
|
10383
|
+
syncQuickReviewRegistrationMode(item, getReviewRegistrationMode('quick-review'));
|
|
10187
10384
|
}
|
|
10188
10385
|
});
|
|
10189
10386
|
}
|
|
@@ -10217,26 +10414,53 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10217
10414
|
void submitDiscoveryReviewIgnore();
|
|
10218
10415
|
});
|
|
10219
10416
|
}
|
|
10417
|
+
const discoveryReviewModeSolo = document.getElementById('discovery-review-mode-solo');
|
|
10418
|
+
if (discoveryReviewModeSolo) {
|
|
10419
|
+
discoveryReviewModeSolo.addEventListener('click', () => {
|
|
10420
|
+
const selectedItem = getSelectedDiscoveryItem();
|
|
10421
|
+
if (!selectedItem || !canChooseReviewScope(selectedItem)) return;
|
|
10422
|
+
syncDiscoveryReviewRegistrationMode(selectedItem, 'solo');
|
|
10423
|
+
setDiscoveryReviewStatus('Solo registration is ready. Choose governed workspace only when needed.', '');
|
|
10424
|
+
});
|
|
10425
|
+
}
|
|
10426
|
+
const discoveryReviewModeWorkspace = document.getElementById('discovery-review-mode-workspace');
|
|
10427
|
+
if (discoveryReviewModeWorkspace) {
|
|
10428
|
+
discoveryReviewModeWorkspace.addEventListener('click', () => {
|
|
10429
|
+
const selectedItem = getSelectedDiscoveryItem();
|
|
10430
|
+
if (!selectedItem || !canChooseReviewScope(selectedItem)) return;
|
|
10431
|
+
syncDiscoveryReviewRegistrationMode(selectedItem, 'workspace');
|
|
10432
|
+
const selectedWorkspaceId = discoveryReviewWorkspaceSelect
|
|
10433
|
+
? String(discoveryReviewWorkspaceSelect.value || '').trim()
|
|
10434
|
+
: '';
|
|
10435
|
+
const selectedProjectId = discoveryReviewProjectSelect
|
|
10436
|
+
? String(discoveryReviewProjectSelect.value || '').trim()
|
|
10437
|
+
: '';
|
|
10438
|
+
void loadDiscoveryReviewProjects(selectedWorkspaceId, selectedProjectId, 'workspace');
|
|
10439
|
+
setDiscoveryReviewStatus(
|
|
10440
|
+
selectedWorkspaceId
|
|
10441
|
+
? 'Choose the governed project for this registration.'
|
|
10442
|
+
: 'Choose a workspace and project for governed registration.',
|
|
10443
|
+
'',
|
|
10444
|
+
);
|
|
10445
|
+
});
|
|
10446
|
+
}
|
|
10220
10447
|
const discoveryReviewWorkspaceSelect = document.getElementById('discovery-review-workspace');
|
|
10221
10448
|
if (discoveryReviewWorkspaceSelect) {
|
|
10222
10449
|
discoveryReviewWorkspaceSelect.addEventListener('change', () => {
|
|
10223
10450
|
const selectedItem = getSelectedDiscoveryItem();
|
|
10224
10451
|
const selectedWorkspaceId = String(discoveryReviewWorkspaceSelect.value || '').trim();
|
|
10225
|
-
const
|
|
10226
|
-
void loadDiscoveryReviewProjects(selectedWorkspaceId, '',
|
|
10452
|
+
const reviewScopeMode = getReviewRegistrationMode('discovery-review');
|
|
10453
|
+
void loadDiscoveryReviewProjects(selectedWorkspaceId, '', reviewScopeMode);
|
|
10227
10454
|
if (selectedItem && canReviewRegister(selectedItem)) {
|
|
10228
10455
|
setDiscoveryReviewStatus(
|
|
10229
|
-
|
|
10230
|
-
?
|
|
10456
|
+
reviewScopeMode === 'workspace'
|
|
10457
|
+
? (selectedWorkspaceId
|
|
10458
|
+
? 'Choose the governed project for this registration.'
|
|
10459
|
+
: 'Choose a workspace and project for governed registration.')
|
|
10231
10460
|
: 'Solo registration stays available. Choose governed scope only when needed.',
|
|
10232
10461
|
'',
|
|
10233
10462
|
);
|
|
10234
|
-
|
|
10235
|
-
primaryLabel: getReviewPrimaryLabel(selectedItem, selectedWorkspaceId ? 'workspace' : 'solo'),
|
|
10236
|
-
primaryEnabled: selectedItem.inboxGroup !== 'ignored',
|
|
10237
|
-
deferEnabled: canReviewDefer(selectedItem),
|
|
10238
|
-
ignoreEnabled: canReviewIgnore(selectedItem),
|
|
10239
|
-
});
|
|
10463
|
+
syncDiscoveryReviewRegistrationMode(selectedItem, reviewScopeMode);
|
|
10240
10464
|
}
|
|
10241
10465
|
});
|
|
10242
10466
|
}
|
|
@@ -10244,15 +10468,8 @@ function renderLauncherHtml(launcherToken) {
|
|
|
10244
10468
|
if (discoveryReviewProjectSelect) {
|
|
10245
10469
|
discoveryReviewProjectSelect.addEventListener('change', () => {
|
|
10246
10470
|
const selectedItem = getSelectedDiscoveryItem();
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
? String(discoveryReviewWorkspaceSelect.value || '').trim()
|
|
10250
|
-
: '';
|
|
10251
|
-
const selectedProjectId = String(discoveryReviewProjectSelect.value || '').trim();
|
|
10252
|
-
const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
|
|
10253
|
-
if (primaryButton && selectedItem && canReviewRegister(selectedItem)) {
|
|
10254
|
-
primaryButton.disabled = Boolean(selectedWorkspaceId && !selectedProjectId);
|
|
10255
|
-
primaryButton.textContent = getReviewPrimaryLabel(selectedItem, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo');
|
|
10471
|
+
if (selectedItem && canReviewRegister(selectedItem)) {
|
|
10472
|
+
syncDiscoveryReviewRegistrationMode(selectedItem, getReviewRegistrationMode('discovery-review'));
|
|
10256
10473
|
}
|
|
10257
10474
|
});
|
|
10258
10475
|
}
|
|
@@ -11022,10 +11239,8 @@ function createLauncherApp(options) {
|
|
|
11022
11239
|
return;
|
|
11023
11240
|
}
|
|
11024
11241
|
if (kind === 'agent') {
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
message: 'Agent defer is not available yet in the local review surface.',
|
|
11028
|
-
});
|
|
11242
|
+
options.service.deferDetectedAgent(selector, Number.isFinite(hours) ? hours : 24);
|
|
11243
|
+
response.json({ ok: true, message: 'Agent review deferred for 24 hours.' });
|
|
11029
11244
|
return;
|
|
11030
11245
|
}
|
|
11031
11246
|
response.status(400).json({ ok: false, message: 'Unsupported review kind.' });
|
|
@@ -11054,10 +11269,8 @@ function createLauncherApp(options) {
|
|
|
11054
11269
|
return;
|
|
11055
11270
|
}
|
|
11056
11271
|
if (kind === 'agent') {
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
message: 'Agent ignore is not available yet in the local review surface.',
|
|
11060
|
-
});
|
|
11272
|
+
options.service.ignoreDetectedAgent(selector);
|
|
11273
|
+
response.json({ ok: true, message: 'Agent review ignored locally.' });
|
|
11061
11274
|
return;
|
|
11062
11275
|
}
|
|
11063
11276
|
response.status(400).json({ ok: false, message: 'Unsupported review kind.' });
|
package/dist/v1/service.d.ts
CHANGED
|
@@ -402,6 +402,7 @@ export declare class ConnectV1Service {
|
|
|
402
402
|
private buildInboxItemId;
|
|
403
403
|
private isDeferredReviewActive;
|
|
404
404
|
private getModelReviewDisposition;
|
|
405
|
+
private getAgentReviewDisposition;
|
|
405
406
|
private getRuntimeReviewDisposition;
|
|
406
407
|
private buildModelVerificationSummary;
|
|
407
408
|
private buildRuntimeVerificationSummary;
|
|
@@ -768,7 +769,9 @@ export declare class ConnectV1Service {
|
|
|
768
769
|
runDoctorChecks(): Promise<DoctorCheck[]>;
|
|
769
770
|
markModelIgnored(modelName: string, digest: string): boolean;
|
|
770
771
|
ignoreDetectedModel(selector: string): boolean;
|
|
772
|
+
ignoreDetectedAgent(selector: string): boolean;
|
|
771
773
|
deferDetectedModel(selector: string, deferHours?: number): boolean;
|
|
774
|
+
deferDetectedAgent(selector: string, deferHours?: number): boolean;
|
|
772
775
|
markRuntimeIgnored(selector: string): boolean;
|
|
773
776
|
deferRuntimeSuggestion(selector: string, deferHours?: number): boolean;
|
|
774
777
|
ignoreRuntimeSuggestion(selector: string): boolean;
|
package/dist/v1/service.js
CHANGED
|
@@ -2153,6 +2153,15 @@ class ConnectV1Service {
|
|
|
2153
2153
|
}
|
|
2154
2154
|
return 'active';
|
|
2155
2155
|
}
|
|
2156
|
+
getAgentReviewDisposition(agent) {
|
|
2157
|
+
if (agent.review_state === 'ignored') {
|
|
2158
|
+
return 'ignored';
|
|
2159
|
+
}
|
|
2160
|
+
if (agent.review_state === 'deferred' && this.isDeferredReviewActive(agent.review_deferred_until)) {
|
|
2161
|
+
return 'deferred';
|
|
2162
|
+
}
|
|
2163
|
+
return 'active';
|
|
2164
|
+
}
|
|
2156
2165
|
getRuntimeReviewDisposition(runtimePassport) {
|
|
2157
2166
|
if (runtimePassport.review_state === 'ignored') {
|
|
2158
2167
|
return 'ignored';
|
|
@@ -3607,6 +3616,8 @@ class ConnectV1Service {
|
|
|
3607
3616
|
source_label: input.candidate.source_label ?? null,
|
|
3608
3617
|
detection_reason: input.candidate.reason ?? null,
|
|
3609
3618
|
},
|
|
3619
|
+
review_state: input.existing?.review_state,
|
|
3620
|
+
review_deferred_until: input.existing?.review_deferred_until ?? null,
|
|
3610
3621
|
};
|
|
3611
3622
|
}
|
|
3612
3623
|
queueAgentC2Event(agent, eventType, metadata = {}, occurredAt) {
|
|
@@ -4434,29 +4445,35 @@ class ConnectV1Service {
|
|
|
4434
4445
|
const sourceLabel = typeof metadata.source_label === 'string' && metadata.source_label.trim()
|
|
4435
4446
|
? metadata.source_label.trim()
|
|
4436
4447
|
: null;
|
|
4437
|
-
const
|
|
4448
|
+
const agentReviewStatus = link
|
|
4438
4449
|
? 'linked_agent'
|
|
4439
4450
|
: agent.agent_type === 'unknown_ai_tool'
|
|
4440
4451
|
? 'unknown_ai_tool'
|
|
4441
4452
|
: agent.detected_at === agent.last_seen_at
|
|
4442
4453
|
? 'new_agent'
|
|
4443
4454
|
: 'known_agent';
|
|
4455
|
+
const reviewDisposition = this.getAgentReviewDisposition(agent);
|
|
4456
|
+
if (reviewDisposition === 'deferred') {
|
|
4457
|
+
continue;
|
|
4458
|
+
}
|
|
4444
4459
|
const agentObservation = this.buildAgentObservationStatus(agent);
|
|
4445
|
-
const group =
|
|
4460
|
+
const group = reviewDisposition === 'ignored'
|
|
4446
4461
|
? 'ignored'
|
|
4447
|
-
:
|
|
4448
|
-
? '
|
|
4449
|
-
:
|
|
4450
|
-
? '
|
|
4451
|
-
:
|
|
4462
|
+
: agent.status === 'inactive'
|
|
4463
|
+
? 'ignored'
|
|
4464
|
+
: link
|
|
4465
|
+
? 'connected'
|
|
4466
|
+
: candidate.model
|
|
4467
|
+
? 'needs_confirmation'
|
|
4468
|
+
: 'ready_to_connect';
|
|
4452
4469
|
const observedWorkspaceId = normalizeDisplayText(metadata.observation_workspace_id ?? metadata.workspaceId ?? metadata.workspace_id);
|
|
4453
4470
|
const observedProjectId = normalizeDisplayText(metadata.observation_project_id ?? metadata.projectId ?? metadata.project_id);
|
|
4454
4471
|
const scopeSuggestion = this.resolveScopeSuggestion(currentState, observedWorkspaceId, observedProjectId);
|
|
4455
4472
|
const itemId = this.buildInboxItemId('agent', agent.agent_id);
|
|
4456
4473
|
const recommendedAction = link ? 'open_on_forkit' : 'link_agent_to_model';
|
|
4457
4474
|
const allowedActions = this.filterInboxActionsForBinding(link
|
|
4458
|
-
? ['open_on_forkit', 'ignore']
|
|
4459
|
-
: ['link_agent_to_model', 'ignore', 'open_on_forkit'], currentState);
|
|
4475
|
+
? ['open_on_forkit', 'defer', 'ignore']
|
|
4476
|
+
: ['link_agent_to_model', 'defer', 'ignore', 'open_on_forkit'], currentState);
|
|
4460
4477
|
if (scopeSuggestion.scope_mismatch_detected && scopeSuggestion.scope_mismatch_reason) {
|
|
4461
4478
|
this.maybeRecordScopeMismatchEvidence(currentState, {
|
|
4462
4479
|
itemType: 'agent',
|
|
@@ -4501,7 +4518,8 @@ class ConnectV1Service {
|
|
|
4501
4518
|
last_observed_tool_at: agentObservation.lastObservedToolAt,
|
|
4502
4519
|
last_tool_decision: agentObservation.lastToolDecision,
|
|
4503
4520
|
source_label: sourceLabel,
|
|
4504
|
-
review_disposition:
|
|
4521
|
+
review_disposition: agentReviewStatus,
|
|
4522
|
+
local_review_disposition: reviewDisposition,
|
|
4505
4523
|
scope_suggestion: scopeSuggestion.scope_suggestion,
|
|
4506
4524
|
scope_suggestion_kind: scopeSuggestion.scope_suggestion_kind,
|
|
4507
4525
|
scope_suggestion_source_label: scopeSuggestion.scope_suggestion_source_label,
|
|
@@ -9024,6 +9042,21 @@ class ConnectV1Service {
|
|
|
9024
9042
|
const model = this.resolveModelSelection(selector, state);
|
|
9025
9043
|
return this.markModelIgnored(model.model, model.digest);
|
|
9026
9044
|
}
|
|
9045
|
+
ignoreDetectedAgent(selector) {
|
|
9046
|
+
const state = this.stateStore.readState();
|
|
9047
|
+
const agent = this.findAgentByIdOrName(state, selector);
|
|
9048
|
+
if (!agent)
|
|
9049
|
+
return false;
|
|
9050
|
+
const nextAgents = state.detected_agents.map((item) => item.agent_id === agent.agent_id
|
|
9051
|
+
? {
|
|
9052
|
+
...item,
|
|
9053
|
+
review_state: 'ignored',
|
|
9054
|
+
review_deferred_until: null,
|
|
9055
|
+
}
|
|
9056
|
+
: item);
|
|
9057
|
+
this.stateStore.replaceDetectedAgents(nextAgents);
|
|
9058
|
+
return true;
|
|
9059
|
+
}
|
|
9027
9060
|
deferDetectedModel(selector, deferHours = 24) {
|
|
9028
9061
|
const state = this.stateStore.readState();
|
|
9029
9062
|
const model = this.resolveModelSelection(selector, state);
|
|
@@ -9038,6 +9071,22 @@ class ConnectV1Service {
|
|
|
9038
9071
|
this.stateStore.replaceDetectedModels(nextModels);
|
|
9039
9072
|
return true;
|
|
9040
9073
|
}
|
|
9074
|
+
deferDetectedAgent(selector, deferHours = 24) {
|
|
9075
|
+
const state = this.stateStore.readState();
|
|
9076
|
+
const agent = this.findAgentByIdOrName(state, selector);
|
|
9077
|
+
if (!agent)
|
|
9078
|
+
return false;
|
|
9079
|
+
const deferredUntil = new Date(Date.now() + Math.max(1, deferHours) * 60 * 60 * 1000).toISOString();
|
|
9080
|
+
const nextAgents = state.detected_agents.map((item) => item.agent_id === agent.agent_id
|
|
9081
|
+
? {
|
|
9082
|
+
...item,
|
|
9083
|
+
review_state: 'deferred',
|
|
9084
|
+
review_deferred_until: deferredUntil,
|
|
9085
|
+
}
|
|
9086
|
+
: item);
|
|
9087
|
+
this.stateStore.replaceDetectedAgents(nextAgents);
|
|
9088
|
+
return true;
|
|
9089
|
+
}
|
|
9041
9090
|
markRuntimeIgnored(selector) {
|
|
9042
9091
|
const state = this.stateStore.readState();
|
|
9043
9092
|
const runtimePassport = this.resolveRuntimePassportSelection(selector, state);
|
package/dist/v1/types.d.ts
CHANGED
|
@@ -569,6 +569,8 @@ export interface DetectedAgent {
|
|
|
569
569
|
persistence?: 'temporary' | 'permanent';
|
|
570
570
|
discovery_sources: AgentDiscoverySource[];
|
|
571
571
|
metadata: Record<string, unknown>;
|
|
572
|
+
review_state?: ReviewDisposition | undefined;
|
|
573
|
+
review_deferred_until?: string | null;
|
|
572
574
|
}
|
|
573
575
|
/**
|
|
574
576
|
* AgentLink (M2: Agent Class Metadata in linkage)
|