agentgui 1.0.969 → 1.0.970

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.
@@ -23,246 +23,11 @@
23
23
  <link rel="modulepreload" href="./js/backend.js">
24
24
  <link rel="modulepreload" href="./js/codec.js">
25
25
  <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
26
- <style>
27
- :root {
28
- --agentgui-bg: #16161a;
29
- --agentgui-fg: #e6e6ea;
30
- --agentgui-accent: #50c878;
31
- --agentgui-warn: #ff6b6b;
32
- /* status-dot state colours, brightened for >=3:1 contrast on the dark bg */
33
- --agentgui-status-connecting: #f0b84a;
34
- --agentgui-status-offline: #e06b66;
35
- /* unified muted text fallback (was an inconsistent mix of #888/#999) */
36
- --agentgui-muted: #8a8f98;
37
- }
38
-
39
- /* visually-hidden but screen-reader-available (aria-live announcer, labels) */
40
- .sr-only {
41
- position: absolute !important; width: 1px; height: 1px;
42
- padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
43
- white-space: nowrap; border: 0;
44
- }
45
- html, body {
46
- margin: 0;
47
- height: 100%;
48
- background: var(--bg, var(--agentgui-bg));
49
- color: var(--fg, var(--agentgui-fg));
50
- /* The DS exposes --ff-display / --ff-mono (there is no --font-sans), so the
51
- old reference fell through to the system font. Use the DS display face. */
52
- font-family: var(--ff-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
53
- }
54
- #app { height: 100vh; height: 100dvh; }
55
- #app > * { height: 100%; }
56
-
57
- /* Themed thin scrollbars - the native chrome scrollbar is chunky/light and
58
- clashes with the dark theme on the history sidebar and settings column. */
59
- * {
60
- scrollbar-width: thin;
61
- scrollbar-color: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 22%, transparent) transparent;
62
- }
63
- *::-webkit-scrollbar { width: 9px; height: 9px; }
64
- *::-webkit-scrollbar-track { background: transparent; }
65
- *::-webkit-scrollbar-thumb {
66
- background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 20%, transparent);
67
- border-radius: 999px;
68
- border: 2px solid transparent;
69
- background-clip: padding-box;
70
- }
71
- *::-webkit-scrollbar-thumb:hover {
72
- background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 34%, transparent);
73
- background-clip: padding-box;
74
- }
75
-
76
- /* We move focus to the page heading on tab change for AT users; suppress the
77
- resulting green outline box on those programmatically-focused elements.
78
- !important + .ds-247420 prefix to beat the runtime-injected DS focus rule. */
79
- .ds-247420 [data-prog-focus]:focus,
80
- .ds-247420 [data-prog-focus]:focus-visible,
81
- [data-prog-focus]:focus, [data-prog-focus]:focus-visible { outline: none !important; box-shadow: none !important; }
82
-
83
- /* (The skip link is rendered + styled by the design system's AppShell;
84
- agentgui carries no local .skip-link rule.) */
85
-
86
- /* The connection dot's disc + pulse are the KIT's canonical .status-dot-disc
87
- (status-dot-live / -connecting / -error) - the app no longer overrides
88
- them. Only the inline-flex wrapper layout for the crumb stays local since
89
- the kit defines the disc, not this wrapper element. */
90
- .status-dot { display: inline-flex; align-items: center; gap: .4em; white-space: nowrap; }
91
-
92
- /* resume banner */
93
- .resume-banner {
94
- padding: .6em .8em;
95
- background: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 12%, transparent);
96
- border: 1px solid color-mix(in srgb, var(--accent, var(--agentgui-accent)) 30%, transparent);
97
- border-radius: 8px;
98
- display: flex; justify-content: space-between; align-items: center; gap: .75em;
99
- margin-bottom: .75em;
100
- }
101
-
102
- /* history action buttons */
103
- .history-actions { display: flex; gap: .5em; padding: 0 0 .75em 0; flex-wrap: wrap; }
104
-
105
- /* empty / loading state */
106
- .empty-state { display: flex; gap: 8px; align-items: center; padding: .5em 0; }
107
-
108
- /* project filter pills */
109
- .pill-row { display: flex; flex-wrap: wrap; gap: .35em; padding: .35em 0; }
110
- .pill {
111
- cursor: pointer; padding: .25em .7em; border-radius: 999px;
112
- border: 1px solid transparent; background: transparent;
113
- font: inherit; color: inherit; line-height: 1.4;
114
- transition: background-color .15s ease, border-color .15s ease;
115
- min-height: 28px;
116
- }
117
- .pill:hover { background: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 10%, transparent); }
118
- .pill.pill-active {
119
- background: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 18%, transparent);
120
- border-color: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 40%, transparent);
121
- }
122
- .pill:focus-visible { outline: 2px solid var(--accent, var(--agentgui-accent)); outline-offset: 2px; }
123
-
124
- /* subagent toggle (the control itself is the kit Checkbox) */
125
- .subagent-toggle { padding: .4em 0; min-height: 32px; }
126
-
127
- .field-error { color: var(--warn, var(--agentgui-warn)); }
128
-
129
- /* Boot splash: static text painted with the HTML, replaced by the first
130
- mount render - the cold module waterfall no longer reads as a blank page. */
131
- .boot-splash { height: 100%; min-height: 60vh; display: flex; align-items: center; justify-content: center; color: var(--agentgui-muted); font-size: .9rem; }
132
-
133
- /* chat control cluster in the crumb bar: model picker, +new, status.
134
- Allowed to wrap so it never overflows the crumb on tablet widths. */
135
- .chat-controls { display: flex; align-items: center; gap: .6em; flex-wrap: wrap; }
136
- .chat-controls > * { flex: 0 0 auto; }
137
- .chat-controls select,
138
- .chat-controls .select,
139
- .chat-controls [role="combobox"] { min-width: 130px; max-width: 220px; }
140
- .chat-controls .status-dot { white-space: nowrap; }
141
-
142
- .agentgui-main .ds-section { margin: 0 0 var(--space-4, 16px); }
143
-
144
- /* readable backend health summary (replaces raw JSON dump) */
145
- .health-summary { display: flex; flex-wrap: wrap; gap: .4em; margin: .6em 0; }
146
- .health-chip {
147
- font-family: var(--ff-mono, ui-monospace, monospace);
148
- font-size: .8rem; padding: .15em .55em; border-radius: 6px;
149
- background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 8%, transparent);
150
- color: var(--fg-2, var(--agentgui-fg));
151
- border: 1px solid color-mix(in srgb, var(--fg, var(--agentgui-fg)) 12%, transparent);
152
- }
153
- .health-summary.health-ok .health-chip:first-child {
154
- color: var(--accent, var(--agentgui-accent));
155
- border-color: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 40%, transparent);
156
- }
157
-
158
- /* (search-input theming now provided by the design system's .ds-search-input
159
- + base input rules; the local reskin hack was removed.) */
160
-
161
- /* empty-state: keep it from wrapping awkwardly in the narrow sidebar */
162
- .empty-state { white-space: normal; }
163
- p.empty-state { text-align: left; padding: .6em 0; color: var(--fg-3, var(--agentgui-muted)); }
164
-
165
- /* generic interactive focus ring */
166
- button:focus-visible, [tabindex]:focus-visible, a:focus-visible {
167
- outline: 2px solid var(--accent, var(--agentgui-accent)); outline-offset: 2px;
168
- }
169
-
170
- /* (Topbar active-tab styling - the subtle tinted underline-pill instead of an
171
- oversized filled oval - now ships as the kit default in app-shell.css, so
172
- agentgui no longer overrides it here.) */
173
-
174
- /* Compact working-directory bar (replaces the full-width tall banner box). */
175
- .cwd-bar {
176
- display: flex; align-items: center; gap: .5em; flex-wrap: wrap;
177
- padding: .15em 0 .5em; font-size: .85rem;
178
- }
179
- .cwd-bar-text {
180
- font-family: var(--ff-mono, ui-monospace, monospace);
181
- color: var(--fg-3, var(--agentgui-muted)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60vw;
182
- }
183
- .cwd-bar-btn {
184
- cursor: pointer; font: inherit; line-height: 1.3;
185
- padding: .15em .55em; border-radius: 6px;
186
- background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 8%, transparent);
187
- border: 1px solid color-mix(in srgb, var(--fg, var(--agentgui-fg)) 14%, transparent);
188
- color: var(--fg-2, var(--agentgui-fg));
189
- }
190
- .cwd-bar-btn:hover { background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 14%, transparent); }
191
- .cwd-bar-btn:focus-visible { outline: 2px solid var(--accent, var(--agentgui-accent)); outline-offset: 2px; }
192
-
193
- /* History no-session empty state: fill the void with a centered prompt. */
194
- .history-empty {
195
- display: flex; flex-direction: column; align-items: center; justify-content: center;
196
- gap: .4em; text-align: center; min-height: 50vh; color: var(--fg-3, var(--agentgui-muted));
197
- }
198
- .history-empty-title { margin: 0; font-size: 1.05rem; color: var(--fg-2, var(--agentgui-fg)); }
199
- .history-empty-sub { margin: 0; max-width: 42ch; }
200
-
201
- /* Settings: two-column on wide screens (backend + agents) so it uses the
202
- full width instead of a cramped centered measure with empty margins. */
203
- .settings-grid {
204
- display: grid; gap: var(--space-4, 16px);
205
- grid-template-columns: minmax(0, 1fr);
206
- align-items: start;
207
- }
208
- @media (min-width: 900px) {
209
- .settings-grid { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); }
210
- }
211
- /* (PageHeader top/bottom margin is now handled by the kit's `compact` prop -
212
- agentgui passes compact:true on its leading PageHeaders, so the fragile
213
- [class*=page-header] !important overrides are gone.) */
214
- .agentgui-main-settings .settings-grid { margin-top: 0; }
215
-
216
- /* The DS Chat head computes its own zero-padded count ("00 msgs") and ignores
217
- our sub prop; it reads as a bug. Hide the DS sub - streaming state shows via
218
- the title and the busy banner. (The decorative head dot was removed from the
219
- kit's Chat component, so it no longer needs hiding here.) */
220
- .chat-head .sub { display: none; }
221
-
222
- /* (Row role=button cursor:pointer now ships as a kit default in app-shell.css.)
223
- A slightly stronger hover tint for event rows specifically remains local. */
224
- .ds-event-list .row[role="button"]:hover { background: color-mix(in srgb, var(--fg, var(--agentgui-fg)) 5%, transparent); }
225
- /* Flash the row a search result landed on, so the match is obvious. */
226
- .ds-event-list .row.event-flash { animation: agentgui-event-flash 2s ease-out; }
227
- @keyframes agentgui-event-flash {
228
- 0% { background: color-mix(in srgb, var(--accent, var(--agentgui-accent)) 40%, transparent); }
229
- 100% { background: transparent; }
230
- }
231
- @media (prefers-reduced-motion: reduce) {
232
- .ds-event-list .row.event-flash { animation: none; outline: 2px solid var(--accent, var(--agentgui-accent)); }
233
- }
234
-
235
- /* Chat composer: hide the idle scrollbar on the (empty/short) textarea. */
236
- .chat-composer textarea { overflow-y: auto; scrollbar-width: thin; }
237
- .chat-composer textarea:not(:focus) { overflow-y: hidden; }
238
-
239
- /* tablet: keep the chat control cluster from wrapping the status dot alone */
240
- @media (max-width: 900px) {
241
- .chat-controls select,
242
- .chat-controls .select,
243
- .chat-controls [role="combobox"] { min-width: 110px; max-width: 170px; }
244
- }
245
-
246
- /* touch targets on small screens */
247
- @media (max-width: 640px) {
248
- .pill { min-height: 36px; padding: .4em .8em; }
249
- .history-actions { gap: .75em; }
250
- .history-actions .btn, .history-actions button { min-height: 44px; }
251
- /* cwd path can't eat the whole row beside its label + buttons on a phone */
252
- .cwd-bar-text { max-width: 42vw; }
253
- .cwd-bar { gap: .3em; }
254
- }
255
-
256
- @media print {
257
- #app { min-height: auto; display: block; height: auto; }
258
- .skip-link, .status-dot, .history-actions, .chat-composer { display: none !important; }
259
- /* Drop chrome backgrounds/shadows for ink-saving, but preserve code
260
- highlighting and rail colors (don't nuke every color to black). */
261
- .app, .app-main, .panel, .chat, .chat-thread {
262
- background: #fff !important; color: #000 !important; box-shadow: none !important;
263
- }
264
- }
265
- </style>
26
+ <!-- No design content lives here. Every agentgui application-surface style
27
+ (pills, cwd bar, resume banner, health chips, settings grid, history
28
+ empty state, boot splash, scrollbar theming, focus rings, print) now
29
+ lives in the kit at ../design/app-surfaces.css and ships in the vendored
30
+ 247420.css bundle, scoped under .ds-247420. The kit owns all design. -->
266
31
  </head>
