@artooi/ag-ui-web-component 0.33.1 → 0.35.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/CHANGELOG.md +563 -1
- package/README.md +279 -16
- package/dist/ag-ui-web-component.bundle.js +676 -101
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +80 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +37 -2
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/dom/animations.d.ts +14 -0
- package/dist/dom/animations.d.ts.map +1 -1
- package/dist/dom/highlight_overlay.d.ts +47 -0
- package/dist/dom/highlight_overlay.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2288 -388
- package/dist/index.js.map +4 -4
- package/dist/tools/chat_surface_tools.d.ts +96 -0
- package/dist/tools/chat_surface_tools.d.ts.map +1 -0
- package/dist/tools/page_action_tools.d.ts +2 -0
- package/dist/tools/page_action_tools.d.ts.map +1 -1
- package/dist/ui/chart_block.d.ts +18 -0
- package/dist/ui/chart_block.d.ts.map +1 -1
- package/dist/ui/clamp_launcher.d.ts +10 -5
- package/dist/ui/clamp_launcher.d.ts.map +1 -1
- package/dist/ui/clamp_panel.d.ts +13 -0
- package/dist/ui/clamp_panel.d.ts.map +1 -0
- package/dist/ui/launcher_drag.d.ts +2 -2
- package/dist/ui/launcher_drag.d.ts.map +1 -1
- package/dist/ui/launcher_placement.d.ts +14 -1
- package/dist/ui/launcher_placement.d.ts.map +1 -1
- package/dist/ui/panel_drag.d.ts +40 -0
- package/dist/ui/panel_drag.d.ts.map +1 -0
- package/dist/ui/place_widget.d.ts +31 -0
- package/dist/ui/place_widget.d.ts.map +1 -0
- package/dist/ui/run_notice.d.ts +14 -3
- package/dist/ui/run_notice.d.ts.map +1 -1
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/thread_drawer.d.ts +21 -0
- package/dist/ui/thread_drawer.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +16 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +87 -0
- package/src/core/ag_ui_chat.ts +1146 -38
- package/src/dom/animations.ts +30 -0
- package/src/dom/highlight_overlay.ts +256 -0
- package/src/index.ts +12 -0
- package/src/tools/chat_surface_tools.ts +207 -0
- package/src/tools/page_action_tools.ts +2 -0
- package/src/ui/chart_block.ts +222 -57
- package/src/ui/clamp_launcher.ts +25 -7
- package/src/ui/clamp_panel.ts +30 -0
- package/src/ui/launcher_drag.ts +11 -2
- package/src/ui/launcher_placement.ts +50 -60
- package/src/ui/panel_drag.ts +138 -0
- package/src/ui/place_widget.ts +64 -0
- package/src/ui/run_notice.ts +32 -3
- package/src/ui/styles.ts +622 -47
- package/src/ui/thread_drawer.ts +138 -8
- package/src/ui/ui_strings.ts +24 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { ClientTool } from "./client_tool_registry.js";
|
|
2
|
+
/** Every corner the panel can be sent to, in the order the schema states them. */
|
|
3
|
+
export declare const CHAT_CORNERS: readonly ["top-left", "top-right", "bottom-left", "bottom-right"];
|
|
4
|
+
/** A corner the panel can be sent to. */
|
|
5
|
+
export type ChatCorner = (typeof CHAT_CORNERS)[number];
|
|
6
|
+
/** What the agent is told about the surface it is speaking from. */
|
|
7
|
+
export interface ChatSurfaceReport {
|
|
8
|
+
/** The placement in force, or `null` when the host set none. */
|
|
9
|
+
readonly placement: string | null;
|
|
10
|
+
/** Whether the panel is currently at its launcher. */
|
|
11
|
+
readonly collapsed: boolean;
|
|
12
|
+
/** Whether this placement has a collapsed state at all. */
|
|
13
|
+
readonly collapsible: boolean;
|
|
14
|
+
/** Whether the panel can be moved, or the placement owns its position. */
|
|
15
|
+
readonly movable: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether this page allows the panel to be moved at all.
|
|
18
|
+
*
|
|
19
|
+
* Reported apart from {@link ChatSurfaceReport.movable} only because the two
|
|
20
|
+
* reasons a move is refused call for different sentences: a host that turned
|
|
21
|
+
* dragging off is not the placement owning the position, and telling the
|
|
22
|
+
* user the second when the first is true is a plain falsehood.
|
|
23
|
+
*/
|
|
24
|
+
readonly draggable: boolean;
|
|
25
|
+
/** Whether the panel currently covers the whole viewport. */
|
|
26
|
+
readonly fullBleed: boolean;
|
|
27
|
+
/** The panel's box, in viewport coordinates. */
|
|
28
|
+
readonly box: {
|
|
29
|
+
readonly left: number;
|
|
30
|
+
readonly top: number;
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The part of the viewport the panel may rest in.
|
|
36
|
+
*
|
|
37
|
+
* With an origin, because it is not always the screen's: a host can reserve
|
|
38
|
+
* the edges its own chrome occupies, and an agent reasoning about the room
|
|
39
|
+
* to the left of `box.left` would otherwise be mixing two coordinate frames
|
|
40
|
+
* without being told there were two.
|
|
41
|
+
*/
|
|
42
|
+
readonly viewport: {
|
|
43
|
+
readonly left: number;
|
|
44
|
+
readonly top: number;
|
|
45
|
+
readonly width: number;
|
|
46
|
+
readonly height: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Whether a string names one of the four corners. */
|
|
50
|
+
export declare function isChatCorner(value: string): value is ChatCorner;
|
|
51
|
+
/**
|
|
52
|
+
* The part of the widget these tools drive.
|
|
53
|
+
*
|
|
54
|
+
* A narrow port rather than the element itself, because the element imports
|
|
55
|
+
* this module to build its own tools and importing it back would be a cycle.
|
|
56
|
+
* It also says exactly what the agent is allowed to reach, which is a shorter
|
|
57
|
+
* list than the element's public surface.
|
|
58
|
+
*/
|
|
59
|
+
export interface ChatSurface {
|
|
60
|
+
describeSurface(): ChatSurfaceReport;
|
|
61
|
+
/**
|
|
62
|
+
* `announce` writes a notice into the transcript with an undo beside it.
|
|
63
|
+
* The tools always pass it: a panel that rearranges itself mid-conversation
|
|
64
|
+
* has to say so, and a host driving the same method is arranging its own
|
|
65
|
+
* page and needs no telling.
|
|
66
|
+
*/
|
|
67
|
+
moveTo(corner: ChatCorner, options?: {
|
|
68
|
+
readonly announce?: boolean;
|
|
69
|
+
}): boolean;
|
|
70
|
+
setCollapsed(collapsed: boolean, options?: {
|
|
71
|
+
readonly announce?: boolean;
|
|
72
|
+
}): void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Tools that let the agent move the panel it is speaking from.
|
|
76
|
+
*
|
|
77
|
+
* This is the affordance nobody else can offer: every other assistant's chat
|
|
78
|
+
* is a surface of its own, so there is nothing for it to be in the way *of*.
|
|
79
|
+
* Ours is mounted in the page the user is working in, which is what makes
|
|
80
|
+
* "let me move this aside so you can see the table" a sentence the agent can
|
|
81
|
+
* act on rather than apologise for.
|
|
82
|
+
*
|
|
83
|
+
* **They report what happened, not what was asked.** A full-bleed panel on a
|
|
84
|
+
* phone has nowhere to move to, and a placement that places itself owns its
|
|
85
|
+
* position -- so `move_chat` answers `moved: false` with the reason and what
|
|
86
|
+
* would work instead, rather than returning success on a panel that did not
|
|
87
|
+
* budge. The same rule the page actions already follow: a tool reports that it
|
|
88
|
+
* fired, not that it worked.
|
|
89
|
+
*
|
|
90
|
+
* `read_chat_surface` exists so the agent can ask before it acts rather than
|
|
91
|
+
* discovering the answer through a failure. It is deliberately a tool and not
|
|
92
|
+
* ambient context: a snapshot the agent chose to take is honest about being
|
|
93
|
+
* one, and it needs no channel that does not already exist.
|
|
94
|
+
*/
|
|
95
|
+
export declare function createChatSurfaceTools(surface: ChatSurface): ClientTool[];
|
|
96
|
+
//# sourceMappingURL=chat_surface_tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat_surface_tools.d.ts","sourceRoot":"","sources":["../../src/tools/chat_surface_tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,kFAAkF;AAClF,eAAO,MAAM,YAAY,YAAI,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,CAAU,CAAC;AAE9F,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,eAAe,IAAI,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/E,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,EAAE,CA2GzE"}
|
|
@@ -9,6 +9,8 @@ export type ResolvePageTarget = (target: string) => HTMLElement | null;
|
|
|
9
9
|
export declare const PAGE_ACTIONS: {
|
|
10
10
|
readonly SCROLL: "scroll";
|
|
11
11
|
readonly DRAG: "drag";
|
|
12
|
+
/** The widget's own position: see `createChatSurfaceTools`. */
|
|
13
|
+
readonly CHAT: "chat";
|
|
12
14
|
};
|
|
13
15
|
/**
|
|
14
16
|
* The opt-in page-action tools selected by `enabled` (a set of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page_action_tools.d.ts","sourceRoot":"","sources":["../../src/tools/page_action_tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;AAEvE,8EAA8E;AAC9E,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,aAAa,EAAE,iBAAiB,GAC/B,UAAU,EAAE,CASd"}
|
|
1
|
+
{"version":3,"file":"page_action_tools.d.ts","sourceRoot":"","sources":["../../src/tools/page_action_tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;AAEvE,8EAA8E;AAC9E,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,IAAI,EAAE,MAAM;IACZ,+DAA+D;aAC/D,IAAI,EAAE,MAAM;CACJ,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAC5B,aAAa,EAAE,iBAAiB,GAC/B,UAAU,EAAE,CASd"}
|
package/dist/ui/chart_block.d.ts
CHANGED
|
@@ -11,6 +11,20 @@
|
|
|
11
11
|
* Hand-rolled rather than a charting library, and the difference is not
|
|
12
12
|
* marginal: the whole renderer costs single-digit kilobytes where a library
|
|
13
13
|
* costs roughly half this bundle again, in a component distributed over a CDN.
|
|
14
|
+
*
|
|
15
|
+
* **The drawing is sized in CSS pixels, not scaled to them.** An SVG with a
|
|
16
|
+
* fixed viewBox and `width: 100%` is a picture the browser magnifies: widen the
|
|
17
|
+
* panel and every stroke, every label and the whole frame grow with it. So the
|
|
18
|
+
* geometry is computed for the width the block actually has, one user unit to
|
|
19
|
+
* one CSS pixel, and recomputed when that width changes -- a 10px label is
|
|
20
|
+
* 10px at every size the block is given.
|
|
21
|
+
*
|
|
22
|
+
* How wide the block is allowed to get is the stylesheet's question, not this
|
|
23
|
+
* module's, and the answer there is that a chart stops at its own width rather
|
|
24
|
+
* than stretching with the panel, the way a message does. The two halves are
|
|
25
|
+
* separate on purpose: this one keeps a chart from being magnified, that one
|
|
26
|
+
* keeps it from being stretched, and a host that raises the cap gets a bigger
|
|
27
|
+
* chart with the same 10px labels rather than a magnified one.
|
|
14
28
|
*/
|
|
15
29
|
/** One named series of numbers. */
|
|
16
30
|
export interface ChartSeries {
|
|
@@ -34,6 +48,10 @@ export declare function seriesColor(index: number): string;
|
|
|
34
48
|
* A spec with no labels or no series is not drawn: an empty frame reads as
|
|
35
49
|
* "there is no data" when the truth is "the caller sent nothing", and the two
|
|
36
50
|
* deserve different answers.
|
|
51
|
+
*
|
|
52
|
+
* The block returned is already drawn at {@link DEFAULT_WIDTH} and redraws
|
|
53
|
+
* itself once it is in a document and knows how wide it really is, so a caller
|
|
54
|
+
* appends it exactly as before and never has to say how big it should be.
|
|
37
55
|
*/
|
|
38
56
|
export declare function renderChart(spec: ChartSpec): HTMLDivElement | null;
|
|
39
57
|
//# sourceMappingURL=chart_block.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart_block.d.ts","sourceRoot":"","sources":["../../src/ui/chart_block.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"chart_block.d.ts","sourceRoot":"","sources":["../../src/ui/chart_block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,2BAA2B;AAC3B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAEvE,wBAAwB;AACxB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAgED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAkWD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,IAAI,CAsClE"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LauncherBox, ViewportBox } from "./launcher_placement.js";
|
|
2
2
|
/**
|
|
3
|
-
* Keep a launcher fully on screen.
|
|
3
|
+
* Keep a launcher fully on screen, and a little clear of the edge.
|
|
4
4
|
*
|
|
5
5
|
* Applied to a dragged position and again to a restored one, because the
|
|
6
6
|
* viewport that stored it may since have shrunk. A launcher parked past the
|
|
7
7
|
* edge is unreachable, and it is the only way back to a collapsed
|
|
8
|
-
* conversation
|
|
9
|
-
*
|
|
8
|
+
* conversation.
|
|
9
|
+
*
|
|
10
|
+
* Not the panel's 24px gutter, which was rejected here on purpose: a launcher
|
|
11
|
+
* held that far in refuses the corners people actually drag it to. But not
|
|
12
|
+
* zero either -- the bubble is a circle with a drop shadow, and one flush
|
|
13
|
+
* against the boundary has its shadow cut and its curve running into the edge,
|
|
14
|
+
* which reads as clipped whether or not a pixel is actually missing.
|
|
10
15
|
*/
|
|
11
|
-
export declare function clampLauncher(launcher: LauncherBox, viewport:
|
|
16
|
+
export declare function clampLauncher(launcher: LauncherBox, viewport: ViewportBox, margin?: number): {
|
|
12
17
|
readonly left: number;
|
|
13
18
|
readonly top: number;
|
|
14
19
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clamp_launcher.d.ts","sourceRoot":"","sources":["../../src/ui/clamp_launcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clamp_launcher.d.ts","sourceRoot":"","sources":["../../src/ui/clamp_launcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAExE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,WAAW,EACrB,MAAM,GAAE,MAA2B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAgBjD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ViewportBox } from "./launcher_placement.js";
|
|
2
|
+
import type { PanelRect } from "./resize_handle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Hold a panel inside the viewport, keeping its size.
|
|
5
|
+
*
|
|
6
|
+
* The near edge is clamped and the far edge follows, so a panel too large for
|
|
7
|
+
* the viewport is held against the near margin and left to the max-width and
|
|
8
|
+
* max-height rules rather than centred by force. The lower bound wins a
|
|
9
|
+
* contradiction for the same reason: `Math.min` first would put an oversized
|
|
10
|
+
* panel off the left edge instead of against the margin it can still honour.
|
|
11
|
+
*/
|
|
12
|
+
export declare function clampPanel(host: PanelRect, viewport: ViewportBox, margin?: number): PanelRect;
|
|
13
|
+
//# sourceMappingURL=clamp_panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clamp_panel.d.ts","sourceRoot":"","sources":["../../src/ui/clamp_panel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,WAAW,EACrB,MAAM,GAAE,MAAoB,GAC3B,SAAS,CAYX"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LauncherBox, ViewportBox } from "./launcher_placement.js";
|
|
2
2
|
/** What the drag needs from its host to do its job. */
|
|
3
3
|
export interface LauncherDragOptions {
|
|
4
4
|
/**
|
|
@@ -10,7 +10,7 @@ export interface LauncherDragOptions {
|
|
|
10
10
|
/** The launcher's current box, in viewport coordinates. */
|
|
11
11
|
readonly rect: () => LauncherBox;
|
|
12
12
|
/** The viewport the launcher has to stay inside. */
|
|
13
|
-
readonly viewport: () =>
|
|
13
|
+
readonly viewport: () => ViewportBox;
|
|
14
14
|
/** Put the launcher's top-left at this point. Called per pointer move. */
|
|
15
15
|
readonly apply: (left: number, top: number) => void;
|
|
16
16
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher_drag.d.ts","sourceRoot":"","sources":["../../src/ui/launcher_drag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"launcher_drag.d.ts","sourceRoot":"","sources":["../../src/ui/launcher_drag.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAExE,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,WAAW,CAAC;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAaD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAuI5F"}
|
|
@@ -5,6 +5,19 @@ export interface LauncherBox {
|
|
|
5
5
|
readonly width: number;
|
|
6
6
|
readonly height: number;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* The part of the screen a widget may rest in: a width and height, and the
|
|
10
|
+
* corner they start from.
|
|
11
|
+
*
|
|
12
|
+
* The origin is not always zero. A host can reserve the edges its own chrome
|
|
13
|
+
* occupies, and a panel clamped against a viewport that starts at the top-left
|
|
14
|
+
* of the screen will happily park itself underneath a sticky header -- where it
|
|
15
|
+
* cannot be reached, and where collapsing it only hides it further.
|
|
16
|
+
*/
|
|
17
|
+
export interface ViewportBox extends Extent {
|
|
18
|
+
readonly left: number;
|
|
19
|
+
readonly top: number;
|
|
20
|
+
}
|
|
8
21
|
/** A width/height pair, in CSS pixels. */
|
|
9
22
|
export interface Extent {
|
|
10
23
|
readonly width: number;
|
|
@@ -60,5 +73,5 @@ export interface LauncherPlacement {
|
|
|
60
73
|
* later panel resize from dragging the launcher: the pinned corner is the one
|
|
61
74
|
* edge a resize cannot move.
|
|
62
75
|
*/
|
|
63
|
-
export declare function launcherPlacement(launcher: LauncherBox, panel: Extent, viewport: Extent, margin?: number): LauncherPlacement;
|
|
76
|
+
export declare function launcherPlacement(launcher: LauncherBox, panel: Extent, viewport: ViewportBox, screen: Extent, margin?: number): LauncherPlacement;
|
|
64
77
|
//# sourceMappingURL=launcher_placement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher_placement.d.ts","sourceRoot":"","sources":["../../src/ui/launcher_placement.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"launcher_placement.d.ts","sourceRoot":"","sources":["../../src/ui/launcher_placement.ts"],"names":[],"mappings":"AAIA,qCAAqC;AACrC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,0CAA0C;AAC1C,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC9B;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAA2B,GAClC,iBAAiB,CA0CnB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { PanelRect } from "./resize_handle.js";
|
|
2
|
+
/** What the drag needs from its host to do its job. */
|
|
3
|
+
export interface PanelDragOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Whether the panel can be moved right now, read per interaction because
|
|
6
|
+
* both halves of the answer are live: a docked or full-bleed placement has
|
|
7
|
+
* nowhere to move the panel to, and a collapsed one has no panel on screen.
|
|
8
|
+
*/
|
|
9
|
+
readonly enabled: () => boolean;
|
|
10
|
+
/** The panel's current box, in viewport coordinates. */
|
|
11
|
+
readonly rect: () => PanelRect;
|
|
12
|
+
/**
|
|
13
|
+
* Put the panel at this box. Called per pointer move, with the box the press
|
|
14
|
+
* started on -- the whole gesture is one translation of that box, and a host
|
|
15
|
+
* with anything else to move alongside the panel needs the same distance
|
|
16
|
+
* rather than a distance measured from wherever the last move left things.
|
|
17
|
+
*/
|
|
18
|
+
readonly apply: (box: PanelRect, from: PanelRect) => void;
|
|
19
|
+
/** Called once per completed move, for persistence. Never per pointer move. */
|
|
20
|
+
readonly commit: (box: PanelRect, from: PanelRect) => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Let the user move the whole widget by dragging the panel's header.
|
|
24
|
+
*
|
|
25
|
+
* The launcher can already be dragged, and this is the same gesture on the
|
|
26
|
+
* half of the widget that is on screen when it is open -- a chat panel is a
|
|
27
|
+
* window, and a window moves by its title bar. The two stay one position
|
|
28
|
+
* rather than two: the host answers a moved panel by moving the launcher with
|
|
29
|
+
* it, so collapsing after a drag leaves the launcher where the panel was.
|
|
30
|
+
*
|
|
31
|
+
* **No keyboard path here, deliberately.** Every other drag in this component
|
|
32
|
+
* has arrow keys on the handle, because the handle is a control and the
|
|
33
|
+
* capability is reachable nowhere else. A header is not a control: making it
|
|
34
|
+
* focusable would put a tab stop with no role in front of every keyboard user,
|
|
35
|
+
* ahead of the controls they actually came for. The capability is not lost --
|
|
36
|
+
* arrow keys on the collapsed launcher move the widget, and the panel follows
|
|
37
|
+
* it -- so what is missing is a shortcut, not the ability.
|
|
38
|
+
*/
|
|
39
|
+
export declare function enablePanelDrag(handle: HTMLElement, options: PanelDragOptions): void;
|
|
40
|
+
//# sourceMappingURL=panel_drag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel_drag.d.ts","sourceRoot":"","sources":["../../src/ui/panel_drag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC;IAChC,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1D,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC5D;AAgBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAkEpF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExpandCorner, Extent, LauncherBox } from "./launcher_placement.js";
|
|
2
|
+
import type { PanelRect } from "./resize_handle.js";
|
|
3
|
+
/** Where to put the host box, and where the launcher sits inside it. */
|
|
4
|
+
export interface WidgetInsets {
|
|
5
|
+
/** An `inset` shorthand for the host box. */
|
|
6
|
+
readonly hostInset: string;
|
|
7
|
+
/** An `inset` shorthand for the launcher, relative to the host box. */
|
|
8
|
+
readonly launcherInset: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Express a panel and its launcher, both already positioned, as the two
|
|
12
|
+
* `inset` shorthands the element writes.
|
|
13
|
+
*
|
|
14
|
+
* Both are measured from the **same** corner, which is what stops a later
|
|
15
|
+
* resize from dragging the launcher: the pinned corner is the one edge a
|
|
16
|
+
* resize cannot move. Which corner that is says nothing about where either box
|
|
17
|
+
* ends up -- the positions are absolute and arrive decided -- so re-picking it
|
|
18
|
+
* moves nothing, and the launcher may sit outside its own host box. Nothing
|
|
19
|
+
* clips it there, and that is what lets a launcher be flush to a screen corner
|
|
20
|
+
* while the panel it opens keeps its margin.
|
|
21
|
+
*
|
|
22
|
+
* `screen` is the **whole** viewport, not the part a host has left free. These
|
|
23
|
+
* are CSS `inset` values on a fixed element, and the browser measures those
|
|
24
|
+
* from the real edges -- so a `bottom` expressed against a box inset from the
|
|
25
|
+
* top comes out short by exactly that inset. It only shows when the corner
|
|
26
|
+
* flips mid-drag, because that is when the same point stops being expressed
|
|
27
|
+
* from `top` and starts being expressed from `bottom`: the widget then leaps by
|
|
28
|
+
* the reserved edge, which is a jump the gesture cannot explain.
|
|
29
|
+
*/
|
|
30
|
+
export declare function placeWidget(host: PanelRect, launcher: LauncherBox, corner: ExpandCorner, screen: Extent): WidgetInsets;
|
|
31
|
+
//# sourceMappingURL=place_widget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"place_widget.d.ts","sourceRoot":"","sources":["../../src/ui/place_widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,YAAY,CAed"}
|
package/dist/ui/run_notice.d.ts
CHANGED
|
@@ -3,8 +3,19 @@
|
|
|
3
3
|
* skill loaded), rendered inline between turns.
|
|
4
4
|
*
|
|
5
5
|
* Distinct from a tool card, which reports work the agent asked for and
|
|
6
|
-
* settles, and from an error, which is a failure. A notice never settles
|
|
7
|
-
* no action
|
|
6
|
+
* settles, and from an error, which is a failure. A notice never settles and
|
|
7
|
+
* takes no action of its own.
|
|
8
|
+
*
|
|
9
|
+
* It may carry exactly one control, and only ever an undo. That is a narrower
|
|
10
|
+
* rule than "no controls", which is what this said until the agent could move
|
|
11
|
+
* the panel it speaks from: something that rearranges the user's window without
|
|
12
|
+
* being asked has to be both visible and reversible, and a notice is already
|
|
13
|
+
* the surface that says what the run did. Anything the user has to *decide* is
|
|
14
|
+
* a confirmation card instead -- the difference is that this reports something
|
|
15
|
+
* already done.
|
|
8
16
|
*/
|
|
9
|
-
export declare function renderRunNotice(icon: string, text: string, kind: string
|
|
17
|
+
export declare function renderRunNotice(icon: string, text: string, kind: string, undo?: {
|
|
18
|
+
readonly label: string;
|
|
19
|
+
readonly onActivate: () => void;
|
|
20
|
+
}): HTMLDivElement;
|
|
10
21
|
//# sourceMappingURL=run_notice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run_notice.d.ts","sourceRoot":"","sources":["../../src/ui/run_notice.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"run_notice.d.ts","sourceRoot":"","sources":["../../src/ui/run_notice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAA;CAAE,GACjE,cAAc,CAuChB"}
|