@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.
Files changed (58) hide show
  1. package/README.md +78 -11
  2. package/lib/client.js +4708 -2932
  3. package/lib/client.js.map +1 -1
  4. package/package.json +3 -1
  5. package/src/client/analysis/AnalysisPanel.tsx +19 -27
  6. package/src/client/analysis/analysis.module.css +36 -97
  7. package/src/client/board/Board.tsx +255 -48
  8. package/src/client/board/board.module.css +113 -92
  9. package/src/client/board/logic.ts +99 -21
  10. package/src/client/board/project-view-logic.ts +27 -34
  11. package/src/client/board/project-view.module.css +46 -83
  12. package/src/client/board/project-view.tsx +50 -8
  13. package/src/client/board/strings.ts +70 -85
  14. package/src/client/commands.ts +30 -15
  15. package/src/client/controller.ts +27 -7
  16. package/src/client/detail/SessionDetail.tsx +234 -37
  17. package/src/client/detail/detail.module.css +100 -153
  18. package/src/client/detail/logic.ts +220 -29
  19. package/src/client/detail/strings.ts +66 -77
  20. package/src/client/detail-glue.ts +33 -0
  21. package/src/client/detail-view.module.css +43 -35
  22. package/src/client/detail-view.tsx +138 -118
  23. package/src/client/dsh-tools/LineageTree.tsx +22 -13
  24. package/src/client/dsh-tools/SearchPanel.tsx +18 -11
  25. package/src/client/dsh-tools/dsh-tools.module.css +53 -140
  26. package/src/client/dsh-tools/strings.ts +42 -77
  27. package/src/client/index.ts +285 -124
  28. package/src/client/inject/InjectPanel.tsx +81 -61
  29. package/src/client/inject/inject.module.css +97 -197
  30. package/src/client/inject/logic.ts +38 -0
  31. package/src/client/lifecycle/handoff.ts +83 -0
  32. package/src/client/locales/en.ts +91 -4
  33. package/src/client/locales/host.ts +131 -0
  34. package/src/client/locales/index.ts +196 -8
  35. package/src/client/locales/react.ts +10 -0
  36. package/src/client/locales/view.ts +38 -0
  37. package/src/client/locales/zh.ts +200 -125
  38. package/src/client/mount.tsx +75 -41
  39. package/src/client/navigation/CenterOverlay.tsx +40 -0
  40. package/src/client/navigation/center-overlay.module.css +51 -0
  41. package/src/client/navigation/center.ts +45 -0
  42. package/src/client/navigation/modal-isolation.ts +152 -0
  43. package/src/client/navigation/modal-surface-anchor.ts +72 -0
  44. package/src/client/navigation/sidebar-entry.module.css +73 -0
  45. package/src/client/navigation/sidebar-entry.ts +309 -0
  46. package/src/client/primitives/StaticPill.tsx +21 -0
  47. package/src/client/settings-card.module.css +35 -119
  48. package/src/client/settings-card.tsx +31 -153
  49. package/src/client/settings-fields.tsx +131 -0
  50. package/src/client/sidebar/SidebarTab.tsx +156 -0
  51. package/src/client/sidebar/model.ts +65 -0
  52. package/src/client/sidebar/sidebar-tab.module.css +118 -0
  53. package/src/client/sidebar-tab.tsx +46 -320
  54. package/src/client/theme/agsc.module.css +31 -0
  55. package/src/client/theme/parts.ts +56 -0
  56. package/src/client/ui-integration.ts +86 -0
  57. package/src/client/widget.tsx +42 -16
  58. 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
+ }
@@ -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(--dsw-alias-state-success-primary, #1a7f37)',
26
- degraded: 'var(--dsw-alias-state-warn-primary, #9a6700)',
27
- off: 'var(--dsw-alias-label-dimmed, #8c959f)',
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(--dsw-alias-label-secondary, #57606a)',
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
- /** Connection dot + working-session counter (e.g. `▸2`) for the footer. */
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
- return (
54
- <button
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
- }