@hydraharness/harness-client-ui-sidebar 0.0.0-stage → 0.1.1-rc.6
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/LICENSE +21 -0
- package/README.md +30 -2
- package/lib/client.js +320 -0
- package/lib/index.js +6 -0
- package/lib/invariant.js +25 -0
- package/lib/types/client/HydraSidebarBrand.d.ts +9 -0
- package/lib/types/client/SidebarRoot.d.ts +8 -0
- package/lib/types/client/contract/slots.d.ts +119 -0
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/locales.d.ts +11 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/invariant.d.ts +16 -0
- package/package.json +75 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @hydraharness/harness-client-ui-sidebar
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Sidebar shell plugin: the brand row, New Session action, layout-owned collapse control, scroll-aware region seat, and bottom-pinned Settings seat. [ui-workspace](../ui-workspace/README.md) owns the Workspace and Session browser rendered into `sidebar.workspaces`; this package neither derives its rows nor owns its view preferences. Collapse into the layout-owned 56px rail remains presentation-local. Contract: the [slot system standard](../../../.agents/notes/implemented/architecture/2026-07-22-slot-type-chain-implementation.md).
|
|
4
|
+
|
|
5
|
+
The expanded brand row renders `sidebar.brand.mark` and `sidebar.brand.name` as independent single slots, while the collapsed rail renders the same mark slot. Without occupants, the shell uses the shared Hydra harness wordmark carrying the build's 7-character `HYDRA_CLIENT_COMMIT_HASH` badge. A deployment package can replace either value without replacing the New Session control or rail geometry; declaration-aware `slots.inject()` lets such a package activate before or after the sidebar.
|
|
6
|
+
|
|
7
|
+
New Session starts the runtime's page-local frontend Session Intent. The runtime targets the explicit Workspace used by a scoped action, otherwise the current Session's Workspace, otherwise the most recently active Workspace; when none exists it clears into the blank New Session page. Workspace-specific controls and the shared picker belong to ui-workspace.
|
|
8
|
+
|
|
9
|
+
`SidebarRootComponentProps` composes the layout owner share, the global `useSessions` and `useWorkspaces` hooks, the declared brand, `sidebar.workspaces`, and `sidebar.settings` child slots, and injected `startSession` plus sidebar-toggle callbacks. There is no plugin store.
|
|
10
|
+
|
|
11
|
+
During a live collapse, the shell holds the expanded content at its current width while it fades out for 150ms. The four upper controls—the shell toggle and New Session plus add and search rendered through `sidebar.workspaces`—then share one 150ms fade and 49px leftward translation into the 56px rail, ending with the layout's 300ms column slide; every 36px control box follows the same path to the rail's 10px left inset. The bottom-pinned `sidebar.settings` control shares the fade timing but has no horizontal translation. A page that starts collapsed renders the rail statically, and reduced-motion mode disables both transitions.
|
|
12
|
+
|
|
13
|
+
Scrollbars in the column are a pointer affordance: the shell rebinds ui-theme's [scrollbar indirection](../ui-theme/README.md) to `transparent` whenever the pointer is outside it, and keeps the thumb drawn for 2s after the pointer leaves, so a list nobody is pointing at carries no bar. The reservation that keeps rows from moving belongs to the scrolling region ([ui-workspace](../ui-workspace/README.md)), so revealing a thumb never reflows.
|
|
14
|
+
|
|
15
|
+
The foot is the `sidebar.settings` seat: the sidebar renders only the bottom-pinned layout slot and shares its column state (`wide`); ui-settings registers the trigger row and settings panel there.
|
|
16
|
+
|
|
17
|
+
The `/client` exports are the plugin body (`apply`/`inject`) plus the contract types only; SidebarRoot, the row components, and the tree derivation remain package-internal behind the slot registration.
|
|
18
|
+
|
|
19
|
+
## Model Experience
|
|
20
|
+
|
|
21
|
+
None, as the sidebar renders the browser session list; nothing here reaches a model request.
|
|
22
|
+
|
|
23
|
+
#### KV Cache effect
|
|
24
|
+
|
|
25
|
+
None; this package neither assembles nor sends a provider request.
|
|
26
|
+
|
|
27
|
+
## Known Limitations and Deferred Work
|
|
28
|
+
|
|
29
|
+
- **Session state-dot rendering is owned by [ui-workspace](../ui-workspace/README.md)** — no done/error notification sources are available.
|
|
30
|
+
- **Workspace browser behavior is composition-owned** — grouping, ordering, search, and row state belong to [ui-workspace](../ui-workspace/README.md), not this shell.
|
|
31
|
+
- **"New task completed" unread marking is local viewing state** — completion-time > last-seen never reaches the host.
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@hydraharness/harness-client-ui-sidebar",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let _hydraharness_harness_client_ui_primitives = require("@hydraharness/harness-client-ui-primitives");
|
|
10
|
+
//#region ../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
11
|
+
function r(e) {
|
|
12
|
+
var t, f, n = "";
|
|
13
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
14
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
15
|
+
var o = e.length;
|
|
16
|
+
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
17
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
18
|
+
return n;
|
|
19
|
+
}
|
|
20
|
+
function clsx() {
|
|
21
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
22
|
+
return n;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region \0hydra-css:/home/runner/work/Hydra-Harness/Hydra-Harness/packages/client/ui-sidebar/src/client/SidebarRoot.module.css.mjs
|
|
26
|
+
const css = "._8h6Zdq_root{--hydra-sidebar-inline-padding:12px;height:100%;padding:6px var(--hydra-sidebar-inline-padding);box-sizing:border-box;background:var(--dsw-specific-sidebar-fill);color:var(--dsw-alias-label-primary);--hydra-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--hydra-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);flex-direction:column;font-size:14px;display:flex}._8h6Zdq_root._8h6Zdq_collapsed{padding:18px 10px 6px}._8h6Zdq_root._8h6Zdq_quietBars{--hydra-scrollbar-thumb:transparent;--hydra-scrollbar-thumb-hover:transparent}._8h6Zdq_fading>*{opacity:0;transition:opacity .15s var(--ds-ease-in-out)}._8h6Zdq_wide{animation:_8h6Zdq_wide-in .2s var(--ds-ease-in-out)}@keyframes _8h6Zdq_wide-in{0%{opacity:0}}._8h6Zdq_railIn ._8h6Zdq_iconButton,._8h6Zdq_railIn ._8h6Zdq_newSession,._8h6Zdq_railIn ._8h6Zdq_regionArea{animation:_8h6Zdq_rail-in .15s var(--ds-ease-in-out) backwards}._8h6Zdq_railIn ._8h6Zdq_footArea{animation:_8h6Zdq_rail-fade-in .15s var(--ds-ease-in-out) backwards}@keyframes _8h6Zdq_rail-in{0%{opacity:0;transform:translate(49px)}}@keyframes _8h6Zdq_rail-fade-in{0%{opacity:0}}._8h6Zdq_logoRow{box-sizing:border-box;flex:none;justify-content:flex-end;align-items:center;gap:8px;height:60px;margin-bottom:8px;padding:8px 0 8px 4px;display:flex;overflow:hidden}._8h6Zdq_collapsed ._8h6Zdq_logoRow{justify-content:flex-start;height:36px;margin-bottom:12px;padding:0}._8h6Zdq_brand{min-width:0;color:inherit;cursor:pointer;background:0 0;border:none;flex:1;align-items:center;padding:0;display:inline-flex;overflow:hidden}._8h6Zdq_brandIdentity{align-items:center;gap:8px;min-width:0;height:24px;display:inline-flex}._8h6Zdq_brandMark{flex:none;justify-content:center;align-items:center;display:inline-flex}._8h6Zdq_brandMark:has(>[data-slot=\"sidebar.brand.mark\"]:empty){display:none}._8h6Zdq_brandName{letter-spacing:.04em;align-items:center;gap:6px;min-width:0;height:24px;font-size:18px;font-weight:600;line-height:24px;display:inline-flex}._8h6Zdq_fallbackBrandName{letter-spacing:0;white-space:nowrap;font-size:17px}._8h6Zdq_localBrandLogo{flex:none}._8h6Zdq_iconButton{border-radius:var(--dsw-radius-control);cursor:pointer;width:28px;height:28px;color:var(--dsw-alias-label-secondary);transition:background-color var(--ds-transition-duration-fast) var(--ds-ease-in-out);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}._8h6Zdq_iconButton:hover{background:var(--dsw-alias-interactive-bg-hover)}._8h6Zdq_collapsed ._8h6Zdq_iconButton{width:36px;height:36px}._8h6Zdq_collapsed ._8h6Zdq_toggle ._8h6Zdq_panelIcon{display:none}._8h6Zdq_collapsed ._8h6Zdq_toggle:hover ._8h6Zdq_panelIcon{display:inline}._8h6Zdq_collapsed ._8h6Zdq_toggle:hover ._8h6Zdq_railMark{display:none}._8h6Zdq_railMark{justify-content:center;align-items:center;display:inline-flex}._8h6Zdq_collapsed ._8h6Zdq_iconButton{color:var(--dsw-alias-label-primary)}._8h6Zdq_buildRevision{height:16px;color:var(--dsw-alias-label-primary-inverted);background:var(--dsw-alias-label-primary);font-family:var(--ds-font-family-code);border-radius:3px;align-items:center;padding:0 4px;font-size:8px;font-weight:500;line-height:16px;display:inline-flex}._8h6Zdq_newSession{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-control);background:var(--dsw-alias-button-elevated-fill);height:38px;box-shadow:var(--dsw-shadow-lv1);color:var(--dsw-alias-label-primary);cursor:pointer;transition:background-color var(--ds-transition-duration-fast) var(--ds-ease-in-out), box-shadow var(--ds-transition-duration-fast) var(--ds-ease-in-out);flex:none;justify-content:center;align-items:center;gap:6px;margin:0 2px 8px;padding:8px 16px;font-size:14px;font-weight:500;line-height:22px;display:flex;overflow:hidden}._8h6Zdq_newSession:hover{background:var(--dsw-alias-button-floating-hover);box-shadow:var(--dsw-shadow-lv1-blur)}._8h6Zdq_collapsed ._8h6Zdq_newSession{background:0 0;border-color:#0000;align-self:flex-start;gap:0;width:36px;height:36px;margin:0 0 12px;padding:0}._8h6Zdq_collapsed ._8h6Zdq_newSession:hover{background:var(--dsw-alias-interactive-bg-hover)}._8h6Zdq_newSessionLabel{white-space:nowrap;max-width:200px;overflow:hidden}._8h6Zdq_collapsed ._8h6Zdq_newSessionLabel{max-width:0}._8h6Zdq_regionArea{min-height:0;margin-left:-4px;margin-right:calc(-1 * var(--hydra-sidebar-inline-padding));flex-direction:column;flex:1;padding-left:4px;display:flex;overflow:hidden}._8h6Zdq_collapsed ._8h6Zdq_regionArea{margin-left:0;margin-right:0;padding-left:0}._8h6Zdq_footArea{flex-direction:column;flex:none;display:flex}._8h6Zdq_settingsArea,._8h6Zdq_footerActions{flex:none;width:100%;min-width:0}._8h6Zdq_footerActions{display:flex}._8h6Zdq_collapsed ._8h6Zdq_footArea{align-items:center}._8h6Zdq_collapsed ._8h6Zdq_settingsArea,._8h6Zdq_collapsed ._8h6Zdq_footerActions{justify-content:center;width:auto;display:flex}@media (prefers-reduced-motion:reduce){._8h6Zdq_wide,._8h6Zdq_fading>*,._8h6Zdq_railIn ._8h6Zdq_iconButton,._8h6Zdq_railIn ._8h6Zdq_newSession,._8h6Zdq_railIn ._8h6Zdq_footArea,._8h6Zdq_railIn ._8h6Zdq_regionArea{transition:none;animation:none}}";
|
|
27
|
+
const tagId = "@hydraharness/harness-client-ui-sidebar/SidebarRoot.module.css";
|
|
28
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
29
|
+
const tag = document.createElement("style");
|
|
30
|
+
tag.dataset.plugin = "@hydraharness/harness-client-ui-sidebar";
|
|
31
|
+
tag.dataset.pluginCss = tagId;
|
|
32
|
+
tag.textContent = css;
|
|
33
|
+
document.head.appendChild(tag);
|
|
34
|
+
}
|
|
35
|
+
var SidebarRoot_module_css_default = {
|
|
36
|
+
"brand": "_8h6Zdq_brand",
|
|
37
|
+
"brandIdentity": "_8h6Zdq_brandIdentity",
|
|
38
|
+
"brandMark": "_8h6Zdq_brandMark",
|
|
39
|
+
"brandName": "_8h6Zdq_brandName",
|
|
40
|
+
"buildRevision": "_8h6Zdq_buildRevision",
|
|
41
|
+
"collapsed": "_8h6Zdq_collapsed",
|
|
42
|
+
"fading": "_8h6Zdq_fading",
|
|
43
|
+
"fallbackBrandName": "_8h6Zdq_fallbackBrandName",
|
|
44
|
+
"footArea": "_8h6Zdq_footArea",
|
|
45
|
+
"footerActions": "_8h6Zdq_footerActions",
|
|
46
|
+
"iconButton": "_8h6Zdq_iconButton",
|
|
47
|
+
"localBrandLogo": "_8h6Zdq_localBrandLogo",
|
|
48
|
+
"logoRow": "_8h6Zdq_logoRow",
|
|
49
|
+
"newSession": "_8h6Zdq_newSession",
|
|
50
|
+
"newSessionLabel": "_8h6Zdq_newSessionLabel",
|
|
51
|
+
"panelIcon": "_8h6Zdq_panelIcon",
|
|
52
|
+
"quietBars": "_8h6Zdq_quietBars",
|
|
53
|
+
"rail-fade-in": "_8h6Zdq_rail-fade-in",
|
|
54
|
+
"rail-in": "_8h6Zdq_rail-in",
|
|
55
|
+
"railIn": "_8h6Zdq_railIn",
|
|
56
|
+
"railMark": "_8h6Zdq_railMark",
|
|
57
|
+
"regionArea": "_8h6Zdq_regionArea",
|
|
58
|
+
"root": "_8h6Zdq_root",
|
|
59
|
+
"settingsArea": "_8h6Zdq_settingsArea",
|
|
60
|
+
"toggle": "_8h6Zdq_toggle",
|
|
61
|
+
"wide": "_8h6Zdq_wide",
|
|
62
|
+
"wide-in": "_8h6Zdq_wide-in"
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region lib/types/client/HydraSidebarBrand.js
|
|
66
|
+
/**
|
|
67
|
+
* Render the Hydra harness name and mark in the sidebar.
|
|
68
|
+
* @param props - Optional layout class.
|
|
69
|
+
* @returns the shared brand wordmark.
|
|
70
|
+
*/
|
|
71
|
+
function HydraSidebarBrand({ className }) {
|
|
72
|
+
return (0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.BrandWordmark, { className });
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region lib/types/client/SidebarRoot.js
|
|
76
|
+
/**
|
|
77
|
+
* Sidebar shell: column geometry only. Collapse is a slide plus crossfade:
|
|
78
|
+
* content freezes at its expanded width (inline style) and fades out in place
|
|
79
|
+
* while the sliding column (AppFrame grid tracks) clips it — nothing reflows
|
|
80
|
+
* mid-slide. At settle the wide-only content unmounts and the four upper
|
|
81
|
+
* controls enter the 56px rail from the same horizontal offset (one icon each,
|
|
82
|
+
* same top-down order) on one fade that ends with the slide. The bottom-pinned
|
|
83
|
+
* settings control only fades. The workspace/session browsing region between
|
|
84
|
+
* the New Session button and the foot is the `sidebar.workspaces` registrant's,
|
|
85
|
+
* and the foot holds `sidebar.settings` plus `sidebar.footer.action`; the shell
|
|
86
|
+
* hands them the wide flag (plus an expand request callback for the browser).
|
|
87
|
+
*
|
|
88
|
+
* The column also owns whether the scroll regions nested in it draw a
|
|
89
|
+
* scrollbar at all: the shell tracks the pointer and rebinds ui-theme's
|
|
90
|
+
* scrollbar indirection away while it is elsewhere, so a list the user is not
|
|
91
|
+
* pointing at carries no bar.
|
|
92
|
+
*/
|
|
93
|
+
/** Wide-content unmount delay; matches the 150ms wide-content fade-out. */
|
|
94
|
+
const COLLAPSE_SETTLE_MS = 150;
|
|
95
|
+
/**
|
|
96
|
+
* How long the column's scrollbars stay drawn after the pointer leaves it.
|
|
97
|
+
* The bar is a pointer affordance here, and hiding it on the leave event
|
|
98
|
+
* itself makes it blink out while the pointer is only crossing the column's
|
|
99
|
+
* edge — on the way to the conversation, or around a portalled menu.
|
|
100
|
+
*/
|
|
101
|
+
const SCROLLBAR_LINGER_MS = 2e3;
|
|
102
|
+
/**
|
|
103
|
+
* Render the sidebar column shell.
|
|
104
|
+
* @param props - composed slot props (runtime share + injected callbacks, contract/slots.ts).
|
|
105
|
+
* @returns the sidebar element tree.
|
|
106
|
+
*/
|
|
107
|
+
function SidebarRoot({ collapsed, width, startSession, toggleSidebar, t, renderSlot }) {
|
|
108
|
+
const [settled, setSettled] = (0, react.useState)(collapsed);
|
|
109
|
+
(0, react.useEffect)(() => {
|
|
110
|
+
if (!collapsed) {
|
|
111
|
+
setSettled(false);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const timer = window.setTimeout(() => {
|
|
115
|
+
setSettled(true);
|
|
116
|
+
}, COLLAPSE_SETTLE_MS);
|
|
117
|
+
return () => {
|
|
118
|
+
window.clearTimeout(timer);
|
|
119
|
+
};
|
|
120
|
+
}, [collapsed]);
|
|
121
|
+
const wide = !collapsed || !settled;
|
|
122
|
+
const lastWideWidth = (0, react.useRef)(width);
|
|
123
|
+
if (!collapsed) lastWideWidth.current = width;
|
|
124
|
+
const everWide = (0, react.useRef)(!collapsed);
|
|
125
|
+
if (!collapsed) everWide.current = true;
|
|
126
|
+
const column = (0, react.useRef)(null);
|
|
127
|
+
const [pointerInside, setPointerInside] = (0, react.useState)(false);
|
|
128
|
+
const lingerTimer = (0, react.useRef)(void 0);
|
|
129
|
+
const armLinger = () => {
|
|
130
|
+
if (lingerTimer.current !== void 0) return;
|
|
131
|
+
lingerTimer.current = window.setTimeout(() => {
|
|
132
|
+
lingerTimer.current = void 0;
|
|
133
|
+
setPointerInside(false);
|
|
134
|
+
}, SCROLLBAR_LINGER_MS);
|
|
135
|
+
};
|
|
136
|
+
const cancelLinger = () => {
|
|
137
|
+
window.clearTimeout(lingerTimer.current);
|
|
138
|
+
lingerTimer.current = void 0;
|
|
139
|
+
};
|
|
140
|
+
(0, react.useEffect)(() => {
|
|
141
|
+
if (!pointerInside) return;
|
|
142
|
+
const onMove = (event) => {
|
|
143
|
+
const rect = column.current?.getBoundingClientRect();
|
|
144
|
+
/* v8 ignore next -- the listener only exists while the column is mounted and revealed. */
|
|
145
|
+
if (rect === void 0) return;
|
|
146
|
+
if (event.clientX >= rect.left && event.clientX < rect.right && event.clientY >= rect.top && event.clientY < rect.bottom) cancelLinger();
|
|
147
|
+
else armLinger();
|
|
148
|
+
};
|
|
149
|
+
document.addEventListener("pointermove", onMove);
|
|
150
|
+
return () => {
|
|
151
|
+
document.removeEventListener("pointermove", onMove);
|
|
152
|
+
cancelLinger();
|
|
153
|
+
};
|
|
154
|
+
}, [pointerInside]);
|
|
155
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
156
|
+
ref: column,
|
|
157
|
+
className: clsx(SidebarRoot_module_css_default.root, !wide && SidebarRoot_module_css_default.collapsed, !wide && everWide.current && SidebarRoot_module_css_default.railIn, collapsed && wide && SidebarRoot_module_css_default.fading, !pointerInside && SidebarRoot_module_css_default.quietBars),
|
|
158
|
+
style: wide ? { width: collapsed ? lastWideWidth.current : width } : void 0,
|
|
159
|
+
onPointerEnter: () => {
|
|
160
|
+
cancelLinger();
|
|
161
|
+
setPointerInside(true);
|
|
162
|
+
},
|
|
163
|
+
onPointerLeave: () => {
|
|
164
|
+
armLinger();
|
|
165
|
+
},
|
|
166
|
+
children: [
|
|
167
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
168
|
+
className: SidebarRoot_module_css_default.logoRow,
|
|
169
|
+
children: [wide && (0, react_jsx_runtime.jsx)("button", {
|
|
170
|
+
type: "button",
|
|
171
|
+
className: clsx(SidebarRoot_module_css_default.brand, SidebarRoot_module_css_default.wide),
|
|
172
|
+
"aria-label": t("session.new.label"),
|
|
173
|
+
onClick: () => {
|
|
174
|
+
startSession();
|
|
175
|
+
},
|
|
176
|
+
children: (0, react_jsx_runtime.jsxs)("span", {
|
|
177
|
+
className: SidebarRoot_module_css_default.brandIdentity,
|
|
178
|
+
"aria-hidden": "true",
|
|
179
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
180
|
+
className: SidebarRoot_module_css_default.brandMark,
|
|
181
|
+
children: renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: null })
|
|
182
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
183
|
+
className: SidebarRoot_module_css_default.brandName,
|
|
184
|
+
children: renderSlot("sidebar.brand.name", {}, { fallback: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsx)(HydraSidebarBrand, { className: SidebarRoot_module_css_default.localBrandLogo }), (0, react_jsx_runtime.jsx)("span", {
|
|
185
|
+
className: SidebarRoot_module_css_default.buildRevision,
|
|
186
|
+
children: "cdc4224"
|
|
187
|
+
})] }) })
|
|
188
|
+
})]
|
|
189
|
+
})
|
|
190
|
+
}), (0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.Tooltip, {
|
|
191
|
+
label: collapsed ? t("toggle.open") : t("toggle.collapse"),
|
|
192
|
+
delayMs: 500,
|
|
193
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
194
|
+
type: "button",
|
|
195
|
+
className: clsx(SidebarRoot_module_css_default.iconButton, SidebarRoot_module_css_default.toggle),
|
|
196
|
+
"aria-label": collapsed ? t("toggle.open") : t("toggle.collapse"),
|
|
197
|
+
onClick: () => {
|
|
198
|
+
toggleSidebar();
|
|
199
|
+
},
|
|
200
|
+
children: [!wide && (0, react_jsx_runtime.jsx)("span", {
|
|
201
|
+
className: SidebarRoot_module_css_default.railMark,
|
|
202
|
+
"aria-hidden": "true",
|
|
203
|
+
children: renderSlot("sidebar.brand.mark", { size: 24 }, { fallback: (0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.HydraLogo, { size: 24 }) })
|
|
204
|
+
}), (0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.IconPanelLeftOutline16, {
|
|
205
|
+
className: SidebarRoot_module_css_default.panelIcon,
|
|
206
|
+
size: wide ? 16 : 18
|
|
207
|
+
})]
|
|
208
|
+
})
|
|
209
|
+
})]
|
|
210
|
+
}),
|
|
211
|
+
(0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.Tooltip, {
|
|
212
|
+
label: t("session.new.label"),
|
|
213
|
+
delayMs: 500,
|
|
214
|
+
disabled: wide,
|
|
215
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
216
|
+
type: "button",
|
|
217
|
+
className: SidebarRoot_module_css_default.newSession,
|
|
218
|
+
"aria-label": t("session.new.label"),
|
|
219
|
+
onClick: () => {
|
|
220
|
+
startSession();
|
|
221
|
+
},
|
|
222
|
+
children: [(0, react_jsx_runtime.jsx)(_hydraharness_harness_client_ui_primitives.IconNewChatOutline16, { size: wide ? 14 : 18 }), wide && (0, react_jsx_runtime.jsx)("span", {
|
|
223
|
+
className: clsx(SidebarRoot_module_css_default.newSessionLabel, SidebarRoot_module_css_default.wide),
|
|
224
|
+
children: t("session.new")
|
|
225
|
+
})]
|
|
226
|
+
})
|
|
227
|
+
}),
|
|
228
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
229
|
+
className: SidebarRoot_module_css_default.regionArea,
|
|
230
|
+
children: renderSlot("sidebar.workspaces", {
|
|
231
|
+
wide,
|
|
232
|
+
expandSidebar: () => {
|
|
233
|
+
if (collapsed) toggleSidebar();
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
}),
|
|
237
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
238
|
+
className: SidebarRoot_module_css_default.footArea,
|
|
239
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
240
|
+
className: SidebarRoot_module_css_default.footerActions,
|
|
241
|
+
children: renderSlot("sidebar.footer.action", { wide })
|
|
242
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
243
|
+
className: SidebarRoot_module_css_default.settingsArea,
|
|
244
|
+
children: renderSlot("sidebar.settings", { wide })
|
|
245
|
+
})]
|
|
246
|
+
})
|
|
247
|
+
]
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region lib/types/client/locales.js
|
|
252
|
+
/** `sidebar` namespace dictionaries: shell controls (brand row, New Session, fold toggle). */
|
|
253
|
+
/** English dictionary (the key-set source of truth). */
|
|
254
|
+
const en = {
|
|
255
|
+
"session.new": "New Session",
|
|
256
|
+
"session.new.label": "New session",
|
|
257
|
+
"toggle.open": "Open sidebar",
|
|
258
|
+
"toggle.collapse": "Collapse sidebar"
|
|
259
|
+
};
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region lib/types/client/index.js
|
|
262
|
+
/** Dictionary namespace owned by this plugin (shell controls copy). */
|
|
263
|
+
const NS = "sidebar";
|
|
264
|
+
/** Services required by the sidebar plugin. */
|
|
265
|
+
const inject = [
|
|
266
|
+
"slots",
|
|
267
|
+
"layout",
|
|
268
|
+
"sessions",
|
|
269
|
+
"workspaces",
|
|
270
|
+
"locale"
|
|
271
|
+
];
|
|
272
|
+
/** Registers the sidebar shell and its service callbacks.
|
|
273
|
+
* @param ctx - Client root context.
|
|
274
|
+
*/
|
|
275
|
+
function apply(ctx) {
|
|
276
|
+
ctx.effect(() => ctx.locale.register(NS, { en }), "ui-sidebar: dictionaries");
|
|
277
|
+
const injectProps = () => ({
|
|
278
|
+
startSession: (workspaceId) => {
|
|
279
|
+
ctx.workspaces.startSession(workspaceId);
|
|
280
|
+
},
|
|
281
|
+
toggleSidebar: () => {
|
|
282
|
+
ctx.layout.toggleSidebar();
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
ctx.effect(() => ctx.slots.register({
|
|
286
|
+
name: "sidebar",
|
|
287
|
+
locale: NS,
|
|
288
|
+
children: {
|
|
289
|
+
"sidebar.brand.mark": {
|
|
290
|
+
kind: "single",
|
|
291
|
+
scope: "root"
|
|
292
|
+
},
|
|
293
|
+
"sidebar.brand.name": {
|
|
294
|
+
kind: "single",
|
|
295
|
+
scope: "root"
|
|
296
|
+
},
|
|
297
|
+
"sidebar.workspaces": {
|
|
298
|
+
kind: "single",
|
|
299
|
+
scope: "root"
|
|
300
|
+
},
|
|
301
|
+
"sidebar.settings": {
|
|
302
|
+
kind: "single",
|
|
303
|
+
scope: "root"
|
|
304
|
+
},
|
|
305
|
+
"sidebar.footer.action": {
|
|
306
|
+
kind: "list",
|
|
307
|
+
scope: "root"
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
inject: injectProps
|
|
311
|
+
}, SidebarRoot), "ui-sidebar: slot registration");
|
|
312
|
+
}
|
|
313
|
+
//#endregion
|
|
314
|
+
exports.apply = apply;
|
|
315
|
+
exports.inject = inject;
|
|
316
|
+
return module.exports;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
//# sourceMappingURL=client.js.map
|
package/lib/index.js
ADDED
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@hydraharness/harness-client-ui-sidebar`.
|
|
4
|
+
* @module @hydraharness/harness-client-ui-sidebar/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@hydraharness/harness-client-ui-sidebar";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "client-ui-sidebar-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: a pure-consumer plugin deriving its rows in-component
|
|
13
|
+
* from the standard useSessions delivery — it emits no cordis events and owns
|
|
14
|
+
* no cross-plugin mutable state; derivation and interaction behavior are
|
|
15
|
+
* asserted directly by this package's tree/component specs.
|
|
16
|
+
*/
|
|
17
|
+
const install = () => {};
|
|
18
|
+
/**
|
|
19
|
+
* Register this package's invariant companion.
|
|
20
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
21
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
22
|
+
*/
|
|
23
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render the Hydra harness name and mark in the sidebar.
|
|
3
|
+
* @param props - Optional layout class.
|
|
4
|
+
* @returns the shared brand wordmark.
|
|
5
|
+
*/
|
|
6
|
+
export declare function HydraSidebarBrand({ className }: {
|
|
7
|
+
className?: string | undefined;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=HydraSidebarBrand.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SidebarRootComponentProps } from './contract/slots.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Render the sidebar column shell.
|
|
4
|
+
* @param props - composed slot props (runtime share + injected callbacks, contract/slots.ts).
|
|
5
|
+
* @returns the sidebar element tree.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SidebarRoot({ collapsed, width, startSession, toggleSidebar, t, renderSlot, }: SidebarRootComponentProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=SidebarRoot.d.ts.map
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar slot contract: the registrant-side props composition for the
|
|
3
|
+
* layout-owned `sidebar` slot, plus the holes this shell declares. The shell
|
|
4
|
+
* owns column geometry (fold state machine, brand row, New Session);
|
|
5
|
+
* everything between the section header and the list bottom is the
|
|
6
|
+
* `sidebar.workspaces` registrant's (ui-workspace), and the foot is the
|
|
7
|
+
* `sidebar.settings` registrant's (ui-settings), followed by optional footer
|
|
8
|
+
* actions in `sidebar.footer.action`.
|
|
9
|
+
*/
|
|
10
|
+
import type { PropsLocale, PropsRenderSlots, PropsRuntime } from '@hydraharness/harness-client-ui-slots';
|
|
11
|
+
import type { WorkspaceId } from '@hydraharness/harness-client-runtime/client';
|
|
12
|
+
declare module '@hydraharness/harness-client-ui-slots' {
|
|
13
|
+
interface SlotMap {
|
|
14
|
+
/**
|
|
15
|
+
* Brand mark rendered in the expanded brand row and collapsed rail.
|
|
16
|
+
* Declared by this package's `sidebar` entry; deployments may replace
|
|
17
|
+
* the shell's local mark fallback without replacing the surrounding controls.
|
|
18
|
+
*/
|
|
19
|
+
'sidebar.brand.mark': {
|
|
20
|
+
kind: 'single';
|
|
21
|
+
scope: 'root';
|
|
22
|
+
owner: SidebarBrandMarkOwnerProps;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Brand name rendered beside the expanded mark. Declared by this
|
|
26
|
+
* package's `sidebar` entry; the shell supplies a generic text fallback.
|
|
27
|
+
*/
|
|
28
|
+
'sidebar.brand.name': {
|
|
29
|
+
kind: 'single';
|
|
30
|
+
scope: 'root';
|
|
31
|
+
owner: SidebarBrandNameOwnerProps;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The workspace/session browsing region: section header, search, the
|
|
35
|
+
* grouped/flat session list, and every workspace dialog. Declared by this
|
|
36
|
+
* package's 'sidebar' entry (declaring is claiming); ui-workspace
|
|
37
|
+
* registers the browser.
|
|
38
|
+
*/
|
|
39
|
+
'sidebar.workspaces': {
|
|
40
|
+
kind: 'single';
|
|
41
|
+
scope: 'root';
|
|
42
|
+
owner: SidebarSectionOwnerProps;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* The settings seat at the sidebar foot. Declared by this package's
|
|
46
|
+
* 'sidebar' entry; ui-settings registers its trigger row + modal panel.
|
|
47
|
+
* The sidebar passes only its column state — it holds no settings state.
|
|
48
|
+
*/
|
|
49
|
+
'sidebar.settings': {
|
|
50
|
+
kind: 'single';
|
|
51
|
+
scope: 'root';
|
|
52
|
+
owner: SidebarSettingsOwnerProps;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Optional actions beside Settings at the sidebar foot. Declared by this
|
|
56
|
+
* package's 'sidebar' entry; each action receives only the column state.
|
|
57
|
+
*/
|
|
58
|
+
'sidebar.footer.action': {
|
|
59
|
+
kind: 'list';
|
|
60
|
+
scope: 'root';
|
|
61
|
+
owner: SidebarFooterActionOwnerProps;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Geometry supplied to the sidebar brand-mark occupant. */
|
|
66
|
+
export interface SidebarBrandMarkOwnerProps {
|
|
67
|
+
/** Requested square edge in pixels. */
|
|
68
|
+
size: number;
|
|
69
|
+
}
|
|
70
|
+
/** Empty owner share for the sidebar brand-name occupant. */
|
|
71
|
+
export interface SidebarBrandNameOwnerProps {
|
|
72
|
+
/** Marker field: the occupant owns its own content and width. */
|
|
73
|
+
children?: never;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Owner share of the browser hole — the only facts crossing the shell/region
|
|
77
|
+
* boundary. Business data and actions arrive through the region's own inject.
|
|
78
|
+
*/
|
|
79
|
+
export interface SidebarSectionOwnerProps {
|
|
80
|
+
/** Shell fold-state output: wide renders the full browser, rail the icon column. */
|
|
81
|
+
wide: boolean;
|
|
82
|
+
/** Rail icons request expansion; the browser rides the wide flip for focus. */
|
|
83
|
+
expandSidebar: () => void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Owner share of the sidebar settings seat: the column display state the
|
|
87
|
+
* occupant's trigger row must render against (wide row vs rail icon).
|
|
88
|
+
*/
|
|
89
|
+
export interface SidebarSettingsOwnerProps {
|
|
90
|
+
/** Whether the sidebar renders wide content (false = 56px rail). */
|
|
91
|
+
wide: boolean;
|
|
92
|
+
}
|
|
93
|
+
/** Owner share of an action rendered beside Settings at the sidebar foot. */
|
|
94
|
+
export interface SidebarFooterActionOwnerProps {
|
|
95
|
+
/** Whether the sidebar renders wide content (false = 56px rail). */
|
|
96
|
+
wide: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Registrant-private injected share (arrives via the register inject
|
|
100
|
+
* factory). The shell keeps only its own controls: starting a Session from
|
|
101
|
+
* the New Session button and toggling the column.
|
|
102
|
+
*/
|
|
103
|
+
export type SidebarRootInjected = {
|
|
104
|
+
/**
|
|
105
|
+
* Start a New Session: with a workspace, reuse-or-create its blank session
|
|
106
|
+
* and open it; without one, inherit the current Session Workspace, then the
|
|
107
|
+
* recent Workspace, or clear into the New Session pure view when none exist.
|
|
108
|
+
*/
|
|
109
|
+
startSession: (workspaceId?: WorkspaceId) => void;
|
|
110
|
+
/** Toggle the sidebar column through the layout service. */
|
|
111
|
+
toggleSidebar: () => void;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Full component props: layout owner state/actions plus the declared holes'
|
|
115
|
+
* render shares, this package's injected callbacks, and the standard locale
|
|
116
|
+
* seat. No store is registered.
|
|
117
|
+
*/
|
|
118
|
+
export type SidebarRootComponentProps = PropsRuntime<'sidebar'> & PropsRenderSlots<'sidebar.brand.mark' | 'sidebar.brand.name' | 'sidebar.workspaces' | 'sidebar.settings' | 'sidebar.footer.action'> & SidebarRootInjected & PropsLocale<'sidebar'>;
|
|
119
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Registers the sidebar shell into the layout-owned slot. */
|
|
2
|
+
import type { ClientContext } from '@hydraharness/harness-client-runtime/client';
|
|
3
|
+
import { type SidebarKey } from './locales.ts';
|
|
4
|
+
export type { SidebarBrandMarkOwnerProps, SidebarBrandNameOwnerProps, SidebarFooterActionOwnerProps, SidebarRootComponentProps, SidebarRootInjected, SidebarSectionOwnerProps, SidebarSettingsOwnerProps, } from './contract/slots.ts';
|
|
5
|
+
export type { SidebarKey } from './locales.ts';
|
|
6
|
+
declare module '@hydraharness/harness-client-ui-slots' {
|
|
7
|
+
interface LocaleNamespaceMap {
|
|
8
|
+
/** Sidebar shell controls copy. */
|
|
9
|
+
sidebar: SidebarKey;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Services required by the sidebar plugin. */
|
|
13
|
+
export declare const inject: string[];
|
|
14
|
+
/** Registers the sidebar shell and its service callbacks.
|
|
15
|
+
* @param ctx - Client root context.
|
|
16
|
+
*/
|
|
17
|
+
export declare function apply(ctx: ClientContext): void;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** `sidebar` namespace dictionaries: shell controls (brand row, New Session, fold toggle). */
|
|
2
|
+
/** English dictionary (the key-set source of truth). */
|
|
3
|
+
export declare const en: {
|
|
4
|
+
'session.new': string;
|
|
5
|
+
'session.new.label': string;
|
|
6
|
+
'toggle.open': string;
|
|
7
|
+
'toggle.collapse': string;
|
|
8
|
+
};
|
|
9
|
+
/** The sidebar namespace key union. */
|
|
10
|
+
export type SidebarKey = keyof typeof en;
|
|
11
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@hydraharness/harness-client-ui-sidebar`.
|
|
3
|
+
* @module @hydraharness/harness-client-ui-sidebar/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@hydraharness/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "client-ui-sidebar-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydraharness/harness-client-ui-sidebar",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"description": "Sidebar plugin: session multi-level tree, search, grouping, state dots",
|
|
4
|
+
"version": "0.1.1-rc.6",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/MaiHongPhong1902/Hydra-Harness.git",
|
|
11
|
+
"directory": "packages/client/ui-sidebar"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./lib/types/client/index.d.ts",
|
|
27
|
+
"default": "./lib/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./src/*": "./src/*",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"hydra": {
|
|
33
|
+
"plugin": {
|
|
34
|
+
"application": "Find, group, and switch between conversations and their child sessions."
|
|
35
|
+
},
|
|
36
|
+
"client": {
|
|
37
|
+
"inject": [
|
|
38
|
+
"@hydraharness/harness-client-runtime",
|
|
39
|
+
"@hydraharness/harness-client-ui-layout",
|
|
40
|
+
"@hydraharness/harness-client-locale"
|
|
41
|
+
],
|
|
42
|
+
"platform": "web"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"clsx": "^2.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@hydraharness/harness-invariants": "^0.1.1-rc.6",
|
|
51
|
+
"@hydraharness/harness-client-locale": "^0.1.1-rc.6",
|
|
52
|
+
"@hydraharness/harness-client-ui-layout": "^0.1.1-rc.6",
|
|
53
|
+
"@hydraharness/harness-client-runtime": "^0.1.1-rc.6",
|
|
54
|
+
"@hydraharness/cordis": "^4.0.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/react": "~18.3.1",
|
|
58
|
+
"react": "^18.2.0",
|
|
59
|
+
"@hydraharness/harness-client-locale": "^0.1.1-rc.6",
|
|
60
|
+
"@hydraharness/harness-client-runtime": "^0.1.1-rc.6",
|
|
61
|
+
"@hydraharness/harness-client-test-runtime": "^0.1.1-rc.6",
|
|
62
|
+
"@hydraharness/harness-client-ui-layout": "^0.1.1-rc.6",
|
|
63
|
+
"@hydraharness/harness-client-ui-primitives": "^0.1.1-rc.6",
|
|
64
|
+
"@hydraharness/harness-client-ui-slots": "^0.1.1-rc.6",
|
|
65
|
+
"@hydraharness/cordis": "^4.0.2",
|
|
66
|
+
"@hydraharness/harness-invariants": "^0.1.1-rc.6"
|
|
67
|
+
},
|
|
68
|
+
"files": [
|
|
69
|
+
"lib/index.js",
|
|
70
|
+
"lib/invariant.js",
|
|
71
|
+
"lib/client.js",
|
|
72
|
+
"lib/types/**/*.d.ts"
|
|
73
|
+
],
|
|
74
|
+
"scripts": {
|
|
75
|
+
"bundle": "tsdown",
|
|
76
|
+
"watch": "tsdown --watch"
|
|
77
|
+
}
|
|
6
78
|
}
|