@yemi33/minions 0.1.2448 → 0.1.2449

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/bin/cli-api-client.js +1 -1
  2. package/bin/install-internal-minions.js +1382 -44
  3. package/bin/install-layout.js +150 -0
  4. package/bin/minions.js +460 -167
  5. package/dashboard/docs/typography.md +65 -12
  6. package/dashboard/js/command-center.js +58 -4
  7. package/dashboard/js/detail-panel.js +36 -0
  8. package/dashboard/js/memory-panel.js +59 -12
  9. package/dashboard/js/qa.js +179 -20
  10. package/dashboard/js/refresh.js +148 -12
  11. package/dashboard/js/render-dispatch.js +3 -4
  12. package/dashboard/js/render-inbox.js +2 -2
  13. package/dashboard/js/render-other.js +3 -3
  14. package/dashboard/js/render-pipelines.js +14 -0
  15. package/dashboard/js/render-plans.js +57 -9
  16. package/dashboard/js/render-prd.js +132 -23
  17. package/dashboard/js/render-prs.js +195 -166
  18. package/dashboard/js/render-schedules.js +63 -3
  19. package/dashboard/js/render-utils.js +3 -3
  20. package/dashboard/js/render-watches.js +19 -3
  21. package/dashboard/js/render-work-items.js +238 -30
  22. package/dashboard/js/settings.js +205 -54
  23. package/dashboard/js/utils.js +51 -1
  24. package/dashboard/pages/home.html +1 -1
  25. package/dashboard/pages/qa.html +1 -16
  26. package/dashboard/pages/work.html +40 -0
  27. package/dashboard/shared/cc-limits.js +79 -0
  28. package/dashboard/shared/pr-filters.js +21 -38
  29. package/dashboard/shared/project-git-summary.js +1 -1
  30. package/dashboard/shared/record-filters.js +169 -0
  31. package/dashboard/shared/watches-source.js +1 -1
  32. package/dashboard/shared/welcome-popup.js +1 -1
  33. package/dashboard/shared/wi-filters.js +302 -0
  34. package/dashboard/slim/body.html +1 -0
  35. package/dashboard/slim/js/command-send.js +26 -0
  36. package/dashboard/slim/js/modals-tiles.js +380 -39
  37. package/dashboard/slim/js/status.js +13 -21
  38. package/dashboard/slim/layout.html +1 -0
  39. package/dashboard/slim/panel-bootstrap.js +6 -2
  40. package/dashboard/slim/styles.css +38 -0
  41. package/dashboard/styles.css +159 -55
  42. package/dashboard-build.js +13 -2
  43. package/dashboard.js +956 -423
  44. package/docs/README.md +11 -6
  45. package/docs/api-errors.md +2 -2
  46. package/docs/architecture-review-2026-07-09.md +1 -1
  47. package/docs/architecture.excalidraw +2 -2
  48. package/docs/auto-discovery.md +18 -9
  49. package/docs/branch-derivation.md +4 -4
  50. package/docs/capture-demos.js +39 -2
  51. package/docs/ci-runner-canary.md +123 -0
  52. package/docs/claude-md-propagation.md +2 -2
  53. package/docs/cloud-agent-dispatch.md +204 -0
  54. package/docs/command-center.md +7 -7
  55. package/docs/completion-reports.md +43 -20
  56. package/docs/constants.md +10 -3
  57. package/docs/constellation-bridge.md +134 -6
  58. package/docs/constellation-style-telemetry.md +4 -4
  59. package/docs/contracts/capability-protocol.v1.json +165 -0
  60. package/docs/cooldown-merge-semantics.md +12 -12
  61. package/docs/copilot-cli-schema.md +7 -7
  62. package/docs/cross-repo-plans.md +10 -10
  63. package/docs/dead-code-audit-retractions.md +5 -5
  64. package/docs/default-branch-ci.md +173 -0
  65. package/docs/deprecated.json +31 -31
  66. package/docs/design-inbox-entries-schema.md +3 -3
  67. package/docs/design-language.md +1051 -0
  68. package/docs/design-state-storage.md +11 -11
  69. package/docs/diagnostics-crash-reports.md +9 -9
  70. package/docs/diagnostics-memory.md +5 -5
  71. package/docs/documentation-audit-2026-07-09.md +7 -7
  72. package/docs/engine-restart.md +90 -5
  73. package/docs/harness-mode.md +1 -1
  74. package/docs/internal-install.md +338 -39
  75. package/docs/kb-dedup-duplicate-pair-investigation.md +5 -5
  76. package/docs/kb-pr3223-cascade-archiving.md +1 -1
  77. package/docs/kb-pr696-merge-conflict-docs.md +6 -6
  78. package/docs/kb-sweep.md +35 -35
  79. package/docs/keep-processes.md +1 -1
  80. package/docs/live-checkout-mode.md +30 -30
  81. package/docs/managed-spawn.md +18 -14
  82. package/docs/named-agents.md +7 -7
  83. package/docs/plan-lifecycle.md +69 -2
  84. package/docs/pr-author-identity.md +114 -0
  85. package/docs/pr-auto-fix-dispatch.md +19 -4
  86. package/docs/pr-comment-followup.md +6 -6
  87. package/docs/pr-review-fix-loop.md +59 -10
  88. package/docs/process-termination.md +40 -0
  89. package/docs/proposals/repo-pool-for-live-checkout.md +13 -13
  90. package/docs/qa-runbook-lifecycle.md +367 -17
  91. package/docs/qa-runbooks.md +3 -3
  92. package/docs/rfc-completion-json.md +18 -18
  93. package/docs/runtime-adapters.md +26 -21
  94. package/docs/security.md +6 -6
  95. package/docs/self-improvement.md +4 -4
  96. package/docs/shared-lifecycle-module-map.md +473 -472
  97. package/docs/skills.md +52 -3
  98. package/docs/slim-ux/concepts.md +121 -116
  99. package/docs/specs/agent-configurability.md +18 -18
  100. package/docs/specs/agent-rename.md +18 -18
  101. package/docs/team-memory.md +38 -21
  102. package/docs/timeouts-and-liveness.md +118 -10
  103. package/docs/tutorials/01-install-and-connect.md +1 -1
  104. package/docs/watches.md +40 -39
  105. package/docs/workspace-manifests.md +4 -4
  106. package/docs/worktree-lifecycle.md +293 -14
  107. package/engine/README.md +46 -0
  108. package/engine/{ado-comment.js → ado/comment.js} +8 -8
  109. package/engine/{ado-git-auth.js → ado/git-auth.js} +4 -4
  110. package/engine/{ado.js → ado/index.js} +417 -63
  111. package/engine/{ado-status.js → ado/status.js} +6 -8
  112. package/engine/{ado-token.js → ado/token.js} +1 -1
  113. package/engine/{acp-transport.js → agents/acp-transport.js} +62 -22
  114. package/engine/{agent-worker-pool.js → agents/agent-worker-pool.js} +17 -8
  115. package/engine/{cc-worker-pool.js → agents/cc-worker-pool.js} +16 -6
  116. package/engine/{claude-md-context.js → agents/claude-md-context.js} +5 -5
  117. package/engine/{harness-context.js → agents/harness-context.js} +5 -5
  118. package/engine/{harness.js → agents/harness.js} +3 -3
  119. package/engine/{llm.js → agents/llm.js} +18 -14
  120. package/engine/{model-discovery.js → agents/model-discovery.js} +2 -2
  121. package/engine/{playbook.js → agents/playbook.js} +155 -22
  122. package/engine/{pooled-agent-process.js → agents/pooled-agent-process.js} +14 -12
  123. package/engine/{preflight.js → agents/preflight.js} +29 -10
  124. package/engine/{spawn-agent.js → agents/spawn-agent.js} +25 -14
  125. package/engine/{spawn-phase-watchdog.js → agents/spawn-phase-watchdog.js} +16 -7
  126. package/engine/{steering.js → agents/steering.js} +5 -5
  127. package/engine/{tools-inventory.js → agents/tools-inventory.js} +2 -2
  128. package/engine/{agent-api-validation.js → api/agent-api-validation.js} +2 -2
  129. package/engine/{api-validation.js → api/api-validation.js} +1 -1
  130. package/engine/api/bridge.js +787 -0
  131. package/engine/{cc-api-validation.js → api/cc-api-validation.js} +1 -1
  132. package/engine/api/companion.js +560 -0
  133. package/engine/{content-api-validation.js → api/content-api-validation.js} +2 -2
  134. package/engine/{pr-issue-validation.js → api/pr-issue-validation.js} +33 -6
  135. package/engine/{settings-validation.js → api/settings-validation.js} +32 -4
  136. package/engine/api-contracts/agent-content.js +4 -4
  137. package/engine/api-contracts/capability-manifest.js +236 -0
  138. package/engine/api-contracts/capability-protocol.js +333 -0
  139. package/engine/api-contracts/cc-ops.js +1 -1
  140. package/engine/api-contracts/config-runtime.js +5 -0
  141. package/engine/api-contracts/core.js +28 -1
  142. package/engine/api-contracts/index.js +100 -0
  143. package/engine/api-contracts/orchestration.js +18 -5
  144. package/engine/api-contracts/pull-requests.js +37 -6
  145. package/engine/api-contracts/qa-process.js +29 -6
  146. package/engine/api-contracts/work-plan-prd.js +21 -1
  147. package/engine/cloud/contract.js +212 -0
  148. package/engine/cloud/index.js +159 -0
  149. package/engine/{execution-model.js → core/execution-model.js} +1 -1
  150. package/engine/{features.js → core/features.js} +4 -4
  151. package/engine/{operator-identity.js → core/operator-identity.js} +1 -1
  152. package/engine/{queries.js → core/queries.js} +201 -36
  153. package/engine/{safe-expr.js → core/safe-expr.js} +1 -1
  154. package/engine/{shared.js → core/shared.js} +1637 -175
  155. package/engine/{stdio-timestamps.js → core/stdio-timestamps.js} +1 -1
  156. package/engine/{untrusted-fence.js → core/untrusted-fence.js} +3 -3
  157. package/engine/db/index.js +11 -2
  158. package/engine/db/migrations/002-dispatches.js +3 -3
  159. package/engine/db/migrations/003-work-items.js +1 -1
  160. package/engine/db/migrations/004-pull-requests.js +1 -1
  161. package/engine/db/migrations/006-metrics.js +1 -1
  162. package/engine/db/migrations/007-watches.js +2 -2
  163. package/engine/db/migrations/008-small-state.js +1 -1
  164. package/engine/db/migrations/009-qa.js +1 -1
  165. package/engine/db/migrations/010-pr-links.js +1 -1
  166. package/engine/db/migrations/011-remaining-state.js +1 -1
  167. package/engine/db/migrations/012-steering-deliveries.js +2 -2
  168. package/engine/db/migrations/013-backfill-broken-note-links.js +1 -1
  169. package/engine/db/migrations/014-pr-fix-target-prefs.js +2 -2
  170. package/engine/db/migrations/015-plans-prds.js +0 -0
  171. package/engine/db/migrations/018-sql-only-cutover.js +2 -2
  172. package/engine/db/migrations/021-archived-work-items.js +1 -1
  173. package/engine/db/migrations/022-global-cc-session.js +1 -1
  174. package/engine/db/migrations/023-engine-state.js +1 -1
  175. package/engine/db/migrations/025-malformed-work-item-phantoms.js +1 -1
  176. package/engine/db/migrations/027-review-learning-lifecycle.js +1 -1
  177. package/engine/db/migrations/029-repair-reused-versions.js +20 -0
  178. package/engine/db/migrations/031-pr-author-identity.js +137 -0
  179. package/engine/{consolidation.js → memory/consolidation.js} +6 -6
  180. package/engine/{kb-sweep-runner.js → memory/kb-sweep-runner.js} +2 -2
  181. package/engine/{kb-sweep.js → memory/kb-sweep.js} +9 -7
  182. package/engine/{memory-retrieval.js → memory/memory-retrieval.js} +46 -4
  183. package/engine/{memory-store.js → memory/memory-store.js} +3 -3
  184. package/engine/{promotion.js → memory/promotion.js} +3 -3
  185. package/engine/{review-learning-backfill.js → memory/review-learning-backfill.js} +6 -6
  186. package/engine/{review-learning.js → memory/review-learning.js} +10 -5
  187. package/engine/{diagnostics-memory.js → observability/diagnostics-memory.js} +1 -1
  188. package/engine/{logs-store.js → observability/logs-store.js} +5 -5
  189. package/engine/{metrics-store.js → observability/metrics-store.js} +4 -4
  190. package/engine/{check-status.js → operations/check-status.js} +3 -3
  191. package/engine/{cli.js → operations/cli.js} +271 -113
  192. package/engine/{distribution.js → operations/distribution.js} +5 -6
  193. package/engine/{cleanup.js → orchestration/cleanup.js} +72 -45
  194. package/engine/{cooldown.js → orchestration/cooldown.js} +5 -5
  195. package/engine/{dispatch-events.js → orchestration/dispatch-events.js} +2 -2
  196. package/engine/{dispatch.js → orchestration/dispatch.js} +129 -36
  197. package/engine/orchestration/failed-scheduled-cleanup.js +274 -0
  198. package/engine/{lifecycle.js → orchestration/lifecycle.js} +198 -90
  199. package/engine/{meeting.js → orchestration/meeting.js} +6 -16
  200. package/engine/{pipeline.js → orchestration/pipeline.js} +12 -12
  201. package/engine/{pre-dispatch-eval.js → orchestration/pre-dispatch-eval.js} +10 -9
  202. package/engine/{routing.js → orchestration/routing.js} +3 -3
  203. package/engine/{schedule-bootstrap.js → orchestration/schedule-bootstrap.js} +4 -4
  204. package/engine/{scheduler.js → orchestration/scheduler.js} +38 -8
  205. package/engine/{timeout.js → orchestration/timeout.js} +158 -109
  206. package/engine/{db-events.js → persistence/db-events.js} +2 -2
  207. package/engine/{dispatch-store.js → persistence/dispatch-store.js} +7 -7
  208. package/engine/{inbox-store.js → persistence/inbox-store.js} +2 -2
  209. package/engine/{note-link-backfill.js → persistence/note-link-backfill.js} +4 -4
  210. package/engine/{pr-fix-target-store.js → persistence/pr-fix-target-store.js} +8 -8
  211. package/engine/{pull-requests-store.js → persistence/pull-requests-store.js} +21 -7
  212. package/engine/{small-state-store.js → persistence/small-state-store.js} +31 -31
  213. package/engine/persistence/state-operations.js +350 -0
  214. package/engine/{steering-store.js → persistence/steering-store.js} +6 -6
  215. package/engine/{issues.js → planning/issues.js} +2 -2
  216. package/engine/{plan-prd-validation.js → planning/plan-prd-validation.js} +8 -2
  217. package/engine/planning/prd-result-sidecar.js +190 -0
  218. package/engine/{prd-store.js → planning/prd-store.js} +17 -17
  219. package/engine/{project-discovery.js → planning/project-discovery.js} +5 -5
  220. package/engine/{projects.js → planning/projects.js} +10 -10
  221. package/engine/{resolve-area.js → planning/resolve-area.js} +1 -1
  222. package/engine/{work-item-validation.js → planning/work-item-validation.js} +39 -3
  223. package/engine/{work-items-store.js → planning/work-items-store.js} +29 -21
  224. package/engine/{keep-process-sweep.js → processes/keep-process-sweep.js} +57 -17
  225. package/engine/{managed-spawn-launcher.js → processes/managed-spawn-launcher.js} +3 -3
  226. package/engine/{managed-spawn.js → processes/managed-spawn.js} +97 -46
  227. package/engine/{process-utils.js → processes/process-utils.js} +599 -55
  228. package/engine/{abandoned-pr-reconciliation.js → providers/abandoned-pr-reconciliation.js} +17 -7
  229. package/engine/{comment-classifier.js → providers/comment-classifier.js} +85 -17
  230. package/engine/{comment-format.js → providers/comment-format.js} +5 -5
  231. package/engine/{gh-comment.js → providers/gh-comment.js} +15 -15
  232. package/engine/{gh-token.js → providers/gh-token.js} +4 -4
  233. package/engine/{github.js → providers/github.js} +131 -54
  234. package/engine/{pr-action.js → providers/pr-action.js} +13 -12
  235. package/engine/{pr-clone-keep.js → providers/pr-clone-keep.js} +7 -7
  236. package/engine/{pr-devbox.js → providers/pr-devbox.js} +6 -6
  237. package/engine/{pr-fix-target.js → providers/pr-fix-target.js} +13 -13
  238. package/engine/{pr-remote-patch.js → providers/pr-remote-patch.js} +4 -4
  239. package/engine/{pr-resolve.js → providers/pr-resolve.js} +7 -7
  240. package/engine/{pr-temp-clone.js → providers/pr-temp-clone.js} +5 -5
  241. package/engine/{pr-track.js → providers/pr-track.js} +11 -13
  242. package/engine/{shared-branch-pr-reconcile.js → providers/shared-branch-pr-reconcile.js} +4 -4
  243. package/engine/qa/auto-prd-qa.js +313 -0
  244. package/engine/{qa-from-prd.js → qa/from-prd.js} +42 -12
  245. package/engine/qa/prd-session.js +240 -0
  246. package/engine/{qa-process-validation.js → qa/process-validation.js} +14 -9
  247. package/engine/{qa-runbooks.js → qa/runbooks.js} +1 -1
  248. package/engine/{qa-runs.js → qa/runs.js} +286 -15
  249. package/engine/{qa-sessions.js → qa/sessions.js} +595 -49
  250. package/engine/qa/visual-journey.js +654 -0
  251. package/engine/{qa-runners.js → qa-runners/index.js} +7 -7
  252. package/engine/qa-runners/maestro.js +3 -3
  253. package/engine/qa-runners/playwright.js +2 -2
  254. package/engine/{restart-health.js → recovery/restart-health.js} +48 -4
  255. package/engine/recovery/stop-stack.js +607 -0
  256. package/engine/{supervisor.js → recovery/supervisor.js} +105 -175
  257. package/engine/{watchdog.js → recovery/watchdog.js} +136 -13
  258. package/engine/runtimes/claude.js +14 -12
  259. package/engine/runtimes/codex.js +8 -6
  260. package/engine/runtimes/copilot.js +17 -16
  261. package/engine/{watch-actions.js → watches/actions.js} +13 -13
  262. package/engine/{watches.js → watches/index.js} +43 -32
  263. package/engine/{watches-store.js → watches/store.js} +4 -4
  264. package/engine/{create-pr-worktree.js → worktrees/create-pr.js} +1 -1
  265. package/engine/{worktree-gc.js → worktrees/gc.js} +70 -22
  266. package/engine/worktrees/inventory.js +671 -0
  267. package/engine/{live-checkout.js → worktrees/live-checkout.js} +4 -4
  268. package/engine/{worktree-pool.js → worktrees/pool.js} +2 -2
  269. package/engine/{worktree-preflight.js → worktrees/preflight.js} +1 -0
  270. package/engine/worktrees/quarantine-refs.js +173 -0
  271. package/engine.js +1137 -208
  272. package/minions.js +147 -77
  273. package/package.json +10 -6
  274. package/playbooks/_pr-description-audit.md +110 -78
  275. package/playbooks/build-fix-complex.md +2 -0
  276. package/playbooks/fix.md +16 -12
  277. package/playbooks/implement-shared.md +2 -0
  278. package/playbooks/implement.md +19 -20
  279. package/playbooks/plan-to-prd.md +18 -3
  280. package/playbooks/qa-session-draft.md +136 -1
  281. package/playbooks/qa-session-execute.md +80 -2
  282. package/playbooks/qa-session-setup.md +17 -1
  283. package/playbooks/qa-validate.md +1 -1
  284. package/playbooks/setup.md +2 -0
  285. package/playbooks/shared-rules.md +25 -32
  286. package/playbooks/templates/followup-dispatch.md +4 -3
  287. package/playbooks/verify.md +1 -1
  288. package/prompts/cc-system.md +19 -27
  289. package/watch-plugins/README.md +92 -0
  290. package/watch-plugins/ado-author-prs.js +336 -0
  291. package/watch-plugins/gh-author-prs.js +375 -0
  292. package/watch-plugins/http.js +474 -0
  293. package/watch-plugins/teams-channel.js +869 -0
  294. package/docs/dev-composite-workflow.md +0 -101
  295. package/docs/pr-screenshots/pr-886/after-single-header.png +0 -0
  296. package/docs/pr-screenshots/pr-886/before-duplicate-header.png +0 -0
  297. package/docs/pr-screenshots/pr-895/01-cancellation-reason-detail.png +0 -0
  298. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
  299. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
  300. package/docs/pr-screenshots/pr-901/projects-tab-default.png +0 -0
  301. package/docs/pr-screenshots/pr-901/projects-tab-fmf-selected.png +0 -0
  302. package/docs/pr-screenshots/pr-916/model-picker-AFTER-crop.png +0 -0
  303. package/docs/pr-screenshots/pr-916/model-picker-AFTER.png +0 -0
  304. package/docs/pr-screenshots/pr-916/model-picker-BEFORE-crop.png +0 -0
  305. package/docs/pr-screenshots/pr-916/model-picker-BEFORE.png +0 -0
  306. package/docs/pr-screenshots/pr-916/model-picker-dropdown-AFTER.png +0 -0
  307. package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
  308. package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
  309. package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
  310. package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
  311. package/docs/visual-evidence-ci.md +0 -103
  312. package/engine/bridge.js +0 -379
  313. package/engine/quarantine-refs.js +0 -103
  314. package/engine/state-operations.js +0 -178
  315. /package/engine/{steering-constraints.js → agents/steering-constraints.js} +0 -0
