diff --git a/cmd/testdata/stores.yaml b/cmd/testdata/stores.yaml index cfa520514..698aab828 100644 --- a/cmd/testdata/stores.yaml +++ b/cmd/testdata/stores.yaml @@ -1,35 +1,88 @@ stores: - - name: git - kind: - name: atest-store-git - enabled: true - url: xxx - readonly: false - disabled: false - - name: ai - kind: - name: atest-ext-ai - enabled: true - url: "" - readonly: false - disabled: false - properties: + - name: git + kind: + name: atest-store-git + dependencies: [] + url: "unix:///tmp/atest-store-git.sock" + params: [] + link: "" + enabled: true + categories: [] + description: "" + url: xxx + username: "" + password: "" + readonly: false + disabled: false + properties: {} + - name: ai + kind: + name: atest-ext-ai + dependencies: [] # 无依赖 + url: "unix:///tmp/atest-ext-ai.sock" + params: - key: "provider" - description: "AI provider (local, openai, claude)" - defaultValue: "local" - - key: "model" - description: "AI model name" - defaultValue: "codellama" + description: "AI provider (ollama, openai, deepseek)" + defaultValue: "ollama" - key: "endpoint" - description: "AI service endpoint" + description: "AI service endpoint URL" defaultValue: "http://localhost:11434" -plugins: - - name: atest-store-git - url: unix:///tmp/atest-store-git.sock - enabled: true - - name: atest-ext-ai - url: unix:///tmp/atest-ext-ai.sock + - key: "api_key" + description: "API key for OpenAI/Deepseek providers" + defaultValue: "" + - key: "model" + description: "AI model name (auto-discovered for ollama)" + defaultValue: "" + - key: "max_tokens" + description: "Maximum tokens for AI generation" + defaultValue: "4096" + - key: "timeout" + description: "Request timeout duration" + defaultValue: "30s" + link: "https://github.com/LinuxSuRen/atest-ext-ai" enabled: true - description: "AI Extension Plugin for intelligent SQL generation and execution" - version: "latest" - registry: "ghcr.io/linuxsuren/atest-ext-ai" + categories: ["ai", "sql-generation"] + description: "AI Extension Plugin for natural language to SQL conversion" + url: "unix:///tmp/atest-ext-ai.sock" + username: "" + password: "" + readonly: false + disabled: false + properties: + provider: "ollama" + endpoint: "http://localhost:11434" + api_key: "" + model: "" + max_tokens: "4096" + timeout: "30s" + +plugins: + - name: atest-store-git + dependencies: [] + url: "unix:///tmp/atest-store-git.sock" + params: [] + link: "" + enabled: true + categories: [] + - name: atest-ext-ai + dependencies: [] + url: "unix:///tmp/atest-ext-ai.sock" + params: + - key: "provider" + description: "AI provider (ollama, openai, deepseek)" + defaultValue: "ollama" + - key: "endpoint" + description: "AI service endpoint" + defaultValue: "http://localhost:11434" + - key: "api_key" + description: "API key for external AI services" + defaultValue: "" + - key: "model" + description: "AI model name (auto-discovered for ollama)" + defaultValue: "" + link: "https://github.com/LinuxSuRen/atest-ext-ai" + enabled: true + categories: ["ai", "sql-generation"] + description: "AI Extension Plugin for natural language to SQL conversion" + version: "v0.1.0" + registry: "ghcr.io/linuxsuren/atest-ext-ai" diff --git a/console/atest-ui/package-lock.json b/console/atest-ui/package-lock.json index cf0ac5ceb..d34b2bcc7 100644 --- a/console/atest-ui/package-lock.json +++ b/console/atest-ui/package-lock.json @@ -7855,22 +7855,6 @@ "dev": true, "license": "MIT" }, - "node_modules/happy-dom": { - "version": "15.10.2", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-15.10.2.tgz", - "integrity": "sha512-NbA5XrSovenJIIcfixCREX3ZnV7yHP4phhbfuxxf4CPn+LZpz/jIM9EqJ2DrPwgVDSMoAKH3pZwQvkbsSiCrUw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "entities": "^4.5.0", - "webidl-conversions": "^7.0.0", - "whatwg-mimetype": "^3.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", @@ -14304,14 +14288,6 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -14965,17 +14941,6 @@ "node": ">=18" } }, - "node_modules/vite-node/node_modules/@types/node": { - "version": "24.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz", - "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "undici-types": "~7.8.0" - } - }, "node_modules/vite-node/node_modules/esbuild": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", @@ -16028,17 +15993,6 @@ "node": ">=18" } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - } - }, "node_modules/whatwg-url": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", @@ -21912,19 +21866,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "happy-dom": { - "version": "15.10.2", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-15.10.2.tgz", - "integrity": "sha512-NbA5XrSovenJIIcfixCREX3ZnV7yHP4phhbfuxxf4CPn+LZpz/jIM9EqJ2DrPwgVDSMoAKH3pZwQvkbsSiCrUw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "entities": "^4.5.0", - "webidl-conversions": "^7.0.0", - "whatwg-mimetype": "^3.0.0" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz", @@ -26559,14 +26500,6 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" }, - "undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", - "dev": true, - "optional": true, - "peer": true - }, "unist-util-is": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz", @@ -26897,17 +26830,6 @@ "dev": true, "optional": true }, - "@types/node": { - "version": "24.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz", - "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "undici-types": "~7.8.0" - } - }, "esbuild": { "version": "0.25.6", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", @@ -27477,14 +27399,6 @@ "iconv-lite": "0.6.3" } }, - "whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "optional": true, - "peer": true - }, "whatwg-url": { "version": "14.2.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", diff --git a/console/atest-ui/src/App.vue b/console/atest-ui/src/App.vue index 33eddafa9..02bf68d4f 100644 --- a/console/atest-ui/src/App.vue +++ b/console/atest-ui/src/App.vue @@ -41,8 +41,8 @@ const appVersion = ref('') const appVersionLink = ref('https://github.com/LinuxSuRen/api-testing') API.GetVersion((d) => { appVersion.value = d.version - const version = d.version.match('^v\\d*.\\d*.\\d*') - const dirtyVersion = d.version.match('^v\\d*.\\d*.\\d*-\\d*-g') + const version = d.version.match(String.raw`^v\d*.\d*.\d*`) + const dirtyVersion = d.version.match(String.raw`^v\d*.\d*.\d*-\d*-g`) if (!version && !dirtyVersion) { return @@ -55,16 +55,18 @@ API.GetVersion((d) => { } }) +const hasLocalStorage = typeof globalThis !== 'undefined' && 'localStorage' in globalThis +const storage = hasLocalStorage ? globalThis.localStorage : undefined const isCollapse = ref(true) watch(isCollapse, (v: boolean) => { - window.localStorage.setItem('button.style', v ? 'simple' : '') + storage?.setItem('button.style', v ? 'simple' : '') }) -const lastActiveMenu = window.localStorage.getItem('activeMenu') +const lastActiveMenu = storage?.getItem('activeMenu') ?? 'welcome' const activeMenu = ref(lastActiveMenu === '' ? 'welcome' : lastActiveMenu) const panelName = ref(activeMenu) const handleSelect = (key: string) => { panelName.value = key - window.localStorage.setItem('activeMenu', key) + storage?.setItem('activeMenu', key) } const locale = ref(Cache.GetPreference().language) @@ -178,7 +180,7 @@ API.GetMenus((menus) => { - + diff --git a/console/atest-ui/src/views/Extension.vue b/console/atest-ui/src/views/Extension.vue index e8287a572..e5238dfbc 100644 --- a/console/atest-ui/src/views/Extension.vue +++ b/console/atest-ui/src/views/Extension.vue @@ -1,48 +1,76 @@