diff --git a/cli-center/package.json b/cli-center/package.json index 27c1c3a..799cf75 100644 --- a/cli-center/package.json +++ b/cli-center/package.json @@ -24,6 +24,7 @@ "@astrojs/sitemap": "^3.6.0", "@astrojs/vue": "^5.1.3", "@kevisual/context": "^0.0.4", + "@kevisual/kv-code": "^0.0.4", "@kevisual/query": "^0.0.32", "@kevisual/query-login": "^0.0.7", "@kevisual/registry": "^0.0.1", diff --git a/cli-center/src/apps/setting/index.tsx b/cli-center/src/apps/setting/index.tsx index 7805d68..30fcae4 100644 --- a/cli-center/src/apps/setting/index.tsx +++ b/cli-center/src/apps/setting/index.tsx @@ -1,6 +1,11 @@ import { use, useEffect, useState } from "react"; import { Layout } from "./layout" import { useStore } from "./store"; +import '@kevisual/kv-code/kv-code.js' +const link = { + loginDocs: '../docs/01-login-first/', + settingDocs: '../../docs/10-config/', +} export const FirstLogin = () => { const store = useStore(); const [username, setUsername] = useState('') @@ -23,7 +28,7 @@ export const FirstLogin = () => {

管理员设置

第一次登录的kevisual 用户为当前设备管理员。如果已经存在管理员账号,管理员可在"全局设置"中设置。 - 文档 + 文档
@@ -34,6 +39,7 @@ export const FirstLogin = () => { onChange={e => setUsername(e.target.value)} value={username} placeholder='请输入账号' + autoComplete="username" className='w-full px-4 py-2 border-2 border-black bg-white text-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent' />
@@ -45,6 +51,7 @@ export const FirstLogin = () => { onChange={e => setPassword(e.target.value)} value={password} placeholder='请输入密码' + autoComplete='current-password' className='w-full px-4 py-2 border-2 border-black bg-white text-black placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:border-transparent' /> @@ -63,15 +70,33 @@ export const FirstLogin = () => { export const Config = () => { const store = useStore(); + const [code, setCode] = useState(''); useEffect(() => { store.initAdmin(); }, []); + const onSaveConfig = async () => { + console.log('onSaveConfig', code); + const parsedCode = JSON.parse(code); + await store.saveConfig(parsedCode); + } return ( -
-
-          {JSON.stringify(store.config, null, 2)}
-        
+
+
+

+ + 配置中心文档 + +

+ +
+ { + setCode(e.nativeEvent?.detail?.value); + }} type="json">
) diff --git a/cli-center/src/apps/setting/layout.tsx b/cli-center/src/apps/setting/layout.tsx index 657a09d..2746a5f 100644 --- a/cli-center/src/apps/setting/layout.tsx +++ b/cli-center/src/apps/setting/layout.tsx @@ -1,4 +1,5 @@ import { Nav } from './nav' +import { toast, ToastContainer } from 'react-toastify' export const Layout = (props) => { return ( @@ -17,6 +18,7 @@ export const Layout = (props) => {
{props.children}
+ ) } \ No newline at end of file diff --git a/cli-center/src/apps/setting/store.ts b/cli-center/src/apps/setting/store.ts index 0578f14..b803fcc 100644 --- a/cli-center/src/apps/setting/store.ts +++ b/cli-center/src/apps/setting/store.ts @@ -1,11 +1,12 @@ import { query, queryLogin } from '@/modules/query'; import { create } from 'zustand'; - +import { toast } from 'react-toastify'; type SettingState = { username?: string; initAdmin: () => any; login: (username: string, password: string) => any; config?: any; + saveConfig: any; } export const useStore = create((set => ({ username: undefined, @@ -33,10 +34,22 @@ export const useStore = create((set => ({ if (res.code === 200) { set({ username }); const setToken = await queryLogin.setLoginToken(res.data) - console.log('setToken', setToken); + toast.success('登录成功'); } - console.log('login res', res); + return res; + }, + saveConfig: async (config: any) => { + const res = await query.post({ + path: 'config', + key: 'set', + data: config + }) + if (res.code === 200) { + set({ config }) + toast.success('配置保存成功'); + } + console.log('saveConfig res', res); return res; } }))); \ No newline at end of file diff --git a/cli-center/src/data/docs/10-config.md b/cli-center/src/data/docs/10-config.md new file mode 100644 index 0000000..f725fee --- /dev/null +++ b/cli-center/src/data/docs/10-config.md @@ -0,0 +1,302 @@ +--- +title: '配置项介绍' +description: 'Assistant 应用配置项完整说明文档,包括应用信息、代理、服务器、认证、AI等各项配置详解' +tags: ['config', 'configuration', 'settings', 'assistant'] +createdAt: '2025-12-18' +--- + +# 配置项介绍 + +本文档详细介绍 Assistant 应用的所有配置项。配置文件通常为 JSON 格式,用于定制应用的行为和功能。 + +## app - 应用信息 + +应用的基本标识信息。 + +```json +{ + "app": { + "id": "my-assistant-001", + "url": "https://my-app.example.com" + } +} +``` + +- **id**: `string` - 应用唯一标识符,用于识别具体设备或应用实例 +- **url**: `string` - 应用访问地址 + +## token - 访问令牌 + +```json +{ + "token": "your-access-token" +} +``` + +- **token**: `string` - 用于身份验证的访问令牌 + +## registry - 注册中心 + +```json +{ + "registry": "https://kevisual.cn" +} +``` + +- **registry**: `string` - 注册中心地址,默认为 `https://kevisual.cn` + +## proxy - 前端代理配置 + +前端路由代理配置,用于将特定路径转发到目标服务器。 + +```json +{ + "proxy": [ + { + "path": "/root/home", + "target": "https://kevisual.cn", + "pathname": "/root/home" + } + ] +} +``` + +- **proxy**: `ProxyInfo[]` - 代理配置数组 + - **path**: `string` - 匹配的路径前缀 + - **target**: `string` - 目标服务器地址 + - **pathname**: `string` - 转发到目标服务器的路径 + +示例:访问 `/root/home` 会被转发到 `https://kevisual.cn/root/home` + +## api - API代理配置 + +专门用于API请求的代理配置。 + +```json +{ + "api": { + "proxy": [ + { + "path": "/api", + "target": "https://api.example.com" + }, + { + "path": "/v1", + "target": "https://api-v1.example.com" + } + ] + } +} +``` + +- **api.proxy**: `ProxyInfo[]` - API代理配置数组,配置方式同 `proxy` + +## description - 应用描述 + +```json +{ + "description": "我的助手应用" +} +``` + +- **description**: `string` - 应用的描述信息 + +## server - 服务器配置 + +配置本地服务器的监听地址和端口。 + +```json +{ + "server": { + "path": "127.0.0.1", + "port": 3000 + } +} +``` + +- **server.path**: `string` - 服务器监听地址,默认 `127.0.0.1` +- **server.port**: `number` - 服务器监听端口号 + +## share - 远程访问配置 + +配置应用是否可被远程调用。 + +```json +{ + "share": { + "url": "https://kevisual.cn/ws/proxy", + "enabled": true + } +} +``` + +- **share.url**: `string` - 远程应用代理地址 +- **share.enabled**: `boolean` - 是否启用远程访问功能 + +## watch - 文件监听配置 + +配置是否监听 pages 目录下的文件变化。 + +```json +{ + "watch": { + "enabled": true + } +} +``` + +- **watch.enabled**: `boolean` - 是否启用文件监听 + +## home - 首页路径 + +```json +{ + "home": "/root/home" +} +``` + +- **home**: `string` - 访问根路径 `/` 时自动重定向的首页地址 + +## ai - AI功能配置 + +启用和配置本地AI代理功能。 + +```json +{ + "ai": { + "enabled": true, + "provider": "DeepSeek", + "apiKey": "your-api-key", + "model": "deepseek-chat" + } +} +``` + +- **ai.enabled**: `boolean` - 是否启用AI功能 +- **ai.provider**: `string` - AI提供商,可选 `'DeepSeek'` | `'Custom'` 或其他自定义值 +- **ai.apiKey**: `string` - API密钥 +- **ai.model**: `string` - 使用的模型名称 + +## scripts - 自定义脚本 + +定义自定义脚本命令,在应用启动时执行。 + +```json +{ + "scripts": { + "start": "node server.js", + "build": "npm run build", + "custom": "echo 'Hello World'" + } +} +``` + +- **scripts**: `Record` - 键值对形式的脚本配置 + - key: 脚本名称 + - value: 要执行的命令 + +## auth - 认证和权限配置 + +配置应用的认证和访问权限策略。 + +```json +{ + "auth": { + "share": "protected" + } +} +``` + +- **auth**: `AuthPermission` - 认证权限配置对象 + - **share**: 共享访问模式 + - `"protected"` - 需要认证才能访问(默认) + - `"public"` - 公开访问,无需认证 + - `"private"` - 私有访问,完全禁止外部访问 + +> **说明**: `share` 配置影响 pages 目录下页面的对外共享权限 + +## https - HTTPS证书配置 + +配置HTTPS服务和证书。 + +```json +{ + "https": { + "type": "https", + "keyPath": "/path/to/private.key", + "certPath": "/path/to/certificate.crt" + } +} +``` + +- **https.type**: `'https' | 'http'` - 服务协议类型,默认 `'http'` +- **https.keyPath**: `string` - SSL证书私钥文件路径 +- **https.certPath**: `string` - SSL证书文件路径 + +> **注意**: 通常不需要配置HTTPS,可以通过反向代理(如Nginx)实现HTTPS访问 + +## 完整配置示例 + +```json +{ + "app": { + "id": "assistant-prod-001", + "url": "https://app.example.com" + }, + "token": "your-secure-token", + "registry": "https://kevisual.cn", + "proxy": [ + { + "path": "/root/home", + "target": "https://kevisual.cn", + "pathname": "/root/home" + } + ], + "api": { + "proxy": [ + { + "path": "/api", + "target": "https://api.example.com" + } + ] + }, + "description": "生产环境助手应用", + "server": { + "path": "0.0.0.0", + "port": 3000 + }, + "share": { + "url": "https://kevisual.cn/ws/proxy", + "enabled": true + }, + "watch": { + "enabled": true + }, + "home": "/root/home", + "ai": { + "enabled": true, + "provider": "DeepSeek", + "apiKey": "sk-xxx", + "model": "deepseek-chat" + }, + "scripts": { + "setup": "npm install", + "dev": "npm run dev" + }, + "auth": { + "share": "protected" + } +} +``` + +## 配置文件位置 + +配置文件通常位于项目根目录,文件名为 `kevisual.json` 或其他约定名称。 + +## 最佳实践 + +1. **安全性**: 不要在配置文件中硬编码敏感信息(如 token、apiKey),建议使用环境变量 +2. **端口选择**: 确保选择的端口未被占用 +3. **代理配置**: 合理配置代理路径,避免路径冲突 +4. **HTTPS**: 生产环境建议使用反向代理配置HTTPS,而非直接在应用中配置 +5. **权限控制**: 根据实际需求选择合适的 `auth.share` 模式 diff --git a/cli-center/src/pages/index.astro b/cli-center/src/pages/index.astro index 3e848df..73f352f 100644 --- a/cli-center/src/pages/index.astro +++ b/cli-center/src/pages/index.astro @@ -1,47 +1,9 @@ --- -// import { query } from '@/modules/query.ts'; -console.log('Hello from index.astro'); -import '../styles/global.css'; +import Html from '@/components/html.astro'; --- - - - My Homepage - - -

Welcome to my website!

-
-
- - - - + +
+ cli-center +
+ diff --git a/cli-center/tsconfig.json b/cli-center/tsconfig.json index fb41ccd..567b5bc 100644 --- a/cli-center/tsconfig.json +++ b/cli-center/tsconfig.json @@ -13,6 +13,8 @@ }, "include": [ "src/**/*", + "typings.d.ts", + "@kevisual/kv-code/typings.d.ts", "agent/**/*" ], } \ No newline at end of file diff --git a/cli-center/typings.d.ts b/cli-center/typings.d.ts new file mode 100644 index 0000000..e69de29 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fea7483..0549496 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,6 +223,9 @@ importers: '@kevisual/context': specifier: ^0.0.4 version: 0.0.4 + '@kevisual/kv-code': + specifier: ^0.0.4 + version: 0.0.4(@types/react@19.2.7)(dotenv@17.2.3) '@kevisual/query': specifier: ^0.0.32 version: 0.0.32 @@ -565,6 +568,42 @@ packages: resolution: {integrity: sha512-8XqW8xGn++Eqqbz3e9wKuK7mxryeRjs4LOHLxbh2lwKeSbuNR4NFifDZT4KzvjU6HMOPbiNTsWpniK5EJfTWkg==} engines: {node: '>=18'} + '@codemirror/autocomplete@6.20.0': + resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==} + + '@codemirror/commands@6.10.1': + resolution: {integrity: sha512-uWDWFypNdQmz2y1LaNJzK7fL7TYKLeUAU0npEC685OKTF3KcQ2Vu3klIM78D7I6wGhktme0lh3CuQLv0ZCrD9Q==} + + '@codemirror/lang-css@6.3.1': + resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==} + + '@codemirror/lang-html@6.4.11': + resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==} + + '@codemirror/lang-javascript@6.2.4': + resolution: {integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==} + + '@codemirror/lang-json@6.0.2': + resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==} + + '@codemirror/lang-markdown@6.5.0': + resolution: {integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==} + + '@codemirror/language@6.11.3': + resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==} + + '@codemirror/lint@6.9.2': + resolution: {integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==} + + '@codemirror/search@6.5.11': + resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==} + + '@codemirror/state@6.5.2': + resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==} + + '@codemirror/view@6.39.4': + resolution: {integrity: sha512-xMF6OfEAUVY5Waega4juo1QGACfNkNF+aJLqpd8oUJz96ms2zbfQ9Gh35/tI3y8akEV31FruKfj7hBnIU/nkqA==} + '@emnapi/runtime@1.7.1': resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} @@ -1218,6 +1257,9 @@ packages: '@kevisual/hot-api@0.0.3': resolution: {integrity: sha512-qZ4CNK08StZP4+DR1vWwJhKVDoSXXC+PBFG4ZxtkXF5vO2rybE055zp1n3dg5jo8GwW5wxpqMIG3KBp3pYSTkg==} + '@kevisual/kv-code@0.0.4': + resolution: {integrity: sha512-9T7//119inomxhddfp0IRrXRzP0nbe0U7hiy+qgfghEbjKGTMkc8rdznz61xBjjMlonTPZnDikedYwNRTykWEw==} + '@kevisual/load@0.0.6': resolution: {integrity: sha512-+3YTFehRcZ1haGel5DKYMUwmi5i6f2psyaPZlfkKU/cOXgkpwoG9/BEqPCnPjicKqqnksEpixVRkyHJ+5bjLVA==} @@ -1268,6 +1310,33 @@ packages: resolution: {integrity: sha512-jlFxSlXUEz93cFW+UYT5BXv/rFVgiMQnIfqRYZ0gj1hSP8PMGRqMqUoHSLfKvfRRS4jseLSvTTeEKSQpZJtURg==} engines: {node: '>=10.0.0'} + '@lezer/common@1.4.0': + resolution: {integrity: sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg==} + + '@lezer/css@1.3.0': + resolution: {integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw==} + + '@lezer/highlight@1.2.3': + resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==} + + '@lezer/html@1.3.12': + resolution: {integrity: sha512-RJ7eRWdaJe3bsiiLLHjCFT1JMk8m1YP9kaUbvu2rMLEoOnke9mcTVDyfOslsln0LtujdWespjJ39w6zo+RsQYw==} + + '@lezer/javascript@1.5.4': + resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==} + + '@lezer/json@1.0.3': + resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} + + '@lezer/lr@1.4.5': + resolution: {integrity: sha512-/YTRKP5yPPSo1xImYQk7AZZMAgap0kegzqCSYHjAL9x1AZ0ZQW+IpcEzMKagCsbTsLnVeWkxYrCNeXG8xEPrjg==} + + '@lezer/markdown@1.6.1': + resolution: {integrity: sha512-72ah+Sml7lD8Wn7lnz9vwYmZBo9aQT+I2gjK/0epI+gjdwUbWw3MJ/ZBGEqG1UfrIauRqH37/c5mVHXeCTGXtA==} + + '@marijn/find-cluster-break@1.0.2': + resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} @@ -2069,6 +2138,9 @@ packages: '@types/send@1.2.1': resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -2484,6 +2556,9 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + codemirror@6.0.2: + resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -2551,6 +2626,9 @@ packages: resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} engines: {node: '>= 14'} + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + croner@4.1.97: resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==} @@ -3518,6 +3596,9 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} + lit-html@3.3.1: + resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + load-bmfont@1.4.2: resolution: {integrity: sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==} @@ -4116,6 +4197,11 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + engines: {node: '>=14'} + hasBin: true + pretty-ms@9.3.0: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} @@ -4597,6 +4683,9 @@ packages: resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} engines: {node: '>=10'} + style-mod@4.1.3: + resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + style-to-js@1.1.21: resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} @@ -4976,6 +5065,9 @@ packages: typescript: optional: true + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} @@ -5508,6 +5600,97 @@ snapshots: dependencies: fontkit: 2.0.4 + '@codemirror/autocomplete@6.20.0': + dependencies: + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + + '@codemirror/commands@6.10.1': + dependencies: + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + + '@codemirror/lang-css@6.3.1': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@lezer/common': 1.4.0 + '@lezer/css': 1.3.0 + + '@codemirror/lang-html@6.4.11': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-javascript': 6.2.4 + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + '@lezer/css': 1.3.0 + '@lezer/html': 1.3.12 + + '@codemirror/lang-javascript@6.2.4': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/language': 6.11.3 + '@codemirror/lint': 6.9.2 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + '@lezer/javascript': 1.5.4 + + '@codemirror/lang-json@6.0.2': + dependencies: + '@codemirror/language': 6.11.3 + '@lezer/json': 1.0.3 + + '@codemirror/lang-markdown@6.5.0': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/lang-html': 6.4.11 + '@codemirror/language': 6.11.3 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + '@lezer/markdown': 1.6.1 + + '@codemirror/language@6.11.3': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.5 + style-mod: 4.1.3 + + '@codemirror/lint@6.9.2': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + crelt: 1.0.6 + + '@codemirror/search@6.5.11': + dependencies: + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + crelt: 1.0.6 + + '@codemirror/state@6.5.2': + dependencies: + '@marijn/find-cluster-break': 1.0.2 + + '@codemirror/view@6.39.4': + dependencies: + '@codemirror/state': 6.5.2 + crelt: 1.0.6 + style-mod: 4.1.3 + w3c-keyname: 2.2.8 + '@emnapi/runtime@1.7.1': dependencies: tslib: 2.8.1 @@ -6123,6 +6306,35 @@ snapshots: - react-native-b4a - supports-color + '@kevisual/kv-code@0.0.4(@types/react@19.2.7)(dotenv@17.2.3)': + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/commands': 6.10.1 + '@codemirror/lang-css': 6.3.1 + '@codemirror/lang-html': 6.4.11 + '@codemirror/lang-javascript': 6.2.4 + '@codemirror/lang-json': 6.0.2 + '@codemirror/lang-markdown': 6.5.0 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + '@kevisual/app': 0.0.1(dotenv@17.2.3) + '@kevisual/context': 0.0.4 + codemirror: 6.0.2 + dayjs: 1.11.19 + eventemitter3: 5.0.1 + lit-html: 3.3.1 + nanoid: 5.1.6 + prettier: 3.7.4 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + zustand: 5.0.9(@types/react@19.2.7)(react@19.2.3) + transitivePeerDependencies: + - '@types/react' + - dotenv + - immer + - supports-color + - use-sync-external-store + '@kevisual/load@0.0.6': dependencies: eventemitter3: 5.0.1 @@ -6202,6 +6414,47 @@ snapshots: '@kevisual/ws@8.0.0': {} + '@lezer/common@1.4.0': {} + + '@lezer/css@1.3.0': + dependencies: + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.5 + + '@lezer/highlight@1.2.3': + dependencies: + '@lezer/common': 1.4.0 + + '@lezer/html@1.3.12': + dependencies: + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.5 + + '@lezer/javascript@1.5.4': + dependencies: + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.5 + + '@lezer/json@1.0.3': + dependencies: + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + '@lezer/lr': 1.4.5 + + '@lezer/lr@1.4.5': + dependencies: + '@lezer/common': 1.4.0 + + '@lezer/markdown@1.6.1': + dependencies: + '@lezer/common': 1.4.0 + '@lezer/highlight': 1.2.3 + + '@marijn/find-cluster-break@1.0.2': {} + '@mdx-js/mdx@3.1.1': dependencies: '@types/estree': 1.0.7 @@ -7159,6 +7412,8 @@ snapshots: dependencies: '@types/node': 25.0.3 + '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -7767,6 +8022,16 @@ snapshots: clsx@2.1.1: {} + codemirror@6.0.2: + dependencies: + '@codemirror/autocomplete': 6.20.0 + '@codemirror/commands': 6.10.1 + '@codemirror/language': 6.11.3 + '@codemirror/lint': 6.9.2 + '@codemirror/search': 6.5.11 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.39.4 + collapse-white-space@2.1.0: {} color-convert@2.0.1: @@ -7820,6 +8085,8 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 + crelt@1.0.6: {} + croner@4.1.97: {} cross-env@10.1.0: @@ -8902,6 +9169,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 + lit-html@3.3.1: + dependencies: + '@types/trusted-types': 2.0.7 + load-bmfont@1.4.2: dependencies: buffer-equal: 0.0.1 @@ -9821,6 +10092,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prettier@3.7.4: {} + pretty-ms@9.3.0: dependencies: parse-ms: 4.0.0 @@ -10466,6 +10739,8 @@ snapshots: '@tokenizer/token': 0.3.0 peek-readable: 4.1.0 + style-mod@4.1.3: {} + style-to-js@1.1.21: dependencies: style-to-object: 1.0.14 @@ -10807,6 +11082,8 @@ snapshots: optionalDependencies: typescript: 5.8.2 + w3c-keyname@2.2.8: {} + web-namespaces@2.0.1: {} webidl-conversions@3.0.1: {}