@@ -15,6 +15,7 @@
15
15
  (function() {
16
16
  'use strict';
17
17
  window.MINIONS_FEATURES = {{minions_features}};
18
+ window.MINIONS_CC_LIMITS = {{cc_api_limits}};
18
19
  /* __JS__ */
19
20
  })();
20
21
  </script>
@@ -72,10 +72,14 @@ function showToast(id, msg, ok, durationMs) {
72
72
  }
73
73
 
74
74
  // ESC closes the slide-in panel (parity with the classic "ESC / Close" button).
75
- // closeDetail() is defined later in this same global script by detail-panel.js;
76
- // it is only invoked on keydown (runtime), so load-order is fine.
75
+ // closeDetail() and isEditableEventTarget() are defined later in this same global
76
+ // script by detail-panel.js; both are only invoked on keydown (runtime), so
77
+ // load-order is fine. isEditableEventTarget() exempts editable targets so Escape
78
+ // while typing in the charter textarea / live-steer input doesn't discard an
79
+ // unsaved draft — shared with the classic handler (no forked copy of the guard).
77
80
  document.addEventListener('keydown', function(e) {
78
81
  if (e.key !== 'Escape') return;
82
+ if (typeof isEditableEventTarget === 'function' && isEditableEventTarget(e)) return;
79
83
  var panel = document.getElementById('detail-panel');
80
84
  if (panel && panel.classList.contains('open') && typeof closeDetail === 'function') {
81
85
  closeDetail();
@@ -796,7 +796,26 @@
796
796
  cached frames must be forced back to none. The id+type+attr selector
797
797
  outranks the class rules (no !important needed). */
798
798
  .slim-tile-embed-host, .slim-tile-transient { display: block; }
799
+ #slim-tile-embed-host { position: relative; }
799
800
  #slim-tile-embed-host iframe[hidden] { display: none; }
801
+ /* Immediate loading affordance (W-ms4odb8h009a5d16) shown while a not-yet-
802
+ booted embed iframe (esp. the heavier Engine screen) finishes its first
803
+ cold boot, so the tile modal never looks frozen on open. Hidden the moment
804
+ the iframe fires 'load'. Overlays the embed host, matching its full-bleed
805
+ treatment. */
806
+ #slim-tile-embed-loading {
807
+ position: absolute; inset: 0; z-index: 2;
808
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
809
+ gap: 12px; background: var(--bg); color: var(--muted, #8a94a6);
810
+ font-size: var(--text-meta);
811
+ }
812
+ #slim-tile-embed-loading[hidden] { display: none; }
813
+ .slim-tile-embed-spinner {
814
+ width: 26px; height: 26px; border-radius: 50%;
815
+ border: 3px solid var(--border, #2a3140); border-top-color: var(--accent, #4ea1ff);
816
+ animation: slim-tile-embed-spin 0.7s linear infinite;
817
+ }
818
+ @keyframes slim-tile-embed-spin { to { transform: rotate(360deg); } }
800
819
  /* Cached slim Settings frame (W-ms4ogdc800aa6931): like the tile embeds it is
801
820
  created once and shown/hidden rather than cold-booted per open. The
802
821
  .slim-settings-embed class rule above sets display:block, which outranks
@@ -819,6 +838,25 @@
819
838
  display: block; width: 100%; height: calc(100vh - 148px); min-height: 320px;
820
839
  border: 0; background: var(--bg);
821
840
  }
841
+ /* "+ Add" picker popover for the Automation cockpit tile. Fixed-positioned
842
+ (appended to <body>) so the tile's bounds can't clip it. */
843
+ .slim-add-menu {
844
+ position: fixed; z-index: 1000;
845
+ background: var(--surface); border: 1px solid var(--border);
846
+ border-radius: var(--radius); padding: 4px;
847
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
848
+ display: flex; flex-direction: column; min-width: 148px;
849
+ }
850
+ .slim-add-menu-item {
851
+ display: block; width: 100%; text-align: left;
852
+ padding: 7px 10px; border: 0; border-radius: 6px;
853
+ background: transparent; color: var(--text);
854
+ font-family: inherit; font-size: var(--text-md); cursor: pointer;
855
+ }
856
+ .slim-add-menu-item:hover,
857
+ .slim-add-menu-item:focus-visible {
858
+ background: var(--surface2); outline: none;
859
+ }
822
860
  .tile-item {
823
861
  display: block;
824
862
  text-decoration: none;
@@ -114,7 +114,7 @@
114
114
  section h2 { font-size: var(--text-base); font-weight: 600; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 14px; display: flex; align-items: center; gap: var(--space-4); }
115
115
  section h2 .count { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-xl); padding: var(--space-1) 7px; font-size: var(--text-base); color: var(--text); }
116
116
 
117
- .agents { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
117
+ .agents { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-5); }
118
118
  .agent-card {
119
119
  background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius-lg);
120
120
  padding: var(--space-6) var(--space-7); transition: all var(--transition-slow); cursor: pointer;
@@ -170,6 +170,9 @@
170
170
  .plan-card-title { font-size: var(--text-lg); font-weight: 600; color: var(--text); }
171
171
  .plan-card-meta { font-size: var(--text-sm); color: var(--muted); margin-top: var(--space-2); display: flex; gap: var(--space-4); flex-wrap: wrap; }
172
172
  .plan-card-actions { display: flex; gap: var(--space-2); margin-top: var(--space-4); flex-wrap: wrap; }
173
+ .plan-card-action-row { margin-top: var(--space-2); align-items: center; }
174
+ .plan-section-header { font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); padding: var(--space-3) 0; margin: var(--space-8) 0 var(--space-4); }
175
+ .plan-section-header:first-child { margin-top: 0; }
173
176
  .plan-btn { font-size: var(--text-base); padding: var(--space-2) var(--space-5); border-radius: var(--radius-sm); cursor: pointer; border: 1px solid var(--border); background: var(--surface); color: var(--text); transition: all var(--transition-fast); position: relative; z-index: 1; }
174
177
  .plan-btn:hover { border-color: var(--text); }
175
178
  .plan-btn.approve { color: var(--green); border-color: var(--green); }
@@ -361,12 +364,21 @@
361
364
  .pr-table--prs { table-layout: fixed; width: 100%; min-width: 1600px; }
362
365
  .pr-table--prs th, .pr-table--prs td { overflow: hidden; text-overflow: ellipsis; }
363
366
  /* W-mqv5ccn7 — the Signed Off By value must never ellipsis-truncate
364
- its own label; let the reviewer cell (9th column) render in full
365
- rather than inheriting the shared cell-level clip above. */
367
+ its own label; let the reviewer cell (9th column after adding the
368
+ dedicated Project column, W-ms90po5j) render in full rather than
369
+ inheriting the shared cell-level clip above. */
366
370
  .pr-table--prs td:nth-child(9) { overflow: visible; }
371
+ /* W-ms8z6l8z — the Status cell (4th column after the Project column was
372
+ added, W-ms90po5j) can hold the lifecycle badge plus a merge-conflict
373
+ badge; let it wrap onto a second line instead of clipping the conflict
374
+ badge when both are present. The wrapping itself is done by the inner
375
+ .pr-status-badges flex container (W-msakop2o), which supplies the
376
+ row gap that plain inline flow could not. */
377
+ .pr-table--prs td:nth-child(4) { white-space: normal; }
367
378
  .pr-table--prs th:last-child, .pr-table--prs td:last-child { width: auto; min-width: 0; }
368
379
  .pr-table--prs .pr-title { display: block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
369
380
  .pr-table--prs .pr-agent { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; white-space: nowrap; }
381
+ .pr-table--prs .pr-project { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; white-space: nowrap; }
370
382
  .pr-table--prs .pr-branch { max-width: 100%; }
371
383
  .pr-table--prs .pr-desc { max-width: 100%; }
372
384
  .pr-table--prs .pr-date { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
@@ -421,11 +433,26 @@
421
433
  .pr-title:hover { text-decoration: underline; }
422
434
  .pr-desc { color: var(--muted); font-size: var(--text-sm); font-weight: 400; margin-top: 2px; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 400px; }
423
435
  .pr-id { color: var(--muted); font-family: Consolas, monospace; font-size: var(--text-base); }
424
- .pr-id-project { max-width: 120px; font-size: var(--text-sm); }
436
+ .pr-project { font-size: var(--text-sm); color: var(--text); }
425
437
  .pr-agent { font-size: var(--text-base); color: var(--text); }
426
438
  .pr-branch { display: inline-block; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; font-family: Consolas, monospace; font-size: var(--text-sm); color: var(--muted); background: var(--bg); padding: var(--space-1) var(--space-3); border-radius: 3px; border: 1px solid var(--border); }
427
439
  .pr-branch.branch-missing { color: var(--red); border-color: var(--red); background: rgba(248,81,73,0.12); }
428
- .pr-badge { font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) var(--space-4); border-radius: var(--radius-xl); text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; }
440
+ /* W-msakop2o — the lifecycle and merge-conflict badges are laid out by a
441
+ flex container, not by inline flow. Inline flow separated them with a
442
+ whitespace text node, which gives a horizontal word-space but NO vertical
443
+ gap, so a wrapped conflict badge landed on a second line box and its
444
+ border box bled into the badge above it. `gap` is the fix for both axes.
445
+ The container is an inner element on purpose: .pr-table--prs is
446
+ `table-layout: fixed`, and making the <td> itself a flex container would
447
+ take the cell out of the fixed column model. */
448
+ .pr-status-badges { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; min-width: 0; }
449
+ /* `display: inline-block` is load-bearing, not cosmetic: a non-replaced
450
+ INLINE element contributes none of its vertical padding or border to the
451
+ line box, so any container that wraps two .pr-badge siblings renders them
452
+ overlapping. Making the pill an atomic inline-level box (with a pinned
453
+ line-height so the height is font-independent) removes that failure mode
454
+ everywhere .pr-badge is used, not just in the PR Status cell. */
455
+ .pr-badge { display: inline-block; line-height: 1.2; font-size: var(--text-sm); font-weight: 600; padding: var(--space-1) var(--space-4); border-radius: var(--radius-xl); text-transform: uppercase; letter-spacing: 0.5px; white-space: nowrap; }
429
456
  .pr-badge.draft { background: rgba(139,148,158,0.15); color: var(--muted); border: 1px solid var(--border); }
430
457
  .pr-badge.active { background: rgba(88,166,255,0.15); color: var(--blue); border: 1px solid var(--blue); }
431
458
  .pr-badge.approved { background: rgba(63,185,80,0.15); color: var(--green); border: 1px solid var(--green); }
@@ -457,40 +484,37 @@
457
484
  .pr-page-info { font-size: var(--text-base); color: var(--muted); }
458
485
  .pr-date { font-size: var(--text-base); color: var(--muted); }
459
486
 
460
- /* PR row auto-observe toggle switch (W-mpof8qam000h62fb).
461
- Semantic <input type=checkbox> hidden but focusable; the visible track
462
- is a sibling span styled via the .pr-observe-on/off class on the
463
- wrapping <label>. Knob slides via left position + transition. */
464
- .pr-observe-switch {
487
+ /* Per-PR automation toggle switches. */
488
+ .pr-automation-switch {
465
489
  display: inline-flex; align-items: center; cursor: pointer;
466
490
  position: relative; user-select: none; vertical-align: middle;
467
491
  }
468
- .pr-observe-switch:has(.pr-observe-switch__input:disabled) { cursor: wait; opacity: 0.6; }
469
- .pr-observe-switch__input {
492
+ .pr-automation-switch:has(.pr-automation-switch__input:disabled) { cursor: wait; opacity: 0.6; }
493
+ .pr-automation-switch__input {
470
494
  position: absolute; opacity: 0; pointer-events: none;
471
495
  width: 1px; height: 1px; margin: 0; padding: 0;
472
496
  }
473
- .pr-observe-switch__track {
497
+ .pr-automation-switch__track {
474
498
  display: inline-block; position: relative;
475
499
  width: 26px; height: 14px; border-radius: 999px;
476
500
  background: var(--surface2); border: 1px dashed var(--border);
477
501
  box-sizing: border-box; transition: all var(--transition-base);
478
502
  }
479
- .pr-observe-switch__knob {
503
+ .pr-automation-switch__knob {
480
504
  position: absolute; top: 1px; left: 1px;
481
505
  width: 10px; height: 10px; border-radius: 50%;
482
506
  background: var(--muted); transition: all var(--transition-base);
483
507
  }
484
- .pr-observe-switch.pr-observe-on .pr-observe-switch__track {
508
+ .pr-automation-switch.pr-automation-on .pr-automation-switch__track {
485
509
  background: rgba(63,185,80,0.18); border: 1px solid var(--green);
486
510
  }
487
- .pr-observe-switch.pr-observe-on .pr-observe-switch__knob {
511
+ .pr-automation-switch.pr-automation-on .pr-automation-switch__knob {
488
512
  left: 14px; background: var(--green);
489
513
  }
490
- .pr-observe-switch.pr-observe-on:hover .pr-observe-switch__track { background: rgba(63,185,80,0.32); }
491
- .pr-observe-switch.pr-observe-off:hover .pr-observe-switch__track { border-color: var(--text); }
492
- .pr-observe-switch.pr-observe-off:hover .pr-observe-switch__knob { background: var(--text); }
493
- .pr-observe-switch__input:focus-visible ~ .pr-observe-switch__track {
514
+ .pr-automation-switch.pr-automation-on:hover .pr-automation-switch__track { background: rgba(63,185,80,0.32); }
515
+ .pr-automation-switch.pr-automation-off:hover .pr-automation-switch__track { border-color: var(--text); }
516
+ .pr-automation-switch.pr-automation-off:hover .pr-automation-switch__knob { background: var(--text); }
517
+ .pr-automation-switch__input:focus-visible ~ .pr-automation-switch__track {
494
518
  outline: 2px solid var(--blue); outline-offset: 2px;
495
519
  }
496
520
 
@@ -550,8 +574,8 @@
550
574
  form-row adders ("+ Add step", "+ Add requirement"). Change the green
551
575
  hex / border / padding / hover once here and every "+ X" button updates.
552
576
  Variant:
553
- .btn-add — compact text-xs / 1px 6px (section-header default)
554
- .btn-add-lg — text-sm / 2px 8px (form rows + larger header buttons)
577
+ .btn-add — --text-sm / 1px 6px (section-header default)
578
+ .btn-add-lg — --text-sm / 2px 8px (form rows + larger header buttons)
555
579
  Positional spacing (e.g. margin-left:8px after an h2 count) lives at
556
580
  the callsite, not on the button itself. Do NOT re-create the green
557
581
  inline style for a new "+ X" button — extend this primitive instead. */
@@ -579,11 +603,11 @@
579
603
  every callsite that was previously inline `style="font-size:…;
580
604
  padding:…;color:var(--green);border-color:var(--green)"` on top of
581
605
  .pr-pager-btn:
582
- .btn-action — compact text-xs / 1px 6px (inline PRD
606
+ .btn-action — --text-sm / 1px 6px (inline PRD
583
607
  chips, work-item feedback)
584
- .btn-action.btn-action-md — text-xs / 2px 8px (meetings, pipelines,
608
+ .btn-action.btn-action-md — --text-sm / 2px 8px (meetings, pipelines,
585
609
  watches resume, schedule run-now chip)
586
- .btn-action.btn-action-lg — text-sm / 2px 10px (modal Save, watch
610
+ .btn-action.btn-action-lg — --text-sm / 2px 10px (modal Save, watch
587
611
  Create, charter Save, schedule modal Run
588
612
  now)
589
613
  Positional/layout-only inline styles (e.g. margin-left:8px, margin-
@@ -610,12 +634,12 @@
610
634
  Abort / Remove / Unpin / unlink-x). Visual sibling to .btn-action —
611
635
  same surface2 background, same padding scale, same hover-tint pattern,
612
636
  just swapped to var(--red). Three size variants:
613
- .btn-destructive — compact text-xs / 1px 6px (work-item
637
+ .btn-destructive — --text-sm / 1px 6px (work-item
614
638
  delete, watch delete, schedule delete,
615
639
  unpin, unlink-x in PR row)
616
- .btn-destructive.btn-destructive-md — text-xs / 2px 8px (pipelines
640
+ .btn-destructive.btn-destructive-md — --text-sm / 2px 8px (pipelines
617
641
  Abort + Delete)
618
- .btn-destructive.btn-destructive-lg — text-sm / 2px 10px (watch
642
+ .btn-destructive.btn-destructive-lg — --text-sm / 2px 10px (watch
619
643
  builder Remove step / Remove
620
644
  requirement)
621
645
  Positional / outlier inline overrides (padding:1px 5px on the PR
@@ -639,30 +663,6 @@
639
663
  .btn-destructive.btn-destructive-md { padding: 2px 8px; }
640
664
  .btn-destructive.btn-destructive-lg { font-size: var(--text-sm); padding: 2px 10px; }
641
665
 
642
- /* W-mqh9bwig — blue-bordered "open PR detail" pill (↗) in the PR-row
643
- Actions cell. Third member of the .btn-action / .btn-destructive
644
- family — same surface2 background, text-xs scale, 1px 6px padding,
645
- radius, and hover-tint pattern — swapped to var(--blue) for the
646
- non-destructive open-detail affordance. Previously had NO rule and fell
647
- back to native button chrome, which clashed with the red unlink-x beside
648
- it. Box model is byte-for-byte the .btn-destructive primitive so the two
649
- buttons in the cell are the same height and vertically aligned; the
650
- native button centres the ↗ glyph and text-align:center keeps it from
651
- drifting. */
652
- .pr-info-pill {
653
- background: var(--surface2);
654
- border: 1px solid var(--blue);
655
- color: var(--blue);
656
- font-size: var(--text-sm);
657
- padding: 1px 6px;
658
- border-radius: var(--radius-sm);
659
- cursor: pointer;
660
- text-align: center;
661
- transition: background var(--transition-base);
662
- }
663
- .pr-info-pill:hover { background: rgba(88,166,255,0.1); }
664
- .pr-info-pill:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
665
-
666
666
  /* W-mq57qetc0009ed48 — solid-blue primary CTA. Single source of truth
667
667
  for the filled-blue rectangle that gates submission flows (QA "Start
668
668
  QA Session", "+ New runbook", "Save" in the QA runbook editor, FRE
@@ -914,7 +914,7 @@
914
914
  }
915
915
  .model-combo-option:hover { background: var(--surface2); }
916
916
  .model-combo-option.active { background: rgba(88,166,255,0.15); }
917
- .model-combo-label { color: var(--muted); font-size: var(--text-xs); }
917
+ .model-combo-label { color: var(--muted); font-size: var(--text-sm); }
918
918
 
919
919
  /* Hints bar */
920
920
  .cmd-hints {
@@ -1343,7 +1343,7 @@
1343
1343
  .settings-rail-fold:hover { color: var(--text); background: var(--surface); }
1344
1344
  .settings-rail-fold.no-match { opacity: 0.3; }
1345
1345
  .settings-rail-fold .rail-label { flex: 1; }
1346
- .settings-rail-fold .match-count { font-size: var(--text-xs); color: var(--blue); background: var(--bg); border-radius: var(--radius-xl); padding: 1px 6px; min-width: 18px; text-align: center; }
1346
+ .settings-rail-fold .match-count { font-size: var(--text-sm); color: var(--blue); background: var(--bg); border-radius: var(--radius-xl); padding: 1px 6px; min-width: 18px; text-align: center; }
1347
1347
  .settings-rail-fold .fold-chevron::before { content: '\25B8'; display: inline-block; font-size: var(--text-xs); color: var(--muted); transition: transform var(--transition-fast); }
1348
1348
  .settings-rail-fold.open .fold-chevron::before { transform: rotate(90deg); }
1349
1349
  .settings-rail-group { display: none; }
@@ -1355,6 +1355,22 @@
1355
1355
  .settings-pane h3 { font-size: var(--text-xl); color: var(--blue); margin-bottom: var(--space-3); font-weight: 600; }
1356
1356
  .settings-pane .settings-pane-sub { font-size: var(--text-base); color: var(--muted); margin-bottom: var(--space-7); }
1357
1357
  .settings-pane h4 { font-size: var(--text-lg); color: var(--text); margin: var(--space-7) 0 var(--space-4); font-weight: 600; }
1358
+ /* W-ms4o7y1g007jdb2d follow-up — prominent numbered section headers for the
1359
+ Plan & PR Workflow tab (Plan / PR creation / Monitor) so the three phases
1360
+ read as distinct steps rather than plain sub-headings. */
1361
+ .settings-pane .settings-section-head {
1362
+ display: flex; align-items: center; gap: var(--space-3);
1363
+ color: var(--text); font-weight: 700;
1364
+ margin: var(--space-8) 0 var(--space-4); padding-bottom: var(--space-3);
1365
+ border-bottom: 2px solid var(--blue);
1366
+ }
1367
+ .settings-pane .settings-section-head:first-of-type { margin-top: var(--space-4); }
1368
+ .settings-pane .settings-section-head .settings-section-num {
1369
+ display: inline-flex; align-items: center; justify-content: center;
1370
+ width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto;
1371
+ background: var(--blue); color: #fff; font-size: var(--text-sm); font-weight: 700;
1372
+ }
1373
+ .settings-pane .settings-section-head .settings-section-title { font-size: var(--text-xl); letter-spacing: 0.01em; }
1358
1374
  .settings-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
1359
1375
  .settings-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-4); }
1360
1376
  .settings-stack { display: flex; flex-direction: column; gap: var(--space-3); }
@@ -1395,11 +1411,51 @@
1395
1411
  .settings-tile.match-highlight .settings-tile-inner { box-shadow: 0 0 0 2px var(--blue); }
1396
1412
  .settings-tile-icon { font-size: var(--text-2xl, 20px); line-height: 1; }
1397
1413
  .settings-tile-label { font-size: var(--text-md); color: var(--text); font-weight: 600; }
1398
- .settings-tile-state { font-size: var(--text-xs); color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
1414
+ .settings-tile-state { font-size: var(--text-sm); color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
1399
1415
  .settings-tile-state::after { content: "Off"; }
1400
1416
  .settings-tile-input:checked ~ .settings-tile-inner .settings-tile-state { color: var(--blue); }
1401
1417
  .settings-tile-input:checked ~ .settings-tile-inner .settings-tile-state::after { content: "On"; }
1402
1418
 
1419
+ /* W-ms4o7y1g007jdb2d — two-state DRAFT ⇄ PUBLISH switch (Settings → Plan & PR
1420
+ Workflow → PR creation). Semantic <input type=checkbox id="set-createPrsAsDraft">
1421
+ hidden but focusable; the visible track + both end labels are siblings.
1422
+ checked = Draft (knob right, Draft end lit); unchecked = Publish (knob left,
1423
+ Publish end lit). Pure CSS via :checked sibling selector — no JS handler. */
1424
+ .settings-switch {
1425
+ display: inline-flex; align-items: center; gap: 8px;
1426
+ cursor: pointer; user-select: none;
1427
+ }
1428
+ .settings-switch__input {
1429
+ position: absolute; opacity: 0; pointer-events: none;
1430
+ width: 1px; height: 1px; margin: 0; padding: 0;
1431
+ }
1432
+ .settings-switch__end {
1433
+ font-size: var(--text-md); color: var(--muted); font-weight: 600;
1434
+ transition: color var(--transition-base);
1435
+ }
1436
+ .settings-switch__input:not(:checked) ~ .settings-switch__end--publish { color: var(--green); }
1437
+ .settings-switch__input:checked ~ .settings-switch__end--draft { color: var(--blue); }
1438
+ .settings-switch__track {
1439
+ display: inline-block; position: relative;
1440
+ width: 34px; height: 16px; border-radius: 999px;
1441
+ background: var(--surface2); border: 1px solid var(--border);
1442
+ box-sizing: border-box; transition: all var(--transition-base);
1443
+ }
1444
+ .settings-switch__knob {
1445
+ position: absolute; top: 1px; left: 1px;
1446
+ width: 12px; height: 12px; border-radius: 50%;
1447
+ background: var(--muted); transition: all var(--transition-base);
1448
+ }
1449
+ .settings-switch__input:checked ~ .settings-switch__track {
1450
+ background: rgba(130,160,210,0.18); border-color: var(--blue);
1451
+ }
1452
+ .settings-switch__input:checked ~ .settings-switch__track .settings-switch__knob {
1453
+ left: 19px; background: var(--blue);
1454
+ }
1455
+ .settings-switch__input:focus-visible ~ .settings-switch__track {
1456
+ outline: 2px solid var(--blue); outline-offset: 2px;
1457
+ }
1458
+
1403
1459
  /* Responsive: tablet / narrow window */
1404
1460
  @media (max-width: 1100px) {
1405
1461
  .layout { grid-template-columns: 1fr; }
@@ -1717,6 +1773,22 @@
1717
1773
  }
1718
1774
  .qa-artifact-log { max-width: 480px; }
1719
1775
 
1776
+ /* W-ms9p62od00kt5b58 — for a run in a terminal state the screenshots and
1777
+ video stay inline and every other artifact (logs, json, md, binaries)
1778
+ collapses behind one disclosure. width:100% breaks the <details> onto its
1779
+ own line inside the .qa-run-artifacts flex row. */
1780
+ .qa-artifact-secondary { width: 100%; }
1781
+ .qa-artifact-secondary-summary {
1782
+ cursor: pointer; color: var(--muted); font-size: var(--text-base);
1783
+ padding: var(--space-2) 0; user-select: none;
1784
+ }
1785
+ .qa-artifact-secondary-summary:hover { color: var(--text); }
1786
+ .qa-artifact-secondary-body {
1787
+ display: flex; flex-wrap: wrap; gap: var(--space-4);
1788
+ margin-top: var(--space-3);
1789
+ }
1790
+ .qa-artifact-binary { max-width: 480px; }
1791
+
1720
1792
  /* ── P-h7e4f9b2: QA Sessions section ───────────────────────────────── */
1721
1793
  .qa-session-form-wrap {
1722
1794
  background: var(--surface2); border: 1px solid var(--border);
@@ -1837,6 +1909,24 @@
1837
1909
  background: var(--surface); padding: var(--space-3);
1838
1910
  border-radius: var(--radius-sm);
1839
1911
  }
1912
+
1913
+ /* W-msb9kgs402813a97-d — the linked qa-run chip and, for a terminal session,
1914
+ the run's primary artifacts. The artifact tiles themselves are the shared
1915
+ .qa-artifact rules above (the card reuses _qaRenderArtifactPreviews), so
1916
+ only the container and the "captured nothing" cue are declared here. */
1917
+ .qa-session-run-link { color: var(--blue); text-decoration: none; }
1918
+ .qa-session-run-link:hover { text-decoration: underline; }
1919
+ .qa-session-run-status { color: var(--muted); font-size: var(--text-sm); }
1920
+ .qa-session-artifacts {
1921
+ display: flex; flex-wrap: wrap; gap: var(--space-4);
1922
+ padding-top: var(--space-3); border-top: 1px solid var(--border);
1923
+ }
1924
+ .qa-session-artifacts-empty {
1925
+ font-size: var(--text-base); color: var(--muted);
1926
+ padding-top: var(--space-3); border-top: 1px solid var(--border);
1927
+ }
1928
+ /* Transient highlight after a run chip scrolls its Recent Runs row into view. */
1929
+ .qa-run-row--flash { border-color: var(--blue); box-shadow: 0 0 0 2px rgba(56, 139, 253, 0.25); }
1840
1930
  .qa-session-actions {
1841
1931
  display: flex; gap: var(--space-3); flex-wrap: wrap;
1842
1932
  padding-top: var(--space-3); border-top: 1px solid var(--border);
@@ -1892,3 +1982,17 @@
1892
1982
  width: 100%; max-width: none; height: 100%; max-height: none;
1893
1983
  border: none; border-radius: 0;
1894
1984
  }
1985
+ /* W-ms4rnxoi — the standalone classic modal caps at 80vh, so .settings-layout
1986
+ is hardcoded to `height: calc(80vh - 64px)` (see the .settings-layout rule
1987
+ above). Inside the full-height embed iframe the modal is forced to 100%, but
1988
+ that 80vh layout only fills ~80% of the frame — leaving a big empty bar below
1989
+ it. Fill the frame with flex rather than viewport math: `body` carries
1990
+ `zoom: var(--minions-font-scale)` (see :root above), and a `vh` value is
1991
+ evaluated in UNZOOMED px, so any calc(100vh - …) renders ~zoom times too
1992
+ tall and pushes settings rows below the frame — where `.settings-body`'s
1993
+ `overflow: hidden` makes them unreachable. `.modal` is already a column flex
1994
+ container forced to `height: 100%` here, so letting the body absorb the
1995
+ leftover space is immune to both the zoom factor and the real header
1996
+ height (no magic 64px, no vh). */
1997
+ html.embed-settings .modal-body.settings-body { flex: 1 1 auto; min-height: 0; }
1998
+ html.embed-settings .settings-layout { height: 100%; }
@@ -4,11 +4,16 @@
4
4
  */
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
- const shared = require('./engine/shared');
7
+ const shared = require('./engine/core/shared');
8
8
  const { safeRead } = shared;
9
9
 
10
10
  const MINIONS_DIR = __dirname;
11
- const DASHBOARD_SHARED_JS = ['pr-merge-state', 'pr-filters', 'cc-suggestions', 'cc-queue-store', 'model-display', 'watches-source', 'project-git-summary', 'welcome-popup'];
11
+ // Order is load-bearing: 'record-filters' publishes window.MinionsRecordFilters,
12
+ // which 'pr-filters' consumes at module scope, so it must be listed first.
13
+ // 'wi-filters' publishes window.MinionsWorkItemFilters (the Work Items table's
14
+ // filter + sort semantics), consumed by render-work-items.js — hence it precedes
15
+ // the renderer bundle (DASHBOARD_JS_FILES) too.
16
+ const DASHBOARD_SHARED_JS = ['record-filters', 'pr-merge-state', 'pr-filters', 'wi-filters', 'cc-suggestions', 'cc-limits', 'cc-queue-store', 'model-display', 'watches-source', 'project-git-summary', 'welcome-popup'];
12
17
 
13
18
  // ── Canonical classic-dashboard assembly manifest ──────────────────────────
14
19
  // Single source of truth, consumed by BOTH assemblers: buildDashboardHtml()
@@ -214,6 +219,11 @@ function buildSlimHtml(opts) {
214
219
  // the default is a valid empty object so direct buildSlimHtml() calls (tests,
215
220
  // other builders) still produce parseable JS.
216
221
  const featuresJson = (opts && opts.featuresJson) || '{ "flags": {}, "defaults": {} }';
222
+ // Command Center length limits, injected so the slim client
223
+ // (dashboard/shared/cc-limits.js) mirrors the server and cannot drift. The
224
+ // default matches ccApiValidation.CC_API_LIMITS so direct buildSlimHtml()
225
+ // calls (tests, other builders) still produce parseable JS (W-mscjjqdh).
226
+ const ccLimitsJson = (opts && opts.ccLimitsJson) || '{ "messageMaxChars": 100000, "transcriptTextMaxChars": 65536, "transcriptMaxEntries": 20 }';
217
227
 
218
228
  return layout
219
229
  .replace('/* __CSS__ */', () => css)
@@ -221,6 +231,7 @@ function buildSlimHtml(opts) {
221
231
  // an exact '\n' match would silently no-op and ship an empty body on CRLF).
222
232
  .replace(/<!-- __BODY__ -->\r?\n/, () => body)
223
233
  .replace('{{minions_features}}', () => featuresJson)
234
+ .replace('{{cc_api_limits}}', () => ccLimitsJson)
224
235
  .replace('/* __PANEL_JS__ */', () => panelJs)
225
236
  .replace('/* __JS__ */', () => js);
226
237
  }