@design.estate/dees-catalog 6.1.0 → 6.2.0
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/dist_bundle/bundle.js +3097 -1497
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.d.ts +2 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.demo.js +484 -8
- package/dist_ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.js +10 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.d.ts +3 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.js +24 -4
- package/dist_ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.d.ts +26 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.js +398 -94
- package/dist_ts_web/elements/00group-harness/dees-harness-overflow-text.d.ts +32 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-overflow-text.demo.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-overflow-text.demo.js +31 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-overflow-text.js +297 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +1 -9
- package/dist_ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.d.ts +10 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.js +181 -2
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.d.ts +17 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.js +476 -36
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/renderers.js +23 -20
- package/dist_ts_web/elements/00group-harness/harness.helpers.d.ts +5 -1
- package/dist_ts_web/elements/00group-harness/harness.helpers.js +66 -1
- package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/index.js +2 -1
- package/dist_ts_web/elements/00group-harness/interfaces.d.ts +31 -2
- package/dist_ts_web/elements/00group-harness/toolregistry.d.ts +4 -0
- package/dist_ts_web/elements/00group-harness/toolregistry.js +8 -1
- package/package.json +2 -2
- package/readme.hints.md +16 -1
- package/readme.md +41 -9
- package/readme.playbook.md +8 -4
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.demo.ts +490 -7
- package/ts_web/elements/00group-harness/dees-harness-chat/dees-harness-chat.ts +9 -0
- package/ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.ts +24 -3
- package/ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.ts +397 -84
- package/ts_web/elements/00group-harness/dees-harness-overflow-text.demo.ts +31 -0
- package/ts_web/elements/00group-harness/dees-harness-overflow-text.ts +236 -0
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +0 -8
- package/ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.ts +193 -1
- package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.ts +480 -34
- package/ts_web/elements/00group-harness/dees-harness-tool-card/renderers.ts +24 -21
- package/ts_web/elements/00group-harness/harness.helpers.ts +68 -1
- package/ts_web/elements/00group-harness/index.ts +1 -0
- package/ts_web/elements/00group-harness/interfaces.ts +36 -2
- package/ts_web/elements/00group-harness/toolregistry.ts +12 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { demoFunc } from './dees-harness-overflow-text.demo.js';
|
|
2
|
+
import {
|
|
3
|
+
DeesElement,
|
|
4
|
+
html,
|
|
5
|
+
css,
|
|
6
|
+
customElement,
|
|
7
|
+
type TemplateResult,
|
|
8
|
+
property,
|
|
9
|
+
state,
|
|
10
|
+
cssManager,
|
|
11
|
+
} from '@design.estate/dees-element';
|
|
12
|
+
import { themeDefaultStyles } from '../00theme.js';
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
interface HTMLElementTagNameMap {
|
|
16
|
+
'dees-harness-overflow-text': DeesHarnessOverflowText;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@customElement('dees-harness-overflow-text')
|
|
21
|
+
export class DeesHarnessOverflowText extends DeesElement {
|
|
22
|
+
public static demo = demoFunc;
|
|
23
|
+
public static demoGroups = ['Agent Chat'];
|
|
24
|
+
|
|
25
|
+
@property({ type: Number })
|
|
26
|
+
accessor fadeWidthPx: number = 40;
|
|
27
|
+
|
|
28
|
+
@property({ type: Number })
|
|
29
|
+
accessor introDelayMs: number = 2000;
|
|
30
|
+
|
|
31
|
+
@state()
|
|
32
|
+
accessor overflowing: boolean = false;
|
|
33
|
+
|
|
34
|
+
@state()
|
|
35
|
+
accessor travelPx: number = 0;
|
|
36
|
+
|
|
37
|
+
private readonly createdAt = performance.now();
|
|
38
|
+
private resizeObserver: ResizeObserver | null = null;
|
|
39
|
+
private visibilityObserver: IntersectionObserver | null = null;
|
|
40
|
+
private measureFrame: number | null = null;
|
|
41
|
+
private introTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
42
|
+
private introAnimation: Animation | null = null;
|
|
43
|
+
private introHandled = false;
|
|
44
|
+
|
|
45
|
+
public static styles = [
|
|
46
|
+
themeDefaultStyles,
|
|
47
|
+
cssManager.defaultStyles,
|
|
48
|
+
css`
|
|
49
|
+
:host {
|
|
50
|
+
display: block;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
width: 100%;
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.viewport {
|
|
57
|
+
display: block;
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
width: 100%;
|
|
60
|
+
min-width: 0;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.viewport.overflowing {
|
|
66
|
+
-webkit-mask-image: linear-gradient(
|
|
67
|
+
to right,
|
|
68
|
+
black 0,
|
|
69
|
+
black calc(100% - var(--harness-overflow-fade-width)),
|
|
70
|
+
transparent 100%
|
|
71
|
+
);
|
|
72
|
+
mask-image: linear-gradient(
|
|
73
|
+
to right,
|
|
74
|
+
black 0,
|
|
75
|
+
black calc(100% - var(--harness-overflow-fade-width)),
|
|
76
|
+
transparent 100%
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.text {
|
|
81
|
+
display: inline-block;
|
|
82
|
+
min-width: max-content;
|
|
83
|
+
transform: translateX(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.viewport.overflowing:hover .text {
|
|
87
|
+
animation: harness-overflow-reveal var(--harness-overflow-duration) var(--dees-ease-standard);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@keyframes harness-overflow-reveal {
|
|
91
|
+
0%, 10%, 100% { transform: translateX(0); }
|
|
92
|
+
72%, 88% { transform: translateX(calc(0px - var(--harness-overflow-travel))); }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (prefers-reduced-motion: reduce) {
|
|
96
|
+
.viewport.overflowing:hover .text {
|
|
97
|
+
animation: none;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
`,
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
public render(): TemplateResult {
|
|
104
|
+
const durationSeconds = Math.min(7, Math.max(3.2, this.travelPx / 80 + 2.4));
|
|
105
|
+
return html`
|
|
106
|
+
<span
|
|
107
|
+
class=${`viewport ${this.overflowing ? 'overflowing' : ''}`}
|
|
108
|
+
style=${`
|
|
109
|
+
--harness-overflow-fade-width: ${this.fadeWidthPx}px;
|
|
110
|
+
--harness-overflow-travel: ${this.travelPx}px;
|
|
111
|
+
--harness-overflow-duration: ${durationSeconds}s;
|
|
112
|
+
`}
|
|
113
|
+
>
|
|
114
|
+
<span class="text"><slot @slotchange=${this.scheduleMeasure}></slot></span>
|
|
115
|
+
</span>
|
|
116
|
+
`;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public firstUpdated(changedProperties: Map<PropertyKey, unknown>): void {
|
|
120
|
+
super.firstUpdated(changedProperties);
|
|
121
|
+
if (!this.isConnected) return;
|
|
122
|
+
this.connectResizeObserver();
|
|
123
|
+
this.scheduleMeasure();
|
|
124
|
+
this.scheduleIntro();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public updated(changedProperties: Map<PropertyKey, unknown>): void {
|
|
128
|
+
super.updated(changedProperties);
|
|
129
|
+
if (!this.isConnected) return;
|
|
130
|
+
if (changedProperties.has('fadeWidthPx')) this.scheduleMeasure();
|
|
131
|
+
if (changedProperties.has('introDelayMs') && !this.introHandled) this.scheduleIntro();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public async connectedCallback(): Promise<void> {
|
|
135
|
+
const connected = super.connectedCallback();
|
|
136
|
+
if (this.hasUpdated) {
|
|
137
|
+
this.connectResizeObserver();
|
|
138
|
+
this.scheduleMeasure();
|
|
139
|
+
this.scheduleIntro();
|
|
140
|
+
}
|
|
141
|
+
await connected;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private connectResizeObserver(): void {
|
|
145
|
+
if (!this.isConnected || this.resizeObserver) return;
|
|
146
|
+
const viewport = this.shadowRoot?.querySelector('.viewport');
|
|
147
|
+
const text = this.shadowRoot?.querySelector('.text');
|
|
148
|
+
if (!viewport || !text) return;
|
|
149
|
+
this.resizeObserver = new ResizeObserver(this.scheduleMeasure);
|
|
150
|
+
this.resizeObserver.observe(viewport);
|
|
151
|
+
this.resizeObserver.observe(text);
|
|
152
|
+
this.visibilityObserver = new IntersectionObserver((entries) => {
|
|
153
|
+
if (!entries.some((entry) => entry.isIntersecting)) return;
|
|
154
|
+
this.scheduleMeasure();
|
|
155
|
+
requestAnimationFrame(() => this.tryRunIntro());
|
|
156
|
+
});
|
|
157
|
+
this.visibilityObserver.observe(this);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private readonly scheduleMeasure = (): void => {
|
|
161
|
+
if (!this.isConnected || this.measureFrame !== null) return;
|
|
162
|
+
this.measureFrame = requestAnimationFrame(() => {
|
|
163
|
+
this.measureFrame = null;
|
|
164
|
+
if (!this.isConnected) return;
|
|
165
|
+
const viewport = this.shadowRoot?.querySelector<HTMLElement>('.viewport');
|
|
166
|
+
const text = this.shadowRoot?.querySelector<HTMLElement>('.text');
|
|
167
|
+
if (!viewport || !text) return;
|
|
168
|
+
this.measureOverflow(viewport, text);
|
|
169
|
+
if (
|
|
170
|
+
!this.introHandled
|
|
171
|
+
&& performance.now() - this.createdAt >= this.introDelayMs
|
|
172
|
+
) {
|
|
173
|
+
requestAnimationFrame(() => this.tryRunIntro());
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
private scheduleIntro(): void {
|
|
179
|
+
if (!this.isConnected || this.introHandled) return;
|
|
180
|
+
if (this.introTimeout) clearTimeout(this.introTimeout);
|
|
181
|
+
const remainingMs = Math.max(0, this.introDelayMs - (performance.now() - this.createdAt));
|
|
182
|
+
this.introTimeout = setTimeout(() => {
|
|
183
|
+
this.introTimeout = null;
|
|
184
|
+
this.scheduleMeasure();
|
|
185
|
+
requestAnimationFrame(() => this.tryRunIntro());
|
|
186
|
+
}, remainingMs);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private tryRunIntro(): void {
|
|
190
|
+
if (!this.isConnected || this.introHandled) return;
|
|
191
|
+
const viewport = this.shadowRoot?.querySelector<HTMLElement>('.viewport');
|
|
192
|
+
const text = this.shadowRoot?.querySelector<HTMLElement>('.text');
|
|
193
|
+
if (!viewport || !text || viewport.clientWidth <= 0) return;
|
|
194
|
+
this.measureOverflow(viewport, text);
|
|
195
|
+
this.introHandled = true;
|
|
196
|
+
if (!this.overflowing || this.travelPx <= 0) return;
|
|
197
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
|
198
|
+
const duration = Math.min(7000, Math.max(3200, this.travelPx / 80 * 1000 + 2400));
|
|
199
|
+
this.introAnimation = text.animate([
|
|
200
|
+
{ transform: 'translateX(0)', offset: 0 },
|
|
201
|
+
{ transform: 'translateX(0)', offset: 0.1 },
|
|
202
|
+
{ transform: `translateX(-${this.travelPx}px)`, offset: 0.72 },
|
|
203
|
+
{ transform: `translateX(-${this.travelPx}px)`, offset: 0.88 },
|
|
204
|
+
{ transform: 'translateX(0)', offset: 1 },
|
|
205
|
+
], {
|
|
206
|
+
duration,
|
|
207
|
+
easing: 'cubic-bezier(0.2, 0, 0, 1)',
|
|
208
|
+
});
|
|
209
|
+
this.introAnimation.onfinish = () => {
|
|
210
|
+
this.introAnimation = null;
|
|
211
|
+
};
|
|
212
|
+
this.introAnimation.oncancel = () => {
|
|
213
|
+
this.introAnimation = null;
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private measureOverflow(viewportArg: HTMLElement, textArg: HTMLElement): void {
|
|
218
|
+
const overflowPx = Math.max(0, textArg.scrollWidth - viewportArg.clientWidth);
|
|
219
|
+
this.overflowing = overflowPx > 0.5;
|
|
220
|
+
this.travelPx = this.overflowing ? overflowPx + this.fadeWidthPx : 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
public async disconnectedCallback(): Promise<void> {
|
|
224
|
+
if (this.measureFrame !== null) cancelAnimationFrame(this.measureFrame);
|
|
225
|
+
if (this.introTimeout) clearTimeout(this.introTimeout);
|
|
226
|
+
this.measureFrame = null;
|
|
227
|
+
this.introTimeout = null;
|
|
228
|
+
this.introAnimation?.cancel();
|
|
229
|
+
this.introAnimation = null;
|
|
230
|
+
this.resizeObserver?.disconnect();
|
|
231
|
+
this.resizeObserver = null;
|
|
232
|
+
this.visibilityObserver?.disconnect();
|
|
233
|
+
this.visibilityObserver = null;
|
|
234
|
+
await super.disconnectedCallback();
|
|
235
|
+
}
|
|
236
|
+
}
|
package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts
CHANGED
|
@@ -751,8 +751,6 @@ export class DeesHarnessSessionList extends DeesElement {
|
|
|
751
751
|
this.finishPointerDrag(false);
|
|
752
752
|
}
|
|
753
753
|
if (!changedProperties.has('sessions')) return;
|
|
754
|
-
const previousSessions = changedProperties.get('sessions') as IHarnessSessionMeta[] | undefined;
|
|
755
|
-
const previousById = new Map((previousSessions ?? []).map((session) => [session.id, session]));
|
|
756
754
|
const knownIds = new Set(this.sessions.map((session) => session.id));
|
|
757
755
|
if (this.pointerDragGesture && !knownIds.has(this.pointerDragGesture.sessionId)) {
|
|
758
756
|
this.finishPointerDrag(false);
|
|
@@ -760,12 +758,6 @@ export class DeesHarnessSessionList extends DeesElement {
|
|
|
760
758
|
const nextExpanded = new Set(
|
|
761
759
|
[...this.expandedSessionIds].filter((sessionId) => knownIds.has(sessionId)),
|
|
762
760
|
);
|
|
763
|
-
for (const session of this.sessions) {
|
|
764
|
-
const previous = previousById.get(session.id);
|
|
765
|
-
if (previous && previous.working !== true && session.working === true) {
|
|
766
|
-
nextExpanded.add(session.id);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
761
|
if (
|
|
770
762
|
nextExpanded.size !== this.expandedSessionIds.size
|
|
771
763
|
|| [...nextExpanded].some((sessionId) => !this.expandedSessionIds.has(sessionId))
|
package/ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.ts
CHANGED
|
@@ -13,20 +13,33 @@ import {
|
|
|
13
13
|
import { themeDefaultStyles } from '../../00theme.js';
|
|
14
14
|
import type {
|
|
15
15
|
IHarnessIntelligenceExchange,
|
|
16
|
+
IHarnessMessage,
|
|
16
17
|
IHarnessScratchpad,
|
|
17
18
|
IHarnessScratchpadSaveDetail,
|
|
18
19
|
IHarnessSessionIntelligenceAskDetail,
|
|
19
20
|
IHarnessSessionMetrics,
|
|
20
21
|
IHarnessTodoItem,
|
|
22
|
+
IHarnessToolCall,
|
|
23
|
+
THarnessToolStatus,
|
|
21
24
|
} from '../interfaces.js';
|
|
25
|
+
import { harnessEffectiveToolStatus, harnessFormatRelativeTime } from '../harness.helpers.js';
|
|
26
|
+
import { DeesHarnessToolRegistry } from '../toolregistry.js';
|
|
22
27
|
import '../dees-harness-todos/dees-harness-todos.js';
|
|
28
|
+
import '../dees-harness-overflow-text.js';
|
|
23
29
|
import '../../00group-button/dees-button/dees-button.js';
|
|
24
30
|
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
25
31
|
|
|
26
32
|
const { repeat } = directives;
|
|
27
33
|
|
|
28
34
|
const formatTokenCount = (valueArg: number): string => valueArg.toLocaleString('en-US');
|
|
29
|
-
type TSessionSidebarSection = 'tasks' | 'metrics' | 'scratchpad' | 'intelligence';
|
|
35
|
+
type TSessionSidebarSection = 'tasks' | 'activity' | 'metrics' | 'scratchpad' | 'intelligence';
|
|
36
|
+
|
|
37
|
+
interface IToolActivityEntry {
|
|
38
|
+
key: string;
|
|
39
|
+
call: IHarnessToolCall;
|
|
40
|
+
createdAt?: number;
|
|
41
|
+
status: THarnessToolStatus;
|
|
42
|
+
}
|
|
30
43
|
|
|
31
44
|
declare global {
|
|
32
45
|
interface HTMLElementTagNameMap {
|
|
@@ -49,6 +62,13 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
49
62
|
@property({ type: Boolean })
|
|
50
63
|
accessor showTasks: boolean = true;
|
|
51
64
|
|
|
65
|
+
/** Top-level tool messages from the host's currently retained transcript window. */
|
|
66
|
+
@property({ attribute: false })
|
|
67
|
+
accessor toolMessages: IHarnessMessage[] = [];
|
|
68
|
+
|
|
69
|
+
@property({ attribute: false })
|
|
70
|
+
accessor toolRegistry: DeesHarnessToolRegistry = DeesHarnessToolRegistry.default;
|
|
71
|
+
|
|
52
72
|
@property({ attribute: false })
|
|
53
73
|
accessor metrics: IHarnessSessionMetrics = {};
|
|
54
74
|
|
|
@@ -313,6 +333,103 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
313
333
|
min-width: 0;
|
|
314
334
|
}
|
|
315
335
|
|
|
336
|
+
.activityList,
|
|
337
|
+
.activityGroup {
|
|
338
|
+
display: grid;
|
|
339
|
+
gap: var(--dees-spacing-sm);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.activityGroup + .activityGroup {
|
|
343
|
+
margin-top: var(--dees-spacing-md);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.activityGroupTitle {
|
|
347
|
+
color: var(--dees-color-text-muted);
|
|
348
|
+
font-size: var(--dees-font-caption2-size, 10px);
|
|
349
|
+
font-weight: 650;
|
|
350
|
+
letter-spacing: 0.04em;
|
|
351
|
+
text-transform: uppercase;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.activityItem {
|
|
355
|
+
display: grid;
|
|
356
|
+
grid-template-columns: 22px minmax(0, 1fr);
|
|
357
|
+
gap: var(--dees-spacing-sm);
|
|
358
|
+
align-items: start;
|
|
359
|
+
min-width: 0;
|
|
360
|
+
padding: var(--dees-spacing-xs) 0;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.activityIcon {
|
|
364
|
+
display: grid;
|
|
365
|
+
place-items: center;
|
|
366
|
+
width: 22px;
|
|
367
|
+
height: 22px;
|
|
368
|
+
border-radius: var(--dees-radius-md);
|
|
369
|
+
background: var(--dees-color-fill-secondary);
|
|
370
|
+
color: var(--dees-color-text-secondary);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.activityItem.status-running .activityIcon,
|
|
374
|
+
.activityItem.status-pending .activityIcon {
|
|
375
|
+
color: var(--dees-color-accent-primary);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.activityItem.status-error .activityIcon {
|
|
379
|
+
color: var(--dees-color-accent-error);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.activityCopy {
|
|
383
|
+
min-width: 0;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.activityTitleRow,
|
|
387
|
+
.activityMeta {
|
|
388
|
+
display: flex;
|
|
389
|
+
align-items: center;
|
|
390
|
+
gap: var(--dees-spacing-xs);
|
|
391
|
+
min-width: 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.activityTitle {
|
|
395
|
+
min-width: 0;
|
|
396
|
+
flex: 1;
|
|
397
|
+
color: var(--dees-color-text-primary);
|
|
398
|
+
font-size: var(--dees-font-control-size-sm, 12px);
|
|
399
|
+
font-weight: 600;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.activityStatus {
|
|
403
|
+
flex: 0 0 auto;
|
|
404
|
+
color: var(--dees-color-text-muted);
|
|
405
|
+
font-size: var(--dees-font-caption2-size, 10px);
|
|
406
|
+
text-transform: capitalize;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.activityItem.status-running .activityStatus,
|
|
410
|
+
.activityItem.status-pending .activityStatus {
|
|
411
|
+
color: var(--dees-color-accent-primary);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.activityItem.status-error .activityStatus {
|
|
415
|
+
color: var(--dees-color-text-error);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.activitySubtitle {
|
|
419
|
+
display: block;
|
|
420
|
+
width: 100%;
|
|
421
|
+
min-width: 0;
|
|
422
|
+
margin-top: 1px;
|
|
423
|
+
color: var(--dees-color-text-secondary);
|
|
424
|
+
font-size: var(--dees-font-caption2-size, 10px);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.activityMeta {
|
|
428
|
+
margin-top: 2px;
|
|
429
|
+
color: var(--dees-color-text-muted);
|
|
430
|
+
font-size: var(--dees-font-caption2-size, 10px);
|
|
431
|
+
}
|
|
432
|
+
|
|
316
433
|
.metricList {
|
|
317
434
|
display: grid;
|
|
318
435
|
gap: 6px;
|
|
@@ -505,6 +622,7 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
505
622
|
return html`
|
|
506
623
|
<div class="sidebar">
|
|
507
624
|
${this.showTasks ? this.renderTasks() : ''}
|
|
625
|
+
${this.toolActivityEntries.length ? this.renderToolActivity() : ''}
|
|
508
626
|
${this.hasMetrics ? this.renderMetrics() : ''}
|
|
509
627
|
${this.scratchpad ? this.renderScratchpad() : ''}
|
|
510
628
|
${this.intelligenceEnabled ? this.renderIntelligence() : ''}
|
|
@@ -516,9 +634,22 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
516
634
|
return Object.values(this.metrics).some((value) => value !== undefined);
|
|
517
635
|
}
|
|
518
636
|
|
|
637
|
+
private get toolActivityEntries(): IToolActivityEntry[] {
|
|
638
|
+
return this.toolMessages
|
|
639
|
+
.filter((message): message is IHarnessMessage & { toolCall: IHarnessToolCall } => Boolean(message.toolCall))
|
|
640
|
+
.map((message) => ({
|
|
641
|
+
key: JSON.stringify([message.id, message.toolCall.id]),
|
|
642
|
+
call: message.toolCall,
|
|
643
|
+
createdAt: message.createdAt ?? message.toolCall.startedAt,
|
|
644
|
+
status: harnessEffectiveToolStatus(message.toolCall),
|
|
645
|
+
}))
|
|
646
|
+
.sort((left, right) => (right.createdAt ?? 0) - (left.createdAt ?? 0));
|
|
647
|
+
}
|
|
648
|
+
|
|
519
649
|
private get availableSections(): TSessionSidebarSection[] {
|
|
520
650
|
return [
|
|
521
651
|
...(this.showTasks ? ['tasks' as const] : []),
|
|
652
|
+
...(this.toolActivityEntries.length ? ['activity' as const] : []),
|
|
522
653
|
...(this.hasMetrics ? ['metrics' as const] : []),
|
|
523
654
|
...(this.scratchpad ? ['scratchpad' as const] : []),
|
|
524
655
|
...(this.intelligenceEnabled ? ['intelligence' as const] : []),
|
|
@@ -527,6 +658,7 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
527
658
|
|
|
528
659
|
private get defaultExpandedSection(): TSessionSidebarSection | undefined {
|
|
529
660
|
if (this.showTasks && this.todos.length > 0) return 'tasks';
|
|
661
|
+
if (this.toolActivityEntries.length) return 'activity';
|
|
530
662
|
if (this.hasMetrics) return 'metrics';
|
|
531
663
|
if (this.scratchpad) return 'scratchpad';
|
|
532
664
|
if (this.intelligenceEnabled) return 'intelligence';
|
|
@@ -580,6 +712,66 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
580
712
|
);
|
|
581
713
|
}
|
|
582
714
|
|
|
715
|
+
private renderToolActivity(): TemplateResult {
|
|
716
|
+
const entries = this.toolActivityEntries;
|
|
717
|
+
const active = entries.filter((entry) => entry.status === 'pending' || entry.status === 'running');
|
|
718
|
+
const history = entries.filter((entry) => entry.status === 'completed' || entry.status === 'error');
|
|
719
|
+
const summary = active.length
|
|
720
|
+
? `${active.length} active · ${history.length} past`
|
|
721
|
+
: `${history.length} past`;
|
|
722
|
+
return this.renderSection(
|
|
723
|
+
'activity',
|
|
724
|
+
'Tools & Subagents',
|
|
725
|
+
'lucide:Wrench',
|
|
726
|
+
html`
|
|
727
|
+
<div class="activityList">
|
|
728
|
+
${active.length ? this.renderActivityGroup('Active', active) : ''}
|
|
729
|
+
${history.length ? this.renderActivityGroup('History', history) : ''}
|
|
730
|
+
</div>
|
|
731
|
+
`,
|
|
732
|
+
summary,
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
private renderActivityGroup(labelArg: string, entriesArg: IToolActivityEntry[]): TemplateResult {
|
|
737
|
+
return html`
|
|
738
|
+
<section class="activityGroup" aria-label=${labelArg}>
|
|
739
|
+
<div class="activityGroupTitle">${labelArg}</div>
|
|
740
|
+
${repeat(
|
|
741
|
+
entriesArg,
|
|
742
|
+
(entry) => entry.key,
|
|
743
|
+
(entry) => this.renderActivityEntry(entry),
|
|
744
|
+
)}
|
|
745
|
+
</section>
|
|
746
|
+
`;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
private renderActivityEntry(entryArg: IToolActivityEntry): TemplateResult {
|
|
750
|
+
const descriptor = this.toolRegistry.resolve(entryArg.call);
|
|
751
|
+
const label = typeof descriptor.label === 'function'
|
|
752
|
+
? descriptor.label(entryArg.call)
|
|
753
|
+
: descriptor.label;
|
|
754
|
+
const subtitle = descriptor.subtitle?.(entryArg.call) ?? '';
|
|
755
|
+
const relativeTime = harnessFormatRelativeTime(entryArg.createdAt);
|
|
756
|
+
return html`
|
|
757
|
+
<article class=${`activityItem status-${entryArg.status}`} data-tool-call-id=${entryArg.call.id}>
|
|
758
|
+
<span class="activityIcon">
|
|
759
|
+
<dees-icon icon=${descriptor.icon} iconSize="13"></dees-icon>
|
|
760
|
+
</span>
|
|
761
|
+
<span class="activityCopy">
|
|
762
|
+
<span class="activityTitleRow">
|
|
763
|
+
<dees-harness-overflow-text class="activityTitle" title=${label}>${label}</dees-harness-overflow-text>
|
|
764
|
+
<span class="activityStatus">${entryArg.status}</span>
|
|
765
|
+
</span>
|
|
766
|
+
${subtitle
|
|
767
|
+
? html`<dees-harness-overflow-text class="activitySubtitle" title=${subtitle}>${subtitle}</dees-harness-overflow-text>`
|
|
768
|
+
: ''}
|
|
769
|
+
${relativeTime ? html`<span class="activityMeta">${relativeTime}</span>` : ''}
|
|
770
|
+
</span>
|
|
771
|
+
</article>
|
|
772
|
+
`;
|
|
773
|
+
}
|
|
774
|
+
|
|
583
775
|
private renderMetrics(): TemplateResult {
|
|
584
776
|
const metrics = this.metrics;
|
|
585
777
|
const percentage = this.contextPercentage;
|