267
32
  <body>
268
33
  <div id="app"><div class="boot-splash" role="status">loading agentgui…</div></div>
@@ -562,14 +562,11 @@ function view() {
562
562
  right: [agentLabel, 'press ? for shortcuts'],
563
563
  });
564
564
 
565
- const mainStyle = state.tab === 'chat'
566
- ? 'min-height:0;display:flex;flex-direction:column;flex:1'
567
- : 'min-height:0';
568
565
  const shortcutsHint = state.showShortcuts
569
566
  ? Alert({ key: 'sc', kind: 'info', title: 'Keyboard shortcuts',
570
567
  children: SHORTCUTS.map(s => s.keys + ' - ' + s.desc).join(' · ') })
571
568
  : null;
572
- const main = h('div', { id: 'agentgui-main', role: 'region', 'aria-label': 'main content', 'data-chat-scroll': '', class: 'agentgui-main agentgui-main-' + state.tab, style: mainStyle }, [shortcutsHint, ...mainContent()].filter(Boolean));
569
+ const main = h('div', { id: 'agentgui-main', role: 'region', 'aria-label': 'main content', 'data-chat-scroll': '', class: 'agentgui-main agentgui-main-' + state.tab }, [shortcutsHint, ...mainContent()].filter(Boolean));
573
570
 
