forkit-connect 0.1.11 → 0.1.12

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.
Files changed (2) hide show
  1. package/dist/launcher.js +330 -113
  2. 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-scope-grid">
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-scope-grid">
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>
@@ -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(governedMode) {
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', governedMode ? 'Choose governed scope' : 'Account scope');
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
- async function loadQuickReviewProjects(workspaceId, selectedProjectId, governedMode) {
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
- setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
7816
- if (primaryButton) primaryButton.disabled = false;
7817
- updateQuickReviewScopeSummary(governedMode);
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(governedMode);
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(governedMode);
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 needsScope = canReviewRegister(item);
7905
- if (!needsScope) {
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.kind === 'runtime' ? 'Open runtime review' : 'Full review available');
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, item.projectId || payload.currentProjectId || '', governedMode);
7936
- const reviewScopeMode = getReviewScopeMode(
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
- ? 'Choose the governed workspace and project for this registration.'
7944
- : 'Solo registration is ready. Choose governed scope only when needed.')
7945
- : (payload.message || 'Workspace access is unavailable right now.'),
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
- setQuickReviewStatus('Workspace access is unavailable right now.', 'warn');
7957
- if (primaryButton) {
7958
- primaryButton.disabled = true;
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 workspaceId = workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
7981
- const projectId = projectSelect ? String(projectSelect.value || '').trim() : '';
7982
- const governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
7983
- if (workspaceId && !projectId) {
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
- async function loadDiscoveryReviewProjects(workspaceId, selectedProjectId, governedMode) {
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
- setScopeOptions(projectSelect, [{ id: '', label: 'Solo registration / no project' }], '');
8066
- if (primaryButton) primaryButton.disabled = false;
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 needsScope = canReviewRegister(item);
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 (!needsScope) {
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, item.projectId || payload.currentProjectId || '', governedMode);
8162
- const reviewScopeMode = getReviewScopeMode(
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
- ? 'Choose the governed workspace and project for this registration.'
8170
- : 'Solo registration is ready. Choose governed scope only when needed.')
8171
- : (payload.message || 'Workspace access is unavailable right now.'),
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
- setDiscoveryReviewStatus('Workspace access is unavailable right now.', 'warn');
8184
- setDiscoveryReviewButtons({
8185
- primaryLabel,
8186
- primaryEnabled: false,
8187
- deferEnabled: canReviewDefer(item),
8188
- ignoreEnabled: canReviewIgnore(item),
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 workspaceId = workspaceSelect ? String(workspaceSelect.value || '').trim() : '';
8208
- const projectId = projectSelect ? String(projectSelect.value || '').trim() : '';
8209
- if (workspaceId && !projectId) {
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 governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
10149
- quickReviewScopeCacheKey = null;
10150
- void loadQuickReviewProjects(selectedWorkspaceId, '', governedMode);
10151
- updateQuickReviewScopeSummary(governedMode);
10363
+ const reviewScopeMode = getReviewRegistrationMode('quick-review');
10364
+ void loadQuickReviewProjects(selectedWorkspaceId, '', reviewScopeMode);
10152
10365
  setQuickReviewStatus(
10153
- selectedWorkspaceId
10154
- ? 'Choose the governed project for this registration.'
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
- setText('quick-review-action-summary', getReviewActionSummary(item, selectedWorkspaceId ? 'workspace' : 'solo'));
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
- setText('quick-review-action-summary', getReviewActionSummary(item, selectedWorkspaceId && selectedProjectId ? 'workspace' : 'solo'));
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 governedMode = Boolean(scopeAccessSnapshot && scopeAccessSnapshot.operatingMode === 'governed');
10226
- void loadDiscoveryReviewProjects(selectedWorkspaceId, '', governedMode);
10452
+ const reviewScopeMode = getReviewRegistrationMode('discovery-review');
10453
+ void loadDiscoveryReviewProjects(selectedWorkspaceId, '', reviewScopeMode);
10227
10454
  if (selectedItem && canReviewRegister(selectedItem)) {
10228
10455
  setDiscoveryReviewStatus(
10229
- selectedWorkspaceId
10230
- ? 'Choose the governed project for this registration.'
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
- setDiscoveryReviewButtons({
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
- const primaryButton = document.getElementById('discovery-review-primary');
10248
- const selectedWorkspaceId = discoveryReviewWorkspaceSelect
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",