specsmd 0.1.71 → 0.1.73

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.
@@ -648,39 +648,38 @@ function getOverviewViewHtml(data) {
648
648
  </div>
649
649
  </div>
650
650
  <div class="overview-fabriqa-copy">
651
- Use Fabriqa.AI with your existing AI subscription to design, run, and reuse agentic workflows around your specs. It is free to try.
651
+ Use Fabriqa.AI with your existing AI subscription to design and reuse agentic workflows around your specs. Free to try.
652
652
  </div>
653
653
  <div class="overview-fabriqa-actions">
654
654
  <div class="overview-fabriqa-link" data-url="https://fabriqa.ai">Explore Fabriqa.AI</div>
655
655
  <div class="overview-fabriqa-link secondary" data-url="https://specs.md">Open specs.md</div>
656
656
  </div>
657
- </div>
658
- <div class="overview-dashboard-tip">
659
- <div>
657
+ <div class="overview-dashboard-tip">
660
658
  <div class="overview-dashboard-title">Did you know?</div>
661
659
  <div class="overview-dashboard-copy">
662
- You can use the specsmd dashboard outside VS Code and VS Code variants. Run this from your project folder:
660
+ Use the dashboard outside VS Code with <code>npx specsmd@latest dashboard</code>.
661
+ <span class="overview-feedback-link" data-url="https://specs.md/getting-started/cli-dashboard">Docs</span>
663
662
  </div>
664
- <code>npx specsmd@latest dashboard</code>
665
- </div>
666
- <div class="overview-fabriqa-link secondary" data-url="https://specs.md/getting-started/cli-dashboard">Dashboard docs</div>
667
- </div>
668
- <div class="overview-resources-title">Community</div>
669
- <div class="overview-resources-links">
670
- <div class="overview-resource-link" data-url="https://discord.specs.md" title="Discord">
671
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
672
- <path fill="currentColor" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
673
- </svg>
674
663
  </div>
675
- <div class="overview-resource-link" data-url="https://x.com/specsmd" title="X (Twitter)">
676
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
677
- <path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
678
- </svg>
664
+ <div class="overview-footer-row">
665
+ <div class="overview-resources-links">
666
+ <div class="overview-resource-link" data-url="https://discord.specs.md" title="Discord">
667
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
668
+ <path fill="currentColor" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
669
+ </svg>
670
+ </div>
671
+ <div class="overview-resource-link" data-url="https://x.com/specsmd" title="X (Twitter)">
672
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
673
+ <path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
674
+ </svg>
675
+ </div>
676
+ </div>
677
+ <div class="overview-footer-feedback">
678
+ <span class="overview-feedback-message">Help improve specs.md</span>
679
+ <span class="overview-feedback-link" data-url="https://specs.md/feedback">Feedback</span>
680
+ </div>
679
681
  </div>
680
682
  </div>
681
- <div class="overview-feedback-message">
682
- We're new! Help us improve — <span class="overview-feedback-link" data-url="https://specs.md/feedback">share your feedback</span>
683
- </div>
684
683
  </div>
685
684
  </div>`;
686
685
  }
@@ -710,12 +709,16 @@ function createSetDataMessage(data) {
710
709
  };
711
710
  }
712
711
 
713
- const flowInfo = {
714
- id: data.flow,
715
- displayName: flowDisplayName(data.flow),
716
- icon: flowIcon(data.flow),
717
- rootFolder: flowRootFolder(data.flow)
718
- };
712
+ const availableFlows = (data.availableFlows && data.availableFlows.length > 0
713
+ ? data.availableFlows
714
+ : [data.flow])
715
+ .filter(Boolean)
716
+ .map((flow) => ({
717
+ id: flow,
718
+ displayName: flowDisplayName(flow),
719
+ icon: flowIcon(flow),
720
+ rootFolder: flowRootFolder(flow)
721
+ }));
719
722
 
720
723
  if (data.flow === 'fire') {
721
724
  return {
@@ -737,7 +740,7 @@ function createSetDataMessage(data) {
737
740
  specsHtml: '',
738
741
  overviewHtml: '',
739
742
  fireData: buildFireViewData(data.snapshot),
740
- availableFlows: [flowInfo],
743
+ availableFlows,
741
744
  activeFlowId: data.flow
742
745
  };
743
746
  }
@@ -761,7 +764,7 @@ function createSetDataMessage(data) {
761
764
  },
762
765
  specsHtml: getSpecsViewHtml(webviewData),
763
766
  overviewHtml: getOverviewViewHtml(webviewData),
764
- availableFlows: [flowInfo],
767
+ availableFlows,
765
768
  activeFlowId: data.flow
766
769
  };
767
770
  }
@@ -6167,26 +6167,51 @@
6167
6167
 
6168
6168
  <!-- Resources Footer -->
6169
6169
  <div class="resources-footer">
6170
- <div class="resources-title">Links</div>
6171
- <div class="resources-links">
6172
- <div class="resource-link" @click=${() => this._openExternal("https://specs.md")} title="Website">
6173
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6174
- <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
6175
- </svg>
6170
+ <div class="fabriqa-card">
6171
+ <div class="fabriqa-brand">
6172
+ <div class="fabriqa-mark">FA</div>
6173
+ <div>
6174
+ <div class="fabriqa-title">specs.md by Fabriqa.AI</div>
6175
+ <div class="fabriqa-subtitle">Spec-native agentic development environment</div>
6176
+ </div>
6176
6177
  </div>
6177
- <div class="resource-link" @click=${() => this._openExternal("https://discord.specs.md")} title="Discord">
6178
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6179
- <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
6180
- </svg>
6178
+ <div class="fabriqa-copy">
6179
+ Use Fabriqa.AI with your existing AI subscription to design and reuse agentic workflows around your specs. Free to try.
6181
6180
  </div>
6182
- <div class="resource-link" @click=${() => this._openExternal("https://x.com/specsmd")} title="X (Twitter)">
6183
- <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6184
- <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
6185
- </svg>
6181
+ <div class="fabriqa-actions">
6182
+ <div class="fabriqa-link" @click=${() => this._openExternal("https://fabriqa.ai")}>Explore Fabriqa.AI</div>
6183
+ <div class="fabriqa-link secondary" @click=${() => this._openExternal("https://specs.md")}>Open specs.md</div>
6184
+ </div>
6185
+ <div class="dashboard-tip">
6186
+ <div class="dashboard-tip-title">Did you know?</div>
6187
+ <div class="dashboard-tip-copy">
6188
+ Use the dashboard outside VS Code with <code>npx specsmd@latest dashboard</code>.
6189
+ <span class="feedback-link" @click=${() => this._openExternal("https://specs.md/getting-started/cli-dashboard")}>Docs</span>
6190
+ </div>
6191
+ </div>
6192
+ <div class="footer-row">
6193
+ <div class="resources-links">
6194
+ <div class="resource-link" @click=${() => this._openExternal("https://specs.md")} title="Website">
6195
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6196
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
6197
+ </svg>
6198
+ </div>
6199
+ <div class="resource-link" @click=${() => this._openExternal("https://discord.specs.md")} title="Discord">
6200
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6201
+ <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
6202
+ </svg>
6203
+ </div>
6204
+ <div class="resource-link" @click=${() => this._openExternal("https://x.com/specsmd")} title="X (Twitter)">
6205
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
6206
+ <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
6207
+ </svg>
6208
+ </div>
6209
+ </div>
6210
+ <div class="footer-feedback">
6211
+ <span class="feedback-message">Help improve specs.md</span>
6212
+ <span class="feedback-link" @click=${() => this._openExternal("https://specs.md/feedback")}>Feedback</span>
6213
+ </div>
6186
6214
  </div>
6187
- </div>
6188
- <div class="feedback-message">
6189
- We're new! Help us improve — <span class="feedback-link" @click=${() => this._openExternal("https://specs.md/feedback")}>share your feedback</span>
6190
6215
  </div>
6191
6216
  </div>
6192
6217
  </div>
@@ -6428,37 +6453,22 @@
6428
6453
 
6429
6454
  /* Resources Footer */
6430
6455
  .resources-footer {
6431
- position: sticky;
6432
- bottom: 0;
6433
- background: var(--background);
6434
- border-top: 1px solid var(--border-color);
6435
- padding: 12px;
6436
- margin-top: auto;
6437
- }
6438
-
6439
- .resources-title {
6440
- font-size: 9px;
6441
- font-weight: 600;
6442
- text-transform: uppercase;
6443
- color: var(--description-foreground);
6444
- letter-spacing: 0.5px;
6445
- margin-bottom: 8px;
6446
- text-align: center;
6456
+ margin-top: 14px;
6447
6457
  }
6448
6458
 
6449
6459
  .resources-links {
6450
- display: flex;
6451
- gap: 12px;
6452
- justify-content: center;
6460
+ display: inline-flex;
6461
+ flex-wrap: wrap;
6462
+ gap: 6px;
6453
6463
  }
6454
6464
 
6455
6465
  .resource-link {
6456
- display: flex;
6466
+ display: inline-flex;
6457
6467
  align-items: center;
6458
6468
  justify-content: center;
6459
- width: 36px;
6460
- height: 36px;
6461
- border-radius: 8px;
6469
+ width: 28px;
6470
+ height: 28px;
6471
+ border-radius: 6px;
6462
6472
  background: var(--editor-background);
6463
6473
  border: 1px solid var(--border-color);
6464
6474
  cursor: pointer;
@@ -6473,19 +6483,15 @@
6473
6483
  }
6474
6484
 
6475
6485
  .resource-link svg {
6476
- width: 18px;
6477
- height: 18px;
6486
+ width: 14px;
6487
+ height: 14px;
6478
6488
  fill: currentColor;
6479
6489
  }
6480
6490
 
6481
6491
  .feedback-message {
6482
- text-align: center;
6492
+ display: inline;
6483
6493
  font-size: 11px;
6484
6494
  color: var(--description-foreground);
6485
- margin-top: 12px;
6486
- padding: 8px 12px;
6487
- background: var(--editor-background);
6488
- border-radius: 6px;
6489
6495
  }
6490
6496
 
6491
6497
  .feedback-link {
@@ -6497,6 +6503,120 @@
6497
6503
  .feedback-link:hover {
6498
6504
  opacity: 0.8;
6499
6505
  }
6506
+
6507
+ .fabriqa-card {
6508
+ padding: 10px;
6509
+ border: 1px solid rgba(249, 115, 22, 0.35);
6510
+ border-radius: 6px;
6511
+ background: linear-gradient(135deg, rgba(249, 115, 22, 0.08), rgba(34, 197, 94, 0.05));
6512
+ }
6513
+
6514
+ .fabriqa-brand {
6515
+ display: flex;
6516
+ align-items: center;
6517
+ gap: 8px;
6518
+ margin-bottom: 6px;
6519
+ }
6520
+
6521
+ .fabriqa-mark {
6522
+ display: flex;
6523
+ align-items: center;
6524
+ justify-content: center;
6525
+ flex: 0 0 26px;
6526
+ height: 26px;
6527
+ border-radius: 6px;
6528
+ background: var(--status-active);
6529
+ color: #ffffff;
6530
+ font-size: 10px;
6531
+ font-weight: 700;
6532
+ }
6533
+
6534
+ .fabriqa-title {
6535
+ font-size: 13px;
6536
+ font-weight: 700;
6537
+ color: var(--foreground);
6538
+ }
6539
+
6540
+ .fabriqa-subtitle,
6541
+ .fabriqa-copy,
6542
+ .dashboard-tip-copy {
6543
+ font-size: 11px;
6544
+ line-height: 1.45;
6545
+ color: var(--description-foreground);
6546
+ }
6547
+
6548
+ .fabriqa-copy {
6549
+ margin-bottom: 8px;
6550
+ }
6551
+
6552
+ .fabriqa-actions {
6553
+ display: flex;
6554
+ flex-wrap: wrap;
6555
+ gap: 8px;
6556
+ }
6557
+
6558
+ .fabriqa-link {
6559
+ display: inline-flex;
6560
+ align-items: center;
6561
+ justify-content: center;
6562
+ min-height: 26px;
6563
+ padding: 0 8px;
6564
+ border-radius: 5px;
6565
+ background: var(--status-active);
6566
+ color: #ffffff;
6567
+ font-size: 11px;
6568
+ font-weight: 600;
6569
+ cursor: pointer;
6570
+ }
6571
+
6572
+ .fabriqa-link.secondary {
6573
+ border: 1px solid var(--border-color);
6574
+ background: var(--editor-background);
6575
+ color: var(--foreground);
6576
+ }
6577
+
6578
+ .fabriqa-link:hover {
6579
+ opacity: 0.86;
6580
+ }
6581
+
6582
+ .dashboard-tip {
6583
+ padding-top: 8px;
6584
+ margin-top: 8px;
6585
+ border-top: 1px solid var(--border-color);
6586
+ }
6587
+
6588
+ .dashboard-tip-title {
6589
+ margin-bottom: 4px;
6590
+ color: var(--foreground);
6591
+ font-size: 11px;
6592
+ font-weight: 700;
6593
+ }
6594
+
6595
+ .dashboard-tip code {
6596
+ padding: 1px 4px;
6597
+ border-radius: 4px;
6598
+ background: var(--background);
6599
+ color: var(--foreground);
6600
+ font-family: var(--font-family);
6601
+ }
6602
+
6603
+ .footer-row {
6604
+ display: flex;
6605
+ flex-wrap: wrap;
6606
+ align-items: center;
6607
+ justify-content: space-between;
6608
+ gap: 8px;
6609
+ padding-top: 8px;
6610
+ margin-top: 8px;
6611
+ border-top: 1px solid var(--border-color);
6612
+ }
6613
+
6614
+ .footer-feedback {
6615
+ display: flex;
6616
+ flex-wrap: wrap;
6617
+ align-items: center;
6618
+ gap: 6px;
6619
+ }
6500
6620
  `
6501
6621
  ];
