@koishi-ce/client 1.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 (121) hide show
  1. package/app/assets/logo.png +0 -0
  2. package/app/home/home.vue +51 -0
  3. package/app/home/index.ts +18 -0
  4. package/app/home/welcome.en-US.yml +9 -0
  5. package/app/home/welcome.vue +111 -0
  6. package/app/home/welcome.zh-CN.yml +9 -0
  7. package/app/index.html +13 -0
  8. package/app/index.scss +64 -0
  9. package/app/index.ts +32 -0
  10. package/app/layout/header.vue +187 -0
  11. package/app/layout/index.ts +15 -0
  12. package/app/layout/layout.vue +194 -0
  13. package/app/layout/menu-item.vue +60 -0
  14. package/app/settings/index.ts +39 -0
  15. package/app/settings/settings.vue +82 -0
  16. package/app/settings/theme.vue +123 -0
  17. package/app/shims.d.ts +1 -0
  18. package/app/status/index.ts +21 -0
  19. package/app/status/loading.vue +23 -0
  20. package/app/status/status.vue +56 -0
  21. package/app/styles/element.scss +217 -0
  22. package/app/styles/hc.scss +35 -0
  23. package/app/styles/index.scss +140 -0
  24. package/app/styles/index.ts +30 -0
  25. package/app/styles/layout.scss +92 -0
  26. package/app/theme/activity/button.vue +97 -0
  27. package/app/theme/activity/index.vue +119 -0
  28. package/app/theme/activity/item.vue +185 -0
  29. package/app/theme/activity/separator.vue +163 -0
  30. package/app/theme/activity/utils.ts +27 -0
  31. package/app/theme/blank.vue +24 -0
  32. package/app/theme/index.ts +37 -0
  33. package/app/theme/index.vue +34 -0
  34. package/app/theme/menu/index.vue +26 -0
  35. package/app/theme/menu/menu-item.vue +58 -0
  36. package/app/theme/menu/menu.vue +45 -0
  37. package/app/theme/status.vue +45 -0
  38. package/app/tsconfig.json +15 -0
  39. package/client/components/chat/image.vue +20 -0
  40. package/client/components/chat/overlay.vue +231 -0
  41. package/client/components/chat/utils.ts +6 -0
  42. package/client/components/common/index.ts +11 -0
  43. package/client/components/common/k-button.vue +127 -0
  44. package/client/components/common/k-hint.vue +62 -0
  45. package/client/components/common/k-tab.vue +50 -0
  46. package/client/components/dynamic.vue +61 -0
  47. package/client/components/icons/activity/default.vue +6 -0
  48. package/client/components/icons/activity/ellipsis.vue +6 -0
  49. package/client/components/icons/activity/home.vue +13 -0
  50. package/client/components/icons/activity/moon.vue +6 -0
  51. package/client/components/icons/activity/settings.vue +6 -0
  52. package/client/components/icons/activity/sun.vue +6 -0
  53. package/client/components/icons/index.ts +133 -0
  54. package/client/components/icons/style.scss +3 -0
  55. package/client/components/icons/svg/arrow-left.vue +6 -0
  56. package/client/components/icons/svg/arrow-right.vue +6 -0
  57. package/client/components/icons/svg/box-open.vue +6 -0
  58. package/client/components/icons/svg/check-full.vue +6 -0
  59. package/client/components/icons/svg/chevron-down.vue +6 -0
  60. package/client/components/icons/svg/chevron-left.vue +6 -0
  61. package/client/components/icons/svg/chevron-right.vue +6 -0
  62. package/client/components/icons/svg/chevron-up.vue +6 -0
  63. package/client/components/icons/svg/clipboard-list.vue +6 -0
  64. package/client/components/icons/svg/edit.vue +6 -0
  65. package/client/components/icons/svg/exclamation-full.vue +6 -0
  66. package/client/components/icons/svg/expand.vue +6 -0
  67. package/client/components/icons/svg/file-archive.vue +6 -0
  68. package/client/components/icons/svg/filter.vue +6 -0
  69. package/client/components/icons/svg/github.vue +6 -0
  70. package/client/components/icons/svg/gitlab.vue +6 -0
  71. package/client/components/icons/svg/info-full.vue +6 -0
  72. package/client/components/icons/svg/koishi.vue +6 -0
  73. package/client/components/icons/svg/link.vue +6 -0
  74. package/client/components/icons/svg/paper-plane.vue +6 -0
  75. package/client/components/icons/svg/question-empty.vue +6 -0
  76. package/client/components/icons/svg/redo.vue +6 -0
  77. package/client/components/icons/svg/search-minus.vue +6 -0
  78. package/client/components/icons/svg/search-plus.vue +6 -0
  79. package/client/components/icons/svg/search.vue +6 -0
  80. package/client/components/icons/svg/star-empty.vue +6 -0
  81. package/client/components/icons/svg/star-full.vue +6 -0
  82. package/client/components/icons/svg/start.vue +6 -0
  83. package/client/components/icons/svg/tag.vue +6 -0
  84. package/client/components/icons/svg/times-full.vue +6 -0
  85. package/client/components/icons/svg/tools.vue +6 -0
  86. package/client/components/icons/svg/undo.vue +6 -0
  87. package/client/components/icons/svg/user.vue +6 -0
  88. package/client/components/index.ts +75 -0
  89. package/client/components/layout/card.vue +69 -0
  90. package/client/components/layout/content.vue +37 -0
  91. package/client/components/layout/empty.vue +41 -0
  92. package/client/components/layout/index.ts +15 -0
  93. package/client/components/layout/tab-group.vue +45 -0
  94. package/client/components/layout/tab-item.vue +35 -0
  95. package/client/components/link.ts +39 -0
  96. package/client/components/perms.vue +73 -0
  97. package/client/components/slot.ts +95 -0
  98. package/client/context.ts +143 -0
  99. package/client/data.ts +178 -0
  100. package/client/index.ts +76 -0
  101. package/client/plugins/action.ts +251 -0
  102. package/client/plugins/i18n.ts +43 -0
  103. package/client/plugins/loader.ts +154 -0
  104. package/client/plugins/router.ts +278 -0
  105. package/client/plugins/setting.ts +217 -0
  106. package/client/plugins/theme.ts +134 -0
  107. package/client/shims.d.ts +55 -0
  108. package/client/tsconfig.json +15 -0
  109. package/client/utils.ts +36 -0
  110. package/global.d.ts +24 -0
  111. package/lib/bin.d.ts +1 -0
  112. package/lib/bin.mjs +112 -0
  113. package/lib/client-CaTn_gVG.mjs +125 -0
  114. package/lib/index.d.ts +20 -0
  115. package/lib/index.mjs +2 -0
  116. package/lib/src-Bxzzi1Rx.mjs +160 -0
  117. package/lib/yaml-UzQbvquH.mjs +23 -0
  118. package/package.json +66 -0
  119. package/src/bin.ts +61 -0
  120. package/src/index.ts +280 -0
  121. package/src/yaml.ts +22 -0
