@kiberon-labs/behave-graph-flow 2.0.0 → 3.0.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 (251) hide show
  1. package/.storybook/manager.ts +6 -0
  2. package/.storybook/preview.ts +49 -1
  3. package/.storybook/styles.css +9 -3
  4. package/.turbo/turbo-build.log +1 -1
  5. package/CHANGELOG.md +368 -0
  6. package/dist/AnyControlImpl-Ds-CShIB.js +20 -0
  7. package/dist/AnyControlImpl-Ds-CShIB.js.map +1 -0
  8. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js +166 -0
  9. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js.map +1 -0
  10. package/dist/index.css +36 -33
  11. package/dist/index.css.map +1 -1
  12. package/dist/index.d.ts +1865 -550
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +14357 -11221
  15. package/dist/index.js.map +1 -1
  16. package/dist/noteImpl-KkrrWgJd.js +242 -0
  17. package/dist/noteImpl-KkrrWgJd.js.map +1 -0
  18. package/dist/styles.module-CvmpDkZj.css +3 -0
  19. package/dist/styles.module-CvmpDkZj.css.map +1 -0
  20. package/dist/styles.module-DZxg8aW9.js +271 -0
  21. package/dist/styles.module-DZxg8aW9.js.map +1 -0
  22. package/dist/useChangeNodeData-ChQGK7AI.js +23 -0
  23. package/dist/useChangeNodeData-ChQGK7AI.js.map +1 -0
  24. package/docs/protocol.md +43 -20
  25. package/package.json +5 -9
  26. package/src/components/FloatingToolbar/index.module.css +5 -13
  27. package/src/components/FloatingToolbar/index.tsx +9 -9
  28. package/src/components/Flow.tsx +34 -23
  29. package/src/components/contextMenus/DynamicContextMenu.tsx +85 -0
  30. package/src/components/contextMenus/NodePicker.module.css +13 -13
  31. package/src/components/contextMenus/edge.tsx +9 -95
  32. package/src/components/contextMenus/node.tsx +9 -149
  33. package/src/components/contextMenus/selection.tsx +5 -71
  34. package/src/components/controls/any/AnyControlImpl.tsx +14 -0
  35. package/src/components/controls/any/index.tsx +13 -2
  36. package/src/components/edges/index.tsx +75 -69
  37. package/src/components/layoutController/index.module.css +3 -0
  38. package/src/components/layoutController/index.tsx +24 -1
  39. package/src/components/layoutController/utils.ts +46 -3
  40. package/src/components/menubar/defaults.tsx +55 -19
  41. package/src/components/menubar/menuItem.module.css +18 -3
  42. package/src/components/menubar/menuItem.tsx +34 -1
  43. package/src/components/nodes/behave/NodeContainer.module.css +26 -25
  44. package/src/components/nodes/group/index.tsx +3 -3
  45. package/src/components/nodes/wrapper/styles.module.css +6 -32
  46. package/src/components/panels/alignment/index.module.css +0 -10
  47. package/src/components/panels/alignment/index.tsx +4 -4
  48. package/src/components/panels/base/styles.module.css +2 -2
  49. package/src/components/panels/common/PanelHeader.module.css +24 -0
  50. package/src/components/panels/common/PanelHeader.tsx +22 -0
  51. package/src/components/panels/common/SectionTitle.module.css +13 -0
  52. package/src/components/panels/common/SectionTitle.tsx +10 -0
  53. package/src/components/panels/events/EditEventPanel.tsx +14 -5
  54. package/src/components/panels/events/ManageEventsPanel.tsx +11 -8
  55. package/src/components/panels/events/styles.module.css +6 -64
  56. package/src/components/panels/graphProperties/index.tsx +125 -0
  57. package/src/components/panels/history/index.tsx +2 -2
  58. package/src/components/panels/history/styles.module.css +0 -9
  59. package/src/components/panels/keymaps/index.module.css +3 -13
  60. package/src/components/panels/keymaps/index.tsx +1 -2
  61. package/src/components/panels/layers/index.tsx +20 -15
  62. package/src/components/panels/layers/styles.module.css +9 -12
  63. package/src/components/panels/legend/index.tsx +1 -1
  64. package/src/components/panels/logs/index.module.css +25 -19
  65. package/src/components/panels/logs/index.tsx +7 -7
  66. package/src/components/panels/nodeInputs/InputsGroup.tsx +1 -0
  67. package/src/components/panels/nodeInputs/NodeSettings.tsx +2 -2
  68. package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +1 -1
  69. package/src/components/panels/nodeInputs/OutputsGroup.tsx +2 -12
  70. package/src/components/panels/nodeInputs/index.module.css +99 -75
  71. package/src/components/panels/nodeInputs/index.tsx +21 -11
  72. package/src/components/panels/nodeInputs/useNodeHandlers.ts +2 -2
  73. package/src/components/panels/nodeInputs/useNodeInputsData.ts +23 -43
  74. package/src/components/panels/nodePicker/index.tsx +8 -8
  75. package/src/components/panels/panel/index.module.css +7 -7
  76. package/src/components/panels/search/index.module.css +0 -50
  77. package/src/components/panels/search/index.tsx +2 -2
  78. package/src/components/panels/systemSettings/ConversionsSettings.tsx +203 -0
  79. package/src/components/panels/systemSettings/index.tsx +221 -176
  80. package/src/components/panels/systemSettings/styles.module.css +135 -8
  81. package/src/components/panels/traces/GridLines.tsx +1 -1
  82. package/src/components/panels/traces/TimeGrid.tsx +3 -3
  83. package/src/components/panels/traces/TraceLane.tsx +1 -1
  84. package/src/components/panels/traces/index.module.css +1 -8
  85. package/src/components/panels/traces/index.tsx +8 -4
  86. package/src/components/panels/traces/useDerivedSpans.ts +241 -146
  87. package/src/components/panels/traces/utils.ts +8 -0
  88. package/src/components/panels/variables/CreateVariableScreen.tsx +3 -3
  89. package/src/components/panels/variables/ManageVariablesScreen.tsx +12 -9
  90. package/src/components/panels/variables/index.tsx +2 -2
  91. package/src/components/panels/variables/styles.module.css +4 -91
  92. package/src/components/primitives/icon.module.css +4 -4
  93. package/src/components/sockets/input/index.tsx +9 -2
  94. package/src/components/sockets/input/styles.module.css +2 -3
  95. package/src/components/sockets/output/index.tsx +10 -3
  96. package/src/components/sockets/output/styles.module.css +1 -6
  97. package/src/css/notes.css +135 -0
  98. package/src/css/prosemirror.css +3 -3
  99. package/src/css/rc-dock.css +143 -43
  100. package/src/css/rc-menu.css +56 -55
  101. package/src/css/themes/kiberon.css +127 -0
  102. package/src/css/vars.css +197 -13
  103. package/src/css/vscode-elements.css +124 -0
  104. package/src/generators/CallSubgraphGenerator.tsx +136 -0
  105. package/src/generators/CustomEventOnTriggeredGenerator.tsx +2 -2
  106. package/src/generators/GraphBoundaryGenerator.module.css +32 -0
  107. package/src/generators/GraphBoundaryGenerator.tsx +193 -0
  108. package/src/generators/SequenceGenerator.tsx +2 -2
  109. package/src/generators/SwitchOnIntegerGenerator.tsx +2 -2
  110. package/src/generators/SwitchOnStringGenerator.tsx +2 -2
  111. package/src/generators/callSubgraphSync.ts +126 -0
  112. package/src/generators/registerDefaultGenerators.ts +21 -0
  113. package/src/generators/registerDefaults.ts +26 -0
  114. package/src/hooks/useBehaveGraphFlow.ts +2 -2
  115. package/src/hooks/useFlowHandlers.ts +47 -9
  116. package/src/hooks/useWasdPan.ts +26 -4
  117. package/src/index.css +4 -16
  118. package/src/index.ts +17 -0
  119. package/src/manifest/contributionRegistry.ts +93 -0
  120. package/src/manifest/index.ts +4 -0
  121. package/src/manifest/loadManifest.ts +82 -0
  122. package/src/manifest/manifestPlugin.ts +29 -0
  123. package/src/manifest/passthroughValueType.ts +40 -0
  124. package/src/plugin/alignment/index.ts +22 -12
  125. package/src/plugin/autosave/controller.ts +366 -0
  126. package/src/plugin/autosave/index.tsx +114 -0
  127. package/src/plugin/autosave/panel/BackupPanel.tsx +141 -0
  128. package/src/plugin/autosave/panel/index.tsx +1 -0
  129. package/src/plugin/autosave/panel/styles.module.css +56 -0
  130. package/src/plugin/autosave/settings.ts +65 -0
  131. package/src/plugin/autosave/storage.ts +147 -0
  132. package/src/plugin/docs/index.tsx +2 -4
  133. package/src/plugin/docs/panel/DocumentationBrowserPanelImpl.tsx +200 -0
  134. package/src/plugin/docs/panel/index.tsx +15 -194
  135. package/src/plugin/docs/panel/styles.module.css +8 -8
  136. package/src/plugin/graphrunner/actions.ts +258 -185
  137. package/src/plugin/graphrunner/buttons.tsx +34 -26
  138. package/src/plugin/graphrunner/client.ts +4 -1
  139. package/src/plugin/graphrunner/index.tsx +29 -100
  140. package/src/plugin/graphrunner/panel.tsx +2 -2
  141. package/src/plugin/graphrunner/runController.ts +283 -0
  142. package/src/plugin/graphrunner/runner.ts +21 -192
  143. package/src/plugin/graphrunner/store.ts +14 -24
  144. package/src/plugin/graphrunner/styles.module.css +17 -57
  145. package/src/plugin/graphrunner/transport.ts +26 -0
  146. package/src/plugin/graphrunner/types.ts +21 -0
  147. package/src/plugin/graphrunner-local/execution-utils.ts +260 -80
  148. package/src/plugin/graphrunner-local/index.tsx +8 -2
  149. package/src/plugin/graphrunner-local/panel.tsx +131 -175
  150. package/src/plugin/graphrunner-local/styles.module.css +57 -76
  151. package/src/plugin/graphrunner-local/transport.ts +151 -184
  152. package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +2 -0
  153. package/src/plugin/graphrunner-webworker/index.tsx +4 -10
  154. package/src/plugin/graphrunner-webworker/store.ts +9 -0
  155. package/src/plugin/kitchen-sink/index.ts +38 -0
  156. package/src/{layout/dagre.tsx → plugin/layout/dagre.ts} +17 -5
  157. package/src/{layout → plugin/layout}/elk.ts +22 -6
  158. package/src/plugin/layout/index.ts +80 -0
  159. package/src/plugin/notes/FormatToolbar.tsx +200 -0
  160. package/src/plugin/notes/index.tsx +191 -0
  161. package/src/plugin/notes/nodeActions.ts +100 -0
  162. package/src/plugin/notes/note.tsx +20 -0
  163. package/src/plugin/notes/noteImpl.tsx +89 -0
  164. package/src/plugin/realtime/realtimeRunner.ts +58 -4
  165. package/src/specifics/CustomEventOnTriggeredSpecific.tsx +2 -2
  166. package/src/specifics/CustomEventTriggerSpecific.tsx +2 -2
  167. package/src/specifics/VariableGetSpecific.tsx +2 -2
  168. package/src/specifics/VariableSetSpecific.tsx +2 -2
  169. package/src/store/actions.tsx +5 -5
  170. package/src/store/commands.ts +278 -0
  171. package/src/store/contextMenu.ts +192 -0
  172. package/src/store/conversions.ts +47 -0
  173. package/src/store/flow.tsx +23 -38
  174. package/src/store/graphMeta.ts +39 -0
  175. package/src/store/hotKeys.tsx +301 -260
  176. package/src/store/layers.ts +3 -3
  177. package/src/store/registry.ts +12 -4
  178. package/src/store/selection.ts +3 -3
  179. package/src/store/settings.ts +82 -82
  180. package/src/store/settingsSchema.ts +210 -0
  181. package/src/store/tabs.ts +5 -1
  182. package/src/store/traces.ts +3 -3
  183. package/src/system/graph.ts +11 -14
  184. package/src/system/graphSession.ts +172 -0
  185. package/src/system/index.ts +3 -0
  186. package/src/system/notifications.ts +13 -0
  187. package/src/system/persistence.ts +82 -0
  188. package/src/system/plugin.ts +28 -0
  189. package/src/system/provider.tsx +64 -0
  190. package/src/system/system.ts +518 -88
  191. package/src/system/tabLoader.tsx +70 -32
  192. package/src/system/undoRedo.ts +1 -1
  193. package/src/transformers/Uigraph.ts +5 -4
  194. package/src/transformers/contract.ts +87 -0
  195. package/src/transformers/flowToBehave.ts +13 -5
  196. package/src/types/nodes.ts +8 -3
  197. package/src/types.ts +2 -0
  198. package/src/util/autoConvert.ts +200 -0
  199. package/src/util/isValidConnection.ts +23 -2
  200. package/stories/defaults/defaultStoryProvider.tsx +17 -14
  201. package/stories/defaults/systemGenerator.ts +6 -1
  202. package/stories/{components/nodes/comment.stories.tsx → plugins/notes.stories.tsx} +24 -30
  203. package/tests/autoConvert.test.ts +329 -0
  204. package/tests/autosavePlugin.test.ts +204 -0
  205. package/tests/callSubgraphSync.test.ts +148 -0
  206. package/tests/commandRegistry.test.ts +137 -0
  207. package/tests/contract.test.ts +51 -0
  208. package/tests/contractSerialize.test.ts +62 -0
  209. package/tests/deriveSpans.test.ts +71 -0
  210. package/tests/flowToBehave.test.ts +2 -1
  211. package/tests/hotkeys.test.ts +79 -0
  212. package/tests/keepAliveLifecycle.test.ts +167 -0
  213. package/tests/loadManifest.test.ts +113 -0
  214. package/tests/noteMarkdown.test.ts +65 -0
  215. package/tests/notesPlugin.test.ts +162 -0
  216. package/tests/persistence.test.ts +51 -0
  217. package/tests/saveLoad.test.ts +7 -6
  218. package/tests/settings.test.ts +178 -0
  219. package/tests/traceStore.test.ts +46 -0
  220. package/tests/visual/README.md +2 -2
  221. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-conversation-chromium-win32.png +0 -0
  222. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-events-chromium-win32.png +0 -0
  223. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-history-chromium-win32.png +0 -0
  224. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-keymaps-chromium-win32.png +0 -0
  225. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-layers-chromium-win32.png +0 -0
  226. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-legend-chromium-win32.png +0 -0
  227. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-localGraphRunner-chromium-win32.png +0 -0
  228. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-logs-chromium-win32.png +0 -0
  229. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodeInputs-chromium-win32.png +0 -0
  230. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodePicker-chromium-win32.png +0 -0
  231. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-panel-chromium-win32.png +0 -0
  232. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-search-chromium-win32.png +0 -0
  233. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-systemSettings-chromium-win32.png +0 -0
  234. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-variables-chromium-win32.png +0 -0
  235. package/tests/visual/panels.visual.test.tsx +3 -3
  236. package/tests/wasdPan.test.ts +71 -0
  237. package/vitest.config.ts +1 -1
  238. package/vitest.visual.config.ts +7 -0
  239. package/.storybook/vscode.css +0 -814
  240. package/src/components/nodes/comment/FormatToolbar.tsx +0 -118
  241. package/src/components/nodes/comment/comment.tsx +0 -103
  242. package/src/components/nodes/comment/styles.module.css +0 -150
  243. package/src/components/panels/conversation/index.module.css +0 -151
  244. package/src/components/panels/conversation/index.tsx +0 -162
  245. package/src/components/panels/events/CustomEventsEditor.tsx +0 -384
  246. package/src/css/vscode.css +0 -13
  247. package/src/hooks/useDetachNodes.ts +0 -39
  248. package/src/plugin/graphrunner-webworker/types.ts +0 -17
  249. package/src/specifics/registerDefaultSpecifics.ts +0 -5
  250. package/src/store/chat.ts +0 -73
  251. package/src/store/graphRunnerClient.ts +0 -110
