@worca/app 1.5.0 → 1.6.0-rc.1
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/README.md +7 -1
- package/docker/compose.broker.yml +79 -0
- package/docker/compose.isolation.yml +40 -0
- package/package.json +2 -1
- package/src/broker/config.mjs +200 -0
- package/src/broker/copilot.mjs +124 -0
- package/src/broker/limits.mjs +88 -0
- package/src/broker/main.mjs +129 -0
- package/src/broker/scrub.mjs +45 -0
- package/src/broker/service.mjs +558 -0
- package/src/broker/slots.mjs +180 -0
- package/src/broker/store.mjs +171 -0
- package/src/broker/tokens.mjs +116 -0
- package/src/broker/ui/page.css +54 -0
- package/src/broker/ui/page.html +25 -0
- package/src/broker/ui/page.mjs +202 -0
- package/src/broker/ui-server.mjs +217 -0
- package/src/broker/usage.mjs +108 -0
- package/src/broker/vault.mjs +37 -0
- package/src/cli/models.mjs +46 -14
- package/src/cli/render.mjs +21 -0
- package/src/cli/runs.mjs +296 -0
- package/src/cli/worca-cc.mjs +14 -2
- package/src/core/agent-pool.mjs +76 -0
- package/src/core/artifacts.mjs +40 -8
- package/src/core/ask/events.mjs +11 -0
- package/src/core/ask/html-text.mjs +113 -0
- package/src/core/ask/limits.mjs +5 -0
- package/src/core/ask/mcp-stdio.mjs +74 -20
- package/src/core/ask/prompt.mjs +25 -6
- package/src/core/ask/spawn.mjs +55 -5
- package/src/core/ask/store.mjs +1 -1
- package/src/core/ask/tools.mjs +66 -1
- package/src/core/ask/turn.mjs +52 -3
- package/src/core/ask/web-access.mjs +26 -0
- package/src/core/ask/web-deps.mjs +56 -0
- package/src/core/ask/web-fetch.mjs +271 -0
- package/src/core/ask/web-proposal.mjs +76 -0
- package/src/core/auto/classify.mjs +20 -8
- package/src/core/auto/runnable.mjs +28 -0
- package/src/core/billing.mjs +53 -0
- package/src/core/bridge/errors.mjs +77 -5
- package/src/core/bridge/openrouter.mjs +59 -0
- package/src/core/bridge/provider-ops.mjs +165 -9
- package/src/core/bridge/providers/endpoint.mjs +112 -7
- package/src/core/bridge/registry.mjs +13 -0
- package/src/core/bridge/server.mjs +16 -3
- package/src/core/bridge/telemetry.mjs +44 -12
- package/src/core/bridge/translate/common.mjs +31 -0
- package/src/core/bridge/translate/request.mjs +4 -1
- package/src/core/bridge/translate/response.mjs +3 -0
- package/src/core/bridge/translate/schema-keywords.mjs +75 -0
- package/src/core/bridge/translate/stream.mjs +50 -4
- package/src/core/bridge/upstream.mjs +102 -17
- package/src/core/broker-boot.mjs +57 -0
- package/src/core/broker-client.mjs +206 -0
- package/src/core/broker-guard.mjs +112 -0
- package/src/core/broker-routing.mjs +138 -0
- package/src/core/claude-auth.mjs +29 -0
- package/src/core/claude-runner.mjs +200 -9
- package/src/core/config.mjs +9 -12
- package/src/core/failure-policy.mjs +4 -2
- package/src/core/git-info.mjs +49 -5
- package/src/core/github-credentials.mjs +44 -1
- package/src/core/graph/script-runner.mjs +3 -1
- package/src/core/list-prices.mjs +29 -0
- package/src/core/mcp-secrets.mjs +80 -0
- package/src/core/metrics/sync.mjs +2 -1
- package/src/core/model-env.mjs +72 -0
- package/src/core/model-test.mjs +17 -5
- package/src/core/onboarding.mjs +12 -6
- package/src/core/openrouter-free.mjs +159 -0
- package/src/core/orchestrator.mjs +100 -12
- package/src/core/policy/effective.mjs +18 -1
- package/src/core/policy/local.mjs +4 -1
- package/src/core/policy/registry.mjs +12 -2
- package/src/core/preflight.mjs +116 -0
- package/src/core/recoverable-error.mjs +95 -0
- package/src/core/recovery-backoff.mjs +84 -0
- package/src/core/redact.mjs +25 -0
- package/src/core/run-context.mjs +6 -0
- package/src/core/run-harness.mjs +112 -30
- package/src/core/run-report.mjs +2 -1
- package/src/core/settings.mjs +90 -5
- package/src/core/title.mjs +7 -2
- package/src/core/web-allowlist.mjs +95 -0
- package/ui/public/app.js +244 -43
- package/ui/public/ask-model.mjs +1 -0
- package/ui/public/ask-panel.mjs +160 -23
- package/ui/public/bridge-view.mjs +175 -6
- package/ui/public/chat-settings-view.mjs +52 -1
- package/ui/public/credential-badges.mjs +63 -0
- package/ui/public/credentials-view.mjs +57 -0
- package/ui/public/index.html +33 -6
- package/ui/public/models-view.mjs +19 -1
- package/ui/public/openrouter-free-view.mjs +118 -0
- package/ui/public/stats-view.mjs +56 -0
- package/ui/public/style.css +99 -50
- package/ui/public/team-policy-view.mjs +2 -1
- package/ui/public/ws-seq.mjs +24 -0
- package/ui/server.mjs +319 -23
package/ui/public/style.css
CHANGED
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
--trunc-ink:light-dark(#994466,#E39BBE);
|
|
71
71
|
--chip-ink:light-dark(#555555,#B4B4AE);
|
|
72
72
|
|
|
73
|
-
--r-card:
|
|
74
|
-
--r-ctrl:
|
|
73
|
+
--r-card:14px;
|
|
74
|
+
--r-ctrl:10px;
|
|
75
75
|
--shadow:0 6px 28px light-dark(rgba(25,25,27,.05),rgba(0,0,0,.45)), 0 1px 2px light-dark(rgba(25,25,27,.04),rgba(0,0,0,.35));
|
|
76
76
|
--shadow-soft:0 2px 12px light-dark(rgba(25,25,27,.04),rgba(0,0,0,.35));
|
|
77
77
|
--shadow-pop:0 6px 28px light-dark(rgba(25,25,27,.10),rgba(0,0,0,.55)),0 1px 2px light-dark(rgba(25,25,27,.06),rgba(0,0,0,.4));
|
|
@@ -503,7 +503,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
503
503
|
|
|
504
504
|
/* @-mention popup: attached-file completions anchored under the prompt caret */
|
|
505
505
|
.mention-popup{position:fixed;z-index:70;min-width:180px;max-width:320px;max-height:210px;overflow-y:auto;
|
|
506
|
-
background:var(--panel);border:1px solid var(--line-2);border-radius:
|
|
506
|
+
background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r-card);box-shadow:var(--shadow);padding:5px;}
|
|
507
507
|
.mention-item{display:block;width:100%;text-align:left;border:0;background:transparent;color:var(--ink-2);
|
|
508
508
|
font-family:inherit;font-weight:500;font-size:12.5px;padding:7px 10px;border-radius:8px;cursor:pointer;
|
|
509
509
|
white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
@@ -622,7 +622,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
622
622
|
One collapsed row per agent showing its effective config; the controls only
|
|
623
623
|
exist once a row is opened, so the page height no longer grows with the
|
|
624
624
|
workflow. (newpipeline-ux-design.md §4.2) */
|
|
625
|
-
.agents-cfg{margin:6px 0 18px;border:1px solid var(--line);border-radius:
|
|
625
|
+
.agents-cfg{margin:6px 0 18px;border:1px solid var(--line);border-radius:var(--r-ctrl);overflow:hidden;background:var(--field);}
|
|
626
626
|
.agents-head{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line);}
|
|
627
627
|
.agents-title{font-weight:700;font-size:13px;}
|
|
628
628
|
.agents-wf{flex:0 0 auto;font-size:11.5px;font-weight:600;color:var(--ink-2);
|
|
@@ -727,7 +727,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
727
727
|
.btn-clear{background:var(--field);border:none;border-radius:10px;padding:8px 15px;font-family:inherit;
|
|
728
728
|
font-weight:600;font-size:12.5px;cursor:pointer;color:var(--ink-2);transition:.15s;}
|
|
729
729
|
.btn-clear:hover{background:var(--line-2);}
|
|
730
|
-
.log{background:var(--panel);border:1px solid var(--line);border-radius:
|
|
730
|
+
.log{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);min-height:260px;max-height:380px;overflow-y:auto;
|
|
731
731
|
padding:18px 20px;font-family:var(--mono);font-size:12.5px;line-height:1.85;color:var(--ink-2);
|
|
732
732
|
white-space:pre-wrap;word-break:break-word;}
|
|
733
733
|
.log .t{color:var(--ink-3);}
|
|
@@ -762,7 +762,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
762
762
|
(design D14). Amber family; the circle inverts to --panel so it still reads
|
|
763
763
|
against the pale wash. */
|
|
764
764
|
.run-ask-banner{display:flex;align-items:center;gap:12px;margin:0 0 18px;padding:13px 18px;
|
|
765
|
-
background:var(--amber-wash);border:1px solid var(--amber);border-radius:
|
|
765
|
+
background:var(--amber-wash);border:1px solid var(--amber);border-radius:var(--r-card);}
|
|
766
766
|
.run-ask-banner[hidden]{display:none;} /* author display:flex beats the UA [hidden] rule */
|
|
767
767
|
.run-ask-banner .rab-mark{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
|
|
768
768
|
width:26px;height:26px;border-radius:50%;background:var(--panel);
|
|
@@ -773,7 +773,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
773
773
|
everything, amber like the other "needs you" banners. */
|
|
774
774
|
.session-expired{position:fixed;top:12px;left:50%;transform:translateX(-50%);z-index:10000;
|
|
775
775
|
display:flex;align-items:center;gap:14px;max-width:calc(100vw - 32px);padding:10px 12px 10px 18px;
|
|
776
|
-
background:var(--amber-wash);border:1px solid var(--amber);border-radius:
|
|
776
|
+
background:var(--amber-wash);border:1px solid var(--amber);border-radius:var(--r-card);
|
|
777
777
|
box-shadow:var(--shadow-pop);}
|
|
778
778
|
.session-expired .se-text{font-weight:500;font-size:13px;color:var(--amber-ink);}
|
|
779
779
|
.session-expired .se-reload{font:inherit;font-size:13px;font-weight:600;padding:6px 14px;border-radius:10px;
|
|
@@ -866,7 +866,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
|
|
|
866
866
|
first — keeping the prose free of them means a future sweep that forgets to
|
|
867
867
|
strip still passes. */
|
|
868
868
|
.qpanel{margin-top:18px;padding:14px 16px 13px;background:var(--amber-wash);
|
|
869
|
-
border:1px solid var(--amber-bg);border-radius:
|
|
869
|
+
border:1px solid var(--amber-bg);border-radius:var(--r-ctrl);}
|
|
870
870
|
.qpanel-head{display:flex;align-items:center;gap:11px;}
|
|
871
871
|
.qpanel-head svg{stroke:var(--amber-ink);flex:0 0 auto;}
|
|
872
872
|
.qpanel-head b{flex:1;min-width:0;font-weight:600;font-size:12.5px;color:var(--amber-ink);}
|
|
@@ -1237,7 +1237,7 @@ button.af-gal-card:focus-visible{outline:2px solid var(--ink);outline-offset:2px
|
|
|
1237
1237
|
.hist-head .h-meta b{cursor:pointer;}
|
|
1238
1238
|
.hist-head .h-meta b:hover{text-decoration:underline;}
|
|
1239
1239
|
.retained-banner{margin:0 0 18px;padding:16px 18px;border:1.5px solid var(--amber);
|
|
1240
|
-
border-radius:
|
|
1240
|
+
border-radius:var(--r-card);background:var(--amber-bg);color:var(--amber-ink);font-size:12.5px;line-height:1.55;}
|
|
1241
1241
|
.retained-banner[hidden]{display:none;}
|
|
1242
1242
|
.retained-banner h4{margin:0 0 6px;font-size:14px;color:var(--amber-ink);}
|
|
1243
1243
|
.retained-banner p{margin:5px 0;}
|
|
@@ -1273,7 +1273,7 @@ button.af-gal-card:focus-visible{outline:2px solid var(--ink);outline-offset:2px
|
|
|
1273
1273
|
|
|
1274
1274
|
/* ---------- Saved-markdown viewer ---------- */
|
|
1275
1275
|
.viewer{font-family:var(--mono);font-size:12.5px;line-height:1.7;background:var(--canvas-2);border:1px solid var(--line);
|
|
1276
|
-
border-radius:
|
|
1276
|
+
border-radius:var(--r-card);padding:18px 20px;max-height:480px;overflow:auto;white-space:pre-wrap;word-break:break-word;margin:0;}
|
|
1277
1277
|
|
|
1278
1278
|
/* ---------- scrollbars ---------- */
|
|
1279
1279
|
::-webkit-scrollbar{width:10px;height:10px;}
|
|
@@ -1334,7 +1334,7 @@ button.af-gal-card:focus-visible{outline:2px solid var(--ink);outline-offset:2px
|
|
|
1334
1334
|
.topnav{display:none;}
|
|
1335
1335
|
@media (max-width:1080px){
|
|
1336
1336
|
.topnav{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:20px;background:var(--panel);
|
|
1337
|
-
border:1px solid var(--line);border-radius:
|
|
1337
|
+
border:1px solid var(--line);border-radius:var(--r-card);padding:5px;}
|
|
1338
1338
|
.topnav button{flex:1;text-align:center;padding:9px 12px;border:0;border-radius:10px;
|
|
1339
1339
|
background:transparent;color:var(--ink-2);font-family:inherit;font-weight:600;font-size:13px;
|
|
1340
1340
|
cursor:pointer;transition:.15s;}
|
|
@@ -1562,6 +1562,10 @@ button.wd-member:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;
|
|
|
1562
1562
|
.wiz-proj:hover{background:var(--surface);}
|
|
1563
1563
|
.wiz-proj input{margin:0;cursor:pointer;}
|
|
1564
1564
|
.wiz-proj.missing{color:var(--ink-3);cursor:not-allowed;}
|
|
1565
|
+
.wiz-proj-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;}
|
|
1566
|
+
.wiz-select-all{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-2);cursor:pointer;}
|
|
1567
|
+
.wiz-select-all input{margin:0;cursor:pointer;}
|
|
1568
|
+
.wiz-select-all:has(input:disabled){opacity:.5;cursor:not-allowed;}
|
|
1565
1569
|
|
|
1566
1570
|
/* Live scan loader (role=status aria-live=polite). */
|
|
1567
1571
|
.ws-loader{display:flex;flex-direction:column;align-items:center;gap:12px;padding:36px 24px;text-align:center;}
|
|
@@ -1595,7 +1599,7 @@ button.wd-member:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;
|
|
|
1595
1599
|
/* ties `.gv-world .node` and loses on source order — silently killing the v2 */
|
|
1596
1600
|
/* status border colours. */
|
|
1597
1601
|
/* ========================================================================== */
|
|
1598
|
-
.run-flow-wrap{position:relative;margin:0 0 18px;border-radius:
|
|
1602
|
+
.run-flow-wrap{position:relative;margin:0 0 18px;border-radius:var(--r-card);border:1px solid var(--line);overflow-x:auto;overflow-y:hidden;background-color:var(--canvas-2);background-image:radial-gradient(circle, var(--line-2) 1.1px, transparent 1.1px);background-size:22px 22px;}
|
|
1599
1603
|
.run-flow{position:relative;display:flex;align-items:center;gap:44px;padding:66px 30px 52px;width:max-content;min-width:100%;}
|
|
1600
1604
|
/* Status badge (top-right pip). */
|
|
1601
1605
|
.run-flow .nstat{position:absolute;top:-8px;right:-8px;width:21px;height:21px;border-radius:50%;display:grid;place-items:center;box-shadow:var(--shadow-soft);z-index:3;}
|
|
@@ -1874,7 +1878,7 @@ input.bench-case-name{width:100%;padding:9px 12px;font-size:13px;}
|
|
|
1874
1878
|
.wz-pick-line{font-size:14px;color:var(--ink-2);}
|
|
1875
1879
|
.wz-rt-cards{display:flex;gap:20px;width:100%;max-width:1080px;}
|
|
1876
1880
|
@media (max-width:900px){.wz-rt-cards{flex-direction:column;}}
|
|
1877
|
-
.wz .rt{display:flex;flex-direction:column;gap:12px;flex:1 1 0;min-width:0;min-height:250px;padding:22px;border-radius:
|
|
1881
|
+
.wz .rt{display:flex;flex-direction:column;gap:12px;flex:1 1 0;min-width:0;min-height:250px;padding:22px;border-radius:var(--r-card);background:var(--panel);border:2px solid transparent;box-shadow:var(--shadow);cursor:pointer;text-align:left;font-family:inherit;color:var(--ink);}
|
|
1878
1882
|
.wz .rt:hover:not(:disabled){transform:translateY(-1px);}
|
|
1879
1883
|
.wz .rt.sel{border-color:var(--ink);}
|
|
1880
1884
|
.wz .rt:disabled{opacity:.45;cursor:not-allowed;}
|
|
@@ -1890,7 +1894,7 @@ input.bench-case-name{width:100%;padding:9px 12px;font-size:13px;}
|
|
|
1890
1894
|
.wz .panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);}
|
|
1891
1895
|
.wz-panel-title{font-size:13.5px;font-weight:600;}
|
|
1892
1896
|
.wz-tile{display:flex;align-items:center;gap:14px;padding:14px 16px;}
|
|
1893
|
-
.wz .tile{width:48px;height:48px;border-radius:
|
|
1897
|
+
.wz .tile{width:48px;height:48px;border-radius:var(--r-ctrl);display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;}
|
|
1894
1898
|
.wz .tile-green{background:var(--green-bg);color:var(--green-ink);}.wz .tile-peach{background:var(--peach-bg);color:var(--peach-ink);}
|
|
1895
1899
|
.wz .tile-red{background:var(--red-bg);color:var(--red-ink);}.wz .tile-blue{background:var(--blue-bg);color:var(--blue-ink);}
|
|
1896
1900
|
.wz .tile-violet{background:var(--violet-bg);color:var(--violet-ink);}.wz .tile-amber{background:var(--amber-bg);color:var(--amber-ink);}
|
|
@@ -2262,6 +2266,21 @@ button.pd-ov-card:hover{border-color:var(--ink-3);}
|
|
|
2262
2266
|
without this the rows touch while every other gap is 14px. */
|
|
2263
2267
|
.charts-grid + .charts-grid{margin-top:14px;}
|
|
2264
2268
|
.chart-card{padding:20px 22px;}
|
|
2269
|
+
/* Stats › By person (credential broker): one full-width card, a table with a share bar. */
|
|
2270
|
+
.people-grid{grid-template-columns:1fr;}
|
|
2271
|
+
.people-scroll{overflow-x:auto;}
|
|
2272
|
+
.people-table{width:100%;border-collapse:collapse;font-size:13px;font-variant-numeric:tabular-nums;}
|
|
2273
|
+
.people-table th{text-align:left;font-weight:500;color:var(--ink-3);font-size:12px;padding:6px 10px 6px 0;border-bottom:1px solid var(--line);white-space:nowrap;}
|
|
2274
|
+
.people-table td{padding:8px 10px 8px 0;border-bottom:1px solid var(--line);vertical-align:middle;}
|
|
2275
|
+
.people-table tr:last-child td{border-bottom:none;}
|
|
2276
|
+
.people-table td.num{white-space:nowrap;color:var(--ink-2);}
|
|
2277
|
+
.people-name{overflow-wrap:anywhere;}
|
|
2278
|
+
.people-spend{min-width:160px;}
|
|
2279
|
+
.people-usd{display:inline-block;min-width:64px;font-weight:600;}
|
|
2280
|
+
.people-bar{display:inline-block;vertical-align:middle;width:90px;height:6px;border-radius:3px;background:var(--line);margin-left:8px;overflow:hidden;}
|
|
2281
|
+
.people-bar-fill{display:block;height:100%;background:var(--blue);}
|
|
2282
|
+
.people-slots{color:var(--ink-2);}
|
|
2283
|
+
.people-card > .hint{display:block;margin-top:10px;}
|
|
2265
2284
|
.chart-fig{margin:0;}
|
|
2266
2285
|
.chart-svg{display:block;width:100%;height:auto;}
|
|
2267
2286
|
.chart-empty{display:grid;place-items:center;min-height:180px;}
|
|
@@ -2291,7 +2310,7 @@ button.pd-ov-card:hover{border-color:var(--ink-3);}
|
|
|
2291
2310
|
.tm-sync-error{white-space:pre-wrap;margin:0;}
|
|
2292
2311
|
section[data-view="team-metrics"] .topbar{align-items:flex-start;}
|
|
2293
2312
|
.sync-chip{margin-left:auto;display:flex;align-items:center;}
|
|
2294
|
-
.sync-chip-inner{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;padding:8px 12px;border:1px solid var(--line-2);border-radius:
|
|
2313
|
+
.sync-chip-inner{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;padding:8px 12px;border:1px solid var(--line-2);border-radius:var(--r-card);background:var(--surface);font-size:12.5px;max-width:520px;}
|
|
2295
2314
|
.sync-chip-inner .dot.green{background:var(--green);} .sync-chip-inner .dot.amber{background:var(--amber);} .sync-chip-inner .dot.red{background:var(--red);}
|
|
2296
2315
|
.sync-chip-inner .tm-sync-error{flex-basis:100%;color:var(--red-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
2297
2316
|
.tm-filter{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:18px;}
|
|
@@ -2451,7 +2470,7 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2451
2470
|
.tl-lg-sw .tl-span,.tl-lg-sw .tl-run{height:12px;margin-top:-6px;}
|
|
2452
2471
|
.tl-foot{display:block;color:var(--ink-2);}
|
|
2453
2472
|
|
|
2454
|
-
.tl-pop{position:fixed;z-index:60;width:340px;max-width:calc(100vw - 32px);background:var(--panel);border:1px solid var(--line);border-radius:
|
|
2473
|
+
.tl-pop{position:fixed;z-index:60;width:340px;max-width:calc(100vw - 32px);background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
|
|
2455
2474
|
box-shadow:var(--shadow-sheet);padding:16px 18px;display:flex;flex-direction:column;gap:10px;}
|
|
2456
2475
|
.tl-pop h3{margin:0;font-size:16px;font-weight:600;line-height:1.3;text-wrap:balance;}
|
|
2457
2476
|
.tl-pop-top{display:flex;align-items:center;justify-content:space-between;gap:8px;}
|
|
@@ -2504,7 +2523,7 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2504
2523
|
.tm-dot.green{background:var(--green);} .tm-dot.amber{background:var(--amber);} .tm-dot.red{background:var(--red);} .tm-dot.grey{background:var(--ink-3);}
|
|
2505
2524
|
/* Enable dialog (boards 5/6) */
|
|
2506
2525
|
/* `.field > label` (display:block, margin-bottom) would otherwise beat this and stack the radio above the title */
|
|
2507
|
-
.radio-card,.field > label.radio-card{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border:1.5px solid var(--line-2);border-radius:var(--r-ctrl,
|
|
2526
|
+
.radio-card,.field > label.radio-card{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border:1.5px solid var(--line-2);border-radius:var(--r-ctrl,10px);margin:8px 0 0;cursor:pointer;font-weight:500;font-size:13px;}
|
|
2508
2527
|
.radio-card input[type="radio"]{flex:0 0 auto;margin:2px 0 0;}
|
|
2509
2528
|
/* :has(), not a render-time .on class: changing the Attribution radio does not re-render the body */
|
|
2510
2529
|
.radio-card:has(> input:checked){border-color:var(--ink);background:var(--field);}
|
|
@@ -2516,7 +2535,7 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2516
2535
|
.wiz-track{display:flex;gap:18px;list-style:none;padding:0;margin:0 0 18px;font-size:12.5px;color:var(--ink-2);}
|
|
2517
2536
|
.wiz-track li span{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--field);margin-right:6px;font-weight:700;}
|
|
2518
2537
|
.wiz-track li.on{color:var(--ink);font-weight:600;} .wiz-track li.on span{background:var(--ink);color:var(--on-ink);}
|
|
2519
|
-
.wiz-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:
|
|
2538
|
+
.wiz-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-ctrl);}
|
|
2520
2539
|
.wiz-row{display:flex;align-items:center;gap:14px;padding:12px 14px;border-top:1px solid var(--line);}
|
|
2521
2540
|
/* The metrics-home picker's radio + slug: the label had no rule, so the radio touched the text. */
|
|
2522
2541
|
.wiz-row-pick{display:flex;align-items:center;gap:10px;min-width:0;cursor:pointer;}
|
|
@@ -2590,6 +2609,8 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2590
2609
|
fill (--line), under verify:theme's 4.5:1. A loss keeps neutral ink (--red-ink is
|
|
2591
2610
|
4.07:1 there); its "−" carries it. */
|
|
2592
2611
|
.spend-ind-saved{margin-top:6px;}
|
|
2612
|
+
/* OpenRouter free-model requests (openrouter-free-view.mjs): a second block under the spend block. */
|
|
2613
|
+
.free-ind{margin-top:8px;}
|
|
2593
2614
|
.spend-ind-saved.pos .spend-ind-label,.spend-ind-saved.pos .spend-ind-amt{color:var(--green-ink-strong);}
|
|
2594
2615
|
.topnav-amt{margin-left:7px;font-family:var(--mono);font-weight:600;}
|
|
2595
2616
|
.topnav-amt.warn{color:var(--amber-ink);}
|
|
@@ -2600,6 +2621,22 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2600
2621
|
/* One width/centering/gap rule for every Settings card. */
|
|
2601
2622
|
.settings-card{max-width:760px;padding:22px;margin-left:auto;margin-right:auto;}
|
|
2602
2623
|
.settings-card + .settings-card{margin-top:18px;}
|
|
2624
|
+
.settings-card[hidden]{display:none;}
|
|
2625
|
+
|
|
2626
|
+
/* My model credentials (credential broker): one row per slot, a state chip on the right. */
|
|
2627
|
+
.cred-list{list-style:none;margin:0;padding:0;display:grid;gap:8px;}
|
|
2628
|
+
.cred-row{display:flex;justify-content:space-between;align-items:center;gap:12px;font-size:13px;}
|
|
2629
|
+
.cred-name{min-width:0;overflow-wrap:anywhere;}
|
|
2630
|
+
.cred-chip{font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;white-space:nowrap;}
|
|
2631
|
+
.cred-chip.tone-green{background:var(--green-bg);color:var(--green-ink);}
|
|
2632
|
+
.cred-chip.tone-red{background:var(--red-bg);color:var(--red-ink);}
|
|
2633
|
+
.cred-chip.tone-blue{background:var(--blue-bg);color:var(--blue-ink);}
|
|
2634
|
+
.cred-chip.tone-slate{background:var(--slate-bg);color:var(--slate-ink);}
|
|
2635
|
+
.cred-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:14px;}
|
|
2636
|
+
/* Providers card with the credential broker: keys, sign-in and key tests live on the key page. */
|
|
2637
|
+
.mv-providers--broker .mv-cp-signin,.mv-providers--broker .mv-cp-signout,.mv-providers--broker .mv-cp-quota-refresh,
|
|
2638
|
+
.mv-providers--broker .mv-cp-quota,.mv-providers--broker .mv-pv-test,.mv-providers--broker .mv-field:has(.mv-pv-key){display:none;}
|
|
2639
|
+
.mv-broker-note{display:block;margin:6px 0 12px;}
|
|
2603
2640
|
|
|
2604
2641
|
/* About card rows. .about-val and .about-link share specificity on one anchor, so
|
|
2605
2642
|
.about-link must stay AFTER .about-val (test/ui-settings-about.test.mjs pins it). */
|
|
@@ -2640,6 +2677,9 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2640
2677
|
.pause-error-banner .peb-text{color:var(--ink);font-family:var(--mono);font-size:12px;word-break:break-word;}
|
|
2641
2678
|
.pause-error-banner .peb-hint{color:var(--ink-2);margin-top:6px;}
|
|
2642
2679
|
.hd-banners .pause-error-banner,.rd-banners .pause-error-banner{align-self:stretch;margin:0;}
|
|
2680
|
+
/* In a run card these banners are nested boxes (--r-ctrl); in the page-level banner
|
|
2681
|
+
stacks they sit on .retained-banner, so they take its card radius. */
|
|
2682
|
+
.hd-banners .cost-banner,.hd-banners .pause-error-banner,.rd-banners .cost-banner,.rd-banners .pause-error-banner{border-radius:var(--r-card);}
|
|
2643
2683
|
|
|
2644
2684
|
@media (max-width:1080px){
|
|
2645
2685
|
.stat-row{grid-template-columns:repeat(2,1fr);}
|
|
@@ -2724,6 +2764,9 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2724
2764
|
bridge's copy uses --ink-2 (6.5:1) so the theme proof passes without a new entry. */
|
|
2725
2765
|
.mv-providers .hint,.mv-conn .hint,.mv-degradation,.mvi .hint,.mv-cp-signin-box .hint{color:var(--ink-2);}
|
|
2726
2766
|
.mv-pv-row .input::placeholder,.mv-conn .input::placeholder,.mv-conn .textarea::placeholder{color:var(--ink-2);}
|
|
2767
|
+
/* Settings → Ask Worca → Web access: its fields are new, so their placeholders use --ink-2 like the rule
|
|
2768
|
+
above instead of joining the legacy light contrast baseline (the allowlist textarea failed at 2.58:1). */
|
|
2769
|
+
.ask-web .input::placeholder{color:var(--ink-2);}
|
|
2727
2770
|
.mv-providers .mv-providers-hint{margin:-6px 0 0;}
|
|
2728
2771
|
.mv-pv-row{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:12px 18px;padding:14px 0 0;border-top:1px solid var(--line-2);}
|
|
2729
2772
|
.mv-pv-main{display:grid;gap:6px;align-content:start;min-width:0;}
|
|
@@ -2782,12 +2825,12 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2782
2825
|
.mv-section-head{display:flex;align-items:center;gap:8px;}
|
|
2783
2826
|
.mv-sec-toggle{display:flex;align-items:center;gap:8px;padding:2px 0;border:0;background:transparent;cursor:pointer;color:inherit;font:inherit;}
|
|
2784
2827
|
.mv-sec-toggle .mv-section-title{margin:0;}
|
|
2785
|
-
.mv-sec-caret{
|
|
2828
|
+
.mv-sec-caret{flex:0 0 auto;transform:rotate(90deg);} /* .adv-chev: points right; a group is open unless folded */
|
|
2786
2829
|
.mv-sec-count{padding:1px 8px;border-radius:999px;background:var(--field);color:var(--ink-2);font:600 11px var(--mono);}
|
|
2787
|
-
.mv-section.is-folded .mv-sec-caret{transform:
|
|
2830
|
+
.mv-section.is-folded .mv-sec-caret{transform:none;}
|
|
2788
2831
|
.mv-section.is-folded .mv-sec-body,.mv-section.is-folded .mv-sec-hint{display:none;}
|
|
2789
2832
|
.mv-no-hits{margin-top:6px;}
|
|
2790
|
-
@media (prefers-reduced-motion: reduce){.mv-sec-caret{transition:none;}}
|
|
2833
|
+
@media (prefers-reduced-motion: reduce){.mv-sec-caret,.advanced .adv-chev{transition:none;}}
|
|
2791
2834
|
.mv-pv-btns .btn-ghost,.mv-pv-btns .btn-go{padding:7px 12px;font-size:12px;}
|
|
2792
2835
|
.mv-pv-row .input,.mv-pv-row .select{font-family:var(--mono);font-size:12.5px;padding:9px 12px;}
|
|
2793
2836
|
.mv-pv-row .mv-pv-conc{max-width:120px;}
|
|
@@ -2826,6 +2869,10 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2826
2869
|
.mv-conn-note{margin:0;}
|
|
2827
2870
|
.mvi-tbl{margin-top:8px;}
|
|
2828
2871
|
.mvi-tbl td{vertical-align:top;}
|
|
2872
|
+
/* A hosted catalog's filters (OpenRouter lists hundreds): the shared .chip-select pills, one row. */
|
|
2873
|
+
.mvi-or-filters{margin-top:10px;}
|
|
2874
|
+
.mvi-or-filters .mvi-f-ctx{padding:2px 6px;font-size:12.5px;min-height:0;}
|
|
2875
|
+
.mv-pv-presets{display:block;margin-top:4px;}
|
|
2829
2876
|
.mvi-tbl .mvi-id{display:block;margin:2px 0 0;font-family:var(--mono);}
|
|
2830
2877
|
.mvi-tbl tr.mvi-disabled{opacity:.55;}
|
|
2831
2878
|
.mvi-status{color:var(--ink-3);font-size:12px;}
|
|
@@ -2968,7 +3015,7 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
2968
3015
|
.hd-more:hover,.hd-more[aria-expanded="true"]{background:var(--field);border-color:var(--ink-3);}
|
|
2969
3016
|
.hd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:5;min-width:214px;
|
|
2970
3017
|
display:flex;flex-direction:column;gap:2px;padding:6px;background:var(--panel);
|
|
2971
|
-
border:1px solid var(--line-2);border-radius:
|
|
3018
|
+
border:1px solid var(--line-2);border-radius:var(--r-card);box-shadow:var(--shadow-menu);}
|
|
2972
3019
|
.hd-menu[hidden]{display:none;}
|
|
2973
3020
|
/* Both items shed their pill dressing in here and become full-width rows. Higher
|
|
2974
3021
|
specificity than the standalone rules above, which still hold nowhere else. */
|
|
@@ -3147,7 +3194,7 @@ button.tl-tile[aria-pressed="true"]{border-color:var(--ink);}
|
|
|
3147
3194
|
reply row draws its own elbow, exactly like `.nav-child` under Running. */
|
|
3148
3195
|
.hd-cmt-thread{position:relative;display:flex;flex-direction:column;max-width:720px;
|
|
3149
3196
|
animation:wr-rise .18s cubic-bezier(.2,.7,.3,1) both;}
|
|
3150
|
-
.hd-cmt-card{background:var(--surface);border:1px solid var(--line);border-radius:
|
|
3197
|
+
.hd-cmt-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow-soft);}
|
|
3151
3198
|
.hd-cmt-block>.hd-cmt-card{max-width:720px;}
|
|
3152
3199
|
.hd-cmt-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px 8px;min-height:20px;
|
|
3153
3200
|
padding:12px 14px 0;font-size:11px;color:var(--ink-2);}
|
|
@@ -3443,7 +3490,7 @@ button.hd-mem-chip:focus-visible{outline:2px solid var(--ink);outline-offset:2px
|
|
|
3443
3490
|
view's, and `.run-log .log` keeps its own sizes there (D7 — the Running view is
|
|
3444
3491
|
untouched). Neither rule sets `display`, so `.hd-sec[hidden]` (:1703) still hides
|
|
3445
3492
|
the whole panel and no `[hidden]` twin is needed. */
|
|
3446
|
-
.hd-sec-logs .log{background:var(--panel);border:1px solid var(--line);border-radius:
|
|
3493
|
+
.hd-sec-logs .log{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
|
|
3447
3494
|
min-height:260px;max-height:520px;overflow-y:auto;padding:18px 20px;}
|
|
3448
3495
|
.hd-sec-logs .log-filters{margin-bottom:10px;}
|
|
3449
3496
|
|
|
@@ -3481,7 +3528,7 @@ button.hd-mem-chip:focus-visible{outline:2px solid var(--ink);outline-offset:2px
|
|
|
3481
3528
|
.shipit-card h2{margin:18px 0 0;font:700 20px/1.25 var(--sans);letter-spacing:-.02em;}
|
|
3482
3529
|
.shipit-sub{margin:8px 0 0;font:400 13.5px/1.6 var(--sans);color:var(--ink-2);}
|
|
3483
3530
|
.shipit-summary{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:8px;
|
|
3484
|
-
margin-top:18px;padding:14px;background:var(--field);border-radius:
|
|
3531
|
+
margin-top:18px;padding:14px;background:var(--field);border-radius:var(--r-ctrl);font-size:12px;color:var(--ink-2);}
|
|
3485
3532
|
.shipit-summary[hidden]{display:none;}
|
|
3486
3533
|
/* An empty flex child still eats a `gap`, so a results-less run ("+12 −3", no file
|
|
3487
3534
|
count) would render a stray 8px hole. Hide the value spans by NAME — a blanket
|
|
@@ -3798,7 +3845,7 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
3798
3845
|
|
|
3799
3846
|
/* ---------- Running detail: pipeline graph ---------- */
|
|
3800
3847
|
/* The dot-grid panel spec §5.3 asks for is already `.run-flow-wrap` —
|
|
3801
|
-
radial-gradient var(--line-2) 1.1px at 22px 22px,
|
|
3848
|
+
radial-gradient var(--line-2) 1.1px at 22px 22px, --r-card radius, horizontal
|
|
3802
3849
|
scroll. This only supplies the margin box; the wrap's own legacy
|
|
3803
3850
|
`margin:0 0 18px` is zeroed so it does not double up with .rd-graph's. */
|
|
3804
3851
|
.rd-graph{margin-top:18px;}
|
|
@@ -3870,12 +3917,12 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
3870
3917
|
.rd-sec[hidden]{display:none;}
|
|
3871
3918
|
.rd-sec:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
|
|
3872
3919
|
|
|
3873
|
-
/* Live log tab (§5.6): white pane, --line border,
|
|
3920
|
+
/* Live log tab (§5.6): white pane, --line border, --r-card radius, bounded height.
|
|
3874
3921
|
The pane is the shared `.log` markup inside a `.run-log` block, so `.run-log .log`
|
|
3875
3922
|
is (0,2,0) and so is this — source order is what makes it win, which is why the
|
|
3876
3923
|
rule lives at the END of the file and must not be moved above it. */
|
|
3877
3924
|
.rd-sec-logs .log{min-height:300px;max-height:520px;
|
|
3878
|
-
background:var(--panel);border:1px solid var(--line);border-radius:
|
|
3925
|
+
background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);}
|
|
3879
3926
|
/* §9's fourth keyframe: the blinking green caret at the tail of a LIVE log.
|
|
3880
3927
|
CSS-only (a ::after on the pane) so no JS has to keep an element last after
|
|
3881
3928
|
every append; Task 9 stamps `.rd-terminal` on the screen when the run ends and
|
|
@@ -3984,7 +4031,7 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
3984
4031
|
.stop-card{padding:24px;animation:wr-rise .28s cubic-bezier(.2,.7,.3,1) both;}
|
|
3985
4032
|
.stop-title{margin:0 0 12px;font:700 17px/1.25 var(--sans);letter-spacing:-.015em;}
|
|
3986
4033
|
.stop-body{margin:0;font:400 13.5px/1.6 var(--sans);color:var(--ink-2);}
|
|
3987
|
-
.stop-ident{margin-top:14px;padding:11px 13px;background:var(--field);border-radius:
|
|
4034
|
+
.stop-ident{margin-top:14px;padding:11px 13px;background:var(--field);border-radius:var(--r-ctrl);
|
|
3988
4035
|
font:400 12px/1.6 var(--mono);color:var(--ink-2);word-break:break-all;}
|
|
3989
4036
|
/* author display rule beats the UA [hidden] rule — a branch-less run must not
|
|
3990
4037
|
leave a blank mono line in the block */
|
|
@@ -4363,7 +4410,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4363
4410
|
attribute from its ledger of rows the transcript has shown before, and on
|
|
4364
4411
|
nothing else. */
|
|
4365
4412
|
.ask-msg[data-ask-enter]{animation:wr-rise .2s cubic-bezier(.2,.7,.3,1) both;}
|
|
4366
|
-
.ask-user-bubble{align-self:flex-end;max-width:78%;padding:10px 14px;border-radius:
|
|
4413
|
+
.ask-user-bubble{align-self:flex-end;max-width:78%;padding:10px 14px;border-radius:var(--r-card) var(--r-card) 4px var(--r-card);
|
|
4367
4414
|
background:var(--field);color:var(--ink);font-size:13.5px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;}
|
|
4368
4415
|
.ask-user-pills{justify-content:flex-end;margin-top:0;}
|
|
4369
4416
|
.ask-attachment-pill{padding-right:12px;}
|
|
@@ -4461,7 +4508,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4461
4508
|
.ask-error-line{font-size:12.5px;color:var(--red-ink);}
|
|
4462
4509
|
|
|
4463
4510
|
.ask-card{margin-top:2px;display:flex;flex-direction:column;gap:10px;padding:13px 15px;
|
|
4464
|
-
border:1.5px solid var(--line);border-radius:
|
|
4511
|
+
border:1.5px solid var(--line);border-radius:var(--r-card);background:var(--panel);}
|
|
4465
4512
|
.ask-card-seg{display:flex;gap:4px;}
|
|
4466
4513
|
.ask-card-seg-btn{padding:5px 12px;border:1px solid var(--line-2);border-radius:999px;background:transparent;
|
|
4467
4514
|
color:var(--ink-2);font-family:inherit;font-weight:600;font-size:11px;cursor:pointer;transition:.15s;}
|
|
@@ -4493,7 +4540,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4493
4540
|
/* ---------- run proposal card v2 (ui/public/ask-panel.mjs buildCardForm; mockup 2026-09-06) ----------
|
|
4494
4541
|
The v1 card rules above still apply to this root (.ask-card); every override below
|
|
4495
4542
|
is written at higher specificity than the rule it replaces. Tokens only. */
|
|
4496
|
-
.ask-card.ask-rp{gap:0;padding:0;overflow:hidden;border-radius:
|
|
4543
|
+
.ask-card.ask-rp{gap:0;padding:0;overflow:hidden;border-radius:var(--r-card);border:1.5px solid var(--line-2);box-shadow:var(--shadow-soft);animation:wr-rise .26s cubic-bezier(.2,.7,.3,1) both;}
|
|
4497
4544
|
.ask-rp>*{min-width:0;}
|
|
4498
4545
|
.ask-rp-head{padding:16px 18px 14px;background:linear-gradient(180deg,var(--violet-wash),var(--panel) 92%);border-bottom:1px solid var(--line);}
|
|
4499
4546
|
.ask-rp-eyebrow{display:flex;align-items:center;gap:8px;height:20px;}
|
|
@@ -4523,7 +4570,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4523
4570
|
.ask-rp .ask-rp-title input:focus-visible{box-shadow:none;outline:none;border-bottom-color:var(--violet);background:transparent;}
|
|
4524
4571
|
.ask-rp-wfdesc{font-size:11.5px;color:var(--ink-3);}
|
|
4525
4572
|
.ask-rp-wfdesc b{font-weight:600;color:var(--ink-2);}
|
|
4526
|
-
.ask-rp-agents{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:
|
|
4573
|
+
.ask-rp-agents{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-ctrl);overflow:hidden;background:var(--canvas-2);}
|
|
4527
4574
|
.ask-rp-tile{display:flex;flex-direction:column;gap:8px;padding:10px 14px;border-top:1px solid var(--line);background:var(--panel);}
|
|
4528
4575
|
.ask-rp-tile:first-child{border-top:0;}
|
|
4529
4576
|
.ask-rp-tile.mod{background:var(--amber-wash);}
|
|
@@ -4572,7 +4619,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4572
4619
|
.ask-rp-foot .ask-card-start svg{width:11px;height:11px;}
|
|
4573
4620
|
.ask-rp .ask-card-err{padding:0 18px 10px;}
|
|
4574
4621
|
.ask-rp .ask-card-scope-warn{margin:12px 18px 0;}
|
|
4575
|
-
.ask-pop-at{width:288px;padding:6px;border-radius:
|
|
4622
|
+
.ask-pop-at{width:288px;padding:6px;border-radius:var(--r-card);max-height:min(320px,60%);overflow-y:auto;}
|
|
4576
4623
|
@media (max-width:640px){.ask-rp-grid,.ask-rp-grid.two{grid-template-columns:1fr;}}
|
|
4577
4624
|
@media (prefers-reduced-motion: reduce){.ask-card.ask-rp{animation:none;} .ask-rp *{transition:none!important;}}
|
|
4578
4625
|
|
|
@@ -4731,7 +4778,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4731
4778
|
the contrast baseline (scripts/verify-theme-cdp.mjs) it has today. */
|
|
4732
4779
|
.ask-composer{position:relative;flex:0 0 auto;padding:10px 16px 14px;display:flex;flex-direction:column;}
|
|
4733
4780
|
.ask-composer-box{width:100%;max-width:var(--ask-col-max);margin-inline:auto;padding:8px 10px;
|
|
4734
|
-
border:1px solid var(--line-2);border-radius:
|
|
4781
|
+
border:1px solid var(--line-2);border-radius:var(--r-card);background:var(--panel);
|
|
4735
4782
|
display:flex;flex-direction:column;gap:4px;}
|
|
4736
4783
|
.ask-chips{display:flex;flex-wrap:wrap;gap:6px;padding:2px 4px 4px;}
|
|
4737
4784
|
.ask-chips[hidden]{display:none;}
|
|
@@ -4776,19 +4823,19 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4776
4823
|
.ask-wt-btn[hidden]{display:none;}
|
|
4777
4824
|
|
|
4778
4825
|
.ask-pop{position:absolute;z-index:3;background:var(--panel);border:1px solid var(--line-2);
|
|
4779
|
-
padding:6px;box-shadow:var(--shadow-menu);border-radius:
|
|
4826
|
+
padding:6px;box-shadow:var(--shadow-menu);border-radius:var(--r-card);}
|
|
4780
4827
|
.ask-pop-threads{top:46px;right:76px;width:326px;}
|
|
4781
4828
|
/* The composer popovers hug the box (--ask-col-inset, see .ask-sheet) and float
|
|
4782
4829
|
just above it (--ask-box-top); agents/worktrees keep their old offsets left of
|
|
4783
4830
|
the model popover. */
|
|
4784
4831
|
.ask-pop-scope{left:var(--ask-col-inset);bottom:calc(var(--ask-box-top) + 6px);width:300px;max-height:min(420px,70%);overflow-y:auto;}
|
|
4785
|
-
.ask-pop-model{right:var(--ask-col-inset);bottom:calc(var(--ask-box-top) + 6px);width:292px;border-radius:
|
|
4832
|
+
.ask-pop-model{right:var(--ask-col-inset);bottom:calc(var(--ask-box-top) + 6px);width:292px;border-radius:var(--r-card);}
|
|
4786
4833
|
.ask-pop-runinfo{right:calc(var(--ask-col-inset) + 66px);bottom:calc(var(--ask-box-top) + 6px);width:326px;z-index:4;}
|
|
4787
4834
|
/* The chip picker (ask-panel.mjs openChipPicker) is the only JS-positioned panel: a band
|
|
4788
4835
|
chip sits wherever the transcript scrolled it. Its rows are the WHOLE model catalog, so
|
|
4789
4836
|
the menu outgrows the sheet, which clips -- the same cap .ask-pop-scope carries keeps
|
|
4790
4837
|
the Effort row reachable, and chipPickerTop() flips it above the chip when that fits. */
|
|
4791
|
-
.ask-pop-chip{width:288px;padding:6px;border-radius:
|
|
4838
|
+
.ask-pop-chip{width:288px;padding:6px;border-radius:var(--r-card);max-height:min(420px,70%);overflow-y:auto;}
|
|
4792
4839
|
.ask-pop-caption,.ask-pop-caption-row .ask-pop-caption{padding:8px 10px 6px;font-weight:600;font-size:10px;
|
|
4793
4840
|
letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}
|
|
4794
4841
|
.ask-pop-caption-row{display:flex;align-items:baseline;gap:8px;}
|
|
@@ -4817,6 +4864,7 @@ body.rail-collapsed .ask-dock{left:76px;}
|
|
|
4817
4864
|
border-radius:999px;white-space:nowrap;background:var(--field);color:var(--ink-3);}
|
|
4818
4865
|
.ask-model-tag.is-warn{flex:0 0 auto;max-width:none;background:var(--amber-bg);color:var(--amber-ink);}
|
|
4819
4866
|
.ask-model-tag.is-err{flex:0 0 auto;max-width:none;background:var(--red-bg);color:var(--red-ink);}
|
|
4867
|
+
.ask-model-tag.is-key{flex:0 0 auto;max-width:none;background:var(--green-bg);color:var(--green-ink);}
|
|
4820
4868
|
.ask-model-item .ask-model-name{flex:0 1 auto;min-width:4.5ch;overflow:hidden;text-overflow:ellipsis;
|
|
4821
4869
|
white-space:nowrap;}
|
|
4822
4870
|
/* The threads list is the only scrollport in a popover: /api/ask/threads returns up
|
|
@@ -5244,6 +5292,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
|
|
|
5244
5292
|
.ob-claude-cmd{margin:12px 0;padding:12px 14px;background:var(--field);border-radius:12px;overflow:auto;}
|
|
5245
5293
|
.ob-claude-cmd code{background:none;padding:0;font-size:12.5px;}
|
|
5246
5294
|
.ob-claude-note a{color:var(--blue-ink-strong);}
|
|
5295
|
+
.ob-claude-step{margin-top:16px;}
|
|
5247
5296
|
.ob-claude-status{min-height:18px;margin-top:12px;font-size:13px;line-height:1.45;}
|
|
5248
5297
|
.ob-claude-status.ok{color:var(--green-ink);}
|
|
5249
5298
|
.ob-claude-status.err{color:var(--red-ink);}
|
|
@@ -5270,14 +5319,14 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
|
|
|
5270
5319
|
.select-wrap.guide-lift::after{z-index:46;}
|
|
5271
5320
|
/* The ring never fades — it is the answer to "which control?". The pulse is a
|
|
5272
5321
|
halo radiating OUT of it, so the mark stays solid and the motion draws the eye. */
|
|
5273
|
-
.guide-ring{position:fixed;z-index:46;pointer-events:none;border:2.5px solid var(--violet);border-radius:
|
|
5322
|
+
.guide-ring{position:fixed;z-index:46;pointer-events:none;border:2.5px solid var(--violet);border-radius:calc(var(--r-ctrl) + 6px);
|
|
5274
5323
|
animation:guide-pulse 1.8s ease-out infinite;}
|
|
5275
5324
|
@keyframes guide-pulse{
|
|
5276
5325
|
0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--violet) 55%,transparent);}
|
|
5277
5326
|
100%{box-shadow:0 0 0 14px color-mix(in srgb,var(--violet) 0%,transparent);}
|
|
5278
5327
|
}
|
|
5279
5328
|
.guide-balloon{position:fixed;z-index:47;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
|
|
5280
|
-
max-width:300px;padding:11px 14px 10px;background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r-
|
|
5329
|
+
max-width:300px;padding:11px 14px 10px;background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r-card);
|
|
5281
5330
|
box-shadow:var(--shadow-pop);color:var(--ink);font-size:13px;line-height:1.45;}
|
|
5282
5331
|
.guide-balloon::before{content:'';position:absolute;top:-6px;left:calc(var(--arrow-x,20px) - 5px);width:10px;height:10px;
|
|
5283
5332
|
background:var(--panel);border-left:1px solid var(--line-2);border-top:1px solid var(--line-2);transform:rotate(45deg);}
|
|
@@ -5329,7 +5378,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
|
|
|
5329
5378
|
.btn-split > .btn-split-more:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
|
|
5330
5379
|
.btn-split > .btn-go:disabled,.btn-split > .btn-split-more:disabled{opacity:.45;cursor:not-allowed;transform:none;filter:none;}
|
|
5331
5380
|
.btn-split-menu{position:absolute;right:0;bottom:calc(100% + 8px);z-index:20;min-width:230px;padding:6px;
|
|
5332
|
-
background:var(--panel);border:1px solid var(--line);border-radius:
|
|
5381
|
+
background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow-menu);}
|
|
5333
5382
|
.btn-split-menu[hidden]{display:none;}
|
|
5334
5383
|
.btn-split-menu button{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;
|
|
5335
5384
|
background:transparent;border:none;border-radius:11px;padding:10px 12px;font-family:inherit;cursor:pointer;color:var(--ink);}
|
|
@@ -5516,7 +5565,7 @@ a.ask-card-task-title:hover{text-decoration-color:currentColor;}
|
|
|
5516
5565
|
|
|
5517
5566
|
/* Page-above-the-mode banner. */
|
|
5518
5567
|
.level-banner{display:flex;flex-wrap:wrap;align-items:center;gap:10px 12px;margin:0 0 18px;
|
|
5519
|
-
padding:10px 14px;border-radius:var(--r-
|
|
5568
|
+
padding:10px 14px;border-radius:var(--r-card);background:var(--canvas-2);border:1px solid var(--line-2);
|
|
5520
5569
|
font-size:13px;color:var(--ink-2);}
|
|
5521
5570
|
.level-banner[hidden]{display:none;}
|
|
5522
5571
|
.level-banner-text{flex:1 1 220px;min-width:0;}
|
|
@@ -5554,7 +5603,7 @@ body.view-workspaces .level-banner{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
5554
5603
|
.mode-sub{margin:0 0 16px;font-size:13px;line-height:1.55;color:var(--ink-2);}
|
|
5555
5604
|
.lv-cards{display:flex;flex-direction:column;gap:8px;}
|
|
5556
5605
|
.lv-card{display:grid;grid-template-columns:40px minmax(0,1fr) 20px;align-items:center;gap:14px;width:100%;
|
|
5557
|
-
padding:13px 15px;border:1.5px solid var(--line-2);border-radius:
|
|
5606
|
+
padding:13px 15px;border:1.5px solid var(--line-2);border-radius:var(--r-ctrl);background:var(--panel);color:var(--ink);
|
|
5558
5607
|
font:inherit;text-align:left;cursor:pointer;transition:border-color .15s,background .15s;}
|
|
5559
5608
|
.lv-card:hover{background:var(--field);}
|
|
5560
5609
|
.lv-card:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
|
|
@@ -5637,7 +5686,7 @@ body.view-workspaces .level-banner{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
5637
5686
|
.gv-wires path.ghost.legal{stroke:var(--green);stroke-dasharray:none;}
|
|
5638
5687
|
.gv-wires path.ghost.illegal{stroke:var(--red);}
|
|
5639
5688
|
.gv-world .node{position:absolute;left:0;top:0;display:block;padding:0;gap:0;align-items:stretch;z-index:2;
|
|
5640
|
-
width:var(--gv-node-w);background:var(--panel);border:var(--gv-border) solid var(--line-2);border-radius:calc(
|
|
5689
|
+
width:var(--gv-node-w);background:var(--panel);border:var(--gv-border) solid var(--line-2);border-radius:calc(14px * var(--gv-scale));
|
|
5641
5690
|
box-shadow:var(--shadow-soft);cursor:grab;transition:box-shadow .12s;}
|
|
5642
5691
|
.gv-world .node::before{content:none;}
|
|
5643
5692
|
.gv-world .node:hover{box-shadow:var(--shadow);}
|
|
@@ -5645,7 +5694,7 @@ body.view-workspaces .level-banner{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
5645
5694
|
.gv-world .node.dragging{cursor:grabbing;transition:none;}
|
|
5646
5695
|
.gv-static .node,.gv-static .wbadge{pointer-events:none;}
|
|
5647
5696
|
.gv-world .nhead{height:var(--gv-head-h);display:flex;align-items:center;gap:calc(8px * var(--gv-scale));padding:0 calc(11px * var(--gv-scale));
|
|
5648
|
-
border-radius:calc(
|
|
5697
|
+
border-radius:calc(12.5px * var(--gv-scale)) calc(12.5px * var(--gv-scale)) 0 0;font-size:max(9px,calc(13px * var(--gv-scale)));font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
5649
5698
|
.gv-world .nhead svg{width:calc(15px * var(--gv-scale));height:calc(15px * var(--gv-scale));flex:0 0 auto;stroke-width:1.85;}
|
|
5650
5699
|
.gv-world .nhead .tt{overflow:hidden;text-overflow:ellipsis;}
|
|
5651
5700
|
.gv-world .nhead .chip.rt{margin-left:auto;flex:0 0 auto;font:700 max(8px,calc(10px * var(--gv-scale)))/1.6 var(--mono);text-transform:none;white-space:nowrap;
|
|
@@ -5740,7 +5789,7 @@ body.view-workspaces .level-banner{margin:12px 32px 0;flex:0 0 auto;}
|
|
|
5740
5789
|
lines), and test/ui-graph-css.test.mjs asserts style.css uses the FULL --gv-*
|
|
5741
5790
|
set injectGeometry writes — dropping them fails that assertion. */
|
|
5742
5791
|
.gv-world .xfoot{position:absolute;left:0;right:0;bottom:0;border-top:1px solid var(--line);
|
|
5743
|
-
border-radius:0 0
|
|
5792
|
+
border-radius:0 0 12.5px 12.5px;overflow:hidden;background:var(--panel);}
|
|
5744
5793
|
.gv-world .xfoot>.fan,.gv-world .xfoot>.xtoggle,.gv-world .xfoot>.xresult,.gv-world .xfoot>.xlive{height:var(--gv-exec-row-h);
|
|
5745
5794
|
display:flex;align-items:center;gap:7px;padding:0 11px;width:100%;box-sizing:border-box;}
|
|
5746
5795
|
.gv-world .xfoot>:first-child{height:var(--gv-foot-h);} /* the first line is the tall one nodeSize bills */
|
|
@@ -6087,7 +6136,7 @@ input.gv-name:focus-visible{outline:none;}
|
|
|
6087
6136
|
.gv-archived .pl-chip:hover{border-color:var(--red);color:var(--red-ink);background:var(--red-bg);}
|
|
6088
6137
|
|
|
6089
6138
|
/* ---------- save dialog ---------- */
|
|
6090
|
-
.save-dialog{border:none;border-radius:
|
|
6139
|
+
.save-dialog{border:none;border-radius:var(--r-card);padding:0;box-shadow:var(--shadow);max-width:420px;width:92vw;}
|
|
6091
6140
|
.save-dialog::backdrop{background:var(--scrim-soft);}
|
|
6092
6141
|
.save-dialog .sd-body{padding:20px 22px 18px;display:flex;flex-direction:column;gap:14px;}
|
|
6093
6142
|
.save-dialog .sd-title{margin:0;font-size:16px;font-weight:700;letter-spacing:-.015em;}
|
|
@@ -6181,7 +6230,7 @@ input.gv-name:focus-visible{outline:none;}
|
|
|
6181
6230
|
/* History: node click drives the Logs tab */
|
|
6182
6231
|
.hd-graph.linked .gv-world .node[data-node-id]{cursor:pointer;}
|
|
6183
6232
|
/* quiescence banner (.rd-banners / .hd-banners / History Overview note) */
|
|
6184
|
-
.run-warn{margin:0;padding:11px 15px;border-radius:
|
|
6233
|
+
.run-warn{margin:0;padding:11px 15px;border-radius:var(--r-card);background:var(--amber-bg);color:var(--amber-ink);font-size:12.5px;font-weight:600;border:1px solid color-mix(in srgb, var(--amber) 45%, transparent);align-self:stretch;}
|
|
6185
6234
|
.run-warn[hidden]{display:none;}
|
|
6186
6235
|
/* gesture hint chip (D10) */
|
|
6187
6236
|
.rg-hint{position:absolute;left:12px;bottom:10px;padding:4px 9px;border-radius:999px;background:color-mix(in srgb, var(--ink) 72%, transparent);color:var(--on-ink);font-size:10.5px;font-weight:600;pointer-events:none;opacity:0;transition:opacity .15s;z-index:5;}
|
|
@@ -6472,7 +6521,7 @@ input.gv-name:focus-visible{outline:none;}
|
|
|
6472
6521
|
/* The catalog editor: one bordered item per set / model, its fields on a grid. */
|
|
6473
6522
|
.tp-cat-list{display:flex;flex-direction:column;gap:12px;}
|
|
6474
6523
|
.tp-cat-list:empty::before{content:'None yet.';color:var(--ink-3);font-size:12.5px;}
|
|
6475
|
-
.tp-cat-item{display:flex;flex-direction:column;gap:12px;padding:14px 16px;border:1px solid var(--line);border-radius:
|
|
6524
|
+
.tp-cat-item{display:flex;flex-direction:column;gap:12px;padding:14px 16px;border:1px solid var(--line);border-radius:var(--r-ctrl);background:var(--surface);}
|
|
6476
6525
|
.tp-cat-item-head{display:flex;align-items:center;gap:10px;font-size:13.5px;}
|
|
6477
6526
|
.tp-cat-item-head .tp-cat-rm{margin-left:auto;padding:5px 11px;font-size:12px;}
|
|
6478
6527
|
.tp-cat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px 14px;}
|
|
@@ -6534,7 +6583,7 @@ input.gv-name:focus-visible{outline:none;}
|
|
|
6534
6583
|
/* The pure editor's bar (team-policy-view.mjs): the page dismantles it into the header. */
|
|
6535
6584
|
.tp-publish-bar{display:flex;align-items:center;gap:12px;}
|
|
6536
6585
|
.tp-publish-bar .grow{flex:1;font-size:12.5px;color:var(--ink-2);}
|
|
6537
|
-
.tp-json{background:var(--panel);border:1px solid var(--line);border-radius:
|
|
6586
|
+
.tp-json{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:14px 16px;font-size:12px;line-height:1.5;overflow-x:auto;margin:0;}
|
|
6538
6587
|
.tp-msg{white-space:pre-wrap;}
|
|
6539
6588
|
@media (max-width:900px){ .tp-edit-row{grid-template-columns:1fr;} }
|
|
6540
6589
|
/* workspace card line (board 6) */
|
|
@@ -696,6 +696,7 @@ function valueControl(doc, meta, entry, row) {
|
|
|
696
696
|
case 'bool': {
|
|
697
697
|
const lab = h(doc, 'label', 'switch-row'); const cb = h(doc, 'input', 'sw-input tp-val'); cb.type = 'checkbox'; cb.checked = v === true;
|
|
698
698
|
cb.setAttribute('aria-label', meta.label);
|
|
699
|
+
if (meta.offOnly) cb.disabled = true; // a policy can only switch it off (registry: offOnly)
|
|
699
700
|
lab.append(cb, h(doc, 'span', 'switch switch-sm'), h(doc, 'span', 'txt', v === true ? 'on' : 'off'));
|
|
700
701
|
cb.addEventListener('change', () => { lab.querySelector('.txt').textContent = cb.checked ? 'on' : 'off'; });
|
|
701
702
|
wrap.append(lab); break;
|
|
@@ -713,7 +714,7 @@ function valueControl(doc, meta, entry, row) {
|
|
|
713
714
|
case 'string[]': {
|
|
714
715
|
writeItems(row, Array.isArray(v) ? v : []);
|
|
715
716
|
wrap.append(h(doc, 'div', 'tp-list'));
|
|
716
|
-
const add = h(doc, 'div', 'path-row tp-add-row'); const inp = h(doc, 'input', 'input tp-add'); inp.type = 'text'; inp.placeholder = meta.key === 'plugins.marketplaces' ? 'owner/repo or URL' : meta.key === 'models.allowed' ? 'model id' : 'plugin name';
|
|
717
|
+
const add = h(doc, 'div', 'path-row tp-add-row'); const inp = h(doc, 'input', 'input tp-add'); inp.type = 'text'; inp.placeholder = meta.key === 'plugins.marketplaces' ? 'owner/repo or URL' : meta.key === 'models.allowed' ? 'model id' : meta.key === 'ask.webAllowedDomains' ? 'example.com or *.example.com' : 'plugin name';
|
|
717
718
|
const b = h(doc, 'button', 'btn btn-ghost btn-mini tp-add-btn', '+ add'); b.type = 'button';
|
|
718
719
|
add.append(inp, b); wrap.append(add);
|
|
719
720
|
break;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ui/public/ws-seq.mjs
|
|
2
|
+
// A reconnect re-subscribes to a live run and the server replays that run's buffered events
|
|
3
|
+
// (ui/server.mjs replayEntry). Each buffered event carries a per-run `seq`; one this page has
|
|
4
|
+
// already applied is skipped, so a socket that drops (a proxy's idle timeout) never shows a
|
|
5
|
+
// log line twice. Frames without a seq (state snapshots, other channels) always apply.
|
|
6
|
+
// Pure: no DOM.
|
|
7
|
+
|
|
8
|
+
/** Whether `msg` was already applied to run `r`; records it when it was not. */
|
|
9
|
+
export function alreadyApplied(r, msg) {
|
|
10
|
+
const seq = msg && typeof msg.seq === 'number' ? msg.seq : null;
|
|
11
|
+
if (seq === null || !r) return false;
|
|
12
|
+
if (seq <= (r.lastSeq || 0)) return true;
|
|
13
|
+
r.lastSeq = seq;
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A restarted server numbers from 1 again: forget what was applied when its boot id changes. */
|
|
18
|
+
export function noteBoot(state, bootId, runsMap) {
|
|
19
|
+
if (!bootId) return;
|
|
20
|
+
if (state.serverBootId && state.serverBootId !== bootId) {
|
|
21
|
+
for (const r of runsMap.values()) r.lastSeq = 0;
|
|
22
|
+
}
|
|
23
|
+
state.serverBootId = bootId;
|
|
24
|
+
}
|