@shendeguize/dsh-agent-sidecar 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -11
- package/lib/client.js +4708 -2932
- package/lib/client.js.map +1 -1
- package/package.json +3 -1
- package/src/client/analysis/AnalysisPanel.tsx +19 -27
- package/src/client/analysis/analysis.module.css +36 -97
- package/src/client/board/Board.tsx +255 -48
- package/src/client/board/board.module.css +113 -92
- package/src/client/board/logic.ts +99 -21
- package/src/client/board/project-view-logic.ts +27 -34
- package/src/client/board/project-view.module.css +46 -83
- package/src/client/board/project-view.tsx +50 -8
- package/src/client/board/strings.ts +70 -85
- package/src/client/commands.ts +30 -15
- package/src/client/controller.ts +27 -7
- package/src/client/detail/SessionDetail.tsx +234 -37
- package/src/client/detail/detail.module.css +100 -153
- package/src/client/detail/logic.ts +220 -29
- package/src/client/detail/strings.ts +66 -77
- package/src/client/detail-glue.ts +33 -0
- package/src/client/detail-view.module.css +43 -35
- package/src/client/detail-view.tsx +138 -118
- package/src/client/dsh-tools/LineageTree.tsx +22 -13
- package/src/client/dsh-tools/SearchPanel.tsx +18 -11
- package/src/client/dsh-tools/dsh-tools.module.css +53 -140
- package/src/client/dsh-tools/strings.ts +42 -77
- package/src/client/index.ts +285 -124
- package/src/client/inject/InjectPanel.tsx +81 -61
- package/src/client/inject/inject.module.css +97 -197
- package/src/client/inject/logic.ts +38 -0
- package/src/client/lifecycle/handoff.ts +83 -0
- package/src/client/locales/en.ts +91 -4
- package/src/client/locales/host.ts +131 -0
- package/src/client/locales/index.ts +196 -8
- package/src/client/locales/react.ts +10 -0
- package/src/client/locales/view.ts +38 -0
- package/src/client/locales/zh.ts +200 -125
- package/src/client/mount.tsx +75 -41
- package/src/client/navigation/CenterOverlay.tsx +40 -0
- package/src/client/navigation/center-overlay.module.css +51 -0
- package/src/client/navigation/center.ts +45 -0
- package/src/client/navigation/modal-isolation.ts +152 -0
- package/src/client/navigation/modal-surface-anchor.ts +72 -0
- package/src/client/navigation/sidebar-entry.module.css +73 -0
- package/src/client/navigation/sidebar-entry.ts +309 -0
- package/src/client/primitives/StaticPill.tsx +21 -0
- package/src/client/settings-card.module.css +35 -119
- package/src/client/settings-card.tsx +31 -153
- package/src/client/settings-fields.tsx +131 -0
- package/src/client/sidebar/SidebarTab.tsx +156 -0
- package/src/client/sidebar/model.ts +65 -0
- package/src/client/sidebar/sidebar-tab.module.css +118 -0
- package/src/client/sidebar-tab.tsx +46 -320
- package/src/client/theme/agsc.module.css +31 -0
- package/src/client/theme/parts.ts +56 -0
- package/src/client/ui-integration.ts +86 -0
- package/src/client/widget.tsx +42 -16
- package/src/client/inject/overlay.module.css +0 -22
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI composition ports for the board and session-detail surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Views depend on these narrow factory seams instead of owning the
|
|
5
|
+
* application assembly contract. The default factory binds the existing
|
|
6
|
+
* stores; callers can provide alternate port implementations in tests or
|
|
7
|
+
* other materializations.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { AnalysisStore } from './analysis-glue.ts'
|
|
13
|
+
import { DetailStore, type DetailHeaderHint } from './detail-glue.ts'
|
|
14
|
+
import type { InjectActions } from './inject-glue.ts'
|
|
15
|
+
import type { InjectMode } from './inject/logic.ts'
|
|
16
|
+
import { ProjectsStore } from './project-glue.ts'
|
|
17
|
+
import { SearchStore } from './search-glue.ts'
|
|
18
|
+
|
|
19
|
+
/** Detail-store capabilities consumed by the session-detail surface. */
|
|
20
|
+
export type DetailStorePort = Pick<
|
|
21
|
+
DetailStore,
|
|
22
|
+
| 'subscribe'
|
|
23
|
+
| 'getState'
|
|
24
|
+
| 'open'
|
|
25
|
+
| 'loadMore'
|
|
26
|
+
| 'toggleListen'
|
|
27
|
+
| 'refreshNewest'
|
|
28
|
+
| 'notifySnapshot'
|
|
29
|
+
| 'dispose'
|
|
30
|
+
>
|
|
31
|
+
|
|
32
|
+
/** Search-store capabilities consumed by the detail tools surface. */
|
|
33
|
+
export type SearchStorePort = Pick<
|
|
34
|
+
SearchStore,
|
|
35
|
+
'subscribe' | 'getState' | 'setQuery' | 'submit' | 'dispose'
|
|
36
|
+
>
|
|
37
|
+
|
|
38
|
+
/** Analysis-store capabilities consumed by the analysis panel. */
|
|
39
|
+
export type AnalysisStorePort = Pick<
|
|
40
|
+
AnalysisStore,
|
|
41
|
+
'subscribe' | 'getState' | 'start' | 'followup' | 'stop' | 'dispose'
|
|
42
|
+
>
|
|
43
|
+
|
|
44
|
+
/** Project-store capabilities consumed by the project view. */
|
|
45
|
+
export type ProjectsStorePort = Pick<
|
|
46
|
+
ProjectsStore,
|
|
47
|
+
'subscribe' | 'getState' | 'refresh' | 'notifySnapshot' | 'dispose'
|
|
48
|
+
>
|
|
49
|
+
|
|
50
|
+
/** Optional injection capability consumed by the detail surface. */
|
|
51
|
+
export interface InjectUiPort {
|
|
52
|
+
actions: InjectActions
|
|
53
|
+
/** Read when the panel opens so late settings updates are observed. */
|
|
54
|
+
getDefaultMode: () => InjectMode
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Dependencies required to assemble one session-detail surface. */
|
|
58
|
+
export interface DetailUiPort {
|
|
59
|
+
inject?: InjectUiPort
|
|
60
|
+
/** Live settings-backed analysis gate; defaults remain fail-closed. */
|
|
61
|
+
getAnalysisEnabled: () => boolean
|
|
62
|
+
createDetailStore: (sessionId: string, hint: DetailHeaderHint | null) => DetailStorePort
|
|
63
|
+
createSearchStore: () => SearchStorePort
|
|
64
|
+
createAnalysisStore: () => AnalysisStorePort
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Dependencies required by the board and the detail route it opens. */
|
|
68
|
+
export interface BoardUiPort {
|
|
69
|
+
detail: DetailUiPort
|
|
70
|
+
createProjectsStore: () => ProjectsStorePort
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
type DetailIntegrationBase = Pick<DetailUiPort, 'inject' | 'getAnalysisEnabled'>
|
|
74
|
+
|
|
75
|
+
/** Bind the production store implementations at the client composition root. */
|
|
76
|
+
export function createDefaultIntegration(base: DetailIntegrationBase): BoardUiPort {
|
|
77
|
+
return {
|
|
78
|
+
detail: {
|
|
79
|
+
...base,
|
|
80
|
+
createDetailStore: (sessionId, hint) => new DetailStore(sessionId, { hint }),
|
|
81
|
+
createSearchStore: () => new SearchStore(),
|
|
82
|
+
createAnalysisStore: () => new AnalysisStore(),
|
|
83
|
+
},
|
|
84
|
+
createProjectsStore: () => new ProjectsStore(),
|
|
85
|
+
}
|
|
86
|
+
}
|
package/src/client/widget.tsx
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import type { CSSProperties, ReactElement } from 'react'
|
|
15
15
|
import { widgetTitle, type WidgetConnection } from './board/logic.ts'
|
|
16
|
+
import { surfaceProps } from './theme/parts.ts'
|
|
16
17
|
|
|
17
18
|
export interface SidecarWidgetProps {
|
|
18
19
|
connection: WidgetConnection
|
|
@@ -22,9 +23,9 @@ export interface SidecarWidgetProps {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const DOT_COLORS: Record<WidgetConnection, string> = {
|
|
25
|
-
ok: 'var(--
|
|
26
|
-
degraded: 'var(--
|
|
27
|
-
off: 'var(--
|
|
26
|
+
ok: 'var(--agsc-ok)',
|
|
27
|
+
degraded: 'var(--agsc-warn)',
|
|
28
|
+
off: 'var(--agsc-fg-dimmed)',
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
const rootStyle: CSSProperties = {
|
|
@@ -35,9 +36,8 @@ const rootStyle: CSSProperties = {
|
|
|
35
36
|
border: 'none',
|
|
36
37
|
borderRadius: 6,
|
|
37
38
|
background: 'transparent',
|
|
38
|
-
cursor: 'pointer',
|
|
39
39
|
font: 'inherit',
|
|
40
|
-
color: 'var(--
|
|
40
|
+
color: 'var(--agsc-fg-secondary)',
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const countStyle: CSSProperties = {
|
|
@@ -47,19 +47,16 @@ const countStyle: CSSProperties = {
|
|
|
47
47
|
whiteSpace: 'nowrap',
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Connection dot + working-session counter (e.g. `▸2`) for the footer.
|
|
52
|
+
*
|
|
53
|
+
* Without `onOpen` the widget remains an inert status `<span>` so button
|
|
54
|
+
* semantics are only emitted for an actual control.
|
|
55
|
+
*/
|
|
51
56
|
export function SidecarWidget(props: SidecarWidgetProps): ReactElement {
|
|
52
57
|
const title = widgetTitle(props.connection, props.workingCount)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
type="button"
|
|
56
|
-
style={rootStyle}
|
|
57
|
-
title={title}
|
|
58
|
-
aria-label={title}
|
|
59
|
-
onClick={props.onOpen}
|
|
60
|
-
data-testid="agent-sidecar-widget"
|
|
61
|
-
data-connection={props.connection}
|
|
62
|
-
>
|
|
58
|
+
const body = (
|
|
59
|
+
<>
|
|
63
60
|
<span
|
|
64
61
|
aria-hidden
|
|
65
62
|
style={{
|
|
@@ -75,6 +72,35 @@ export function SidecarWidget(props: SidecarWidgetProps): ReactElement {
|
|
|
75
72
|
{`▸${props.workingCount}`}
|
|
76
73
|
</span>
|
|
77
74
|
)}
|
|
75
|
+
</>
|
|
76
|
+
)
|
|
77
|
+
if (props.onOpen === undefined) {
|
|
78
|
+
return (
|
|
79
|
+
<span
|
|
80
|
+
{...surfaceProps('footer-widget')}
|
|
81
|
+
style={rootStyle}
|
|
82
|
+
title={title}
|
|
83
|
+
aria-label={title}
|
|
84
|
+
role="status"
|
|
85
|
+
data-testid="agent-sidecar-widget"
|
|
86
|
+
data-connection={props.connection}
|
|
87
|
+
>
|
|
88
|
+
{body}
|
|
89
|
+
</span>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
return (
|
|
93
|
+
<button
|
|
94
|
+
{...surfaceProps('footer-widget')}
|
|
95
|
+
type="button"
|
|
96
|
+
style={{ ...rootStyle, cursor: 'pointer' }}
|
|
97
|
+
title={title}
|
|
98
|
+
aria-label={title}
|
|
99
|
+
onClick={props.onOpen}
|
|
100
|
+
data-testid="agent-sidecar-widget"
|
|
101
|
+
data-connection={props.connection}
|
|
102
|
+
>
|
|
103
|
+
{body}
|
|
78
104
|
</button>
|
|
79
105
|
)
|
|
80
106
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/* Modal host for the inject panel (S5 wiring): a centered dialog over the
|
|
2
|
-
* board, opened by selecting a session card. Backdrop rides the dsh mask
|
|
3
|
-
* token --dsw-alias-bg-mask-1 (the ui-attachment / ui-settings-general
|
|
4
|
-
* modal precedent) — same no-literal-colors discipline as the panel. */
|
|
5
|
-
|
|
6
|
-
.backdrop {
|
|
7
|
-
position: fixed;
|
|
8
|
-
inset: 0;
|
|
9
|
-
z-index: 1000;
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
padding: 24px;
|
|
14
|
-
background: var(--dsw-alias-bg-mask-1);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.dialog {
|
|
18
|
-
width: min(560px, 100%);
|
|
19
|
-
max-height: min(85vh, 720px);
|
|
20
|
-
overflow: auto;
|
|
21
|
-
border-radius: 12px;
|
|
22
|
-
}
|