@@ -1,118 +0,0 @@
1
- import styles from './styles.module.css';
2
- import type { Editor } from '@tiptap/react';
3
- import { Code, List, NumberedListLeft, Quote } from 'iconoir-react';
4
-
5
- interface FormatToolbarProps {
6
- editor: Editor;
7
- }
8
-
9
- export const FormatToolbar = ({ editor }: FormatToolbarProps) => {
10
- return (
11
- <div className={styles.bubbleMenu}>
12
- <div className={styles.menuBar}>
13
- <button
14
- type="button"
15
- onClick={() => editor.chain().focus().toggleBold().run()}
16
- className={editor.isActive('bold') ? styles.isActive : ''}
17
- title="Bold"
18
- >
19
- <strong>B</strong>
20
- </button>
21
- <button
22
- type="button"
23
- onClick={() => editor.chain().focus().toggleItalic().run()}
24
- className={editor.isActive('italic') ? styles.isActive : ''}
25
- title="Italic"
26
- >
27
- <em>I</em>
28
- </button>
29
- <button
30
- type="button"
31
- onClick={() => editor.chain().focus().toggleStrike().run()}
32
- className={editor.isActive('strike') ? styles.isActive : ''}
33
- title="Strikethrough"
34
- >
35
- <s>S</s>
36
- </button>
37
- <button
38
- type="button"
39
- onClick={() => editor.chain().focus().toggleCode().run()}
40
- className={editor.isActive('code') ? styles.isActive : ''}
41
- title="Code"
42
- >
43
- <Code />
44
- </button>
45
- <div className={styles.separator} />
46
- <button
47
- type="button"
48
- onClick={() =>
49
- editor.chain().focus().toggleHeading({ level: 1 }).run()
50
- }
51
- className={
52
- editor.isActive('heading', { level: 1 }) ? styles.isActive : ''
53
- }
54
- title="Heading 1"
55
- >
56
- H1
57
- </button>
58
- <button
59
- type="button"
60
- onClick={() =>
61
- editor.chain().focus().toggleHeading({ level: 2 }).run()
62
- }
63
- className={
64
- editor.isActive('heading', { level: 2 }) ? styles.isActive : ''
65
- }
66
- title="Heading 2"
67
- >
68
- H2
69
- </button>
70
- <button
71
- type="button"
72
- onClick={() =>
73
- editor.chain().focus().toggleHeading({ level: 3 }).run()
74
- }
75
- className={
76
- editor.isActive('heading', { level: 3 }) ? styles.isActive : ''
77
- }
78
- title="Heading 3"
79
- >
80
- H3
81
- </button>
82
- <div className={styles.separator} />
83
- <button
84
- type="button"
85
- onClick={() => editor.chain().focus().toggleBulletList().run()}
86
- className={editor.isActive('bulletList') ? styles.isActive : ''}
87
- title="Bullet List"
88
- >
89
- <List />
90
- </button>
91
- <button
92
- type="button"
93
- onClick={() => editor.chain().focus().toggleOrderedList().run()}
94
- className={editor.isActive('orderedList') ? styles.isActive : ''}
95
- title="Numbered List"
96
- >
97
- <NumberedListLeft />
98
- </button>
99
- <button
100
- type="button"
101
- onClick={() => editor.chain().focus().toggleCodeBlock().run()}
102
- className={editor.isActive('codeBlock') ? styles.isActive : ''}
103
- title="Code Block"
104
- >
105
- <Code />
106
- </button>
107
- <button
108
- type="button"
109
- onClick={() => editor.chain().focus().toggleBlockquote().run()}
110
- className={editor.isActive('blockquote') ? styles.isActive : ''}
111
- title="Quote"
112
- >
113
- <Quote />
114
- </button>
115
- </div>
116
- </div>
117
- );
118
- };
@@ -1,103 +0,0 @@
1
- import styles from './styles.module.css';
2
- import { memo, useEffect, useRef, useState } from 'react';
3
- import { NodeResizer, type OnResize } from 'reactflow';
4
- import { useEditor, EditorContent } from '@tiptap/react';
5
- import StarterKit from '@tiptap/starter-kit';
6
- import { useChangeNodeData } from '@/hooks/useChangeNodeData';
7
- import { BaseNodeWrapper } from '../wrapper';
8
- import { Markdown } from 'tiptap-markdown';
9
- import type { ICommentNode } from '@/types/nodes';
10
- import { FormatToolbar } from './FormatToolbar';
11
- import type { NodeProps } from 'reactflow';
12
-
13
- const CommentNodeRaw = ({
14
- data,
15
- selected,
16
- id
17
- }: NodeProps<ICommentNode['data']>) => {
18
- const [isEditing, setIsEditing] = useState(false);
19
- const containerRef = useRef<HTMLDivElement>(null);
20
- const handleNodeChange = useChangeNodeData(id);
21
-
22
- const editor = useEditor({
23
- extensions: [StarterKit, Markdown],
24
- content: data.text || '> Comment',
25
- editable: isEditing,
26
- editorProps: {
27
- attributes: {
28
- class: 'prose prose-sm focus:outline-none w-full h-full nodrag',
29
- style: `font-size: ${data.fontSize || 'medium'}; padding: 0.5rem;`
30
- }
31
- },
32
- onUpdate: ({ editor }) => {
33
- const markdown = (
34
- editor.storage as { markdown?: { getMarkdown(): string } }
35
- ).markdown;
36
- if (markdown) {
37
- handleNodeChange('text', markdown.getMarkdown());
38
- }
39
- }
40
- });
41
-
42
- useEffect(() => {
43
- if (editor) {
44
- editor.setEditable(isEditing);
45
- }
46
- }, [isEditing, editor]);
47
-
48
- useEffect(() => {
49
- if (editor && data.fontSize) {
50
- const editorElement = editor.view.dom as HTMLElement;
51
- editorElement.style.fontSize = data.fontSize;
52
- }
53
- }, [data.fontSize, editor]);
54
-
55
- const onResize: OnResize = (event, params) => {
56
- if (!containerRef.current) return;
57
- containerRef.current.style.height = `${params.height}px`;
58
- containerRef.current.style.width = `${params.width}px`;
59
- };
60
-
61
- const handleDoubleClick = () => {
62
- setIsEditing(true);
63
- setTimeout(() => {
64
- editor?.commands.focus();
65
- }, 0);
66
- };
67
-
68
- const handleBlur = (e: React.FocusEvent) => {
69
- // Check if the new focus target is within the editor
70
- const relatedTarget = e.relatedTarget as Node;
71
- if (containerRef.current?.contains(relatedTarget)) {
72
- return; // Don't close if focus is moving within the editor
73
- }
74
-
75
- setTimeout(() => {
76
- setIsEditing(false);
77
- }, 200);
78
- };
79
-
80
- return (
81
- <BaseNodeWrapper metadata={data.annotations}>
82
- <div className={styles.commentNode}>
83
- <NodeResizer
84
- onResize={onResize}
85
- color="#ff0071"
86
- isVisible={selected || false}
87
- />
88
-
89
- <div
90
- ref={containerRef}
91
- className={styles.editorContainer}
92
- onDoubleClick={handleDoubleClick}
93
- onBlur={handleBlur}
94
- >
95
- {editor && isEditing && <FormatToolbar editor={editor} />}
96
- <EditorContent editor={editor} className={styles.editorContent} />
97
- </div>
98
- </div>
99
- </BaseNodeWrapper>
100
- );
101
- };
102
-
103
- export const CommentNode = memo(CommentNodeRaw);
@@ -1,150 +0,0 @@
1
- .commentNode {
2
- background: var(--colors-bgSurface);
3
- color: white;
4
- border-radius: 2px;
5
- border: 1px solid var(--vscode-textBlockQuote-border);
6
- position: relative;
7
- width: 100%;
8
- height: 100%;
9
- }
10
-
11
- .editorContainer {
12
- background: var(--vscode-editor-background);
13
- padding: 10px;
14
- width: 100%;
15
- height: 100%;
16
- position: relative;
17
- }
18
-
19
- .editorContent {
20
- width: 100%;
21
- height: 100%;
22
- min-height: 100px;
23
- cursor: text;
24
- overflow: auto;
25
- }
26
-
27
- .editorContent :global(.ProseMirror) {
28
- outline: none;
29
- width: 100%;
30
- height: 100%;
31
- color: var(--vscode-editor-foreground);
32
- }
33
-
34
- .editorContent :global(.ProseMirror p) {
35
- margin: 0.5em 0;
36
- }
37
-
38
- .editorContent :global(.ProseMirror h1) {
39
- font-size: 2em;
40
- font-weight: bold;
41
- margin: 0.67em 0;
42
- }
43
-
44
- .editorContent :global(.ProseMirror h2) {
45
- font-size: 1.5em;
46
- font-weight: bold;
47
- margin: 0.75em 0;
48
- }
49
-
50
- .editorContent :global(.ProseMirror h3) {
51
- font-size: 1.17em;
52
- font-weight: bold;
53
- margin: 0.83em 0;
54
- }
55
-
56
- .editorContent :global(.ProseMirror ul),
57
- .editorContent :global(.ProseMirror ol) {
58
- padding-left: 1.5em;
59
- margin: 0.5em 0;
60
- }
61
-
62
- .editorContent :global(.ProseMirror code) {
63
- background: var(--vscode-textCodeBlock-background);
64
- padding: 0.125em 0.25em;
65
- border-radius: 3px;
66
- font-family: var(--vscode-editor-font-family);
67
- }
68
-
69
- .editorContent :global(.ProseMirror pre) {
70
- background: var(--vscode-textCodeBlock-background);
71
- padding: 0.75em;
72
- border-radius: 4px;
73
- overflow-x: auto;
74
- margin: 0.5em 0;
75
- }
76
-
77
- .editorContent :global(.ProseMirror pre code) {
78
- background: none;
79
- padding: 0;
80
- }
81
-
82
- .editorContent :global(.ProseMirror blockquote) {
83
- border-left: 3px solid var(--vscode-textBlockQuote-border);
84
- padding-left: 1em;
85
- margin: 0.5em 0;
86
- font-style: italic;
87
- }
88
-
89
- .bubbleMenu {
90
- position: absolute;
91
- top: -45px;
92
- left: 50%;
93
- transform: translateX(-50%);
94
- background: var(--vscode-editorWidget-background);
95
- border: 1px solid var(--vscode-editorWidget-border);
96
- border-radius: 4px;
97
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
98
- padding: 4px;
99
- z-index: 1000;
100
- animation: fadeIn 0.15s ease;
101
- pointer-events: auto;
102
- }
103
-
104
- @keyframes fadeIn {
105
- from {
106
- opacity: 0;
107
- transform: translateX(-50%) translateY(-5px);
108
- }
109
-
110
- to {
111
- opacity: 1;
112
- transform: translateX(-50%) translateY(0);
113
- }
114
- }
115
-
116
- .menuBar {
117
- display: flex;
118
- gap: 2px;
119
- align-items: center;
120
- }
121
-
122
- .menuBar button {
123
- background: transparent;
124
- border: none;
125
- color: var(--vscode-foreground);
126
- padding: 4px 8px;
127
- cursor: pointer;
128
- border-radius: 3px;
129
- font-size: 13px;
130
- display: flex;
131
- align-items: center;
132
- justify-content: center;
133
- transition: background-color 0.15s;
134
- }
135
-
136
- .menuBar button:hover {
137
- background: var(--vscode-list-hoverBackground);
138
- }
139
-
140
- .menuBar button.isActive {
141
- background: var(--vscode-list-activeSelectionBackground);
142
- color: var(--vscode-list-activeSelectionForeground);
143
- }
144
-
145
- .separator {
146
- width: 1px;
147
- height: 20px;
148
- background: var(--vscode-editorWidget-border);
149
- margin: 0 4px;
150
- }
@@ -1,151 +0,0 @@
1
- .container {
2
- display: flex;
3
- flex-direction: column;
4
- height: 100%;
5
- overflow: hidden;
6
- }
7
-
8
- .header {
9
- display: flex;
10
- align-items: center;
11
- justify-content: space-between;
12
- padding: var(--component-spacing-xs) var(--component-spacing-sm);
13
- border-bottom: 1px solid var(--vscode-panel-border);
14
- flex-shrink: 0;
15
- }
16
-
17
- .title {
18
- font-size: 0.95em;
19
- font-weight: 600;
20
- margin: 0;
21
- }
22
-
23
- .headerActions {
24
- display: flex;
25
- gap: var(--component-spacing-xs);
26
- }
27
-
28
- .noAgent {
29
- display: flex;
30
- flex-direction: column;
31
- align-items: center;
32
- justify-content: center;
33
- flex: 1;
34
- gap: var(--component-spacing-sm);
35
- opacity: 0.6;
36
- font-size: 0.9em;
37
- text-align: center;
38
- padding: var(--component-spacing-md);
39
- }
40
-
41
- .messageList {
42
- flex: 1;
43
- overflow-y: auto;
44
- padding: var(--component-spacing-sm);
45
- display: flex;
46
- flex-direction: column;
47
- gap: var(--component-spacing-sm);
48
- }
49
-
50
- .message {
51
- display: flex;
52
- flex-direction: column;
53
- gap: 2px;
54
- max-width: 85%;
55
- animation: fadeIn 0.15s ease-in;
56
- }
57
-
58
- .userMessage {
59
- align-self: flex-end;
60
- }
61
-
62
- .assistantMessage {
63
- align-self: flex-start;
64
- }
65
-
66
- .systemMessage {
67
- align-self: center;
68
- opacity: 0.6;
69
- font-style: italic;
70
- font-size: 0.85em;
71
- }
72
-
73
- .roleLabel {
74
- font-size: 0.7em;
75
- text-transform: uppercase;
76
- letter-spacing: 0.05em;
77
- opacity: 0.6;
78
- padding: 0 var(--component-spacing-xs);
79
- }
80
-
81
- .bubble {
82
- padding: var(--component-spacing-xs) var(--component-spacing-sm);
83
- border-radius: 8px;
84
- font-size: 0.9em;
85
- line-height: 1.5;
86
- white-space: pre-wrap;
87
- word-break: break-word;
88
- }
89
-
90
- .userBubble {
91
- background-color: var(--vscode-button-background);
92
- color: var(--vscode-button-foreground);
93
- border-bottom-right-radius: 2px;
94
- }
95
-
96
- .assistantBubble {
97
- background-color: var(--vscode-editor-inactiveSelectionBackground, #2a2d2e);
98
- color: var(--vscode-editor-foreground);
99
- border-bottom-left-radius: 2px;
100
- }
101
-
102
- .systemBubble {
103
- background-color: transparent;
104
- }
105
-
106
- .streamingIndicator {
107
- display: inline-block;
108
- width: 6px;
109
- height: 14px;
110
- background-color: var(--vscode-editor-foreground);
111
- opacity: 0.6;
112
- margin-left: 2px;
113
- animation: blink 0.8s step-end infinite;
114
- vertical-align: text-bottom;
115
- }
116
-
117
- .timestamp {
118
- font-size: 0.65em;
119
- opacity: 0.4;
120
- padding: 0 var(--component-spacing-xs);
121
- }
122
-
123
- .inputArea {
124
- display: flex;
125
- gap: var(--component-spacing-xs);
126
- padding: var(--component-spacing-sm);
127
- border-top: 1px solid var(--vscode-panel-border);
128
- flex-shrink: 0;
129
- }
130
-
131
- .textInput {
132
- flex: 1;
133
- }
134
-
135
- @keyframes blink {
136
- 50% {
137
- opacity: 0;
138
- }
139
- }
140
-
141
- @keyframes fadeIn {
142
- from {
143
- opacity: 0;
144
- transform: translateY(4px);
145
- }
146
-
147
- to {
148
- opacity: 1;
149
- transform: translateY(0);
150
- }
151
- }
@@ -1,162 +0,0 @@
1
- import React, { useCallback, useEffect, useRef } from 'react';
2
- import { VscodeButton, VscodeTextfield } from '@vscode-elements/react-elements';
3
- import { Trash, SendDiagonal } from 'iconoir-react';
4
- import { useSystem } from '@/system/provider';
5
- import { useStore } from 'zustand';
6
- import { BasePanel } from '../base';
7
- import { Icon } from '@/components/primitives/icon';
8
- import type { ChatMessage } from '@/store/chat';
9
- import styles from './index.module.css';
10
-
11
- function formatTime(date: Date): string {
12
- return date.toLocaleTimeString([], {
13
- hour: '2-digit',
14
- minute: '2-digit'
15
- });
16
- }
17
-
18
- function MessageBubble({ message }: { message: ChatMessage }) {
19
- const roleClass =
20
- message.role === 'user'
21
- ? styles.userMessage
22
- : message.role === 'assistant'
23
- ? styles.assistantMessage
24
- : styles.systemMessage;
25
-
26
- const bubbleClass =
27
- message.role === 'user'
28
- ? styles.userBubble
29
- : message.role === 'assistant'
30
- ? styles.assistantBubble
31
- : styles.systemBubble;
32
-
33
- return (
34
- <div className={`${styles.message} ${roleClass}`}>
35
- <span className={styles.roleLabel}>{message.role}</span>
36
- <div className={`${styles.bubble} ${bubbleClass}`}>
37
- {message.content}
38
- {message.isStreaming && <span className={styles.streamingIndicator} />}
39
- </div>
40
- <span className={styles.timestamp}>{formatTime(message.timestamp)}</span>
41
- </div>
42
- );
43
- }
44
-
45
- export function ConversationPanel() {
46
- const system = useSystem();
47
- const messages = useStore(system.chatStore, (s) => s.messages);
48
- const agent = useStore(system.chatStore, (s) => s.agent);
49
- const isStreaming = useStore(system.chatStore, (s) => s.isStreaming);
50
- const inputValue = useStore(system.chatStore, (s) => s.inputValue);
51
- const setInputValue = useStore(system.chatStore, (s) => s.setInputValue);
52
- const clearMessages = useStore(system.chatStore, (s) => s.clearMessages);
53
-
54
- const messagesEndRef = useRef<HTMLDivElement | null>(null);
55
-
56
- const scrollToBottom = useCallback(() => {
57
- messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
58
- }, []);
59
-
60
- useEffect(() => {
61
- scrollToBottom();
62
- }, [messages, scrollToBottom]);
63
-
64
- const handleSend = useCallback(() => {
65
- const trimmed = inputValue.trim();
66
- if (!trimmed || !agent || isStreaming) {
67
- return;
68
- }
69
-
70
- system.chatStore.getState().setInputValue('');
71
-
72
- // Publish the user message — the AI subsystem adds it to
73
- // memory which fires listeners that sync to the chat store.
74
- system.pubsub.publish('chat:userMessage', {
75
- content: trimmed
76
- });
77
- }, [inputValue, agent, isStreaming, system]);
78
-
79
- const handleKeyDown = useCallback(
80
- (e: React.KeyboardEvent) => {
81
- if (e.key === 'Enter' && !e.shiftKey) {
82
- e.preventDefault();
83
- handleSend();
84
- }
85
- },
86
- [handleSend]
87
- );
88
-
89
- const handleInputChange = useCallback(
90
- (e: Event) => {
91
- const target = e.target as HTMLInputElement;
92
- setInputValue(target.value);
93
- },
94
- [setInputValue]
95
- );
96
-
97
- if (!agent) {
98
- return (
99
- <BasePanel>
100
- <div className={styles.container}>
101
- <div className={styles.noAgent}>
102
- <p>No agent connected.</p>
103
- <p>
104
- Use the <strong>Setup UI</strong> node to connect an agent to this
105
- panel.
106
- </p>
107
- </div>
108
- </div>
109
- </BasePanel>
110
- );
111
- }
112
-
113
- return (
114
- <BasePanel>
115
- <div className={styles.container}>
116
- <div className={styles.header}>
117
- <h3 className={styles.title}>Conversation</h3>
118
- <div className={styles.headerActions}>
119
- <VscodeButton
120
- secondary
121
- onClick={clearMessages}
122
- title="Clear messages"
123
- >
124
- <Icon slot="start">
125
- <Trash />
126
- </Icon>
127
- </VscodeButton>
128
- </div>
129
- </div>
130
-
131
- <div className={styles.messageList}>
132
- {messages.map((msg) => (
133
- <MessageBubble key={msg.id} message={msg} />
134
- ))}
135
- <div ref={messagesEndRef} />
136
- </div>
137
-
138
- <div className={styles.inputArea}>
139
- <VscodeTextfield
140
- className={styles.textInput}
141
- placeholder={
142
- isStreaming ? 'Waiting for response...' : 'Type a message...'
143
- }
144
- value={inputValue}
145
- onInput={handleInputChange}
146
- onKeyDown={handleKeyDown}
147
- disabled={isStreaming}
148
- />
149
- <VscodeButton
150
- onClick={handleSend}
151
- disabled={isStreaming || !inputValue.trim()}
152
- title="Send"
153
- >
154
- <Icon slot="start">
155
- <SendDiagonal />
156
- </Icon>
157
- </VscodeButton>
158
- </div>
159
- </div>
160
- </BasePanel>
161
- );
162
- }