@growthub/cli 0.13.7 → 0.13.8

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 (18) hide show
  1. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/helper/query/route.js +98 -34
  2. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/api/workspace/swarm-condition/route.js +106 -0
  3. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceActivationPanel.jsx +17 -0
  4. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceContributionGraph.jsx +119 -0
  5. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceHelperSetupModal.jsx +357 -0
  6. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceLensPanel.jsx +488 -0
  7. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/components/WorkspaceLensWalkthrough.jsx +69 -0
  8. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/data-model/components/HelperSidecar.jsx +37 -2
  9. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/globals.css +267 -25
  10. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-builder.jsx +55 -2
  11. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-lens/page.jsx +76 -0
  12. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/app/workspace-rail.jsx +140 -4
  13. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-activation.js +1025 -0
  14. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-data-model.js +2 -3
  15. package/assets/worker-kits/growthub-custom-workspace-starter-v1/apps/workspace/lib/workspace-helper-apply.js +24 -8
  16. package/assets/worker-kits/growthub-custom-workspace-starter-v1/kit.json +5 -0
  17. package/dist/index.js +5224 -5225
  18. package/package.json +1 -1
@@ -445,46 +445,53 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
445
445
  .workspace-rail.is-collapsed {
446
446
  padding: 18px 10px;
447
447
  align-items: center;
448
- gap: 10px;
448
+ gap: 8px;
449
449
  }
450
+ /* Collapsed rail = a single clean icon column. Every primary action stays
451
+ tracked as an icon (toggle, home, search, chat, builder, lens, management,
452
+ settings); only labels, folders, chat list, brand, helper pill, activation
453
+ panel, and the duplicate top-bar gear are hidden. Native title attributes
454
+ provide the hover tooltip of each item's name. */
450
455
  .workspace-rail.is-collapsed .workspace-rail-brand-button,
451
456
  .workspace-rail.is-collapsed .workspace-rail-folders,
452
- .workspace-rail.is-collapsed .workspace-nav,
453
457
  .workspace-rail.is-collapsed .workspace-rail-chat,
454
458
  .workspace-rail.is-collapsed .workspace-rail-status,