Binary file
@@ -0,0 +1,51 @@
1
+ <!--
2
+ 控制台首页:WebSocket 就绪后渲染 "home" 插槽内容(默认为欢迎卡片),
3
+ 未连接时显示连接提示卡片。
4
+ -->
5
+ <template>
6
+ <k-layout :main="`darker page-home${socket ? '' : ' loading'}`">
7
+ <el-scrollbar v-if="socket">
8
+ <k-slot name="home">
9
+ <k-slot-item :order="1000">
10
+ <welcome></welcome>
11
+ </k-slot-item>
12
+ </k-slot>
13
+ </el-scrollbar>
14
+ <div v-else>
15
+ <k-card class="connect">正在连接到 Koishi 服务器……</k-card>
16
+ </div>
17
+ </k-layout>
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ import { global, socket } from "@koishi-ce/client";
22
+ import Welcome from "./welcome.vue";
23
+ </script>
24
+
25
+ <style lang="scss">
26
+
27
+ .page-home {
28
+ &.loading {
29
+ display: flex;
30
+ flex-direction: column;
31
+ align-items: center;
32
+ justify-content: center;
33
+ }
34
+
35
+ .k-card.welcome {
36
+ margin: var(--card-margin);
37
+ }
38
+
39
+ .k-card.connect {
40
+ width: 400px;
41
+ max-width: 400px;
42
+ text-align: center;
43
+ line-height: 2;
44
+
45
+ p {
46
+ margin: 0;
47
+ }
48
+ }
49
+ }
50
+
51
+ </style>
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 首页插件:将 welcome 欢迎页注册为根路由 "/"。
3
+ * order 取极大值(活动栏 top 组渲染时按 order 逆序输出,故首页位于最顶部)。
4
+ */
5
+
6
+ import type { Context } from "@koishi-ce/client";
7
+ import Home from "./home.vue";
8
+
9
+ export default function (ctx: Context) {
10
+ ctx.page({
11
+ id: "home",
12
+ path: "/",
13
+ name: "欢迎",
14
+ icon: "activity:home",
15
+ order: 1000,
16
+ component: Home,
17
+ });
18
+ }
@@ -0,0 +1,9 @@
1
+ title: Welcome to Koishi!
2
+ description: Your chatbot is ready to go. 点击下面的任一选项,开启你的 Koishi 之旅吧。
3
+ action:
4
+ docs:
5
+ title: Documentation
6
+ description: The official documentation contains everything you want to know.
7
+ forum:
8
+ title: Forum
9
+ description: If you run into problems, you can always ask for help on the forum.
@@ -0,0 +1,111 @@
1
+ <!--
2
+ 欢迎卡片:文档 / 社区论坛等入口链接。
3
+ 自带 zh-CN 与 en-US 两套文案(局部 vue-i18n 实例,独立于全局语言包),
4
+ 其余扩展可通过 "welcome-choice" 插槽追加自定义入口。
5
+ -->
6
+ <template>
7
+ <div class="k-card welcome">
8
+ <h1>{{ t('title') }}</h1>
9
+ <p>{{ t('description') }}</p>
10
+ <div class="choices">
11
+ <k-slot name="welcome-choice">
12
+ <k-slot-item :order="1000">
13
+ <a class="choice" href="https://koishi.chat" rel="noopener noreferer" target="_blank">
14
+ <h2>{{ t('action.docs.title') }}</h2>
15
+ <p>{{ t('action.docs.description') }}</p>
16
+ </a>
17
+ </k-slot-item>
18
+ <k-slot-item :order="500">
19
+ <a class="choice" href="https://k.ilharp.cc" rel="noopener noreferer" target="_blank">
20
+ <h2>{{ t('action.forum.title') }}</h2>
21
+ <p>{{ t('action.forum.description') }}</p>
22
+ </a>
23
+ </k-slot-item>
24
+ </k-slot>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script lang="ts" setup>
30
+ import { useI18n } from "vue-i18n";
31
+ import enUS from "./welcome.en-US.yml";
32
+ import zhCN from "./welcome.zh-CN.yml";
33
+
34
+ // 组件私有的双语文案:不依赖全局 i18n,确保欢迎页在任何语言环境下可用
35
+ const { t, setLocaleMessage } = useI18n({
36
+ messages: {
37
+ "zh-CN": zhCN,
38
+ "en-US": enUS,
39
+ },
40
+ });
41
+
42
+ // 开发模式下 yml 文案改动即时热替换,无需整页刷新
43
+ if (import.meta.hot) {
44
+ import.meta.hot.accept("./welcome.zh-CN.yml", (module) => {
45
+ setLocaleMessage("zh-CN", module.default);
46
+ });
47
+ import.meta.hot.accept("./welcome.en-US.yml", (module) => {
48
+ setLocaleMessage("en-US", module.default);
49
+ });
50
+ }
51
+ </script>
52
+
53
+ <style lang="scss">
54
+
55
+ .page-home .welcome {
56
+ --welcome-title: 2.5rem;
57
+ --welcome-padding: 3rem 3rem;
58
+ --welcome-choice-padding: 0.5rem 1.5rem;
59
+ --welcome-gap: 2rem;
60
+
61
+ padding: var(--welcome-padding);
62
+
63
+ h1 {
64
+ font-size: var(--welcome-title);
65
+ margin-top: 0;
66
+ }
67
+
68
+ h1 + p {
69
+ margin: var(--welcome-gap) 0;
70
+ }
71
+
72
+ .choices {
73
+ display: flex;
74
+ flex-flow: row wrap;
75
+ gap: var(--welcome-gap);
76
+ }
77
+
78
+ .choice {
79
+ flex: 1 0 auto;
80
+ display: inline-block;
81
+ width: 280px;
82
+ box-sizing: border-box;
83
+ padding: var(--welcome-choice-padding);
84
+ border: 1px solid var(--k-color-divider);
85
+ border-radius: 6px;
86
+ cursor: pointer;
87
+ transition: var(--color-transition);
88
+
89
+ &:hover {
90
+ background-color: var(--k-side-color);
91
+ }
92
+
93
+ h2 {
94
+ font-size: 1.25rem;
95
+ margin-top: 1rem;
96
+ }
97
+
98
+ p {
99
+ font-size: 0.9375rem;
100
+ }
101
+ }
102
+
103
+ @media screen and (max-width: 768px) {
104
+ --welcome-title: 2rem;
105
+ --welcome-padding: 1.5rem 1.5rem;
106
+ --welcome-gap: 1.5rem;
107
+ --welcome-choice-padding: 0.5rem 1.5rem;
108
+ }
109
+ }
110
+
111
+ </style>
@@ -0,0 +1,9 @@
1
+ title: 欢迎使用 Koishi!
2
+ description: 你的机器人已经准备就绪。点击下面的任一选项,开启你的 Koishi 之旅吧。
3
+ action:
4
+ docs:
5
+ title: 阅读文档
6
+ description: 开始阅读官方文档。官方文档里包含了你想要了解的全部内容。
7
+ forum:
8
+ title: 前往论坛
9
+ description: 前往论坛与其他用户交流。如果你遇到了问题,可以在这里寻求帮助。
package/app/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Koishi 控制台</title>
7
+ <link rel="icon" href="/assets/logo.png" />
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/index.ts"></script>
12
+ </body>
13
+ </html>
package/app/index.scss ADDED
@@ -0,0 +1,64 @@
1
+ body {
2
+ margin: 0;
3
+ min-height: 100vh;
4
+ font-family: var(--font-family);
5
+ -webkit-font-smoothing: antialiased;
6
+ -moz-osx-font-smoothing: grayscale;
7
+ color: var(--fg1);
8
+ background-color: var(--k-page-bg);
9
+ position: relative;
10
+ transition: color 0.3s ease, background-color 0.3s ease;
11
+ }
12
+
13
+ code {
14
+ font-family: var(--font-family-code);
15
+ }
16
+
17
+ a {
18
+ color: inherit;
19
+ text-decoration: none;
20
+ transition: color 0.3s ease;
21
+ }
22
+
23
+ p, ul {
24
+ margin: 1em 0;
25
+ line-height: 1.7;
26
+ }
27
+
28
+ table {
29
+ text-align: center;
30
+ width: 100%;
31
+ border-collapse: collapse;
32
+
33
+ td, th {
34
+ padding: .5em 1em;
35
+ }
36
+
37
+ tr {
38
+ border-top: 1px solid var(--k-color-divider);
39
+ transition: border-color 0.3s ease;
40
+ }
41
+
42
+ tr:last-child {
43
+ border-bottom: 1px solid var(--k-color-divider);
44
+ }
45
+ }
46
+
47
+ .markdown {
48
+ a, code a {
49
+ color: var(--k-text-active);
50
+
51
+ &:hover {
52
+ text-decoration: underline;
53
+ }
54
+ }
55
+
56
+ code {
57
+ color: var(--k-text-normal);
58
+ padding: 0.25rem 0.5rem;
59
+ background-color: var(--k-page-bg);
60
+ border-radius: 3px;
61
+ overflow-wrap: break-word;
62
+ transition: background-color 0.3s ease, color 0.3s ease;
63
+ }
64
+ }
package/app/index.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 控制台前端宿主应用入口(scripts/client.ts 总装构建的主入口)。
3
+ *
4
+ * 依次注册内置的功能插件(首页 / 布局 / 设置 / 状态栏 / 全局样式 / 主题),
5
+ * 启动应用根上下文后,在非静态模式下与 Koishi 服务端建立 WebSocket 连接。
6
+ */
7
+
8
+ import { connect, global, root } from "@koishi-ce/client";
9
+ import home from "./home";
10
+ import layout from "./layout";
11
+ import settings from "./settings";
12
+ import status from "./status";
13
+ import styles from "./styles";
14
+ import theme from "./theme";
15
+
16
+ import "virtual:uno.css";
17
+ import "./index.scss";
18
+
19
+ root.plugin(home);
20
+ root.plugin(layout);
21
+ root.plugin(settings);
22
+ root.plugin(status);
23
+ root.plugin(styles);
24
+ root.plugin(theme);
25
+
26
+ root.start();
27
+
28
+ if (!global.static) {
29
+ // global.static 为真表示纯静态构建(无后端),跳过连接
30
+ const endpoint = new URL(global.endpoint, location.origin).toString();
31
+ connect(root, () => new WebSocket(endpoint.replace(/^http/, "ws")));
32
+ }
@@ -0,0 +1,187 @@
1
+ <!--
2
+ 布局顶栏:左侧标题(默认取当前路由名)、右侧菜单区,
3
+ 移动端额外提供侧栏开关按钮与溢出菜单("...")按钮。
4
+ -->
5
+ <template>
6
+ <div class="layout-header" :class="{ 'has-menu': menuKey }">
7
+ <div
8
+ class="toggle-sidebar-button"
9
+ role="button"
10
+ tabindex="0"
11
+ @click="$emit('update:isLeftAsideOpen', !isLeftAsideOpen)"
12
+ >
13
+ <div class="icon">
14
+ <span></span>
15
+ <span></span>
16
+ <span></span>
17
+ </div>
18
+ </div>
19
+ <div class="left">
20
+ <slot name="left">{{ route.name }}</slot>
21
+ </div>
22
+ <div class="right">
23
+ <slot name="right"></slot>
24
+ </div>
25
+ <div class="toggle-menu-button"
26
+ v-if="menuKey"
27
+ role="button"
28
+ tabindex="1"
29
+ @click.stop="trigger($event, menuData)"
30
+ >
31
+ <k-icon name="ellipsis"></k-icon>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <script lang="ts" setup>
37
+ import { type ActionContext, useMenu } from "@koishi-ce/client";
38
+ import { useRoute } from "vue-router";
39
+
40
+ const props = defineProps<{
41
+ isLeftAsideOpen: boolean;
42
+ isRightAsideOpen: boolean;
43
+ menuKey?: string;
44
+ menuData?: unknown;
45
+ }>();
46
+
47
+ // 溢出菜单按钮的点击触发器:打开 menuKey 对应的上下文菜单
48
+ // (menuKey 为运行期字符串,这里断言为菜单键类型以复用字面量重载)
49
+ const trigger = useMenu(props.menuKey as keyof ActionContext);
50
+
51
+ defineEmits(["update:isLeftAsideOpen", "update:isRightAsideOpen"]);
52
+
53
+ const route = useRoute();
54
+ </script>
55
+
56
+ <style lang="scss">
57
+
58
+ .toggle-sidebar-button {
59
+ position: absolute;
60
+ top: 0;
61
+ height: 100%;
62
+ left: 1rem;
63
+ display: none;
64
+ cursor: pointer;
65
+ }
66
+
67
+ .toggle-sidebar-button .icon {
68
+ display: flex;
69
+ flex-direction: column;
70
+ justify-content: center;
71
+ align-items: center;
72
+ width: 1.25rem;
73
+ height: 100%;
74
+ cursor: inherit;
75
+
76
+ span {
77
+ display: inline-block;
78
+ width: 100%;
79
+ height: 2px;
80
+ border-radius: 2px;
81
+ background-color: var(--fg1);
82
+ transition: transform 0.3s ease;
83
+
84
+ &:nth-child(2) {
85
+ margin: 6px 0;
86
+ }
87
+ }
88
+ }
89
+
90
+ .toggle-menu-button {
91
+ display: none;
92
+ height: 100%;
93
+ width: var(--header-height);
94
+ align-items: center;
95
+ justify-content: center;
96
+
97
+ .k-icon {
98
+ height: 1.25rem;
99
+ }
100
+ }
101
+
102
+ @media screen and (max-width: 768px) {
103
+ .toggle-sidebar-button {
104
+ display: block;
105
+ }
106
+
107
+ .toggle-menu-button {
108
+ display: flex;
109
+ }
110
+
111
+ .layout-header.has-menu .right {
112
+ display: none;
113
+ }
114
+ }
115
+
116
+ .layout-header {
117
+ position: relative;
118
+ box-sizing: border-box;
119
+ height: var(--header-height);
120
+ flex: 0 0 auto;
121
+ background-color: inherit;
122
+ display: flex;
123
+ flex-direction: row;
124
+ align-items: center;
125
+ justify-content: space-between;
126
+ border-bottom: var(--k-color-divider-dark) 1px solid;
127
+ transition: var(--color-transition);
128
+ font-weight: bolder;
129
+
130
+ .left {
131
+ margin-left: var(--header-height);
132
+ padding-left: 0.5rem;
133
+ }
134
+
135
+ .right {
136
+ margin-right: 0.5rem;
137
+ flex: 0 0 auto;
138
+ }
139
+
140
+ .menu-item {
141
+ position: relative;
142
+ width: 4rem;
143
+ height: var(--header-height);
144
+ display: inline-flex;
145
+ flex-direction: column;
146
+ align-items: center;
147
+ justify-content: center;
148
+ cursor: pointer;
149
+ transition: var(--color-transition);
150
+
151
+ &.active {
152
+ color: var(--k-color-primary);
153
+ }
154
+
155
+ &.spin {
156
+ animation: spin 1s linear infinite;
157
+ }
158
+
159
+ @keyframes spin {
160
+ 0% {
161
+ transform: rotate(0deg);
162
+ }
163
+ 100% {
164
+ transform: rotate(360deg);
165
+ }
166
+ }
167
+
168
+ &.disabled {
169
+ opacity: 0.3;
170
+ pointer-events: none;
171
+
172
+ @media screen and (max-width: 768px) {
173
+ display: none;
174
+ }
175
+ }
176
+
177
+ .menu-icon {
178
+ height: 1.125rem;
179
+ }
180
+
181
+ @media screen and (max-width: 768px) {
182
+ width: 3rem;
183
+ }
184
+ }
185
+ }
186
+
187
+ </style>
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 布局插件:向全局 "layout" 插槽注册三栏布局组件。
3
+ * order 取极小值保证它先于其它同插槽内容排序(作为页面骨架)。
4
+ */
5
+
6
+ import type { Context } from "@koishi-ce/client";
7
+ import Layout from "./layout.vue";
8
+
9
+ export default function (ctx: Context) {
10
+ ctx.slot({
11
+ type: "layout",
12
+ component: Layout,
13
+ order: -1000,
14
+ });
15
+ }