@yemi33/minions 0.1.2147 → 0.1.2149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/minions.js CHANGED
@@ -1044,6 +1044,14 @@ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
1044
1044
  Dashboard:
1045
1045
  minions dash Start web dashboard (default :7331)
1046
1046
 
1047
+ Watchdog (out-of-process recovery):
1048
+ minions watchdog install [--interval=5]
1049
+ Register OS scheduler task to probe + heal every N minutes
1050
+ (Windows Task Scheduler / macOS launchd / Linux systemd --user)
1051
+ minions watchdog uninstall Remove the scheduled task (idempotent)
1052
+ minions watchdog status Show registration + last-run details from the OS scheduler
1053
+ minions watchdog tick One-shot probe + recovery (used by the scheduler; safe to run by hand)
1054
+
1047
1055
  Runtime root: ${MINIONS_HOME}
1048
1056
  `);
1049
1057
  } else if (cmd === 'init') {
@@ -292,12 +292,19 @@ async function openSettings() {
292
292
  '<div class="settings-pane-sub">Persistent CC worker pool and git worktree provisioning. Tune these only if you see worktree-create timeouts or slow CC cold-spawns.</div>' +
293
293
  '<div class="settings-stack" style="margin-bottom:12px">' +
294
294
  settingsToggle('CC Worker Pool', 'set-ccUseWorkerPool', (e.ccUseWorkerPool === undefined ? ((e.ccCli || e.defaultCli) === 'copilot') : !!e.ccUseWorkerPool), 'Route Command Center / doc-chat through a persistent copilot --acp worker per tab instead of spawning a fresh CLI per turn. Copilot-only (Agent Client Protocol transport); Claude does not implement ACP, so this toggle has no effect when CC runtime is Claude. Default ON for copilot (cold-spawn ~20s on Windows); forced OFF for non-copilot CC runtimes regardless of this toggle.') +
295
+ // W-mq6f2fe0000557fa — opt-in: auto-kill orphan spawn-agent processes
296
+ // holding a stuck worktree's cwd. Gated by safe-reap criteria (cmdline
297
+ // matches spawn-agent.js + basename + age > agentTimeout * 2). Default
298
+ // OFF because killing a foreign process is destructive.
299
+ settingsToggle('Auto-reap orphan worktree holders', 'set-autoReapOrphanWorktreeHolders', !!e.autoReapOrphanWorktreeHolders,
300
+ 'When ON, the periodic orphan-worktree sweep automatically kills unambiguous orphan `spawn-agent.js` processes holding a stuck worktree\'s cwd (Windows file-lock pattern, e.g. W-mq1k8z6o003acd89 / PID 16828). Safe-reap criteria: cmdline must match spawn-agent.js, reference the worktree basename, AND process age must exceed `engine.agentTimeout * 2`. Default OFF because killing a foreign process is destructive. The holder SCAN runs either way and is appended to the escalation inbox note.') +
295
301
  '</div>' +
296
302
  '<div class="settings-grid-2">' +
297
303
  settingsField('Worktree Create Timeout', 'set-worktreeCreateTimeout', e.worktreeCreateTimeout || 300000, 'ms', 'Timeout for git worktree add (increase for large repos/Windows)') +
298
304
  settingsField('Worktree Create Retries', 'set-worktreeCreateRetries', e.worktreeCreateRetries || 1, '', 'Retry count for transient worktree add failures (0-3)') +
299
305
  settingsField('Worktree Root', 'set-worktreeRoot', e.worktreeRoot || '../worktrees', '', 'Relative or absolute path for git worktrees; on Windows prefer a short path like C:\\wt') +
300
306
  settingsField('Assert-Clean Status Probe Timeout', 'set-assertCleanStatusTimeoutMs', e.assertCleanStatusTimeoutMs || 10000, 'ms', 'Timeout for the `git status --porcelain` preflight probe in assertCleanSharedWorktree. Raise this (e.g. 60000) on GVFS/Plastic-backed monorepos where sparse hydration runs longer than the 10s default. On timeout the engine quarantines the bad worktree and emits a RETRYABLE failure so the next dispatch starts fresh. Clamped 1000–120000ms.') +
307
+ settingsField('Orphan-holder scan timeout', 'set-orphanHolderScanTimeoutMs', e.orphanHolderScanTimeoutMs || 5000, 'ms', 'Cap on the cross-platform scan (PowerShell / /proc walk / lsof) that identifies the OS process holding a stuck worktree\'s cwd. Bumps up only matter on heavily-loaded hosts where the holder scan races the sweep tick. Clamped 1000–30000ms.') +
301
308
  '</div>';
302
309
 
303
310
  const paneCopilot =
@@ -873,6 +880,8 @@ async function saveSettings() {
873
880
  autoFixHumanComments: document.getElementById('set-autoFixHumanComments').checked,
874
881
  autoCompletePrs: document.getElementById('set-autoCompletePrs').checked,
875
882
  ccUseWorkerPool: !!document.getElementById('set-ccUseWorkerPool')?.checked,
883
+ autoReapOrphanWorktreeHolders: !!document.getElementById('set-autoReapOrphanWorktreeHolders')?.checked,
884
+ orphanHolderScanTimeoutMs: document.getElementById('set-orphanHolderScanTimeoutMs')?.value,
876
885
  adoPollEnabled: document.getElementById('set-adoPollEnabled').checked,
877
886
  ghPollEnabled: document.getElementById('set-ghPollEnabled').checked,
878
887
  prPollStatusEvery: document.getElementById('set-prPollStatusEvery').value,
@@ -8,7 +8,8 @@
8
8
  silently break (handler attaches before crash, button still renders,
9
9
  click fires but no global handler). addEventListener attaches inside
10
10
  the same scope and is observable in DevTools when wiring fails. -->
11
- <button id="slim-new-chat-btn" class="icon-btn" title="New chat (clears session)">&#x270E;</button>
11
+ <button id="slim-back-classic-btn" class="topbar-back-btn" title="Return to the classic dashboard">&#8592; Classic dashboard</button>
12
+ <button id="slim-report-bug-btn" class="topbar-back-btn" title="Report a bug in Minions">Report Bug</button>
12
13
  <button id="slim-settings-btn" class="icon-btn" title="Settings">&#9881;</button>
13
14
  </div>
14
15
  </div>
@@ -171,8 +171,9 @@
171
171
  inputEl.focus();
172
172
  }
173
173
 
174
- var newChatBtn = document.getElementById('slim-new-chat-btn');
175
- if (newChatBtn) newChatBtn.addEventListener('click', slimChatNew);
174
+ // (The header "new chat" button was replaced by "Classic dashboard" /
175
+ // "Report Bug"; new chats are created via the "+" affordance in the chat
176
+ // tab bar — see renderTabBar.)
176
177
  sendBtn.addEventListener('click', sendMessage);
177
178
  stopBtn.addEventListener('click', abortInFlight);
178
179
  inputEl.addEventListener('keydown', function(ev) {
@@ -83,7 +83,12 @@
83
83
  chip.title = 'review';
84
84
  } else {
85
85
  chip.className = 'completions-card-type-chip';
86
- chip.textContent = typeEmoji(c.type);
86
+ // Known types → Fluent icon via CSS mask (data-type); unknown → "•" glyph.
87
+ if (c.type && TYPE_ICON_SET[c.type]) {
88
+ chip.setAttribute('data-type', c.type);
89
+ } else {
90
+ chip.textContent = '•';
91
+ }
87
92
  if (c.type) chip.title = c.type;
88
93
  }
89
94
  railTop.appendChild(chip);
@@ -92,7 +97,9 @@
92
97
  railBottom.className = 'completions-card-rail-bottom';
93
98
  var icon = document.createElement('span');
94
99
  icon.className = 'completions-card-status-icon ' + status;
95
- icon.textContent = status === 'active' ? '●' : (status === 'ok' ? '✓' : (status === 'warn' ? '⚠' : '✕'));
100
+ // ok/warn/fail render as Fluent icons via the status class (CSS mask in
101
+ // styles.css); the live 'active' state keeps its pulsing dot.
102
+ if (status === 'active') icon.textContent = '●';
96
103
  icon.title = status === 'active' ? 'Running' : (status === 'ok' ? 'Success' : (status === 'warn' ? 'Partial' : 'Failure'));
97
104
  var sep = document.createElement('span');
98
105
  sep.className = 'completions-card-rail-sep';
@@ -474,6 +474,29 @@
474
474
  .tile-chip.blue { background: rgba(88, 166, 255, 0.12); color: var(--blue); border-color: var(--blue); }
475
475
  .tile-empty { color: var(--muted); font-style: italic; font-size: 13px; }
476
476
 
477
+ /* Pinned-context list rows (slim-pinned-modal). */
478
+ .pinned-row {
479
+ border: 1px solid var(--border);
480
+ border-radius: var(--radius);
481
+ background: var(--surface2);
482
+ padding: 10px 12px;
483
+ margin-bottom: 8px;
484
+ }
485
+ .pinned-row-top { display: flex; align-items: center; gap: 8px; }
486
+ .pinned-row-title {
487
+ flex: 1; min-width: 0;
488
+ font-weight: 600; font-size: var(--text-md); color: var(--text);
489
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
490
+ }
491
+ .pinned-row-preview {
492
+ margin-top: 6px;
493
+ font-size: var(--text-base); color: var(--muted); line-height: 1.5;
494
+ white-space: pre-wrap; word-break: break-word;
495
+ }
496
+ .pinned-row-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
497
+ .pinned-row-actions .btn-secondary { padding: 4px 12px; font-size: var(--text-base); }
498
+ .pinned-row-unpin { color: var(--red); border-color: var(--red); }
499
+
477
500
  .chat-thinking {
478
501
  color: var(--muted);
479
502
  font-size: 13px;
@@ -564,7 +587,20 @@
564
587
  transition: border-color 0.15s, background 0.15s, color 0.15s;
565
588
  }
566
589
  .link-pr-btn:hover { border-color: var(--green); background: var(--surface); color: var(--green); }
567
- .link-pr-btn .link-pr-icon { font-size: 16px; }
590
+ /* Action-button icons render as Fluent System Icons (Microsoft, MIT — see
591
+ attribution in the completion-card block) via CSS mask, inheriting the
592
+ button text color (currentColor → green on hover). */
593
+ .link-pr-btn .link-pr-icon {
594
+ display: inline-block;
595
+ width: 18px;
596
+ height: 18px;
597
+ background-color: currentColor;
598
+ -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
599
+ -webkit-mask-position: center; mask-position: center;
600
+ -webkit-mask-size: contain; mask-size: contain;
601
+ }
602
+ .act-ic-link { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M9%207C9.55228%207%2010%207.44772%2010%208C10%208.51284%209.61396%208.93551%209.11662%208.99327L9%209H7C5.34315%209%204%2010.3431%204%2012C4%2013.5977%205.24892%2014.9037%206.82373%2014.9949L7%2015H9C9.55228%2015%2010%2015.4477%2010%2016C10%2016.5128%209.61396%2016.9355%209.11662%2016.9933L9%2017H7C4.23858%2017%202%2014.7614%202%2012C2%209.31125%204.12231%207.11818%206.78311%207.00462L7%207H9ZM17%207C19.7614%207%2022%209.23858%2022%2012C22%2014.6888%2019.8777%2016.8818%2017.2169%2016.9954L17%2017H15C14.4477%2017%2014%2016.5523%2014%2016C14%2015.4872%2014.386%2015.0645%2014.8834%2015.0067L15%2015H17C18.6569%2015%2020%2013.6569%2020%2012C20%2010.4023%2018.7511%209.09634%2017.1763%209.00509L17%209H15C14.4477%209%2014%208.55228%2014%208C14%207.48716%2014.386%207.06449%2014.8834%207.00673L15%207H17ZM7%2011H17C17.5523%2011%2018%2011.4477%2018%2012C18%2012.5128%2017.614%2012.9355%2017.1166%2012.9933L17%2013H7C6.44772%2013%206%2012.5523%206%2012C6%2011.4872%206.38604%2011.0645%206.88338%2011.0067L7%2011H17H7Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M9%207C9.55228%207%2010%207.44772%2010%208C10%208.51284%209.61396%208.93551%209.11662%208.99327L9%209H7C5.34315%209%204%2010.3431%204%2012C4%2013.5977%205.24892%2014.9037%206.82373%2014.9949L7%2015H9C9.55228%2015%2010%2015.4477%2010%2016C10%2016.5128%209.61396%2016.9355%209.11662%2016.9933L9%2017H7C4.23858%2017%202%2014.7614%202%2012C2%209.31125%204.12231%207.11818%206.78311%207.00462L7%207H9ZM17%207C19.7614%207%2022%209.23858%2022%2012C22%2014.6888%2019.8777%2016.8818%2017.2169%2016.9954L17%2017H15C14.4477%2017%2014%2016.5523%2014%2016C14%2015.4872%2014.386%2015.0645%2014.8834%2015.0067L15%2015H17C18.6569%2015%2020%2013.6569%2020%2012C20%2010.4023%2018.7511%209.09634%2017.1763%209.00509L17%209H15C14.4477%209%2014%208.55228%2014%208C14%207.48716%2014.386%207.06449%2014.8834%207.00673L15%207H17ZM7%2011H17C17.5523%2011%2018%2011.4477%2018%2012C18%2012.5128%2017.614%2012.9355%2017.1166%2012.9933L17%2013H7C6.44772%2013%206%2012.5523%206%2012C6%2011.4872%206.38604%2011.0645%206.88338%2011.0067L7%2011H17H7Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
603
+ .act-ic-pin { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M21.0682%207.75765L16.2425%202.93189C14.9152%201.60462%2012.6777%201.96772%2011.8382%203.6466L9.40281%208.51748C9.31512%208.69287%209.16223%208.82694%208.97688%208.89096L4.81061%2010.3302C3.93791%2010.6317%203.682%2011.7427%204.33487%2012.3956L7.43936%2015.5001L3.00008%2019.9394L3%2021.0001H4.06074L8.50002%2016.5607L11.6045%2019.6653C12.2574%2020.3181%2013.3684%2020.0622%2013.6699%2019.1895L15.1092%2015.0232C15.1732%2014.8379%2015.3073%2014.685%2015.4826%2014.5973L20.3535%2012.1619C22.0324%2011.3224%2022.3955%209.08491%2021.0682%207.75765Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M21.0682%207.75765L16.2425%202.93189C14.9152%201.60462%2012.6777%201.96772%2011.8382%203.6466L9.40281%208.51748C9.31512%208.69287%209.16223%208.82694%208.97688%208.89096L4.81061%2010.3302C3.93791%2010.6317%203.682%2011.7427%204.33487%2012.3956L7.43936%2015.5001L3.00008%2019.9394L3%2021.0001H4.06074L8.50002%2016.5607L11.6045%2019.6653C12.2574%2020.3181%2013.3684%2020.0622%2013.6699%2019.1895L15.1092%2015.0232C15.1732%2014.8379%2015.3073%2014.685%2015.4826%2014.5973L20.3535%2012.1619C22.0324%2011.3224%2022.3955%209.08491%2021.0682%207.75765Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
568
604
  .link-pr-btn .link-pr-label { font-weight: 600; }
569
605
  .link-pr-btn .link-pr-sub { font-size: 12px; color: var(--muted); }
570
606
 
@@ -940,19 +976,61 @@
940
976
  @media (prefers-reduced-motion: reduce) {
941
977
  .completions-card-status-icon.active { animation: none; }
942
978
  }
979
+ /* Terminal status icons (ok/warn/fail) as Fluent masks; .active keeps its
980
+ pulsing "•" dot. background-color: currentColor inherits the icon color
981
+ set above (var(--muted), or var(--blue) for active — which is unmasked). */
982
+ .completions-card-status-icon.ok,
983
+ .completions-card-status-icon.warn,
984
+ .completions-card-status-icon.fail {
985
+ display: inline-block;
986
+ width: 13px; height: 13px;
987
+ vertical-align: -2px;
988
+ background-color: currentColor;
989
+ -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
990
+ -webkit-mask-position: center; mask-position: center;
991
+ -webkit-mask-size: contain; mask-size: contain;
992
+ }
993
+ .completions-card-status-icon.ok { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M8.5%2016.5858L4.70711%2012.7929C4.31658%2012.4024%203.68342%2012.4024%203.29289%2012.7929C2.90237%2013.1834%202.90237%2013.8166%203.29289%2014.2071L7.79289%2018.7071C8.18342%2019.0976%208.81658%2019.0976%209.20711%2018.7071L20.2071%207.70711C20.5976%207.31658%2020.5976%206.68342%2020.2071%206.29289C19.8166%205.90237%2019.1834%205.90237%2018.7929%206.29289L8.5%2016.5858Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M8.5%2016.5858L4.70711%2012.7929C4.31658%2012.4024%203.68342%2012.4024%203.29289%2012.7929C2.90237%2013.1834%202.90237%2013.8166%203.29289%2014.2071L7.79289%2018.7071C8.18342%2019.0976%208.81658%2019.0976%209.20711%2018.7071L20.2071%207.70711C20.5976%207.31658%2020.5976%206.68342%2020.2071%206.29289C19.8166%205.90237%2019.1834%205.90237%2018.7929%206.29289L8.5%2016.5858Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
994
+ .completions-card-status-icon.warn { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M9.13841%203.70704C10.3662%201.43109%2013.6314%201.43093%2014.8591%203.70704L21.6023%2016.209C22.7698%2018.3741%2021.2018%2021.0016%2018.7419%2021.002H5.25462C2.79479%2021.0016%201.22676%2018.3741%202.39426%2016.209L9.13841%203.70704ZM12.0007%2015C11.4486%2015.0002%2011.0008%2015.4479%2011.0007%2016C11.0007%2016.5522%2011.4486%2016.9998%2012.0007%2017C12.5528%2016.9998%2013.0007%2016.5522%2013.0007%2016C13.0006%2015.4479%2012.5528%2015.0002%2012.0007%2015ZM12.0007%207.50001C11.5867%207.50019%2011.2508%207.83598%2011.2507%208.25001V12.75C11.2507%2013.1641%2011.5867%2013.4998%2012.0007%2013.5C12.4148%2013.4998%2012.7507%2013.1641%2012.7507%2012.75V8.25001C12.7506%207.83599%2012.4147%207.50021%2012.0007%207.50001Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M9.13841%203.70704C10.3662%201.43109%2013.6314%201.43093%2014.8591%203.70704L21.6023%2016.209C22.7698%2018.3741%2021.2018%2021.0016%2018.7419%2021.002H5.25462C2.79479%2021.0016%201.22676%2018.3741%202.39426%2016.209L9.13841%203.70704ZM12.0007%2015C11.4486%2015.0002%2011.0008%2015.4479%2011.0007%2016C11.0007%2016.5522%2011.4486%2016.9998%2012.0007%2017C12.5528%2016.9998%2013.0007%2016.5522%2013.0007%2016C13.0006%2015.4479%2012.5528%2015.0002%2012.0007%2015ZM12.0007%207.50001C11.5867%207.50019%2011.2508%207.83598%2011.2507%208.25001V12.75C11.2507%2013.1641%2011.5867%2013.4998%2012.0007%2013.5C12.4148%2013.4998%2012.7507%2013.1641%2012.7507%2012.75V8.25001C12.7506%207.83599%2012.4147%207.50021%2012.0007%207.50001Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
995
+ .completions-card-status-icon.fail { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M4.2097%204.3871L4.29289%204.29289C4.65338%203.93241%205.22061%203.90468%205.6129%204.2097L5.70711%204.29289L12%2010.585L18.2929%204.29289C18.6834%203.90237%2019.3166%203.90237%2019.7071%204.29289C20.0976%204.68342%2020.0976%205.31658%2019.7071%205.70711L13.415%2012L19.7071%2018.2929C20.0676%2018.6534%2020.0953%2019.2206%2019.7903%2019.6129L19.7071%2019.7071C19.3466%2020.0676%2018.7794%2020.0953%2018.3871%2019.7903L18.2929%2019.7071L12%2013.415L5.70711%2019.7071C5.31658%2020.0976%204.68342%2020.0976%204.29289%2019.7071C3.90237%2019.3166%203.90237%2018.6834%204.29289%2018.2929L10.585%2012L4.29289%205.70711C3.93241%205.34662%203.90468%204.77939%204.2097%204.3871L4.29289%204.29289L4.2097%204.3871Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M4.2097%204.3871L4.29289%204.29289C4.65338%203.93241%205.22061%203.90468%205.6129%204.2097L5.70711%204.29289L12%2010.585L18.2929%204.29289C18.6834%203.90237%2019.3166%203.90237%2019.7071%204.29289C20.0976%204.68342%2020.0976%205.31658%2019.7071%205.70711L13.415%2012L19.7071%2018.2929C20.0676%2018.6534%2020.0953%2019.2206%2019.7903%2019.6129L19.7071%2019.7071C19.3466%2020.0676%2018.7794%2020.0953%2018.3871%2019.7903L18.2929%2019.7071L12%2013.415L5.70711%2019.7071C5.31658%2020.0976%204.68342%2020.0976%204.29289%2019.7071C3.90237%2019.3166%203.90237%2018.6834%204.29289%2018.2929L10.585%2012L4.29289%205.70711C3.93241%205.34662%203.90468%204.77939%204.2097%204.3871L4.29289%204.29289L4.2097%204.3871Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
943
996
  .completions-card-rail-sep {
944
997
  color: var(--muted);
945
998
  line-height: 1;
946
999
  }
947
- /* Type indicator — a single emoji glyph at 28px (alone on the rail's
948
- top row). The full c.type string is exposed via the `title`
949
- attribute so hovering reveals it. */
950
- .completions-card-type-chip {
951
- font-size: 28px;
952
- line-height: 1;
953
- cursor: help;
954
- white-space: nowrap;
955
- }
1000
+ /* ───────────────────────────────────────────────────────────────────────
1001
+ Fluent System Icons (Microsoft) MIT License.
1002
+ https://github.com/microsoft/fluentui-system-icons
1003
+ Copyright (c) Microsoft Corporation. Vendored as inline CSS `mask`
1004
+ data-URIs (24px regular) so completion-card type/status icons render as
1005
+ theme-colored monochrome glyphs (currentColor) with no font asset, no
1006
+ extra dependency, and no CSP change (img-src already allows data:).
1007
+ ─────────────────────────────────────────────────────────────────────── */
1008
+ /* Type indicator. Known work types render as a monochrome Fluent icon via
1009
+ CSS mask (inherits theme color); unknown types fall back to a "•" glyph
1010
+ sized by font-size. The full c.type is exposed via the title attribute. */
1011
+ .completions-card-type-chip[data-type] {
1012
+ display: inline-block;
1013
+ width: 24px;
1014
+ height: 24px;
1015
+ background-color: var(--text);
1016
+ -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
1017
+ -webkit-mask-position: center; mask-position: center;
1018
+ -webkit-mask-size: contain; mask-size: contain;
1019
+ }
1020
+ .completions-card-type-chip[data-type="implement"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M16.5002%202C13.4627%202%2011.0002%204.46243%2011.0002%207.5C11.0002%207.94322%2011.0528%208.37496%2011.1523%208.78899L2.84099%2017.1003C1.71967%2018.2216%201.71967%2020.0396%202.84099%2021.1609C3.96231%2022.2823%205.78033%2022.2823%206.90165%2021.1609L15.214%2012.8486C15.6272%2012.9477%2016.058%2013%2016.5002%2013C19.5378%2013%2022.0002%2010.5376%2022.0002%207.5C22.0002%206.89137%2021.9011%206.30437%2021.7175%205.75516C21.6351%205.50875%2021.4311%205.32252%2021.1782%205.26294C20.9253%205.20336%2020.6595%205.27892%2020.4758%205.46266L18.0317%207.90697C17.7389%208.19989%2017.264%208.19991%2016.9711%207.907L16.0934%207.0293C15.8005%206.73642%2015.8005%206.26156%2016.0933%205.96867L18.5375%203.5243C18.7212%203.34057%2018.7967%203.07485%2018.7371%202.82197C18.6775%202.56908%2018.4913%202.36505%2018.2449%202.28268C17.6957%202.09912%2017.1088%202%2016.5002%202Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M16.5002%202C13.4627%202%2011.0002%204.46243%2011.0002%207.5C11.0002%207.94322%2011.0528%208.37496%2011.1523%208.78899L2.84099%2017.1003C1.71967%2018.2216%201.71967%2020.0396%202.84099%2021.1609C3.96231%2022.2823%205.78033%2022.2823%206.90165%2021.1609L15.214%2012.8486C15.6272%2012.9477%2016.058%2013%2016.5002%2013C19.5378%2013%2022.0002%2010.5376%2022.0002%207.5C22.0002%206.89137%2021.9011%206.30437%2021.7175%205.75516C21.6351%205.50875%2021.4311%205.32252%2021.1782%205.26294C20.9253%205.20336%2020.6595%205.27892%2020.4758%205.46266L18.0317%207.90697C17.7389%208.19989%2017.264%208.19991%2016.9711%207.907L16.0934%207.0293C15.8005%206.73642%2015.8005%206.26156%2016.0933%205.96867L18.5375%203.5243C18.7212%203.34057%2018.7967%203.07485%2018.7371%202.82197C18.6775%202.56908%2018.4913%202.36505%2018.2449%202.28268C17.6957%202.09912%2017.1088%202%2016.5002%202Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1021
+ .completions-card-type-chip[data-type="implement:large"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M16.0792%202.41459C16.2062%202.1605%2016.4659%202%2016.75%202H18.25C18.5341%202%2018.7938%202.1605%2018.9208%202.41459L19.9208%204.41459C20.033%204.63888%2020.0256%204.90438%2019.9012%205.1221L19%206.69917V12H20.25C20.6642%2012%2021%2012.3358%2021%2012.75V14.5H14V12.75C14%2012.3358%2014.3358%2012%2014.75%2012H16V6.69917L15.0988%205.1221C14.9744%204.90438%2014.967%204.63888%2015.0792%204.41459L16.0792%202.41459ZM14%2016V18.5C14%2020.433%2015.567%2022%2017.5%2022C19.433%2022%2021%2020.433%2021%2018.5V16H14ZM8.82848%202.2123C9.03402%202.07269%209.29535%202.04394%209.52632%202.13551C11.5598%202.94176%2013%204.92679%2013%207.25C13%209.37406%2011.7961%2011.2154%2010.0357%2012.1317V19.4641C10.0357%2020.8645%208.90043%2021.9998%207.5%2021.9998C6.09956%2021.9998%204.96429%2020.8645%204.96429%2019.4641V12.1317C3.20387%2011.2154%202%209.37406%202%207.25C2%204.92688%203.44005%202.94192%205.47344%202.13561C5.70441%202.04402%205.96575%202.07277%206.1713%202.21238C6.37684%202.35198%206.4999%202.58433%206.4999%202.8328V6.49988C6.4999%207.05216%206.94761%207.49988%207.4999%207.49988C8.05218%207.49988%208.4999%207.05216%208.4999%206.49988V2.83271C8.4999%202.58425%208.62295%202.35191%208.82848%202.2123Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M16.0792%202.41459C16.2062%202.1605%2016.4659%202%2016.75%202H18.25C18.5341%202%2018.7938%202.1605%2018.9208%202.41459L19.9208%204.41459C20.033%204.63888%2020.0256%204.90438%2019.9012%205.1221L19%206.69917V12H20.25C20.6642%2012%2021%2012.3358%2021%2012.75V14.5H14V12.75C14%2012.3358%2014.3358%2012%2014.75%2012H16V6.69917L15.0988%205.1221C14.9744%204.90438%2014.967%204.63888%2015.0792%204.41459L16.0792%202.41459ZM14%2016V18.5C14%2020.433%2015.567%2022%2017.5%2022C19.433%2022%2021%2020.433%2021%2018.5V16H14ZM8.82848%202.2123C9.03402%202.07269%209.29535%202.04394%209.52632%202.13551C11.5598%202.94176%2013%204.92679%2013%207.25C13%209.37406%2011.7961%2011.2154%2010.0357%2012.1317V19.4641C10.0357%2020.8645%208.90043%2021.9998%207.5%2021.9998C6.09956%2021.9998%204.96429%2020.8645%204.96429%2019.4641V12.1317C3.20387%2011.2154%202%209.37406%202%207.25C2%204.92688%203.44005%202.94192%205.47344%202.13561C5.70441%202.04402%205.96575%202.07277%206.1713%202.21238C6.37684%202.35198%206.4999%202.58433%206.4999%202.8328V6.49988C6.4999%207.05216%206.94761%207.49988%207.4999%207.49988C8.05218%207.49988%208.4999%207.05216%208.4999%206.49988V2.83271C8.4999%202.58425%208.62295%202.35191%208.82848%202.2123Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1022
+ .completions-card-type-chip[data-type="fix"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M14.25%202.00195C14.6297%202.00195%2014.9435%202.28411%2014.9932%202.65018L15%202.75195V3.50406C15%204.13683%2014.8041%204.72384%2014.4696%205.20775C15.8646%205.68594%2016.8883%206.96607%2016.9914%208.49849L17.2469%208.49857C18.4895%208.49343%2019.4927%207.48192%2019.4876%206.23929L19.4814%204.75369C19.4797%204.33948%2019.8141%204.00231%2020.2283%204.00059C20.6425%203.99889%2020.9797%204.33328%2020.9814%204.74749L20.9876%206.23309C20.9958%208.23733%2019.4302%209.88083%2017.4522%209.99254L17.2376%209.99859L17%209.99795V11.5L21.2528%2011.5006C21.6325%2011.5006%2021.9463%2011.7827%2021.996%2012.1488L22.0028%2012.2506C22.0028%2012.6303%2021.7207%2012.9441%2021.3546%2012.9937L21.2528%2013.0006H17.0004L17%2015L17.2376%2015.0006L17.4522%2015.0066C19.3643%2015.1146%2020.891%2016.654%2020.9832%2018.5669L20.9876%2018.7661L20.9814%2020.2517C20.9797%2020.6659%2020.6425%2021.0003%2020.2283%2020.9986C19.8486%2020.997%2019.536%2020.7136%2019.4878%2020.3473L19.4814%2020.2455L19.4876%2018.7599C19.4925%2017.569%2018.5714%2016.5904%2017.4009%2016.5064L17.2469%2016.5006L16.7713%2016.5005C16.1343%2018.5294%2014.239%2020.0011%2012%2020.0011C9.76098%2020.0011%207.86569%2018.5294%207.22873%2016.5005L6.74073%2016.5006C5.4981%2016.5057%204.49492%2017.5173%204.50005%2018.7599L4.50619%2020.2455C4.50791%2020.6597%204.17351%2020.9969%203.7593%2020.9986C3.34509%2021.0003%203.00792%2020.6659%203.00621%2020.2517L3%2018.7661C2.99178%2016.7618%204.55736%2015.1183%206.5354%2015.0066L6.75003%2015.0006L7%2015V13L2.75%2013.0006C2.3703%2013.0006%202.05651%2012.7184%202.00685%2012.3524L2%2012.2506C2%2011.8709%202.28215%2011.5571%202.64823%2011.5074L2.75%2011.5006L7%2011.5V9.99795L6.75%209.99858L6.53536%209.99253C4.62326%209.88455%203.09658%208.34519%203.00438%206.43226L3%206.23308L3.00617%204.74749C3.00789%204.33328%203.34506%203.99888%203.75927%204.00059C4.13896%204.00216%204.45159%204.28561%204.49973%204.65189L4.50616%204.75369L4.50002%206.23928C4.4951%207.43014%205.41622%208.40873%206.58667%208.49274L6.7407%208.49856L7.00857%208.49849C7.11171%206.96607%208.13544%205.68594%209.53135%205.20652C9.23317%204.77747%209.04526%204.26599%209.00718%203.71321L9%203.50406V2.75195C9%202.33774%209.33579%202.00195%209.75%202.00195C10.1297%202.00195%2010.4435%202.28411%2010.4932%202.65018L10.5%202.75195V3.50406C10.5%204.33249%2011.1716%205.00406%2012%205.00406C12.7797%205.00406%2013.4204%204.40918%2013.4931%203.64852L13.5%203.50406V2.75195C13.5%202.33774%2013.8358%202.00195%2014.25%202.00195Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M14.25%202.00195C14.6297%202.00195%2014.9435%202.28411%2014.9932%202.65018L15%202.75195V3.50406C15%204.13683%2014.8041%204.72384%2014.4696%205.20775C15.8646%205.68594%2016.8883%206.96607%2016.9914%208.49849L17.2469%208.49857C18.4895%208.49343%2019.4927%207.48192%2019.4876%206.23929L19.4814%204.75369C19.4797%204.33948%2019.8141%204.00231%2020.2283%204.00059C20.6425%203.99889%2020.9797%204.33328%2020.9814%204.74749L20.9876%206.23309C20.9958%208.23733%2019.4302%209.88083%2017.4522%209.99254L17.2376%209.99859L17%209.99795V11.5L21.2528%2011.5006C21.6325%2011.5006%2021.9463%2011.7827%2021.996%2012.1488L22.0028%2012.2506C22.0028%2012.6303%2021.7207%2012.9441%2021.3546%2012.9937L21.2528%2013.0006H17.0004L17%2015L17.2376%2015.0006L17.4522%2015.0066C19.3643%2015.1146%2020.891%2016.654%2020.9832%2018.5669L20.9876%2018.7661L20.9814%2020.2517C20.9797%2020.6659%2020.6425%2021.0003%2020.2283%2020.9986C19.8486%2020.997%2019.536%2020.7136%2019.4878%2020.3473L19.4814%2020.2455L19.4876%2018.7599C19.4925%2017.569%2018.5714%2016.5904%2017.4009%2016.5064L17.2469%2016.5006L16.7713%2016.5005C16.1343%2018.5294%2014.239%2020.0011%2012%2020.0011C9.76098%2020.0011%207.86569%2018.5294%207.22873%2016.5005L6.74073%2016.5006C5.4981%2016.5057%204.49492%2017.5173%204.50005%2018.7599L4.50619%2020.2455C4.50791%2020.6597%204.17351%2020.9969%203.7593%2020.9986C3.34509%2021.0003%203.00792%2020.6659%203.00621%2020.2517L3%2018.7661C2.99178%2016.7618%204.55736%2015.1183%206.5354%2015.0066L6.75003%2015.0006L7%2015V13L2.75%2013.0006C2.3703%2013.0006%202.05651%2012.7184%202.00685%2012.3524L2%2012.2506C2%2011.8709%202.28215%2011.5571%202.64823%2011.5074L2.75%2011.5006L7%2011.5V9.99795L6.75%209.99858L6.53536%209.99253C4.62326%209.88455%203.09658%208.34519%203.00438%206.43226L3%206.23308L3.00617%204.74749C3.00789%204.33328%203.34506%203.99888%203.75927%204.00059C4.13896%204.00216%204.45159%204.28561%204.49973%204.65189L4.50616%204.75369L4.50002%206.23928C4.4951%207.43014%205.41622%208.40873%206.58667%208.49274L6.7407%208.49856L7.00857%208.49849C7.11171%206.96607%208.13544%205.68594%209.53135%205.20652C9.23317%204.77747%209.04526%204.26599%209.00718%203.71321L9%203.50406V2.75195C9%202.33774%209.33579%202.00195%209.75%202.00195C10.1297%202.00195%2010.4435%202.28411%2010.4932%202.65018L10.5%202.75195V3.50406C10.5%204.33249%2011.1716%205.00406%2012%205.00406C12.7797%205.00406%2013.4204%204.40918%2013.4931%203.64852L13.5%203.50406V2.75195C13.5%202.33774%2013.8358%202.00195%2014.25%202.00195Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1023
+ .completions-card-type-chip[data-type="verify"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C6.47715%2022%202%2017.5228%202%2012C2%206.47715%206.47715%202%2012%202ZM15.2197%208.96967L10.75%2013.4393L8.78033%2011.4697C8.48744%2011.1768%208.01256%2011.1768%207.71967%2011.4697C7.42678%2011.7626%207.42678%2012.2374%207.71967%2012.5303L10.2197%2015.0303C10.5126%2015.3232%2010.9874%2015.3232%2011.2803%2015.0303L16.2803%2010.0303C16.5732%209.73744%2016.5732%209.26256%2016.2803%208.96967C15.9874%208.67678%2015.5126%208.67678%2015.2197%208.96967Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C6.47715%2022%202%2017.5228%202%2012C2%206.47715%206.47715%202%2012%202ZM15.2197%208.96967L10.75%2013.4393L8.78033%2011.4697C8.48744%2011.1768%208.01256%2011.1768%207.71967%2011.4697C7.42678%2011.7626%207.42678%2012.2374%207.71967%2012.5303L10.2197%2015.0303C10.5126%2015.3232%2010.9874%2015.3232%2011.2803%2015.0303L16.2803%2010.0303C16.5732%209.73744%2016.5732%209.26256%2016.2803%208.96967C15.9874%208.67678%2015.5126%208.67678%2015.2197%208.96967Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1024
+ .completions-card-type-chip[data-type="test"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M8.99998%204.5V10.7382C8.99998%2011.1132%208.90628%2011.4822%208.72739%2011.8117L7.53944%2014H16.4605L15.2726%2011.8117C15.0937%2011.4822%2015%2011.1132%2015%2010.7382V4.5H16C16.4142%204.5%2016.75%204.16421%2016.75%203.75C16.75%203.33579%2016.4142%203%2016%203H8C7.58579%203%207.25%203.33579%207.25%203.75C7.25%204.16421%207.58579%204.5%208%204.5H8.99998ZM17.2748%2015.5H6.72515L5.14269%2018.415C4.50968%2019.5811%205.35388%2020.9999%206.68068%2020.9999H17.3193C18.6461%2020.9999%2019.4903%2019.5811%2018.8573%2018.415L17.2748%2015.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M8.99998%204.5V10.7382C8.99998%2011.1132%208.90628%2011.4822%208.72739%2011.8117L7.53944%2014H16.4605L15.2726%2011.8117C15.0937%2011.4822%2015%2011.1132%2015%2010.7382V4.5H16C16.4142%204.5%2016.75%204.16421%2016.75%203.75C16.75%203.33579%2016.4142%203%2016%203H8C7.58579%203%207.25%203.33579%207.25%203.75C7.25%204.16421%207.58579%204.5%208%204.5H8.99998ZM17.2748%2015.5H6.72515L5.14269%2018.415C4.50968%2019.5811%205.35388%2020.9999%206.68068%2020.9999H17.3193C18.6461%2020.9999%2019.4903%2019.5811%2018.8573%2018.415L17.2748%2015.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1025
+ .completions-card-type-chip[data-type="plan"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M13.75%202H10.25C9.09205%202%208.13841%202.87472%208.01379%203.99944L6.25%204C5.00736%204%204%205.00736%204%206.25V19.75C4%2020.9926%205.00736%2022%206.25%2022H17.75C18.9926%2022%2020%2020.9926%2020%2019.75V6.25C20%205.00736%2018.9926%204%2017.75%204L15.9862%203.99944C15.8616%202.87472%2014.9079%202%2013.75%202ZM10.25%203.5H13.75C14.1642%203.5%2014.5%203.83579%2014.5%204.25C14.5%204.66421%2014.1642%205%2013.75%205H10.25C9.83579%205%209.5%204.66421%209.5%204.25C9.5%203.83579%209.83579%203.5%2010.25%203.5ZM12.5%2010.25C12.5%209.83579%2012.8358%209.5%2013.25%209.5H16.75C17.1642%209.5%2017.5%209.83579%2017.5%2010.25C17.5%2010.6642%2017.1642%2011%2016.75%2011H13.25C12.8358%2011%2012.5%2010.6642%2012.5%2010.25ZM13.2501%2015H16.7499C17.1642%2015%2017.4999%2015.3358%2017.4999%2015.75C17.4999%2016.1642%2017.1642%2016.5%2016.7499%2016.5H13.2501C12.8358%2016.5%2012.5001%2016.1642%2012.5001%2015.75C12.5001%2015.3358%2012.8358%2015%2013.2501%2015ZM10.7803%209.78033L8.78033%2011.7803C8.48744%2012.0732%208.01256%2012.0732%207.71967%2011.7803L6.71967%2010.7803C6.42678%2010.4874%206.42678%2010.0126%206.71967%209.71967C7.01256%209.42678%207.48744%209.42678%207.78033%209.71967L8.25%2010.1893L9.71967%208.71967C10.0126%208.42678%2010.4874%208.42678%2010.7803%208.71967C11.0732%209.01256%2011.0732%209.48744%2010.7803%209.78033ZM10.7803%2014.2197C11.0732%2014.5126%2011.0732%2014.9874%2010.7803%2015.2803L8.78033%2017.2803C8.48744%2017.5732%208.01256%2017.5732%207.71967%2017.2803L6.71967%2016.2803C6.42678%2015.9874%206.42678%2015.5126%206.71967%2015.2197C7.01256%2014.9268%207.48744%2014.9268%207.78033%2015.2197L8.25%2015.6893L9.71967%2014.2197C10.0126%2013.9268%2010.4874%2013.9268%2010.7803%2014.2197Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M13.75%202H10.25C9.09205%202%208.13841%202.87472%208.01379%203.99944L6.25%204C5.00736%204%204%205.00736%204%206.25V19.75C4%2020.9926%205.00736%2022%206.25%2022H17.75C18.9926%2022%2020%2020.9926%2020%2019.75V6.25C20%205.00736%2018.9926%204%2017.75%204L15.9862%203.99944C15.8616%202.87472%2014.9079%202%2013.75%202ZM10.25%203.5H13.75C14.1642%203.5%2014.5%203.83579%2014.5%204.25C14.5%204.66421%2014.1642%205%2013.75%205H10.25C9.83579%205%209.5%204.66421%209.5%204.25C9.5%203.83579%209.83579%203.5%2010.25%203.5ZM12.5%2010.25C12.5%209.83579%2012.8358%209.5%2013.25%209.5H16.75C17.1642%209.5%2017.5%209.83579%2017.5%2010.25C17.5%2010.6642%2017.1642%2011%2016.75%2011H13.25C12.8358%2011%2012.5%2010.6642%2012.5%2010.25ZM13.2501%2015H16.7499C17.1642%2015%2017.4999%2015.3358%2017.4999%2015.75C17.4999%2016.1642%2017.1642%2016.5%2016.7499%2016.5H13.2501C12.8358%2016.5%2012.5001%2016.1642%2012.5001%2015.75C12.5001%2015.3358%2012.8358%2015%2013.2501%2015ZM10.7803%209.78033L8.78033%2011.7803C8.48744%2012.0732%208.01256%2012.0732%207.71967%2011.7803L6.71967%2010.7803C6.42678%2010.4874%206.42678%2010.0126%206.71967%209.71967C7.01256%209.42678%207.48744%209.42678%207.78033%209.71967L8.25%2010.1893L9.71967%208.71967C10.0126%208.42678%2010.4874%208.42678%2010.7803%208.71967C11.0732%209.01256%2011.0732%209.48744%2010.7803%209.78033ZM10.7803%2014.2197C11.0732%2014.5126%2011.0732%2014.9874%2010.7803%2015.2803L8.78033%2017.2803C8.48744%2017.5732%208.01256%2017.5732%207.71967%2017.2803L6.71967%2016.2803C6.42678%2015.9874%206.42678%2015.5126%206.71967%2015.2197C7.01256%2014.9268%207.48744%2014.9268%207.78033%2015.2197L8.25%2015.6893L9.71967%2014.2197C10.0126%2013.9268%2010.4874%2013.9268%2010.7803%2014.2197Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1026
+ .completions-card-type-chip[data-type="plan-to-prd"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M7%204.25C7%203.00736%208.00736%202%209.25%202H14.75C15.9926%202%2017%203.00736%2017%204.25V19.75C17%2020.9926%2015.9926%2022%2014.75%2022H9.25C9.09467%2022%208.94302%2021.9843%208.79655%2021.9543C7.77126%2021.7445%207%2020.8373%207%2019.75V4.25ZM8.5%205V6.5H10.25C10.6642%206.5%2011%206.16421%2011%205.75C11%205.33579%2010.6642%205%2010.25%205H8.5ZM8.5%208V9.5H12.25C12.6642%209.5%2013%209.16421%2013%208.75C13%208.33579%2012.6642%208%2012.25%208H8.5ZM8.5%2011.25V12.75H10.25C10.6642%2012.75%2011%2012.4142%2011%2012C11%2011.5858%2010.6642%2011.25%2010.25%2011.25H8.5ZM8.5%2014.5V16H12.25C12.6642%2016%2013%2015.6642%2013%2015.25C13%2014.8358%2012.6642%2014.5%2012.25%2014.5H8.5ZM8.5%2017.5V19H10.25C10.6642%2019%2011%2018.6642%2011%2018.25C11%2017.8358%2010.6642%2017.5%2010.25%2017.5H8.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M7%204.25C7%203.00736%208.00736%202%209.25%202H14.75C15.9926%202%2017%203.00736%2017%204.25V19.75C17%2020.9926%2015.9926%2022%2014.75%2022H9.25C9.09467%2022%208.94302%2021.9843%208.79655%2021.9543C7.77126%2021.7445%207%2020.8373%207%2019.75V4.25ZM8.5%205V6.5H10.25C10.6642%206.5%2011%206.16421%2011%205.75C11%205.33579%2010.6642%205%2010.25%205H8.5ZM8.5%208V9.5H12.25C12.6642%209.5%2013%209.16421%2013%208.75C13%208.33579%2012.6642%208%2012.25%208H8.5ZM8.5%2011.25V12.75H10.25C10.6642%2012.75%2011%2012.4142%2011%2012C11%2011.5858%2010.6642%2011.25%2010.25%2011.25H8.5ZM8.5%2014.5V16H12.25C12.6642%2016%2013%2015.6642%2013%2015.25C13%2014.8358%2012.6642%2014.5%2012.25%2014.5H8.5ZM8.5%2017.5V19H10.25C10.6642%2019%2011%2018.6642%2011%2018.25C11%2017.8358%2010.6642%2017.5%2010.25%2017.5H8.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1027
+ .completions-card-type-chip[data-type="decompose"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M4%205.5C4%203.567%205.567%202%207.5%202C9.433%202%2011%203.567%2011%205.5C11%207.08957%209.94034%208.43164%208.48889%208.85835C9.17675%2011.1112%2011.272%2012.75%2013.75%2012.75H14.0805C14.4239%2011.1774%2015.8244%2010%2017.5%2010C19.433%2010%2021%2011.567%2021%2013.5C21%2015.433%2019.433%2017%2017.5%2017C15.8244%2017%2014.4239%2015.8226%2014.0805%2014.25H13.75C11.519%2014.25%209.53183%2013.2063%208.25%2011.5806L8.25%2015.0805C9.82259%2015.4239%2011%2016.8244%2011%2018.5C11%2020.433%209.433%2022%207.5%2022C5.567%2022%204%2020.433%204%2018.5C4%2016.8244%205.17741%2015.4239%206.75%2015.0805L6.75%208.91946C5.17741%208.57612%204%207.17556%204%205.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M4%205.5C4%203.567%205.567%202%207.5%202C9.433%202%2011%203.567%2011%205.5C11%207.08957%209.94034%208.43164%208.48889%208.85835C9.17675%2011.1112%2011.272%2012.75%2013.75%2012.75H14.0805C14.4239%2011.1774%2015.8244%2010%2017.5%2010C19.433%2010%2021%2011.567%2021%2013.5C21%2015.433%2019.433%2017%2017.5%2017C15.8244%2017%2014.4239%2015.8226%2014.0805%2014.25H13.75C11.519%2014.25%209.53183%2013.2063%208.25%2011.5806L8.25%2015.0805C9.82259%2015.4239%2011%2016.8244%2011%2018.5C11%2020.433%209.433%2022%207.5%2022C5.567%2022%204%2020.433%204%2018.5C4%2016.8244%205.17741%2015.4239%206.75%2015.0805L6.75%208.91946C5.17741%208.57612%204%207.17556%204%205.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1028
+ .completions-card-type-chip[data-type="meeting"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C10.3596%2022%208.77516%2021.6039%207.35578%2020.8583L3.06538%2021.9753C2.6111%2022.0937%202.1469%2021.8213%202.02858%2021.367C1.99199%2021.2266%201.99198%2021.0791%202.02855%2020.9386L3.1449%2016.6502C2.3972%2015.2294%202%2013.6428%202%2012C2%206.47715%206.47715%202%2012%202ZM13.2517%2013H8.75L8.64823%2013.0068C8.28215%2013.0565%208%2013.3703%208%2013.75C8%2014.1297%208.28215%2014.4435%208.64823%2014.4932L8.75%2014.5H13.2517L13.3535%2014.4932C13.7196%2014.4435%2014.0017%2014.1297%2014.0017%2013.75C14.0017%2013.3703%2013.7196%2013.0565%2013.3535%2013.0068L13.2517%2013ZM15.25%209.5H8.75L8.64823%209.50685C8.28215%209.55651%208%209.8703%208%2010.25C8%2010.6297%208.28215%2010.9435%208.64823%2010.9932L8.75%2011H15.25L15.3518%2010.9932C15.7178%2010.9435%2016%2010.6297%2016%2010.25C16%209.8703%2015.7178%209.55651%2015.3518%209.50685L15.25%209.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C10.3596%2022%208.77516%2021.6039%207.35578%2020.8583L3.06538%2021.9753C2.6111%2022.0937%202.1469%2021.8213%202.02858%2021.367C1.99199%2021.2266%201.99198%2021.0791%202.02855%2020.9386L3.1449%2016.6502C2.3972%2015.2294%202%2013.6428%202%2012C2%206.47715%206.47715%202%2012%202ZM13.2517%2013H8.75L8.64823%2013.0068C8.28215%2013.0565%208%2013.3703%208%2013.75C8%2014.1297%208.28215%2014.4435%208.64823%2014.4932L8.75%2014.5H13.2517L13.3535%2014.4932C13.7196%2014.4435%2014.0017%2014.1297%2014.0017%2013.75C14.0017%2013.3703%2013.7196%2013.0565%2013.3535%2013.0068L13.2517%2013ZM15.25%209.5H8.75L8.64823%209.50685C8.28215%209.55651%208%209.8703%208%2010.25C8%2010.6297%208.28215%2010.9435%208.64823%2010.9932L8.75%2011H15.25L15.3518%2010.9932C15.7178%2010.9435%2016%2010.6297%2016%2010.25C16%209.8703%2015.7178%209.55651%2015.3518%209.50685L15.25%209.5Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1029
+ .completions-card-type-chip[data-type="explore"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M3%206.5C3%204.567%204.567%203%206.5%203H9C9.55228%203%2010%203.44772%2010%204C10%204.55228%209.55228%205%209%205H6.5C5.67157%205%205%205.67157%205%206.5V9C5%209.55229%204.55228%2010%204%2010C3.44772%2010%203%209.55229%203%209V6.5ZM21%2017.5C21%2019.433%2019.433%2021%2017.5%2021H15C14.4477%2021%2014%2020.5523%2014%2020C14%2019.4477%2014.4477%2019%2015%2019L17.5%2019C18.3284%2019%2019%2018.3284%2019%2017.5V15C19%2014.4477%2019.4477%2014%2020%2014C20.5523%2014%2021%2014.4477%2021%2015V17.5ZM21%206.5C21%204.567%2019.433%203%2017.5%203H15C14.4477%203%2014%203.44772%2014%204C14%204.55228%2014.4477%205%2015%205H17.5C18.3284%205%2019%205.67157%2019%206.5V9C19%209.55228%2019.4477%2010%2020%2010C20.5523%2010%2021%209.55229%2021%209V6.5ZM6.5%2021C4.567%2021%203%2019.433%203%2017.5V15C3%2014.4477%203.44772%2014%204%2014C4.55229%2014%205%2014.4477%205%2015L5%2017.5C5%2018.3284%205.67157%2019%206.5%2019H9C9.55229%2019%2010%2019.4477%2010%2020C10%2020.5523%209.55228%2021%209%2021H6.5ZM12%2015C13.6569%2015%2015%2013.6569%2015%2012C15%2010.3431%2013.6569%209%2012%209C10.3431%209%209%2010.3431%209%2012C9%2013.6569%2010.3431%2015%2012%2015ZM7.5%208.75C8.19036%208.75%208.75%208.19036%208.75%207.5C8.75%206.80964%208.19036%206.25%207.5%206.25C6.80964%206.25%206.25%206.80964%206.25%207.5C6.25%208.19036%206.80964%208.75%207.5%208.75Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M3%206.5C3%204.567%204.567%203%206.5%203H9C9.55228%203%2010%203.44772%2010%204C10%204.55228%209.55228%205%209%205H6.5C5.67157%205%205%205.67157%205%206.5V9C5%209.55229%204.55228%2010%204%2010C3.44772%2010%203%209.55229%203%209V6.5ZM21%2017.5C21%2019.433%2019.433%2021%2017.5%2021H15C14.4477%2021%2014%2020.5523%2014%2020C14%2019.4477%2014.4477%2019%2015%2019L17.5%2019C18.3284%2019%2019%2018.3284%2019%2017.5V15C19%2014.4477%2019.4477%2014%2020%2014C20.5523%2014%2021%2014.4477%2021%2015V17.5ZM21%206.5C21%204.567%2019.433%203%2017.5%203H15C14.4477%203%2014%203.44772%2014%204C14%204.55228%2014.4477%205%2015%205H17.5C18.3284%205%2019%205.67157%2019%206.5V9C19%209.55228%2019.4477%2010%2020%2010C20.5523%2010%2021%209.55229%2021%209V6.5ZM6.5%2021C4.567%2021%203%2019.433%203%2017.5V15C3%2014.4477%203.44772%2014%204%2014C4.55229%2014%205%2014.4477%205%2015L5%2017.5C5%2018.3284%205.67157%2019%206.5%2019H9C9.55229%2019%2010%2019.4477%2010%2020C10%2020.5523%209.55228%2021%209%2021H6.5ZM12%2015C13.6569%2015%2015%2013.6569%2015%2012C15%2010.3431%2013.6569%209%2012%209C10.3431%209%209%2010.3431%209%2012C9%2013.6569%2010.3431%2015%2012%2015ZM7.5%208.75C8.19036%208.75%208.75%208.19036%208.75%207.5C8.75%206.80964%208.19036%206.25%207.5%206.25C6.80964%206.25%206.25%206.80964%206.25%207.5C6.25%208.19036%206.80964%208.75%207.5%208.75Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1030
+ .completions-card-type-chip[data-type="ask"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.523%202%2022%206.478%2022%2012C22%2017.522%2017.523%2022%2012%2022C6.477%2022%202%2017.522%202%2012C2%206.478%206.477%202%2012%202ZM12%2015.5C11.4477%2015.5%2011%2015.9477%2011%2016.5C11%2017.0523%2011.4477%2017.5%2012%2017.5C12.5523%2017.5%2013%2017.0523%2013%2016.5C13%2015.9477%2012.5523%2015.5%2012%2015.5ZM12%206.75C10.4812%206.75%209.25%207.98122%209.25%209.5C9.25%209.91421%209.58579%2010.25%2010%2010.25C10.3797%2010.25%2010.6935%209.96785%2010.7432%209.60177L10.75%209.5C10.75%208.80964%2011.3096%208.25%2012%208.25C12.6904%208.25%2013.25%208.80964%2013.25%209.5C13.25%2010.0388%2013.115%2010.3053%2012.6051%2010.8322L12.4697%2010.9697C11.5916%2011.8478%2011.25%2012.4171%2011.25%2013.5C11.25%2013.9142%2011.5858%2014.25%2012%2014.25C12.4142%2014.25%2012.75%2013.9142%2012.75%2013.5C12.75%2012.9612%2012.885%2012.6947%2013.3949%2012.1678L13.5303%2012.0303C14.4084%2011.1522%2014.75%2010.5829%2014.75%209.5C14.75%207.98122%2013.5188%206.75%2012%206.75Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%202C17.523%202%2022%206.478%2022%2012C22%2017.522%2017.523%2022%2012%2022C6.477%2022%202%2017.522%202%2012C2%206.478%206.477%202%2012%202ZM12%2015.5C11.4477%2015.5%2011%2015.9477%2011%2016.5C11%2017.0523%2011.4477%2017.5%2012%2017.5C12.5523%2017.5%2013%2017.0523%2013%2016.5C13%2015.9477%2012.5523%2015.5%2012%2015.5ZM12%206.75C10.4812%206.75%209.25%207.98122%209.25%209.5C9.25%209.91421%209.58579%2010.25%2010%2010.25C10.3797%2010.25%2010.6935%209.96785%2010.7432%209.60177L10.75%209.5C10.75%208.80964%2011.3096%208.25%2012%208.25C12.6904%208.25%2013.25%208.80964%2013.25%209.5C13.25%2010.0388%2013.115%2010.3053%2012.6051%2010.8322L12.4697%2010.9697C11.5916%2011.8478%2011.25%2012.4171%2011.25%2013.5C11.25%2013.9142%2011.5858%2014.25%2012%2014.25C12.4142%2014.25%2012.75%2013.9142%2012.75%2013.5C12.75%2012.9612%2012.885%2012.6947%2013.3949%2012.1678L13.5303%2012.0303C14.4084%2011.1522%2014.75%2010.5829%2014.75%209.5C14.75%207.98122%2013.5188%206.75%2012%206.75Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1031
+ .completions-card-type-chip[data-type="docs"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M6.25%202C5.00736%202%204%203.00736%204%204.25V19.75C4%2020.9926%205.00736%2022%206.25%2022H17.75C18.9926%2022%2020%2020.9926%2020%2019.75V4.25C20%203.00736%2018.9926%202%2017.75%202H6.25ZM7.75%206H16.25C16.6642%206%2017%206.33579%2017%206.75C17%207.16421%2016.6642%207.5%2016.25%207.5H7.75C7.33579%207.5%207%207.16421%207%206.75C7%206.33579%207.33579%206%207.75%206ZM7%2016.75C7%2016.3358%207.33579%2016%207.75%2016H16.25C16.6642%2016%2017%2016.3358%2017%2016.75C17%2017.1642%2016.6642%2017.5%2016.25%2017.5H7.75C7.33579%2017.5%207%2017.1642%207%2016.75ZM7.75%2011H16.25C16.6642%2011%2017%2011.3358%2017%2011.75C17%2012.1642%2016.6642%2012.5%2016.25%2012.5H7.75C7.33579%2012.5%207%2012.1642%207%2011.75C7%2011.3358%207.33579%2011%207.75%2011Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M6.25%202C5.00736%202%204%203.00736%204%204.25V19.75C4%2020.9926%205.00736%2022%206.25%2022H17.75C18.9926%2022%2020%2020.9926%2020%2019.75V4.25C20%203.00736%2018.9926%202%2017.75%202H6.25ZM7.75%206H16.25C16.6642%206%2017%206.33579%2017%206.75C17%207.16421%2016.6642%207.5%2016.25%207.5H7.75C7.33579%207.5%207%207.16421%207%206.75C7%206.33579%207.33579%206%207.75%206ZM7%2016.75C7%2016.3358%207.33579%2016%207.75%2016H16.25C16.6642%2016%2017%2016.3358%2017%2016.75C17%2017.1642%2016.6642%2017.5%2016.25%2017.5H7.75C7.33579%2017.5%207%2017.1642%207%2016.75ZM7.75%2011H16.25C16.6642%2011%2017%2011.3358%2017%2011.75C17%2012.1642%2016.6642%2012.5%2016.25%2012.5H7.75C7.33579%2012.5%207%2012.1642%207%2011.75C7%2011.3358%207.33579%2011%207.75%2011Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1032
+ .completions-card-type-chip[data-type="setup"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12.0122%202.25C12.7462%202.25846%2013.4773%202.34326%2014.1937%202.50304C14.5064%202.57279%2014.7403%202.83351%2014.7758%203.15196L14.946%204.67881C15.0231%205.37986%2015.615%205.91084%2016.3206%205.91158C16.5103%205.91188%2016.6979%205.87238%2016.8732%205.79483L18.2738%205.17956C18.5651%205.05159%2018.9055%205.12136%2019.1229%205.35362C20.1351%206.43464%2020.8889%207.73115%2021.3277%209.14558C21.4223%209.45058%2021.3134%209.78203%2021.0564%209.9715L19.8149%2010.8866C19.4607%2011.1468%2019.2516%2011.56%2019.2516%2011.9995C19.2516%2012.4389%2019.4607%2012.8521%2019.8157%2013.1129L21.0582%2014.0283C21.3153%2014.2177%2021.4243%2014.5492%2021.3297%2014.8543C20.8911%2016.2685%2020.1377%2017.5649%2019.1261%2018.6461C18.9089%2018.8783%2018.5688%2018.9483%2018.2775%2018.8206L16.8712%2018.2045C16.4688%2018.0284%2016.0068%2018.0542%2015.6265%2018.274C15.2463%2018.4937%2014.9933%2018.8812%2014.945%2019.3177L14.7759%2020.8444C14.741%2021.1592%2014.5122%2021.4182%2014.204%2021.4915C12.7556%2021.8361%2011.2465%2021.8361%209.79803%2021.4915C9.48991%2021.4182%209.26105%2021.1592%209.22618%2020.8444L9.05736%2019.32C9.00777%2018.8843%208.75434%2018.498%208.37442%2018.279C7.99451%2018.06%207.5332%2018.0343%207.1322%2018.2094L5.72557%2018.8256C5.43422%2018.9533%205.09403%2018.8833%204.87678%2018.6509C3.86462%2017.5685%203.11119%2016.2705%202.6732%2014.8548C2.57886%2014.5499%202.68786%2014.2186%202.94485%2014.0293L4.18818%2013.1133C4.54232%2012.8531%204.75147%2012.4399%204.75147%2012.0005C4.75147%2011.561%204.54232%2011.1478%204.18771%2010.8873L2.94516%209.97285C2.6878%209.78345%202.5787%209.45178%202.67337%209.14658C3.11212%207.73215%203.86594%206.43564%204.87813%205.35462C5.09559%205.12236%205.43594%205.05259%205.72724%205.18056L7.12762%205.79572C7.53056%205.97256%207.9938%205.94585%208.37577%205.72269C8.75609%205.50209%209.00929%205.11422%209.05817%204.67764L9.22824%203.15196C9.26376%202.83335%209.49786%202.57254%209.8108%202.50294C10.5281%202.34342%2011.26%202.25865%2012.0122%202.25ZM11.9997%208.99995C10.3428%208.99995%208.9997%2010.3431%208.9997%2012C8.9997%2013.6568%2010.3428%2015%2011.9997%2015C13.6565%2015%2014.9997%2013.6568%2014.9997%2012C14.9997%2010.3431%2013.6565%208.99995%2011.9997%208.99995Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12.0122%202.25C12.7462%202.25846%2013.4773%202.34326%2014.1937%202.50304C14.5064%202.57279%2014.7403%202.83351%2014.7758%203.15196L14.946%204.67881C15.0231%205.37986%2015.615%205.91084%2016.3206%205.91158C16.5103%205.91188%2016.6979%205.87238%2016.8732%205.79483L18.2738%205.17956C18.5651%205.05159%2018.9055%205.12136%2019.1229%205.35362C20.1351%206.43464%2020.8889%207.73115%2021.3277%209.14558C21.4223%209.45058%2021.3134%209.78203%2021.0564%209.9715L19.8149%2010.8866C19.4607%2011.1468%2019.2516%2011.56%2019.2516%2011.9995C19.2516%2012.4389%2019.4607%2012.8521%2019.8157%2013.1129L21.0582%2014.0283C21.3153%2014.2177%2021.4243%2014.5492%2021.3297%2014.8543C20.8911%2016.2685%2020.1377%2017.5649%2019.1261%2018.6461C18.9089%2018.8783%2018.5688%2018.9483%2018.2775%2018.8206L16.8712%2018.2045C16.4688%2018.0284%2016.0068%2018.0542%2015.6265%2018.274C15.2463%2018.4937%2014.9933%2018.8812%2014.945%2019.3177L14.7759%2020.8444C14.741%2021.1592%2014.5122%2021.4182%2014.204%2021.4915C12.7556%2021.8361%2011.2465%2021.8361%209.79803%2021.4915C9.48991%2021.4182%209.26105%2021.1592%209.22618%2020.8444L9.05736%2019.32C9.00777%2018.8843%208.75434%2018.498%208.37442%2018.279C7.99451%2018.06%207.5332%2018.0343%207.1322%2018.2094L5.72557%2018.8256C5.43422%2018.9533%205.09403%2018.8833%204.87678%2018.6509C3.86462%2017.5685%203.11119%2016.2705%202.6732%2014.8548C2.57886%2014.5499%202.68786%2014.2186%202.94485%2014.0293L4.18818%2013.1133C4.54232%2012.8531%204.75147%2012.4399%204.75147%2012.0005C4.75147%2011.561%204.54232%2011.1478%204.18771%2010.8873L2.94516%209.97285C2.6878%209.78345%202.5787%209.45178%202.67337%209.14658C3.11212%207.73215%203.86594%206.43564%204.87813%205.35462C5.09559%205.12236%205.43594%205.05259%205.72724%205.18056L7.12762%205.79572C7.53056%205.97256%207.9938%205.94585%208.37577%205.72269C8.75609%205.50209%209.00929%205.11422%209.05817%204.67764L9.22824%203.15196C9.26376%202.83335%209.49786%202.57254%209.8108%202.50294C10.5281%202.34342%2011.26%202.25865%2012.0122%202.25ZM11.9997%208.99995C10.3428%208.99995%208.9997%2010.3431%208.9997%2012C8.9997%2013.6568%2010.3428%2015%2011.9997%2015C13.6565%2015%2014.9997%2013.6568%2014.9997%2012C14.9997%2010.3431%2013.6565%208.99995%2011.9997%208.99995Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
1033
+ .completions-card-type-chip[data-type="qa-validate"] { -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%2014C13.1046%2014%2014%2013.1046%2014%2012C14%2010.8954%2013.1046%2010%2012%2010C10.8954%2010%2010%2010.8954%2010%2012C10%2013.1046%2010.8954%2014%2012%2014ZM6%2012C6%208.68629%208.68629%206%2012%206C15.3137%206%2018%208.68629%2018%2012C18%2015.3137%2015.3137%2018%2012%2018C8.68629%2018%206%2015.3137%206%2012ZM12%208C9.79086%208%208%209.79086%208%2012C8%2014.2091%209.79086%2016%2012%2016C14.2091%2016%2016%2014.2091%2016%2012C16%209.79086%2014.2091%208%2012%208ZM2%2012C2%206.47715%206.47715%202%2012%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C6.47715%2022%202%2017.5228%202%2012ZM12%204C7.58172%204%204%207.58172%204%2012C4%2016.4183%207.58172%2020%2012%2020C16.4183%2020%2020%2016.4183%2020%2012C20%207.58172%2016.4183%204%2012%204Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); mask-image: url("data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%3Cpath%20d%3D%22M12%2014C13.1046%2014%2014%2013.1046%2014%2012C14%2010.8954%2013.1046%2010%2012%2010C10.8954%2010%2010%2010.8954%2010%2012C10%2013.1046%2010.8954%2014%2012%2014ZM6%2012C6%208.68629%208.68629%206%2012%206C15.3137%206%2018%208.68629%2018%2012C18%2015.3137%2015.3137%2018%2012%2018C8.68629%2018%206%2015.3137%206%2012ZM12%208C9.79086%208%208%209.79086%208%2012C8%2014.2091%209.79086%2016%2012%2016C14.2091%2016%2016%2014.2091%2016%2012C16%209.79086%2014.2091%208%2012%208ZM2%2012C2%206.47715%206.47715%202%2012%202C17.5228%202%2022%206.47715%2022%2012C22%2017.5228%2017.5228%2022%2012%2022C6.47715%2022%202%2017.5228%202%2012ZM12%204C7.58172%204%204%207.58172%204%2012C4%2016.4183%207.58172%2020%2012%2020C16.4183%2020%2020%2016.4183%2020%2012C20%207.58172%2016.4183%204%2012%204Z%22%20fill%3D%22%23212121%22%2F%3E%20%3C%2Fsvg%3E"); }
956
1034
  /* Review cards swap the emoji for a "REVIEW" word chip — same boxed
957
1035
  treatment as the lineage WI/Plan/PR chips (monospace, bordered, muted)
958
1036
  but a larger font so it reads as the rail's primary type marker. */
package/dashboard.js CHANGED
@@ -9361,6 +9361,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
9361
9361
  // 2min ceiling (covers even a GVFS-backed sparse hydration without
9362
9362
  // letting a config typo wedge dispatch for an hour).
9363
9363
  assertCleanStatusTimeoutMs: [1000, 120000],
9364
+ // W-mq6f2fe0000557fa — cap on the cross-platform holder scan for the
9365
+ // orphan-worktree GC. 1s floor (PowerShell startup alone is 0.5–1s);
9366
+ // 30s ceiling (the scan runs once per orphan-sweep tick and a slow
9367
+ // scan must not block the rest of the sweep for minutes).
9368
+ orphanHolderScanTimeoutMs: [1000, 30000],
9364
9369
  idleAlertMinutes: [1], shutdownTimeout: [30000], restartGracePeriod: [60000],
9365
9370
  meetingRoundTimeout: [60000],
9366
9371
  // W-mq066js7000fff1f-c (Gap B/C): steering safety-net knobs.
package/docs/README.md CHANGED
@@ -17,6 +17,7 @@ Architecture, design proposals, and lifecycle references for people working on t
17
17
  - [completion-reports.md](completion-reports.md) — Canonical schema for the per-spawn completion JSON: trust nonce, `failure_class` enum, `noop` semantics, `retryable` / `needs_rerun` shape, and the artifacts array.
18
18
  - [constants.md](constants.md) — Cross-cutting status / type / condition constants (`WI_STATUS`, `WORK_TYPE`, `PR_STATUS`, `WATCH_CONDITION`, …) and the no-magic-strings invariant.
19
19
  - [constellation-bridge.md](constellation-bridge.md) — Read-only cross-repo bridge: `engine.constellationBridge.enabled` flag, marker-file contract, and the `minions bridge` subcommand for local debugging.
20
+ - [constellation-style-telemetry.md](constellation-style-telemetry.md) — Feasibility study for a local-first usage/analytics layer modeled on Constellation's telemetry (typed event log + daily rollup + dashboard view), and why a 1:1 PostgreSQL/multi-tenant port is the wrong goal for Minions.
20
21
  - [cooldown-merge-semantics.md](cooldown-merge-semantics.md) — Scoping deliverable defining merge semantics for `saveCooldowns` (longer-of TTL merge, key-level upserts, gitignored on-disk format).
21
22
  - [copilot-cli-schema.md](copilot-cli-schema.md) — Behavior and schema reference for the GitHub Copilot CLI adapter (capability flags, stdin vs `-p`, model discovery, effort levels).
22
23
  - [dead-code-audit-retractions.md](dead-code-audit-retractions.md) — Retracted dead-code-audit findings (false positives) that future audits MUST read before re-citing.
@@ -84,27 +84,59 @@ Do **not** invent, regenerate, or share the nonce across dispatches — each spa
84
84
  | `tests` | string | `pass`, `fail`, `skipped`, `N/A`, or a free-form note like `skipped — relying on PR pipeline`. |
85
85
  | `pending` | string | Any remaining work, or `none`. |
86
86
  | `followups` | array | Optional. PR-comment follow-up work items the agent dispatched via `POST /api/work-items` with `meta.pr_followup` set. Each entry: `{wi_id, title, reason, parent_comment_id}`. See [PR-comment follow-ups](#pr-comment-follow-ups). |
87
- | `meta.review` | object | Optional, review tasks only. Records project-local review-skill outcome — see [Review skill outcomes](#review-skill-outcomes). |
87
+ | `meta.review` | object | Optional, review tasks only. Records project-local review-skill outcome — see [Review skill outcomes](#review-skill-outcomes). Aliased by the generalized `meta.skill` (W-mq1cczi90006b21f). |
88
+ | `meta.skill` | object | Optional. Records project-local skill outcome for ANY playbook type that surfaces a `## Project skills` block (implement / fix / plan / review / etc.). See [Project skill outcomes](#project-skill-outcomes). |
89
+
90
+ ## Project skill outcomes
91
+
92
+ W-mq1cczi90006b21f. Generalizes the PR-82 review-only `meta.review.skill*` fields to the full Minions lifecycle. When the playbook renders a `## Project skills` block (via `engine/playbook-intents.js` → `engine/discover-project-skills.js`) and the agent acts on a discovered skill, record the outcome under `meta.skill` so later evaluation can compare skill-driven vs. first-principles work across implement / fix / plan / review dispatches uniformly.
93
+
94
+ All `meta.skill` fields are optional and backward-compatible — older agents that never set them stay valid.
95
+
96
+ ```json
97
+ {
98
+ "status": "success",
99
+ "meta": {
100
+ "skill": {
101
+ "invoked": {
102
+ "name": "bump-fmf-android",
103
+ "path": ".claude/skills/bump-fmf-android/SKILL.md",
104
+ "kind": "skill",
105
+ "intent": "build"
106
+ },
107
+ "findings": 3
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ | Field | Type | Notes |
114
+ |---|---|---|
115
+ | `meta.skill.invoked` | object | The project skill the agent actually ran. Shape: `{name, path, kind, intent}` where `kind` is one of `skill`, `command`, `slash-command` (mirrors the discovery layer in `engine/discover-project-skills.js`) and `intent` is the bucket it served (`build`, `review`, `fix`, `test`, `plan`, `research`, `deploy`, `observability`, `meta`). Omit when no skill was invoked. |
116
+ | `meta.skill.findings` | number | Count of findings/artifacts the invoked skill returned. Semantics is per-skill; treat as opaque integer. Omit when no skill was invoked. |
117
+ | `meta.skill.skipped` | object | Set when a project skill was available but the agent intentionally chose not to run it (trivial diff, out-of-scope, meta-work on the skill itself, etc.). Shape: `{name, reason}`. Mirror the skip rationale into the PR comment / completion summary so a human sees the reasoning. |
118
+
119
+ Dispatchers can suppress the block entirely by setting `meta.skipProjectSkills: true` on the work item — the playbook then renders without the skills block. Use this for meta-work that targets the skill itself; the engine still accepts `meta.skill.skipped` in the report regardless. The PR-82 `meta.skipProjectReviewSkills` flag is preserved as an alias (suppresses the block on every dispatch type, not just review).
88
120
 
89
121
  ## Review skill outcomes
90
122
 
91
- W-mq16xtdx001a347e. Review playbook renders a `## Project review skills` block at dispatch time when the target project ships `.claude/skills/*` or `.claude/commands/*` with `review` / `swarm` in the name or description (or when `.github/copilot-instructions.md` / `CLAUDE.md` mention a canonical `/…review…` slash-command). When the agent acts on that block, it records the outcome under `meta.review` so later evaluation can compare skill-driven reviews vs. first-principles reviews.
123
+ W-mq16xtdx001a347e. **Original PR-82 fields, preserved as aliases.** New code should prefer the generalized `meta.skill.*` fields above (W-mq1cczi90006b21f) those work for every playbook type, not just review.
124
+
125
+ Review playbook renders a `## Project review skills` block at dispatch time when the target project ships `.claude/skills/*` or `.claude/commands/*` with `review` / `swarm` in the name or description (or when `.github/copilot-instructions.md` / `CLAUDE.md` mention a canonical `/…review…` slash-command). When the agent acts on that block, it records the outcome under `meta.review` so later evaluation can compare skill-driven reviews vs. first-principles reviews.
92
126
 