455
- .workspace-rail.is-collapsed .workspace-rail-helper-pill {
459
+ .workspace-rail.is-collapsed .workspace-rail-helper-pill,
460
+ .workspace-rail.is-collapsed .workspace-rail-activation-slot,
461
+ .workspace-rail.is-collapsed .workspace-rail-icon-btn[aria-label="Workspace settings"],
462
+ .workspace-rail.is-collapsed .workspace-nav-label {
456
463
  display: none;
457
464
  }
458
- .workspace-rail.is-collapsed .workspace-rail-topbar {
459
- justify-content: center;
460
- width: 100%;
461
- display: contents;
462
- }
463
- .workspace-rail.is-collapsed .workspace-rail-topbar-actions {
465
+ .workspace-rail.is-collapsed .workspace-rail-topbar,
466
+ .workspace-rail.is-collapsed .workspace-rail-topbar-actions,
467
+ .workspace-rail.is-collapsed .workspace-rail-tabbar,
468
+ .workspace-rail.is-collapsed .workspace-rail-tabs {
464
469
  display: contents;
465
470
  }
466
- .workspace-rail.is-collapsed .workspace-rail-icon-btn[aria-pressed="true"] {
467
- order: 1;
468
- }
469
- .workspace-rail.is-collapsed .workspace-rail-icon-btn[data-rail-search] {
470
- order: 3;
471
- }
472
- .workspace-rail.is-collapsed .workspace-rail-icon-btn[aria-label="Workspace settings"] {
473
- order: 4;
474
- }
471
+ /* Vertical order: toggle · home · search · chat · [nav: builder, lens,
472
+ management, settings]. */
473
+ .workspace-rail.is-collapsed .workspace-rail-icon-btn[aria-pressed="true"] { order: 1; }
474
+ .workspace-rail.is-collapsed .workspace-rail-tab[aria-label="Home"] { order: 2; }
475
+ .workspace-rail.is-collapsed .workspace-rail-icon-btn[data-rail-search] { order: 3; }
476
+ .workspace-rail.is-collapsed .workspace-rail-tab[aria-label="Helper conversations"] { order: 4; }
477
+ .workspace-rail.is-collapsed .workspace-nav { order: 5; }
475
478
  .workspace-rail.is-collapsed .workspace-rail-icon-btn[aria-pressed="true"] svg {
476
479
  transform: rotate(180deg);
477
480
  }
478
- .workspace-rail.is-collapsed .workspace-rail-tabbar {
481
+ .workspace-rail.is-collapsed .workspace-nav {
479
482
  display: flex;
480
- justify-content: center;
481
- width: 100%;
482
- order: 2;
483
- }
484
- .workspace-rail.is-collapsed .workspace-rail-tabs {
485
483
  flex-direction: column;
484
+ align-items: center;
486
485
  gap: 8px;
486
+ width: 100%;
487
+ }
488
+ .workspace-rail.is-collapsed .workspace-nav a,
489
+ .workspace-rail.is-collapsed .workspace-nav .workspace-nav-button {
490
+ justify-content: center;
491
+ gap: 0;
487
492
  padding: 0;
493
+ width: 34px;
494
+ height: 34px;
488
495
  }
489
496
  .workspace-rail.is-collapsed .workspace-rail-tab,
490
497
  .workspace-rail.is-collapsed .workspace-rail-icon-btn {
@@ -525,12 +532,31 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
525
532
  margin-top: 2px;
526
533
  }
527
534
  .workspace-nav a,
528
- .workspace-nav-static {
535
+ .workspace-nav-static,
536
+ .workspace-nav .workspace-nav-button {
537
+ display: flex;
538
+ align-items: center;
539
+ gap: 10px;
529
540
  border-radius: 6px;
530
541
  color: #686868;
531
542
  font-size: 13px;
532
543
  padding: 8px 9px;
533
544
  text-decoration: none;
545
+ width: 100%;
546
+ }
547
+ .workspace-nav a > svg,
548
+ .workspace-nav .workspace-nav-button > svg {
549
+ flex-shrink: 0;
550
+ color: #9a9a9a;
551
+ }
552
+ .workspace-nav a.active > svg,
553
+ .workspace-nav .workspace-nav-button.active > svg {
554
+ color: #2c2c2c;
555
+ }
556
+ .workspace-nav-label {
557
+ white-space: nowrap;
558
+ overflow: hidden;
559
+ text-overflow: ellipsis;
534
560
  }
535
561
  .workspace-nav-static {
536
562
  cursor: default;
@@ -8656,6 +8682,222 @@ body.workspace-rail-collapsed .workspace-builder.dm-workflow-page {
8656
8682
  .workspace-activation-helper-btn { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 1px dashed #c7d2fe; color: #4338ca; font-size: 12px; padding: 6px 10px; border-radius: 6px; cursor: pointer; }
8657
8683
  .workspace-activation-helper-btn:hover { background: #eef2ff; }
8658
8684
 
8685
+ /* Activation → Workspace Lens handoff teaser (shown once setup completes). */
8686
+ .workspace-activation-lens-teaser { margin-top: 14px; border-top: 1px solid #eef0f2; padding-top: 12px; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
8687
+ .workspace-activation-lens-teaser-text { font-size: 12px; color: #4b5563; line-height: 1.45; }
8688
+ .workspace-activation-lens-teaser-link { font-size: 12px; font-weight: 600; color: #374151; text-decoration: none; white-space: nowrap; }
8689
+ .workspace-activation-lens-teaser-link:hover { text-decoration: underline; }
8690
+
8691
+ /* Locked rail nav affordance (Workspace Lens before setup completes). */
8692
+ .workspace-nav-button.is-locked { opacity: 0.45; cursor: default; }
8693
+
8694
+ /* ── Workspace Lens — post-activation operating surface ─────────────────────
8695
+ Neutral, calm, aggregate-first. No semantic color overload, no icon spam. */
8696
+ body.workspace-rail-collapsed .workspace-builder.workspace-lens-page,
8697
+ .workspace-builder.workspace-lens-page { grid-template-columns: var(--workspace-rail-width) minmax(0, 1fr); height: 100vh; overflow: hidden; }
8698
+ .workspace-lens-surface { width: 100%; padding: 0; background: #f7f7f8; overflow-y: auto; overflow-x: hidden; }
8699
+ .workspace-lens-shell { width: 100%; max-width: none; margin: 0; padding: 24px 28px 32px; }
8700
+ .workspace-lens-locked { border: 1px solid #e5e7eb; border-radius: 10px; background: #fff; padding: 28px; max-width: 560px; margin: 48px auto; display: flex; flex-direction: column; gap: 8px; }
8701
+ .workspace-lens-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
8702
+ .workspace-lens-title { font-size: 18px; font-weight: 600; color: #111827; margin: 0; }
8703
+ .workspace-lens-subtitle { font-size: 13px; color: #6b7280; margin: 4px 0 0; }
8704
+ .workspace-lens-score { font-size: 12px; color: #4b5563; font-variant-numeric: tabular-nums; margin: 2px 0 0; }
8705
+ .workspace-lens-controls.workspace-builder-filterbar { margin: 0 0 14px; border: 1px solid #e8edf3; border-radius: 8px; background: #fff; }
8706
+ .workspace-lens-filters.workspace-builder-filterbar__segments { max-width: 100%; overflow-x: auto; }
8707
+ .workspace-lens-filter { white-space: nowrap; }
8708
+ .workspace-lens-filter.is-active { background: #fff; color: #111827; box-shadow: 0 1px 2px rgba(15, 23, 42, .08); }
8709
+ .workspace-lens-search-wrap { flex-shrink: 0; }
8710
+ .workspace-lens-search { width: 100%; min-width: 0; border: 0; outline: 0; background: transparent; color: #111827; font: inherit; font-size: 12px; padding: 0; }
8711
+ .workspace-lens-control-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin: 0 0 22px; }
8712
+ .workspace-lens-control-card { border: 1px solid #e5e7eb; border-radius: 8px; background: #ffffff; min-height: 184px; padding: 14px; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); display: flex; flex-direction: column; gap: 12px; }
8713
+ .workspace-lens-control-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
8714
+ .workspace-lens-control-card-head h2 { margin: 0; color: #111827; font-size: 13px; font-weight: 600; line-height: 1.3; }
8715
+ .workspace-lens-control-card-head span { color: #6b7280; font-size: 12px; }
8716
+ .workspace-lens-icon-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid transparent; border-radius: 6px; background: transparent; color: #6b7280; cursor: pointer; }
8717
+ .workspace-lens-icon-btn:hover { border-color: #e5e7eb; background: #f9fafb; color: #111827; }
8718
+ .workspace-lens-checklist { display: flex; flex-direction: column; gap: 6px; }
8719
+ .workspace-lens-check-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 32px; border-radius: 6px; background: #f3f4f6; color: #374151; padding: 0 10px; text-decoration: none; font-size: 12px; }
8720
+ .workspace-lens-check-item:hover { background: #e5e7eb; }
8721
+ .workspace-lens-check-item.is-complete { background: #dcfce7; color: #15803d; text-decoration: line-through; box-shadow: inset 3px 0 0 #22c55e; }
8722
+ .workspace-lens-check-item.is-complete svg { color: #16a34a; }
8723
+ .workspace-lens-stat-list { display: flex; flex-direction: column; gap: 0; margin-top: 14px; }
8724
+ .workspace-lens-stat-row { display: grid; grid-template-columns: minmax(0, 1fr) 64px; align-items: center; gap: 12px; min-height: 31px; border-bottom: 1px solid #eef0f2; color: #6b7280; font-size: 12px; }
8725
+ .workspace-lens-stat-row:last-child { border-bottom: 0; }
8726
+ .workspace-lens-stat-row strong { color: #111827; font-size: 13px; font-weight: 500; text-align: left; font-variant-numeric: tabular-nums; }
8727
+ .workspace-lens-helper-card-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; color: #4b5563; }
8728
+ .workspace-lens-helper-card-body svg { color: #111827; }
8729
+ .workspace-lens-helper-card-body strong { color: #111827; font-size: 13px; }
8730
+ .workspace-lens-helper-card-body p { margin: 0; color: #6b7280; font-size: 12px; line-height: 1.45; max-width: 260px; }
8731
+ .workspace-lens-helper-card-body button { margin-top: 4px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; color: #111827; font-size: 12px; font-weight: 500; padding: 7px 12px; cursor: pointer; }
8732
+ .workspace-lens-helper-card-body button:hover { background: #f9fafb; }
8733
+ .workspace-lens-branches { margin: 24px 0 32px; }
8734
+ .workspace-lens-branches-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 12px; }
8735
+ .workspace-lens-branches-head h2 { margin: 0; color: #111827; font-size: 18px; font-weight: 600; }
8736
+ .workspace-lens-branches-head span { display: inline-flex; align-items: center; justify-content: center; border-radius: 999px; background: #e5e7eb; color: #374151; padding: 2px 8px; font-size: 11px; font-weight: 600; }
8737
+ .workspace-lens-branches-table { border: 1px solid #e5e7eb; border-radius: 8px; background: #ffffff; overflow: visible; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); }
8738
+ .workspace-lens-branch-row { position: relative; display: grid; grid-template-columns: minmax(240px, 1fr) auto; align-items: center; gap: 16px; min-height: 46px; border-bottom: 1px solid #eef0f2; padding: 0 16px; }
8739
+ .workspace-lens-branch-row:last-child { border-bottom: 0; }
8740
+ .workspace-lens-branch-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; color: #111827; font-size: 13px; font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace); }
8741
+ .workspace-lens-branch-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
8742
+ .workspace-lens-branch-name svg { color: #4b5563; flex-shrink: 0; }
8743
+ .workspace-lens-branch-actions { position: relative; display: inline-flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; }
8744
+ .workspace-lens-preview-pill,
8745
+ .workspace-lens-progress-pill,
8746
+ .workspace-lens-owner-pill { display: inline-flex; align-items: center; gap: 5px; min-height: 24px; border: 1px solid #e5e7eb; border-radius: 999px; background: #ffffff; color: #4b5563; padding: 0 9px; text-decoration: none; font-size: 11px; white-space: nowrap; }
8747
+ .workspace-lens-preview-pill:hover { background: #f9fafb; color: #111827; }
8748
+ .workspace-lens-owner-pill { border-color: transparent; color: #4b5563; }
8749
+ .workspace-lens-branch-summary,
8750
+ .workspace-lens-branch-next { display: none; grid-column: 1 / -1; margin: -6px 0 10px 22px; color: #6b7280; font-size: 12px; line-height: 1.4; }
8751
+ .workspace-lens-branch-next { margin-top: -8px; color: #374151; font-weight: 500; }
8752
+ .workspace-lens-action-menu { position: absolute; z-index: 80; top: 34px; right: 0; width: 190px; border: 1px solid #e5e7eb; border-radius: 8px; background: #ffffff; box-shadow: 0 12px 28px rgba(15, 23, 42, 0.16); padding: 6px; display: flex; flex-direction: column; gap: 2px; }
8753
+ .workspace-lens-action-menu button,
8754
+ .workspace-lens-action-menu a { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; border: 0; border-radius: 6px; background: transparent; color: #111827; padding: 9px 8px; text-align: left; text-decoration: none; font-size: 12px; cursor: pointer; }
8755
+ .workspace-lens-action-menu button:hover,
8756
+ .workspace-lens-action-menu a:hover { background: #f3f4f6; }
8757
+ @media (max-width: 1100px) {
8758
+ .workspace-lens-control-grid { grid-template-columns: 1fr; }
8759
+ .workspace-lens-branch-row { grid-template-columns: 1fr; align-items: flex-start; padding: 10px 12px; gap: 8px; }
8760
+ .workspace-lens-branch-actions { justify-content: flex-start; flex-wrap: wrap; }
8761
+ .workspace-lens-branch-summary,
8762
+ .workspace-lens-branch-next { margin-left: 22px; }
8763
+ }
8764
+ .workspace-lens-stream { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
8765
+ .workspace-lens-card { border: 1px solid #e8edf3; border-radius: 10px; background: #fff; padding: 12px 14px; }
8766
+ .workspace-lens-card.is-ready { opacity: 0.7; }
8767
+ .workspace-lens-card-head { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: none; padding: 0; cursor: pointer; text-align: left; }
8768
+ .workspace-lens-card-title { font-size: 13px; font-weight: 600; color: #111827; flex: 1; }
8769
+ .workspace-lens-chip { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: #6b7280; border: 1px solid #e5e7eb; border-radius: 999px; padding: 1px 8px; }
8770
+ .workspace-lens-chip.is-blocked { color: #374151; border-color: #d1d5db; background: #f3f4f6; }
8771
+ .workspace-lens-card-progress { font-size: 11px; color: #6b7280; font-variant-numeric: tabular-nums; }
8772
+ .workspace-lens-caret { color: #9ca3af; transition: transform 120ms ease; }
8773
+ .workspace-lens-caret.is-open { transform: rotate(180deg); }
8774
+ .workspace-lens-card-headline { font-size: 12px; color: #4b5563; line-height: 1.45; margin: 8px 0 0; }
8775
+ .workspace-lens-card-next { display: flex; align-items: baseline; gap: 6px; margin-top: 8px; font-size: 12px; }
8776
+ .workspace-lens-next-label { color: #9ca3af; }
8777
+ .workspace-lens-next-link { color: #374151; font-weight: 600; text-decoration: none; }
8778
+ .workspace-lens-next-link:hover { text-decoration: underline; }
8779
+ .workspace-lens-card-detail { margin-top: 12px; border-top: 1px solid #f1f5f9; padding-top: 10px; display: flex; flex-direction: column; gap: 10px; }
8780
+ .workspace-lens-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
8781
+ .workspace-lens-step { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: #4b5563; }
8782
+ .workspace-lens-step-label { flex: 1; }
8783
+ .workspace-lens-step-status { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; color: #9ca3af; }
8784
+ .workspace-lens-step.is-blocked .workspace-lens-step-status { color: #6b7280; font-weight: 600; }
8785
+ .workspace-lens-step-hint { flex-basis: 100%; font-size: 11px; color: #9ca3af; }
8786
+ .workspace-lens-blocked { font-size: 12px; color: #374151; margin: 0; }
8787
+ .workspace-lens-agent { border: 1px solid #f1f5f9; border-radius: 8px; background: #fafbfc; padding: 10px; }
8788
+ .workspace-lens-agent-title { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: #6b7280; margin: 0 0 6px; }
8789
+ .workspace-lens-agent-row { display: flex; gap: 8px; font-size: 12px; color: #4b5563; margin: 2px 0; }
8790
+ .workspace-lens-agent-row > span { color: #9ca3af; min-width: 84px; }
8791
+ .workspace-lens-empty { font-size: 12px; color: #9ca3af; padding: 16px; text-align: center; }
8792
+
8793
+ /* Workspace contribution graph — neutral chrome, GitHub green cell scale. */
8794
+ .workspace-contrib { border: 1px solid #e8edf3; border-radius: 10px; background: #fff; padding: 14px 16px; margin-bottom: 16px; }
8795
+ .workspace-contrib-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
8796
+ .workspace-contrib-total { font-size: 12px; color: #4b5563; }
8797
+ .workspace-contrib-legend { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: #9ca3af; }
8798
+ .workspace-contrib-grid-wrap { width: 100%; overflow: visible; }
8799
+ .workspace-contrib-months { display: grid; grid-template-columns: repeat(53, minmax(0, 1fr)); gap: 3px; margin-left: 38px; margin-bottom: 4px; }
8800
+ .workspace-contrib-month { font-size: 9px; color: #9ca3af; white-space: nowrap; }
8801
+ .workspace-contrib-body { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 8px; align-items: stretch; }
8802
+ .workspace-contrib-weekdays { display: grid; grid-template-rows: repeat(7, minmax(0, 1fr)); gap: 3px; width: 30px; }
8803
+ .workspace-contrib-weekdays span { font-size: 9px; color: #9ca3af; line-height: 1; display: flex; align-items: center; }
8804
+ .workspace-contrib-weeks { display: grid; grid-template-columns: repeat(53, minmax(0, 1fr)); gap: 3px; min-width: 0; }
8805
+ .workspace-contrib-week { display: grid; grid-template-rows: repeat(7, minmax(0, 1fr)); gap: 3px; min-width: 0; }
8806
+ .workspace-contrib-cell { width: 100%; aspect-ratio: 1; min-height: 10px; max-height: 18px; border-radius: 3px; padding: 0; border: 1px solid rgba(27, 31, 35, 0.06); background: #ebedf0; cursor: pointer; }
8807
+ .workspace-contrib-cell:disabled { cursor: default; }
8808
+ .workspace-contrib-cell.lvl-0 { background: #ebedf0; }
8809
+ .workspace-contrib-cell.lvl-1 { background: #9be9a8; }
8810
+ .workspace-contrib-cell.lvl-2 { background: #40c463; }
8811
+ .workspace-contrib-cell.lvl-3 { background: #30a14e; }
8812
+ .workspace-contrib-cell.lvl-4 { background: #216e39; }
8813
+ .workspace-contrib-cell.has-count { border-color: rgba(27, 31, 35, 0.18); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.18), 0 0 0 1px rgba(34,197,94,0.18); }
8814
+ .workspace-contrib-cell.has-count:hover { outline: 2px solid rgba(17, 24, 39, 0.75); outline-offset: 1px; }
8815
+ .workspace-contrib-cell.lvl-future { background: transparent; border-color: transparent; }
8816
+ .workspace-contrib-legend .workspace-contrib-cell { cursor: default; }
8817
+ .workspace-contrib-tooltip { position: fixed; transform: translate(-50%, calc(-100% - 8px)); z-index: 50; background: #111827; color: #fff; border-radius: 6px; padding: 6px 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.18); display: flex; flex-direction: column; gap: 2px; pointer-events: auto; }
8818
+ .workspace-contrib-tooltip-count { font-size: 11px; font-weight: 600; }
8819
+ .workspace-contrib-tooltip-date { font-size: 10px; color: #cbd5e1; }
8820
+ .workspace-contrib-tooltip-link { font-size: 10px; color: #9be9a8; text-decoration: none; margin-top: 2px; }
8821
+ .workspace-contrib-tooltip-link:hover { text-decoration: underline; }
8822
+
8823
+ /* Workspace Lens one-time walkthrough — calm white popover. */
8824
+ .workspace-rail-lens-nav { position: relative; }
8825
+ .workspace-lens-walkthrough { position: relative; width: 264px; background: #ffffff; border: 1px solid #d1d5db; border-radius: 5px; box-shadow: 0 6px 18px rgba(17, 24, 39, 0.12); padding: 12px 13px; }
8826
+ .workspace-lens-walkthrough.is-anchored,
8827
+ .workspace-lens-walkthrough.is-rail-reveal { position: fixed; z-index: 1200; }
8828
+ .workspace-lens-walkthrough.is-anchored::before,
8829
+ .workspace-lens-walkthrough.is-rail-reveal::before { content: ""; position: absolute; left: -6px; top: 16px; width: 10px; height: 10px; background: #ffffff; border-left: 1px solid #d1d5db; border-bottom: 1px solid #d1d5db; transform: rotate(45deg); }
8830
+ @media (max-width: 760px) {
8831
+ .workspace-lens-walkthrough.is-anchored,
8832
+ .workspace-lens-walkthrough.is-rail-reveal { right: 16px; width: auto; }
8833
+ .workspace-lens-walkthrough.is-anchored::before,
8834
+ .workspace-lens-walkthrough.is-rail-reveal::before { display: none; }
8835
+ }
8836
+ .workspace-lens-walkthrough.is-panel { width: 100%; max-width: 520px; margin: 0 0 16px; }
8837
+ .workspace-lens-walkthrough-x { position: absolute; top: 8px; right: 8px; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border: none; background: transparent; color: #9ca3af; border-radius: 5px; cursor: pointer; }
8838
+ .workspace-lens-walkthrough-x:hover { background: #f3f4f6; color: #4b5563; }
8839
+ .workspace-lens-walkthrough-eyebrow { margin: 0 0 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: #9ca3af; }
8840
+ .workspace-lens-walkthrough-title { margin: 0 0 5px; font-size: 13px; font-weight: 600; color: #111827; padding-right: 18px; }
8841
+ .workspace-lens-walkthrough-body { margin: 0 0 12px; font-size: 12px; line-height: 1.5; color: #4b5563; }
8842
+ .workspace-lens-walkthrough-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
8843
+ .workspace-lens-walkthrough-steps { font-size: 11px; color: #9ca3af; font-variant-numeric: tabular-nums; }
8844
+ .workspace-lens-walkthrough-next { font-size: 12px; font-weight: 600; color: #ffffff; background: #111827; border: none; border-radius: 6px; padding: 6px 12px; cursor: pointer; }
8845
+ .workspace-lens-walkthrough-next:hover { background: #1f2937; }
8846
+
8847
+ /* Helper handoff — one callout, one helper widget, one sandbox config. */
8848
+ .workspace-lens-helper-callout { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; border: 1px solid #e5e7eb; border-radius: 8px; background: #fafbfc; padding: 12px 14px; margin: 0 0 16px; }
8849
+ .workspace-lens-helper-callout-text { min-width: 0; }
8850
+ .workspace-lens-helper-callout-title { margin: 0 0 3px; font-size: 13px; font-weight: 600; color: #111827; }
8851
+ .workspace-lens-helper-callout-body { margin: 0; font-size: 12px; line-height: 1.5; color: #6b7280; max-width: 560px; }
8852
+ .workspace-lens-helper-callout-btn { flex-shrink: 0; font-size: 12px; font-weight: 600; color: #111827; background: #ffffff; border: 1px solid #d1d5db; border-radius: 6px; padding: 7px 12px; cursor: pointer; }
8853
+ .workspace-lens-helper-callout-btn:hover:not(:disabled) { background: #f3f4f6; }
8854
+ .workspace-lens-helper-callout-btn:disabled { opacity: 0.6; cursor: default; }
8855
+ .workspace-helper-setup-modal-backdrop { position: fixed; inset: 0; z-index: 1400; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(17, 24, 39, 0.42); backdrop-filter: blur(3px); }
8856
+ .workspace-helper-setup-modal { position: relative; width: min(620px, 100%); max-height: min(720px, calc(100vh - 48px)); overflow: auto; background: #ffffff; border: 1px solid #d1d5db; border-radius: 8px; box-shadow: 0 24px 70px rgba(17, 24, 39, 0.28); padding: 18px; }
8857
+ .workspace-helper-setup-modal-close { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff; color: #6b7280; cursor: pointer; }
8858
+ .workspace-helper-setup-modal-close:hover { background: #f9fafb; color: #111827; }
8859
+ .workspace-helper-setup-breadcrumbs { display: flex; gap: 8px; flex-wrap: wrap; padding-right: 36px; margin-bottom: 16px; font-size: 12px; color: #9ca3af; }
8860
+ .workspace-helper-setup-breadcrumbs span { border: 1px solid #e5e7eb; border-radius: 999px; padding: 4px 9px; background: #f9fafb; }
8861
+ .workspace-helper-setup-breadcrumbs span.active { color: #111827; border-color: #111827; background: #fff; font-weight: 600; }
8862
+ .workspace-helper-setup-step { display: flex; flex-direction: column; gap: 12px; }
8863
+ .workspace-helper-setup-step h2 { margin: 0; font-size: 18px; line-height: 1.25; color: #111827; }
8864
+ .workspace-helper-setup-step p { margin: 0; font-size: 13px; line-height: 1.55; color: #4b5563; }
8865
+ .workspace-helper-setup-eyebrow { font-size: 11px !important; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: #6b7280 !important; }
8866
+ .workspace-helper-setup-target { border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; display: grid; gap: 4px; background: #fafafa; }
8867
+ .workspace-helper-setup-target span, .workspace-helper-setup-target small { font-size: 12px; color: #6b7280; }
8868
+ .workspace-helper-setup-target strong { font-size: 14px; color: #111827; }
8869
+ .workspace-helper-setup-card-grid { display: grid; gap: 8px; }
8870
+ .workspace-helper-setup-toggle { display: flex !important; align-items: flex-start; gap: 10px; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; padding: 11px 12px; cursor: pointer; }
8871
+ .workspace-helper-setup-toggle:hover { background: #f9fafb; }
8872
+ .workspace-helper-setup-toggle input { width: 16px !important; height: 16px; margin: 2px 0 0; padding: 0 !important; accent-color: #111827; flex-shrink: 0; }
8873
+ .workspace-helper-setup-toggle span { display: grid; gap: 3px; min-width: 0; }
8874
+ .workspace-helper-setup-toggle strong { color: #111827; font-size: 13px; }
8875
+ .workspace-helper-setup-toggle small { color: #6b7280; font-size: 12px; line-height: 1.35; }
8876
+ .workspace-helper-setup-radio-group { border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; display: grid; gap: 8px; background: #fafafa; }
8877
+ .workspace-helper-setup-radio-group > span { font-size: 12px; font-weight: 700; color: #374151; }
8878
+ .workspace-helper-setup-radio-group label { display: flex !important; align-items: center; gap: 8px; font-size: 13px; color: #111827; font-weight: 600; }
8879
+ .workspace-helper-setup-radio-group input { width: 15px !important; height: 15px; margin: 0; padding: 0 !important; accent-color: #111827; }
8880
+ .workspace-helper-setup-radio-group small { color: #9ca3af; font-size: 12px; line-height: 1.4; }
8881
+ .workspace-helper-setup-field-stack { display: grid; gap: 10px; }
8882
+ .workspace-helper-agent-options { display: grid; gap: 8px; }
8883
+ .workspace-helper-agent-options button { display: grid; gap: 3px; text-align: left; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; padding: 10px 12px; cursor: pointer; }
8884
+ .workspace-helper-agent-options button:hover { background: #f9fafb; }
8885
+ .workspace-helper-agent-options button.active { border-color: #111827; box-shadow: inset 3px 0 0 #111827; }
8886
+ .workspace-helper-agent-options strong { font-size: 13px; color: #111827; }
8887
+ .workspace-helper-agent-options span { font-size: 12px; line-height: 1.4; color: #6b7280; }
8888
+ .workspace-helper-setup-two-col { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
8889
+ .workspace-helper-setup-step label { display: grid; gap: 6px; font-size: 12px; font-weight: 600; color: #374151; }
8890
+ .workspace-helper-setup-step input, .workspace-helper-setup-step select { width: 100%; border: 1px solid #d1d5db; border-radius: 7px; padding: 9px 10px; font-size: 13px; color: #111827; background: #fff; }
8891
+ .workspace-helper-setup-review { display: grid; gap: 8px; margin: 0; }
8892
+ .workspace-helper-setup-review div { display: grid; grid-template-columns: 120px 1fr; gap: 12px; border-bottom: 1px solid #f3f4f6; padding-bottom: 8px; }
8893
+ .workspace-helper-setup-review dt { font-size: 12px; color: #6b7280; }
8894
+ .workspace-helper-setup-review dd { margin: 0; min-width: 0; overflow-wrap: anywhere; font-size: 12px; color: #111827; }
8895
+ .workspace-helper-setup-error { color: #b91c1c !important; }
8896
+ .workspace-helper-setup-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
8897
+ .workspace-helper-setup-actions button { border: 1px solid #d1d5db; border-radius: 7px; background: #fff; color: #111827; padding: 8px 12px; font-size: 13px; font-weight: 600; cursor: pointer; }
8898
+ .workspace-helper-setup-actions button.primary { background: #111827; border-color: #111827; color: #fff; }
8899
+ .workspace-helper-setup-actions button:disabled { opacity: 0.55; cursor: default; }
8900
+
8659
8901
  /* Compact rail variant — slim activation chip in WorkspaceRail Home */
8660
8902
  .workspace-activation-panel.is-compact { padding: 12px 14px; margin: 0 0 12px; gap: 10px; border-radius: 8px; }
8661
8903
  .workspace-activation-panel.is-compact .workspace-activation-head { gap: 8px; }
@@ -59,6 +59,8 @@ import {
59
59
  Trash2,
60
60
  Type,
61
61
  Users,
62
+ Eye,
63
+ Wrench,
62
64
  X,
63
65
  Zap,
64
66
  } from "lucide-react";
@@ -4316,6 +4318,18 @@ function WorkspaceBuilder({ initialConfig, initialSourceRecords, adapterConfig,
4316
4318
  workspaceConfig: config,
4317
4319
  workspaceSourceRecords,
4318
4320
  }), [config, workspaceSourceRecords]);
4321
+ // Safe runtime descriptor for the secondary readiness lenses — assembled from
4322
+ // the persistence/adapter props the builder already receives (no fetch, no
4323
+ // secrets; booleans only).
4324
+ const lensMetadataGraph = useMemo(() => ({
4325
+ runtime: {
4326
+ persistenceMode: persistence?.mode || "",
4327
+ persistenceAdapter: persistence?.mode === "database" ? (adapterConfig?.dataAdapter || null) : null,
4328
+ allowFsWrite: persistence?.mode === "filesystem" && persistence?.canSave === true,
4329
+ nangoConfigured: Boolean(adapterConfig?.nango?.hasSecretKey),
4330
+ deploy: { target: adapterConfig?.deployTarget || "" },
4331
+ },
4332
+ }), [persistence, adapterConfig]);
4319
4333
  const activationStarted = activationState.completedCount > 0;
4320
4334
  const activationComplete = Boolean(activationState.complete);
4321
4335
  const activationUiCache = useMemo(() => getWorkspaceUiCache(config), [config]);
@@ -5752,6 +5766,40 @@ function WorkspaceBuilder({ initialConfig, initialSourceRecords, adapterConfig,
5752
5766
  id: "workspace.builder", group: "Navigation", icon: Home, label: "Go to Builder",
5753
5767
  run: () => showDashboardHome()
5754
5768
  });
5769
+ list.push({
5770
+ id: "nav.data-model", group: "Navigation", icon: Database, label: "Go to Management (Data Model)",
5771
+ run: () => { window.location.href = "/data-model"; }
5772
+ });
5773
+
5774
+ // Workspace Lens — fast navigation into the post-activation operating
5775
+ // surface and its filtered views. Unlocks once activation completes.
5776
+ const lensReady = Boolean(activationState?.complete);
5777
+ list.push({
5778
+ id: "lens.open", group: "Workspace Lens", icon: Eye,
5779
+ label: lensReady ? "Open Workspace Lens" : "Workspace Lens (finish setup to unlock)",
5780
+ disabled: !lensReady,
5781
+ run: () => { window.location.href = "/workspace-lens"; }
5782
+ });
5783
+ list.push({
5784
+ id: "lens.blocked", group: "Workspace Lens", icon: Eye, label: "Workspace Lens — Blocked",
5785
+ disabled: !lensReady,
5786
+ run: () => { window.location.href = "/workspace-lens?filter=blocked"; }
5787
+ });
5788
+ list.push({
5789
+ id: "lens.ready", group: "Workspace Lens", icon: Eye, label: "Workspace Lens — Ready",
5790
+ disabled: !lensReady,
5791
+ run: () => { window.location.href = "/workspace-lens?filter=ready"; }
5792
+ });
5793
+ list.push({
5794
+ id: "lens.assignable", group: "Workspace Lens", icon: Eye, label: "Workspace Lens — Agent-assignable",
5795
+ disabled: !lensReady,
5796
+ run: () => { window.location.href = "/workspace-lens?filter=assignable"; }
5797
+ });
5798
+ list.push({
5799
+ id: "lens.runs", group: "Workspace Lens", icon: Eye, label: "Workspace Lens — Runs",
5800
+ disabled: !lensReady,
5801
+ run: () => { window.location.href = "/workspace-lens?filter=runs"; }
5802
+ });
5755
5803
 
5756
5804
  return list;
5757
5805
  }, [
@@ -5770,7 +5818,8 @@ function WorkspaceBuilder({ initialConfig, initialSourceRecords, adapterConfig,
5770
5818
  saving,
5771
5819
  selectedWidget,
5772
5820
  showDashboardHome,
5773
- workspaceView
5821
+ workspaceView,
5822
+ activationState
5774
5823
  ]);
5775
5824
 
5776
5825
  return <main className="workspace-builder" onPointerDownCapture={resetWidgetSelectionOnOutsidePointer} style={builderStyle}>
@@ -5798,10 +5847,12 @@ function WorkspaceBuilder({ initialConfig, initialSourceRecords, adapterConfig,
5798
5847
  dashboardsSlot={(
5799
5848
  <button
5800
5849
  type="button"
5850
+ title="Builder"
5801
5851
  className={workspaceView === "dashboards" ? "active workspace-nav-button" : "workspace-nav-button"}
5802
5852
  onClick={showDashboardHome}
5803
5853
  >
5804
- Builder
5854
+ <Wrench size={15} aria-hidden="true" />
5855
+ <span className="workspace-nav-label">Builder</span>
5805
5856
  </button>
5806
5857
  )}
5807
5858
  managementSlot={(
@@ -5881,6 +5932,8 @@ function WorkspaceBuilder({ initialConfig, initialSourceRecords, adapterConfig,
5881
5932
  {showActivationPanel ? <WorkspaceActivationPanel
5882
5933
  workspaceConfig={config}
5883
5934
  workspaceSourceRecords={workspaceSourceRecords}
5935
+ metadataGraph={lensMetadataGraph}
5936
+ showLenses={true}
5884
5937
  onStepAction={(step) => {
5885
5938
  if (step?.id === "add-widget") return openAddWidgetBuilder();
5886
5939
  if (step?.id === "create-workflow") {
@@ -0,0 +1,76 @@
1
+ import { Suspense } from "react";
2
+ import Link from "next/link";
3
+ import { readAdapterConfig } from "@/lib/adapters/env";
4
+ import { describePersistenceMode, readWorkspaceConfig, readWorkspaceSourceRecords } from "@/lib/workspace-config";
5
+ import { deriveWorkspaceActivationState } from "@/lib/workspace-activation";
6
+ import { WorkspaceRail } from "../workspace-rail.jsx";
7
+ import { WorkspaceLensPanel } from "../components/WorkspaceLensPanel.jsx";
8
+
9
+ /**
10
+ * /workspace-lens — the dedicated Workspace Lens surface.
11
+ *
12
+ * Server-rendered and force-dynamic so it always reflects the LIVE workspace
13
+ * artifact (a live operating surface must not be statically baked). Reads the
14
+ * same governed helpers the home page uses, assembles a safe runtime
15
+ * descriptor (no secrets), and gates behind activation completeness:
16
+ * onboarding first, operating surface second.
17
+ */
18
+ export const dynamic = "force-dynamic";
19
+
20
+ async function WorkspaceLens() {
21
+ const adapter = readAdapterConfig();
22
+ const persistence = describePersistenceMode();
23
+ const workspaceConfig = await readWorkspaceConfig();
24
+ let workspaceSourceRecords = {};
25
+ try {
26
+ workspaceSourceRecords = (await readWorkspaceSourceRecords()) || {};
27
+ } catch {
28
+ workspaceSourceRecords = {};
29
+ }
30
+
31
+ const metadataGraph = {
32
+ runtime: {
33
+ persistenceMode: persistence?.mode || "",
34
+ persistenceAdapter: persistence?.mode === "database" ? (adapter?.dataAdapter || null) : null,
35
+ allowFsWrite: persistence?.mode === "filesystem" && persistence?.canSave === true,
36
+ nangoConfigured: Boolean(adapter?.nango?.hasSecretKey),
37
+ deploy: { target: adapter?.deployTarget || "" },
38
+ },
39
+ };
40
+
41
+ const activationComplete = deriveWorkspaceActivationState({ workspaceConfig, workspaceSourceRecords }).complete;
42
+
43
+ return (
44
+ <main className="workspace-builder workspace-lens-page">
45
+ <WorkspaceRail workspaceConfig={workspaceConfig || {}} />
46
+ <section className="workspace-surface workspace-lens-surface">
47
+ <div className="workspace-lens-shell">
48
+ {activationComplete ? (
49
+ <WorkspaceLensPanel
50
+ workspaceConfig={workspaceConfig}
51
+ workspaceSourceRecords={workspaceSourceRecords}
52
+ metadataGraph={metadataGraph}
53
+ />
54
+ ) : (
55
+ <div className="workspace-lens-locked">
56
+ <h1 className="workspace-lens-title">Workspace Lens is locked</h1>
57
+ <p className="workspace-lens-subtitle">
58
+ Finish workspace setup to unlock the live operating surface — state, blocked conditions,
59
+ next actions, and agent-assignable work.
60
+ </p>
61
+ <Link href="/" className="workspace-lens-next-link">Finish setup in the Builder</Link>
62
+ </div>
63
+ )}
64
+ </div>
65
+ </section>
66
+ </main>
67
+ );
68
+ }
69
+
70
+ export default function WorkspaceLensPage() {
71
+ return (
72
+ <Suspense fallback={null}>
73
+ <WorkspaceLens />
74
+ </Suspense>
75
+ );
76
+ }