@vybestack/llxprt-ui 0.7.0-nightly.251211.5750c518a
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/PLAN-messages.md +681 -0
- package/PLAN.md +47 -0
- package/README.md +25 -0
- package/bun.lock +1024 -0
- package/dev-docs/ARCHITECTURE.md +178 -0
- package/dev-docs/CODE_ORGANIZATION.md +232 -0
- package/dev-docs/STANDARDS.md +235 -0
- package/dev-docs/UI_DESIGN.md +425 -0
- package/eslint.config.cjs +194 -0
- package/images/nui.png +0 -0
- package/llxprt.png +0 -0
- package/llxprt.svg +128 -0
- package/package.json +66 -0
- package/scripts/check-limits.ts +177 -0
- package/scripts/start.js +71 -0
- package/src/app.tsx +599 -0
- package/src/bootstrap.tsx +23 -0
- package/src/commands/AuthCommand.tsx +80 -0
- package/src/commands/ModelCommand.tsx +102 -0
- package/src/commands/ProviderCommand.tsx +103 -0
- package/src/commands/ThemeCommand.tsx +71 -0
- package/src/features/chat/history.ts +178 -0
- package/src/features/chat/index.ts +3 -0
- package/src/features/chat/persistentHistory.ts +102 -0
- package/src/features/chat/responder.ts +217 -0
- package/src/features/completion/completions.ts +161 -0
- package/src/features/completion/index.ts +3 -0
- package/src/features/completion/slash.test.ts +82 -0
- package/src/features/completion/slash.ts +248 -0
- package/src/features/completion/suggestions.test.ts +51 -0
- package/src/features/completion/suggestions.ts +112 -0
- package/src/features/config/configSession.test.ts +189 -0
- package/src/features/config/configSession.ts +179 -0
- package/src/features/config/index.ts +4 -0
- package/src/features/config/llxprtAdapter.integration.test.ts +202 -0
- package/src/features/config/llxprtAdapter.test.ts +139 -0
- package/src/features/config/llxprtAdapter.ts +257 -0
- package/src/features/config/llxprtCommands.test.ts +40 -0
- package/src/features/config/llxprtCommands.ts +35 -0
- package/src/features/config/llxprtConfig.test.ts +261 -0
- package/src/features/config/llxprtConfig.ts +418 -0
- package/src/features/theme/index.ts +2 -0
- package/src/features/theme/theme.test.ts +51 -0
- package/src/features/theme/theme.ts +105 -0
- package/src/features/theme/themeManager.ts +84 -0
- package/src/hooks/useAppCommands.ts +129 -0
- package/src/hooks/useApprovalKeyboard.ts +156 -0
- package/src/hooks/useChatStore.test.ts +112 -0
- package/src/hooks/useChatStore.ts +252 -0
- package/src/hooks/useInputManager.ts +99 -0
- package/src/hooks/useKeyboardHandlers.ts +130 -0
- package/src/hooks/useListNavigation.test.ts +166 -0
- package/src/hooks/useListNavigation.ts +62 -0
- package/src/hooks/usePersistentHistory.ts +94 -0
- package/src/hooks/useScrollManagement.ts +107 -0
- package/src/hooks/useSelectionClipboard.ts +48 -0
- package/src/hooks/useSessionManager.test.ts +85 -0
- package/src/hooks/useSessionManager.ts +101 -0
- package/src/hooks/useStreamingLifecycle.ts +71 -0
- package/src/hooks/useStreamingResponder.ts +401 -0
- package/src/hooks/useSuggestionSetup.ts +23 -0
- package/src/hooks/useToolApproval.test.ts +140 -0
- package/src/hooks/useToolApproval.ts +264 -0
- package/src/hooks/useToolScheduler.ts +432 -0
- package/src/index.ts +3 -0
- package/src/jsx.d.ts +11 -0
- package/src/lib/clipboard.ts +18 -0
- package/src/lib/logger.ts +107 -0
- package/src/lib/random.ts +5 -0
- package/src/main.tsx +13 -0
- package/src/test/mockTheme.ts +51 -0
- package/src/types/events.ts +87 -0
- package/src/types.ts +13 -0
- package/src/ui/components/ChatLayout.tsx +694 -0
- package/src/ui/components/CommandComponents.tsx +74 -0
- package/src/ui/components/DiffViewer.tsx +306 -0
- package/src/ui/components/FilterInput.test.ts +69 -0
- package/src/ui/components/FilterInput.tsx +62 -0
- package/src/ui/components/HeaderBar.tsx +137 -0
- package/src/ui/components/RadioSelect.test.ts +140 -0
- package/src/ui/components/RadioSelect.tsx +88 -0
- package/src/ui/components/SelectableList.test.ts +83 -0
- package/src/ui/components/SelectableList.tsx +35 -0
- package/src/ui/components/StatusBar.tsx +45 -0
- package/src/ui/components/SuggestionPanel.tsx +102 -0
- package/src/ui/components/messages/ModelMessage.tsx +14 -0
- package/src/ui/components/messages/SystemMessage.tsx +29 -0
- package/src/ui/components/messages/ThinkingMessage.tsx +14 -0
- package/src/ui/components/messages/UserMessage.tsx +26 -0
- package/src/ui/components/messages/index.ts +15 -0
- package/src/ui/components/messages/renderMessage.test.ts +49 -0
- package/src/ui/components/messages/renderMessage.tsx +43 -0
- package/src/ui/components/messages/types.test.ts +24 -0
- package/src/ui/components/messages/types.ts +36 -0
- package/src/ui/modals/AuthModal.tsx +106 -0
- package/src/ui/modals/ModalShell.tsx +60 -0
- package/src/ui/modals/SearchSelectModal.tsx +236 -0
- package/src/ui/modals/ThemeModal.tsx +204 -0
- package/src/ui/modals/ToolApprovalModal.test.ts +206 -0
- package/src/ui/modals/ToolApprovalModal.tsx +282 -0
- package/src/ui/modals/index.ts +20 -0
- package/src/ui/modals/modals.test.ts +26 -0
- package/src/ui/modals/types.ts +19 -0
- package/src/uicontext/Command.tsx +102 -0
- package/src/uicontext/Dialog.tsx +65 -0
- package/src/uicontext/index.ts +2 -0
- package/themes/ansi-light.json +59 -0
- package/themes/ansi.json +59 -0
- package/themes/atom-one-dark.json +59 -0
- package/themes/ayu-light.json +59 -0
- package/themes/ayu.json +59 -0
- package/themes/default-light.json +59 -0
- package/themes/default.json +59 -0
- package/themes/dracula.json +59 -0
- package/themes/github-dark.json +59 -0
- package/themes/github-light.json +59 -0
- package/themes/googlecode.json +59 -0
- package/themes/green-screen.json +59 -0
- package/themes/no-color.json +59 -0
- package/themes/shades-of-purple.json +59 -0
- package/themes/xcode.json +59 -0
- package/tsconfig.json +28 -0
- package/vitest.config.ts +10 -0
package/llxprt.svg
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
3
|
+
viewBox="0 0 415 260" >
|
|
4
|
+
<style type="text/css">
|
|
5
|
+
.st0{fill:none;stroke:#000000;stroke-width:5.1877;}
|
|
6
|
+
.st1{fill:none;stroke:#C0C0C0;stroke-width:9.8156;}
|
|
7
|
+
.st2{fill:url(#SVGID_1_);}
|
|
8
|
+
.st3{opacity:0.6;fill:#FFFFFF;}
|
|
9
|
+
.st4{opacity:0.4;fill:#FFFFFF;}
|
|
10
|
+
</style>
|
|
11
|
+
<circle class="st0" cx="246.09" cy="75.4" r="70.4"/>
|
|
12
|
+
<circle class="st1" cx="246.09" cy="75.4" r="63.02"/>
|
|
13
|
+
<radialGradient id="SVGID_1_" cx="246.0865" cy="75.5194" r="65.8884" gradientUnits="userSpaceOnUse">
|
|
14
|
+
<stop offset="0" style="stop-color:#FFFF00"/>
|
|
15
|
+
<stop offset="0.6441" style="stop-color:#FF0A00"/>
|
|
16
|
+
<stop offset="0.9927" style="stop-color:#FF0A00"/>
|
|
17
|
+
</radialGradient>
|
|
18
|
+
<circle class="st2" cx="246.09" cy="75.4" r="52"/>
|
|
19
|
+
<circle class="st3" cx="231.23" cy="56.83" r="7.43"/>
|
|
20
|
+
<circle class="st4" cx="260.94" cy="49.4" r="4.46"/>
|
|
21
|
+
<path d="M-0.38,122.22l21.99-1.94l11-0.95l5.5-0.46c1.81-0.16,3.59-0.36,5.37-0.71c3.54-0.65,6.99-1.71,10.31-3.08
|
|
22
|
+
c1.66-0.69,3.28-1.46,4.87-2.3c1.59-0.84,3.12-1.77,4.77-2.69c6.56-3.64,13.61-6.41,20.87-8.29c7.25-1.94,14.72-3.01,22.21-3.42
|
|
23
|
+
l2.81-0.14c0.94-0.03,1.87-0.02,2.81-0.03l2.81-0.01c0.94,0.01,1.89,0.09,2.84,0.13l2.85,0.15c0.95,0.07,1.89,0.22,2.83,0.33
|
|
24
|
+
l2.83,0.36l2.81,0.54c7.48,1.48,14.74,4.08,21.49,7.52c6.75,3.43,13.09,7.51,19.18,11.68c3.05,2.08,6.06,4.15,9.08,6.13l4.6,2.9
|
|
25
|
+
c1.61,0.99,3.18,2,4.73,3.02c6.2,4.08,12.18,8.13,18.45,11.54c6.24,3.44,12.77,6.14,19.54,7.91c6.77,1.77,13.75,2.68,20.79,2.75
|
|
26
|
+
l5.4-0.13c1.83-0.03,3.21-0.1,4.94-0.38c3.37-0.52,6.92-1.36,10.46-2.18c7.1-1.69,14.31-3.49,21.59-5.02
|
|
27
|
+
c1.82-0.39,3.65-0.75,5.47-1.12c0.91-0.18,1.91-0.33,2.86-0.5l1.44-0.24l1.47-0.17c3.91-0.47,7.96-0.67,12.17-0.08
|
|
28
|
+
c4.17,0.59,8.65,2.05,12.35,5.06c1.86,1.48,3.37,3.34,4.62,5.28c1.22,1.97,2.06,4.06,2.73,6.13l-6.04-3.02
|
|
29
|
+
c1.28-0.46,2.32-0.78,3.48-1.11c1.13-0.32,2.26-0.62,3.4-0.88c2.28-0.53,4.58-0.96,6.92-1.27c4.67-0.61,9.51-0.78,14.44-0.02
|
|
30
|
+
c4.9,0.71,9.98,2.54,14.24,5.85c2.13,1.65,3.94,3.69,5.44,5.88c1.54,2.19,2.56,4.59,3.47,6.98l-4.41-3.2
|
|
31
|
+
c0.83,0.02,1.4,0.06,2.07,0.11c0.65,0.06,1.29,0.12,1.93,0.2c1.27,0.16,2.54,0.36,3.8,0.62c2.52,0.51,5.03,1.2,7.5,2.18
|
|
32
|
+
c2.47,0.98,4.91,2.21,7.19,3.87c2.27,1.65,4.38,3.73,6.04,6.19c1.65,2.47,2.76,5.3,3.31,8.14c0.13,0.71,0.28,1.4,0.33,2.17
|
|
33
|
+
l0.1,1.12c0.01,0.2,0.04,0.34,0.04,0.59l-0.02,0.75c-0.09,1.68-0.44,3.35-1.08,4.94c-0.64,1.59-1.58,3.09-2.71,4.36
|
|
34
|
+
c-1.13,1.29-2.47,2.27-3.82,3.12c-2.74,1.6-5.57,2.36-8.27,2.81l3.93-5.53c0.1,0.6,0.11,0.86,0.15,1.26
|
|
35
|
+
c0.02,0.36,0.05,0.72,0.05,1.07c0.01,0.71-0.01,1.41-0.09,2.12c-0.13,1.41-0.42,2.85-0.96,4.28c-0.97,2.86-3.14,5.57-5.73,7.24
|
|
36
|
+
c-0.64,0.43-1.32,0.75-1.98,1.1c-0.65,0.31-1.3,0.56-1.96,0.78c-1.32,0.44-2.65,0.74-3.96,0.91c-0.66,0.09-1.31,0.15-1.96,0.18
|
|
37
|
+
c-0.35,0.02-0.6,0.02-0.86,0.02l-0.8,0.01l-3.21,0.04c-2.17,0-4.22,0.1-6.29,0.19c-2.07,0.07-4.14,0.28-6.21,0.41
|
|
38
|
+
c-2.07,0.12-4.14,0.4-6.21,0.59c-1.03,0.11-2.07,0.2-3.1,0.33l-3.09,0.43c-2.06,0.3-4.13,0.53-6.18,0.89l-6.16,1.06l-12.47,2.37
|
|
39
|
+
c-8.28,1.61-16.52,3.36-24.72,5.3c-16.4,3.89-32.67,8.47-48.82,13.47l-12.18,3.81l-6.13,1.77c-2.05,0.6-4.12,1.2-6.22,1.76
|
|
40
|
+
c-4.2,1.12-8.52,2.08-12.94,2.68c-4.42,0.6-8.95,0.73-13.45,0.45l-3.37-0.32c-1.12-0.15-2.23-0.37-3.34-0.55l-1.67-0.29
|
|
41
|
+
l-1.64-0.42l-3.27-0.85c-4.26-1.4-8.46-3.01-12.33-5.17l-2.93-1.57l-2.75-1.6l-5.49-3.18c-3.67-2.1-7.35-4.15-11.06-6.16
|
|
42
|
+
c-7.43-4-14.95-7.81-22.6-11.36c-7.65-3.53-15.43-6.8-23.31-9.78c-15.77-5.95-32.08-10.53-48.78-12.98
|
|
43
|
+
c-8.35-1.21-16.79-1.81-25.24-1.69c-8.45,0.11-16.92,0.99-25.22,2.82c8.19-2.27,16.65-3.62,25.16-4.18
|
|
44
|
+
c8.52-0.55,17.09-0.29,25.6,0.56c17.04,1.68,33.76,5.85,49.97,11.26c16.23,5.43,31.93,12.36,47.2,20.03
|
|
45
|
+
c3.81,1.93,7.6,3.9,11.37,5.91l5.63,3.04l2.79,1.54l2.72,1.38c3.59,1.91,7.39,3.25,11.21,4.44l2.91,0.69l1.46,0.34l1.48,0.22
|
|
46
|
+
c0.99,0.14,1.96,0.32,2.95,0.43l2.98,0.22c3.98,0.16,7.97-0.02,11.95-0.65c3.98-0.63,7.95-1.59,11.93-2.74
|
|
47
|
+
c1.99-0.57,3.99-1.2,6-1.83l6.07-1.89c4.02-1.33,7.99-2.69,12.07-3.98c16.22-5.24,32.61-10.08,49.21-14.24
|
|
48
|
+
c8.3-2.07,16.65-3.96,25.02-5.69c4.18-0.86,8.37-1.66,12.55-2.46l6.39-1.13c2.13-0.38,4.28-0.63,6.42-0.95l3.21-0.46
|
|
49
|
+
c1.07-0.14,2.15-0.24,3.23-0.36c2.16-0.21,4.3-0.51,6.46-0.65c2.16-0.15,4.32-0.37,6.49-0.45c2.18-0.11,4.36-0.22,6.44-0.23
|
|
50
|
+
l3.16-0.05l0.79-0.01c0.26,0,0.55-0.01,0.73-0.02c0.41-0.02,0.81-0.06,1.2-0.12c0.79-0.11,1.54-0.28,2.23-0.52
|
|
51
|
+
c0.34-0.12,0.69-0.25,0.99-0.4c0.26-0.17,0.56-0.28,0.8-0.45c0.46-0.34,0.9-0.66,1.2-1.11c0.19-0.18,0.29-0.46,0.46-0.67
|
|
52
|
+
c0.1-0.27,0.27-0.5,0.35-0.81c0.22-0.56,0.35-1.22,0.42-1.92c0.04-0.35,0.05-0.71,0.04-1.06c0-0.18-0.02-0.35-0.02-0.52
|
|
53
|
+
c-0.01-0.13-0.04-0.39-0.03-0.32l3.93-5.53c1.88-0.32,3.61-0.85,4.89-1.62c1.27-0.79,2.07-1.69,2.52-2.82
|
|
54
|
+
c0.23-0.56,0.36-1.21,0.39-1.85c0-0.05,0-0.08,0-0.12c0-0.04-0.02-0.19-0.03-0.28l-0.07-0.62c-0.02-0.4-0.13-0.85-0.2-1.28
|
|
55
|
+
c-0.35-1.73-0.99-3.3-1.91-4.72c-1.86-2.82-5.01-5.03-8.74-6.49c-1.86-0.74-3.85-1.31-5.89-1.73c-1.02-0.21-2.06-0.38-3.09-0.51
|
|
56
|
+
c-0.52-0.07-1.03-0.12-1.55-0.17c-0.48-0.04-1.08-0.08-1.41-0.09l-3.21-0.1l-1.2-3.1c-0.66-1.7-1.34-3.38-2.34-4.78
|
|
57
|
+
c-0.98-1.42-2.09-2.71-3.44-3.76c-2.68-2.09-6.08-3.44-9.85-3.99c-3.75-0.6-7.78-0.51-11.8,0c-2.01,0.26-4.03,0.62-6.02,1.08
|
|
58
|
+
c-1,0.23-1.99,0.48-2.97,0.76c-0.96,0.26-2.01,0.59-2.8,0.87l-4.54,1.6l-1.5-4.62c-0.46-1.42-1-2.77-1.71-3.93
|
|
59
|
+
c-0.74-1.13-1.56-2.18-2.59-2.99c-2.03-1.66-4.76-2.67-7.83-3.16c-3.08-0.48-6.45-0.39-9.83-0.02l-1.27,0.13l-1.28,0.2
|
|
60
|
+
c-0.86,0.14-1.69,0.25-2.58,0.42l-5.35,1.02c-7.13,1.41-14.23,3.08-21.46,4.71c-3.63,0.8-7.26,1.62-11.17,2.18
|
|
61
|
+
c-1.9,0.31-4.2,0.41-6.05,0.4l-5.63,0.06c-7.66-0.19-15.38-1.22-22.79-3.36c-7.42-2.11-14.52-5.24-21.08-9.03
|
|
62
|
+
c-6.59-3.76-12.72-8.11-18.72-12.23c-1.5-1.04-3.01-2.04-4.51-3.01l-4.67-3.08c-3.09-2.11-6.1-4.27-9.08-6.4
|
|
63
|
+
c-5.96-4.27-11.89-8.37-18.17-11.77c-6.26-3.42-12.92-6.01-19.83-7.59c-6.9-1.61-14.05-2-21.29-1.86
|
|
64
|
+
c-7.21,0.14-14.42,0.9-21.44,2.51c-7.04,1.55-13.89,3.96-20.32,7.23c-1.59,0.81-3.24,1.73-4.95,2.53
|
|
65
|
+
c-1.7,0.81-3.43,1.54-5.2,2.19c-3.54,1.29-7.21,2.24-10.93,2.75c-1.85,0.28-3.74,0.41-5.6,0.49l-5.51,0.22l-11.03,0.41
|
|
66
|
+
L-0.38,122.22z"
|
|
67
|
+
fill="#C0C0C0"
|
|
68
|
+
stroke="#000000"
|
|
69
|
+
stroke-width="1"
|
|
70
|
+
paint-order="stroke"
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
<path d="M255.71,153.08c3.96,2.49,7.69,5.02,11.43,7.67c3.73,2.63,7.39,5.39,10.98,8.26c3.59,2.86,7.09,5.88,10.43,9.15
|
|
74
|
+
c1.69,1.6,3.28,3.36,4.87,5.13l2.27,2.82c0.72,0.98,1.37,2.02,2.05,3.03c2.62,4.01,4.76,8.74,5.29,13.98
|
|
75
|
+
c0.26,2.62,0.03,5.41-0.91,8.02l-0.39,0.97l-0.2,0.48c-0.08,0.17-0.1,0.27-0.3,0.63c-0.46,0.78-0.9,1.33-1.4,1.88
|
|
76
|
+
c-0.99,1.08-2.1,1.98-3.31,2.68c-2.41,1.44-5.08,2.14-7.65,2.33c-2.57,0.18-5.08-0.04-7.46-0.52c-1.2-0.22-2.35-0.58-3.51-0.86
|
|
77
|
+
c-1.03-0.27-2.05-0.55-3.1-0.81l-3.19-0.66l-3.26-0.55c-8.77-1.32-17.81-2.18-26.73-3.94c-4.47-0.83-8.89-1.95-13.25-3.26
|
|
78
|
+
l-3.25-1.05c-1.09-0.34-2.14-0.8-3.21-1.19c-2.15-0.76-4.21-1.76-6.29-2.68c-2.04-0.98-4.07-2.11-6.03-3.13
|
|
79
|
+
c-1.93-1.04-3.97-1.96-6.01-2.85c-4.1-1.76-8.29-3.34-12.53-4.81c-8.48-2.9-17.1-5.47-25.95-7.06c8.91,1.2,17.68,3.38,26.32,5.92
|
|
80
|
+
c4.32,1.29,8.6,2.69,12.84,4.29c2.11,0.81,4.21,1.65,6.29,2.65c2.07,0.96,4.01,1.94,6.06,2.81c2.06,0.81,4.1,1.68,6.22,2.33
|
|
81
|
+
c1.06,0.33,2.09,0.73,3.16,1.01l3.2,0.88c4.3,1.08,8.64,1.98,13.04,2.59c8.79,1.34,17.7,1.78,26.75,2.73l3.41,0.42l3.44,0.55
|
|
82
|
+
c1.15,0.22,2.31,0.49,3.46,0.74c1.03,0.19,2.04,0.46,3.06,0.6c2.03,0.31,4.05,0.37,5.95,0.16c1.9-0.22,3.65-0.82,5.07-1.76
|
|
83
|
+
c0.72-0.45,1.34-1.02,1.84-1.62c0.24-0.29,0.48-0.64,0.58-0.84c-0.05,0.11,0.01-0.05,0.04-0.15l0.1-0.3l0.22-0.6
|
|
84
|
+
c0.51-1.66,0.6-3.46,0.33-5.29c-0.26-1.84-0.86-3.7-1.66-5.51c-0.41-0.9-0.86-1.8-1.38-2.66c-0.51-0.87-1.04-1.69-1.7-2.58
|
|
85
|
+
c-2.27-3.39-5.3-6.37-8.52-9.25c-3.21-2.87-6.65-5.59-10.21-8.17c-3.55-2.59-7.19-5.08-10.91-7.47
|
|
86
|
+
c-3.7-2.38-7.52-4.73-11.27-6.86L255.71,153.08z"
|
|
87
|
+
fill="#C0C0C0"
|
|
88
|
+
stroke="#000000"
|
|
89
|
+
stroke-width="1"
|
|
90
|
+
paint-order="stroke"
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
<path d="M385.35,207.8c-0.01-0.01,0-0.02-0.02-0.05l-0.15-0.21c-0.1-0.14-0.18-0.28-0.3-0.43l-0.77-0.93
|
|
94
|
+
c-0.29-0.31-0.6-0.61-0.9-0.91c-0.3-0.31-0.59-0.62-0.95-0.9c-0.7-0.56-1.33-1.19-2.09-1.7l-2.26-1.58l-2.44-1.4
|
|
95
|
+
c-0.41-0.23-0.8-0.49-1.23-0.69l-1.3-0.6l-2.6-1.2c-0.89-0.37-1.81-0.66-2.72-1l-2.74-0.99l-2.83-0.77l-2.84-0.77
|
|
96
|
+
c-0.94-0.28-1.93-0.39-2.9-0.6c-1.95-0.34-3.88-0.79-5.85-1.04l-5.94-0.68c-1.98-0.29-3.99-0.27-5.99-0.4
|
|
97
|
+
c-2-0.08-4.01-0.23-6.02-0.24l-6.04,0.09c-2.01,0.06-4.04-0.01-6.05,0.19l-6.05,0.44l-3.03,0.22l-1.52,0.12l-1.51,0.19
|
|
98
|
+
l-12.08,1.51l11.92-2.59l1.49-0.32l1.51-0.25l3.01-0.49l6.04-0.99c2.01-0.38,4.05-0.51,6.08-0.75l6.11-0.64
|
|
99
|
+
c2.04-0.17,4.1-0.2,6.15-0.31c2.06-0.06,4.11-0.26,6.18-0.15l6.21,0.15c2.07,0.08,4.14,0.37,6.22,0.54
|
|
100
|
+
c1.04,0.12,2.08,0.15,3.11,0.36l3.1,0.55l3.11,0.55l3.08,0.8c1.03,0.28,2.06,0.52,3.08,0.84l3.04,1.08l1.52,0.55
|
|
101
|
+
c0.51,0.19,0.99,0.44,1.49,0.66l2.98,1.37l2.89,1.66c0.97,0.54,1.87,1.26,2.82,1.89c0.47,0.31,0.92,0.69,1.36,1.07
|
|
102
|
+
c0.45,0.38,0.9,0.74,1.34,1.14l1.3,1.3c0.22,0.23,0.44,0.5,0.65,0.75l0.32,0.39l0.41,0.58L385.35,207.8z"
|
|
103
|
+
fill="#C0C0C0"
|
|
104
|
+
stroke="#000000"
|
|
105
|
+
stroke-width="1"
|
|
106
|
+
paint-order="stroke"
|
|
107
|
+
/>
|
|
108
|
+
|
|
109
|
+
<path d="M380,178.69c-7.36,0.06-14.78,0.22-22.17,0.46c-7.4,0.24-14.79,0.55-22.18,0.98c-7.38,0.46-14.77,0.99-22.12,1.79
|
|
110
|
+
c-3.67,0.44-7.35,0.87-10.98,1.52c-3.65,0.59-7.25,1.42-10.77,2.63c3.37-1.54,6.93-2.74,10.53-3.69
|
|
111
|
+
c3.59-1.01,7.23-1.8,10.88-2.61c7.3-1.52,14.64-2.79,22-3.97c7.36-1.16,14.74-2.2,22.12-3.17c7.39-0.97,14.77-1.85,22.22-2.65
|
|
112
|
+
L380,178.69z"
|
|
113
|
+
fill="#C0C0C0"
|
|
114
|
+
stroke="#000000"
|
|
115
|
+
stroke-width="1"
|
|
116
|
+
paint-order="stroke"/>
|
|
117
|
+
|
|
118
|
+
<path d="M331.96,164.72l-6.35,2.25l-0.48,0.17l-0.12,0.02c-3.87,0.53-7.7,1-11.55,1.46c-3.85,0.46-7.7,0.87-11.56,1.26
|
|
119
|
+
c-3.85,0.39-7.72,0.71-11.58,0.97c-3.86,0.25-7.74,0.45-11.61,0.31c3.82-0.54,7.56-1.42,11.29-2.34
|
|
120
|
+
c3.73-0.93,7.44-1.92,11.13-2.98c3.7-1.05,7.38-2.13,11.06-3.25c3.67-1.12,7.35-2.26,10.98-3.44l-0.6,0.19l6.16-2.73
|
|
121
|
+
L331.96,164.72z"
|
|
122
|
+
fill="#C0C0C0"
|
|
123
|
+
stroke="#000000"
|
|
124
|
+
stroke-width="1"
|
|
125
|
+
paint-order="stroke"
|
|
126
|
+
/>
|
|
127
|
+
|
|
128
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vybestack/llxprt-ui",
|
|
3
|
+
"version": "0.7.0-nightly.251211.5750c518a",
|
|
4
|
+
"description": "Experimental terminal UI for llxprt-code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./src/index.ts",
|
|
10
|
+
"bun": "./src/index.ts"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "echo 'UI package uses bun runtime - no build required'",
|
|
15
|
+
"dev": "bun run src/main.tsx",
|
|
16
|
+
"start": "bun run src/main.tsx",
|
|
17
|
+
"lint": "bunx eslint \"src/**/*.{ts,tsx}\" \"scripts/**/*.ts\"",
|
|
18
|
+
"test": "bunx vitest run",
|
|
19
|
+
"test:ci": "bunx vitest run",
|
|
20
|
+
"test:coverage": "bunx vitest run --coverage",
|
|
21
|
+
"check:limits": "bun run scripts/check-limits.ts",
|
|
22
|
+
"check": "bun run lint && bun run test && bun run check:limits",
|
|
23
|
+
"typecheck": "bunx tsc --noEmit"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"llxprt",
|
|
27
|
+
"terminal-ui",
|
|
28
|
+
"opentui",
|
|
29
|
+
"experimental"
|
|
30
|
+
],
|
|
31
|
+
"author": "Vybestack",
|
|
32
|
+
"license": "ISC",
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=20",
|
|
35
|
+
"bun": ">=1.2.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@vybestack/opentui-core": "^0.1.61",
|
|
39
|
+
"@vybestack/opentui-react": "^0.1.61",
|
|
40
|
+
"clipboardy": "^4.0.0",
|
|
41
|
+
"react": "^19.2.1"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@vybestack/llxprt-code-core": "^0.7.0-nightly.251211.5750c518a"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@eslint/js": "^9.39.1",
|
|
48
|
+
"@testing-library/react": "^16.3.0",
|
|
49
|
+
"@types/bun": "^1.3.4",
|
|
50
|
+
"@types/node": "^24.10.1",
|
|
51
|
+
"@types/react": "^19.2.7",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
|
53
|
+
"@typescript-eslint/parser": "^8.48.1",
|
|
54
|
+
"@vitest/eslint-plugin": "^1.5.1",
|
|
55
|
+
"eslint": "^9.39.1",
|
|
56
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
57
|
+
"eslint-plugin-react": "^7.37.5",
|
|
58
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
59
|
+
"eslint-plugin-sonarjs": "^3.0.5",
|
|
60
|
+
"globals": "^16.5.0",
|
|
61
|
+
"happy-dom": "^18.0.1",
|
|
62
|
+
"tsx": "^4.21.0",
|
|
63
|
+
"typescript": "^5.9.3",
|
|
64
|
+
"vitest": "^4.0.15"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import { getLogger } from '../src/lib/logger';
|
|
5
|
+
|
|
6
|
+
type ViolationLevel = 'warn' | 'error';
|
|
7
|
+
|
|
8
|
+
interface Violation {
|
|
9
|
+
level: ViolationLevel;
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const FILE_WARN_LINES = 800;
|
|
14
|
+
const FILE_ERROR_LINES = 1200;
|
|
15
|
+
const FUNCTION_WARN_LINES = 80;
|
|
16
|
+
const FUNCTION_ERROR_LINES = 120;
|
|
17
|
+
|
|
18
|
+
const projectRoot = path.resolve(new URL('.', import.meta.url).pathname, '..');
|
|
19
|
+
|
|
20
|
+
const sourceRoots = [
|
|
21
|
+
path.join(projectRoot, '..', 'src'),
|
|
22
|
+
path.join(projectRoot, '..', 'scripts'),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const violations: Violation[] = [];
|
|
26
|
+
|
|
27
|
+
for (const root of sourceRoots) {
|
|
28
|
+
for (const filePath of collectSourceFiles(root)) {
|
|
29
|
+
checkFileLimits(filePath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
reportViolations(violations);
|
|
34
|
+
|
|
35
|
+
function collectSourceFiles(root: string): string[] {
|
|
36
|
+
if (!fs.existsSync(root)) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
41
|
+
const files: string[] = [];
|
|
42
|
+
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
const entryPath = path.join(root, entry.name);
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
files.push(...collectSourceFiles(entryPath));
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (entry.isFile() && isSupportedFile(entry.name)) {
|
|
51
|
+
files.push(entryPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isSupportedFile(fileName: string): boolean {
|
|
59
|
+
return (
|
|
60
|
+
(fileName.endsWith('.ts') || fileName.endsWith('.tsx')) &&
|
|
61
|
+
!fileName.endsWith('.d.ts') &&
|
|
62
|
+
!fileName.endsWith('.d.tsx')
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function checkFileLimits(filePath: string): void {
|
|
67
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
68
|
+
const lineCount = content.split(/\r?\n/).length;
|
|
69
|
+
const relativePath = path.relative(path.join(projectRoot, '..'), filePath);
|
|
70
|
+
|
|
71
|
+
if (lineCount > FILE_ERROR_LINES) {
|
|
72
|
+
violations.push({
|
|
73
|
+
level: 'error',
|
|
74
|
+
message: `${relativePath} has ${lineCount} lines (error > ${FILE_ERROR_LINES})`,
|
|
75
|
+
});
|
|
76
|
+
} else if (lineCount > FILE_WARN_LINES) {
|
|
77
|
+
violations.push({
|
|
78
|
+
level: 'warn',
|
|
79
|
+
message: `${relativePath} has ${lineCount} lines (warn > ${FILE_WARN_LINES})`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const sourceFile = ts.createSourceFile(
|
|
84
|
+
filePath,
|
|
85
|
+
content,
|
|
86
|
+
ts.ScriptTarget.Latest,
|
|
87
|
+
true,
|
|
88
|
+
filePath.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
visitFunctions(sourceFile, relativePath);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function visitFunctions(sourceFile: ts.SourceFile, relativePath: string): void {
|
|
95
|
+
const queue: ts.Node[] = [sourceFile];
|
|
96
|
+
|
|
97
|
+
while (queue.length > 0) {
|
|
98
|
+
const current = queue.shift();
|
|
99
|
+
if (!current) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (isFunctionWithBody(current)) {
|
|
104
|
+
recordFunctionLength(current, sourceFile, relativePath);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
current.forEachChild((child) => {
|
|
108
|
+
queue.push(child);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isFunctionWithBody(
|
|
114
|
+
node: ts.Node,
|
|
115
|
+
): node is ts.FunctionLikeDeclarationBase & { body: ts.Block } {
|
|
116
|
+
return (
|
|
117
|
+
ts.isFunctionLike(node) &&
|
|
118
|
+
'body' in node &&
|
|
119
|
+
node.body !== undefined &&
|
|
120
|
+
ts.isBlock(node.body as ts.Node)
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function recordFunctionLength(
|
|
125
|
+
node: ts.FunctionLikeDeclarationBase & { body: ts.Block },
|
|
126
|
+
sourceFile: ts.SourceFile,
|
|
127
|
+
relativePath: string,
|
|
128
|
+
): void {
|
|
129
|
+
const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
130
|
+
const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
131
|
+
const functionLines = end.line - start.line + 1;
|
|
132
|
+
const functionName = getFunctionName(node);
|
|
133
|
+
|
|
134
|
+
if (functionLines > FUNCTION_ERROR_LINES) {
|
|
135
|
+
violations.push({
|
|
136
|
+
level: 'error',
|
|
137
|
+
message: `${relativePath} :: ${functionName} is ${functionLines} lines (error > ${FUNCTION_ERROR_LINES})`,
|
|
138
|
+
});
|
|
139
|
+
} else if (functionLines > FUNCTION_WARN_LINES) {
|
|
140
|
+
violations.push({
|
|
141
|
+
level: 'warn',
|
|
142
|
+
message: `${relativePath} :: ${functionName} is ${functionLines} lines (warn > ${FUNCTION_WARN_LINES})`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function getFunctionName(node: ts.FunctionLikeDeclarationBase): string {
|
|
148
|
+
const name = ts.getNameOfDeclaration(node);
|
|
149
|
+
if (name && ts.isIdentifier(name)) {
|
|
150
|
+
return name.text;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return '<anonymous>';
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const logger = getLogger('nui:check-limits');
|
|
157
|
+
|
|
158
|
+
function reportViolations(results: Violation[]): void {
|
|
159
|
+
const errors = results.filter((violation) => violation.level === 'error');
|
|
160
|
+
|
|
161
|
+
for (const violation of results) {
|
|
162
|
+
if (violation.level === 'error') {
|
|
163
|
+
logger.error(violation.message);
|
|
164
|
+
} else {
|
|
165
|
+
logger.warn(violation.message);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (errors.length > 0) {
|
|
170
|
+
process.exitCode = 1;
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (results.length === 0) {
|
|
175
|
+
logger.log('limit checks passed');
|
|
176
|
+
}
|
|
177
|
+
}
|
package/scripts/start.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const root = join(__dirname, '..');
|
|
7
|
+
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
const bunArgs = ['run', 'src/main.tsx', ...args];
|
|
10
|
+
|
|
11
|
+
const child = spawn('bun', bunArgs, {
|
|
12
|
+
cwd: root,
|
|
13
|
+
stdio: 'inherit',
|
|
14
|
+
env: {
|
|
15
|
+
...process.env,
|
|
16
|
+
DEV: 'true',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
let cleaned = false;
|
|
21
|
+
const cleanup = (code, signal) => {
|
|
22
|
+
if (cleaned) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
cleaned = true;
|
|
26
|
+
// Ensure we leave the terminal in cooked mode even on abrupt exits.
|
|
27
|
+
try {
|
|
28
|
+
// Reset modes similar to tput cnorm; clear mouse/alt-screen.
|
|
29
|
+
process.stdout.write(
|
|
30
|
+
'\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?25h\u001b[?1049l',
|
|
31
|
+
);
|
|
32
|
+
} catch {
|
|
33
|
+
// ignore
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (signal) {
|
|
37
|
+
const signalCode = 128 + (signal === 'SIGINT' ? 2 : 15);
|
|
38
|
+
process.exit(signalCode);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
process.exit(code ?? 0);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const forwardSignal = (signal) => {
|
|
45
|
+
if (!child.killed) {
|
|
46
|
+
child.kill(signal);
|
|
47
|
+
}
|
|
48
|
+
// If the child drags its feet, escalate to SIGKILL then exit.
|
|
49
|
+
const killTimer = setTimeout(() => {
|
|
50
|
+
if (!child.killed) {
|
|
51
|
+
child.kill('SIGKILL');
|
|
52
|
+
}
|
|
53
|
+
}, 800);
|
|
54
|
+
killTimer.unref();
|
|
55
|
+
|
|
56
|
+
const exitTimer = setTimeout(() => {
|
|
57
|
+
cleanup(undefined, signal);
|
|
58
|
+
}, 1200);
|
|
59
|
+
exitTimer.unref();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
['SIGINT', 'SIGTERM'].forEach((signal) => {
|
|
63
|
+
process.on(signal, () => forwardSignal(signal));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
child.on('exit', (code, signal) => cleanup(code, signal));
|
|
67
|
+
|
|
68
|
+
child.on('error', (error) => {
|
|
69
|
+
console.error('Failed to start UI process:', error);
|
|
70
|
+
cleanup(1);
|
|
71
|
+
});
|