93
127
  All `meta.review` fields are optional and backward-compatible — older agents that never set them stay valid.
94
128
 
95
129
  ```json
96
130
  {
97
131
  "status": "success",
98
- "verdict": "approved",
99
- "pr": "https://github.com/owner/repo/pull/123",
100
132
  "meta": {
101
133
  "review": {
102
134
  "skillInvoked": {
103
- "name": "/review-swarm",
104
- "path": ".claude/commands/review-swarm.md",
105
- "kind": "command"
135
+ "name": "code-reviewer",
136
+ "path": ".claude/skills/code-reviewer/SKILL.md",
137
+ "kind": "skill"
106
138
  },
107
- "skillFindings": 4
139
+ "skillFindings": 3
108
140
  }
109
141
  }
110
142
  }
@@ -112,11 +144,11 @@ All `meta.review` fields are optional and backward-compatible — older agents t
112
144
 
113
145
  | Field | Type | Notes |
114
146
  |---|---|---|
115
- | `meta.review.skillInvoked` | object | The project review skill the agent actually ran. Shape: `{name, path, kind}` where `kind` is one of `skill`, `command`, `slash-command` (mirrors the discovery layer in `engine/discover-review-skills.js`). Omit when no skill was invoked. |
116
- | `meta.review.skillFindings` | number | Count of findings the invoked skill returned. Used later to measure skill quality and the value-add of first-principles review on top. Omit when no skill was invoked. |
117
- | `meta.review.skillSkipped` | object | Set when a project review skill was available but the agent intentionally chose not to run it (trivial diff, out-of-scope diff, meta-review of the skill itself, etc.). Shape: `{name, reason}`. Mirror the skip rationale into the `Automated checks` section of the PR comment so a human reviewer sees the reasoning. |
147
+ | `meta.review.skillInvoked` | object | The project review skill the agent actually ran. Shape: `{name, path, kind}` where `kind` is one of `skill`, `command`, `slash-command` (mirrors the discovery layer in `engine/discover-project-skills.js`). Omit when no skill was invoked. Aliased by `meta.skill.invoked`. |
148
+ | `meta.review.skillFindings` | number | Count of findings the invoked skill returned. Used later to measure skill quality and the value-add of first-principles review on top. Omit when no skill was invoked. Aliased by `meta.skill.findings`. |
149
+ | `meta.review.skillSkipped` | object | Set when a project review skill was available but the agent intentionally chose not to run it (trivial diff, out-of-scope diff, meta-review of the skill itself, etc.). Shape: `{name, reason}`. Aliased by `meta.skill.skipped`. |
118
150
 
119
- Dispatchers can suppress the block entirely by setting `meta.skipProjectReviewSkills: true` on the review work item — the playbook then renders identically to the pre-W-mq16xtdx 8-step contract. Use this for meta-reviews of the review skill itself; the engine still accepts `meta.review.skillSkipped` in the report regardless.
151
+ Dispatchers can suppress the block entirely by setting `meta.skipProjectReviewSkills: true` on the review work item — the playbook then renders identically to the pre-W-mq16xtdx 8-step contract. Use this for meta-reviews of the review skill itself; the engine still accepts `meta.review.skillSkipped` in the report regardless. (W-mq1cczi90006b21f generalized this to `meta.skipProjectSkills`, which suppresses the block on every dispatch type — both flags are honored.)
120
152
 
121
153
  ## `failure_class` enum
122
154
 
@@ -0,0 +1,133 @@
1
+ # Project skill discovery & intent vocabulary
2
+
3
+ W-mq1cczi90006b21f (follow-on to PR #82, W-mq16xtdx001a347e).
4
+
5
+ Minions' project-local **skill discovery layer** surfaces purpose-built tooling that a project ships (`.claude/skills/`, `.claude/commands/`, slash-command mentions in `CLAUDE.md` / `.github/copilot-instructions.md`) so dispatched agents steer toward the right skill instead of reinventing the flow from first principles.
6
+
7
+ This document is the contract every playbook author and project teammate needs to know.
8
+
9
+ ## Where the code lives
10
+
11
+ | File | Role |
12
+ |---|---|
13
+ | `engine/discover-project-skills.js` | Bounded filesystem walk + classification heuristic. The crash-safe primitive. |
14
+ | `engine/playbook-intents.js` | Single source of truth for the playbook → intent set mapping. |
15
+ | `engine/playbook.js` | Calls discovery + filter at render time, injects `{{project_skills_block}}` into the rendered prompt. |
16
+ | `engine/discover-review-skills.js` | Thin re-export shim. Backward-compat only — new code uses `discover-project-skills.js`. |
17
+
18
+ ## What gets discovered
19
+
20
+ Per project worktree, the discovery walk visits:
21
+
22
+ - `<projectRoot>/.claude/skills/*/SKILL.md` — top-level skill packs.
23
+ - `<projectRoot>/.claude/commands/*.md` — top-level slash-commands.
24
+ - `<projectRoot>/<area>/.claude/skills/*/SKILL.md` — **nested per-area skills** (one level deep). This is how OCM / loop / officemobile organize their skills in a monorepo.
25
+ - `<projectRoot>/<area>/.claude/commands/*.md` — same, for nested commands.
26
+ - `<projectRoot>/.github/copilot-instructions.md` — slash-command mentions (top 32 KB).
27
+ - `<projectRoot>/CLAUDE.md` — slash-command mentions (top 32 KB).
28
+
29
+ Each discovery entry has shape:
30
+
31
+ ```js
32
+ {
33
+ kind: 'skill' | 'command' | 'slash-command',
34
+ name: string, // e.g. "code-reviewer" or "/review-swarm"
35
+ path: string, // relative to projectRoot
36
+ oneLineDescription: string, // ≤200 chars
37
+ intents: string[] // closed enum, see below
38
+ }
39
+ ```
40
+
41
+ The walk is **cheap and bounded** — preserve every guardrail in
42
+ `engine/discover-project-skills.js`:
43
+
44
+ - ≤ 50 files per surface
45
+ - 8 KB per skill / 32 KB per docs file
46
+ - 250 ms walltime budget — bails rather than blocks dispatch
47
+ - ≤ 50 nested areas probed
48
+ - Missing worktree / unreadable → `[]` (never throws)
49
+
50
+ ## The intent vocabulary (CLOSED)
51
+
52
+ | Intent | What belongs here |
53
+ |---|---|
54
+ | `review` | code review, PR review, swarm review (`code-reviewer`, `/review-swarm`, `/code-review`, etc.) |
55
+ | `build` | scaffold, generate, bump, migrate, codemod, refactor (`bump-fmf-android`, `workspace`, `vhd`, etc.) |
56
+ | `fix` | debug, triage, repro, regression, flake-killing (`triage-flake`, `cover-pr` for missing tests on PR…) |
57
+ | `test` | author tests, increase coverage, validate (`integration-tests`, `run-tests`, `qa-validate`) |
58
+ | `plan` | PRD authoring, ADR, design-doc, decompose (`substitute-scheduler-template-vars`, `decompose`) |
59
+ | `research` | investigate, gather-impact, telemetry-query, audit (`gather-impact`, `audit-deprecated`) |
60
+ | `deploy` | release, publish, buddy-build, rollout, ship (`buddy-build`, `track-pr`) |
61
+ | `observability` | telemetry, logs, kusto, monitoring, metrics dashboards (`kusto-telemetry-lmf-quality-report`, `weekly-repo-summary`) |
62
+ | `meta` | meta-tooling about the skill system itself. **Do NOT use as a catch-all** — empty `intents: []` is the honest signal when the heuristic doesn't fire. |
63
+
64
+ ### How intents are assigned
65
+
66
+ For each discovered entry, `classifyIntents(...)` does:
67
+
68
+ 1. **Honor explicit author intent first.** A skill's `SKILL.md` frontmatter may declare `intents:` (or `tags:` / `intent:`) — only values that match the closed vocabulary above are accepted. Example:
69
+ ```yaml
70
+ ---
71
+ name: bump-fmf-android
72
+ description: Bump the FMF SDK version pin in OCM Android
73
+ intents: [build, deploy]
74
+ ---
75
+ ```
76
+ 2. **Fall back to keyword heuristics.** The skill's `name`, frontmatter `description`, first heading, and filename are matched against the per-intent keyword regexes in `INTENT_KEYWORDS` (engine/discover-project-skills.js). A skill matching multiple regexes carries multiple intents.
77
+ 3. **Empty intents are honest.** Zero matches → `intents: []`. The entry is still discovered and returned, but no intent-filtered playbook will surface it. NEVER default to `meta` just to satisfy the field.
78
+
79
+ ### Slash-commands scraped from docs
80
+
81
+ For `/foo` mentions in `CLAUDE.md` / `.github/copilot-instructions.md`, the discovery layer is more conservative: it only surfaces slash-commands whose **name itself** matches at least one intent keyword. This keeps doc-scrape noise out of every prompt (a doc may name 50 `/foo` commands; we don't want to dump them all into an `implement` prompt).
82
+
83
+ ## The playbook → intent map
84
+
85
+ Defined in `engine/playbook-intents.js`. The default mapping at time of writing:
86
+
87
+ | Playbook | Intents surfaced |
88
+ |---|---|
89
+ | `review` | `['review']` |
90
+ | `fix` | `['fix', 'test', 'review']` |
91
+ | `implement` / `implement-shared` | `['build', 'test', 'research']` |
92
+ | `plan` / `plan-to-prd` / `decompose` | `['plan', 'research']` |
93
+ | `docs` | `['research']` |
94
+ | `verify` | `['test', 'review']` |
95
+ | `build-and-test` | `['build', 'test']` |
96
+ | `test` / `qa-validate` | `['test']` |
97
+ | `explore` | `['research']` |
98
+ | (all others) | `[]` — no block rendered |
99
+
100
+ When a playbook's intent set is empty (or maps to none), the `{{project_skills_block}}` template variable resolves to the empty string and the splice fence collapses cleanly (no stray header, no padding).
101
+
102
+ The `followup-dispatch` template **inherits** its parent dispatch's intent set via `vars.parent_dispatch_type` — there's no row in the map for it.
103
+
104
+ ## Adding a new playbook
105
+
106
+ 1. Add a row to `PLAYBOOK_INTENTS` in `engine/playbook-intents.js` mapping your playbook name to the intent set it should surface.
107
+ 2. Splice the conditional template fence into your playbook markdown at the position where the agent should see purpose-built tooling — typically between the task-intake step and the first "actually do the work" step:
108
+ ```md
109
+ {{#project_skills_block}}
110
+ {{project_skills_block}}
111
+
112
+ {{/project_skills_block}}
113
+ ```
114
+ 3. If the playbook should opt out for some dispatches, the dispatcher can set `meta.skipProjectSkills: true` (or the PR-82 alias `meta.skipProjectReviewSkills: true`) on the work item.
115
+
116
+ ## Adding a new intent
117
+
118
+ 1. Add a regex to `INTENT_KEYWORDS` in `engine/discover-project-skills.js`. Use `\b` word boundaries.
119
+ 2. Add the value to `INTENT_VOCABULARY` so explicit frontmatter `intents:` entries with the new name are accepted.
120
+ 3. Add a row to the table above, with a one-line description of what belongs.
121
+ 4. Update one or more playbook entries in `engine/playbook-intents.js` to include the new intent.
122
+
123
+ Keep the vocabulary tight — every additional intent is noise risk in every prompt that surfaces it.
124
+
125
+ ## Completion-report contract
126
+
127
+ When an agent acts on a discovered skill, record the outcome in the completion report's `meta.skill` block. See [docs/completion-reports.md](completion-reports.md#project-skill-outcomes) for the full schema. The legacy `meta.review.skill*` fields (PR #82) remain accepted as aliases — new code should prefer `meta.skill.*`.
128
+
129
+ ## Tests
130
+
131
+ - `test/unit/discover-project-skills.test.js` — discovery + classification + intent filtering + render + per-playbook splice coverage.
132
+
133
+ When you change discovery, classification, or the playbook→intent map, extend or update this test file.
package/engine/ado.js CHANGED
@@ -395,6 +395,24 @@ function applyAdoPrMetadata(pr, prData) {
395
395
  updated = true;
396
396
  }
397
397
 
398
+ // #3079 — Track target ref + clear stale merge-conflict dispatch state
399
+ // when the PR is retargeted. The same-head guard at engine.js:5676 and
400
+ // the MERGE_CONFLICT fingerprint at shared.js:6595 are now target-aware
401
+ // (via shared.prMergeConflictGuardKey), but pre-existing
402
+ // _lastDispatchByCause[MERGE_CONFLICT] / _noOpFixes[MERGE_CONFLICT]
403
+ // records would still block re-dispatch until something else cleared
404
+ // them. Reset them explicitly on retarget. First-poll seeding
405
+ // (no prior targetRefName) is a no-op so we don't strip state immediately
406
+ // after upsert.
407
+ const nextTargetRef = String(prData.targetRefName || '').trim();
408
+ if (nextTargetRef && pr.targetRefName !== nextTargetRef) {
409
+ if (shared.resetMergeConflictStateOnRetarget(pr, nextTargetRef)) {
410
+ log('info', `ADO: PR ${pr.id || '?'} retargeted ${pr.targetRefName} → ${nextTargetRef}, clearing stale MERGE_CONFLICT dispatch records`);
411
+ }
412
+ pr.targetRefName = nextTargetRef;
413
+ updated = true;
414
+ }
415
+
398
416
  return updated;
399
417
  }
400
418
 
@@ -2600,6 +2618,7 @@ module.exports = {
2600
2618
  fetchAdoPrMetadata,
2601
2619
  fetchSinglePrBuildStatus,
2602
2620
  findOpenPrOnBranch,
2621
+ applyAdoPrMetadata, // #3079 — exported for unit tests of targetRefName + retarget reset
2603
2622
  _resetAdoThrottle, // exported for testing
2604
2623
  _setAdoThrottleForTest, // exported for testing
2605
2624
  _setAdoTokenForTest, // exported for testing