diff --git a/AGENTS.md b/AGENTS.md
index 745531f..aab608e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -9,8 +9,7 @@
## 仓库结构
- `backend`: Go Gin + Gorm + PostgreSQL API。
-- `apps/senlinai-acro-react`: 当前主 Web 客户端,使用 React + TypeScript + Arco Design。
-- `apps/web`: 旧 Svelte Web 客户端,已不再作为主前端使用。
+- `apps/web_v1`: 当前主 Web 客户端,使用 React + TypeScript + Arco Design。
- `apps/desktop`: Web 客户端的 Tauri 桌面壳。
- `infra`: 本地开发基础设施,例如 Docker Compose。
- `docs/superpowers/specs`: 产品和技术规格文档。
@@ -38,8 +37,7 @@
## 前端规则
-- 当前主前端使用 React、TypeScript、Vite 和 Arco Design,位于 `apps/senlinai-acro-react`。
-- 不要继续在旧 `apps/web` Svelte 应用上开发主前端功能,除非用户明确要求维护旧客户端。
+- 当前主前端使用 React、TypeScript、Vite 和 Arco Design,位于 `apps/web_v1`。
- Web 应用优先面向桌面端构建,同时保持移动浏览器可用。
- 登录界面必须允许用户输入服务器 IP 地址或域名。
- 页面级工作台状态使用浏览器式标签页。
@@ -68,6 +66,6 @@
- 后端变更应在 `backend` 目录运行 `go test ./...`。
- PostgreSQL 集成检查应从 `DATABASE_URL` 读取实时测试数据库 URL;不要提交真实凭据。
-- Web 变更应在 `apps/senlinai-acro-react` 目录运行 `node scripts/visual-check.mjs`、`npm run build` 和 `npm run lint`。
+- Web 变更应在 `apps/web_v1` 目录运行 `node scripts/visual-check.mjs`、`npm run build` 和 `npm run lint`。
- Tauri 变更应先构建 Web 应用,然后在 `apps/desktop` 目录运行 Tauri 验证命令。
- 每个实施任务结束时都应创建一个聚焦的提交。
diff --git a/README.md b/README.md
index 7dfbaff..3b51685 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ go run ./cmd/api
启动 Web 客户端:
```powershell
-Set-Location apps/senlinai-acro-react
+Set-Location apps/web_v1
npm run dev
```
@@ -52,7 +52,7 @@ backend/etc/agent.dev.yaml
## 前端
-Web 客户端只使用 Svelte 和 TypeScript。登录界面允许用户输入服务器 IP 地址或域名,并将其保存为 API base URL。
+Web 客户端使用 React、TypeScript、Vite 和 Arco Design。登录界面允许用户输入服务器 IP 地址或域名,并将其保存为 API base URL。
## 桌面端
@@ -84,7 +84,7 @@ go test ./... -v
Web:
```powershell
-Set-Location apps/senlinai-acro-react
+Set-Location apps/web_v1
node scripts/visual-check.mjs
npm run build
npm run lint
diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json
index 783bdd0..71d7b61 100644
--- a/apps/desktop/src-tauri/tauri.conf.json
+++ b/apps/desktop/src-tauri/tauri.conf.json
@@ -4,10 +4,10 @@
"version": "0.1.0",
"identifier": "ai.senlin.workbench",
"build": {
- "frontendDist": "../../senlinai-acro-react/dist",
+ "frontendDist": "../../web_v1/dist",
"devUrl": "http://localhost:5173",
- "beforeDevCommand": "cd ../senlinai-acro-react && npm run dev",
- "beforeBuildCommand": "cd ../senlinai-acro-react && npm run build"
+ "beforeDevCommand": "cd ../web_v1 && npm run dev",
+ "beforeBuildCommand": "cd ../web_v1 && npm run build"
},
"app": {
"windows": [
diff --git a/apps/web/.gitignore b/apps/web/.gitignore
deleted file mode 100644
index a547bf3..0000000
--- a/apps/web/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-node_modules
-dist
-dist-ssr
-*.local
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/apps/web/.oxlintrc.json b/apps/web/.oxlintrc.json
deleted file mode 100644
index 6fa991d..0000000
--- a/apps/web/.oxlintrc.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "$schema": "./node_modules/oxlint/configuration_schema.json",
- "plugins": ["react", "typescript", "oxc"],
- "rules": {
- "react/rules-of-hooks": "error",
- "react/only-export-components": ["warn", { "allowConstantExport": true }]
- }
-}
diff --git a/apps/web/README.md b/apps/web/README.md
deleted file mode 100644
index 5e6fab9..0000000
--- a/apps/web/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# SenlinAI Web
-
-Svelte + TypeScript web client for the project workbench.
-
-## Scripts
-
-```powershell
-npm run dev
-npm test -- --run
-npm run build
-npx playwright test
-```
-
-The login shell lets users enter the server IP address or domain name used as the API base URL.
diff --git a/apps/web/e2e/project-workbench.spec.ts b/apps/web/e2e/project-workbench.spec.ts
deleted file mode 100644
index 1b67f8f..0000000
--- a/apps/web/e2e/project-workbench.spec.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { expect, test } from '@playwright/test';
-
-test('login and project channel workbench flow', async ({ page }) => {
- await page.goto('/');
-
- await expect(page.getByLabel('Server IP or domain')).toBeVisible();
- await page.getByLabel('Server IP or domain').fill('localhost:8080');
- await page.getByLabel('Email or username').fill('david@example.com');
- await page.getByLabel('Password').fill('secret');
- await page.getByRole('button', { name: 'Log in' }).click();
-
- await expect(page.getByLabel('Project list')).toBeVisible();
- await expect(page.getByRole('button', { name: 'Project A1' })).toHaveAttribute('aria-pressed', 'true');
- await expect(page.getByRole('button', { name: 'Message Flow 36' })).toBeVisible();
-
- await page.getByRole('button', { name: 'Work Plan 8' }).click();
- await expect(page.getByText('Tasks')).toBeVisible();
- await expect(page.getByRole('button', { name: 'Inspect Confirm homepage information architecture' })).toBeVisible();
-
- await page.getByRole('button', { name: 'Project A2' }).click();
- await expect(page.getByRole('button', { name: 'Project A2' })).toHaveAttribute('aria-pressed', 'true');
- await expect(page.getByText('Ops Dashboard')).toBeVisible();
-
- await page.getByRole('button', { name: 'Ops Dashboard' }).click();
- await expect(page.getByText('Open external channel')).toBeVisible();
-});
-
-for (const server of [
- 'https://user:secret@example.com',
- 'http:////example.com',
- 'http//example.com',
- 'https//example.com',
- 'http:/example.com',
- 'https:/example.com',
- 'http://example.com\\path',
- 'http://example..com',
- 'http://-bad.com',
-]) {
- test(`rejects malformed server address: ${server}`, async ({ page }) => {
- await page.goto('/');
-
- await page.getByLabel('Server IP or domain').fill(server);
- await page.getByLabel('Email or username').fill('david@example.com');
- await page.getByLabel('Password').fill('secret');
- await page.getByRole('button', { name: 'Log in' }).click();
-
- await expect(page.getByText('Enter a valid HTTP or HTTPS server address.')).toBeVisible();
- await expect(page.getByLabel('Server IP or domain')).toBeVisible();
- });
-}
-
-test('mobile workbench keeps project navigation and inspector compact', async ({ page }) => {
- await page.setViewportSize({ width: 390, height: 844 });
- await page.goto('/');
-
- await page.getByLabel('Server IP or domain').fill('localhost:8080');
- await page.getByLabel('Email or username').fill('david@example.com');
- await page.getByLabel('Password').fill('secret');
- await page.getByRole('button', { name: 'Log in' }).click();
-
- const rail = page.getByLabel('Project list');
- const sidebar = page.getByLabel('Project channels');
- const stage = page.getByLabel('Channel content');
- const inspector = page.getByLabel('Object inspector');
-
- await expect(rail).toHaveCSS('grid-auto-flow', 'column');
- await expect(rail).toHaveCSS('max-height', '76px');
- await expect(inspector).toHaveCSS('max-height', '288px');
-
- const workPlan = page.getByRole('button', { name: 'Work Plan 8' });
- await expect(workPlan).toBeVisible();
- await expect(workPlan).toBeInViewport();
- await workPlan.click();
- await expect(page.getByRole('heading', { name: 'Tasks' })).toBeVisible();
-
- const [sidebarBox, stageBox] = await Promise.all([sidebar.boundingBox(), stage.boundingBox()]);
- expect(sidebarBox?.y).toBeLessThan(stageBox?.y ?? 0);
- expect((stageBox?.y ?? 0) - (sidebarBox?.y ?? 0)).toBeLessThanOrEqual(248);
-});
diff --git a/apps/web/index.html b/apps/web/index.html
deleted file mode 100644
index a9ca7ee..0000000
--- a/apps/web/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
- 项目工作台
-
-
-
-
-
-
diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json
deleted file mode 100644
index bb825b2..0000000
--- a/apps/web/package-lock.json
+++ /dev/null
@@ -1,2690 +0,0 @@
-{
- "name": "web",
- "version": "0.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "web",
- "version": "0.0.0",
- "dependencies": {
- "@sveltejs/vite-plugin-svelte": "^6.2.1",
- "svelte": "^5.42.0"
- },
- "devDependencies": {
- "@playwright/test": "^1.61.1",
- "@testing-library/jest-dom": "^6.9.1",
- "@testing-library/svelte": "^5.2.9",
- "@tsconfig/svelte": "^5.0.5",
- "jsdom": "^27.3.0",
- "typescript": "~6.0.2",
- "vite": "^7.2.7",
- "vitest": "^4.0.16"
- }
- },
- "node_modules/@acemir/cssom": {
- "version": "0.9.31",
- "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz",
- "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@adobe/css-tools": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz",
- "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@asamuzakjp/css-color": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz",
- "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@csstools/css-calc": "^3.0.0",
- "@csstools/css-color-parser": "^4.0.1",
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0",
- "lru-cache": "^11.2.5"
- }
- },
- "node_modules/@asamuzakjp/dom-selector": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz",
- "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@asamuzakjp/nwsapi": "^2.3.9",
- "bidi-js": "^1.0.3",
- "css-tree": "^3.1.0",
- "is-potential-custom-element-name": "^1.0.1",
- "lru-cache": "^11.2.6"
- }
- },
- "node_modules/@asamuzakjp/nwsapi": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
- "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
- "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@csstools/color-helpers": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz",
- "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT-0",
- "engines": {
- "node": ">=20.19.0"
- }
- },
- "node_modules/@csstools/css-calc": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz",
- "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=20.19.0"
- },
- "peerDependencies": {
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0"
- }
- },
- "node_modules/@csstools/css-color-parser": {
- "version": "4.1.9",
- "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz",
- "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@csstools/color-helpers": "^6.1.0",
- "@csstools/css-calc": "^3.2.1"
- },
- "engines": {
- "node": ">=20.19.0"
- },
- "peerDependencies": {
- "@csstools/css-parser-algorithms": "^4.0.0",
- "@csstools/css-tokenizer": "^4.0.0"
- }
- },
- "node_modules/@csstools/css-parser-algorithms": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
- "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=20.19.0"
- },
- "peerDependencies": {
- "@csstools/css-tokenizer": "^4.0.0"
- }
- },
- "node_modules/@csstools/css-syntax-patches-for-csstree": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz",
- "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT-0",
- "peerDependencies": {
- "css-tree": "^3.2.1"
- },
- "peerDependenciesMeta": {
- "css-tree": {
- "optional": true
- }
- }
- },
- "node_modules/@csstools/css-tokenizer": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
- "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=20.19.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
- "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
- "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
- "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
- "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
- "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
- "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
- "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
- "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
- "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
- "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
- "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
- "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
- "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
- "cpu": [
- "mips64el"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
- "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
- "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
- "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
- "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
- "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
- "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
- "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
- "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
- "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
- "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
- "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@exodus/bytes": {
- "version": "1.15.1",
- "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz",
- "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
- },
- "peerDependencies": {
- "@noble/hashes": "^1.8.0 || ^2.0.0"
- },
- "peerDependenciesMeta": {
- "@noble/hashes": {
- "optional": true
- }
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@playwright/test": {
- "version": "1.61.1",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.1.tgz",
- "integrity": "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright": "1.61.1"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",
- "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",
- "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",
- "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",
- "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",
- "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",
- "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",
- "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",
- "cpu": [
- "arm"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",
- "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",
- "cpu": [
- "arm"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",
- "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",
- "cpu": [
- "arm64"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",
- "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",
- "cpu": [
- "arm64"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",
- "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",
- "cpu": [
- "loong64"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",
- "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",
- "cpu": [
- "loong64"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",
- "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",
- "cpu": [
- "ppc64"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",
- "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",
- "cpu": [
- "ppc64"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",
- "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",
- "cpu": [
- "riscv64"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",
- "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",
- "cpu": [
- "riscv64"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",
- "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",
- "cpu": [
- "s390x"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",
- "cpu": [
- "x64"
- ],
- "libc": [
- "glibc"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",
- "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",
- "cpu": [
- "x64"
- ],
- "libc": [
- "musl"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",
- "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",
- "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",
- "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",
- "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",
- "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@standard-schema/spec": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
- "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sveltejs/acorn-typescript": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.11.tgz",
- "integrity": "sha512-LFuZUkjJ9iF7JZye/aG5XM0SFcQ5VyL0oVX4WJ9dc0Va3R3s0OauX1BESVCb+YN/ol8TAfqGDDAQsTG627Y5kw==",
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^8.9.0"
- }
- },
- "node_modules/@sveltejs/vite-plugin-svelte": {
- "version": "6.2.4",
- "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz",
- "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==",
- "license": "MIT",
- "dependencies": {
- "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
- "deepmerge": "^4.3.1",
- "magic-string": "^0.30.21",
- "obug": "^2.1.0",
- "vitefu": "^1.1.1"
- },
- "engines": {
- "node": "^20.19 || ^22.12 || >=24"
- },
- "peerDependencies": {
- "svelte": "^5.0.0",
- "vite": "^6.3.0 || ^7.0.0"
- }
- },
- "node_modules/@sveltejs/vite-plugin-svelte-inspector": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.2.tgz",
- "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==",
- "license": "MIT",
- "dependencies": {
- "obug": "^2.1.0"
- },
- "engines": {
- "node": "^20.19 || ^22.12 || >=24"
- },
- "peerDependencies": {
- "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0",
- "svelte": "^5.0.0",
- "vite": "^6.3.0 || ^7.0.0"
- }
- },
- "node_modules/@testing-library/dom": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
- "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "5.3.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "picocolors": "1.1.1",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@testing-library/dom/node_modules/aria-query": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
- "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
- "node_modules/@testing-library/dom/node_modules/dom-accessibility-api": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
- "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@testing-library/jest-dom": {
- "version": "6.9.1",
- "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
- "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@adobe/css-tools": "^4.4.0",
- "aria-query": "^5.0.0",
- "css.escape": "^1.5.1",
- "dom-accessibility-api": "^0.6.3",
- "picocolors": "^1.1.1",
- "redent": "^3.0.0"
- },
- "engines": {
- "node": ">=14",
- "npm": ">=6",
- "yarn": ">=1"
- }
- },
- "node_modules/@testing-library/svelte": {
- "version": "5.4.2",
- "resolved": "https://registry.npmjs.org/@testing-library/svelte/-/svelte-5.4.2.tgz",
- "integrity": "sha512-4o31E4HGo5BU5KwPkulNRocEden+7Tt9JYm9uhln5ajF7DULeyFA46BBWVfKJ8Ms9B3JmOFPTIiVamH7n3KpuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@testing-library/dom": "9.x.x || 10.x.x",
- "@testing-library/svelte-core": "1.1.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "peerDependencies": {
- "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0",
- "vite": "*",
- "vitest": "*"
- },
- "peerDependenciesMeta": {
- "vite": {
- "optional": true
- },
- "vitest": {
- "optional": true
- }
- }
- },
- "node_modules/@testing-library/svelte-core": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@testing-library/svelte-core/-/svelte-core-1.1.3.tgz",
- "integrity": "sha512-KkMAvXeWorxN2Yn0kdC1lfoAItxpoj4uOWzxK5leDrNxonLvS5nwBFvztrroyTszQ0Wf/EU6iLT8JhY5qcn22g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0"
- }
- },
- "node_modules/@tsconfig/svelte": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.8.tgz",
- "integrity": "sha512-UkNnw1/oFEfecR8ypyHIQuWYdkPvHiwcQ78sh+ymIiYoF+uc5H1UBetbjyqT+vgGJ3qQN6nhucJviX6HesWtKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/aria-query": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
- "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/chai": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
- "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/deep-eql": "*",
- "assertion-error": "^2.0.1"
- }
- },
- "node_modules/@types/deep-eql": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
- "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/estree": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
- "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
- "license": "MIT"
- },
- "node_modules/@types/trusted-types": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
- "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
- "license": "MIT"
- },
- "node_modules/@vitest/expect": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz",
- "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@standard-schema/spec": "^1.1.0",
- "@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.10",
- "@vitest/utils": "4.1.10",
- "chai": "^6.2.2",
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/mocker": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz",
- "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/spy": "4.1.10",
- "estree-walker": "^3.0.3",
- "magic-string": "^0.30.21"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "msw": "^2.4.9",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "msw": {
- "optional": true
- },
- "vite": {
- "optional": true
- }
- }
- },
- "node_modules/@vitest/pretty-format": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz",
- "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz",
- "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "4.1.10",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz",
- "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "4.1.10",
- "@vitest/utils": "4.1.10",
- "magic-string": "^0.30.21",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/spy": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz",
- "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz",
- "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "4.1.10",
- "convert-source-map": "^2.0.0",
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/aria-query": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
- "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/axobject-query": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
- "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/bidi-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
- "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "require-from-string": "^2.0.2"
- }
- },
- "node_modules/chai": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
- "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/clsx": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
- "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/css-tree": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
- "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mdn-data": "2.27.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
- "node_modules/css.escape": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
- "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cssstyle": {
- "version": "5.3.7",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz",
- "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@asamuzakjp/css-color": "^4.1.1",
- "@csstools/css-syntax-patches-for-csstree": "^1.0.21",
- "css-tree": "^3.1.0",
- "lru-cache": "^11.2.4"
- },
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/data-urls": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz",
- "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "whatwg-mimetype": "^5.0.0",
- "whatwg-url": "^15.1.0"
- },
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/data-urls/node_modules/whatwg-mimetype": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
- "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decimal.js": {
- "version": "10.6.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
- "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/devalue": {
- "version": "5.8.1",
- "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz",
- "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==",
- "license": "MIT"
- },
- "node_modules/dom-accessibility-api": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
- "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/entities": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
- "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=20.19.0"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/es-module-lexer": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz",
- "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/esbuild": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
- "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.1",
- "@esbuild/android-arm": "0.28.1",
- "@esbuild/android-arm64": "0.28.1",
- "@esbuild/android-x64": "0.28.1",
- "@esbuild/darwin-arm64": "0.28.1",
- "@esbuild/darwin-x64": "0.28.1",
- "@esbuild/freebsd-arm64": "0.28.1",
- "@esbuild/freebsd-x64": "0.28.1",
- "@esbuild/linux-arm": "0.28.1",
- "@esbuild/linux-arm64": "0.28.1",
- "@esbuild/linux-ia32": "0.28.1",
- "@esbuild/linux-loong64": "0.28.1",
- "@esbuild/linux-mips64el": "0.28.1",
- "@esbuild/linux-ppc64": "0.28.1",
- "@esbuild/linux-riscv64": "0.28.1",
- "@esbuild/linux-s390x": "0.28.1",
- "@esbuild/linux-x64": "0.28.1",
- "@esbuild/netbsd-arm64": "0.28.1",
- "@esbuild/netbsd-x64": "0.28.1",
- "@esbuild/openbsd-arm64": "0.28.1",
- "@esbuild/openbsd-x64": "0.28.1",
- "@esbuild/openharmony-arm64": "0.28.1",
- "@esbuild/sunos-x64": "0.28.1",
- "@esbuild/win32-arm64": "0.28.1",
- "@esbuild/win32-ia32": "0.28.1",
- "@esbuild/win32-x64": "0.28.1"
- }
- },
- "node_modules/esm-env": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
- "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
- "license": "MIT"
- },
- "node_modules/esrap": {
- "version": "2.2.13",
- "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.13.tgz",
- "integrity": "sha512-m8jH5hZgJE2RRUK/jjkGPcJEDAV+dYnZYFkosQaPTcE+Yw4xynXHOo6FUdwaWBtdR3b1MMa7wEDTSHeR2VWsGA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- },
- "peerDependencies": {
- "@typescript-eslint/types": "^8.2.0"
- },
- "peerDependenciesMeta": {
- "@typescript-eslint/types": {
- "optional": true
- }
- }
- },
- "node_modules/estree-walker": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
- "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "^1.0.0"
- }
- },
- "node_modules/expect-type": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz",
- "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/html-encoding-sniffer": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
- "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@exodus/bytes": "^1.6.0"
- },
- "engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
- }
- },
- "node_modules/http-proxy-agent": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
- "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-potential-custom-element-name": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
- "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-reference": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
- "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "^1.0.6"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/jsdom": {
- "version": "27.4.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz",
- "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@acemir/cssom": "^0.9.28",
- "@asamuzakjp/dom-selector": "^6.7.6",
- "@exodus/bytes": "^1.6.0",
- "cssstyle": "^5.3.4",
- "data-urls": "^6.0.0",
- "decimal.js": "^10.6.0",
- "html-encoding-sniffer": "^6.0.0",
- "http-proxy-agent": "^7.0.2",
- "https-proxy-agent": "^7.0.6",
- "is-potential-custom-element-name": "^1.0.1",
- "parse5": "^8.0.0",
- "saxes": "^6.0.0",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^6.0.0",
- "w3c-xmlserializer": "^5.0.0",
- "webidl-conversions": "^8.0.0",
- "whatwg-mimetype": "^4.0.0",
- "whatwg-url": "^15.1.0",
- "ws": "^8.18.3",
- "xml-name-validator": "^5.0.0"
- },
- "engines": {
- "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
- },
- "peerDependencies": {
- "canvas": "^3.0.0"
- },
- "peerDependenciesMeta": {
- "canvas": {
- "optional": true
- }
- }
- },
- "node_modules/locate-character": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
- "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
- "license": "MIT"
- },
- "node_modules/lru-cache": {
- "version": "11.5.2",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
- "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/lz-string": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
- "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "lz-string": "bin/bin.js"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/mdn-data": {
- "version": "2.27.1",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
- "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
- "dev": true,
- "license": "CC0-1.0"
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.16",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
- "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/obug": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz",
- "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==",
- "funding": [
- "https://github.com/sponsors/sxzz",
- "https://opencollective.com/debug"
- ],
- "license": "MIT",
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "node_modules/parse5": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
- "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "entities": "^8.0.0"
- },
- "funding": {
- "url": "https://github.com/inikulin/parse5?sponsor=1"
- }
- },
- "node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/playwright": {
- "version": "1.61.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz",
- "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright-core": "1.61.1"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "fsevents": "2.3.2"
- }
- },
- "node_modules/playwright-core": {
- "version": "1.61.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz",
- "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "playwright-core": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/playwright/node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.19",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz",
- "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.12",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/pretty-format": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
- "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/rollup": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
- "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.9"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.62.2",
- "@rollup/rollup-android-arm64": "4.62.2",
- "@rollup/rollup-darwin-arm64": "4.62.2",
- "@rollup/rollup-darwin-x64": "4.62.2",
- "@rollup/rollup-freebsd-arm64": "4.62.2",
- "@rollup/rollup-freebsd-x64": "4.62.2",
- "@rollup/rollup-linux-arm-gnueabihf": "4.62.2",
- "@rollup/rollup-linux-arm-musleabihf": "4.62.2",
- "@rollup/rollup-linux-arm64-gnu": "4.62.2",
- "@rollup/rollup-linux-arm64-musl": "4.62.2",
- "@rollup/rollup-linux-loong64-gnu": "4.62.2",
- "@rollup/rollup-linux-loong64-musl": "4.62.2",
- "@rollup/rollup-linux-ppc64-gnu": "4.62.2",
- "@rollup/rollup-linux-ppc64-musl": "4.62.2",
- "@rollup/rollup-linux-riscv64-gnu": "4.62.2",
- "@rollup/rollup-linux-riscv64-musl": "4.62.2",
- "@rollup/rollup-linux-s390x-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-musl": "4.62.2",
- "@rollup/rollup-openbsd-x64": "4.62.2",
- "@rollup/rollup-openharmony-arm64": "4.62.2",
- "@rollup/rollup-win32-arm64-msvc": "4.62.2",
- "@rollup/rollup-win32-ia32-msvc": "4.62.2",
- "@rollup/rollup-win32-x64-gnu": "4.62.2",
- "@rollup/rollup-win32-x64-msvc": "4.62.2",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/saxes": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
- "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "xmlchars": "^2.2.0"
- },
- "engines": {
- "node": ">=v12.22.7"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/std-env": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz",
- "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/svelte": {
- "version": "5.56.6",
- "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.56.6.tgz",
- "integrity": "sha512-p4HDLDogGHKRKCrgckQHNs5PEfXkju6JI5jTywueaKJI5hAdjPohEhRtQ0M1SWC/+TA73SPln+r7srr+7e4nZA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/remapping": "^2.3.4",
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@sveltejs/acorn-typescript": "^1.0.10",
- "@types/estree": "^1.0.5",
- "@types/trusted-types": "^2.0.7",
- "acorn": "^8.12.1",
- "aria-query": "5.3.1",
- "axobject-query": "^4.1.0",
- "clsx": "^2.1.1",
- "devalue": "^5.8.1",
- "esm-env": "^1.2.1",
- "esrap": "^2.2.12",
- "is-reference": "^3.0.3",
- "locate-character": "^3.0.0",
- "magic-string": "^0.30.11",
- "zimmerframe": "^1.1.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/svelte/node_modules/aria-query": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
- "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/symbol-tree": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinyexec": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
- "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
- "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.4"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tinyrainbow": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
- "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tldts": {
- "version": "7.4.9",
- "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.9.tgz",
- "integrity": "sha512-3kZ8wQQ/k5DrChD4X4FVvr2D7E5uoRgAqkPyLpSCGUvqOvqu+JEdr3mwMUaVWb+vMHZaKhF5fp2PBigKsui7hA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tldts-core": "^7.4.9"
- },
- "bin": {
- "tldts": "bin/cli.js"
- }
- },
- "node_modules/tldts-core": {
- "version": "7.4.9",
- "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.9.tgz",
- "integrity": "sha512-DxKfPBI52p2msTEu7MPhdpdDTBhhVQg1a/8PjQckeyAvO13eMYElX545grIp6nnTGIMZlRvFZPvFhvI/WIz2Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tough-cookie": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz",
- "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "tldts": "^7.0.5"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/tr46": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
- "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.3.1"
- },
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/vite": {
- "version": "7.3.6",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
- "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.27.0 || ^0.28.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/vitefu": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz",
- "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==",
- "license": "MIT",
- "workspaces": [
- "tests/deps/*",
- "tests/projects/*",
- "tests/projects/workspace/packages/*"
- ],
- "peerDependencies": {
- "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "vite": {
- "optional": true
- }
- }
- },
- "node_modules/vitest": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
- "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/expect": "4.1.10",
- "@vitest/mocker": "4.1.10",
- "@vitest/pretty-format": "4.1.10",
- "@vitest/runner": "4.1.10",
- "@vitest/snapshot": "4.1.10",
- "@vitest/spy": "4.1.10",
- "@vitest/utils": "4.1.10",
- "es-module-lexer": "^2.0.0",
- "expect-type": "^1.3.0",
- "magic-string": "^0.30.21",
- "obug": "^2.1.1",
- "pathe": "^2.0.3",
- "picomatch": "^4.0.3",
- "std-env": "^4.0.0-rc.1",
- "tinybench": "^2.9.0",
- "tinyexec": "^1.0.2",
- "tinyglobby": "^0.2.15",
- "tinyrainbow": "^3.1.0",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
- "why-is-node-running": "^2.3.0"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@opentelemetry/api": "^1.9.0",
- "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.1.10",
- "@vitest/browser-preview": "4.1.10",
- "@vitest/browser-webdriverio": "4.1.10",
- "@vitest/coverage-istanbul": "4.1.10",
- "@vitest/coverage-v8": "4.1.10",
- "@vitest/ui": "4.1.10",
- "happy-dom": "*",
- "jsdom": "*",
- "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@opentelemetry/api": {
- "optional": true
- },
- "@types/node": {
- "optional": true
- },
- "@vitest/browser-playwright": {
- "optional": true
- },
- "@vitest/browser-preview": {
- "optional": true
- },
- "@vitest/browser-webdriverio": {
- "optional": true
- },
- "@vitest/coverage-istanbul": {
- "optional": true
- },
- "@vitest/coverage-v8": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- },
- "vite": {
- "optional": false
- }
- }
- },
- "node_modules/w3c-xmlserializer": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
- "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "xml-name-validator": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
- "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/whatwg-mimetype": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
- "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/whatwg-url": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz",
- "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tr46": "^6.0.0",
- "webidl-conversions": "^8.0.0"
- },
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/why-is-node-running": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ws": {
- "version": "8.21.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",
- "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": ">=5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/xml-name-validator": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
- "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/xmlchars": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/zimmerframe": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
- "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
- "license": "MIT"
- }
- }
-}
diff --git a/apps/web/package.json b/apps/web/package.json
deleted file mode 100644
index 8a9b585..0000000
--- a/apps/web/package.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "web",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "test": "vitest",
- "preview": "vite preview"
- },
- "dependencies": {
- "@sveltejs/vite-plugin-svelte": "^6.2.1",
- "svelte": "^5.42.0"
- },
- "devDependencies": {
- "@playwright/test": "^1.61.1",
- "@testing-library/jest-dom": "^6.9.1",
- "@testing-library/svelte": "^5.2.9",
- "@tsconfig/svelte": "^5.0.5",
- "jsdom": "^27.3.0",
- "typescript": "~6.0.2",
- "vite": "^7.2.7",
- "vitest": "^4.0.16"
- }
-}
diff --git a/apps/web/playwright.config.ts b/apps/web/playwright.config.ts
deleted file mode 100644
index 7f354be..0000000
--- a/apps/web/playwright.config.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { defineConfig, devices } from '@playwright/test';
-
-export default defineConfig({
- testDir: './e2e',
- webServer: {
- command: 'npm run dev -- --host 127.0.0.1',
- url: 'http://127.0.0.1:5173',
- reuseExistingServer: !process.env.CI,
- },
- use: {
- baseURL: 'http://127.0.0.1:5173',
- trace: 'on-first-retry',
- },
- projects: [
- {
- name: 'chromium',
- use: { ...devices['Desktop Chrome'] },
- },
- ],
-});
diff --git a/apps/web/public/favicon.svg b/apps/web/public/favicon.svg
deleted file mode 100644
index 6893eb1..0000000
--- a/apps/web/public/favicon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/web/public/icons.svg b/apps/web/public/icons.svg
deleted file mode 100644
index e952219..0000000
--- a/apps/web/public/icons.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-
diff --git a/apps/web/src/app/App.svelte b/apps/web/src/app/App.svelte
deleted file mode 100644
index e7170ef..0000000
--- a/apps/web/src/app/App.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-{#if currentUser}
-
-{:else}
-
-{/if}
diff --git a/apps/web/src/app/tabs.ts b/apps/web/src/app/tabs.ts
deleted file mode 100644
index cd41f04..0000000
--- a/apps/web/src/app/tabs.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export type WorkspaceTab = {
- key: string;
- title: string;
- route: string;
-};
-
-export function openTab(existing: WorkspaceTab[], next: WorkspaceTab): WorkspaceTab[] {
- if (existing.some((tab) => tab.key === next.key)) return existing;
- return [...existing, next];
-}
diff --git a/apps/web/src/assets/hero.png b/apps/web/src/assets/hero.png
deleted file mode 100644
index 02251f4..0000000
Binary files a/apps/web/src/assets/hero.png and /dev/null differ
diff --git a/apps/web/src/assets/vite.svg b/apps/web/src/assets/vite.svg
deleted file mode 100644
index 5101b67..0000000
--- a/apps/web/src/assets/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/apps/web/src/features/ai/AISessionCards.svelte b/apps/web/src/features/ai/AISessionCards.svelte
deleted file mode 100644
index 527524a..0000000
--- a/apps/web/src/features/ai/AISessionCards.svelte
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- {#each sessions as session}
-
- {/each}
-
diff --git a/apps/web/src/features/auth/ServerLogin.svelte b/apps/web/src/features/auth/ServerLogin.svelte
deleted file mode 100644
index b895727..0000000
--- a/apps/web/src/features/auth/ServerLogin.svelte
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
-
-
-
diff --git a/apps/web/src/features/auth/ServerLogin.test.ts b/apps/web/src/features/auth/ServerLogin.test.ts
deleted file mode 100644
index e8a617c..0000000
--- a/apps/web/src/features/auth/ServerLogin.test.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { fireEvent, render, screen } from '@testing-library/svelte';
-import { describe, expect, it, vi } from 'vitest';
-import ServerLogin from './ServerLogin.svelte';
-
-describe('ServerLogin', () => {
- it('renders server, account, and password fields', () => {
- render(ServerLogin, { props: { apiBase: 'http://localhost:8080' } });
-
- expect(screen.getByLabelText('Server IP or domain')).toBeInTheDocument();
- expect(screen.getByLabelText('Email or username')).toBeInTheDocument();
- expect(screen.getByLabelText('Password')).toBeInTheDocument();
- expect(screen.getByRole('button', { name: 'Log in' })).toBeInTheDocument();
- expect(screen.getByRole('status')).toHaveTextContent('Not connected. Enter a server address to continue.');
- });
-
- it('normalizes server address and emits login details', async () => {
- const onLogin = vi.fn();
- render(ServerLogin, {
- props: {
- apiBase: 'localhost:8080',
- onLogin,
- },
- });
-
- await fireEvent.input(screen.getByLabelText('Server IP or domain'), {
- target: { value: '10.0.0.12:8080' },
- });
- await fireEvent.input(screen.getByLabelText('Email or username'), {
- target: { value: 'david@example.com' },
- });
- await fireEvent.input(screen.getByLabelText('Password'), {
- target: { value: 'secret' },
- });
- await fireEvent.click(screen.getByRole('button', { name: 'Log in' }));
-
- expect(onLogin).toHaveBeenCalledWith({
- apiBase: 'http://10.0.0.12:8080',
- account: 'david@example.com',
- });
- });
-
- it.each([
- ['localhost', 'http://localhost'],
- ['localhost:8080', 'http://localhost:8080'],
- ['192.168.1.20:3000', 'http://192.168.1.20:3000'],
- ['example.com:8443', 'http://example.com:8443'],
- ['https://example.com', 'https://example.com'],
- ])('accepts and normalizes a valid server value: %s', async (server, apiBase) => {
- const onLogin = vi.fn();
- render(ServerLogin, { props: { apiBase: 'http://localhost:8080', onLogin } });
-
- await fireEvent.input(screen.getByLabelText('Server IP or domain'), { target: { value: server } });
- await fireEvent.input(screen.getByLabelText('Email or username'), { target: { value: 'david@example.com' } });
- await fireEvent.input(screen.getByLabelText('Password'), { target: { value: 'secret' } });
- await fireEvent.click(screen.getByRole('button', { name: 'Log in' }));
-
- expect(onLogin).toHaveBeenCalledWith({ apiBase, account: 'david@example.com' });
- });
-
- it('shows an error when account or password is missing', async () => {
- render(ServerLogin, { props: { apiBase: 'http://localhost:8080' } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Log in' }));
-
- expect(screen.getByText('Enter an account and password.')).toBeInTheDocument();
- });
-
- it.each([
- ['', 'Enter a server address.'],
- ['http:// bad-server', 'Enter a valid HTTP or HTTPS server address.'],
- [' https://example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['https://example.com/path with spaces', 'Enter a valid HTTP or HTTPS server address.'],
- ['https://example%20.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['https://user:secret@example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://', 'Enter a valid HTTP or HTTPS server address.'],
- ['ftp://example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http:////example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http//example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['https//example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http:/example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['https:/example.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://example.com\\path', 'Enter a valid HTTP or HTTPS server address.'],
- ['example.com\\path', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://example..com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://-bad.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://bad-.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://bad_host.com', 'Enter a valid HTTP or HTTPS server address.'],
- ['http://bad!.com', 'Enter a valid HTTP or HTTPS server address.'],
- ])('rejects an invalid server value: %s', async (server, error) => {
- const onLogin = vi.fn();
- render(ServerLogin, { props: { apiBase: 'http://localhost:8080', onLogin } });
-
- await fireEvent.input(screen.getByLabelText('Server IP or domain'), { target: { value: server } });
- await fireEvent.input(screen.getByLabelText('Email or username'), { target: { value: 'david@example.com' } });
- await fireEvent.input(screen.getByLabelText('Password'), { target: { value: 'secret' } });
- await fireEvent.click(screen.getByRole('button', { name: 'Log in' }));
-
- expect(screen.getByText(error)).toBeInTheDocument();
- expect(onLogin).not.toHaveBeenCalled();
- });
-});
diff --git a/apps/web/src/features/capture/QuickCapture.svelte b/apps/web/src/features/capture/QuickCapture.svelte
deleted file mode 100644
index 579aa43..0000000
--- a/apps/web/src/features/capture/QuickCapture.svelte
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/inbox/InboxPanel.svelte b/apps/web/src/features/inbox/InboxPanel.svelte
deleted file mode 100644
index 31dfd35..0000000
--- a/apps/web/src/features/inbox/InboxPanel.svelte
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/web/src/features/inbox/SuggestionList.svelte b/apps/web/src/features/inbox/SuggestionList.svelte
deleted file mode 100644
index 913d06b..0000000
--- a/apps/web/src/features/inbox/SuggestionList.svelte
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/inbox/SuggestionList.test.ts b/apps/web/src/features/inbox/SuggestionList.test.ts
deleted file mode 100644
index d7ee65a..0000000
--- a/apps/web/src/features/inbox/SuggestionList.test.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { fireEvent, render, screen } from '@testing-library/svelte';
-import { describe, expect, it, vi } from 'vitest';
-import SuggestionList from './SuggestionList.svelte';
-
-describe('SuggestionList', () => {
- it('requires explicit selection before confirmation', async () => {
- const onConfirm = vi.fn();
- render(SuggestionList, {
- props: {
- suggestions: [{ kind: 'task', title: '跟进报价', body: '联系客户' }],
- onConfirm,
- },
- });
-
- await fireEvent.click(screen.getByText('创建选中项'));
- expect(onConfirm).toHaveBeenCalledWith([]);
-
- await fireEvent.click(screen.getByLabelText('选择 跟进报价'));
- await fireEvent.click(screen.getByText('创建选中项'));
- expect(onConfirm).toHaveBeenLastCalledWith([
- { kind: 'task', title: '跟进报价', body: '联系客户' },
- ]);
- });
-});
diff --git a/apps/web/src/features/inbox/types.ts b/apps/web/src/features/inbox/types.ts
deleted file mode 100644
index 7ac3153..0000000
--- a/apps/web/src/features/inbox/types.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type Suggestion = {
- kind: 'task' | 'note' | 'source';
- title: string;
- body: string;
-};
diff --git a/apps/web/src/features/notes/MarkdownEditor.svelte b/apps/web/src/features/notes/MarkdownEditor.svelte
deleted file mode 100644
index 33e26c5..0000000
--- a/apps/web/src/features/notes/MarkdownEditor.svelte
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/projects/ProjectDashboard.svelte b/apps/web/src/features/projects/ProjectDashboard.svelte
deleted file mode 100644
index 1abc079..0000000
--- a/apps/web/src/features/projects/ProjectDashboard.svelte
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- {#each metrics as [label, value]}
-
- {label}
- {value}
-
- {/each}
-
diff --git a/apps/web/src/features/projects/ProjectDashboard.test.ts b/apps/web/src/features/projects/ProjectDashboard.test.ts
deleted file mode 100644
index fc82cf2..0000000
--- a/apps/web/src/features/projects/ProjectDashboard.test.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { render, screen } from '@testing-library/svelte';
-import { describe, expect, it } from 'vitest';
-import ProjectDashboard from './ProjectDashboard.svelte';
-
-describe('ProjectDashboard', () => {
- it('shows project counters', () => {
- render(ProjectDashboard, {
- props: {
- summary: {
- project_id: 1,
- pending_inbox_count: 2,
- open_task_count: 5,
- recent_note_count: 3,
- recent_session_count: 4,
- },
- },
- });
-
- expect(screen.getByText('待处理 Inbox')).toBeInTheDocument();
- expect(screen.getByText('2')).toBeInTheDocument();
- expect(screen.getByText('当前任务')).toBeInTheDocument();
- expect(screen.getByText('5')).toBeInTheDocument();
- });
-});
diff --git a/apps/web/src/features/tasks/TaskList.svelte b/apps/web/src/features/tasks/TaskList.svelte
deleted file mode 100644
index 9d18323..0000000
--- a/apps/web/src/features/tasks/TaskList.svelte
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- {#each tasks as task}
-
- {task.title}
- {task.status}
- {#if task.assignee}
- {task.assignee}
- {/if}
-
- {/each}
-
diff --git a/apps/web/src/features/workbench/ChannelContent.svelte b/apps/web/src/features/workbench/ChannelContent.svelte
deleted file mode 100644
index 6d18e6a..0000000
--- a/apps/web/src/features/workbench/ChannelContent.svelte
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-{#if channel.type === 'overview'}
-
-{:else if channel.type === 'inbox'}
-
-{:else if channel.type === 'tasks'}
-
-{:else if channel.type === 'ai_sessions'}
-
-{:else if channel.type === 'notes_sources'}
-
-{:else if channel.type === 'cron'}
-
-{:else}
-
-{/if}
diff --git a/apps/web/src/features/workbench/ChannelContent.test.ts b/apps/web/src/features/workbench/ChannelContent.test.ts
deleted file mode 100644
index e5887db..0000000
--- a/apps/web/src/features/workbench/ChannelContent.test.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { fireEvent, render, screen, within } from '@testing-library/svelte';
-import { describe, expect, it, vi } from 'vitest';
-import ChannelContent from './ChannelContent.svelte';
-import { getProjectWorkspace } from './mockData';
-
-describe('ChannelContent', () => {
- const workspace = getProjectWorkspace(1);
-
- it('renders a distinctive heading or control for every channel type', () => {
- const expectedContent = {
- overview: { role: 'heading', name: 'Overview' },
- inbox: { role: 'heading', name: 'Inbox' },
- tasks: { role: 'checkbox', name: 'Mark Confirm homepage information architecture complete' },
- ai_sessions: { role: 'heading', name: 'AI Sessions' },
- notes_sources: { role: 'heading', name: 'Notes & Sources' },
- cron: { role: 'heading', name: 'Cron Plans' },
- custom_link: { role: 'link', name: 'Open external channel' },
- } as const;
-
- for (const type of Object.keys(expectedContent) as Array) {
- const channel = workspace.channels.find((item) => item.type === type);
- if (!channel) throw new Error(`missing ${type}`);
-
- const { unmount } = render(ChannelContent, { props: { workspace, channel, onInspect: () => {} } });
- expect(screen.getByRole(expectedContent[type].role, { name: expectedContent[type].name })).toBeInTheDocument();
- unmount();
- }
- });
-
- it('sends selected task details to inspector', async () => {
- let inspectedTitle = '';
- const channel = workspace.channels.find((item) => item.type === 'tasks');
- if (!channel) throw new Error('missing task channel');
-
- render(ChannelContent, {
- props: {
- workspace,
- channel,
- onInspect: (item) => {
- inspectedTitle = item.title;
- },
- },
- });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
- expect(inspectedTitle).toBe('Confirm homepage information architecture');
- });
-
- it('reports task completion changes to its owner', async () => {
- const channel = workspace.channels.find((item) => item.type === 'tasks');
- if (!channel) throw new Error('missing task channel');
- const onToggleTask = vi.fn();
-
- render(ChannelContent, { props: { workspace, channel, onInspect: () => {}, onToggleTask } });
-
- const completion = screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' });
- expect(completion).not.toBeChecked();
-
- await fireEvent.click(completion);
-
- expect(onToggleTask).toHaveBeenCalledWith('1-task-1');
- });
-});
diff --git a/apps/web/src/features/workbench/ObjectInspector.svelte b/apps/web/src/features/workbench/ObjectInspector.svelte
deleted file mode 100644
index 6fbe503..0000000
--- a/apps/web/src/features/workbench/ObjectInspector.svelte
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/workbench/ObjectInspector.test.ts b/apps/web/src/features/workbench/ObjectInspector.test.ts
deleted file mode 100644
index b586131..0000000
--- a/apps/web/src/features/workbench/ObjectInspector.test.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/svelte';
-import { afterEach, describe, expect, it, vi } from 'vitest';
-import ObjectInspector from './ObjectInspector.svelte';
-
-const item = {
- title: 'Review navigation',
- type: 'Task',
- description: 'Check the project navigation flow.',
- properties: [],
-};
-const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');
-
-function setClipboard(writeText: Clipboard['writeText']) {
- Object.defineProperty(navigator, 'clipboard', {
- configurable: true,
- value: { writeText } as Clipboard,
- });
-}
-
-afterEach(() => {
- cleanup();
- if (originalClipboard) {
- Object.defineProperty(navigator, 'clipboard', originalClipboard);
- } else {
- Reflect.deleteProperty(navigator, 'clipboard');
- }
-});
-
-describe('ObjectInspector', () => {
- async function openMoreActions() {
- await fireEvent.click(screen.getByRole('button', { name: 'More' }));
- }
-
- it('shows copy success only after clipboard writing resolves', async () => {
- let resolveWrite: (() => void) | undefined;
- const writeText = vi.fn(
- () =>
- new Promise((resolve) => {
- resolveWrite = resolve;
- }),
- );
- setClipboard(writeText);
- render(ObjectInspector, { props: { item } });
-
- await openMoreActions();
- await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
-
- expect(screen.queryByRole('status')).not.toBeInTheDocument();
- resolveWrite?.();
- await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('Link copied to clipboard.'));
- });
-
- it('reports a copy failure when clipboard writing rejects', async () => {
- setClipboard(vi.fn().mockRejectedValue(new Error('Permission denied')));
- render(ObjectInspector, { props: { item } });
-
- await openMoreActions();
- await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
-
- await waitFor(() => expect(screen.getByRole('status')).toHaveTextContent('Unable to copy link.'));
- });
-
- it('reports unavailable clipboard access without showing success', async () => {
- Reflect.deleteProperty(navigator, 'clipboard');
- render(ObjectInspector, { props: { item } });
-
- await openMoreActions();
- await fireEvent.click(screen.getByRole('button', { name: 'Copy link' }));
-
- expect(screen.getByRole('status')).toHaveTextContent('Clipboard access is unavailable.');
- });
-});
diff --git a/apps/web/src/features/workbench/ProjectChannelSidebar.svelte b/apps/web/src/features/workbench/ProjectChannelSidebar.svelte
deleted file mode 100644
index 251682b..0000000
--- a/apps/web/src/features/workbench/ProjectChannelSidebar.svelte
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/workbench/ProjectRail.svelte b/apps/web/src/features/workbench/ProjectRail.svelte
deleted file mode 100644
index be4dd5c..0000000
--- a/apps/web/src/features/workbench/ProjectRail.svelte
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/workbench/ProjectWorkbench.svelte b/apps/web/src/features/workbench/ProjectWorkbench.svelte
deleted file mode 100644
index be184c5..0000000
--- a/apps/web/src/features/workbench/ProjectWorkbench.svelte
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
diff --git a/apps/web/src/features/workbench/ProjectWorkbench.test.ts b/apps/web/src/features/workbench/ProjectWorkbench.test.ts
deleted file mode 100644
index 4f5c1da..0000000
--- a/apps/web/src/features/workbench/ProjectWorkbench.test.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { fireEvent, render, screen, waitFor, within } from '@testing-library/svelte';
-import { describe, expect, it, vi } from 'vitest';
-import ProjectWorkbench from './ProjectWorkbench.svelte';
-
-describe('ProjectWorkbench', () => {
- it('renders project rail, channel sidebar, topbar, and inspector', () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
-
- expect(screen.getByLabelText('Project list')).toBeInTheDocument();
- expect(screen.getByRole('button', { name: 'Project A1' })).toHaveAttribute('aria-pressed', 'true');
- expect(screen.getByLabelText('Project A1 updates 36')).toBeInTheDocument();
- expect(screen.getByLabelText('Project channels')).toBeInTheDocument();
- expect(screen.getByRole('button', { name: 'Message Flow 36' })).toBeInTheDocument();
- expect(screen.getByLabelText('Global search')).toBeEnabled();
- expect(screen.getByRole('button', { name: 'Search workspace' })).toBeInTheDocument();
- expect(screen.getByRole('button', { name: 'Switch to dark mode' })).toBeInTheDocument();
- expect(screen.getByLabelText('Object inspector')).toBeInTheDocument();
- });
-
- it('pins user actions and task status to the page bottom bar', () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
- const statusBar = screen.getByLabelText('Workspace status');
-
- expect(within(statusBar).getByText('david@example.com')).toBeInTheDocument();
- expect(within(statusBar).getByRole('button', { name: 'Friends' })).toBeInTheDocument();
- expect(within(statusBar).getByRole('button', { name: 'Direct messages' })).toBeInTheDocument();
- expect(within(statusBar).getByRole('button', { name: 'Settings' })).toBeInTheDocument();
- expect(within(statusBar).getByText('Sync complete')).toBeInTheDocument();
- expect(within(statusBar).getByText('3 tasks running')).toBeInTheDocument();
- expect(within(statusBar).getByText('AI queue idle')).toBeInTheDocument();
- expect(within(statusBar).getByText('Draft saved')).toBeInTheDocument();
- });
-
- it('shows overview work queues below the metric cards', () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
-
- expect(screen.getByRole('heading', { name: 'Inbox 待处理' })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: '进行中的任务' })).toBeInTheDocument();
- expect(screen.getByRole('heading', { name: 'AI 会话' })).toBeInTheDocument();
- expect(screen.getByText('Collect competitor pricing notes')).toBeInTheDocument();
- expect(screen.getByText('Confirm homepage information architecture')).toBeInTheDocument();
- });
-
- it('toggles between light and dark workbench palettes', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
- const shell = screen.getByLabelText('SenlinAI workbench');
-
- expect(shell).toHaveAttribute('data-theme', 'light');
-
- await fireEvent.click(screen.getByRole('button', { name: 'Switch to dark mode' }));
-
- expect(shell).toHaveAttribute('data-theme', 'dark');
- expect(screen.getByRole('button', { name: 'Switch to light mode' })).toBeInTheDocument();
- });
-
- it('refreshes channels when switching projects', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Project A2' }));
-
- expect(screen.getByRole('button', { name: 'Project A2' })).toHaveAttribute('aria-pressed', 'true');
- expect(screen.getByText('Ops Dashboard')).toBeInTheDocument();
- });
-
- it('marks active channel with aria-pressed', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
-
- expect(screen.getByRole('button', { name: 'Work Plan 8' })).toHaveAttribute('aria-pressed', 'true');
- });
-
- it('shows inspected task details in the inspector', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
- const inspector = screen.getByLabelText('Object inspector');
-
- expect(within(inspector).getByRole('button', { name: 'Discussion' })).toHaveAttribute('aria-pressed', 'true');
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
-
- expect(within(inspector).getByRole('heading', { name: 'Confirm homepage information architecture' })).toBeInTheDocument();
-
- await fireEvent.click(within(inspector).getByRole('button', { name: 'Properties' }));
-
- expect(within(inspector).getByRole('button', { name: 'Properties' })).toHaveAttribute('aria-pressed', 'true');
- expect(within(inspector).getByText('Status')).toBeInTheDocument();
- expect(within(inspector).getByText('Open')).toBeInTheDocument();
- expect(within(inspector).getByText('Owner')).toBeInTheDocument();
- expect(within(inspector).getByText('David')).toBeInTheDocument();
- });
-
- it('clears the inspector when the project or channel changes', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
- const inspector = screen.getByLabelText('Object inspector');
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
- expect(within(inspector).getByRole('heading', { name: 'Confirm homepage information architecture' })).toBeInTheDocument();
-
- await fireEvent.click(screen.getByRole('button', { name: 'Project A2' }));
- expect(within(inspector).getByRole('heading', { name: 'Inspector' })).toBeInTheDocument();
- expect(within(inspector).queryByRole('heading', { name: 'Confirm homepage information architecture' })).not.toBeInTheDocument();
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Message Flow 36' }));
- expect(within(inspector).getByRole('heading', { name: 'Inspector' })).toBeInTheDocument();
- });
-
- it('preserves task completion when switching channels within a project', async () => {
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- const task = screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' });
- await fireEvent.click(task);
- expect(task).toBeChecked();
-
- await fireEvent.click(screen.getByRole('button', { name: 'Message Flow 36' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- expect(screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' })).toBeChecked();
-
- await fireEvent.click(screen.getByRole('button', { name: 'Project A2' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- expect(screen.getByRole('checkbox', { name: 'Mark Confirm homepage information architecture complete' })).not.toBeChecked();
- });
-
- it('provides Copy link feedback and disables unavailable archive actions', async () => {
- const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');
- Object.defineProperty(navigator, 'clipboard', {
- configurable: true,
- value: { writeText: vi.fn().mockResolvedValue(undefined) } as Clipboard,
- });
- render(ProjectWorkbench, { props: { currentUser: { account: 'david@example.com' } } });
- const inspector = screen.getByLabelText('Object inspector');
-
- await fireEvent.click(screen.getByRole('button', { name: 'Work Plan 8' }));
- await fireEvent.click(screen.getByRole('button', { name: 'Inspect Confirm homepage information architecture' }));
- await fireEvent.click(within(inspector).getByRole('button', { name: 'More' }));
- await fireEvent.click(within(inspector).getByRole('button', { name: 'Copy link' }));
-
- await waitFor(() => expect(within(inspector).getByRole('status')).toHaveTextContent('Link copied to clipboard.'));
- expect(within(inspector).getByRole('button', { name: 'Archive is unavailable in this preview' })).toBeDisabled();
-
- if (originalClipboard) {
- Object.defineProperty(navigator, 'clipboard', originalClipboard);
- } else {
- Reflect.deleteProperty(navigator, 'clipboard');
- }
- });
-});
diff --git a/apps/web/src/features/workbench/WorkspaceStatusBar.svelte b/apps/web/src/features/workbench/WorkspaceStatusBar.svelte
deleted file mode 100644
index 2375a18..0000000
--- a/apps/web/src/features/workbench/WorkspaceStatusBar.svelte
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/workbench/WorkspaceTopbar.svelte b/apps/web/src/features/workbench/WorkspaceTopbar.svelte
deleted file mode 100644
index 802d31b..0000000
--- a/apps/web/src/features/workbench/WorkspaceTopbar.svelte
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
diff --git a/apps/web/src/features/workbench/channels/AISessionsChannel.svelte b/apps/web/src/features/workbench/channels/AISessionsChannel.svelte
deleted file mode 100644
index 3b52383..0000000
--- a/apps/web/src/features/workbench/channels/AISessionsChannel.svelte
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- {#each sessions as session}
-
- {/each}
-
- {#if selectedSession}
-
{selectedSession.title}
{selectedSession.summary}
References: {selectedSession.references.join(', ')}
- {/if}
-
-
diff --git a/apps/web/src/features/workbench/channels/CronChannel.svelte b/apps/web/src/features/workbench/channels/CronChannel.svelte
deleted file mode 100644
index 7a6f2c3..0000000
--- a/apps/web/src/features/workbench/channels/CronChannel.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- {#each plans as plan}
-
{plan.title}
{plan.schedule} · {plan.nextRun}
{plan.enabled ? 'Enabled' : 'Disabled'} · {plan.lastResult}
- {/each}
-
-
diff --git a/apps/web/src/features/workbench/channels/CustomLinkChannel.svelte b/apps/web/src/features/workbench/channels/CustomLinkChannel.svelte
deleted file mode 100644
index 57a3ff2..0000000
--- a/apps/web/src/features/workbench/channels/CustomLinkChannel.svelte
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
- {channel.url}
- Open external channel
-
- {#if copyStatus}
- {copyStatus}
- {/if}
-
diff --git a/apps/web/src/features/workbench/channels/CustomLinkChannel.test.ts b/apps/web/src/features/workbench/channels/CustomLinkChannel.test.ts
deleted file mode 100644
index e968295..0000000
--- a/apps/web/src/features/workbench/channels/CustomLinkChannel.test.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import '@testing-library/jest-dom/vitest';
-import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/svelte';
-import { afterEach, describe, expect, it, vi } from 'vitest';
-import CustomLinkChannel from './CustomLinkChannel.svelte';
-
-const channel = {
- id: 'project-custom-link',
- projectID: 1,
- type: 'custom_link' as const,
- title: 'Roadmap Board',
- icon: 'link',
- url: 'https://example.com/roadmap',
- sortOrder: 1,
-};
-const originalClipboard = Object.getOwnPropertyDescriptor(navigator, 'clipboard');
-
-function setClipboard(writeText: Clipboard['writeText']) {
- Object.defineProperty(navigator, 'clipboard', {
- configurable: true,
- value: { writeText } as Clipboard,
- });
-}
-
-afterEach(() => {
- cleanup();
- if (originalClipboard) {
- Object.defineProperty(navigator, 'clipboard', originalClipboard);
- } else {
- Reflect.deleteProperty(navigator, 'clipboard');
- }
-});
-
-describe('CustomLinkChannel', () => {
- it('shows copy success only after clipboard writing resolves', async () => {
- let resolveWrite: (() => void) | undefined;
- const writeText = vi.fn(
- () =>
- new Promise((resolve) => {
- resolveWrite = resolve;
- }),
- );
- setClipboard(writeText);
- render(CustomLinkChannel, { props: { channel } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
-
- expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
- resolveWrite?.();
- await waitFor(() => expect(screen.getByText('URL copied.')).toBeInTheDocument());
- });
-
- it('reports a copy failure when clipboard writing rejects', async () => {
- setClipboard(vi.fn().mockRejectedValue(new Error('Permission denied')));
- render(CustomLinkChannel, { props: { channel } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
-
- await waitFor(() => expect(screen.getByText('Unable to copy URL.')).toBeInTheDocument());
- });
-
- it('reports unavailable clipboard access without showing URL copied', async () => {
- Reflect.deleteProperty(navigator, 'clipboard');
- render(CustomLinkChannel, { props: { channel } });
-
- await fireEvent.click(screen.getByRole('button', { name: 'Copy URL' }));
-
- await waitFor(() => expect(screen.getByText('Copy unavailable in this browser.')).toBeInTheDocument());
- expect(screen.queryByText('URL copied.')).not.toBeInTheDocument();
- });
-});
diff --git a/apps/web/src/features/workbench/channels/InboxChannel.svelte b/apps/web/src/features/workbench/channels/InboxChannel.svelte
deleted file mode 100644
index 2d25d63..0000000
--- a/apps/web/src/features/workbench/channels/InboxChannel.svelte
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
- {#each messages as message}
-
- {message.source} · {message.time}{message.title}
{message.summary}
{message.status} · #{message.tag}
-
-
- {/each}
-
-
diff --git a/apps/web/src/features/workbench/channels/NotesSourcesChannel.svelte b/apps/web/src/features/workbench/channels/NotesSourcesChannel.svelte
deleted file mode 100644
index 256ef8b..0000000
--- a/apps/web/src/features/workbench/channels/NotesSourcesChannel.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
- {#each items as item}
-
{item.kind}{item.title}
{item.source} · {item.updatedAt} · #{item.tag}
- {/each}
-
-
diff --git a/apps/web/src/features/workbench/channels/OverviewChannel.svelte b/apps/web/src/features/workbench/channels/OverviewChannel.svelte
deleted file mode 100644
index 5421b8e..0000000
--- a/apps/web/src/features/workbench/channels/OverviewChannel.svelte
+++ /dev/null
@@ -1,148 +0,0 @@
-
-
-
-
-
- {#each metrics(workspace) as metric}
-
- {/each}
-
-
-
-
-
-
- {#each workspace.inbox as message}
-
- {/each}
-
-
-
-
-
-
- {#each workspace.tasks as task}
-
- {/each}
-
-
-
-
-
-
- {#each workspace.aiSessions as session}
-
- {/each}
-
-
-
-
-
-
- {#each workspace.notesSources as item}
-
- {/each}
-
-
-
-
diff --git a/apps/web/src/features/workbench/channels/TasksChannel.svelte b/apps/web/src/features/workbench/channels/TasksChannel.svelte
deleted file mode 100644
index 8639b22..0000000
--- a/apps/web/src/features/workbench/channels/TasksChannel.svelte
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
- {#each tasks as task}
-
- onToggleTask(task.id)}
- />
-
-
{task.title}
-
{task.summary}
-
{task.owner} / {task.due} / #{task.tag}
-
{task.completed ? 'Completed' : 'Open'}
-
-
-
- {/each}
-
-
diff --git a/apps/web/src/features/workbench/mockData.test.ts b/apps/web/src/features/workbench/mockData.test.ts
deleted file mode 100644
index fdbf451..0000000
--- a/apps/web/src/features/workbench/mockData.test.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { describe, expect, it } from 'vitest';
-import { getProjectWorkspace, workbenchProjects } from './mockData';
-
-describe('workbench mock data', () => {
- it('provides dynamic projects', () => {
- expect(workbenchProjects.length).toBeGreaterThanOrEqual(2);
- expect(workbenchProjects[0]).toMatchObject({ id: expect.any(Number), name: expect.any(String) });
- });
-
- it('loads project-specific channels and counts', () => {
- const first = getProjectWorkspace(workbenchProjects[0].id);
- const second = getProjectWorkspace(workbenchProjects[1].id);
-
- expect(first.project.id).not.toBe(second.project.id);
- expect(first.channels.map((channel) => channel.type)).toEqual([
- 'overview',
- 'inbox',
- 'tasks',
- 'ai_sessions',
- 'notes_sources',
- 'cron',
- 'custom_link',
- ]);
- expect(first.channels.find((channel) => channel.type === 'custom_link')).toMatchObject({
- title: expect.any(String),
- url: expect.stringMatching(/^https?:\/\//),
- });
- });
-});
diff --git a/apps/web/src/features/workbench/mockData.ts b/apps/web/src/features/workbench/mockData.ts
deleted file mode 100644
index 90a25c2..0000000
--- a/apps/web/src/features/workbench/mockData.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import type { ProjectWorkspace, WorkbenchChannel, WorkbenchProject } from './types';
-
-export const workbenchProjects: WorkbenchProject[] = [
- { id: 1, name: 'Project A1', description: 'Client strategy workspace', initials: 'A1', unreadCount: 36 },
- { id: 2, name: 'Project A2', description: 'Operations planning workspace', initials: 'A2', unreadCount: 12 },
-];
-
-function systemChannels(projectID: number): WorkbenchChannel[] {
- return [
- { id: `${projectID}-overview`, projectID, type: 'overview', title: 'Overview', icon: 'home', count: 635, sortOrder: 1 },
- { id: `${projectID}-inbox`, projectID, type: 'inbox', title: 'Message Flow', icon: 'mail', count: 36, sortOrder: 2 },
- { id: `${projectID}-tasks`, projectID, type: 'tasks', title: 'Work Plan', icon: 'list', count: 8, sortOrder: 3 },
- { id: `${projectID}-ai`, projectID, type: 'ai_sessions', title: 'AI Sessions', icon: 'sparkles', count: 4, sortOrder: 4 },
- { id: `${projectID}-notes`, projectID, type: 'notes_sources', title: 'Notes & Sources', icon: 'file', count: 343, sortOrder: 5 },
- { id: `${projectID}-cron`, projectID, type: 'cron', title: 'Cron Plans', icon: 'clock', count: 45, sortOrder: 6 },
- {
- id: `${projectID}-custom-roadmap`,
- projectID,
- type: 'custom_link',
- title: projectID === 1 ? 'Roadmap Board' : 'Ops Dashboard',
- icon: 'link',
- url: projectID === 1 ? 'https://example.com/roadmap-a1' : 'https://example.com/ops-a2',
- sortOrder: 7,
- },
- ];
-}
-
-const workspaces: ProjectWorkspace[] = workbenchProjects.map((project) => ({
- project,
- channels: systemChannels(project.id),
- tags: ['all', 'tag1', 'UI', 'knowledge'],
- recentSessions: [
- { id: `${project.id}-session-1`, title: 'Skill setup notes', summary: 'Install and verify Codex skills.', updatedAt: 'Yesterday', references: ['Notes'] },
- { id: `${project.id}-session-2`, title: 'Pricing logic analysis', summary: 'Compare decision branches and risks.', updatedAt: '7 days ago', references: ['Tasks', 'Sources'] },
- ],
- inbox: [
- { id: `${project.id}-inbox-1`, source: 'Manual', title: 'Collect competitor pricing notes', summary: 'Turn pasted research into structured follow-up tasks.', status: 'open', tag: 'UI', time: '09:32' },
- { id: `${project.id}-inbox-2`, source: 'AI', title: 'Meeting summary candidate', summary: 'Review suggested note before saving official object.', status: 'processed', tag: 'knowledge', time: 'Yesterday' },
- ],
- tasks: [
- { id: `${project.id}-task-1`, title: 'Confirm homepage information architecture', summary: 'Review channel layout and right inspector behavior.', completed: false, owner: 'David', due: 'Today', tag: 'UI' },
- { id: `${project.id}-task-2`, title: 'Archive old planning notes', summary: 'Move outdated notes into processed state.', completed: true, owner: 'Team', due: 'Yesterday', tag: 'knowledge' },
- ],
- aiSessions: [
- { id: `${project.id}-ai-1`, title: 'UI prototype critique', summary: 'Discuss Discord-like project channel behavior.', updatedAt: '10 min ago', references: ['ScreenShot.png', 'design.md'] },
- { id: `${project.id}-ai-2`, title: 'Task sharing policy', summary: 'Validate explicit object sharing rules.', updatedAt: 'Yesterday', references: ['Tasks'] },
- ],
- notesSources: [
- { id: `${project.id}-note-1`, kind: 'note', title: 'Product workbench principles', updatedAt: 'Today', tag: 'knowledge', source: 'Markdown' },
- { id: `${project.id}-file-1`, kind: 'file', title: 'ScreenShot.png', updatedAt: 'Today', tag: 'UI', source: 'Attachment' },
- { id: `${project.id}-link-1`, kind: 'link', title: 'Reference board', updatedAt: '7 days ago', tag: 'tag1', source: 'URL' },
- ],
- cronPlans: [
- { id: `${project.id}-cron-1`, title: 'Weekly inbox review reminder', schedule: '0 9 * * 1', nextRun: 'Next Monday 09:00', enabled: true, lastResult: 'Not run yet', owner: 'David' },
- { id: `${project.id}-cron-2`, title: 'Monthly source cleanup', schedule: '0 10 1 * *', nextRun: 'Next month', enabled: false, lastResult: 'Paused', owner: 'Team' },
- ],
-}));
-
-export function getProjectWorkspace(projectID: number): ProjectWorkspace {
- return workspaces.find((workspace) => workspace.project.id === projectID) ?? workspaces[0];
-}
diff --git a/apps/web/src/features/workbench/types.ts b/apps/web/src/features/workbench/types.ts
deleted file mode 100644
index 98ae0f9..0000000
--- a/apps/web/src/features/workbench/types.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-export type ChannelType =
- | 'overview'
- | 'inbox'
- | 'tasks'
- | 'ai_sessions'
- | 'notes_sources'
- | 'cron'
- | 'custom_link';
-
-export type WorkbenchProject = {
- id: number;
- name: string;
- description: string;
- initials: string;
- unreadCount: number;
-};
-
-export type WorkbenchChannel = {
- id: string;
- projectID: number;
- type: ChannelType;
- title: string;
- icon: string;
- count?: number;
- url?: string;
- sortOrder: number;
-};
-
-export type InboxMessage = {
- id: string;
- source: string;
- title: string;
- summary: string;
- status: 'open' | 'processed' | 'archived';
- tag: string;
- time: string;
-};
-
-export type WorkTask = {
- id: string;
- title: string;
- summary: string;
- completed: boolean;
- owner: string;
- due: string;
- tag: string;
-};
-
-export type AISessionItem = {
- id: string;
- title: string;
- summary: string;
- updatedAt: string;
- references: string[];
-};
-
-export type NoteSourceItem = {
- id: string;
- kind: 'note' | 'file' | 'link';
- title: string;
- updatedAt: string;
- tag: string;
- source: string;
-};
-
-export type CronPlan = {
- id: string;
- title: string;
- schedule: string;
- nextRun: string;
- enabled: boolean;
- lastResult: string;
- owner: string;
-};
-
-export type InspectorItem = {
- title: string;
- type: string;
- description: string;
- properties: Array<{ label: string; value: string }>;
-};
-
-export type ProjectWorkspace = {
- project: WorkbenchProject;
- channels: WorkbenchChannel[];
- tags: string[];
- recentSessions: AISessionItem[];
- inbox: InboxMessage[];
- tasks: WorkTask[];
- aiSessions: AISessionItem[];
- notesSources: NoteSourceItem[];
- cronPlans: CronPlan[];
-};
diff --git a/apps/web/src/index.css b/apps/web/src/index.css
deleted file mode 100644
index 2c3e6a3..0000000
--- a/apps/web/src/index.css
+++ /dev/null
@@ -1,844 +0,0 @@
-:root {
- color: #1d2129;
- background: #f7f8fa;
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
- line-height: 1.5;
- --background: #f7f8fa;
- --panel: #ffffff;
- --panel-muted: #f2f3f5;
- --border: #e5e6eb;
- --text: #1d2129;
- --muted: #86909c;
- --subtle: #4e5969;
- --primary: #165dff;
- --primary-strong: #0e42d2;
- --primary-soft: #e8f3ff;
- --success: #00b42a;
- --warning: #ff7d00;
- --danger: #f53f3f;
- --statusbar: #142033;
- --statusbar-border: #22314a;
- --radius: 6px;
-}
-
-* { box-sizing: border-box; }
-body { margin: 0; min-width: 320px; min-height: 100vh; }
-button, input, textarea, select { font: inherit; }
-button { cursor: pointer; }
-button:focus-visible, input:focus-visible, a:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
-button:disabled { cursor: not-allowed; opacity: 0.58; }
-a { color: inherit; text-decoration: none; }
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border: 0;
-}
-
-.login-page {
- min-height: 100vh;
- display: grid;
- place-items: center;
- padding: 28px;
- background:
- radial-gradient(circle at top left, rgba(22, 93, 255, 0.08), transparent 32%),
- var(--background);
-}
-
-.login-panel {
- width: min(1200px, 100%);
- min-height: 420px;
- display: grid;
- grid-template-columns: 1fr 1.1fr 1fr;
- overflow: hidden;
- border: 1px solid var(--border);
- border-radius: 8px;
- background: var(--panel);
- box-shadow: 0 10px 30px rgba(29, 33, 41, 0.08);
-}
-
-.login-brand-panel,
-.server-login,
-.login-value-panel {
- padding: 36px 42px;
-}
-
-.login-brand-panel {
- display: grid;
- align-content: center;
- gap: 10px;
- border-right: 1px solid var(--border);
-}
-
-.login-brand {
- width: 42px;
- height: 42px;
- display: grid;
- place-items: center;
- border-radius: 10px;
- background: var(--primary);
- color: white;
- font-weight: 800;
- font-size: 1.35rem;
-}
-
-.login-brand-panel h1,
-.login-heading h2,
-.login-value-panel h2 {
- margin: 0;
- color: var(--text);
-}
-
-.login-brand-panel h1 { font-size: 1.8rem; }
-.login-brand-panel p,
-.login-value-panel p {
- margin: 0;
- color: var(--subtle);
-}
-
-.login-brand-panel small,
-.login-links,
-.connection-status,
-.login-note,
-.form-error,
-.channel-header p,
-.channel-page small,
-.channel-page > p,
-.object-inspector > p {
- margin: 0;
- color: var(--muted);
- font-size: 0.875rem;
-}
-
-.login-links {
- align-self: end;
- display: flex;
- gap: 18px;
- margin-top: 72px;
-}
-
-.server-login,
-.login-heading,
-.channel-page,
-.object-inspector,
-.channel-sidebar {
- display: grid;
- gap: 12px;
-}
-
-.login-heading { gap: 4px; }
-.login-heading p { margin: 0; color: var(--text); font-weight: 600; }
-.login-heading h2 { font-size: 1rem; font-weight: 500; color: var(--muted); }
-
-.server-login {
- border-right: 1px solid var(--border);
-}
-
-.server-login label {
- color: var(--subtle);
- font-size: 0.8125rem;
- font-weight: 600;
-}
-
-.server-login input,
-.search-box input {
- width: 100%;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: white;
- color: var(--text);
-}
-
-.server-login input {
- height: 36px;
- padding: 8px 10px;
-}
-
-.server-login button,
-.primary-action {
- height: 38px;
- border: 1px solid var(--primary);
- border-radius: var(--radius);
- background: var(--primary);
- color: white;
- padding: 0 14px;
- font-weight: 600;
-}
-
-.form-error { color: var(--danger); }
-
-.connection-status {
- border: 1px solid #7be188;
- border-radius: var(--radius);
- background: #f0fff4;
- color: #168a2f;
- padding: 8px 10px;
-}
-
-.login-value-panel {
- display: grid;
- align-content: center;
- gap: 18px;
-}
-
-.login-value-panel ul {
- display: grid;
- gap: 18px;
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-.login-value-panel li {
- display: grid;
- gap: 3px;
- padding-left: 16px;
- border-left: 3px solid var(--primary-soft);
-}
-
-.login-value-panel strong { color: var(--text); }
-.login-value-panel span { color: var(--muted); font-size: 0.875rem; }
-
-.workbench-shell {
- min-height: 100vh;
- display: grid;
- grid-template-rows: 58px minmax(0, 1fr) 32px;
- background: var(--background);
- color: var(--text);
-}
-
-.workbench-shell[data-theme='dark'] {
- --background: #1e1e1e;
- --panel: #252526;
- --panel-muted: #2d2d30;
- --border: #3c3c3c;
- --text: #cccccc;
- --muted: #858585;
- --subtle: #a7a7a7;
- --primary: #007acc;
- --primary-strong: #1890e8;
- --primary-soft: rgba(0, 122, 204, 0.22);
- --statusbar: #007acc;
- --statusbar-border: #1f6feb;
-}
-
-.workspace-topbar {
- display: grid;
- grid-template-columns: 192px minmax(420px, 1fr) auto;
- align-items: center;
- gap: 18px;
- border-bottom: 1px solid var(--border);
- background: var(--panel);
- padding: 0 16px;
-}
-
-.brand-mark {
- display: flex;
- align-items: center;
- gap: 10px;
- font-size: 1.05rem;
- font-weight: 700;
-}
-
-.brand-logo {
- width: 28px;
- height: 28px;
- display: grid;
- place-items: center;
- border-radius: 7px;
- background: var(--primary);
- color: white;
- font-weight: 800;
-}
-
-.search-box {
- display: grid;
- grid-template-columns: minmax(0, 1fr) 72px;
- align-items: center;
- max-width: 680px;
- min-width: 0;
- height: 42px;
- border: 1px solid var(--primary);
- border-radius: 7px;
- background: var(--panel);
- box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.06);
-}
-
-.search-box input {
- height: 40px;
- border: 0;
- padding: 0 16px;
- background: transparent;
-}
-
-.search-box button {
- height: 40px;
- border: 0;
- border-left: 1px solid var(--primary);
- border-radius: 0 6px 6px 0;
- background: var(--primary);
- color: white;
- font-weight: 600;
-}
-
-.topbar-actions {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.topbar-actions button {
- width: 32px;
- height: 32px;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel);
- color: var(--subtle);
-}
-
-.topbar-actions .theme-toggle {
- width: 56px;
- background: var(--panel-muted);
- color: var(--primary);
-}
-
-.workbench-body {
- min-height: 0;
- display: grid;
- grid-template-columns: 88px 248px minmax(0, 1fr) 330px;
-}
-
-.project-rail,
-.channel-sidebar,
-.object-inspector {
- border-right: 1px solid var(--border);
- background: var(--panel);
-}
-
-.project-rail {
- display: grid;
- align-content: start;
- gap: 12px;
- padding: 14px 12px;
-}
-
-.project-rail button {
- position: relative;
- width: 56px;
- min-height: 56px;
- display: grid;
- place-items: center;
- gap: 2px;
- border: 1px solid var(--border);
- border-radius: 8px;
- background: var(--panel-muted);
- color: var(--subtle);
-}
-
-.project-rail button.active {
- border-color: var(--primary);
- background: var(--primary);
- color: white;
-}
-
-.project-initials { font-weight: 700; }
-
-.project-rail small {
- position: absolute;
- top: -6px;
- right: -7px;
- min-width: 19px;
- height: 19px;
- display: grid;
- place-items: center;
- border: 2px solid var(--panel);
- border-radius: 999px;
- background: var(--primary);
- color: white;
- font-size: 0.625rem;
- line-height: 1;
-}
-
-.project-rail small.urgent { background: var(--danger); }
-
-.channel-sidebar,
-.object-inspector,
-.channel-stage {
- padding: 16px;
- overflow: auto;
-}
-
-.channel-sidebar {
- align-content: start;
- justify-items: start;
-}
-
-.channel-sidebar > header,
-.channel-sidebar > .channel-group,
-.channel-sidebar > .recent-sessions {
- width: 100%;
-}
-
-.channel-sidebar header {
- display: flex;
- align-items: start;
- justify-content: space-between;
- gap: 12px;
-}
-
-.channel-sidebar header p,
-.channel-sidebar h2,
-.channel-sidebar h3 { margin: 0; }
-.channel-sidebar h2 { font-size: 1rem; }
-.channel-sidebar h3 { color: var(--muted); font-size: 0.8125rem; font-weight: 600; }
-
-.channel-sidebar header button {
- width: 30px;
- height: 30px;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel-muted);
-}
-
-.tag-row,
-.recent-sessions ul {
- display: flex;
- flex-wrap: wrap;
- gap: 6px;
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-.tag-row li {
- border: 1px solid var(--border);
- border-radius: 999px;
- padding: 3px 8px;
- background: var(--panel-muted);
- color: var(--muted);
- font-size: 0.75rem;
-}
-
-.channel-group,
-.task-list,
-.record-list,
-.message-list,
-.file-list,
-.cron-list {
- display: grid;
- gap: 8px;
-}
-
-.channel-group button {
- width: 100%;
- min-height: 34px;
- display: grid;
- grid-template-columns: 18px minmax(0, 1fr) auto;
- gap: 8px;
- align-items: center;
- border: 0;
- border-radius: var(--radius);
- background: transparent;
- color: var(--text);
- padding: 7px 9px;
- text-align: left;
-}
-
-.channel-group button.active {
- color: var(--primary);
- background: var(--primary-soft);
- box-shadow: inset 3px 0 0 var(--primary);
-}
-
-.channel-group small {
- min-width: 26px;
- border-radius: 999px;
- background: var(--panel-muted);
- color: var(--muted);
- padding: 1px 6px;
- text-align: center;
-}
-
-.channel-icon { color: currentColor; text-align: center; }
-.recent-sessions { display: grid; gap: 8px; }
-.recent-sessions li { display: grid; gap: 2px; min-width: 0; padding: 7px 8px; border-radius: var(--radius); }
-.recent-sessions span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.8125rem; }
-.recent-sessions small { color: var(--muted); font-size: 0.6875rem; }
-
-.channel-stage { background: var(--background); }
-.channel-page { align-content: start; }
-.channel-header {
- display: flex;
- align-items: end;
- justify-content: space-between;
- border-bottom: 1px solid var(--border);
- padding-bottom: 12px;
-}
-.channel-header h1,
-.channel-page h2 { margin: 0; }
-.channel-header h1 { font-size: 1.125rem; }
-.channel-page h2 { font-size: 0.9375rem; }
-.channel-page h2 + p { margin: 4px 0; }
-
-.overview-tools {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.overview-tools span,
-.overview-tools button {
- height: 30px;
- display: inline-flex;
- align-items: center;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel);
- color: var(--subtle);
- padding: 0 10px;
- font-size: 0.8125rem;
-}
-
-.overview-tools button { width: 34px; justify-content: center; }
-
-.metric-list {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
- gap: 10px;
-}
-
-.metric-card,
-.task-card,
-.record-row,
-.cron-row,
-.message-row,
-.file-row,
-.conversation-summary {
- width: 100%;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel);
- padding: 10px 12px;
-}
-
-.metric-card {
- display: grid;
- gap: 4px;
- text-align: left;
-}
-
-.metric-card strong { font-size: 1.45rem; color: var(--text); }
-.metric-card span { color: var(--muted); font-size: 0.8125rem; }
-
-.overview-grid {
- display: grid;
- gap: 12px;
-}
-
-.overview-section {
- display: grid;
- gap: 6px;
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel);
- padding: 10px 12px;
-}
-
-.overview-section header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
-}
-
-.overview-section h2 {
- font-size: 0.875rem;
-}
-
-.overview-section a {
- color: var(--primary);
- font-size: 0.75rem;
- font-weight: 600;
-}
-
-.overview-rows {
- display: grid;
-}
-
-.overview-row {
- width: 100%;
- display: grid;
- grid-template-columns: minmax(160px, 1fr) minmax(180px, 1.1fr) auto;
- gap: 12px;
- align-items: center;
- border: 0;
- border-top: 1px solid var(--border);
- background: transparent;
- color: var(--text);
- padding: 8px 0;
- text-align: left;
-}
-
-.overview-row:first-child {
- border-top: 0;
-}
-
-.overview-row span,
-.overview-row small {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.overview-row span {
- font-weight: 600;
-}
-
-.overview-row small,
-.overview-row time {
- color: var(--muted);
- font-size: 0.75rem;
-}
-
-.task-card,
-.record-row,
-.cron-row,
-.message-row,
-.file-row {
- display: grid;
- grid-template-columns: auto minmax(0, 1fr) auto;
- gap: 12px;
- align-items: start;
-}
-
-.task-card.completed {
- color: var(--muted);
- background: var(--panel-muted);
-}
-
-.task-check { width: 18px; height: 18px; margin: 3px 0 0; accent-color: var(--primary); }
-.task-status { display: inline-block; margin-top: 6px; color: var(--muted); font-size: 0.75rem; }
-.message-row { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
-.file-row { grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; }
-.file-row > span { min-width: 40px; border: 1px solid var(--border); border-radius: 4px; padding: 3px 5px; color: var(--muted); font-size: 0.6875rem; text-align: center; text-transform: uppercase; }
-.message-row p,
-.cron-row p,
-.conversation-summary p { margin: 4px 0; }
-
-.message-row button,
-.file-row button,
-.task-card > button,
-.cron-row button,
-.conversation-summary button,
-.copy-url-button,
-.object-inspector button {
- border: 1px solid var(--border);
- border-radius: var(--radius);
- background: var(--panel);
- color: var(--text);
- padding: 6px 9px;
-}
-
-.session-layout { display: grid; grid-template-columns: minmax(180px, 0.7fr) minmax(0, 1.3fr); gap: 12px; }
-.session-list { display: grid; align-content: start; gap: 6px; }
-.session-list button { display: grid; gap: 3px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--panel); padding: 9px; text-align: left; }
-.session-list button.active { border-color: var(--primary); background: var(--primary-soft); }
-.session-list small { color: var(--muted); }
-.conversation-summary { align-content: start; }
-.custom-link { color: var(--primary-strong); font-weight: 600; width: max-content; }
-.copy-url-button { width: max-content; }
-.copy-feedback { margin: 0; color: var(--success); font-size: 0.8125rem; }
-.copy-feedback.copy-error { color: var(--danger); }
-
-.object-inspector {
- align-content: start;
- grid-auto-rows: min-content;
-}
-
-.inspector-tabs {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- align-content: start;
- grid-auto-rows: min-content;
- gap: 4px;
-}
-
-.inspector-tabs button[aria-pressed='true'] {
- border-color: var(--primary);
- color: var(--primary);
- background: var(--primary-soft);
-}
-
-.workspace-statusbar {
- min-height: 32px;
- display: grid;
- grid-template-columns: minmax(280px, 0.9fr) minmax(420px, 1.2fr) minmax(260px, 0.9fr);
- align-items: center;
- gap: 14px;
- border-top: 1px solid var(--statusbar-border);
- background: var(--statusbar);
- color: rgba(255, 255, 255, 0.82);
- padding: 0 14px;
- font-size: 0.75rem;
-}
-
-.statusbar-user,
-.statusbar-tasks,
-.statusbar-system {
- min-width: 0;
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-.statusbar-tasks { justify-content: center; color: rgba(255, 255, 255, 0.86); }
-.statusbar-system { justify-content: end; color: rgba(255, 255, 255, 0.72); }
-
-.user-avatar {
- width: 24px;
- height: 24px;
- display: grid;
- place-items: center;
- border-radius: 999px;
- background: var(--primary);
- color: white;
- font-size: 0.6875rem;
- font-weight: 700;
-}
-
-.user-meta {
- min-width: 0;
- display: grid;
- line-height: 1.05;
-}
-
-.user-meta strong {
- max-width: 160px;
- overflow: hidden;
- color: white;
- font-size: 0.75rem;
- font-weight: 600;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.user-meta small { color: #7be188; font-size: 0.6875rem; }
-
-.workspace-statusbar button {
- height: 24px;
- border: 0;
- border-radius: 4px;
- background: transparent;
- color: rgba(255, 255, 255, 0.78);
- padding: 0 6px;
-}
-
-.workspace-statusbar button:hover { background: rgba(255, 255, 255, 0.1); }
-
-@media (max-width: 920px) {
- .login-panel {
- grid-template-columns: 1fr;
- }
-
- .login-brand-panel,
- .server-login {
- border-right: 0;
- border-bottom: 1px solid var(--border);
- }
-
- .workspace-topbar {
- grid-template-columns: minmax(0, 1fr) auto;
- height: auto;
- padding: 12px;
- }
-
- .search-box { grid-column: 1 / -1; grid-row: 2; max-width: none; }
- .topbar-actions { grid-column: 2; grid-row: 1; }
-
- .workbench-shell {
- grid-template-rows: auto 1fr auto;
- }
-
- .workbench-body {
- grid-template-columns: 1fr;
- align-content: start;
- }
-
- .project-rail,
- .channel-sidebar,
- .object-inspector {
- border-right: 0;
- border-bottom: 1px solid var(--border);
- }
-
- .project-rail {
- grid-template-columns: none;
- grid-auto-flow: column;
- grid-auto-columns: 56px;
- align-items: center;
- max-height: 84px;
- overflow-x: auto;
- overflow-y: hidden;
- padding: 10px 12px;
- }
-
- .channel-sidebar {
- align-content: start;
- max-height: 230px;
- padding: 12px;
- }
-
- .channel-group,
- .tag-row,
- .recent-sessions ul {
- grid-auto-flow: column;
- grid-auto-columns: minmax(132px, max-content);
- grid-template-columns: none;
- flex-wrap: nowrap;
- overflow-x: auto;
- padding-bottom: 2px;
- }
-
- .channel-group {
- grid-auto-flow: row;
- grid-auto-columns: auto;
- grid-template-columns: repeat(3, minmax(0, 1fr));
- overflow: visible;
- }
-
- .channel-group button {
- min-width: 0;
- min-height: 48px;
- grid-template-columns: 18px minmax(0, 1fr);
- padding: 8px;
- }
-
- .channel-group button > span:last-of-type {
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- .channel-group small { display: none; }
- .recent-sessions li { min-width: 160px; }
- .channel-stage { max-height: 36vh; overflow: auto; }
- .object-inspector { max-height: 288px; overflow: auto; }
- .session-layout { grid-template-columns: 1fr; }
-
- .workspace-statusbar {
- grid-template-columns: 1fr;
- gap: 6px;
- padding: 8px 12px;
- }
-
- .statusbar-tasks,
- .statusbar-system {
- justify-content: start;
- flex-wrap: wrap;
- }
-}
diff --git a/apps/web/src/lib/api.ts b/apps/web/src/lib/api.ts
deleted file mode 100644
index 6f8db99..0000000
--- a/apps/web/src/lib/api.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export type Project = { id: number; name: string; description: string };
-
-export type ProjectDashboardSummary = {
- project_id: number;
- pending_inbox_count: number;
- open_task_count: number;
- recent_note_count: number;
- recent_session_count: number;
-};
-
-export function createApi(apiBase: string, token?: string) {
- async function request(path: string): Promise {
- const response = await fetch(`${apiBase}/api${path}`, {
- headers: token ? { Authorization: `Bearer ${token}` } : {},
- });
- if (!response.ok) throw new Error(`API request failed: ${response.status}`);
- return response.json() as Promise;
- }
-
- return {
- getProjects: () => request('/projects'),
- getProjectDashboard: (projectID: number) =>
- request(`/projects/${projectID}/dashboard`),
- };
-}
diff --git a/apps/web/src/main.ts b/apps/web/src/main.ts
deleted file mode 100644
index fde0ae5..0000000
--- a/apps/web/src/main.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import './index.css';
-import App from './app/App.svelte';
-import { mount } from 'svelte';
-
-const target = document.getElementById('app');
-
-if (!target) {
- throw new Error('Missing #app mount target');
-}
-
-mount(App, { target });
diff --git a/apps/web/src/vite-env.d.ts b/apps/web/src/vite-env.d.ts
deleted file mode 100644
index 4078e74..0000000
--- a/apps/web/src/vite-env.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-///
-///
diff --git a/apps/web/tsconfig.app.json b/apps/web/tsconfig.app.json
deleted file mode 100644
index 3446152..0000000
--- a/apps/web/tsconfig.app.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "@tsconfig/svelte/tsconfig.json",
- "compilerOptions": {
- "target": "ES2023",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "resolveJsonModule": true,
- "allowJs": true,
- "checkJs": true,
- "isolatedModules": true,
- "moduleDetection": "force",
- "types": ["svelte", "vite/client", "vitest/globals"],
- "noEmit": true,
- "strict": true
- },
- "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
-}
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
deleted file mode 100644
index 1ffef60..0000000
--- a/apps/web/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "files": [],
- "references": [
- { "path": "./tsconfig.app.json" },
- { "path": "./tsconfig.node.json" }
- ]
-}
diff --git a/apps/web/tsconfig.node.json b/apps/web/tsconfig.node.json
deleted file mode 100644
index 8455dcb..0000000
--- a/apps/web/tsconfig.node.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "compilerOptions": {
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
- "target": "es2023",
- "lib": ["ES2023"],
- "types": ["node"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "module": "nodenext",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "moduleDetection": "force",
- "noEmit": true,
-
- /* Linting */
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "erasableSyntaxOnly": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["vite.config.ts"]
-}
diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts
deleted file mode 100644
index 03d655a..0000000
--- a/apps/web/vite.config.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { svelte } from '@sveltejs/vite-plugin-svelte';
-import { defineConfig } from 'vite';
-
-export default defineConfig({
- plugins: [svelte()],
- resolve: {
- conditions: ['browser'],
- },
- test: {
- environment: 'jsdom',
- exclude: ['node_modules/**', 'dist/**', 'e2e/**'],
- globals: true,
- },
-});
diff --git a/apps/senlinai-acro-react/.gitignore b/apps/web_v1/.gitignore
similarity index 100%
rename from apps/senlinai-acro-react/.gitignore
rename to apps/web_v1/.gitignore
diff --git a/apps/senlinai-acro-react/.oxlintrc.json b/apps/web_v1/.oxlintrc.json
similarity index 100%
rename from apps/senlinai-acro-react/.oxlintrc.json
rename to apps/web_v1/.oxlintrc.json
diff --git a/apps/senlinai-acro-react/README.md b/apps/web_v1/README.md
similarity index 67%
rename from apps/senlinai-acro-react/README.md
rename to apps/web_v1/README.md
index e2f2da4..c086495 100644
--- a/apps/senlinai-acro-react/README.md
+++ b/apps/web_v1/README.md
@@ -2,7 +2,7 @@
SenlinAI primary web client built with React, TypeScript, Vite, and Arco Design.
-This app is now the active web client under `apps`. The legacy `apps/web` Svelte app is no longer the primary frontend.
+This app is the active web client under `apps/web_v1`.
## Scripts
diff --git a/apps/senlinai-acro-react/index.html b/apps/web_v1/index.html
similarity index 89%
rename from apps/senlinai-acro-react/index.html
rename to apps/web_v1/index.html
index 0bc891a..c80d6e3 100644
--- a/apps/senlinai-acro-react/index.html
+++ b/apps/web_v1/index.html
@@ -4,7 +4,7 @@
- senlinai-acro-react
+ web_v1
diff --git a/apps/senlinai-acro-react/package-lock.json b/apps/web_v1/package-lock.json
similarity index 99%
rename from apps/senlinai-acro-react/package-lock.json
rename to apps/web_v1/package-lock.json
index 96ff766..812fdf6 100644
--- a/apps/senlinai-acro-react/package-lock.json
+++ b/apps/web_v1/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "senlinai-acro-react",
+ "name": "web_v1",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "senlinai-acro-react",
+ "name": "web_v1",
"version": "0.0.0",
"dependencies": {
"@arco-design/web-react": "^2.66.16",
diff --git a/apps/senlinai-acro-react/package.json b/apps/web_v1/package.json
similarity index 94%
rename from apps/senlinai-acro-react/package.json
rename to apps/web_v1/package.json
index b9fbea6..9b045ea 100644
--- a/apps/senlinai-acro-react/package.json
+++ b/apps/web_v1/package.json
@@ -1,5 +1,5 @@
{
- "name": "senlinai-acro-react",
+ "name": "web_v1",
"private": true,
"version": "0.0.0",
"type": "module",
diff --git a/apps/senlinai-acro-react/public/favicon.svg b/apps/web_v1/public/favicon.svg
similarity index 100%
rename from apps/senlinai-acro-react/public/favicon.svg
rename to apps/web_v1/public/favicon.svg
diff --git a/apps/senlinai-acro-react/scripts/structure-check.mjs b/apps/web_v1/scripts/structure-check.mjs
similarity index 100%
rename from apps/senlinai-acro-react/scripts/structure-check.mjs
rename to apps/web_v1/scripts/structure-check.mjs
diff --git a/apps/senlinai-acro-react/scripts/visual-check.mjs b/apps/web_v1/scripts/visual-check.mjs
similarity index 100%
rename from apps/senlinai-acro-react/scripts/visual-check.mjs
rename to apps/web_v1/scripts/visual-check.mjs
diff --git a/apps/senlinai-acro-react/src/App.css b/apps/web_v1/src/App.css
similarity index 100%
rename from apps/senlinai-acro-react/src/App.css
rename to apps/web_v1/src/App.css
diff --git a/apps/senlinai-acro-react/src/api/client.ts b/apps/web_v1/src/api/client.ts
similarity index 100%
rename from apps/senlinai-acro-react/src/api/client.ts
rename to apps/web_v1/src/api/client.ts
diff --git a/apps/senlinai-acro-react/src/api/inbox.ts b/apps/web_v1/src/api/inbox.ts
similarity index 100%
rename from apps/senlinai-acro-react/src/api/inbox.ts
rename to apps/web_v1/src/api/inbox.ts
diff --git a/apps/senlinai-acro-react/src/api/mappers.tsx b/apps/web_v1/src/api/mappers.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/api/mappers.tsx
rename to apps/web_v1/src/api/mappers.tsx
diff --git a/apps/senlinai-acro-react/src/api/projects.ts b/apps/web_v1/src/api/projects.ts
similarity index 100%
rename from apps/senlinai-acro-react/src/api/projects.ts
rename to apps/web_v1/src/api/projects.ts
diff --git a/apps/senlinai-acro-react/src/app/App.tsx b/apps/web_v1/src/app/App.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/app/App.tsx
rename to apps/web_v1/src/app/App.tsx
diff --git a/apps/senlinai-acro-react/src/index.css b/apps/web_v1/src/index.css
similarity index 100%
rename from apps/senlinai-acro-react/src/index.css
rename to apps/web_v1/src/index.css
diff --git a/apps/senlinai-acro-react/src/main.tsx b/apps/web_v1/src/main.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/main.tsx
rename to apps/web_v1/src/main.tsx
diff --git a/apps/senlinai-acro-react/src/pages/login.tsx b/apps/web_v1/src/pages/login.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/login.tsx
rename to apps/web_v1/src/pages/login.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-action-modals.tsx b/apps/web_v1/src/pages/projects/project-action-modals.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-action-modals.tsx
rename to apps/web_v1/src/pages/projects/project-action-modals.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-ai.tsx b/apps/web_v1/src/pages/projects/project-ai.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-ai.tsx
rename to apps/web_v1/src/pages/projects/project-ai.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx b/apps/web_v1/src/pages/projects/project-channel-page.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-channel-page.tsx
rename to apps/web_v1/src/pages/projects/project-channel-page.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-cron.tsx b/apps/web_v1/src/pages/projects/project-cron.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-cron.tsx
rename to apps/web_v1/src/pages/projects/project-cron.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-file-grid.tsx b/apps/web_v1/src/pages/projects/project-file-grid.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-file-grid.tsx
rename to apps/web_v1/src/pages/projects/project-file-grid.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-new-channel.tsx b/apps/web_v1/src/pages/projects/project-new-channel.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-new-channel.tsx
rename to apps/web_v1/src/pages/projects/project-new-channel.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-notes.tsx b/apps/web_v1/src/pages/projects/project-notes.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-notes.tsx
rename to apps/web_v1/src/pages/projects/project-notes.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-overview.tsx b/apps/web_v1/src/pages/projects/project-overview.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-overview.tsx
rename to apps/web_v1/src/pages/projects/project-overview.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-rail.tsx b/apps/web_v1/src/pages/projects/project-rail.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-rail.tsx
rename to apps/web_v1/src/pages/projects/project-rail.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-sidebar.tsx b/apps/web_v1/src/pages/projects/project-sidebar.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-sidebar.tsx
rename to apps/web_v1/src/pages/projects/project-sidebar.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-statusbar.tsx b/apps/web_v1/src/pages/projects/project-statusbar.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-statusbar.tsx
rename to apps/web_v1/src/pages/projects/project-statusbar.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-task-edit-modal.tsx b/apps/web_v1/src/pages/projects/project-task-edit-modal.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-task-edit-modal.tsx
rename to apps/web_v1/src/pages/projects/project-task-edit-modal.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-tasks.tsx b/apps/web_v1/src/pages/projects/project-tasks.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-tasks.tsx
rename to apps/web_v1/src/pages/projects/project-tasks.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-topbar.tsx b/apps/web_v1/src/pages/projects/project-topbar.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-topbar.tsx
rename to apps/web_v1/src/pages/projects/project-topbar.tsx
diff --git a/apps/senlinai-acro-react/src/pages/projects/project-types.ts b/apps/web_v1/src/pages/projects/project-types.ts
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/projects/project-types.ts
rename to apps/web_v1/src/pages/projects/project-types.ts
diff --git a/apps/senlinai-acro-react/src/pages/workspace-body.tsx b/apps/web_v1/src/pages/workspace-body.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/workspace-body.tsx
rename to apps/web_v1/src/pages/workspace-body.tsx
diff --git a/apps/senlinai-acro-react/src/pages/workspace-explore.tsx b/apps/web_v1/src/pages/workspace-explore.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/workspace-explore.tsx
rename to apps/web_v1/src/pages/workspace-explore.tsx
diff --git a/apps/senlinai-acro-react/src/pages/workspace-home.tsx b/apps/web_v1/src/pages/workspace-home.tsx
similarity index 100%
rename from apps/senlinai-acro-react/src/pages/workspace-home.tsx
rename to apps/web_v1/src/pages/workspace-home.tsx
diff --git a/apps/senlinai-acro-react/tsconfig.app.json b/apps/web_v1/tsconfig.app.json
similarity index 100%
rename from apps/senlinai-acro-react/tsconfig.app.json
rename to apps/web_v1/tsconfig.app.json
diff --git a/apps/senlinai-acro-react/tsconfig.json b/apps/web_v1/tsconfig.json
similarity index 100%
rename from apps/senlinai-acro-react/tsconfig.json
rename to apps/web_v1/tsconfig.json
diff --git a/apps/senlinai-acro-react/tsconfig.node.json b/apps/web_v1/tsconfig.node.json
similarity index 100%
rename from apps/senlinai-acro-react/tsconfig.node.json
rename to apps/web_v1/tsconfig.node.json
diff --git a/apps/senlinai-acro-react/vite.config.ts b/apps/web_v1/vite.config.ts
similarity index 100%
rename from apps/senlinai-acro-react/vite.config.ts
rename to apps/web_v1/vite.config.ts
diff --git a/docs/mvp-verification.md b/docs/mvp-verification.md
index 4e2a464..8ad1e9c 100644
--- a/docs/mvp-verification.md
+++ b/docs/mvp-verification.md
@@ -26,12 +26,12 @@ Expected: `TestPostgresPing` passes.
## Web
-The primary frontend is the React + Arco Design client under `apps/senlinai-acro-react`.
+The primary frontend is the React + Arco Design client under `apps/web_v1`.
Run:
```powershell
-Set-Location apps/senlinai-acro-react
+Set-Location apps/web_v1
node scripts/visual-check.mjs
npm run build
npm run lint
@@ -44,7 +44,7 @@ Expected: visual smoke checks, production build, and lint pass.
Run:
```powershell
-Set-Location apps/senlinai-acro-react
+Set-Location apps/web_v1
npm run build
Set-Location ../desktop
npm run build
@@ -70,9 +70,9 @@ Current machine status:
Last audited: 2026-07-18.
- `backend`: `go test ./... -v` passed.
-- `apps/senlinai-acro-react`: `node scripts/visual-check.mjs` passed.
-- `apps/senlinai-acro-react`: `npm run build` passed.
-- `apps/senlinai-acro-react`: `npm run lint` passed.
+- `apps/web_v1`: `node scripts/visual-check.mjs` passed.
+- `apps/web_v1`: `npm run build` passed.
+- `apps/web_v1`: `npm run lint` passed.
- `apps/desktop`: `npx tauri build --no-bundle --verbose` passed and produced the desktop executable.
- `apps/desktop`: installer packaging is still blocked by Tauri CLI bundling timeout on the current machine.
diff --git a/scripts/build-web.sh b/scripts/build-web.sh
index 3ad2a6b..e3929ec 100755
--- a/scripts/build-web.sh
+++ b/scripts/build-web.sh
@@ -3,8 +3,8 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
-cd "$ROOT_DIR/apps/web"
+cd "$ROOT_DIR/apps/web_v1"
npm run build
-echo "Web build output: $ROOT_DIR/apps/web/dist"
+echo "Web build output: $ROOT_DIR/apps/web_v1/dist"
diff --git a/scripts/dev-all.sh b/scripts/dev-all.sh
index bda211e..73e1cac 100755
--- a/scripts/dev-all.sh
+++ b/scripts/dev-all.sh
@@ -21,9 +21,9 @@ echo "Starting backend API..."
) &
BACKEND_PID=$!
-echo "Starting Svelte web client..."
+echo "Starting Web client..."
(
- cd "$ROOT_DIR/apps/web"
+ cd "$ROOT_DIR/apps/web_v1"
npm run dev
) &
WEB_PID=$!