forkit-connect 0.1.16 → 0.1.18

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 +326 -82
  2. package/package.json +1 -1
package/dist/launcher.js CHANGED
@@ -1250,6 +1250,18 @@ async function buildSettings(service, options) {
1250
1250
  const config = service.getConfig();
1251
1251
  const entitlements = service.getServiceEntitlements();
1252
1252
  const updateCheck = options?.updateChecker ? await options.updateChecker() : await (0, update_1.checkForUpdates)();
1253
+ const effectiveBinding = service.getEffectiveBinding();
1254
+ const approvedUser = effectiveBinding?.approved_user ?? null;
1255
+ const approvedUserRecord = approvedUser;
1256
+ const avatarUrl = safeStringRecordValue(approvedUserRecord, [
1257
+ 'avatarUrl',
1258
+ 'avatar_url',
1259
+ 'picture',
1260
+ 'pictureUrl',
1261
+ 'picture_url',
1262
+ 'photoUrl',
1263
+ 'photo_url',
1264
+ ]);
1253
1265
  const capabilities = [
1254
1266
  { key: 'secure_device_pairing', enabled: entitlements.secure_device_pairing },
1255
1267
  { key: 'signed_events', enabled: entitlements.signed_events },
@@ -1268,6 +1280,10 @@ async function buildSettings(service, options) {
1268
1280
  tier: entitlements.tier,
1269
1281
  workspaceBound: entitlements.workspace_bound,
1270
1282
  projectBound: entitlements.project_bound,
1283
+ displayName: approvedUser?.name ?? null,
1284
+ email: approvedUser?.email ?? null,
1285
+ goaid: approvedUser?.goaid ?? null,
1286
+ avatarUrl,
1271
1287
  },
1272
1288
  preferences: {
1273
1289
  discoveryMode: config.discovery_mode,
@@ -1318,7 +1334,7 @@ function renderLauncherHtml(launcherToken) {
1318
1334
  <head>
1319
1335
  <meta charset="UTF-8" />
1320
1336
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1321
- <title>Forkit Connect Command Center</title>
1337
+ <title>Forkit Connect Status</title>
1322
1338
  <link rel="preconnect" href="https://fonts.googleapis.com">
1323
1339
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1324
1340
  <link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
@@ -1336,6 +1352,20 @@ function renderLauncherHtml(launcherToken) {
1336
1352
  --surface-strong: rgba(34, 26, 68, 0.88);
1337
1353
  --border: rgba(241, 235, 223, 0.18);
1338
1354
  --glass-shadow: 0 24px 70px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.08);
1355
+ --launcher-text-strong: #fff8ef;
1356
+ --launcher-text-primary: rgba(241, 235, 223, 0.92);
1357
+ --launcher-text-secondary: rgba(241, 235, 223, 0.8);
1358
+ --launcher-text-muted: rgba(241, 235, 223, 0.68);
1359
+ --launcher-text-faint: rgba(241, 235, 223, 0.55);
1360
+ --launcher-surface-soft: rgba(255, 255, 255, 0.045);
1361
+ --launcher-surface-muted: rgba(255, 255, 255, 0.038);
1362
+ --launcher-surface-strong: rgba(17, 19, 30, 0.985);
1363
+ --launcher-border-soft: rgba(241, 235, 223, 0.1);
1364
+ --launcher-border-strong: rgba(241, 235, 223, 0.16);
1365
+ --launcher-border-accent: rgba(157, 238, 245, 0.18);
1366
+ --launcher-accent-text: rgba(157, 238, 245, 0.92);
1367
+ --launcher-warning-text: rgba(255, 211, 178, 0.9);
1368
+ --launcher-shadow-strong: 0 28px 56px rgba(7, 10, 24, 0.42);
1339
1369
  --traffic-intensity: 32;
1340
1370
  --traffic-speed: 12s;
1341
1371
  }
@@ -1876,17 +1906,17 @@ function renderLauncherHtml(launcherToken) {
1876
1906
 
1877
1907
  .quick-review-card {
1878
1908
  display: grid;
1879
- gap: 14px;
1909
+ gap: 12px;
1880
1910
  padding: 18px;
1881
1911
  border-radius: 26px;
1882
- border: 1px solid rgba(241, 235, 223, 0.16);
1912
+ border: 1px solid var(--launcher-border-strong);
1883
1913
  background:
1884
1914
  radial-gradient(circle at 100% 0%, rgba(106, 167, 171, 0.18), transparent 38%),
1885
1915
  linear-gradient(135deg, rgba(24, 22, 38, 0.98) 0%, rgba(17, 19, 30, 0.985) 100%);
1886
1916
  box-shadow:
1887
- 0 28px 56px rgba(7, 10, 24, 0.42),
1917
+ var(--launcher-shadow-strong),
1888
1918
  inset 0 1px 0 rgba(255,255,255,0.07);
1889
- color: #f7efe4;
1919
+ color: var(--launcher-text-primary);
1890
1920
  }
1891
1921
 
1892
1922
  .review-summary-grid {
@@ -1897,11 +1927,11 @@ function renderLauncherHtml(launcherToken) {
1897
1927
 
1898
1928
  .review-summary-pill {
1899
1929
  display: grid;
1900
- gap: 4px;
1901
- padding: 11px 12px;
1930
+ gap: 3px;
1931
+ padding: 10px 12px;
1902
1932
  border-radius: 16px;
1903
- border: 1px solid rgba(241, 235, 223, 0.1);
1904
- background: rgba(255,255,255,0.045);
1933
+ border: 1px solid var(--launcher-border-soft);
1934
+ background: var(--launcher-surface-soft);
1905
1935
  }
1906
1936
 
1907
1937
  .review-summary-label {
@@ -1909,13 +1939,13 @@ function renderLauncherHtml(launcherToken) {
1909
1939
  text-transform: uppercase;
1910
1940
  letter-spacing: 0.12em;
1911
1941
  font-weight: 700;
1912
- color: rgba(241, 235, 223, 0.55);
1942
+ color: var(--launcher-text-faint);
1913
1943
  }
1914
1944
 
1915
1945
  .review-summary-value {
1916
1946
  font-size: 0.86rem;
1917
1947
  line-height: 1.35;
1918
- color: #fff7ea;
1948
+ color: var(--launcher-text-strong);
1919
1949
  font-weight: 600;
1920
1950
  }
1921
1951
 
@@ -1924,7 +1954,7 @@ function renderLauncherHtml(launcherToken) {
1924
1954
  gap: 6px;
1925
1955
  padding: 14px 15px;
1926
1956
  border-radius: 18px;
1927
- border: 1px solid rgba(157, 238, 245, 0.14);
1957
+ border: 1px solid var(--launcher-border-accent);
1928
1958
  background:
1929
1959
  linear-gradient(180deg, rgba(39, 51, 69, 0.52), rgba(22, 18, 47, 0.72)),
1930
1960
  radial-gradient(circle at top right, rgba(244, 147, 85, 0.12), transparent 52%);
@@ -1937,7 +1967,7 @@ function renderLauncherHtml(launcherToken) {
1937
1967
  text-transform: uppercase;
1938
1968
  letter-spacing: 0.13em;
1939
1969
  font-weight: 700;
1940
- color: rgba(157, 238, 245, 0.82);
1970
+ color: var(--launcher-accent-text);
1941
1971
  }
1942
1972
 
1943
1973
  .review-recommendation-title {
@@ -1945,7 +1975,7 @@ function renderLauncherHtml(launcherToken) {
1945
1975
  font-family: "Sora", sans-serif;
1946
1976
  font-size: 1rem;
1947
1977
  line-height: 1.2;
1948
- color: #fff8ef;
1978
+ color: var(--launcher-text-strong);
1949
1979
  font-weight: 700;
1950
1980
  }
1951
1981
 
@@ -1953,7 +1983,7 @@ function renderLauncherHtml(launcherToken) {
1953
1983
  margin: 0;
1954
1984
  font-size: 0.86rem;
1955
1985
  line-height: 1.5;
1956
- color: rgba(241, 235, 223, 0.74);
1986
+ color: var(--launcher-text-secondary);
1957
1987
  }
1958
1988
 
1959
1989
  .quick-review-topline {
@@ -1969,7 +1999,7 @@ function renderLauncherHtml(launcherToken) {
1969
1999
  text-transform: uppercase;
1970
2000
  letter-spacing: 0.12em;
1971
2001
  font-weight: 700;
1972
- color: rgba(157, 238, 245, 0.84);
2002
+ color: var(--launcher-accent-text);
1973
2003
  }
1974
2004
 
1975
2005
  .quick-review-title {
@@ -1978,7 +2008,7 @@ function renderLauncherHtml(launcherToken) {
1978
2008
  font-size: 1.22rem;
1979
2009
  line-height: 1.12;
1980
2010
  letter-spacing: -0.02em;
1981
- color: #fff8ef;
2011
+ color: var(--launcher-text-strong);
1982
2012
  }
1983
2013
 
1984
2014
  .quick-review-badge {
@@ -1991,7 +2021,7 @@ function renderLauncherHtml(launcherToken) {
1991
2021
  border-radius: 999px;
1992
2022
  border: 1px solid rgba(157, 238, 245, 0.26);
1993
2023
  background: rgba(55, 68, 86, 0.42);
1994
- color: rgba(157, 238, 245, 0.96);
2024
+ color: var(--launcher-accent-text);
1995
2025
  font-family: "Sora", sans-serif;
1996
2026
  font-size: 0.88rem;
1997
2027
  font-weight: 700;
@@ -1999,21 +2029,32 @@ function renderLauncherHtml(launcherToken) {
1999
2029
  text-transform: uppercase;
2000
2030
  }
2001
2031
 
2002
- .quick-review-meta,
2032
+ .quick-review-meta {
2033
+ margin: 0;
2034
+ font-size: 0.8rem;
2035
+ line-height: 1.35;
2036
+ color: var(--launcher-text-muted);
2037
+ letter-spacing: 0.01em;
2038
+ }
2039
+
2003
2040
  .quick-review-detail {
2004
2041
  margin: 0;
2005
- font-size: 0.92rem;
2006
- line-height: 1.5;
2007
- color: rgba(241, 235, 223, 0.78);
2042
+ font-size: 0.86rem;
2043
+ line-height: 1.45;
2044
+ color: var(--launcher-text-secondary);
2045
+ }
2046
+
2047
+ .quick-review-detail[hidden] {
2048
+ display: none;
2008
2049
  }
2009
2050
 
2010
2051
  .quick-review-status {
2011
2052
  border-radius: 16px;
2012
- padding: 12px 14px;
2053
+ padding: 10px 13px;
2013
2054
  border: 1px solid rgba(202, 188, 255, 0.12);
2014
- background: rgba(255,255,255,0.04);
2015
- color: rgba(241, 235, 223, 0.8);
2016
- font-size: 0.88rem;
2055
+ background: var(--launcher-surface-muted);
2056
+ color: var(--launcher-text-secondary);
2057
+ font-size: 0.84rem;
2017
2058
  line-height: 1.45;
2018
2059
  }
2019
2060
 
@@ -2144,7 +2185,7 @@ function renderLauncherHtml(launcherToken) {
2144
2185
  padding: 12px 13px;
2145
2186
  border-radius: 16px;
2146
2187
  border: 1px solid rgba(244, 147, 85, 0.16);
2147
- background: rgba(255,255,255,0.038);
2188
+ background: var(--launcher-surface-muted);
2148
2189
  }
2149
2190
 
2150
2191
  .review-resolution-shell[hidden] {
@@ -2157,14 +2198,14 @@ function renderLauncherHtml(launcherToken) {
2157
2198
  text-transform: uppercase;
2158
2199
  letter-spacing: 0.12em;
2159
2200
  font-weight: 700;
2160
- color: rgba(255, 211, 178, 0.82);
2201
+ color: var(--launcher-warning-text);
2161
2202
  }
2162
2203
 
2163
2204
  .review-resolution-copy {
2164
2205
  margin: 0;
2165
2206
  font-size: 0.84rem;
2166
2207
  line-height: 1.45;
2167
- color: rgba(241, 235, 223, 0.72);
2208
+ color: var(--launcher-text-secondary);
2168
2209
  }
2169
2210
 
2170
2211
  .review-resolution-actions[hidden] {
@@ -2554,7 +2595,7 @@ function renderLauncherHtml(launcherToken) {
2554
2595
  font-family: "Sora", sans-serif;
2555
2596
  font-size: 0.96rem;
2556
2597
  line-height: 1.2;
2557
- color: #fff8ef;
2598
+ color: var(--launcher-text-strong);
2558
2599
  overflow: hidden;
2559
2600
  text-overflow: ellipsis;
2560
2601
  white-space: nowrap;
@@ -2564,19 +2605,50 @@ function renderLauncherHtml(launcherToken) {
2564
2605
  display: block;
2565
2606
  margin-top: 3px;
2566
2607
  font-size: 0.78rem;
2567
- color: rgba(241,235,223,0.66);
2608
+ color: var(--launcher-text-muted);
2568
2609
  overflow: hidden;
2569
2610
  text-overflow: ellipsis;
2570
2611
  white-space: nowrap;
2571
2612
  }
2572
2613
 
2614
+ .launch-account-menu-summary {
2615
+ display: grid;
2616
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2617
+ gap: 8px;
2618
+ padding: 0 2px 6px;
2619
+ }
2620
+
2621
+ .launch-account-menu-metric {
2622
+ display: grid;
2623
+ gap: 4px;
2624
+ padding: 10px 11px;
2625
+ border-radius: 14px;
2626
+ border: 1px solid var(--launcher-border-soft);
2627
+ background: var(--launcher-surface-soft);
2628
+ }
2629
+
2630
+ .launch-account-menu-metric-label {
2631
+ font-size: 0.66rem;
2632
+ text-transform: uppercase;
2633
+ letter-spacing: 0.12em;
2634
+ font-weight: 700;
2635
+ color: var(--launcher-text-faint);
2636
+ }
2637
+
2638
+ .launch-account-menu-metric-value {
2639
+ font-size: 0.84rem;
2640
+ line-height: 1.35;
2641
+ color: var(--launcher-text-strong);
2642
+ font-weight: 600;
2643
+ }
2644
+
2573
2645
  .launch-account-action {
2574
2646
  appearance: none;
2575
2647
  width: 100%;
2576
2648
  border: 1px solid transparent;
2577
2649
  border-radius: 12px;
2578
- background: rgba(255,255,255,0.035);
2579
- color: #f1ebdf;
2650
+ background: var(--launcher-surface-muted);
2651
+ color: var(--launcher-text-primary);
2580
2652
  text-align: left;
2581
2653
  padding: 11px 12px;
2582
2654
  font-size: 0.9rem;
@@ -3994,6 +4066,23 @@ function renderLauncherHtml(launcherToken) {
3994
4066
  .chart svg { width: 100%; height: 100%; display: block; }
3995
4067
 
3996
4068
  .status-line { margin: 6px 0; font-size: 0.92rem; color: rgba(42, 31, 85, 0.9); }
4069
+
4070
+ .discovery-side-meta {
4071
+ display: inline-flex;
4072
+ align-items: center;
4073
+ gap: 8px;
4074
+ width: fit-content;
4075
+ min-height: 34px;
4076
+ padding: 0 12px;
4077
+ border-radius: 999px;
4078
+ border: 1px solid var(--launcher-border-soft);
4079
+ background: rgba(18, 15, 40, 0.72);
4080
+ color: var(--launcher-text-primary);
4081
+ font-size: 0.8rem;
4082
+ font-weight: 600;
4083
+ letter-spacing: 0.01em;
4084
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
4085
+ }
3997
4086
  .ok { color: #0b7f46; }
3998
4087
  .warn { color: #a85b00; }
3999
4088
  .error { color: #a11522; }
@@ -6460,11 +6549,11 @@ function renderLauncherHtml(launcherToken) {
6460
6549
  <nav class="sidebar-nav" id="sidebar-nav">
6461
6550
  <button class="sidebar-nav-item active" id="nav-command" data-view="command" type="button">
6462
6551
  <svg class="sidebar-nav-icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M3 5h14M3 10h14M3 15h7"/></svg>
6463
- Command Center
6552
+ Status
6464
6553
  </button>
6465
6554
  <button class="sidebar-nav-item" id="nav-discovery" data-view="discovery" type="button">
6466
6555
  <svg class="sidebar-nav-icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="10" cy="10" r="7"/><circle cx="10" cy="10" r="3"/></svg>
6467
- Discovery
6556
+ Inbox
6468
6557
  </button>
6469
6558
  <button class="sidebar-nav-item" id="nav-passports" data-view="passports" type="button">
6470
6559
  <svg class="sidebar-nav-icon" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="4" y="2" width="12" height="16" rx="2"/><path d="M7 7h6M7 11h4"/></svg>
@@ -6504,8 +6593,8 @@ function renderLauncherHtml(launcherToken) {
6504
6593
  <div class="main-area">
6505
6594
  <div class="page-header command-header">
6506
6595
  <div class="page-title-block">
6507
- <div class="page-title" id="page-title">Good morning!</div>
6508
- <div class="page-subtitle" id="activity-message">Forkit Connect keeps your AI environment in sync with Forkit.dev.</div>
6596
+ <div class="page-title" id="page-title">Status</div>
6597
+ <div class="page-subtitle" id="activity-message">Review account, scope, daemon, inbox, and runtime health for this device.</div>
6509
6598
  </div>
6510
6599
  <div class="page-header-controls">
6511
6600
  <div class="status-chip" id="connection-pill">
@@ -6552,8 +6641,8 @@ function renderLauncherHtml(launcherToken) {
6552
6641
  </div>
6553
6642
  <span class="quick-review-badge" id="quick-review-badge">Review</span>
6554
6643
  </div>
6555
- <p class="quick-review-meta" id="quick-review-meta">Open Connect to approve or defer this item.</p>
6556
- <p class="quick-review-detail" id="quick-review-detail">Nothing is registered automatically.</p>
6644
+ <p class="quick-review-meta" id="quick-review-meta">Model · Local</p>
6645
+ <p class="quick-review-detail" id="quick-review-detail" hidden>Nothing is registered automatically.</p>
6557
6646
  <div class="review-summary-grid">
6558
6647
  <div class="review-summary-pill">
6559
6648
  <span class="review-summary-label">Action</span>
@@ -6632,9 +6721,27 @@ function renderLauncherHtml(launcherToken) {
6632
6721
  <span class="launch-account-menu-subtitle" id="account-menu-subtitle">Account scope</span>
6633
6722
  </span>
6634
6723
  </div>
6724
+ <div class="launch-account-menu-summary">
6725
+ <div class="launch-account-menu-metric">
6726
+ <span class="launch-account-menu-metric-label">Plan</span>
6727
+ <span class="launch-account-menu-metric-value" id="account-menu-tier">Solo</span>
6728
+ </div>
6729
+ <div class="launch-account-menu-metric">
6730
+ <span class="launch-account-menu-metric-label">Sync</span>
6731
+ <span class="launch-account-menu-metric-value" id="account-menu-sync">Not signed in</span>
6732
+ </div>
6733
+ </div>
6734
+ <button class="launch-account-action" id="account-open-profile" type="button">
6735
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="8" r="3.5" stroke="currentColor" stroke-width="1.7"/><path d="M5 20c0-4 3.2-6.5 7-6.5s7 2.5 7 6.5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
6736
+ Open Profile
6737
+ </button>
6738
+ <button class="launch-account-action" id="account-open-security" type="button">
6739
+ <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 3l7 3v5c0 4-3.5 7-7 8-3.5-1-7-4-7-8V6l7-3Z" stroke="currentColor" stroke-width="1.7"/><path d="M9.5 11.5 11 13l3.5-3.5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
6740
+ Account Security
6741
+ </button>
6635
6742
  <button class="launch-account-action" id="account-open-settings" type="button">
6636
6743
  <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z" stroke="currentColor" stroke-width="1.7"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.88l.05.05a2 2 0 1 1-2.83 2.83l-.05-.05A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 .6l-.03.03a2 2 0 0 1-3.42-1.42v-.07A1.7 1.7 0 0 0 9.5 17a1.7 1.7 0 0 0-1.88.34l-.05.05a2 2 0 1 1-2.83-2.83l.05-.05A1.7 1.7 0 0 0 5.1 12a1.7 1.7 0 0 0-.6-1l-.03-.03a2 2 0 0 1 1.42-3.42h.07A1.7 1.7 0 0 0 7 6.5a1.7 1.7 0 0 0-.34-1.88l-.05-.05a2 2 0 1 1 2.83-2.83l.05.05A1.7 1.7 0 0 0 12 4.9a1.7 1.7 0 0 0 1-.6l.03-.03a2 2 0 0 1 3.42 1.42v.07A1.7 1.7 0 0 0 17 7a1.7 1.7 0 0 0 1.88-.34l.05-.05a2 2 0 1 1 2.83 2.83l-.05.05A1.7 1.7 0 0 0 19.4 12Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
6637
- Open Settings
6744
+ Launcher Settings
6638
6745
  </button>
6639
6746
  <button class="launch-account-action" id="account-switch-account" type="button">
6640
6747
  <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M8 21H5a2 2 0 0 1-2-2v-3M3 8V5a2 2 0 0 1 2-2h3" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/><path d="M8 12h8M13 9l3 3-3 3" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
@@ -6728,7 +6835,7 @@ function renderLauncherHtml(launcherToken) {
6728
6835
 
6729
6836
  <p class="login-alt">Don't have an account? <button type="button" id="login-create-account">Create account</button></p>
6730
6837
 
6731
- <div class="login-note">Global-ready auth is currently powered by secure device-code sign in. After sign in is approved on Forkit.dev, this screen switches to Command Center automatically.</div>
6838
+ <div class="login-note">Global-ready auth is currently powered by secure device-code sign in. After sign in is approved on Forkit.dev, this screen switches to Status automatically.</div>
6732
6839
  </form>
6733
6840
  </section>
6734
6841
  </section>
@@ -6808,11 +6915,11 @@ function renderLauncherHtml(launcherToken) {
6808
6915
  </svg>
6809
6916
  </div>
6810
6917
  <div class="command-hero-content">
6811
- <h2>Everything is in sync</h2>
6812
- <p>Your local AI environment is healthy and all systems are up to date.</p>
6918
+ <h2>Connect status</h2>
6919
+ <p>Account, scope, daemon, inbox, and runtime health for this device.</p>
6813
6920
  <div class="command-hero-actions">
6814
- <button class="primary" id="cmd-open-passports">Open Passports</button>
6815
- <button class="secondary" id="cmd-check-status">Check Status</button>
6921
+ <button class="primary" id="cmd-open-passports">Open Inbox</button>
6922
+ <button class="secondary" id="cmd-check-status">Open Runtime</button>
6816
6923
  </div>
6817
6924
  </div>
6818
6925
  </div>
@@ -6831,8 +6938,8 @@ function renderLauncherHtml(launcherToken) {
6831
6938
  <div class="command-card-icon" aria-hidden="true">
6832
6939
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7"><path d="M17.5 18H8a5 5 0 1 1 .9-9.9 6 6 0 0 1 11.5 2.6A3.8 3.8 0 0 1 17.5 18Z"/><path d="M9 13l2.2 2.2L16 10.5"/></svg>
6833
6940
  </div>
6834
- <h3>Workspace Sync</h3>
6835
- <div class="command-card-stat">Synced with Forkit.dev</div>
6941
+ <h3>Active Scope</h3>
6942
+ <div class="command-card-stat">Solo or governed scope</div>
6836
6943
  <div class="command-card-items">
6837
6944
  <div class="command-card-item">
6838
6945
  <span class="command-card-item-label">Workspace</span>
@@ -6882,10 +6989,10 @@ function renderLauncherHtml(launcherToken) {
6882
6989
  <div id="view-discovery" class="view-hidden discovery-shell">
6883
6990
  <div class="discovery-page-intro">
6884
6991
  <div class="discovery-page-title-row">
6885
- <h2>Discovery</h2>
6992
+ <h2>Inbox</h2>
6886
6993
  <span class="discovery-page-count" id="discovery-page-count">0</span>
6887
6994
  </div>
6888
- <p>Detected models, agents and runtimes on your machine. Review and register them to create <strong>Passports on Forkit.dev</strong>.</p>
6995
+ <p>Models, agents, and runtimes waiting for action on this device. Review them to continue registration, reuse an existing passport, or open runtime work.</p>
6889
6996
  </div>
6890
6997
  <div class="discovery-feedback" id="discovery-feedback" hidden></div>
6891
6998
 
@@ -6957,9 +7064,9 @@ function renderLauncherHtml(launcherToken) {
6957
7064
  </svg>
6958
7065
  </div>
6959
7066
 
6960
- <div class="status-line" id="discovery-last-scan">Last scan: -</div>
6961
- <h3 class="discovery-side-title">Discovery intelligence</h3>
6962
- <p class="discovery-side-copy">We automatically scan your environment and understand the systems running locally.</p>
7067
+ <div class="discovery-side-meta" id="discovery-last-scan">Last scan · unavailable</div>
7068
+ <h3 class="discovery-side-title">Inbox review</h3>
7069
+ <p class="discovery-side-copy">Select an inbox item and continue the exact next step Forkit Connect recommends.</p>
6963
7070
 
6964
7071
  <section class="discovery-review-panel" id="discovery-review-panel">
6965
7072
  <p class="discovery-review-kicker" id="discovery-review-kicker">Review item</p>
@@ -7023,7 +7130,7 @@ function renderLauncherHtml(launcherToken) {
7023
7130
  <li><span class="discovery-note-label"><span class="discovery-note-icon info">i</span>Passport readiness</span><span class="discovery-note-value" id="disc-check-passport">-</span></li>
7024
7131
  </ul>
7025
7132
 
7026
- <button id="discovery-review-all" class="discovery-review-button" type="button">Review all ↗</button>
7133
+ <button id="discovery-review-all" class="discovery-review-button" type="button">Open full inbox ↗</button>
7027
7134
  </aside>
7028
7135
  </div>
7029
7136
 
@@ -7824,6 +7931,41 @@ function renderLauncherHtml(launcherToken) {
7824
7931
  return item.detailSummary || item.statusMeta || 'Review local metadata, then decide what happens next.';
7825
7932
  }
7826
7933
 
7934
+ function getQuickReviewDetailText(item) {
7935
+ if (!item) return '';
7936
+ if (item.kind === 'runtime') {
7937
+ return item.statusTone === 'error'
7938
+ ? 'Resolve runtime attention before linked registrations continue.'
7939
+ : 'Open runtime review to confirm health and connected models.';
7940
+ }
7941
+ if (item.statusLabel === 'Registration in progress') {
7942
+ return 'Continue the existing private review instead of creating a second record.';
7943
+ }
7944
+ if (item.statusLabel === 'Finish privately first') {
7945
+ return 'One private review step is still required before publishing.';
7946
+ }
7947
+ if (item.matchedPassportGaid && !item.passportGaid) {
7948
+ return 'A matching passport already exists. Reuse it first.';
7949
+ }
7950
+ if (item.passportGaid) {
7951
+ return 'This item is already linked. Open the passport to inspect it.';
7952
+ }
7953
+ if (item.actionLabel === 'Retry') {
7954
+ return 'Registration failed earlier. Retry when the scope is ready.';
7955
+ }
7956
+ return '';
7957
+ }
7958
+
7959
+ function getQuickReviewStatusText(item) {
7960
+ if (!item) return 'Waiting for review.';
7961
+ const meta = typeof item.statusMeta === 'string' ? item.statusMeta.trim() : '';
7962
+ if (!meta) return item.statusLabel;
7963
+ if (item.kind === 'runtime' || item.statusTone === 'error' || item.statusLabel === 'Registration in progress' || item.statusLabel === 'Finish privately first') {
7964
+ return item.statusLabel + ' · ' + meta;
7965
+ }
7966
+ return item.statusLabel;
7967
+ }
7968
+
7827
7969
  function formatLauncherActionFeedback(result, fallbackMessage) {
7828
7970
  const base = result && typeof result.message === 'string' && result.message.trim()
7829
7971
  ? result.message.trim()
@@ -8099,9 +8241,9 @@ function renderLauncherHtml(launcherToken) {
8099
8241
  setText('quick-review-kicker', item.typeLabel || item.kind);
8100
8242
  setText('quick-review-title', item.name);
8101
8243
  setText('quick-review-badge', item.kind === 'runtime' ? 'Runtime' : item.kind === 'agent' ? 'Agent' : 'Model');
8102
- setText('quick-review-meta', item.subtitle + ' · ' + item.source);
8103
- setText('quick-review-detail', getReviewDetailText(item));
8104
- setQuickReviewStatus(item.statusLabel + (item.statusMeta ? ' · ' + item.statusMeta : ''), item.statusTone === 'muted' ? '' : item.statusTone);
8244
+ setText('quick-review-meta', [item.typeLabel || item.kind, item.source].filter(Boolean).join(' · '));
8245
+ setOptionalDetail('quick-review-detail', getQuickReviewDetailText(item));
8246
+ setQuickReviewStatus(getQuickReviewStatusText(item), item.statusTone === 'muted' ? '' : item.statusTone);
8105
8247
  resetReviewResolutionActions('quick-review');
8106
8248
 
8107
8249
  const primaryLabel = getReviewPrimaryLabel(item, 'solo');
@@ -8645,6 +8787,42 @@ function renderLauncherHtml(launcherToken) {
8645
8787
  return normalized.slice(0, 2).toUpperCase();
8646
8788
  }
8647
8789
 
8790
+ function formatTierLabel(value) {
8791
+ const normalized = String(value || '').trim();
8792
+ if (!normalized) return 'Solo';
8793
+ return normalized.split(/[_-]+/).filter(Boolean).map((chunk) => chunk.charAt(0).toUpperCase() + chunk.slice(1)).join(' ');
8794
+ }
8795
+
8796
+ function summarizeAccountSync(summary) {
8797
+ if (!summary || !summary.authenticated) {
8798
+ return 'Sign in required';
8799
+ }
8800
+ if (summary.workspaceId && summary.projectId) {
8801
+ return 'Governed scope ready';
8802
+ }
8803
+ if (summary.workspaceId) {
8804
+ return 'Workspace selected';
8805
+ }
8806
+ return 'Solo ready';
8807
+ }
8808
+
8809
+ function formatSettingsAccountLabel(profile) {
8810
+ if (!profile || !profile.authenticated) {
8811
+ return 'Not signed in';
8812
+ }
8813
+ const primary = String(profile.displayName || profile.email || 'Connected account').trim();
8814
+ const extras = [profile.email, formatTierLabel(profile.tier)].filter((value, index, array) => value && value !== primary && array.indexOf(value) === index);
8815
+ return [primary, ...extras].filter(Boolean).join(' · ');
8816
+ }
8817
+
8818
+ function setOptionalDetail(id, message) {
8819
+ const element = document.getElementById(id);
8820
+ if (!element) return;
8821
+ const normalized = typeof message === 'string' ? message.trim() : '';
8822
+ element.textContent = normalized;
8823
+ element.hidden = normalized.length === 0;
8824
+ }
8825
+
8648
8826
  function getGreetingLabel() {
8649
8827
  const hour = new Date().getHours();
8650
8828
  if (hour < 12) return 'Good morning';
@@ -8944,18 +9122,16 @@ function renderLauncherHtml(launcherToken) {
8944
9122
  const boundCount = scopedPassports.filter((item) => String(item.bindingStatus || '').toLowerCase() === 'bound').length;
8945
9123
  const subtitle = boundCount > 0
8946
9124
  ? boundCount === 1
8947
- ? '1 registration is already linked to the current scope.'
8948
- : boundCount + ' registrations are already linked to the current scope.'
8949
- : 'Current scope is ready for new registrations.';
9125
+ ? 'Status is healthy. 1 registration is already linked to the current scope.'
9126
+ : 'Status is healthy. ' + boundCount + ' registrations are already linked to the current scope.'
9127
+ : 'Status is healthy. Account, scope, daemon, and inbox are ready for new registrations.';
8950
9128
  if (currentView === 'command') {
8951
9129
  setText('activity-message', subtitle, '');
8952
9130
  }
8953
9131
 
8954
- const accountName = toDisplayName(workspaceLabel, 'Operator');
8955
- const greeting = getGreetingLabel() + ', ' + accountName + '!';
8956
9132
  if (currentView === 'command') {
8957
9133
  const title = document.getElementById('page-title');
8958
- if (title) title.textContent = greeting;
9134
+ if (title) title.textContent = 'Status';
8959
9135
  }
8960
9136
  }
8961
9137
 
@@ -9090,6 +9266,8 @@ function renderLauncherHtml(launcherToken) {
9090
9266
  setText('header-account-meta', accountMeta);
9091
9267
  setText('account-menu-title', accountTitle);
9092
9268
  setText('account-menu-subtitle', accountMeta);
9269
+ setText('account-menu-tier', formatTierLabel(summary.tier));
9270
+ setText('account-menu-sync', summarizeAccountSync(summary));
9093
9271
 
9094
9272
  const bindingBits = [
9095
9273
  'State: ' + (summary.bindingState || 'none'),
@@ -9242,6 +9420,38 @@ function renderLauncherHtml(launcherToken) {
9242
9420
  await refreshAll();
9243
9421
  }
9244
9422
 
9423
+ async function handleAccountSessionExit(startLogin) {
9424
+ if (currentPollTimer) {
9425
+ clearInterval(currentPollTimer);
9426
+ currentPollTimer = null;
9427
+ }
9428
+ currentDeviceCode = null;
9429
+ const accountDropdownBtn = document.getElementById('user-chip-btn');
9430
+ const accountDropdownMenu = document.getElementById('account-dropdown-menu');
9431
+ if (accountDropdownMenu) {
9432
+ accountDropdownMenu.hidden = true;
9433
+ }
9434
+ if (accountDropdownBtn) {
9435
+ accountDropdownBtn.setAttribute('aria-expanded', 'false');
9436
+ }
9437
+ const result = await postAction('/api/session/logout', startLogin ? 'Switching account…' : 'Signing out…');
9438
+ if (!result.ok) {
9439
+ setActivityMessage(result.message || 'Session update failed.', 'warn');
9440
+ return;
9441
+ }
9442
+ if (startLogin) {
9443
+ setView('login');
9444
+ setLoginStatus(result.message || 'Signed out. Continue with another account.', 'ok');
9445
+ await refreshAll();
9446
+ handleLogin();
9447
+ return;
9448
+ }
9449
+ setActivityMessage(result.message || 'Signed out.', 'ok');
9450
+ setView('signed-out');
9451
+ setLoginStatus('Sign in required to continue.', 'warn');
9452
+ await refreshAll();
9453
+ }
9454
+
9245
9455
  function setScopeStatus(message, tone) {
9246
9456
  const status = document.getElementById('scope-modal-status');
9247
9457
  if (!status) return;
@@ -9550,8 +9760,8 @@ function renderLauncherHtml(launcherToken) {
9550
9760
  const VIEW_TITLES = {
9551
9761
  login: 'Sign in',
9552
9762
  'signed-out': 'Signed out',
9553
- command: 'Command Center',
9554
- discovery: 'Discovery',
9763
+ command: 'Status',
9764
+ discovery: 'Inbox',
9555
9765
  passports: 'Passports',
9556
9766
  runtime: 'Runtime',
9557
9767
  diagnostics: 'Diagnostics',
@@ -9562,8 +9772,8 @@ function renderLauncherHtml(launcherToken) {
9562
9772
  const VIEW_SUBTITLES = {
9563
9773
  login: 'Authenticate with Forkit.dev to continue.',
9564
9774
  'signed-out': 'Sign in again to restore registration sync and connected workflows.',
9565
- command: 'Monitor local environment, passports, and runtime health.',
9566
- discovery: 'Scan and review detected models, agents, and runtimes.',
9775
+ command: 'Review account, scope, daemon, inbox, and runtime health for this device.',
9776
+ discovery: 'Review detected models, agents, and runtimes waiting in the local inbox.',
9567
9777
  passports: 'Review published, draft and linked Passports from the local device state.',
9568
9778
  runtime: 'Inspect connected runtime environments and metrics.',
9569
9779
  diagnostics: 'Run health checks and review system diagnostics.',
@@ -9783,7 +9993,12 @@ function renderLauncherHtml(launcherToken) {
9783
9993
  setText('count-agents', String(discovery.counts.agents));
9784
9994
  setText('count-runtimes', String(discovery.counts.runtimes));
9785
9995
  setText('discovery-page-count', String(discovery.counts.all));
9786
- setText('discovery-last-scan', discovery.lastScanAt ? ('Last scan: ' + discovery.lastScanAt) : 'Last scan: not available');
9996
+ setText(
9997
+ 'discovery-last-scan',
9998
+ discovery.lastScanAt
9999
+ ? ('Last scan · ' + formatRelativeTime(discovery.lastScanAt) + ' · ' + formatTimestamp(discovery.lastScanAt))
10000
+ : 'Last scan · not available',
10001
+ );
9787
10002
  setText('disc-check-local', discovery.checks.localDetection, discovery.checks.localDetection === 'active' ? 'ok' : 'warn');
9788
10003
  setText('disc-check-meta', discovery.checks.metadataExtraction, discovery.checks.metadataExtraction === 'active' ? 'ok' : 'warn');
9789
10004
  setText('disc-check-dup', discovery.checks.duplicateMatching, discovery.checks.duplicateMatching === 'active' ? 'ok' : 'warn');
@@ -10173,18 +10388,23 @@ function renderLauncherHtml(launcherToken) {
10173
10388
  if (!data) return;
10174
10389
 
10175
10390
  // Account & Sync section
10176
- const email = data.profile.authenticated ? (data.system.runtimeId || 'Authenticated') : 'Not signed in';
10177
- setText('settings-signed-in-email', email);
10391
+ setText('settings-signed-in-email', formatSettingsAccountLabel(data.profile));
10178
10392
  const syncBadge = document.getElementById('settings-sync-badge');
10179
10393
  if (syncBadge) {
10180
- syncBadge.textContent = data.profile.workspaceBound ? 'Synced' : 'Not synced';
10181
- syncBadge.className = 'settings-sync-badge' + (data.profile.workspaceBound ? '' : ' warn');
10182
- }
10183
- const lastHeartbeatLine = data.preferences.updatedAt ? 'Last sync: ' + data.preferences.updatedAt : 'Not yet synced';
10394
+ syncBadge.textContent = !data.profile.authenticated
10395
+ ? 'Sign in required'
10396
+ : data.profile.workspaceBound
10397
+ ? 'Governed ready'
10398
+ : 'Solo ready';
10399
+ syncBadge.className = 'settings-sync-badge' + (data.profile.authenticated ? '' : ' warn');
10400
+ }
10401
+ const lastHeartbeatLine = data.preferences.updatedAt ? 'Last sync: ' + formatTimestamp(data.preferences.updatedAt) : 'Not yet synced';
10184
10402
  setText('settings-last-sync', lastHeartbeatLine);
10185
- const syncDesc = data.profile.workspaceBound
10186
- ? 'All registrations are up to date.'
10187
- : 'Workspace not yet bound. Sign in and select the target scope to continue sync.';
10403
+ const syncDesc = !data.profile.authenticated
10404
+ ? 'Sign in to sync registrations, review items, and runtime health across devices.'
10405
+ : data.profile.workspaceBound
10406
+ ? 'Account, workspace, and project are synced and ready for governed registration.'
10407
+ : 'Your account is synced. Solo registration can continue now, and governed sync starts when you choose a workspace/project.';
10188
10408
  setText('settings-sync-desc', syncDesc);
10189
10409
 
10190
10410
  // Notifications toggles — reflect real preferences
@@ -10581,8 +10801,8 @@ function renderLauncherHtml(launcherToken) {
10581
10801
  document.getElementById('diag-action-heartbeat').addEventListener('click', handleHeartbeat);
10582
10802
  document.getElementById('diag-action-update').addEventListener('click', handleUpdate);
10583
10803
  document.getElementById('activity-export-csv').addEventListener('click', handleExportActivityCsv);
10584
- document.getElementById('cmd-open-passports').addEventListener('click', () => setView('passports'));
10585
- document.getElementById('cmd-check-status').addEventListener('click', () => setView('diagnostics'));
10804
+ document.getElementById('cmd-open-passports').addEventListener('click', () => setView('discovery'));
10805
+ document.getElementById('cmd-check-status').addEventListener('click', () => setView('runtime'));
10586
10806
 
10587
10807
  function wireScopeDropdown(selectId) {
10588
10808
  const button = document.getElementById(selectId);
@@ -10625,6 +10845,20 @@ function renderLauncherHtml(launcherToken) {
10625
10845
  }
10626
10846
 
10627
10847
  const accountOpenSettings = document.getElementById('account-open-settings');
10848
+ const accountOpenProfile = document.getElementById('account-open-profile');
10849
+ const accountOpenSecurity = document.getElementById('account-open-security');
10850
+ if (accountOpenProfile) {
10851
+ accountOpenProfile.addEventListener('click', () => {
10852
+ window.open('${FORKIT_DEV_URL}/profile?tab=profile', '_blank', 'noopener,noreferrer');
10853
+ if (accountDropdownMenu) accountDropdownMenu.hidden = true;
10854
+ });
10855
+ }
10856
+ if (accountOpenSecurity) {
10857
+ accountOpenSecurity.addEventListener('click', () => {
10858
+ window.open('${FORKIT_DEV_URL}/profile?tab=security', '_blank', 'noopener,noreferrer');
10859
+ if (accountDropdownMenu) accountDropdownMenu.hidden = true;
10860
+ });
10861
+ }
10628
10862
  if (accountOpenSettings) {
10629
10863
  accountOpenSettings.addEventListener('click', () => {
10630
10864
  setView('settings');
@@ -10635,18 +10869,16 @@ function renderLauncherHtml(launcherToken) {
10635
10869
  const accountSwitch = document.getElementById('account-switch-account');
10636
10870
  if (accountSwitch) {
10637
10871
  accountSwitch.addEventListener('click', () => {
10638
- setView('login');
10639
- handleLogin();
10640
10872
  if (accountDropdownMenu) accountDropdownMenu.hidden = true;
10873
+ void handleAccountSessionExit(true);
10641
10874
  });
10642
10875
  }
10643
10876
 
10644
10877
  const accountSignOut = document.getElementById('account-sign-out');
10645
10878
  if (accountSignOut) {
10646
10879
  accountSignOut.addEventListener('click', () => {
10647
- setView('signed-out');
10648
- setLoginStatus('Sign in required to continue.', 'warn');
10649
10880
  if (accountDropdownMenu) accountDropdownMenu.hidden = true;
10881
+ void handleAccountSessionExit(false);
10650
10882
  });
10651
10883
  }
10652
10884
 
@@ -11476,6 +11708,18 @@ function createLauncherApp(options) {
11476
11708
  sendInternalError(response, error, 'launcher_settings_failed');
11477
11709
  }
11478
11710
  });
11711
+ app.post('/api/session/logout', (_request, response) => {
11712
+ try {
11713
+ options.service.setSessionRef(null);
11714
+ response.json({
11715
+ ok: true,
11716
+ message: 'Signed out. Local discovery stays available on this device.',
11717
+ });
11718
+ }
11719
+ catch (error) {
11720
+ sendInternalError(response, error, 'launcher_logout_failed');
11721
+ }
11722
+ });
11479
11723
  app.post('/api/scan', async (_request, response) => {
11480
11724
  try {
11481
11725
  const result = await options.service.scanRuntime();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forkit-connect",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Forkit Connect Local Engine - The Global AI Governance Fabric",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",