@design.estate/dees-catalog 4.0.3 → 4.1.1
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 +1463 -1176
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.js +8 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.d.ts +14 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.js +171 -7
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-fullscreen.d.ts +26 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-fullscreen.js +211 -0
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.ts +7 -0
- package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.ts +150 -2
- package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-fullscreen.ts +168 -0
package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-fullscreen.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { DeesElement, html, css, customElement, property, cssManager, } from '@design.estate/dees-element';
|
|
36
|
+
import { themeDefaultStyles } from '../../00theme.js';
|
|
37
|
+
import { DeesHarnessToolRegistry, parseMcpName } from '../toolregistry.js';
|
|
38
|
+
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
39
|
+
/**
|
|
40
|
+
* Fullscreen view of one tool card, appended to document.body by
|
|
41
|
+
* DeesHarnessToolCard so it escapes every containment context
|
|
42
|
+
* (content-visibility, transforms) that would trap a position: fixed layer
|
|
43
|
+
* inside the transcript. Emits `tool-fullscreen-close` on Escape, backdrop
|
|
44
|
+
* press, or the minimize button; the owning card removes it and flashes.
|
|
45
|
+
*/
|
|
46
|
+
let DeesHarnessToolFullscreen = (() => {
|
|
47
|
+
let _classDecorators = [customElement('dees-harness-tool-fullscreen')];
|
|
48
|
+
let _classDescriptor;
|
|
49
|
+
let _classExtraInitializers = [];
|
|
50
|
+
let _classThis;
|
|
51
|
+
let _classSuper = DeesElement;
|
|
52
|
+
let _call_decorators;
|
|
53
|
+
let _call_initializers = [];
|
|
54
|
+
let _call_extraInitializers = [];
|
|
55
|
+
let _toolRegistry_decorators;
|
|
56
|
+
let _toolRegistry_initializers = [];
|
|
57
|
+
let _toolRegistry_extraInitializers = [];
|
|
58
|
+
var DeesHarnessToolFullscreen = class extends _classSuper {
|
|
59
|
+
static { _classThis = this; }
|
|
60
|
+
static {
|
|
61
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
62
|
+
_call_decorators = [property({ attribute: false })];
|
|
63
|
+
_toolRegistry_decorators = [property({ attribute: false })];
|
|
64
|
+
__esDecorate(this, null, _call_decorators, { kind: "accessor", name: "call", static: false, private: false, access: { has: obj => "call" in obj, get: obj => obj.call, set: (obj, value) => { obj.call = value; } }, metadata: _metadata }, _call_initializers, _call_extraInitializers);
|
|
65
|
+
__esDecorate(this, null, _toolRegistry_decorators, { kind: "accessor", name: "toolRegistry", static: false, private: false, access: { has: obj => "toolRegistry" in obj, get: obj => obj.toolRegistry, set: (obj, value) => { obj.toolRegistry = value; } }, metadata: _metadata }, _toolRegistry_initializers, _toolRegistry_extraInitializers);
|
|
66
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
67
|
+
DeesHarnessToolFullscreen = _classThis = _classDescriptor.value;
|
|
68
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
69
|
+
}
|
|
70
|
+
#call_accessor_storage = __runInitializers(this, _call_initializers, { id: '', name: '', status: 'pending' });
|
|
71
|
+
get call() { return this.#call_accessor_storage; }
|
|
72
|
+
set call(value) { this.#call_accessor_storage = value; }
|
|
73
|
+
#toolRegistry_accessor_storage = (__runInitializers(this, _call_extraInitializers), __runInitializers(this, _toolRegistry_initializers, DeesHarnessToolRegistry.default));
|
|
74
|
+
get toolRegistry() { return this.#toolRegistry_accessor_storage; }
|
|
75
|
+
set toolRegistry(value) { this.#toolRegistry_accessor_storage = value; }
|
|
76
|
+
static styles = [
|
|
77
|
+
themeDefaultStyles,
|
|
78
|
+
cssManager.defaultStyles,
|
|
79
|
+
css `
|
|
80
|
+
:host {
|
|
81
|
+
position: fixed;
|
|
82
|
+
inset: 0;
|
|
83
|
+
z-index: 4000;
|
|
84
|
+
display: grid;
|
|
85
|
+
place-items: center;
|
|
86
|
+
padding: 4vh 3vw;
|
|
87
|
+
background: color-mix(in srgb, var(--dees-color-bg-primary) 55%, transparent);
|
|
88
|
+
backdrop-filter: blur(6px);
|
|
89
|
+
font-family: var(--dees-font-family);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.panel {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
width: min(1200px, 100%);
|
|
96
|
+
height: 100%;
|
|
97
|
+
min-height: 0;
|
|
98
|
+
border: 1px solid var(--dees-color-border-default);
|
|
99
|
+
border-radius: var(--dees-radius-lg);
|
|
100
|
+
background: var(--dees-color-bg-primary);
|
|
101
|
+
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.panelHeader {
|
|
106
|
+
display: flex;
|
|
107
|
+
flex: 0 0 auto;
|
|
108
|
+
align-items: center;
|
|
109
|
+
gap: var(--dees-spacing-sm);
|
|
110
|
+
padding: var(--dees-spacing-sm) var(--dees-spacing-md);
|
|
111
|
+
border-bottom: 1px solid var(--dees-color-border-subtle);
|
|
112
|
+
color: var(--dees-color-text-primary);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.panelTitle {
|
|
116
|
+
min-width: 0;
|
|
117
|
+
overflow: hidden;
|
|
118
|
+
text-overflow: ellipsis;
|
|
119
|
+
white-space: nowrap;
|
|
120
|
+
font-size: var(--dees-font-control-size-sm, 12px);
|
|
121
|
+
font-weight: 650;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.panelClose {
|
|
125
|
+
display: grid;
|
|
126
|
+
place-items: center;
|
|
127
|
+
margin-left: auto;
|
|
128
|
+
padding: 6px;
|
|
129
|
+
border: 0;
|
|
130
|
+
border-radius: var(--dees-radius-md);
|
|
131
|
+
background: transparent;
|
|
132
|
+
color: var(--dees-color-text-secondary);
|
|
133
|
+
cursor: pointer;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.panelClose:hover {
|
|
137
|
+
background: var(--dees-color-hover);
|
|
138
|
+
color: var(--dees-color-text-primary);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.panelBody {
|
|
142
|
+
flex: 1;
|
|
143
|
+
min-height: 0;
|
|
144
|
+
overflow: auto;
|
|
145
|
+
padding: var(--dees-spacing-md);
|
|
146
|
+
scrollbar-width: thin;
|
|
147
|
+
scrollbar-color: var(--dees-color-scrollbar-thumb) transparent;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.panelBody dees-harness-tool-card {
|
|
151
|
+
display: block;
|
|
152
|
+
}
|
|
153
|
+
`,
|
|
154
|
+
];
|
|
155
|
+
render() {
|
|
156
|
+
const parsed = this.call.mcp ? undefined : parseMcpName(this.call.name);
|
|
157
|
+
const enriched = parsed
|
|
158
|
+
? { ...this.call, mcp: { serverName: parsed.serverName, toolName: parsed.toolName } }
|
|
159
|
+
: this.call;
|
|
160
|
+
const descriptor = this.toolRegistry.resolve(enriched);
|
|
161
|
+
const label = typeof descriptor.label === 'function' ? descriptor.label(enriched) : descriptor.label;
|
|
162
|
+
const subtitle = descriptor.subtitle?.(enriched) ?? '';
|
|
163
|
+
return html `
|
|
164
|
+
<div class="panel" @click=${(event) => event.stopPropagation()}>
|
|
165
|
+
<header class="panelHeader">
|
|
166
|
+
<dees-icon .icon=${descriptor.icon} iconSize="15"></dees-icon>
|
|
167
|
+
<span class="panelTitle">${label}${subtitle ? ` · ${subtitle}` : ''}</span>
|
|
168
|
+
<button class="panelClose" type="button" @click=${this.emitClose}>
|
|
169
|
+
<dees-icon icon="lucide:Minimize2" iconSize="15"></dees-icon>
|
|
170
|
+
</button>
|
|
171
|
+
</header>
|
|
172
|
+
<div class="panelBody">
|
|
173
|
+
<dees-harness-tool-card
|
|
174
|
+
.call=${this.call}
|
|
175
|
+
.toolRegistry=${this.toolRegistry}
|
|
176
|
+
.expanded=${true}
|
|
177
|
+
.outputExpanded=${true}
|
|
178
|
+
uncapped
|
|
179
|
+
></dees-harness-tool-card>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
`;
|
|
183
|
+
}
|
|
184
|
+
firstUpdated() {
|
|
185
|
+
window.addEventListener('keydown', this.handleKeydown);
|
|
186
|
+
this.addEventListener('click', (event) => {
|
|
187
|
+
if (event.target === this)
|
|
188
|
+
this.emitClose();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
handleKeydown = (__runInitializers(this, _toolRegistry_extraInitializers), (event) => {
|
|
192
|
+
if (event.key === 'Escape') {
|
|
193
|
+
event.preventDefault();
|
|
194
|
+
this.emitClose();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
emitClose = () => {
|
|
198
|
+
this.dispatchEvent(new CustomEvent('tool-fullscreen-close', { bubbles: false }));
|
|
199
|
+
};
|
|
200
|
+
async disconnectedCallback() {
|
|
201
|
+
window.removeEventListener('keydown', this.handleKeydown);
|
|
202
|
+
await super.disconnectedCallback();
|
|
203
|
+
}
|
|
204
|
+
static {
|
|
205
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
return DeesHarnessToolFullscreen = _classThis;
|
|
209
|
+
})();
|
|
210
|
+
export { DeesHarnessToolFullscreen };
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy1oYXJuZXNzLXRvb2wtZnVsbHNjcmVlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzX3dlYi9lbGVtZW50cy8wMGdyb3VwLWhhcm5lc3MvZGVlcy1oYXJuZXNzLXRvb2wtY2FyZC9kZWVzLWhhcm5lc3MtdG9vbC1mdWxsc2NyZWVuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsV0FBVyxFQUNYLElBQUksRUFDSixHQUFHLEVBQ0gsYUFBYSxFQUViLFFBQVEsRUFDUixVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDM0UsT0FBTyw4Q0FBOEMsQ0FBQztBQVF0RDs7Ozs7O0dBTUc7SUFFVSx5QkFBeUI7NEJBRHJDLGFBQWEsQ0FBQyw4QkFBOEIsQ0FBQzs7OztzQkFDQyxXQUFXOzs7Ozs7O3lDQUFuQixTQUFRLFdBQVc7Ozs7Z0NBQ3ZELFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQzt3Q0FHOUIsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBRi9CLGlLQUFTLElBQUksNkJBQUosSUFBSSxtRkFBNkQ7WUFHMUUseUxBQVMsWUFBWSw2QkFBWixZQUFZLG1HQUE0RDtZQUxuRiw2S0EySUM7Ozs7UUF6SUMscUVBQWtDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFBQztRQUExRSxJQUFTLElBQUksMENBQTZEO1FBQTFFLElBQVMsSUFBSSxnREFBNkQ7UUFHMUUsd0lBQWlELHVCQUF1QixDQUFDLE9BQU8sR0FBQztRQUFq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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design.estate/dees-catalog",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
|
|
6
6
|
"main": "dist_ts_web/index.js",
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/dees-catalog',
|
|
6
|
-
version: '4.
|
|
6
|
+
version: '4.1.1',
|
|
7
7
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
|
8
8
|
}
|
|
@@ -81,6 +81,13 @@ export class DeesHarnessMessage extends DeesElement {
|
|
|
81
81
|
boundary instead of widening the whole conversation; scrollable
|
|
82
82
|
payload blocks inside keep their own horizontal scrollbars. */
|
|
83
83
|
overflow-x: clip;
|
|
84
|
+
/* Virtualized rendering: cards outside the viewport skip style,
|
|
85
|
+
layout, and paint entirely and re-render when scrolled back —
|
|
86
|
+
state and DOM stay, so expansion and selection survive. The
|
|
87
|
+
'auto' keyword keeps the last rendered size as the placeholder,
|
|
88
|
+
holding the scrollbar steady. */
|
|
89
|
+
content-visibility: auto;
|
|
90
|
+
contain-intrinsic-size: auto 96px;
|
|
84
91
|
font-family: var(--dees-font-family);
|
|
85
92
|
/* entry: new boxes make space for themselves while fading in.
|
|
86
93
|
A keyframes animation (not a transition) so the parent tree's
|
|
@@ -22,6 +22,7 @@ import { harnessCardStyles, harnessPillStyles, harnessMonoStyles } from '../harn
|
|
|
22
22
|
import { harnessFormatDuration, harnessTruncate } from '../harness.helpers.js';
|
|
23
23
|
import '../dees-harness-content-blocks/dees-harness-content-blocks.js';
|
|
24
24
|
import '../../00group-dataview/dees-dataview-codebox/dees-dataview-codebox.js';
|
|
25
|
+
import './dees-harness-tool-fullscreen.js';
|
|
25
26
|
import '../../00group-feedback/dees-badge/dees-badge.js';
|
|
26
27
|
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
27
28
|
|
|
@@ -54,6 +55,24 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
54
55
|
@state()
|
|
55
56
|
accessor outputExpanded: boolean = false;
|
|
56
57
|
|
|
58
|
+
/** Body height cap; taller content scrolls in place and offers fullscreen. */
|
|
59
|
+
@property({ type: Number })
|
|
60
|
+
accessor bodyCapPx: number = 360;
|
|
61
|
+
|
|
62
|
+
/** Set on the card inside the fullscreen modal: no cap, no maximize bar. */
|
|
63
|
+
@property({ type: Boolean })
|
|
64
|
+
accessor uncapped: boolean = false;
|
|
65
|
+
|
|
66
|
+
@state()
|
|
67
|
+
accessor bodyOverflowing: boolean = false;
|
|
68
|
+
|
|
69
|
+
@state()
|
|
70
|
+
accessor returnFlash: boolean = false;
|
|
71
|
+
|
|
72
|
+
private bodyResizeObserver: ResizeObserver | null = null;
|
|
73
|
+
private observedBodyInner: Element | null = null;
|
|
74
|
+
private fullscreenPortal: HTMLElementTagNameMap['dees-harness-tool-fullscreen'] | null = null;
|
|
75
|
+
|
|
57
76
|
public static styles = [
|
|
58
77
|
themeDefaultStyles,
|
|
59
78
|
cssManager.defaultStyles,
|
|
@@ -180,6 +199,59 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
180
199
|
dees-dataview-codebox {
|
|
181
200
|
font-family: var(--dees-font-family);
|
|
182
201
|
}
|
|
202
|
+
|
|
203
|
+
/* Three body modes: collapsed (no body), normal (content fits the
|
|
204
|
+
cap), capped (content taller than the cap scrolls inside the frame
|
|
205
|
+
and offers the fullscreen modal). */
|
|
206
|
+
.bodyClipFrame {
|
|
207
|
+
position: relative;
|
|
208
|
+
overflow-y: auto;
|
|
209
|
+
overflow-x: hidden;
|
|
210
|
+
scrollbar-width: thin;
|
|
211
|
+
scrollbar-color: var(--dees-color-scrollbar-thumb) transparent;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.maximizeBar {
|
|
215
|
+
display: flex;
|
|
216
|
+
align-items: center;
|
|
217
|
+
justify-content: center;
|
|
218
|
+
gap: var(--dees-spacing-xs);
|
|
219
|
+
width: 100%;
|
|
220
|
+
padding: var(--dees-spacing-xs) var(--dees-spacing-md);
|
|
221
|
+
border: 0;
|
|
222
|
+
border-top: 1px solid var(--dees-color-border-subtle);
|
|
223
|
+
background: transparent;
|
|
224
|
+
color: var(--dees-color-link);
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
font-family: inherit;
|
|
227
|
+
font-size: var(--dees-font-control-size-sm, 12px);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.maximizeBar:hover {
|
|
231
|
+
background: var(--dees-color-hover);
|
|
232
|
+
color: var(--dees-color-link-hover);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* Locates the card after minimizing: a brief highlight pulse. */
|
|
236
|
+
.harness-card.returnFlash {
|
|
237
|
+
animation: harness-card-return-flash 1.4s var(--dees-ease-standard);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@keyframes harness-card-return-flash {
|
|
241
|
+
0%, 55% {
|
|
242
|
+
box-shadow: 0 0 0 2px var(--dees-color-accent-primary);
|
|
243
|
+
}
|
|
244
|
+
100% {
|
|
245
|
+
box-shadow: 0 0 0 0 transparent;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@media (prefers-reduced-motion: reduce) {
|
|
250
|
+
.harness-card.returnFlash {
|
|
251
|
+
animation: none;
|
|
252
|
+
box-shadow: 0 0 0 2px var(--dees-color-accent-primary);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
183
255
|
`,
|
|
184
256
|
];
|
|
185
257
|
|
|
@@ -210,7 +282,13 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
210
282
|
const statusTone = call.isError ? 'error' : call.status === 'completed' ? 'success' : call.status;
|
|
211
283
|
const duration = harnessFormatDuration(call.startedAt, call.finishedAt);
|
|
212
284
|
return html`
|
|
213
|
-
<div class="harness-card status-${call.isError ? 'error' : call.status} ${descriptor.destructive ? 'destructive' : ''}"
|
|
285
|
+
<div class="harness-card status-${call.isError ? 'error' : call.status} ${descriptor.destructive ? 'destructive' : ''} ${this.returnFlash ? 'returnFlash' : ''}"
|
|
286
|
+
@animationend=${(event: AnimationEvent) => {
|
|
287
|
+
if (event.animationName === 'harness-card-return-flash') {
|
|
288
|
+
this.returnFlash = false;
|
|
289
|
+
}
|
|
290
|
+
}}
|
|
291
|
+
>
|
|
214
292
|
<button
|
|
215
293
|
class="header"
|
|
216
294
|
type="button"
|
|
@@ -234,11 +312,81 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
234
312
|
</span>
|
|
235
313
|
</span>
|
|
236
314
|
</button>
|
|
237
|
-
${this.isOpen
|
|
315
|
+
${this.isOpen
|
|
316
|
+
? html`
|
|
317
|
+
<div
|
|
318
|
+
class="bodyClipFrame"
|
|
319
|
+
style=${this.uncapped ? '' : `max-height: ${this.bodyCapPx}px;`}
|
|
320
|
+
>
|
|
321
|
+
<div class="body bodyInner">${this.renderBody(call)}</div>
|
|
322
|
+
</div>
|
|
323
|
+
${this.bodyOverflowing && !this.uncapped
|
|
324
|
+
? html`
|
|
325
|
+
<button class="maximizeBar" type="button" @click=${this.openFullscreen}>
|
|
326
|
+
<dees-icon icon="lucide:Maximize2" iconSize="12"></dees-icon>
|
|
327
|
+
Show everything
|
|
328
|
+
</button>
|
|
329
|
+
`
|
|
330
|
+
: ''}
|
|
331
|
+
`
|
|
332
|
+
: ''}
|
|
238
333
|
</div>
|
|
239
334
|
`;
|
|
240
335
|
}
|
|
241
336
|
|
|
337
|
+
private readonly openFullscreen = (): void => {
|
|
338
|
+
if (this.fullscreenPortal) return;
|
|
339
|
+
// Appended to document.body: content-visibility containment in the
|
|
340
|
+
// transcript would trap a position: fixed layer inside this card.
|
|
341
|
+
const portal = document.createElement('dees-harness-tool-fullscreen');
|
|
342
|
+
portal.call = this.enrichedCall;
|
|
343
|
+
portal.toolRegistry = this.toolRegistry;
|
|
344
|
+
portal.addEventListener('tool-fullscreen-close', this.closeFullscreen, { once: true });
|
|
345
|
+
document.body.append(portal);
|
|
346
|
+
this.fullscreenPortal = portal;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
private readonly closeFullscreen = (): void => {
|
|
350
|
+
const portal = this.fullscreenPortal;
|
|
351
|
+
if (!portal) return;
|
|
352
|
+
this.fullscreenPortal = null;
|
|
353
|
+
portal.remove();
|
|
354
|
+
// The flash locates the card the user was just reading in fullscreen.
|
|
355
|
+
this.returnFlash = true;
|
|
356
|
+
requestAnimationFrame(() => {
|
|
357
|
+
this.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
|
358
|
+
});
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
public updated(changedProperties: Map<PropertyKey, unknown>): void {
|
|
362
|
+
super.updated(changedProperties);
|
|
363
|
+
if (this.uncapped) return;
|
|
364
|
+
const bodyInner = this.shadowRoot?.querySelector('.bodyInner') ?? null;
|
|
365
|
+
if (bodyInner === this.observedBodyInner) return;
|
|
366
|
+
this.bodyResizeObserver?.disconnect();
|
|
367
|
+
this.observedBodyInner = bodyInner;
|
|
368
|
+
if (!bodyInner) {
|
|
369
|
+
this.bodyOverflowing = false;
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
this.bodyResizeObserver ??= new ResizeObserver(() => {
|
|
373
|
+
const inner = this.observedBodyInner;
|
|
374
|
+
if (!inner) return;
|
|
375
|
+
// small slack so a few px never trigger the cap chrome
|
|
376
|
+
this.bodyOverflowing = inner.scrollHeight > this.bodyCapPx + 24;
|
|
377
|
+
});
|
|
378
|
+
this.bodyResizeObserver.observe(bodyInner);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
public async disconnectedCallback(): Promise<void> {
|
|
382
|
+
this.fullscreenPortal?.remove();
|
|
383
|
+
this.fullscreenPortal = null;
|
|
384
|
+
this.bodyResizeObserver?.disconnect();
|
|
385
|
+
this.bodyResizeObserver = null;
|
|
386
|
+
this.observedBodyInner = null;
|
|
387
|
+
await super.disconnectedCallback();
|
|
388
|
+
}
|
|
389
|
+
|
|
242
390
|
private renderMcpBadges(call: IHarnessToolCall): TemplateResult {
|
|
243
391
|
if (!call.mcp) return html``;
|
|
244
392
|
const annotations = call.mcp.annotations;
|
package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-fullscreen.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
html,
|
|
4
|
+
css,
|
|
5
|
+
customElement,
|
|
6
|
+
type TemplateResult,
|
|
7
|
+
property,
|
|
8
|
+
cssManager,
|
|
9
|
+
} from '@design.estate/dees-element';
|
|
10
|
+
import { themeDefaultStyles } from '../../00theme.js';
|
|
11
|
+
import type { IHarnessToolCall } from '../interfaces.js';
|
|
12
|
+
import { DeesHarnessToolRegistry, parseMcpName } from '../toolregistry.js';
|
|
13
|
+
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface HTMLElementTagNameMap {
|
|
17
|
+
'dees-harness-tool-fullscreen': DeesHarnessToolFullscreen;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fullscreen view of one tool card, appended to document.body by
|
|
23
|
+
* DeesHarnessToolCard so it escapes every containment context
|
|
24
|
+
* (content-visibility, transforms) that would trap a position: fixed layer
|
|
25
|
+
* inside the transcript. Emits `tool-fullscreen-close` on Escape, backdrop
|
|
26
|
+
* press, or the minimize button; the owning card removes it and flashes.
|
|
27
|
+
*/
|
|
28
|
+
@customElement('dees-harness-tool-fullscreen')
|
|
29
|
+
export class DeesHarnessToolFullscreen extends DeesElement {
|
|
30
|
+
@property({ attribute: false })
|
|
31
|
+
accessor call: IHarnessToolCall = { id: '', name: '', status: 'pending' };
|
|
32
|
+
|
|
33
|
+
@property({ attribute: false })
|
|
34
|
+
accessor toolRegistry: DeesHarnessToolRegistry = DeesHarnessToolRegistry.default;
|
|
35
|
+
|
|
36
|
+
public static styles = [
|
|
37
|
+
themeDefaultStyles,
|
|
38
|
+
cssManager.defaultStyles,
|
|
39
|
+
css`
|
|
40
|
+
:host {
|
|
41
|
+
position: fixed;
|
|
42
|
+
inset: 0;
|
|
43
|
+
z-index: 4000;
|
|
44
|
+
display: grid;
|
|
45
|
+
place-items: center;
|
|
46
|
+
padding: 4vh 3vw;
|
|
47
|
+
background: color-mix(in srgb, var(--dees-color-bg-primary) 55%, transparent);
|
|
48
|
+
backdrop-filter: blur(6px);
|
|
49
|
+
font-family: var(--dees-font-family);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.panel {
|
|
53
|
+
display: flex;
|
|
54
|
+
flex-direction: column;
|
|
55
|
+
width: min(1200px, 100%);
|
|
56
|
+
height: 100%;
|
|
57
|
+
min-height: 0;
|
|
58
|
+
border: 1px solid var(--dees-color-border-default);
|
|
59
|
+
border-radius: var(--dees-radius-lg);
|
|
60
|
+
background: var(--dees-color-bg-primary);
|
|
61
|
+
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.4);
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.panelHeader {
|
|
66
|
+
display: flex;
|
|
67
|
+
flex: 0 0 auto;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: var(--dees-spacing-sm);
|
|
70
|
+
padding: var(--dees-spacing-sm) var(--dees-spacing-md);
|
|
71
|
+
border-bottom: 1px solid var(--dees-color-border-subtle);
|
|
72
|
+
color: var(--dees-color-text-primary);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.panelTitle {
|
|
76
|
+
min-width: 0;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
text-overflow: ellipsis;
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
font-size: var(--dees-font-control-size-sm, 12px);
|
|
81
|
+
font-weight: 650;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.panelClose {
|
|
85
|
+
display: grid;
|
|
86
|
+
place-items: center;
|
|
87
|
+
margin-left: auto;
|
|
88
|
+
padding: 6px;
|
|
89
|
+
border: 0;
|
|
90
|
+
border-radius: var(--dees-radius-md);
|
|
91
|
+
background: transparent;
|
|
92
|
+
color: var(--dees-color-text-secondary);
|
|
93
|
+
cursor: pointer;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.panelClose:hover {
|
|
97
|
+
background: var(--dees-color-hover);
|
|
98
|
+
color: var(--dees-color-text-primary);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.panelBody {
|
|
102
|
+
flex: 1;
|
|
103
|
+
min-height: 0;
|
|
104
|
+
overflow: auto;
|
|
105
|
+
padding: var(--dees-spacing-md);
|
|
106
|
+
scrollbar-width: thin;
|
|
107
|
+
scrollbar-color: var(--dees-color-scrollbar-thumb) transparent;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.panelBody dees-harness-tool-card {
|
|
111
|
+
display: block;
|
|
112
|
+
}
|
|
113
|
+
`,
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
public render(): TemplateResult {
|
|
117
|
+
const parsed = this.call.mcp ? undefined : parseMcpName(this.call.name);
|
|
118
|
+
const enriched = parsed
|
|
119
|
+
? { ...this.call, mcp: { serverName: parsed.serverName, toolName: parsed.toolName } }
|
|
120
|
+
: this.call;
|
|
121
|
+
const descriptor = this.toolRegistry.resolve(enriched);
|
|
122
|
+
const label = typeof descriptor.label === 'function' ? descriptor.label(enriched) : descriptor.label;
|
|
123
|
+
const subtitle = descriptor.subtitle?.(enriched) ?? '';
|
|
124
|
+
return html`
|
|
125
|
+
<div class="panel" @click=${(event: Event) => event.stopPropagation()}>
|
|
126
|
+
<header class="panelHeader">
|
|
127
|
+
<dees-icon .icon=${descriptor.icon} iconSize="15"></dees-icon>
|
|
128
|
+
<span class="panelTitle">${label}${subtitle ? ` · ${subtitle}` : ''}</span>
|
|
129
|
+
<button class="panelClose" type="button" @click=${this.emitClose}>
|
|
130
|
+
<dees-icon icon="lucide:Minimize2" iconSize="15"></dees-icon>
|
|
131
|
+
</button>
|
|
132
|
+
</header>
|
|
133
|
+
<div class="panelBody">
|
|
134
|
+
<dees-harness-tool-card
|
|
135
|
+
.call=${this.call}
|
|
136
|
+
.toolRegistry=${this.toolRegistry}
|
|
137
|
+
.expanded=${true}
|
|
138
|
+
.outputExpanded=${true}
|
|
139
|
+
uncapped
|
|
140
|
+
></dees-harness-tool-card>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public firstUpdated(): void {
|
|
147
|
+
window.addEventListener('keydown', this.handleKeydown);
|
|
148
|
+
this.addEventListener('click', (event) => {
|
|
149
|
+
if (event.target === this) this.emitClose();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private readonly handleKeydown = (event: KeyboardEvent): void => {
|
|
154
|
+
if (event.key === 'Escape') {
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
this.emitClose();
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
private readonly emitClose = (): void => {
|
|
161
|
+
this.dispatchEvent(new CustomEvent('tool-fullscreen-close', { bubbles: false }));
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
public async disconnectedCallback(): Promise<void> {
|
|
165
|
+
window.removeEventListener('keydown', this.handleKeydown);
|
|
166
|
+
await super.disconnectedCallback();
|
|
167
|
+
}
|
|
168
|
+
}
|