6502
6622
  __decorateClass([
@@ -7772,36 +7892,33 @@
7772
7892
 
7773
7893
  /* ==================== OVERVIEW RESOURCES FOOTER ==================== */
7774
7894
  .overview-resources-footer {
7775
- margin-top: 20px;
7776
- padding-top: 16px;
7777
- border-top: 1px solid var(--border-color);
7895
+ margin-top: 14px;
7778
7896
  }
7779
7897
 
7780
7898
  .overview-fabriqa-card {
7781
- margin-bottom: 14px;
7782
- padding: 14px;
7899
+ padding: 10px;
7783
7900
  border: 1px solid var(--border-color);
7784
- border-radius: 8px;
7901
+ border-radius: 6px;
7785
7902
  background: var(--editor-background);
7786
7903
  }
7787
7904
 
7788
7905
  .overview-fabriqa-brand {
7789
7906
  display: flex;
7790
7907
  align-items: center;
7791
- gap: 10px;
7792
- margin-bottom: 10px;
7908
+ gap: 8px;
7909
+ margin-bottom: 6px;
7793
7910
  }
7794
7911
 
7795
7912
  .overview-fabriqa-mark {
7796
- width: 34px;
7797
- height: 34px;
7798
- border-radius: 8px;
7913
+ width: 26px;
7914
+ height: 26px;
7915
+ border-radius: 6px;
7799
7916
  display: inline-flex;
7800
7917
  align-items: center;
7801
7918
  justify-content: center;
7802
7919
  background: var(--accent-primary);
7803
7920
  color: #ffffff;
7804
- font-size: 12px;
7921
+ font-size: 10px;
7805
7922
  font-weight: 700;
7806
7923
  flex-shrink: 0;
7807
7924
  }
@@ -7822,7 +7939,7 @@
7822
7939
  }
7823
7940
 
7824
7941
  .overview-fabriqa-copy {
7825
- margin-bottom: 12px;
7942
+ margin-bottom: 8px;
7826
7943
  }
7827
7944
 
7828
7945
  .overview-fabriqa-actions {
@@ -7835,9 +7952,9 @@
7835
7952
  display: inline-flex;
7836
7953
  align-items: center;
7837
7954
  justify-content: center;
7838
- min-height: 30px;
7839
- padding: 0 10px;
7840
- border-radius: 6px;
7955
+ min-height: 26px;
7956
+ padding: 0 8px;
7957
+ border-radius: 5px;
7841
7958
  background: var(--accent-primary);
7842
7959
  color: #ffffff;
7843
7960
  font-size: 11px;
@@ -7856,15 +7973,9 @@
7856
7973
  }
7857
7974
 
7858
7975
  .overview-dashboard-tip {
7859
- display: flex;
7860
- align-items: flex-start;
7861
- justify-content: space-between;
7862
- gap: 12px;
7863
- margin-bottom: 14px;
7864
- padding: 12px;
7865
- border: 1px solid var(--border-color);
7866
- border-radius: 8px;
7867
- background: var(--vscode-input-background);
7976
+ padding-top: 8px;
7977
+ margin-top: 8px;
7978
+ border-top: 1px solid var(--border-color);
7868
7979
  }
7869
7980
 
7870
7981
  .overview-dashboard-title {
@@ -7875,39 +7986,25 @@
7875
7986
  }
7876
7987
 
7877
7988
  .overview-dashboard-tip code {
7878
- display: inline-block;
7879
- margin-top: 8px;
7880
- padding: 5px 7px;
7989
+ padding: 1px 4px;
7881
7990
  border-radius: 4px;
7882
7991
  background: var(--editor-background);
7883
7992
  color: var(--foreground);
7884
- font-size: 10px;
7885
- white-space: nowrap;
7886
- }
7887
-
7888
- .overview-resources-title {
7889
- font-size: 9px;
7890
- font-weight: 600;
7891
- text-transform: uppercase;
7892
- color: var(--description-foreground);
7893
- letter-spacing: 0.5px;
7894
- margin-bottom: 8px;
7895
- text-align: center;
7896
7993
  }
7897
7994
 
7898
7995
  .overview-resources-links {
7899
- display: flex;
7900
- gap: 12px;
7901
- justify-content: center;
7996
+ display: inline-flex;
7997
+ flex-wrap: wrap;
7998
+ gap: 6px;
7902
7999
  }
7903
8000
 
7904
8001
  .overview-resource-link {
7905
- display: flex;
8002
+ display: inline-flex;
7906
8003
  align-items: center;
7907
8004
  justify-content: center;
7908
- width: 36px;
7909
- height: 36px;
7910
- border-radius: 8px;
8005
+ width: 28px;
8006
+ height: 28px;
8007
+ border-radius: 6px;
7911
8008
  background: var(--editor-background);
7912
8009
  border: 1px solid var(--border-color);
7913
8010
  cursor: pointer;
@@ -7922,18 +8019,14 @@
7922
8019
  }
7923
8020
 
7924
8021
  .overview-resource-link svg {
7925
- width: 18px;
7926
- height: 18px;
8022
+ width: 14px;
8023
+ height: 14px;
7927
8024
  }
7928
8025
 
7929
8026
  .overview-feedback-message {
7930
- text-align: center;
8027
+ display: inline;
7931
8028
  font-size: 11px;
7932
8029
  color: var(--description-foreground);
7933
- margin-top: 12px;
7934
- padding: 8px 12px;
7935
- background: var(--editor-background);
7936
- border-radius: 6px;
7937
8030
  }
7938
8031
 
7939
8032
  .overview-feedback-link {
@@ -7946,6 +8039,24 @@
7946
8039
  opacity: 0.8;
7947
8040
  }
7948
8041
 
8042
+ .overview-footer-row {
8043
+ display: flex;
8044
+ flex-wrap: wrap;
8045
+ align-items: center;
8046
+ justify-content: space-between;
8047
+ gap: 8px;
8048
+ padding-top: 8px;
8049
+ margin-top: 8px;
8050
+ border-top: 1px solid var(--border-color);
8051
+ }
8052
+
8053
+ .overview-footer-feedback {
8054
+ display: flex;
8055
+ flex-wrap: wrap;
8056
+ align-items: center;
8057
+ gap: 6px;
8058
+ }
8059
+
7949
8060
  /* ==================== EMPTY STATE ==================== */
7950
8061
  .empty-state {
7951
8062
  padding: 20px;
@@ -5,7 +5,7 @@ const { URL } = require('url');
5
5
  const { spawn } = require('child_process');
6
6
  const crypto = require('crypto');
7
7
  const { createWatchRuntime } = require('../runtime/watch-runtime');
8
- const { detectFlow } = require('../flow-detect');
8
+ const { detectAvailableFlows, detectFlow } = require('../flow-detect');
9
9
  const { loadWebDashboardData } = require('./snapshot');
10
10
 
11
11
  const PUBLIC_DIR = path.join(__dirname, 'public');
@@ -179,9 +179,13 @@ async function startDashboardWeb(options = {}) {
179
179
  const clients = new Set();
180
180
  let watcher = null;
181
181
  let lastData = null;
182
+ let activeFlow = options.flow || null;
182
183
 
183
184
  async function loadAndBroadcast() {
184
- lastData = await loadWebDashboardData({ workspacePath, flow: options.flow });
185
+ lastData = await loadWebDashboardData({ workspacePath, flow: activeFlow });
186
+ if (lastData.flow) {
187
+ activeFlow = lastData.flow;
188
+ }
185
189
  const message = lastData.webviewMessage || lastData;
186
190
  const payload = `event: message\ndata: ${JSON.stringify(message)}\n\n`;
187
191
  for (const client of clients) {
@@ -218,6 +222,19 @@ async function startDashboardWeb(options = {}) {
218
222
  sendJson(res, 200, { ok: true, data });
219
223
  return;
220
224
  }
225
+ if (message.type === 'switchFlow') {
226
+ const availableFlows = detectAvailableFlows(workspacePath);
227
+ const requestedFlow = typeof message.flowId === 'string' ? message.flowId : null;
228
+ if (requestedFlow && availableFlows.includes(requestedFlow)) {
229
+ activeFlow = requestedFlow;
230
+ } else if (availableFlows.length > 0) {
231
+ const currentIndex = availableFlows.indexOf(activeFlow);
232
+ activeFlow = availableFlows[(currentIndex + 1) % availableFlows.length];
233
+ }
234
+ const data = await loadAndBroadcast();
235
+ sendJson(res, 200, { ok: true, data });
236
+ return;
237
+ }
221
238
  if (message.type === 'openExternal') {
222
239
  const opened = openExternal(message.url);
223
240
  sendJson(res, opened ? 200 : 400, opened
@@ -308,14 +325,9 @@ async function startDashboardWeb(options = {}) {
308
325
 
309
326
  const initialData = await loadAndBroadcast();
310
327
  if (options.watch !== false && initialData.flow) {
311
- let detection = null;
312
- try {
313
- detection = detectFlow(workspacePath, options.flow);
314
- } catch {
315
- detection = null;
316
- }
317
- const flow = detection?.flow || initialData.flow;
318
- const roots = buildWatchRoots(workspacePath, flow).filter((root) => fs.existsSync(root));
328
+ const roots = detectAvailableFlows(workspacePath)
329
+ .flatMap((flow) => buildWatchRoots(workspacePath, flow))
330
+ .filter((root) => fs.existsSync(root));
319
331
  if (roots.length > 0) {
320
332
  watcher = createWatchRuntime({
321
333
  rootPaths: roots,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specsmd",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {