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.
- package/.claude/workflows/gui-design-consolidation.js +101 -0
- package/AGENTS.md +6 -0
- package/PUNCHLIST-DESIGN.md +196 -0
- package/package.json +1 -1
- package/site/app/index.html +5 -240
- package/site/app/js/app.js +7 -10
- package/site/app/vendor/anentrypoint-design/247420.css +357 -69
- package/site/app/vendor/anentrypoint-design/247420.js +12 -12
package/site/app/index.html
CHANGED
|
@@ -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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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>
|
package/site/app/js/app.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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',
|
|
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
|
|
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
|
|
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);
|