agentgui 1.0.1052 → 1.0.1053
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/package.json
CHANGED
package/site/app/js/app.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as B from './backend.js';
|
|
|
3
3
|
|
|
4
4
|
installStyles().catch(() => {});
|
|
5
5
|
|
|
6
|
-
const { AppShell, WorkspaceShell, WorkspaceRail, Topbar, Crumb, Side, Status, Chat, ChatComposer, AgentChat, ConversationList, SessionDashboard, Row, Panel, PageHeader, TextField, Select, Btn, Icon, EventList, Spinner, Alert, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker, BreadcrumbPath, EmptyState, FileViewer, FilePreviewPane, FilePreviewCode, FilePreviewText, FilePreviewMedia, ThemeToggle, ContextPane, PromptDialog, ConfirmDialog, DropZone, UploadProgress, FilterPills, SessionMeta, BulkBar, Checkbox, ShortcutList, FocusTrap, AgentListSkeleton } = C;
|
|
6
|
+
const { AppShell, WorkspaceShell, WorkspaceRail, Topbar, Crumb, Side, Status, Chat, ChatComposer, AgentChat, ConversationList, SessionDashboard, Row, Panel, PageHeader, TextField, Select, Btn, Icon, IconButton, EventList, Spinner, Alert, FileGrid, FileSkeleton, sortFiles, FileToolbar, RootsPicker, BreadcrumbPath, EmptyState, FileViewer, FilePreviewPane, FilePreviewCode, FilePreviewText, FilePreviewMedia, ThemeToggle, ContextPane, PromptDialog, ConfirmDialog, DropZone, UploadProgress, FilterPills, SessionMeta, BulkBar, Checkbox, ShortcutList, FocusTrap, AgentListSkeleton } = C;
|
|
7
7
|
|
|
8
8
|
// One duration/bytes vocabulary across every surface: prefer the kit's shared
|
|
9
9
|
// formatters (exported alongside the components), fall back to the local
|
|
@@ -437,6 +437,21 @@ async function stopActiveChat(sid) {
|
|
|
437
437
|
state.active = (Array.isArray(state.active) ? state.active : []).filter(a => a.sessionId !== sid);
|
|
438
438
|
await refreshActive();
|
|
439
439
|
render();
|
|
440
|
+
// The backend accepted the cancel, but the underlying process can outlive
|
|
441
|
+
// this immediate refresh - if it's still showing active after a bounded
|
|
442
|
+
// wait, stop treating it as en-route-to-stopped: clear `stopping` (or the
|
|
443
|
+
// row wedges permanently disabled) and surface the same retry banner used
|
|
444
|
+
// on an outright rejection.
|
|
445
|
+
setTimeout(() => {
|
|
446
|
+
const st2 = state.live.stopping;
|
|
447
|
+
const stillActive = Array.isArray(state.active) && state.active.some(a => a.sessionId === sid);
|
|
448
|
+
if (st2 && st2.has(sid) && stillActive) {
|
|
449
|
+
st2.delete(sid);
|
|
450
|
+
state.live.bulkStopError = 'conversation did not stop - try again';
|
|
451
|
+
announce('stop failed');
|
|
452
|
+
render();
|
|
453
|
+
}
|
|
454
|
+
}, 9000);
|
|
440
455
|
}
|
|
441
456
|
|
|
442
457
|
function openLiveStream() {
|
|
@@ -507,6 +522,7 @@ function openLiveStream() {
|
|
|
507
522
|
if (ev.type === 'tool_use') { t.tools++; t.toolRunning = true; t.toolName = ev.tool || ev.name || ''; }
|
|
508
523
|
if (ev.type === 'tool_result') { t.toolRunning = false; t.toolName = ''; }
|
|
509
524
|
if (ev.type === 'result' && ev.usage) { t.tokens = (t.tokens || 0) + (ev.usage.input_tokens || 0) + (ev.usage.output_tokens || 0); }
|
|
525
|
+
if (ev.type === 'result' && typeof ev.total_cost_usd === 'number') { t.cost = (t.cost || 0) + ev.total_cost_usd; }
|
|
510
526
|
if (ev.isError) { t.errors++; t.lastErrorTs = t.last; }
|
|
511
527
|
}
|
|
512
528
|
state.live.tally.set(data.sid, t);
|
|
@@ -708,8 +724,13 @@ function workspaceRail() {
|
|
|
708
724
|
action: { label: 'New chat', icon: 'pencil', onClick: () => { navTo('chat'); newChat(); } },
|
|
709
725
|
items,
|
|
710
726
|
// W18: a persistent theme toggle pinned to the rail bottom (the Claude-Desktop
|
|
711
|
-
// / cowork pinned-bottom affordance).
|
|
712
|
-
|
|
727
|
+
// / cowork pinned-bottom affordance). A shortcuts-help icon sits alongside it -
|
|
728
|
+
// the '?' overlay (state.showShortcuts) was previously 100% keyboard-only
|
|
729
|
+
// tribal knowledge with zero visible entry point outside Settings.
|
|
730
|
+
footer: [
|
|
731
|
+
h('span', { key: 'rail-help' }, IconButton({ icon: 'help', title: 'Keyboard shortcuts', onClick: () => { state.showShortcuts = true; render(); } })),
|
|
732
|
+
h('span', { key: 'rail-theme' }, ThemeToggle({ compact: true })),
|
|
733
|
+
],
|
|
713
734
|
});
|
|
714
735
|
}
|
|
715
736
|
|
|
@@ -1779,7 +1800,7 @@ function computeLiveSessions() {
|
|
|
1779
1800
|
// Surface the in-page chat's own running cost and token count on its card
|
|
1780
1801
|
// (the only session we hold reliable per-session data for; others omit it).
|
|
1781
1802
|
cost: (state.chat.resumeSid && (r.claudeSessionId === state.chat.resumeSid || r.sessionId === state.chat.resumeSid))
|
|
1782
|
-
? (state.chat.totalCost || null) : null,
|
|
1803
|
+
? (state.chat.totalCost || null) : (t && t.cost ? t.cost : null),
|
|
1783
1804
|
tokens: (state.chat.resumeSid && (r.claudeSessionId === state.chat.resumeSid || r.sessionId === state.chat.resumeSid) && state.chat.usage)
|
|
1784
1805
|
? ((state.chat.usage.inputTokens || 0) + (state.chat.usage.outputTokens || 0)) : (t && t.tokens ? t.tokens : undefined),
|
|
1785
1806
|
};
|
|
@@ -3121,6 +3142,15 @@ function resumeSidLabel(sid) {
|
|
|
3121
3142
|
return label || UNTITLED_CONVERSATION;
|
|
3122
3143
|
}
|
|
3123
3144
|
|
|
3145
|
+
// Same identity contract as the sessions rail/history rail/Live SessionCard:
|
|
3146
|
+
// a running row must show the resolved conversation title, not just agent
|
|
3147
|
+
// metadata - otherwise the same session reads as "nameless" here and named
|
|
3148
|
+
// everywhere else.
|
|
3149
|
+
function runningRowTitle(r) {
|
|
3150
|
+
const realSid = r.claudeSessionId || r.sessionId;
|
|
3151
|
+
return resumeSidLabel(realSid);
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3124
3154
|
function uniqueProjects() {
|
|
3125
3155
|
const arr = Array.isArray(state.sessions) ? state.sessions : [];
|
|
3126
3156
|
const seen = new Map();
|
|
@@ -3168,7 +3198,7 @@ function runningPanel() {
|
|
|
3168
3198
|
// unkeyed one crashes webjsx applyDiff "reading 'key'").
|
|
3169
3199
|
return h('div', { key: 'run' + r.sessionId, class: 'resume-banner', role: 'group' },
|
|
3170
3200
|
h('span', { key: 'rd-' + r.sessionId, class: 'status-dot-disc ' + (isStopping ? 'status-dot-connecting' : 'status-dot-live'), 'aria-hidden': 'true' }),
|
|
3171
|
-
h('span', { key: 'rl-' + r.sessionId, class: 't-meta' }, agentName + (r.model ? ' · ' + r.model : '') + (elapsedMs ? ' · ' + fmtDuration(elapsedMs) : '') + (r.cwd ? ' · ' + pathBasename(r.cwd) : '')),
|
|
3201
|
+
h('span', { key: 'rl-' + r.sessionId, class: 't-meta' }, runningRowTitle(r) + ' · ' + agentName + (r.model ? ' · ' + r.model : '') + (elapsedMs ? ' · ' + fmtDuration(elapsedMs) : '') + (r.cwd ? ' · ' + pathBasename(r.cwd) : '')),
|
|
3172
3202
|
Btn({ key: 'open' + r.sessionId, onClick: () => navTo('live'), children: 'open in live' }),
|
|
3173
3203
|
Btn({ key: 'stop' + r.sessionId, disabled: isStopping, onClick: () => stopActiveChat(r.sessionId), children: isStopping ? 'stopping…' : 'stop' }));
|
|
3174
3204
|
}),
|