574
571
  // Claude-Desktop three-column shell: a persistent left rail (workspace nav), an
575
572
  // optional sessions column (chat + history share the conversation list), the
@@ -2883,7 +2880,7 @@ function settingsMain() {
2883
2880
  key: 'backendForm',
2884
2881
  onSubmit: (e) => { e.preventDefault(); saveBackend(); },
2885
2882
  }, [
2886
- h('p', { key: 'blede', class: 'lede', style: 'margin:0 0 .5em',
2883
+ h('p', { key: 'blede', class: 'lede agentgui-field-mb',
2887
2884
  title: 'Also settable with a ?backend= URL parameter; the value persists in this browser.' },
2888
2885
  'Connect to a different agentgui server. Leave blank to use this one.'),
2889
2886
  TextField({
@@ -2927,7 +2924,7 @@ function settingsMain() {
2927
2924
  id: 'appearance',
2928
2925
  title: 'appearance',
2929
2926
  children: [
2930
- h('div', { key: 'apl', class: 'lede', style: 'margin-bottom:.5em' }, 'theme - follows the OS in auto, or pick light/dark.'),
2927
+ h('div', { key: 'apl', class: 'lede agentgui-field-mb' }, 'theme - follows the OS in auto, or pick light/dark.'),
2931
2928
  ThemeToggle({ key: 'tt' }),
2932
2929
  ],
2933
2930
  }),
@@ -3003,14 +3000,14 @@ function preferencesPanel() {
3003
3000
  (window.__SERVER_VERSION && window.__SERVER_VERSION !== hh.version)
3004
3001
  ? h('div', { key: 'ver', class: 'lede' }, 'build ' + window.__SERVER_VERSION)
3005
3002
  : null,
3006
- h('div', { key: 'lsize', class: 'lede', style: 'margin:.5em 0' },
3003
+ h('div', { key: 'lsize', class: 'lede agentgui-field-my' },
3007
3004
  'local data: ' + fmtBytes(lsBytes) + ' across ' + lsKeys + ' key' + (lsKeys === 1 ? '' : 's')),
3008
- h('div', { key: 'expchatrow', style: 'margin:.5em 0' },
3005
+ h('div', { key: 'expchatrow', class: 'agentgui-field-my' },
3009
3006
  Btn({ key: 'expchat', disabled: !savedChat,
3010
3007
  title: savedChat ? 'Download the saved chat transcript as JSON' : 'no saved chat',
3011
3008
  onClick: savedChat ? () => downloadBlob(savedChat, 'agentgui-chat-' + dateStamp() + '.json', 'application/json') : undefined,
3012
3009
  children: savedChat ? 'export chat' : 'no saved chat' })),
3013
- h('div', { key: 'cwdnote', class: 'lede', style: 'margin:.5em 0' },
3010
+ h('div', { key: 'cwdnote', class: 'lede agentgui-field-my' },
3014
3011
  'working directory: set per-chat in the chat composer’s cwd bar' + (state.chatCwd ? ' (current: ' + state.chatCwd + ')' : ' (currently: server default)')),
3015
3012
  state.confirmingClearData
3016
3013
  ? Alert({ key: 'cld', kind: 'warn', title: 'Clear all local data?',
@@ -3039,7 +3036,7 @@ function agentsPanel() {
3039
3036
  // on-demand and restarted with backoff by the server, so there are no
3040
3037
  // manual start/stop controls by design. This note makes that explicit so
3041
3038
  // a 'stopped' row doesn't read as a missing action.
3042
- hasAcp ? h('p', { key: 'acpnote', class: 'lede', style: 'margin:0 0 .5em' }, 'ACP agents start on demand and restart automatically; selecting one launches it.') : null,
3039
+ hasAcp ? h('p', { key: 'acpnote', class: 'lede agentgui-field-mb' }, 'ACP agents start on demand and restart automatically; selecting one launches it.') : null,
3043
3040
  ...(state.agents.length
3044
3041
  ? state.agents.map((a, i) => {
3045
3042
  const acp = acpStatusFor(a.id);