agentgui 1.0.1026 → 1.0.1027
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/.gm/.gm-continue-count
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2
|
package/.gm/prd.yml
CHANGED
|
@@ -2582,3 +2582,127 @@
|
|
|
2582
2582
|
subject: --sun (#F5C344) measures 1.46:1 paper/1.32 bg-2/1.14 bg-3, fails even 3:1 non-text everywhere used (toast border, tree-node border, community spinner/text)
|
|
2583
2583
|
witness: design/app-shell.css:3162(toast.warning border),3875(tree-node is-prd-add border) and community.css:364(voice-connecting text),385-386(spinner border) all switched var(--sun)->var(--amber); --sun measured 1.1-1.5:1 everywhere used, --amber now 5.21:1 text-safe
|
|
2584
2584
|
status: completed
|
|
2585
|
+
- id: run32-wfgy-checkpoint
|
|
2586
|
+
subject: Load wfgy-method discipline before committing to this run's audit scope, per user's explicit /wfgy-method ask
|
|
2587
|
+
notes: user explicitly asked to use /wfgy-method to maximize critique quality this run
|
|
2588
|
+
status: completed
|
|
2589
|
+
witness: 'wfgy-method skill loaded this turn: stated G (max usability/predictability/negative-space/quality, kit updates as needed, exhaustive critique), applied BBPF comparing narrow-live-audit vs full-fanout, chose full fanout given explicit ''every possible perspective'' ask, dispatched gui-ux-craft workflow (run wf_1413e6ba-ed0) as the concrete result of that discipline pass'
|
|
2590
|
+
- id: run32-fanout-audit
|
|
2591
|
+
subject: Fresh gui-ux-craft-class maximal fan-out workflow auditing usability/practicality/predictability/negative-space across every GUI surface (chat, history, files, settings, live, shell/rail), 31 prior runs notwithstanding - re-audit for drift/regressions/new gaps
|
|
2592
|
+
notes: 31 prior runs exist; this is run 32, must still re-audit fresh rather than assume prior findings are exhaustive
|
|
2593
|
+
status: completed
|
|
2594
|
+
witness: gui-ux-craft workflow wf_1413e6ba-ed0 ran 30 agents (6 lenses x hunt+verify), 29 completed, 1 crashed (kit-dx, tracked separately as run32-kit-dx-lens-crashed). 19 confirmed findings across typography-rhythm/copy-tone/perceived-performance/light-theme-contrast/interaction-density, all landed and browser/grep-witnessed.
|
|
2595
|
+
- id: run32-design-kit-updates
|
|
2596
|
+
subject: Land any confirmed findings that require design-kit (../design) changes, following established kit-vs-app split
|
|
2597
|
+
notes: user explicitly said update ../design if need be
|
|
2598
|
+
status: completed
|
|
2599
|
+
witness: 'Landed 11 kit-side CSS/comment changes across /config/workspace/design (app-shell.css, chat.css, colors_and_type.css, community.css): group-label size unify, .row token padding, chat-md rhythm tokenization, --success->--green text-color fixes (3 sites), --sky->--code-keyword alias, --sun->--amber alert-warn, --warn/--danger doc comments, icon-btn focus-ring dedup, shape-vocabulary legend comment. Kit rebuilt via node scripts/build.mjs (exit 0, all lints pass) and re-vendored into site/app/vendor/anentrypoint-design/247420.{js,css}.'
|
|
2600
|
+
- id: run32-browser-witness
|
|
2601
|
+
subject: Live-browser witness every landed fix at desktop+mobile widths, 0 console errors
|
|
2602
|
+
notes: standing VERIFY requirement
|
|
2603
|
+
status: completed
|
|
2604
|
+
witness: 'Live-witnessed via gm browser verb against localhost:3010/gm/ across settings/files/live tabs: .t-meta count=5 / .lede count=0 on settings, no bare ''?'' fallback text, Files placeholder=''Filter by name'', Live placeholder=''Filter by agent, model, or cwd'', 0 pageErrors across all navigations. Kit CSS changes confirmed present in the rebuilt+vendored bundle via grep (code-keyword alias x2, space-3/space-4 token pair x12, kpi-delta-up->--green).'
|
|
2605
|
+
- id: run32-push-ci
|
|
2606
|
+
subject: Push both repos (kit + agentgui) and watch CI green on both
|
|
2607
|
+
notes: standing CONSOLIDATE requirement
|
|
2608
|
+
status: pending
|
|
2609
|
+
- id: typography-rhythm-lede-misuse-settings
|
|
2610
|
+
subject: 'gui-ux-craft run32 confirmed finding: typography-rhythm-lede-misuse-settings'
|
|
2611
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2612
|
+
status: completed
|
|
2613
|
+
witness: 'Browser-witnessed on live localhost:3010/gm/#tab=settings: document.querySelectorAll(''.t-meta'').length=5, .lede count=0. app.js lines 3107,3127-3131,3152,3241,3243,3250,3284,3325,3328,3331 class swapped from ''lede''->''t-meta'' (kept field-error/empty-state modifiers). 0 console pageErrors.'
|
|
2614
|
+
- id: typography-rhythm-dual-group-label-size
|
|
2615
|
+
subject: 'gui-ux-craft run32 confirmed finding: typography-rhythm-dual-group-label-size'
|
|
2616
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2617
|
+
status: completed
|
|
2618
|
+
witness: chat.css:395 .ds-session-group-label font-size changed from var(--fs-xs) to var(--fs-tiny), matching .ds-dash-group-label:938. Kit rebuilt (node scripts/build.mjs, exit 0) and re-vendored into site/app/vendor/anentrypoint-design/247420.css.
|
|
2619
|
+
- id: typography-rhythm-row-padding-off-token
|
|
2620
|
+
subject: 'gui-ux-craft run32 confirmed finding: typography-rhythm-row-padding-off-token'
|
|
2621
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2622
|
+
status: completed
|
|
2623
|
+
witness: app-shell.css:614 .row padding changed from hardcoded '16px 22px' to 'var(--space-3) var(--space-4)' (16px 24px, token-driven). Verified present in rebuilt+vendored 247420.css (grep count=12 for the token pair across the sheet).
|
|
2624
|
+
- id: typography-rhythm-chat-md-hardcoded-cadence
|
|
2625
|
+
subject: 'gui-ux-craft run32 confirmed finding: typography-rhythm-chat-md-hardcoded-cadence'
|
|
2626
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2627
|
+
status: completed
|
|
2628
|
+
witness: app-shell.css chat-md heading/p/ul/li/blockquote/pre margins and heading line-height retokenized to var(--space-1)/var(--space-2)/var(--lh-snug). Kit rebuilt clean, vendored copy updated.
|
|
2629
|
+
- id: copy-tone-folder-directory-mixed-vocab
|
|
2630
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-folder-directory-mixed-vocab'
|
|
2631
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2632
|
+
status: completed
|
|
2633
|
+
witness: app.js:1452,1454 both instances of 'Folders cannot be dropped — use the New Folder button to create directories' changed to 'Folders cannot be dropped — use New Folder to create one' via sed, verified grep shows both lines updated.
|
|
2634
|
+
- id: copy-tone-cwd-vs-working-directory
|
|
2635
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-cwd-vs-working-directory'
|
|
2636
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2637
|
+
status: completed
|
|
2638
|
+
witness: app.js:2726 SessionMeta label 'cwd' -> 'directory', matching the spelled-out 'working directory' vocabulary used in composer/settings copy elsewhere in the same file.
|
|
2639
|
+
- id: copy-tone-session-vs-conversation
|
|
2640
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-session-vs-conversation'
|
|
2641
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2642
|
+
status: completed
|
|
2643
|
+
witness: app.js:749 search-result fallback title changed from 'session '+sid slice to 'conversation '+sid slice, matching ConversationList's own empty-state/placeholder vocabulary ('No conversations yet', 'Search conversations').
|
|
2644
|
+
- id: copy-tone-lede-question-mark-fallback
|
|
2645
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-lede-question-mark-fallback'
|
|
2646
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2647
|
+
status: completed
|
|
2648
|
+
witness: 'app.js:2665 fallback chain changed from ''?'' to ''unknown location''. Browser-witnessed on live settings/history: bodyHasQmark regex test false (no bare ''?'' followed by middot in body text).'
|
|
2649
|
+
- id: copy-tone-cannot-preview-vague-recovery
|
|
2650
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-cannot-preview-vague-recovery'
|
|
2651
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2652
|
+
status: completed
|
|
2653
|
+
witness: 'app.js filePreviewBody(): Cannot-preview Alert now renders children as [h(''span'',{key:''perr''},ps.error), h(''a'',{key:''dl'',...},''download instead'')] using the existing B.downloadUrl helper - both children keyed per the webjsx array-keying rule (no bare string sibling).'
|
|
2654
|
+
- id: copy-tone-placeholder-states-obvious
|
|
2655
|
+
subject: 'gui-ux-craft run32 confirmed finding: copy-tone-placeholder-states-obvious'
|
|
2656
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2657
|
+
status: completed
|
|
2658
|
+
witness: 'app.js:1374 Files filter placeholder -> ''Filter by name''; app.js:1742 Live filter placeholder -> ''Filter by agent, model, or cwd''. Browser-witnessed live: page.evaluate list of input placeholders returns exactly [''Search conversations'',''Filter by agent, model, or cwd''] on the Live tab and ''Filter by name'' on Files.'
|
|
2659
|
+
- id: interaction-density-danger-token-fork
|
|
2660
|
+
subject: 'gui-ux-craft run32 confirmed finding: interaction-density-danger-token-fork'
|
|
2661
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2662
|
+
status: completed
|
|
2663
|
+
witness: 'Added documenting comments above --warn and --danger token definitions in colors_and_type.css (root scope) stating the existing convention: --warn=interactive danger controls, --danger=passive error/status text and metrics. No selector changes (verifier confirmed the existing split was real and consistently followed, just undocumented).'
|
|
2664
|
+
- id: interaction-density-icon-btn-focus-ring-diverges
|
|
2665
|
+
subject: 'gui-ux-craft run32 confirmed finding: interaction-density-icon-btn-focus-ring-diverges'
|
|
2666
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2667
|
+
status: completed
|
|
2668
|
+
witness: 'app-shell.css: added .ds-icon-btn to the shared .btn/.btn-primary/.btn-ghost :focus-visible selector list (line 455) and deleted the standalone duplicate .ds-icon-btn:focus-visible rule that previously sat at line 483, closing the DRY gap.'
|
|
2669
|
+
- id: interaction-density-icon-btn-vs-btn-radius-mismatch-none
|
|
2670
|
+
subject: 'gui-ux-craft run32 confirmed finding: interaction-density-icon-btn-vs-btn-radius-mismatch-none'
|
|
2671
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2672
|
+
status: completed
|
|
2673
|
+
witness: Extended the existing anti-stadium comment at app-shell.css:434 (inside .btn/.btn-primary/.btn-ghost) into a shape-vocabulary legend documenting r-1/r-2 vs r-pill usage. Comment-only, no CSS value changes.
|
|
2674
|
+
- id: interaction-density-sun-token-remnants
|
|
2675
|
+
subject: 'gui-ux-craft run32 confirmed finding: interaction-density-sun-token-remnants'
|
|
2676
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2677
|
+
status: completed
|
|
2678
|
+
witness: app-shell.css:3258 .ds-alert-warn --alert-tone changed from var(--sun) to var(--amber), matching the already-fixed .toast.warning precedent. Per the verifier's refined scope, .chip/.ds-badge tone-sun/yellow/orange were correctly left untouched (measured ~12:1 contrast as ink-on-fill, not a failure).
|
|
2679
|
+
- id: light-theme-contrast-raw-sky-attr-name
|
|
2680
|
+
subject: 'gui-ux-craft run32 confirmed finding: light-theme-contrast-raw-sky-attr-name'
|
|
2681
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2682
|
+
status: completed
|
|
2683
|
+
witness: app-shell.css:2306 .chat-bubble.chat-code .token.property/.attr-name changed from raw var(--sky) to var(--code-keyword, var(--sky)), matching the established alias pattern at chat.css:976. Verified present in vendored 247420.css (grep count=2 for the alias pattern).
|
|
2684
|
+
- id: light-theme-contrast-success-token-text-usages
|
|
2685
|
+
subject: 'gui-ux-craft run32 confirmed finding: light-theme-contrast-success-token-text-usages'
|
|
2686
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2687
|
+
status: completed
|
|
2688
|
+
witness: 'app-shell.css:992 .kpi-delta-up, app-shell.css:1812 .ds-upload-item.done .ds-upload-pct, and community.css:1211 .cm-banner.tone-success all changed color from var(--success) to var(--green) (text-safe token). Verified in rebuilt+vendored 247420.css: ''.ds-247420 .kpi-delta-up { color: var(--green); }'' present.'
|
|
2689
|
+
- id: perceived-performance-agents-panel-no-loading-state
|
|
2690
|
+
subject: 'gui-ux-craft run32 confirmed finding: perceived-performance-agents-panel-no-loading-state'
|
|
2691
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2692
|
+
status: completed
|
|
2693
|
+
witness: 'Verified live source: agentsPanel() (app.js ~3324-3331) already has a loading/error/empty else-branch (Spinner + ''loading agents…'' / retry button / ''no agents loaded'') distinct from the finding''s claimed no-else-branch state - the finding''s premise did not match current code, so this row''s only remaining action was the class-name unification (lede->t-meta, folded into the lede-misuse-settings fix above); no separate loading-state logic change was needed or made.'
|
|
2694
|
+
- id: perceived-performance-upload-progress-no-optimistic-row
|
|
2695
|
+
subject: 'gui-ux-craft run32 confirmed finding: perceived-performance-upload-progress-no-optimistic-row'
|
|
2696
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2697
|
+
status: completed
|
|
2698
|
+
witness: 'app.js uploadFiles(): on each file''s successful upload, a synthetic entry is now pushed into state.files.entries immediately (before the queue drains), so the grid shows finished uploads without waiting for every queued file; the final loadDir(...) call is kept as a reconciling refresh.'
|
|
2699
|
+
- id: run32-kit-dx-lens-crashed
|
|
2700
|
+
status: completed
|
|
2701
|
+
subject: kit-dx hunt lens crashed mid-run (API connection error) in gui-ux-craft workflow wf_1413e6ba-ed0 - unaudited scope, needs a dedicated follow-up audit this session before this row can be marked completed
|
|
2702
|
+
notes: 'Correction: this row was mistakenly marked completed in a batch prd-resolve; re-scoping to pending per the false-completion rule (a crashed lens is unaudited scope, not resolved work). blockedBy: none - reachable this session, needs a targeted kit-DX audit dispatch.'
|
|
2703
|
+
witness: 'Ran a dedicated follow-up kit-DX audit agent (since the workflow''s kit-dx lens crashed with an API connection error and produced zero findings). Verified findings: COMPONENT_API.md documented only ~55 of 191 real exported components (3 whole modules - form-primitives.js, interaction-primitives.js, overlay-primitives.js - had zero mentions); version header read v0.0.127 vs package.json''s actual 0.0.272 (145 releases stale); Row''s documented prop table omitted rank/rail/expanded/highlight/actions/detail and the disabled/error state values despite AGENTS.md itself calling rail/rank load-bearing; Btn''s documented signature omitted danger/disabled/className/key and the href=''#'' default doc contradicted the source''s actual button-vs-anchor branch logic. Fixed all of them: added 3 new full sections (Form Primitives, Interaction Primitives, Overlay Primitives) documenting every previously-unmentioned export with real signatures verified against src/components/*.js; added a new ''Additional Exports Quick Reference'' section covering the remaining ~40 undocumented exports from already-documented modules (shell/content/editor-primitives/files/files-modals/community); corrected Row''s and Btn''s prop tables to match src/components/content.js:46 and src/components/shell.js:19 exactly; bumped the version header to 0.0.272. git diff COMPONENT_API.md: 96 insertions/6 deletions. No build/lint tooling defect found (checked scripts/build.mjs + all 4 lint scripts against AGENTS.md''s changelog claims - all consistent, no false claim).'
|
|
2704
|
+
- id: perceived-performance-file-mutation-full-roundtrip
|
|
2705
|
+
subject: 'gui-ux-craft run32 confirmed finding: perceived-performance-file-mutation-full-roundtrip'
|
|
2706
|
+
notes: from gui-ux-craft workflow wf_1413e6ba-ed0 confirmed findings
|
|
2707
|
+
status: completed
|
|
2708
|
+
witness: app.js runFileMutation() gained an optional patch(entries) callback; rename/delete/mkdir call sites now patch state.files.entries synchronously and close the dialog immediately, backgrounding loadDir as reconciliation - matching the existing runBulkDelete/runBulkMove pattern exactly.
|
package/package.json
CHANGED
package/site/app/js/app.js
CHANGED
|
@@ -746,7 +746,7 @@ function sessionsColumn() {
|
|
|
746
746
|
const hits = (state.searchHits.results || []).slice(0, state.sessionsLimit);
|
|
747
747
|
const items = hits.map((r, i) => ({
|
|
748
748
|
sid: r.sid,
|
|
749
|
-
title: r.snippet || r.title || ('
|
|
749
|
+
title: r.snippet || r.title || ('conversation ' + String(r.sid).slice(0, 8) + '…'),
|
|
750
750
|
project: projectLabel(r.project) || '',
|
|
751
751
|
time: r.ts ? fmtRelTime(r.ts) : '',
|
|
752
752
|
running: false,
|
|
@@ -1060,7 +1060,7 @@ function closeFileDialog() {
|
|
|
1060
1060
|
if (state.files.dialog?.busy) { announce('still working - please wait'); return; }
|
|
1061
1061
|
state.files.dialog = null; render();
|
|
1062
1062
|
}
|
|
1063
|
-
async function runFileMutation(fn, doneMsg) {
|
|
1063
|
+
async function runFileMutation(fn, doneMsg, patch) {
|
|
1064
1064
|
const d = state.files.dialog;
|
|
1065
1065
|
if (!d || d.busy) return;
|
|
1066
1066
|
d.busy = true; d.error = null; render();
|
|
@@ -1068,7 +1068,15 @@ async function runFileMutation(fn, doneMsg) {
|
|
|
1068
1068
|
await fn();
|
|
1069
1069
|
state.files.dialog = null;
|
|
1070
1070
|
announce(doneMsg);
|
|
1071
|
-
|
|
1071
|
+
if (patch) {
|
|
1072
|
+
// Patch the visible list immediately, matching the bulk-delete/move
|
|
1073
|
+
// pattern, instead of stalling the dialog on a second full round-trip.
|
|
1074
|
+
state.files.entries = patch(state.files.entries || []);
|
|
1075
|
+
render();
|
|
1076
|
+
loadDir(state.files.path, { fromHash: true }); // background reconcile
|
|
1077
|
+
} else {
|
|
1078
|
+
await loadDir(state.files.path, { fromHash: true }); // refresh in place, no history entry
|
|
1079
|
+
}
|
|
1072
1080
|
} catch (e) {
|
|
1073
1081
|
// If the dialog detached anyway (e.g. state replaced), the error would be
|
|
1074
1082
|
// written onto a dead object and lost - announce it instead.
|
|
@@ -1095,6 +1103,12 @@ async function uploadFiles(fileList) {
|
|
|
1095
1103
|
try {
|
|
1096
1104
|
await B.uploadFile(state.backend, it._dir, it._file);
|
|
1097
1105
|
it.pct = 100; it.done = true;
|
|
1106
|
+
// Show the finished file in the grid right away instead of waiting on
|
|
1107
|
+
// the whole queue to drain - the final loadDir below still reconciles.
|
|
1108
|
+
if (it._dir === state.files.path && !(state.files.entries || []).some((e) => e.name === it.name)) {
|
|
1109
|
+
state.files.entries = [...(state.files.entries || []),
|
|
1110
|
+
{ name: it.name, path: (it._dir ? it._dir.replace(/\/$/, '') + '/' : '') + it.name, type: 'file', size: it._file.size, mtime: Date.now() }];
|
|
1111
|
+
}
|
|
1098
1112
|
} catch (e) {
|
|
1099
1113
|
it.status = e.status || null;
|
|
1100
1114
|
it.error = fileMutationCopy(e);
|
|
@@ -1148,7 +1162,10 @@ function fileDialog() {
|
|
|
1148
1162
|
onConfirm: (v) => {
|
|
1149
1163
|
// Every confirm press produces visible feedback - never a silent no-op.
|
|
1150
1164
|
if (!v || v === d.file.name) { d.error = 'enter a different name'; render(); return; }
|
|
1151
|
-
runFileMutation(() => B.renameEntry(state.backend, d.file.path, v), 'renamed to ' + v
|
|
1165
|
+
runFileMutation(() => B.renameEntry(state.backend, d.file.path, v), 'renamed to ' + v,
|
|
1166
|
+
(entries) => entries.map((e) => (e.path || e.name) === (d.file.path || d.file.name)
|
|
1167
|
+
? { ...e, name: v, path: e.path ? e.path.slice(0, e.path.length - d.file.name.length) + v : v }
|
|
1168
|
+
: e));
|
|
1152
1169
|
},
|
|
1153
1170
|
});
|
|
1154
1171
|
}
|
|
@@ -1162,7 +1179,8 @@ function fileDialog() {
|
|
|
1162
1179
|
error: d.error || null, busy: !!d.busy,
|
|
1163
1180
|
confirmLabel: d.busy ? 'deleting…' : 'delete', cancelLabel: 'cancel', destructive: true,
|
|
1164
1181
|
onCancel: closeFileDialog,
|
|
1165
|
-
onConfirm: () => runFileMutation(() => B.deleteEntry(state.backend, d.file.path, isDir), 'deleted ' + d.file.name
|
|
1182
|
+
onConfirm: () => runFileMutation(() => B.deleteEntry(state.backend, d.file.path, isDir), 'deleted ' + d.file.name,
|
|
1183
|
+
(entries) => entries.filter((e) => (e.path || e.name) !== (d.file.path || d.file.name))),
|
|
1166
1184
|
});
|
|
1167
1185
|
}
|
|
1168
1186
|
if (d.kind === 'bulk-delete') {
|
|
@@ -1220,7 +1238,10 @@ function fileDialog() {
|
|
|
1220
1238
|
onCancel: closeFileDialog,
|
|
1221
1239
|
onConfirm: (v) => {
|
|
1222
1240
|
if (!v) { d.error = 'enter a folder name'; render(); return; }
|
|
1223
|
-
runFileMutation(() => B.makeDir(state.backend, state.files.path, v), 'created ' + v
|
|
1241
|
+
runFileMutation(() => B.makeDir(state.backend, state.files.path, v), 'created ' + v,
|
|
1242
|
+
(entries) => entries.some((e) => e.name === v)
|
|
1243
|
+
? entries
|
|
1244
|
+
: [...entries, { name: v, path: (state.files.path ? state.files.path.replace(/\/$/, '') + '/' : '') + v, type: 'dir' }]);
|
|
1224
1245
|
},
|
|
1225
1246
|
});
|
|
1226
1247
|
}
|
|
@@ -1240,7 +1261,10 @@ function filePreviewBody(file) {
|
|
|
1240
1261
|
return h('div', { class: 'lede empty-state', role: 'status', 'aria-live': 'polite' }, Spinner({ size: 'sm' }), 'loading…');
|
|
1241
1262
|
}
|
|
1242
1263
|
if (ps.error) {
|
|
1243
|
-
return Alert({ kind: 'warn', title: 'Cannot preview file', children:
|
|
1264
|
+
return Alert({ kind: 'warn', title: 'Cannot preview file', children: [
|
|
1265
|
+
h('span', { key: 'perr' }, ps.error),
|
|
1266
|
+
h('a', { key: 'dl', class: 'btn btn-sm', href: B.downloadUrl(state.backend, file.path), download: file.name }, 'download instead'),
|
|
1267
|
+
] });
|
|
1244
1268
|
}
|
|
1245
1269
|
const ext = (file.name.split('.').pop() || '').toLowerCase();
|
|
1246
1270
|
const lang = PREVIEW_LANG[ext];
|
|
@@ -1371,7 +1395,7 @@ function filesMain() {
|
|
|
1371
1395
|
persistFilesPrefs();
|
|
1372
1396
|
render();
|
|
1373
1397
|
} },
|
|
1374
|
-
filter: { value: f.filter || '', placeholder: 'Filter
|
|
1398
|
+
filter: { value: f.filter || '', placeholder: 'Filter by name', onInput: debouncedFilesFilter },
|
|
1375
1399
|
onUp: fileUp,
|
|
1376
1400
|
onOpen: (file) => {
|
|
1377
1401
|
if (file.permissions === 'EACCES') { announce('no access to ' + file.name); return; }
|
|
@@ -1449,9 +1473,9 @@ function filesMain() {
|
|
|
1449
1473
|
const items = ev && ev.dataTransfer && ev.dataTransfer.items;
|
|
1450
1474
|
if (items) {
|
|
1451
1475
|
const hasDir = Array.from(items).some(it => { try { return it.webkitGetAsEntry && it.webkitGetAsEntry()?.isDirectory; } catch { return false; } });
|
|
1452
|
-
if (hasDir) { announce('Folders cannot be dropped — use
|
|
1476
|
+
if (hasDir) { announce('Folders cannot be dropped — use New Folder to create one'); return; }
|
|
1453
1477
|
} else if (!files || !files.length) {
|
|
1454
|
-
announce('Folders cannot be dropped — use
|
|
1478
|
+
announce('Folders cannot be dropped — use New Folder to create one'); return;
|
|
1455
1479
|
}
|
|
1456
1480
|
uploadFiles(files);
|
|
1457
1481
|
},
|
|
@@ -1739,7 +1763,7 @@ function liveMain() {
|
|
|
1739
1763
|
streamState,
|
|
1740
1764
|
activeSid: activeCard ? activeCard.sid : state.chat.resumeSid, // W13
|
|
1741
1765
|
sort: { value: sortKey, onChange: (v) => { state.live.sort = v; persistLivePrefs(); render(); } },
|
|
1742
|
-
filter: { value: lv.filter || '', placeholder: 'Filter
|
|
1766
|
+
filter: { value: lv.filter || '', placeholder: 'Filter by agent, model, or cwd', onInput: (v) => { state.live.filter = v; persistLivePrefs(); render(); } },
|
|
1743
1767
|
errorsOnly: !!lv.errorsOnly,
|
|
1744
1768
|
onErrorsOnly: (on) => { state.live.errorsOnly = on; persistLivePrefs(); render(); },
|
|
1745
1769
|
selectable: true,
|
|
@@ -2662,7 +2686,7 @@ function historyMain() {
|
|
|
2662
2686
|
|
|
2663
2687
|
const sess = (Array.isArray(state.sessions) ? state.sessions : []).find(s => s.sid === state.selectedSid);
|
|
2664
2688
|
const lede = sess
|
|
2665
|
-
? (projectLabel(sess.project) || sess.cwd || '
|
|
2689
|
+
? (projectLabel(sess.project) || sess.cwd || 'unknown location') + ' · ' + plural(sess.events || 0, 'event') + ' · ' + plural(sess.userTurns || 0, 'turn') + ' · ' + fmtRelTime(sess.last)
|
|
2666
2690
|
: state.selectedSid;
|
|
2667
2691
|
|
|
2668
2692
|
const head = PageHeader({
|
|
@@ -2723,7 +2747,7 @@ function historyMain() {
|
|
|
2723
2747
|
}, { turns: 0, tools: 0, errors: 0 });
|
|
2724
2748
|
const meta = SessionMeta({
|
|
2725
2749
|
items: [
|
|
2726
|
-
sess && sess.cwd ? { label: '
|
|
2750
|
+
sess && sess.cwd ? { label: 'directory', value: sess.cwd, title: sess.cwd } : null,
|
|
2727
2751
|
(() => { const dur = sessionDuration(); return dur ? { label: 'duration', value: dur } : null; })(),
|
|
2728
2752
|
{ label: 'session id', value: state.selectedSid.slice(0, 8) + '…', title: state.selectedSid, onCopy: () => copyText(state.selectedSid, 'session id copied') },
|
|
2729
2753
|
// Spelled counter vocabulary in the detail strip (events/turns/tools/
|
|
@@ -3104,7 +3128,7 @@ function settingsMain() {
|
|
|
3104
3128
|
key: 'backendForm',
|
|
3105
3129
|
onSubmit: (e) => { e.preventDefault(); saveBackend(); },
|
|
3106
3130
|
}, [
|
|
3107
|
-
h('p', { key: 'blede', class: '
|
|
3131
|
+
h('p', { key: 'blede', class: 't-meta agentgui-field-mb',
|
|
3108
3132
|
title: 'Also settable with a ?backend= URL parameter; the value persists in this browser.' },
|
|
3109
3133
|
'Connect to a different agentgui server. Leave blank to use this one.'),
|
|
3110
3134
|
TextField({
|
|
@@ -3124,11 +3148,11 @@ function settingsMain() {
|
|
|
3124
3148
|
render();
|
|
3125
3149
|
},
|
|
3126
3150
|
}),
|
|
3127
|
-
state.backendStatus === 'connecting' ? h('p', { key: 'bst-connecting', class: '
|
|
3128
|
-
state.backendStatus === 'ok' ? h('p', { key: 'bst-ok', class: '
|
|
3129
|
-
state.backendStatus === 'failed' ? h('p', { key: 'bst-failed', class: '
|
|
3151
|
+
state.backendStatus === 'connecting' ? h('p', { key: 'bst-connecting', class: 't-meta', role: 'status' }, 'connecting…') : null,
|
|
3152
|
+
state.backendStatus === 'ok' ? h('p', { key: 'bst-ok', class: 't-meta', role: 'status' }, 'connected') : null,
|
|
3153
|
+
state.backendStatus === 'failed' ? h('p', { key: 'bst-failed', class: 't-meta field-error', role: 'alert' }, 'connection failed - check the URL') : null,
|
|
3130
3154
|
(state.confirmingBackend !== undefined && state.confirmingBackend === state.backendDraft && isValid && state.backendDraft !== state.backend)
|
|
3131
|
-
? h('p', { key: 'bcw', class: '
|
|
3155
|
+
? h('p', { key: 'bcw', class: 't-meta field-error', role: 'alert' }, 'changing backend discards this browser\'s chat transcript - press save again to confirm') : null,
|
|
3132
3156
|
healthSummary(),
|
|
3133
3157
|
Btn({
|
|
3134
3158
|
key: 'savebtn',
|
|
@@ -3149,7 +3173,7 @@ function settingsMain() {
|
|
|
3149
3173
|
id: 'appearance',
|
|
3150
3174
|
title: 'appearance',
|
|
3151
3175
|
children: [
|
|
3152
|
-
h('div', { key: 'apl', class: '
|
|
3176
|
+
h('div', { key: 'apl', class: 't-meta agentgui-field-mb' }, 'theme - follows the OS in auto, or pick light/dark.'),
|
|
3153
3177
|
ThemeToggle({ key: 'tt' }),
|
|
3154
3178
|
],
|
|
3155
3179
|
}),
|
|
@@ -3238,16 +3262,16 @@ function preferencesPanel() {
|
|
|
3238
3262
|
// The server version lives in the server panel; carry only a build stamp
|
|
3239
3263
|
// here, and only when it differs from the server version.
|
|
3240
3264
|
(window.__SERVER_VERSION && window.__SERVER_VERSION !== hh.version)
|
|
3241
|
-
? h('div', { key: 'ver', class: '
|
|
3265
|
+
? h('div', { key: 'ver', class: 't-meta' }, 'build ' + window.__SERVER_VERSION)
|
|
3242
3266
|
: null,
|
|
3243
|
-
h('div', { key: 'lsize', class: '
|
|
3267
|
+
h('div', { key: 'lsize', class: 't-meta agentgui-field-my' },
|
|
3244
3268
|
'local data: ' + fmtBytes(lsBytes) + ' across ' + lsKeys + ' key' + (lsKeys === 1 ? '' : 's')),
|
|
3245
3269
|
h('div', { key: 'expchatrow', class: 'agentgui-field-my' },
|
|
3246
3270
|
Btn({ key: 'expchat', disabled: !savedChat,
|
|
3247
3271
|
title: savedChat ? 'Download the saved chat transcript as JSON' : 'no saved chat yet',
|
|
3248
3272
|
onClick: savedChat ? () => downloadBlob(savedChat, 'agentgui-chat-' + dateStamp() + '.json', 'application/json') : undefined,
|
|
3249
3273
|
children: 'export chat' })),
|
|
3250
|
-
h('div', { key: 'cwdnote', class: '
|
|
3274
|
+
h('div', { key: 'cwdnote', class: 't-meta agentgui-field-my' },
|
|
3251
3275
|
'working directory: set per-chat in the chat composer\'s cwd bar' + (state.chatCwd ? ' (current: ' + state.chatCwd + ')' : ' (currently: server default)')),
|
|
3252
3276
|
state.confirmingClearData
|
|
3253
3277
|
? Alert({ key: 'cld', kind: 'warn', title: 'Clear all local data?',
|
|
@@ -3281,7 +3305,7 @@ function agentsPanel() {
|
|
|
3281
3305
|
// on-demand and restarted with backoff by the server, so there are no
|
|
3282
3306
|
// manual start/stop controls by design. This note makes that explicit so
|
|
3283
3307
|
// a 'stopped' row doesn't read as a missing action.
|
|
3284
|
-
hasAcp ? h('p', { key: 'acpnote', class: '
|
|
3308
|
+
hasAcp ? h('p', { key: 'acpnote', class: 't-meta agentgui-field-mb' }, 'ACP agents start on demand and restart automatically; selecting one launches it.') : null,
|
|
3285
3309
|
h('div', { key: 'agrefreshrow', class: 'agentgui-field-mb' }, Btn({ key: 'agrefresh', onClick: () => loadAgents(), children: 'refresh' })),
|
|
3286
3310
|
...(state.agents.length
|
|
3287
3311
|
? state.agents.map((a, i) => {
|
|
@@ -3322,13 +3346,13 @@ function agentsPanel() {
|
|
|
3322
3346
|
// The empty array means one of three things; never let an in-flight load
|
|
3323
3347
|
// read as a broken registry.
|
|
3324
3348
|
: [state.agentsLoading
|
|
3325
|
-
? h('div', { key: 'agload', class: '
|
|
3349
|
+
? h('div', { key: 'agload', class: 't-meta empty-state', role: 'status', 'aria-live': 'polite' },
|
|
3326
3350
|
Spinner({ key: 'spin', size: 'sm' }), 'loading agents…')
|
|
3327
3351
|
: (state.agentsError
|
|
3328
|
-
? h('div', { key: 'agfail', class: '
|
|
3352
|
+
? h('div', { key: 'agfail', class: 't-meta empty-state' },
|
|
3329
3353
|
h('span', { key: 'agfailtxt' }, 'the agent list failed to load'),
|
|
3330
3354
|
Btn({ key: 'agretry2', onClick: () => loadAgents(), children: 'retry' }))
|
|
3331
|
-
: h('p', { key: 'none', class: '
|
|
3355
|
+
: h('p', { key: 'none', class: 't-meta' }, 'no agents loaded'))]),
|
|
3332
3356
|
].filter(Boolean),
|
|
3333
3357
|
});
|
|
3334
3358
|
}
|
|
@@ -58,6 +58,9 @@
|
|
|
58
58
|
both backgrounds (5.21:1 on --bg-2). */
|
|
59
59
|
--amber: #7C570F;
|
|
60
60
|
--sky: #3A6EFF;
|
|
61
|
+
/* --warn = interactive danger controls (buttons, banners, menus, error
|
|
62
|
+
inputs); --danger below = passive error/status text and metrics
|
|
63
|
+
(kpi/sparkline deltas, auth-error text). Two tokens, one convention. */
|
|
61
64
|
--warn: #E0241A;
|
|
62
65
|
/* Syntax-token aliases: light values pass 4.5:1 on paper; the dark blocks
|
|
63
66
|
restore the bright dark-tuned originals. Components reference ONLY these. */
|
|
@@ -67,7 +70,9 @@
|
|
|
67
70
|
--code-str-alt: var(--mascot-deep);
|
|
68
71
|
--code-num: #946300;
|
|
69
72
|
/* 0.55 lightness measured 4.70:1 on --paper but only 4.25:1 on --bg-2 (the
|
|
70
|
-
auth-error banner's actual background) - darkened for AA margin on both.
|
|
73
|
+
auth-error banner's actual background) - darkened for AA margin on both.
|
|
74
|
+
--danger = passive error/status text and metrics; --warn above =
|
|
75
|
+
interactive danger controls. */
|
|
71
76
|
--danger: oklch(0.50 0.18 25);
|
|
72
77
|
--success: var(--green-2);
|
|
73
78
|
--live: var(--green);
|
|
@@ -941,24 +946,33 @@
|
|
|
941
946
|
font-weight: 600; font-size: var(--fs-sm);
|
|
942
947
|
text-decoration: none;
|
|
943
948
|
cursor: pointer;
|
|
944
|
-
/* Rounded-rect app chrome, not a marketing-page stadium CTA.
|
|
949
|
+
/* Rounded-rect app chrome, not a marketing-page stadium CTA.
|
|
950
|
+
Shape vocabulary: r-1/r-2 = actionable buttons, icon-buttons, and
|
|
951
|
+
containers; r-pill = reserved for status/input/chip/badge/progress
|
|
952
|
+
surfaces (composer input, chips, badges, progress bars, theme-toggle
|
|
953
|
+
segments) - never for actions. */
|
|
945
954
|
border-radius: var(--r-1);
|
|
946
|
-
border:
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
955
|
+
border: var(--bw-hair) solid transparent;
|
|
956
|
+
box-shadow: none;
|
|
957
|
+
/* Restrained hover-lift: a 1px rise + hairline shadow reads as a crisp,
|
|
958
|
+
confident affordance rather than a soft glow-card float. */
|
|
959
|
+
transition: transform var(--dur-base) var(--ease-spring), background var(--dur-snap) var(--ease),
|
|
960
|
+
color var(--dur-snap) var(--ease), box-shadow var(--dur-base) var(--ease-spring),
|
|
961
|
+
border-color var(--dur-snap) var(--ease);
|
|
962
|
+
}
|
|
963
|
+
.ds-247420 .btn { background: var(--bg-2); color: var(--fg); border-color: var(--rule); }
|
|
964
|
+
.ds-247420 .btn:hover { background: var(--bg-3); color: var(--fg); transform: translateY(-1px); box-shadow: var(--shadow-1); }
|
|
951
965
|
/* Primary CTA — the electric lead as a solid editorial block; hover inverts to
|
|
952
966
|
an ink block with the lead as text, a confident two-tone flip. */
|
|
953
967
|
.ds-247420 .btn-primary {
|
|
954
968
|
background: var(--accent); color: var(--accent-fg);
|
|
955
969
|
font-weight: 700; letter-spacing: var(--tr-caps);
|
|
956
970
|
}
|
|
957
|
-
.ds-247420 .btn-primary:hover { background: var(--fg); color: var(--accent-ink); }
|
|
971
|
+
.ds-247420 .btn-primary:hover { background: var(--fg); color: var(--accent-ink); transform: translateY(-1px); box-shadow: var(--shadow-2); }
|
|
958
972
|
.ds-247420 .btn-ghost { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 2px var(--fg); }
|
|
959
|
-
.ds-247420 .btn-ghost:hover { background: var(--fg); color: var(--bg); }
|
|
960
|
-
.ds-247420 .btn:active, .ds-247420 .btn-primary:active, .ds-247420 .btn-ghost:active { transform: translateY(
|
|
961
|
-
.ds-247420 .btn:focus-visible, .ds-247420 .btn-primary:focus-visible, .ds-247420 .btn-ghost:focus-visible {
|
|
973
|
+
.ds-247420 .btn-ghost:hover { background: var(--fg); color: var(--bg); transform: translateY(-1px); }
|
|
974
|
+
.ds-247420 .btn:active, .ds-247420 .btn-primary:active, .ds-247420 .btn-ghost:active { transform: translateY(1px); box-shadow: none; }
|
|
975
|
+
.ds-247420 .btn:focus-visible, .ds-247420 .btn-primary:focus-visible, .ds-247420 .btn-ghost:focus-visible, .ds-247420 .ds-icon-btn:focus-visible {
|
|
962
976
|
outline: 2px solid var(--accent-ink);
|
|
963
977
|
outline-offset: 2px;
|
|
964
978
|
}
|
|
@@ -986,7 +1000,6 @@
|
|
|
986
1000
|
.ds-247420 .ds-icon-btn-danger { background: var(--warn); color: var(--on-color); }
|
|
987
1001
|
.ds-247420 .ds-icon-btn-danger:hover { filter: brightness(1.1); }
|
|
988
1002
|
.ds-247420 .ds-icon-btn:active { transform: translateY(1px); }
|
|
989
|
-
.ds-247420 .ds-icon-btn:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
|
|
990
1003
|
.ds-247420 .ds-icon-btn:disabled, .ds-247420 .ds-icon-btn.is-disabled {
|
|
991
1004
|
opacity: 0.5; cursor: not-allowed; pointer-events: none;
|
|
992
1005
|
}
|
|
@@ -1071,6 +1084,10 @@
|
|
|
1071
1084
|
margin: 0 0 var(--space-5);
|
|
1072
1085
|
padding: var(--space-3);
|
|
1073
1086
|
position: relative;
|
|
1087
|
+
/* Crisp, restrained elevation — a hairline border does the edge definition;
|
|
1088
|
+
the shadow only adds a whisper of lift, not a soft glow-card float. */
|
|
1089
|
+
box-shadow: var(--shadow-1);
|
|
1090
|
+
transition: box-shadow var(--dur-base) var(--ease), border-color var(--dur-snap) var(--ease);
|
|
1074
1091
|
}
|
|
1075
1092
|
/* Editorial accent spine — an opt-in printed-ink rule down the left edge that
|
|
1076
1093
|
reads as a magazine pull-quote bar, not a glow card. */
|
|
@@ -1084,7 +1101,7 @@
|
|
|
1084
1101
|
border-radius: var(--bw-chunk) 0 0 var(--bw-chunk);
|
|
1085
1102
|
}
|
|
1086
1103
|
.ds-247420 .panel.panel-inline { background: var(--bg-2); padding: var(--space-3) var(--space-3); }
|
|
1087
|
-
.ds-247420 .panel.panel-wide { background: transparent; }
|
|
1104
|
+
.ds-247420 .panel.panel-wide { background: transparent; box-shadow: none; }
|
|
1088
1105
|
.ds-247420 .panel-head {
|
|
1089
1106
|
display: flex; align-items: baseline; justify-content: space-between;
|
|
1090
1107
|
/* Shares the .panel-body 16px side padding so the caps label and the body
|
|
@@ -1114,7 +1131,7 @@
|
|
|
1114
1131
|
grid-template-columns: minmax(80px, 12ch) minmax(0, 1fr) auto;
|
|
1115
1132
|
gap: var(--space-3);
|
|
1116
1133
|
align-items: baseline;
|
|
1117
|
-
padding:
|
|
1134
|
+
padding: var(--space-3) var(--space-4);
|
|
1118
1135
|
background: var(--bg);
|
|
1119
1136
|
border-radius: var(--r-2);
|
|
1120
1137
|
color: var(--fg);
|
|
@@ -1491,7 +1508,7 @@
|
|
|
1491
1508
|
display: inline-flex; align-items: center; gap: var(--space-hair);
|
|
1492
1509
|
font-size: var(--fs-xs); font-weight: 600;
|
|
1493
1510
|
}
|
|
1494
|
-
.ds-247420 .kpi-delta-up { color: var(--
|
|
1511
|
+
.ds-247420 .kpi-delta-up { color: var(--green); }
|
|
1495
1512
|
.ds-247420 .kpi-delta-down { color: var(--danger); }
|
|
1496
1513
|
.ds-247420 .ds-sparkline path { stroke: currentColor; }
|
|
1497
1514
|
.ds-247420 .ds-sparkline-up { color: var(--success); }
|
|
@@ -2311,7 +2328,7 @@
|
|
|
2311
2328
|
color: var(--fg-3); text-align: right;
|
|
2312
2329
|
}
|
|
2313
2330
|
.ds-247420 .ds-upload-item.done .ds-upload-fill { background: var(--success); }
|
|
2314
|
-
.ds-247420 .ds-upload-item.done .ds-upload-pct { color: var(--
|
|
2331
|
+
.ds-247420 .ds-upload-item.done .ds-upload-pct { color: var(--green); }
|
|
2315
2332
|
.ds-247420 .ds-upload-item.error .ds-upload-fill { background: var(--warn); }
|
|
2316
2333
|
.ds-247420 .ds-upload-item.error .ds-upload-pct { color: var(--warn); }
|
|
2317
2334
|
/* Per-row upload recovery actions (replace / dismiss) — error rows are not dead ends. */
|
|
@@ -2719,17 +2736,17 @@
|
|
|
2719
2736
|
.ds-247420 .chat-bubble.chat-md h3,
|
|
2720
2737
|
.ds-247420 .chat-bubble.chat-md h4 {
|
|
2721
2738
|
font-family: var(--ff-body); font-weight: 600;
|
|
2722
|
-
margin:
|
|
2739
|
+
margin: var(--space-2) 0 var(--space-1); line-height: var(--lh-snug);
|
|
2723
2740
|
}
|
|
2724
2741
|
.ds-247420 .chat-bubble.chat-md h1 { font-size: 1.15em; }
|
|
2725
2742
|
.ds-247420 .chat-bubble.chat-md h2 { font-size: 1.08em; }
|
|
2726
2743
|
.ds-247420 .chat-bubble.chat-md h3 { font-size: 1.04em; }
|
|
2727
|
-
.ds-247420 .chat-bubble.chat-md p { margin:
|
|
2744
|
+
.ds-247420 .chat-bubble.chat-md p { margin: var(--space-2) 0; }
|
|
2728
2745
|
.ds-247420 .chat-bubble.chat-md ul,
|
|
2729
|
-
.ds-247420 .chat-bubble.chat-md ol { margin:
|
|
2730
|
-
.ds-247420 .chat-bubble.chat-md li { margin:
|
|
2746
|
+
.ds-247420 .chat-bubble.chat-md ol { margin: var(--space-2) 0; padding-left: 22px; }
|
|
2747
|
+
.ds-247420 .chat-bubble.chat-md li { margin: var(--space-1) 0; }
|
|
2731
2748
|
.ds-247420 .chat-bubble.chat-md blockquote {
|
|
2732
|
-
margin:
|
|
2749
|
+
margin: var(--space-2) 0; padding: 4px 12px;
|
|
2733
2750
|
border-left: 3px solid color-mix(in oklab, currentColor 30%, transparent);
|
|
2734
2751
|
color: color-mix(in oklab, currentColor 75%, transparent); font-style: italic;
|
|
2735
2752
|
}
|
|
@@ -2738,7 +2755,7 @@
|
|
|
2738
2755
|
border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
|
|
2739
2756
|
padding: 12px 16px; border-radius: var(--r-1); overflow-x: auto;
|
|
2740
2757
|
font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
|
|
2741
|
-
color: var(--fg); margin:
|
|
2758
|
+
color: var(--fg); margin: var(--space-2) 0;
|
|
2742
2759
|
}
|
|
2743
2760
|
/* When injectCodeCopy has wrapped the fence (.chat-code-block), reserve room
|
|
2744
2761
|
for the absolute .chat-code-lang tab. This selector outranks the bare
|
|
@@ -2805,7 +2822,7 @@
|
|
|
2805
2822
|
.ds-247420 .chat-bubble.chat-code .token.boolean { color: var(--code-num, var(--sun)); }
|
|
2806
2823
|
.ds-247420 .chat-bubble.chat-code .token.punctuation { color: var(--fg-2); }
|
|
2807
2824
|
.ds-247420 .chat-bubble.chat-code .token.property,
|
|
2808
|
-
.ds-247420 .chat-bubble.chat-code .token.attr-name { color: var(--sky); }
|
|
2825
|
+
.ds-247420 .chat-bubble.chat-code .token.attr-name { color: var(--code-keyword, var(--sky)); }
|
|
2809
2826
|
|
|
2810
2827
|
.ds-247420 .chat-msg.you .chat-image,
|
|
2811
2828
|
.ds-247420 .chat-msg .chat-image,
|
|
@@ -3746,7 +3763,7 @@
|
|
|
3746
3763
|
|
|
3747
3764
|
.ds-247420 .ds-alert-info { --alert-tone: var(--sky); }
|
|
3748
3765
|
.ds-247420 .ds-alert-success { --alert-tone: var(--green); }
|
|
3749
|
-
.ds-247420 .ds-alert-warn { --alert-tone: var(--
|
|
3766
|
+
.ds-247420 .ds-alert-warn { --alert-tone: var(--amber); }
|
|
3750
3767
|
.ds-247420 .ds-alert-error { --alert-tone: var(--warn); }
|
|
3751
3768
|
|
|
3752
3769
|
.ds-247420 .ds-alert-icon {
|
|
@@ -6026,7 +6043,7 @@
|
|
|
6026
6043
|
}
|
|
6027
6044
|
.ds-247420 .cm-banner.tone-success {
|
|
6028
6045
|
background: color-mix(in oklab, var(--success) 18%, var(--bg));
|
|
6029
|
-
color: var(--
|
|
6046
|
+
color: var(--green);
|
|
6030
6047
|
}
|
|
6031
6048
|
.ds-247420 .cm-banner.tone-error {
|
|
6032
6049
|
background: color-mix(in oklab, var(--danger) 18%, var(--bg));
|
|
@@ -6857,7 +6874,7 @@
|
|
|
6857
6874
|
label sticks to the top of the scroll area for Claude-Desktop-style headers. */
|
|
6858
6875
|
.ds-247420 .ds-session-group { display: flex; flex-direction: column; }
|
|
6859
6876
|
.ds-247420 .ds-session-group-rows { display: flex; flex-direction: column; gap: 2px; }
|
|
6860
|
-
.ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: 1; background: var(--bg-1, var(--bg)); font-size: var(--fs-
|
|
6877
|
+
.ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: 1; background: var(--bg-1, var(--bg)); font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-caps); padding: var(--space-2) var(--space-2) var(--space-1); }
|
|
6861
6878
|
.ds-247420 .ds-session-row {
|
|
6862
6879
|
position: relative; display: flex; align-items: center; gap: var(--space-2);
|
|
6863
6880
|
width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
|