diff --git a/package.json b/package.json index 0594cf6..72bc879 100644 --- a/package.json +++ b/package.json @@ -1,60 +1,35 @@ { "name": "ai-terminal-assistant", "version": "1.0.0", + "private": true, "description": "A terminal-based AI coding assistant powered by Claude", - "main": "dist/index.js", - "bin": { - "ai-assist": "./dist/index.js" - }, "type": "module", "scripts": { - "build": "tsc && mkdir -p dist/tools/descriptions && cp -r src/tools/descriptions/* dist/tools/descriptions/", - "start": "node dist/index.js", - "dev": "tsx src/index.ts", - "lint": "eslint src/**/*.ts", - "test": "vitest run", - "test:watch": "vitest", - "test:coverage": "vitest run --coverage" + "build": "pnpm -r build", + "dev": "pnpm -r --parallel dev", + "test": "pnpm -r test", + "test:coverage": "pnpm -r test:coverage", + "lint": "pnpm -r lint", + "clean": "pnpm -r exec rm -rf dist node_modules", + "server:start": "pnpm --filter @ai-assistant/server start", + "server:dev": "pnpm --filter @ai-assistant/server start:dev" }, "keywords": [ "ai", "cli", "assistant", "claude", - "terminal" + "terminal", + "monorepo" ], "author": "", "license": "MIT", - "dependencies": { - "@ai-sdk/anthropic": "^2.0.54", - "@ai-sdk/deepseek": "^1.0.31", - "@ai-sdk/openai": "^2.0.80", - "@tavily/core": "^0.6.0", - "ai": "^5.0.108", - "chalk": "^5.3.0", - "commander": "^12.1.0", - "inquirer": "^12.0.0", - "js-yaml": "^4.1.1", - "minimatch": "^10.1.1", - "ora": "^8.1.0", - "qwen-ai-provider-v5": "^1.0.2", - "simple-git": "^3.30.0", - "tree-sitter-bash": "^0.25.1", - "uuid": "^13.0.0", - "vscode-jsonrpc": "^8.2.1", - "vscode-languageserver-protocol": "^3.17.5", - "web-tree-sitter": "^0.25.10", - "yaml": "^2.8.2", - "zod": "^4.1.13" - }, "devDependencies": { - "@types/js-yaml": "^4.0.9", - "@types/json-schema": "^7.0.15", - "@types/node": "^22.0.0", - "@types/uuid": "^10.0.0", - "@vitest/coverage-v8": "^4.0.15", - "tsx": "^4.19.0", - "typescript": "^5.6.0", - "vitest": "^4.0.15" - } + "typescript": "^5.6.0" + }, + "engines": { + "node": ">=18.0.0", + "pnpm": ">=8.0.0" + }, + "packageManager": "pnpm@9.0.0" } diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 0000000..6ab9076 --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,77 @@ +{ + "name": "@ai-assistant/core", + "version": "1.0.0", + "description": "Core engine for AI terminal assistant - Agent, Tools, LSP, Checkpoint", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./agent": { + "types": "./dist/core/agent.d.ts", + "import": "./dist/core/agent.js" + }, + "./tools": { + "types": "./dist/tools/index.d.ts", + "import": "./dist/tools/index.js" + }, + "./editors": { + "types": "./dist/editors/index.d.ts", + "import": "./dist/editors/index.js" + }, + "./lsp": { + "types": "./dist/lsp/index.d.ts", + "import": "./dist/lsp/index.js" + }, + "./checkpoint": { + "types": "./dist/checkpoint/index.d.ts", + "import": "./dist/checkpoint/index.js" + }, + "./hooks": { + "types": "./dist/hooks/index.d.ts", + "import": "./dist/hooks/index.js" + }, + "./types": { + "types": "./dist/types/index.d.ts", + "import": "./dist/types/index.js" + } + }, + "scripts": { + "build": "tsc && cp -r src/tools/descriptions dist/tools/", + "dev": "tsc --watch", + "test": "vitest run", + "test:watch": "vitest", + "test:coverage": "vitest run --coverage" + }, + "dependencies": { + "@ai-sdk/anthropic": "^2.0.54", + "@ai-sdk/deepseek": "^1.0.31", + "@ai-sdk/openai": "^2.0.80", + "@tavily/core": "^0.6.0", + "ai": "^5.0.108", + "chalk": "^5.3.0", + "js-yaml": "^4.1.1", + "minimatch": "^10.1.1", + "qwen-ai-provider-v5": "^1.0.2", + "simple-git": "^3.30.0", + "tree-sitter-bash": "^0.25.1", + "uuid": "^13.0.0", + "vscode-jsonrpc": "^8.2.1", + "vscode-languageserver-protocol": "^3.17.5", + "web-tree-sitter": "^0.25.10", + "yaml": "^2.8.2", + "zod": "^4.1.13" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/json-schema": "^7.0.15", + "@types/node": "^22.0.0", + "@types/uuid": "^10.0.0", + "@vitest/coverage-v8": "^4.0.15", + "typescript": "^5.6.0", + "vitest": "^4.0.15" + } +} diff --git a/src/agent/config-loader.ts b/packages/core/src/agent/config-loader.ts similarity index 100% rename from src/agent/config-loader.ts rename to packages/core/src/agent/config-loader.ts diff --git a/src/agent/executor.ts b/packages/core/src/agent/executor.ts similarity index 100% rename from src/agent/executor.ts rename to packages/core/src/agent/executor.ts diff --git a/src/agent/index.ts b/packages/core/src/agent/index.ts similarity index 100% rename from src/agent/index.ts rename to packages/core/src/agent/index.ts diff --git a/src/agent/manager.ts b/packages/core/src/agent/manager.ts similarity index 100% rename from src/agent/manager.ts rename to packages/core/src/agent/manager.ts diff --git a/src/agent/permission-merger.ts b/packages/core/src/agent/permission-merger.ts similarity index 100% rename from src/agent/permission-merger.ts rename to packages/core/src/agent/permission-merger.ts diff --git a/src/agent/presets/build.ts b/packages/core/src/agent/presets/build.ts similarity index 100% rename from src/agent/presets/build.ts rename to packages/core/src/agent/presets/build.ts diff --git a/src/agent/presets/code-reviewer.ts b/packages/core/src/agent/presets/code-reviewer.ts similarity index 100% rename from src/agent/presets/code-reviewer.ts rename to packages/core/src/agent/presets/code-reviewer.ts diff --git a/src/agent/presets/explore.ts b/packages/core/src/agent/presets/explore.ts similarity index 100% rename from src/agent/presets/explore.ts rename to packages/core/src/agent/presets/explore.ts diff --git a/src/agent/presets/general.ts b/packages/core/src/agent/presets/general.ts similarity index 100% rename from src/agent/presets/general.ts rename to packages/core/src/agent/presets/general.ts diff --git a/src/agent/presets/index.ts b/packages/core/src/agent/presets/index.ts similarity index 100% rename from src/agent/presets/index.ts rename to packages/core/src/agent/presets/index.ts diff --git a/src/agent/presets/plan.ts b/packages/core/src/agent/presets/plan.ts similarity index 100% rename from src/agent/presets/plan.ts rename to packages/core/src/agent/presets/plan.ts diff --git a/src/agent/presets/vision.ts b/packages/core/src/agent/presets/vision.ts similarity index 100% rename from src/agent/presets/vision.ts rename to packages/core/src/agent/presets/vision.ts diff --git a/src/agent/registry.ts b/packages/core/src/agent/registry.ts similarity index 100% rename from src/agent/registry.ts rename to packages/core/src/agent/registry.ts diff --git a/src/agent/types.ts b/packages/core/src/agent/types.ts similarity index 100% rename from src/agent/types.ts rename to packages/core/src/agent/types.ts diff --git a/src/checkpoint/index.ts b/packages/core/src/checkpoint/index.ts similarity index 100% rename from src/checkpoint/index.ts rename to packages/core/src/checkpoint/index.ts diff --git a/src/checkpoint/manager.ts b/packages/core/src/checkpoint/manager.ts similarity index 100% rename from src/checkpoint/manager.ts rename to packages/core/src/checkpoint/manager.ts diff --git a/src/checkpoint/shadow-git.ts b/packages/core/src/checkpoint/shadow-git.ts similarity index 100% rename from src/checkpoint/shadow-git.ts rename to packages/core/src/checkpoint/shadow-git.ts diff --git a/src/checkpoint/types.ts b/packages/core/src/checkpoint/types.ts similarity index 100% rename from src/checkpoint/types.ts rename to packages/core/src/checkpoint/types.ts diff --git a/src/commands/builtin/index.ts b/packages/core/src/commands/builtin/index.ts similarity index 100% rename from src/commands/builtin/index.ts rename to packages/core/src/commands/builtin/index.ts diff --git a/src/commands/executor.ts b/packages/core/src/commands/executor.ts similarity index 100% rename from src/commands/executor.ts rename to packages/core/src/commands/executor.ts diff --git a/src/commands/index.ts b/packages/core/src/commands/index.ts similarity index 100% rename from src/commands/index.ts rename to packages/core/src/commands/index.ts diff --git a/src/commands/loader.ts b/packages/core/src/commands/loader.ts similarity index 100% rename from src/commands/loader.ts rename to packages/core/src/commands/loader.ts diff --git a/src/commands/registry.ts b/packages/core/src/commands/registry.ts similarity index 100% rename from src/commands/registry.ts rename to packages/core/src/commands/registry.ts diff --git a/src/commands/types.ts b/packages/core/src/commands/types.ts similarity index 100% rename from src/commands/types.ts rename to packages/core/src/commands/types.ts diff --git a/src/context/compaction.ts b/packages/core/src/context/compaction.ts similarity index 100% rename from src/context/compaction.ts rename to packages/core/src/context/compaction.ts diff --git a/src/context/index.ts b/packages/core/src/context/index.ts similarity index 100% rename from src/context/index.ts rename to packages/core/src/context/index.ts diff --git a/src/context/manager.ts b/packages/core/src/context/manager.ts similarity index 100% rename from src/context/manager.ts rename to packages/core/src/context/manager.ts diff --git a/src/context/prune.ts b/packages/core/src/context/prune.ts similarity index 100% rename from src/context/prune.ts rename to packages/core/src/context/prune.ts diff --git a/src/context/token-counter.ts b/packages/core/src/context/token-counter.ts similarity index 100% rename from src/context/token-counter.ts rename to packages/core/src/context/token-counter.ts diff --git a/src/context/types.ts b/packages/core/src/context/types.ts similarity index 100% rename from src/context/types.ts rename to packages/core/src/context/types.ts diff --git a/src/core/agent.ts b/packages/core/src/core/agent.ts similarity index 100% rename from src/core/agent.ts rename to packages/core/src/core/agent.ts diff --git a/src/core/providers.ts b/packages/core/src/core/providers.ts similarity index 100% rename from src/core/providers.ts rename to packages/core/src/core/providers.ts diff --git a/src/editors/applier.ts b/packages/core/src/editors/applier.ts similarity index 100% rename from src/editors/applier.ts rename to packages/core/src/editors/applier.ts diff --git a/src/editors/index.ts b/packages/core/src/editors/index.ts similarity index 100% rename from src/editors/index.ts rename to packages/core/src/editors/index.ts diff --git a/src/editors/parsers.ts b/packages/core/src/editors/parsers.ts similarity index 100% rename from src/editors/parsers.ts rename to packages/core/src/editors/parsers.ts diff --git a/src/editors/types.ts b/packages/core/src/editors/types.ts similarity index 100% rename from src/editors/types.ts rename to packages/core/src/editors/types.ts diff --git a/src/editors/validator.ts b/packages/core/src/editors/validator.ts similarity index 100% rename from src/editors/validator.ts rename to packages/core/src/editors/validator.ts diff --git a/src/git/auto-commit.ts b/packages/core/src/git/auto-commit.ts similarity index 100% rename from src/git/auto-commit.ts rename to packages/core/src/git/auto-commit.ts diff --git a/src/git/index.ts b/packages/core/src/git/index.ts similarity index 100% rename from src/git/index.ts rename to packages/core/src/git/index.ts diff --git a/src/git/manager.ts b/packages/core/src/git/manager.ts similarity index 100% rename from src/git/manager.ts rename to packages/core/src/git/manager.ts diff --git a/src/git/message-generator.ts b/packages/core/src/git/message-generator.ts similarity index 100% rename from src/git/message-generator.ts rename to packages/core/src/git/message-generator.ts diff --git a/src/git/repo.ts b/packages/core/src/git/repo.ts similarity index 100% rename from src/git/repo.ts rename to packages/core/src/git/repo.ts diff --git a/src/git/types.ts b/packages/core/src/git/types.ts similarity index 100% rename from src/git/types.ts rename to packages/core/src/git/types.ts diff --git a/src/git/undo-manager.ts b/packages/core/src/git/undo-manager.ts similarity index 100% rename from src/git/undo-manager.ts rename to packages/core/src/git/undo-manager.ts diff --git a/src/hooks/config-loader.ts b/packages/core/src/hooks/config-loader.ts similarity index 100% rename from src/hooks/config-loader.ts rename to packages/core/src/hooks/config-loader.ts diff --git a/src/hooks/index.ts b/packages/core/src/hooks/index.ts similarity index 100% rename from src/hooks/index.ts rename to packages/core/src/hooks/index.ts diff --git a/src/hooks/manager.ts b/packages/core/src/hooks/manager.ts similarity index 100% rename from src/hooks/manager.ts rename to packages/core/src/hooks/manager.ts diff --git a/src/hooks/types.ts b/packages/core/src/hooks/types.ts similarity index 100% rename from src/hooks/types.ts rename to packages/core/src/hooks/types.ts diff --git a/src/index.ts b/packages/core/src/index.ts similarity index 100% rename from src/index.ts rename to packages/core/src/index.ts diff --git a/src/lsp/cli.ts b/packages/core/src/lsp/cli.ts similarity index 100% rename from src/lsp/cli.ts rename to packages/core/src/lsp/cli.ts diff --git a/src/lsp/client.ts b/packages/core/src/lsp/client.ts similarity index 100% rename from src/lsp/client.ts rename to packages/core/src/lsp/client.ts diff --git a/src/lsp/index.ts b/packages/core/src/lsp/index.ts similarity index 100% rename from src/lsp/index.ts rename to packages/core/src/lsp/index.ts diff --git a/src/lsp/language.ts b/packages/core/src/lsp/language.ts similarity index 100% rename from src/lsp/language.ts rename to packages/core/src/lsp/language.ts diff --git a/src/lsp/server.ts b/packages/core/src/lsp/server.ts similarity index 100% rename from src/lsp/server.ts rename to packages/core/src/lsp/server.ts diff --git a/src/mcp/client.ts b/packages/core/src/mcp/client.ts similarity index 100% rename from src/mcp/client.ts rename to packages/core/src/mcp/client.ts diff --git a/src/mcp/config.ts b/packages/core/src/mcp/config.ts similarity index 100% rename from src/mcp/config.ts rename to packages/core/src/mcp/config.ts diff --git a/src/mcp/index.ts b/packages/core/src/mcp/index.ts similarity index 100% rename from src/mcp/index.ts rename to packages/core/src/mcp/index.ts diff --git a/src/mcp/manager.ts b/packages/core/src/mcp/manager.ts similarity index 100% rename from src/mcp/manager.ts rename to packages/core/src/mcp/manager.ts diff --git a/src/mcp/tool-adapter.ts b/packages/core/src/mcp/tool-adapter.ts similarity index 100% rename from src/mcp/tool-adapter.ts rename to packages/core/src/mcp/tool-adapter.ts diff --git a/src/mcp/transports/index.ts b/packages/core/src/mcp/transports/index.ts similarity index 100% rename from src/mcp/transports/index.ts rename to packages/core/src/mcp/transports/index.ts diff --git a/src/mcp/transports/stdio.ts b/packages/core/src/mcp/transports/stdio.ts similarity index 100% rename from src/mcp/transports/stdio.ts rename to packages/core/src/mcp/transports/stdio.ts diff --git a/src/mcp/types.ts b/packages/core/src/mcp/types.ts similarity index 100% rename from src/mcp/types.ts rename to packages/core/src/mcp/types.ts diff --git a/src/permission/bash-parser.ts b/packages/core/src/permission/bash-parser.ts similarity index 100% rename from src/permission/bash-parser.ts rename to packages/core/src/permission/bash-parser.ts diff --git a/src/permission/checkers/base.ts b/packages/core/src/permission/checkers/base.ts similarity index 100% rename from src/permission/checkers/base.ts rename to packages/core/src/permission/checkers/base.ts diff --git a/src/permission/checkers/bash.ts b/packages/core/src/permission/checkers/bash.ts similarity index 100% rename from src/permission/checkers/bash.ts rename to packages/core/src/permission/checkers/bash.ts diff --git a/src/permission/checkers/file.ts b/packages/core/src/permission/checkers/file.ts similarity index 100% rename from src/permission/checkers/file.ts rename to packages/core/src/permission/checkers/file.ts diff --git a/src/permission/checkers/git.ts b/packages/core/src/permission/checkers/git.ts similarity index 100% rename from src/permission/checkers/git.ts rename to packages/core/src/permission/checkers/git.ts diff --git a/src/permission/checkers/index.ts b/packages/core/src/permission/checkers/index.ts similarity index 100% rename from src/permission/checkers/index.ts rename to packages/core/src/permission/checkers/index.ts diff --git a/src/permission/checkers/web.ts b/packages/core/src/permission/checkers/web.ts similarity index 100% rename from src/permission/checkers/web.ts rename to packages/core/src/permission/checkers/web.ts diff --git a/src/permission/file-prompt.ts b/packages/core/src/permission/file-prompt.ts similarity index 100% rename from src/permission/file-prompt.ts rename to packages/core/src/permission/file-prompt.ts diff --git a/src/permission/index.ts b/packages/core/src/permission/index.ts similarity index 100% rename from src/permission/index.ts rename to packages/core/src/permission/index.ts diff --git a/src/permission/manager.ts b/packages/core/src/permission/manager.ts similarity index 100% rename from src/permission/manager.ts rename to packages/core/src/permission/manager.ts diff --git a/src/permission/prompt.ts b/packages/core/src/permission/prompt.ts similarity index 100% rename from src/permission/prompt.ts rename to packages/core/src/permission/prompt.ts diff --git a/src/permission/types.ts b/packages/core/src/permission/types.ts similarity index 100% rename from src/permission/types.ts rename to packages/core/src/permission/types.ts diff --git a/src/permission/wildcard.ts b/packages/core/src/permission/wildcard.ts similarity index 100% rename from src/permission/wildcard.ts rename to packages/core/src/permission/wildcard.ts diff --git a/src/repomap/cache/disk-cache.ts b/packages/core/src/repomap/cache/disk-cache.ts similarity index 100% rename from src/repomap/cache/disk-cache.ts rename to packages/core/src/repomap/cache/disk-cache.ts diff --git a/src/repomap/cache/index.ts b/packages/core/src/repomap/cache/index.ts similarity index 100% rename from src/repomap/cache/index.ts rename to packages/core/src/repomap/cache/index.ts diff --git a/src/repomap/index.ts b/packages/core/src/repomap/index.ts similarity index 100% rename from src/repomap/index.ts rename to packages/core/src/repomap/index.ts diff --git a/src/repomap/ranking/graph.ts b/packages/core/src/repomap/ranking/graph.ts similarity index 100% rename from src/repomap/ranking/graph.ts rename to packages/core/src/repomap/ranking/graph.ts diff --git a/src/repomap/ranking/index.ts b/packages/core/src/repomap/ranking/index.ts similarity index 100% rename from src/repomap/ranking/index.ts rename to packages/core/src/repomap/ranking/index.ts diff --git a/src/repomap/ranking/pagerank.ts b/packages/core/src/repomap/ranking/pagerank.ts similarity index 100% rename from src/repomap/ranking/pagerank.ts rename to packages/core/src/repomap/ranking/pagerank.ts diff --git a/src/repomap/repomap.ts b/packages/core/src/repomap/repomap.ts similarity index 100% rename from src/repomap/repomap.ts rename to packages/core/src/repomap/repomap.ts diff --git a/src/repomap/tags/extractor.ts b/packages/core/src/repomap/tags/extractor.ts similarity index 100% rename from src/repomap/tags/extractor.ts rename to packages/core/src/repomap/tags/extractor.ts diff --git a/src/repomap/tags/index.ts b/packages/core/src/repomap/tags/index.ts similarity index 100% rename from src/repomap/tags/index.ts rename to packages/core/src/repomap/tags/index.ts diff --git a/src/repomap/tags/queries/javascript-tags.scm b/packages/core/src/repomap/tags/queries/javascript-tags.scm similarity index 100% rename from src/repomap/tags/queries/javascript-tags.scm rename to packages/core/src/repomap/tags/queries/javascript-tags.scm diff --git a/src/repomap/tags/queries/python-tags.scm b/packages/core/src/repomap/tags/queries/python-tags.scm similarity index 100% rename from src/repomap/tags/queries/python-tags.scm rename to packages/core/src/repomap/tags/queries/python-tags.scm diff --git a/src/repomap/tags/queries/typescript-tags.scm b/packages/core/src/repomap/tags/queries/typescript-tags.scm similarity index 100% rename from src/repomap/tags/queries/typescript-tags.scm rename to packages/core/src/repomap/tags/queries/typescript-tags.scm diff --git a/src/repomap/types.ts b/packages/core/src/repomap/types.ts similarity index 100% rename from src/repomap/types.ts rename to packages/core/src/repomap/types.ts diff --git a/src/session/index.ts b/packages/core/src/session/index.ts similarity index 100% rename from src/session/index.ts rename to packages/core/src/session/index.ts diff --git a/src/session/manager.ts b/packages/core/src/session/manager.ts similarity index 100% rename from src/session/manager.ts rename to packages/core/src/session/manager.ts diff --git a/src/session/storage.ts b/packages/core/src/session/storage.ts similarity index 100% rename from src/session/storage.ts rename to packages/core/src/session/storage.ts diff --git a/src/session/types.ts b/packages/core/src/session/types.ts similarity index 100% rename from src/session/types.ts rename to packages/core/src/session/types.ts diff --git a/src/skills/builtin/index.ts b/packages/core/src/skills/builtin/index.ts similarity index 100% rename from src/skills/builtin/index.ts rename to packages/core/src/skills/builtin/index.ts diff --git a/src/skills/index.ts b/packages/core/src/skills/index.ts similarity index 100% rename from src/skills/index.ts rename to packages/core/src/skills/index.ts diff --git a/src/skills/loader.ts b/packages/core/src/skills/loader.ts similarity index 100% rename from src/skills/loader.ts rename to packages/core/src/skills/loader.ts diff --git a/src/skills/registry.ts b/packages/core/src/skills/registry.ts similarity index 100% rename from src/skills/registry.ts rename to packages/core/src/skills/registry.ts diff --git a/src/skills/types.ts b/packages/core/src/skills/types.ts similarity index 100% rename from src/skills/types.ts rename to packages/core/src/skills/types.ts diff --git a/src/tools/checkpoint/checkpoint_create.ts b/packages/core/src/tools/checkpoint/checkpoint_create.ts similarity index 100% rename from src/tools/checkpoint/checkpoint_create.ts rename to packages/core/src/tools/checkpoint/checkpoint_create.ts diff --git a/src/tools/checkpoint/checkpoint_diff.ts b/packages/core/src/tools/checkpoint/checkpoint_diff.ts similarity index 100% rename from src/tools/checkpoint/checkpoint_diff.ts rename to packages/core/src/tools/checkpoint/checkpoint_diff.ts diff --git a/src/tools/checkpoint/checkpoint_list.ts b/packages/core/src/tools/checkpoint/checkpoint_list.ts similarity index 100% rename from src/tools/checkpoint/checkpoint_list.ts rename to packages/core/src/tools/checkpoint/checkpoint_list.ts diff --git a/src/tools/checkpoint/checkpoint_restore.ts b/packages/core/src/tools/checkpoint/checkpoint_restore.ts similarity index 100% rename from src/tools/checkpoint/checkpoint_restore.ts rename to packages/core/src/tools/checkpoint/checkpoint_restore.ts diff --git a/src/tools/checkpoint/index.ts b/packages/core/src/tools/checkpoint/index.ts similarity index 100% rename from src/tools/checkpoint/index.ts rename to packages/core/src/tools/checkpoint/index.ts diff --git a/src/tools/checkpoint/undo.ts b/packages/core/src/tools/checkpoint/undo.ts similarity index 100% rename from src/tools/checkpoint/undo.ts rename to packages/core/src/tools/checkpoint/undo.ts diff --git a/src/tools/descriptions/checkpoint_create.txt b/packages/core/src/tools/descriptions/checkpoint_create.txt similarity index 100% rename from src/tools/descriptions/checkpoint_create.txt rename to packages/core/src/tools/descriptions/checkpoint_create.txt diff --git a/src/tools/descriptions/checkpoint_diff.txt b/packages/core/src/tools/descriptions/checkpoint_diff.txt similarity index 100% rename from src/tools/descriptions/checkpoint_diff.txt rename to packages/core/src/tools/descriptions/checkpoint_diff.txt diff --git a/src/tools/descriptions/checkpoint_list.txt b/packages/core/src/tools/descriptions/checkpoint_list.txt similarity index 100% rename from src/tools/descriptions/checkpoint_list.txt rename to packages/core/src/tools/descriptions/checkpoint_list.txt diff --git a/src/tools/descriptions/checkpoint_restore.txt b/packages/core/src/tools/descriptions/checkpoint_restore.txt similarity index 100% rename from src/tools/descriptions/checkpoint_restore.txt rename to packages/core/src/tools/descriptions/checkpoint_restore.txt diff --git a/src/tools/descriptions/filesystem/copy_file.txt b/packages/core/src/tools/descriptions/filesystem/copy_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/copy_file.txt rename to packages/core/src/tools/descriptions/filesystem/copy_file.txt diff --git a/src/tools/descriptions/filesystem/create_directory.txt b/packages/core/src/tools/descriptions/filesystem/create_directory.txt similarity index 100% rename from src/tools/descriptions/filesystem/create_directory.txt rename to packages/core/src/tools/descriptions/filesystem/create_directory.txt diff --git a/src/tools/descriptions/filesystem/delete_file.txt b/packages/core/src/tools/descriptions/filesystem/delete_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/delete_file.txt rename to packages/core/src/tools/descriptions/filesystem/delete_file.txt diff --git a/src/tools/descriptions/filesystem/edit_file.txt b/packages/core/src/tools/descriptions/filesystem/edit_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/edit_file.txt rename to packages/core/src/tools/descriptions/filesystem/edit_file.txt diff --git a/src/tools/descriptions/filesystem/get_file_info.txt b/packages/core/src/tools/descriptions/filesystem/get_file_info.txt similarity index 100% rename from src/tools/descriptions/filesystem/get_file_info.txt rename to packages/core/src/tools/descriptions/filesystem/get_file_info.txt diff --git a/src/tools/descriptions/filesystem/grep_content.txt b/packages/core/src/tools/descriptions/filesystem/grep_content.txt similarity index 100% rename from src/tools/descriptions/filesystem/grep_content.txt rename to packages/core/src/tools/descriptions/filesystem/grep_content.txt diff --git a/src/tools/descriptions/filesystem/list_directory.txt b/packages/core/src/tools/descriptions/filesystem/list_directory.txt similarity index 100% rename from src/tools/descriptions/filesystem/list_directory.txt rename to packages/core/src/tools/descriptions/filesystem/list_directory.txt diff --git a/src/tools/descriptions/filesystem/move_file.txt b/packages/core/src/tools/descriptions/filesystem/move_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/move_file.txt rename to packages/core/src/tools/descriptions/filesystem/move_file.txt diff --git a/src/tools/descriptions/filesystem/multi_edit.txt b/packages/core/src/tools/descriptions/filesystem/multi_edit.txt similarity index 100% rename from src/tools/descriptions/filesystem/multi_edit.txt rename to packages/core/src/tools/descriptions/filesystem/multi_edit.txt diff --git a/src/tools/descriptions/filesystem/read_file.txt b/packages/core/src/tools/descriptions/filesystem/read_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/read_file.txt rename to packages/core/src/tools/descriptions/filesystem/read_file.txt diff --git a/src/tools/descriptions/filesystem/search_files.txt b/packages/core/src/tools/descriptions/filesystem/search_files.txt similarity index 100% rename from src/tools/descriptions/filesystem/search_files.txt rename to packages/core/src/tools/descriptions/filesystem/search_files.txt diff --git a/src/tools/descriptions/filesystem/write_file.txt b/packages/core/src/tools/descriptions/filesystem/write_file.txt similarity index 100% rename from src/tools/descriptions/filesystem/write_file.txt rename to packages/core/src/tools/descriptions/filesystem/write_file.txt diff --git a/src/tools/descriptions/git/git_add.txt b/packages/core/src/tools/descriptions/git/git_add.txt similarity index 100% rename from src/tools/descriptions/git/git_add.txt rename to packages/core/src/tools/descriptions/git/git_add.txt diff --git a/src/tools/descriptions/git/git_branch.txt b/packages/core/src/tools/descriptions/git/git_branch.txt similarity index 100% rename from src/tools/descriptions/git/git_branch.txt rename to packages/core/src/tools/descriptions/git/git_branch.txt diff --git a/src/tools/descriptions/git/git_checkout.txt b/packages/core/src/tools/descriptions/git/git_checkout.txt similarity index 100% rename from src/tools/descriptions/git/git_checkout.txt rename to packages/core/src/tools/descriptions/git/git_checkout.txt diff --git a/src/tools/descriptions/git/git_commit.txt b/packages/core/src/tools/descriptions/git/git_commit.txt similarity index 100% rename from src/tools/descriptions/git/git_commit.txt rename to packages/core/src/tools/descriptions/git/git_commit.txt diff --git a/src/tools/descriptions/git/git_diff.txt b/packages/core/src/tools/descriptions/git/git_diff.txt similarity index 100% rename from src/tools/descriptions/git/git_diff.txt rename to packages/core/src/tools/descriptions/git/git_diff.txt diff --git a/src/tools/descriptions/git/git_log.txt b/packages/core/src/tools/descriptions/git/git_log.txt similarity index 100% rename from src/tools/descriptions/git/git_log.txt rename to packages/core/src/tools/descriptions/git/git_log.txt diff --git a/src/tools/descriptions/git/git_pull.txt b/packages/core/src/tools/descriptions/git/git_pull.txt similarity index 100% rename from src/tools/descriptions/git/git_pull.txt rename to packages/core/src/tools/descriptions/git/git_pull.txt diff --git a/src/tools/descriptions/git/git_push.txt b/packages/core/src/tools/descriptions/git/git_push.txt similarity index 100% rename from src/tools/descriptions/git/git_push.txt rename to packages/core/src/tools/descriptions/git/git_push.txt diff --git a/src/tools/descriptions/git/git_stash.txt b/packages/core/src/tools/descriptions/git/git_stash.txt similarity index 100% rename from src/tools/descriptions/git/git_stash.txt rename to packages/core/src/tools/descriptions/git/git_stash.txt diff --git a/src/tools/descriptions/git/git_status.txt b/packages/core/src/tools/descriptions/git/git_status.txt similarity index 100% rename from src/tools/descriptions/git/git_status.txt rename to packages/core/src/tools/descriptions/git/git_status.txt diff --git a/src/tools/descriptions/repo_map.txt b/packages/core/src/tools/descriptions/repo_map.txt similarity index 100% rename from src/tools/descriptions/repo_map.txt rename to packages/core/src/tools/descriptions/repo_map.txt diff --git a/src/tools/descriptions/shell/bash.txt b/packages/core/src/tools/descriptions/shell/bash.txt similarity index 100% rename from src/tools/descriptions/shell/bash.txt rename to packages/core/src/tools/descriptions/shell/bash.txt diff --git a/src/tools/descriptions/todo/todo_read.txt b/packages/core/src/tools/descriptions/todo/todo_read.txt similarity index 100% rename from src/tools/descriptions/todo/todo_read.txt rename to packages/core/src/tools/descriptions/todo/todo_read.txt diff --git a/src/tools/descriptions/todo/todo_write.txt b/packages/core/src/tools/descriptions/todo/todo_write.txt similarity index 100% rename from src/tools/descriptions/todo/todo_write.txt rename to packages/core/src/tools/descriptions/todo/todo_write.txt diff --git a/src/tools/descriptions/undo.txt b/packages/core/src/tools/descriptions/undo.txt similarity index 100% rename from src/tools/descriptions/undo.txt rename to packages/core/src/tools/descriptions/undo.txt diff --git a/src/tools/descriptions/web/web_extract.txt b/packages/core/src/tools/descriptions/web/web_extract.txt similarity index 100% rename from src/tools/descriptions/web/web_extract.txt rename to packages/core/src/tools/descriptions/web/web_extract.txt diff --git a/src/tools/descriptions/web/web_search.txt b/packages/core/src/tools/descriptions/web/web_search.txt similarity index 100% rename from src/tools/descriptions/web/web_search.txt rename to packages/core/src/tools/descriptions/web/web_search.txt diff --git a/src/tools/filesystem/copy_file.ts b/packages/core/src/tools/filesystem/copy_file.ts similarity index 100% rename from src/tools/filesystem/copy_file.ts rename to packages/core/src/tools/filesystem/copy_file.ts diff --git a/src/tools/filesystem/create_directory.ts b/packages/core/src/tools/filesystem/create_directory.ts similarity index 100% rename from src/tools/filesystem/create_directory.ts rename to packages/core/src/tools/filesystem/create_directory.ts diff --git a/src/tools/filesystem/delete_file.ts b/packages/core/src/tools/filesystem/delete_file.ts similarity index 100% rename from src/tools/filesystem/delete_file.ts rename to packages/core/src/tools/filesystem/delete_file.ts diff --git a/src/tools/filesystem/edit_file.ts b/packages/core/src/tools/filesystem/edit_file.ts similarity index 100% rename from src/tools/filesystem/edit_file.ts rename to packages/core/src/tools/filesystem/edit_file.ts diff --git a/src/tools/filesystem/get_file_info.ts b/packages/core/src/tools/filesystem/get_file_info.ts similarity index 100% rename from src/tools/filesystem/get_file_info.ts rename to packages/core/src/tools/filesystem/get_file_info.ts diff --git a/src/tools/filesystem/grep_content.ts b/packages/core/src/tools/filesystem/grep_content.ts similarity index 100% rename from src/tools/filesystem/grep_content.ts rename to packages/core/src/tools/filesystem/grep_content.ts diff --git a/src/tools/filesystem/index.ts b/packages/core/src/tools/filesystem/index.ts similarity index 100% rename from src/tools/filesystem/index.ts rename to packages/core/src/tools/filesystem/index.ts diff --git a/src/tools/filesystem/list_directory.ts b/packages/core/src/tools/filesystem/list_directory.ts similarity index 100% rename from src/tools/filesystem/list_directory.ts rename to packages/core/src/tools/filesystem/list_directory.ts diff --git a/src/tools/filesystem/move_file.ts b/packages/core/src/tools/filesystem/move_file.ts similarity index 100% rename from src/tools/filesystem/move_file.ts rename to packages/core/src/tools/filesystem/move_file.ts diff --git a/src/tools/filesystem/multi_edit.ts b/packages/core/src/tools/filesystem/multi_edit.ts similarity index 100% rename from src/tools/filesystem/multi_edit.ts rename to packages/core/src/tools/filesystem/multi_edit.ts diff --git a/src/tools/filesystem/read_file.ts b/packages/core/src/tools/filesystem/read_file.ts similarity index 100% rename from src/tools/filesystem/read_file.ts rename to packages/core/src/tools/filesystem/read_file.ts diff --git a/src/tools/filesystem/search_files.ts b/packages/core/src/tools/filesystem/search_files.ts similarity index 100% rename from src/tools/filesystem/search_files.ts rename to packages/core/src/tools/filesystem/search_files.ts diff --git a/src/tools/filesystem/write_file.ts b/packages/core/src/tools/filesystem/write_file.ts similarity index 100% rename from src/tools/filesystem/write_file.ts rename to packages/core/src/tools/filesystem/write_file.ts diff --git a/src/tools/git/git_add.ts b/packages/core/src/tools/git/git_add.ts similarity index 100% rename from src/tools/git/git_add.ts rename to packages/core/src/tools/git/git_add.ts diff --git a/src/tools/git/git_branch.ts b/packages/core/src/tools/git/git_branch.ts similarity index 100% rename from src/tools/git/git_branch.ts rename to packages/core/src/tools/git/git_branch.ts diff --git a/src/tools/git/git_checkout.ts b/packages/core/src/tools/git/git_checkout.ts similarity index 100% rename from src/tools/git/git_checkout.ts rename to packages/core/src/tools/git/git_checkout.ts diff --git a/src/tools/git/git_commit.ts b/packages/core/src/tools/git/git_commit.ts similarity index 100% rename from src/tools/git/git_commit.ts rename to packages/core/src/tools/git/git_commit.ts diff --git a/src/tools/git/git_diff.ts b/packages/core/src/tools/git/git_diff.ts similarity index 100% rename from src/tools/git/git_diff.ts rename to packages/core/src/tools/git/git_diff.ts diff --git a/src/tools/git/git_log.ts b/packages/core/src/tools/git/git_log.ts similarity index 100% rename from src/tools/git/git_log.ts rename to packages/core/src/tools/git/git_log.ts diff --git a/src/tools/git/git_pull.ts b/packages/core/src/tools/git/git_pull.ts similarity index 100% rename from src/tools/git/git_pull.ts rename to packages/core/src/tools/git/git_pull.ts diff --git a/src/tools/git/git_push.ts b/packages/core/src/tools/git/git_push.ts similarity index 100% rename from src/tools/git/git_push.ts rename to packages/core/src/tools/git/git_push.ts diff --git a/src/tools/git/git_stash.ts b/packages/core/src/tools/git/git_stash.ts similarity index 100% rename from src/tools/git/git_stash.ts rename to packages/core/src/tools/git/git_stash.ts diff --git a/src/tools/git/git_status.ts b/packages/core/src/tools/git/git_status.ts similarity index 100% rename from src/tools/git/git_status.ts rename to packages/core/src/tools/git/git_status.ts diff --git a/src/tools/git/index.ts b/packages/core/src/tools/git/index.ts similarity index 100% rename from src/tools/git/index.ts rename to packages/core/src/tools/git/index.ts diff --git a/src/tools/index.ts b/packages/core/src/tools/index.ts similarity index 100% rename from src/tools/index.ts rename to packages/core/src/tools/index.ts diff --git a/src/tools/load_description.ts b/packages/core/src/tools/load_description.ts similarity index 100% rename from src/tools/load_description.ts rename to packages/core/src/tools/load_description.ts diff --git a/src/tools/registry.ts b/packages/core/src/tools/registry.ts similarity index 100% rename from src/tools/registry.ts rename to packages/core/src/tools/registry.ts diff --git a/src/tools/repomap/index.ts b/packages/core/src/tools/repomap/index.ts similarity index 100% rename from src/tools/repomap/index.ts rename to packages/core/src/tools/repomap/index.ts diff --git a/src/tools/repomap/repo_map.ts b/packages/core/src/tools/repomap/repo_map.ts similarity index 100% rename from src/tools/repomap/repo_map.ts rename to packages/core/src/tools/repomap/repo_map.ts diff --git a/src/tools/search.ts b/packages/core/src/tools/search.ts similarity index 100% rename from src/tools/search.ts rename to packages/core/src/tools/search.ts diff --git a/src/tools/shell/bash.ts b/packages/core/src/tools/shell/bash.ts similarity index 100% rename from src/tools/shell/bash.ts rename to packages/core/src/tools/shell/bash.ts diff --git a/src/tools/shell/index.ts b/packages/core/src/tools/shell/index.ts similarity index 100% rename from src/tools/shell/index.ts rename to packages/core/src/tools/shell/index.ts diff --git a/src/tools/skill/index.ts b/packages/core/src/tools/skill/index.ts similarity index 100% rename from src/tools/skill/index.ts rename to packages/core/src/tools/skill/index.ts diff --git a/src/tools/skill/skill.ts b/packages/core/src/tools/skill/skill.ts similarity index 100% rename from src/tools/skill/skill.ts rename to packages/core/src/tools/skill/skill.ts diff --git a/src/tools/skill/skill_search.ts b/packages/core/src/tools/skill/skill_search.ts similarity index 100% rename from src/tools/skill/skill_search.ts rename to packages/core/src/tools/skill/skill_search.ts diff --git a/src/tools/task/agent_output.ts b/packages/core/src/tools/task/agent_output.ts similarity index 100% rename from src/tools/task/agent_output.ts rename to packages/core/src/tools/task/agent_output.ts diff --git a/src/tools/task/index.ts b/packages/core/src/tools/task/index.ts similarity index 100% rename from src/tools/task/index.ts rename to packages/core/src/tools/task/index.ts diff --git a/src/tools/task/task.ts b/packages/core/src/tools/task/task.ts similarity index 100% rename from src/tools/task/task.ts rename to packages/core/src/tools/task/task.ts diff --git a/src/tools/todo/index.ts b/packages/core/src/tools/todo/index.ts similarity index 100% rename from src/tools/todo/index.ts rename to packages/core/src/tools/todo/index.ts diff --git a/src/tools/todo/todo-manager.ts b/packages/core/src/tools/todo/todo-manager.ts similarity index 100% rename from src/tools/todo/todo-manager.ts rename to packages/core/src/tools/todo/todo-manager.ts diff --git a/src/tools/todo/todoread.ts b/packages/core/src/tools/todo/todoread.ts similarity index 100% rename from src/tools/todo/todoread.ts rename to packages/core/src/tools/todo/todoread.ts diff --git a/src/tools/todo/todowrite.ts b/packages/core/src/tools/todo/todowrite.ts similarity index 100% rename from src/tools/todo/todowrite.ts rename to packages/core/src/tools/todo/todowrite.ts diff --git a/src/tools/tool-search.ts b/packages/core/src/tools/tool-search.ts similarity index 100% rename from src/tools/tool-search.ts rename to packages/core/src/tools/tool-search.ts diff --git a/src/tools/types.ts b/packages/core/src/tools/types.ts similarity index 100% rename from src/tools/types.ts rename to packages/core/src/tools/types.ts diff --git a/src/tools/web/index.ts b/packages/core/src/tools/web/index.ts similarity index 100% rename from src/tools/web/index.ts rename to packages/core/src/tools/web/index.ts diff --git a/src/tools/web/web_extract.ts b/packages/core/src/tools/web/web_extract.ts similarity index 100% rename from src/tools/web/web_extract.ts rename to packages/core/src/tools/web/web_extract.ts diff --git a/src/tools/web/web_search.ts b/packages/core/src/tools/web/web_search.ts similarity index 100% rename from src/tools/web/web_search.ts rename to packages/core/src/tools/web/web_search.ts diff --git a/src/types/index.ts b/packages/core/src/types/index.ts similarity index 100% rename from src/types/index.ts rename to packages/core/src/types/index.ts diff --git a/src/ui/terminal.ts b/packages/core/src/ui/terminal.ts similarity index 100% rename from src/ui/terminal.ts rename to packages/core/src/ui/terminal.ts diff --git a/src/utils/config.ts b/packages/core/src/utils/config.ts similarity index 100% rename from src/utils/config.ts rename to packages/core/src/utils/config.ts diff --git a/src/utils/diff.ts b/packages/core/src/utils/diff.ts similarity index 100% rename from src/utils/diff.ts rename to packages/core/src/utils/diff.ts diff --git a/src/utils/image.ts b/packages/core/src/utils/image.ts similarity index 100% rename from src/utils/image.ts rename to packages/core/src/utils/image.ts diff --git a/tests/checkpoint/checkpoint.test.ts b/packages/core/tests/checkpoint/checkpoint.test.ts similarity index 100% rename from tests/checkpoint/checkpoint.test.ts rename to packages/core/tests/checkpoint/checkpoint.test.ts diff --git a/tests/editors/editors.test.ts b/packages/core/tests/editors/editors.test.ts similarity index 100% rename from tests/editors/editors.test.ts rename to packages/core/tests/editors/editors.test.ts diff --git a/tests/git/git.test.ts b/packages/core/tests/git/git.test.ts similarity index 100% rename from tests/git/git.test.ts rename to packages/core/tests/git/git.test.ts diff --git a/tests/hooks/hooks.test.ts b/packages/core/tests/hooks/hooks.test.ts similarity index 100% rename from tests/hooks/hooks.test.ts rename to packages/core/tests/hooks/hooks.test.ts diff --git a/tests/repomap/repomap.test.ts b/packages/core/tests/repomap/repomap.test.ts similarity index 100% rename from tests/repomap/repomap.test.ts rename to packages/core/tests/repomap/repomap.test.ts diff --git a/tests/setup.ts b/packages/core/tests/setup.ts similarity index 100% rename from tests/setup.ts rename to packages/core/tests/setup.ts diff --git a/tests/unit/agent/config-loader.test.ts b/packages/core/tests/unit/agent/config-loader.test.ts similarity index 100% rename from tests/unit/agent/config-loader.test.ts rename to packages/core/tests/unit/agent/config-loader.test.ts diff --git a/tests/unit/agent/executor-extended.test.ts b/packages/core/tests/unit/agent/executor-extended.test.ts similarity index 100% rename from tests/unit/agent/executor-extended.test.ts rename to packages/core/tests/unit/agent/executor-extended.test.ts diff --git a/tests/unit/agent/executor.test.ts b/packages/core/tests/unit/agent/executor.test.ts similarity index 100% rename from tests/unit/agent/executor.test.ts rename to packages/core/tests/unit/agent/executor.test.ts diff --git a/tests/unit/agent/manager.test.ts b/packages/core/tests/unit/agent/manager.test.ts similarity index 100% rename from tests/unit/agent/manager.test.ts rename to packages/core/tests/unit/agent/manager.test.ts diff --git a/tests/unit/agent/permission-merger.test.ts b/packages/core/tests/unit/agent/permission-merger.test.ts similarity index 100% rename from tests/unit/agent/permission-merger.test.ts rename to packages/core/tests/unit/agent/permission-merger.test.ts diff --git a/tests/unit/agent/presets/index.test.ts b/packages/core/tests/unit/agent/presets/index.test.ts similarity index 100% rename from tests/unit/agent/presets/index.test.ts rename to packages/core/tests/unit/agent/presets/index.test.ts diff --git a/tests/unit/agent/registry.test.ts b/packages/core/tests/unit/agent/registry.test.ts similarity index 100% rename from tests/unit/agent/registry.test.ts rename to packages/core/tests/unit/agent/registry.test.ts diff --git a/tests/unit/commands/executor.test.ts b/packages/core/tests/unit/commands/executor.test.ts similarity index 100% rename from tests/unit/commands/executor.test.ts rename to packages/core/tests/unit/commands/executor.test.ts diff --git a/tests/unit/commands/loader.test.ts b/packages/core/tests/unit/commands/loader.test.ts similarity index 100% rename from tests/unit/commands/loader.test.ts rename to packages/core/tests/unit/commands/loader.test.ts diff --git a/tests/unit/commands/registry.test.ts b/packages/core/tests/unit/commands/registry.test.ts similarity index 100% rename from tests/unit/commands/registry.test.ts rename to packages/core/tests/unit/commands/registry.test.ts diff --git a/tests/unit/context/compaction.test.ts b/packages/core/tests/unit/context/compaction.test.ts similarity index 100% rename from tests/unit/context/compaction.test.ts rename to packages/core/tests/unit/context/compaction.test.ts diff --git a/tests/unit/context/manager-extended.test.ts b/packages/core/tests/unit/context/manager-extended.test.ts similarity index 100% rename from tests/unit/context/manager-extended.test.ts rename to packages/core/tests/unit/context/manager-extended.test.ts diff --git a/tests/unit/context/manager.test.ts b/packages/core/tests/unit/context/manager.test.ts similarity index 100% rename from tests/unit/context/manager.test.ts rename to packages/core/tests/unit/context/manager.test.ts diff --git a/tests/unit/context/prune.test.ts b/packages/core/tests/unit/context/prune.test.ts similarity index 100% rename from tests/unit/context/prune.test.ts rename to packages/core/tests/unit/context/prune.test.ts diff --git a/tests/unit/context/token-counter.test.ts b/packages/core/tests/unit/context/token-counter.test.ts similarity index 100% rename from tests/unit/context/token-counter.test.ts rename to packages/core/tests/unit/context/token-counter.test.ts diff --git a/tests/unit/core/agent-tool-filter.test.ts b/packages/core/tests/unit/core/agent-tool-filter.test.ts similarity index 100% rename from tests/unit/core/agent-tool-filter.test.ts rename to packages/core/tests/unit/core/agent-tool-filter.test.ts diff --git a/tests/unit/core/agent.test.ts b/packages/core/tests/unit/core/agent.test.ts similarity index 100% rename from tests/unit/core/agent.test.ts rename to packages/core/tests/unit/core/agent.test.ts diff --git a/tests/unit/core/providers.test.ts b/packages/core/tests/unit/core/providers.test.ts similarity index 100% rename from tests/unit/core/providers.test.ts rename to packages/core/tests/unit/core/providers.test.ts diff --git a/tests/unit/lsp/cli.test.ts b/packages/core/tests/unit/lsp/cli.test.ts similarity index 100% rename from tests/unit/lsp/cli.test.ts rename to packages/core/tests/unit/lsp/cli.test.ts diff --git a/tests/unit/lsp/client-extended.test.ts b/packages/core/tests/unit/lsp/client-extended.test.ts similarity index 100% rename from tests/unit/lsp/client-extended.test.ts rename to packages/core/tests/unit/lsp/client-extended.test.ts diff --git a/tests/unit/lsp/client.test.ts b/packages/core/tests/unit/lsp/client.test.ts similarity index 100% rename from tests/unit/lsp/client.test.ts rename to packages/core/tests/unit/lsp/client.test.ts diff --git a/tests/unit/lsp/index.test.ts b/packages/core/tests/unit/lsp/index.test.ts similarity index 100% rename from tests/unit/lsp/index.test.ts rename to packages/core/tests/unit/lsp/index.test.ts diff --git a/tests/unit/lsp/language.test.ts b/packages/core/tests/unit/lsp/language.test.ts similarity index 100% rename from tests/unit/lsp/language.test.ts rename to packages/core/tests/unit/lsp/language.test.ts diff --git a/tests/unit/lsp/server.test.ts b/packages/core/tests/unit/lsp/server.test.ts similarity index 100% rename from tests/unit/lsp/server.test.ts rename to packages/core/tests/unit/lsp/server.test.ts diff --git a/tests/unit/mcp/config.test.ts b/packages/core/tests/unit/mcp/config.test.ts similarity index 100% rename from tests/unit/mcp/config.test.ts rename to packages/core/tests/unit/mcp/config.test.ts diff --git a/tests/unit/mcp/manager.test.ts b/packages/core/tests/unit/mcp/manager.test.ts similarity index 100% rename from tests/unit/mcp/manager.test.ts rename to packages/core/tests/unit/mcp/manager.test.ts diff --git a/tests/unit/mcp/tool-adapter.test.ts b/packages/core/tests/unit/mcp/tool-adapter.test.ts similarity index 100% rename from tests/unit/mcp/tool-adapter.test.ts rename to packages/core/tests/unit/mcp/tool-adapter.test.ts diff --git a/tests/unit/permission/bash-checker.test.ts b/packages/core/tests/unit/permission/bash-checker.test.ts similarity index 100% rename from tests/unit/permission/bash-checker.test.ts rename to packages/core/tests/unit/permission/bash-checker.test.ts diff --git a/tests/unit/permission/bash-parser.test.ts b/packages/core/tests/unit/permission/bash-parser.test.ts similarity index 100% rename from tests/unit/permission/bash-parser.test.ts rename to packages/core/tests/unit/permission/bash-parser.test.ts diff --git a/tests/unit/permission/file-checker.test.ts b/packages/core/tests/unit/permission/file-checker.test.ts similarity index 100% rename from tests/unit/permission/file-checker.test.ts rename to packages/core/tests/unit/permission/file-checker.test.ts diff --git a/tests/unit/permission/file-prompt.test.ts b/packages/core/tests/unit/permission/file-prompt.test.ts similarity index 100% rename from tests/unit/permission/file-prompt.test.ts rename to packages/core/tests/unit/permission/file-prompt.test.ts diff --git a/tests/unit/permission/git-checker.test.ts b/packages/core/tests/unit/permission/git-checker.test.ts similarity index 100% rename from tests/unit/permission/git-checker.test.ts rename to packages/core/tests/unit/permission/git-checker.test.ts diff --git a/tests/unit/permission/manager.test.ts b/packages/core/tests/unit/permission/manager.test.ts similarity index 100% rename from tests/unit/permission/manager.test.ts rename to packages/core/tests/unit/permission/manager.test.ts diff --git a/tests/unit/permission/prompt.test.ts b/packages/core/tests/unit/permission/prompt.test.ts similarity index 100% rename from tests/unit/permission/prompt.test.ts rename to packages/core/tests/unit/permission/prompt.test.ts diff --git a/tests/unit/permission/web-checker.test.ts b/packages/core/tests/unit/permission/web-checker.test.ts similarity index 100% rename from tests/unit/permission/web-checker.test.ts rename to packages/core/tests/unit/permission/web-checker.test.ts diff --git a/tests/unit/permission/wildcard.test.ts b/packages/core/tests/unit/permission/wildcard.test.ts similarity index 100% rename from tests/unit/permission/wildcard.test.ts rename to packages/core/tests/unit/permission/wildcard.test.ts diff --git a/tests/unit/session/manager.test.ts b/packages/core/tests/unit/session/manager.test.ts similarity index 100% rename from tests/unit/session/manager.test.ts rename to packages/core/tests/unit/session/manager.test.ts diff --git a/tests/unit/session/storage.test.ts b/packages/core/tests/unit/session/storage.test.ts similarity index 100% rename from tests/unit/session/storage.test.ts rename to packages/core/tests/unit/session/storage.test.ts diff --git a/tests/unit/skills/builtin/index.test.ts b/packages/core/tests/unit/skills/builtin/index.test.ts similarity index 100% rename from tests/unit/skills/builtin/index.test.ts rename to packages/core/tests/unit/skills/builtin/index.test.ts diff --git a/tests/unit/skills/loader.test.ts b/packages/core/tests/unit/skills/loader.test.ts similarity index 100% rename from tests/unit/skills/loader.test.ts rename to packages/core/tests/unit/skills/loader.test.ts diff --git a/tests/unit/skills/registry.test.ts b/packages/core/tests/unit/skills/registry.test.ts similarity index 100% rename from tests/unit/skills/registry.test.ts rename to packages/core/tests/unit/skills/registry.test.ts diff --git a/tests/unit/tools/filesystem/copy_file-extended.test.ts b/packages/core/tests/unit/tools/filesystem/copy_file-extended.test.ts similarity index 100% rename from tests/unit/tools/filesystem/copy_file-extended.test.ts rename to packages/core/tests/unit/tools/filesystem/copy_file-extended.test.ts diff --git a/tests/unit/tools/filesystem/copy_file.test.ts b/packages/core/tests/unit/tools/filesystem/copy_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/copy_file.test.ts rename to packages/core/tests/unit/tools/filesystem/copy_file.test.ts diff --git a/tests/unit/tools/filesystem/create_directory.test.ts b/packages/core/tests/unit/tools/filesystem/create_directory.test.ts similarity index 100% rename from tests/unit/tools/filesystem/create_directory.test.ts rename to packages/core/tests/unit/tools/filesystem/create_directory.test.ts diff --git a/tests/unit/tools/filesystem/delete_file.test.ts b/packages/core/tests/unit/tools/filesystem/delete_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/delete_file.test.ts rename to packages/core/tests/unit/tools/filesystem/delete_file.test.ts diff --git a/tests/unit/tools/filesystem/edit_file.test.ts b/packages/core/tests/unit/tools/filesystem/edit_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/edit_file.test.ts rename to packages/core/tests/unit/tools/filesystem/edit_file.test.ts diff --git a/tests/unit/tools/filesystem/get_file_info.test.ts b/packages/core/tests/unit/tools/filesystem/get_file_info.test.ts similarity index 100% rename from tests/unit/tools/filesystem/get_file_info.test.ts rename to packages/core/tests/unit/tools/filesystem/get_file_info.test.ts diff --git a/tests/unit/tools/filesystem/grep_content.test.ts b/packages/core/tests/unit/tools/filesystem/grep_content.test.ts similarity index 100% rename from tests/unit/tools/filesystem/grep_content.test.ts rename to packages/core/tests/unit/tools/filesystem/grep_content.test.ts diff --git a/tests/unit/tools/filesystem/list_directory.test.ts b/packages/core/tests/unit/tools/filesystem/list_directory.test.ts similarity index 100% rename from tests/unit/tools/filesystem/list_directory.test.ts rename to packages/core/tests/unit/tools/filesystem/list_directory.test.ts diff --git a/tests/unit/tools/filesystem/move_file.test.ts b/packages/core/tests/unit/tools/filesystem/move_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/move_file.test.ts rename to packages/core/tests/unit/tools/filesystem/move_file.test.ts diff --git a/tests/unit/tools/filesystem/read_file.test.ts b/packages/core/tests/unit/tools/filesystem/read_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/read_file.test.ts rename to packages/core/tests/unit/tools/filesystem/read_file.test.ts diff --git a/tests/unit/tools/filesystem/search_files.test.ts b/packages/core/tests/unit/tools/filesystem/search_files.test.ts similarity index 100% rename from tests/unit/tools/filesystem/search_files.test.ts rename to packages/core/tests/unit/tools/filesystem/search_files.test.ts diff --git a/tests/unit/tools/filesystem/write_file-extended.test.ts b/packages/core/tests/unit/tools/filesystem/write_file-extended.test.ts similarity index 100% rename from tests/unit/tools/filesystem/write_file-extended.test.ts rename to packages/core/tests/unit/tools/filesystem/write_file-extended.test.ts diff --git a/tests/unit/tools/filesystem/write_file.test.ts b/packages/core/tests/unit/tools/filesystem/write_file.test.ts similarity index 100% rename from tests/unit/tools/filesystem/write_file.test.ts rename to packages/core/tests/unit/tools/filesystem/write_file.test.ts diff --git a/tests/unit/tools/git/git_add.test.ts b/packages/core/tests/unit/tools/git/git_add.test.ts similarity index 100% rename from tests/unit/tools/git/git_add.test.ts rename to packages/core/tests/unit/tools/git/git_add.test.ts diff --git a/tests/unit/tools/git/git_branch.test.ts b/packages/core/tests/unit/tools/git/git_branch.test.ts similarity index 100% rename from tests/unit/tools/git/git_branch.test.ts rename to packages/core/tests/unit/tools/git/git_branch.test.ts diff --git a/tests/unit/tools/git/git_checkout.test.ts b/packages/core/tests/unit/tools/git/git_checkout.test.ts similarity index 100% rename from tests/unit/tools/git/git_checkout.test.ts rename to packages/core/tests/unit/tools/git/git_checkout.test.ts diff --git a/tests/unit/tools/git/git_commit-extended.test.ts b/packages/core/tests/unit/tools/git/git_commit-extended.test.ts similarity index 100% rename from tests/unit/tools/git/git_commit-extended.test.ts rename to packages/core/tests/unit/tools/git/git_commit-extended.test.ts diff --git a/tests/unit/tools/git/git_commit.test.ts b/packages/core/tests/unit/tools/git/git_commit.test.ts similarity index 100% rename from tests/unit/tools/git/git_commit.test.ts rename to packages/core/tests/unit/tools/git/git_commit.test.ts diff --git a/tests/unit/tools/git/git_diff.test.ts b/packages/core/tests/unit/tools/git/git_diff.test.ts similarity index 100% rename from tests/unit/tools/git/git_diff.test.ts rename to packages/core/tests/unit/tools/git/git_diff.test.ts diff --git a/tests/unit/tools/git/git_log.test.ts b/packages/core/tests/unit/tools/git/git_log.test.ts similarity index 100% rename from tests/unit/tools/git/git_log.test.ts rename to packages/core/tests/unit/tools/git/git_log.test.ts diff --git a/tests/unit/tools/git/git_pull.test.ts b/packages/core/tests/unit/tools/git/git_pull.test.ts similarity index 100% rename from tests/unit/tools/git/git_pull.test.ts rename to packages/core/tests/unit/tools/git/git_pull.test.ts diff --git a/tests/unit/tools/git/git_push.test.ts b/packages/core/tests/unit/tools/git/git_push.test.ts similarity index 100% rename from tests/unit/tools/git/git_push.test.ts rename to packages/core/tests/unit/tools/git/git_push.test.ts diff --git a/tests/unit/tools/git/git_stash.test.ts b/packages/core/tests/unit/tools/git/git_stash.test.ts similarity index 100% rename from tests/unit/tools/git/git_stash.test.ts rename to packages/core/tests/unit/tools/git/git_stash.test.ts diff --git a/tests/unit/tools/git/git_status.test.ts b/packages/core/tests/unit/tools/git/git_status.test.ts similarity index 100% rename from tests/unit/tools/git/git_status.test.ts rename to packages/core/tests/unit/tools/git/git_status.test.ts diff --git a/tests/unit/tools/load_description.test.ts b/packages/core/tests/unit/tools/load_description.test.ts similarity index 100% rename from tests/unit/tools/load_description.test.ts rename to packages/core/tests/unit/tools/load_description.test.ts diff --git a/tests/unit/tools/registry.test.ts b/packages/core/tests/unit/tools/registry.test.ts similarity index 100% rename from tests/unit/tools/registry.test.ts rename to packages/core/tests/unit/tools/registry.test.ts diff --git a/tests/unit/tools/search.test.ts b/packages/core/tests/unit/tools/search.test.ts similarity index 100% rename from tests/unit/tools/search.test.ts rename to packages/core/tests/unit/tools/search.test.ts diff --git a/tests/unit/tools/shell/bash.test.ts b/packages/core/tests/unit/tools/shell/bash.test.ts similarity index 100% rename from tests/unit/tools/shell/bash.test.ts rename to packages/core/tests/unit/tools/shell/bash.test.ts diff --git a/tests/unit/tools/skill/skill.test.ts b/packages/core/tests/unit/tools/skill/skill.test.ts similarity index 100% rename from tests/unit/tools/skill/skill.test.ts rename to packages/core/tests/unit/tools/skill/skill.test.ts diff --git a/tests/unit/tools/skill/skill_search-extended.test.ts b/packages/core/tests/unit/tools/skill/skill_search-extended.test.ts similarity index 100% rename from tests/unit/tools/skill/skill_search-extended.test.ts rename to packages/core/tests/unit/tools/skill/skill_search-extended.test.ts diff --git a/tests/unit/tools/skill/skill_search.test.ts b/packages/core/tests/unit/tools/skill/skill_search.test.ts similarity index 100% rename from tests/unit/tools/skill/skill_search.test.ts rename to packages/core/tests/unit/tools/skill/skill_search.test.ts diff --git a/tests/unit/tools/task/agent_output.test.ts b/packages/core/tests/unit/tools/task/agent_output.test.ts similarity index 100% rename from tests/unit/tools/task/agent_output.test.ts rename to packages/core/tests/unit/tools/task/agent_output.test.ts diff --git a/tests/unit/tools/task/task-extended.test.ts b/packages/core/tests/unit/tools/task/task-extended.test.ts similarity index 100% rename from tests/unit/tools/task/task-extended.test.ts rename to packages/core/tests/unit/tools/task/task-extended.test.ts diff --git a/tests/unit/tools/task/task.test.ts b/packages/core/tests/unit/tools/task/task.test.ts similarity index 100% rename from tests/unit/tools/task/task.test.ts rename to packages/core/tests/unit/tools/task/task.test.ts diff --git a/tests/unit/tools/todo-manager.test.ts b/packages/core/tests/unit/tools/todo-manager.test.ts similarity index 100% rename from tests/unit/tools/todo-manager.test.ts rename to packages/core/tests/unit/tools/todo-manager.test.ts diff --git a/tests/unit/tools/todo/todo-manager.test.ts b/packages/core/tests/unit/tools/todo/todo-manager.test.ts similarity index 100% rename from tests/unit/tools/todo/todo-manager.test.ts rename to packages/core/tests/unit/tools/todo/todo-manager.test.ts diff --git a/tests/unit/tools/todo/todoread.test.ts b/packages/core/tests/unit/tools/todo/todoread.test.ts similarity index 100% rename from tests/unit/tools/todo/todoread.test.ts rename to packages/core/tests/unit/tools/todo/todoread.test.ts diff --git a/tests/unit/tools/todo/todowrite.test.ts b/packages/core/tests/unit/tools/todo/todowrite.test.ts similarity index 100% rename from tests/unit/tools/todo/todowrite.test.ts rename to packages/core/tests/unit/tools/todo/todowrite.test.ts diff --git a/tests/unit/tools/tool-search.test.ts b/packages/core/tests/unit/tools/tool-search.test.ts similarity index 100% rename from tests/unit/tools/tool-search.test.ts rename to packages/core/tests/unit/tools/tool-search.test.ts diff --git a/tests/unit/tools/web/web_extract.test.ts b/packages/core/tests/unit/tools/web/web_extract.test.ts similarity index 100% rename from tests/unit/tools/web/web_extract.test.ts rename to packages/core/tests/unit/tools/web/web_extract.test.ts diff --git a/tests/unit/tools/web/web_search.test.ts b/packages/core/tests/unit/tools/web/web_search.test.ts similarity index 100% rename from tests/unit/tools/web/web_search.test.ts rename to packages/core/tests/unit/tools/web/web_search.test.ts diff --git a/tests/unit/types/index.test.ts b/packages/core/tests/unit/types/index.test.ts similarity index 100% rename from tests/unit/types/index.test.ts rename to packages/core/tests/unit/types/index.test.ts diff --git a/tests/unit/ui/terminal.test.ts b/packages/core/tests/unit/ui/terminal.test.ts similarity index 100% rename from tests/unit/ui/terminal.test.ts rename to packages/core/tests/unit/ui/terminal.test.ts diff --git a/tests/unit/utils/config-extended.test.ts b/packages/core/tests/unit/utils/config-extended.test.ts similarity index 100% rename from tests/unit/utils/config-extended.test.ts rename to packages/core/tests/unit/utils/config-extended.test.ts diff --git a/tests/unit/utils/config.test.ts b/packages/core/tests/unit/utils/config.test.ts similarity index 100% rename from tests/unit/utils/config.test.ts rename to packages/core/tests/unit/utils/config.test.ts diff --git a/tests/unit/utils/diff-extended.test.ts b/packages/core/tests/unit/utils/diff-extended.test.ts similarity index 100% rename from tests/unit/utils/diff-extended.test.ts rename to packages/core/tests/unit/utils/diff-extended.test.ts diff --git a/tests/unit/utils/diff.test.ts b/packages/core/tests/unit/utils/diff.test.ts similarity index 100% rename from tests/unit/utils/diff.test.ts rename to packages/core/tests/unit/utils/diff.test.ts diff --git a/tests/unit/utils/image.test.ts b/packages/core/tests/unit/utils/image.test.ts similarity index 100% rename from tests/unit/utils/image.test.ts rename to packages/core/tests/unit/utils/image.test.ts diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json new file mode 100644 index 0000000..c83c533 --- /dev/null +++ b/packages/core/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 0000000..71bfaf7 --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + include: ['tests/**/*.test.ts'], + exclude: ['node_modules', 'dist'], + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + include: ['src/**/*.ts'], + exclude: [ + 'src/index.ts', + 'src/ui/**', + 'src/tools/descriptions/**', + ], + }, + setupFiles: ['tests/setup.ts'], + testTimeout: 10000, + }, + resolve: { + alias: { + '@': '/src', + }, + }, +}); diff --git a/packages/server/package.json b/packages/server/package.json new file mode 100644 index 0000000..b866dbd --- /dev/null +++ b/packages/server/package.json @@ -0,0 +1,35 @@ +{ + "name": "@ai-assistant/server", + "version": "1.0.0", + "description": "HTTP Server for AI terminal assistant - REST API, WebSocket, SSE", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "start": "bun run src/bin/server.ts", + "start:dev": "bun --watch run src/bin/server.ts", + "test": "vitest run", + "test:watch": "vitest" + }, + "dependencies": { + "@ai-assistant/core": "workspace:*", + "hono": "^4.6.0", + "uuid": "^13.0.0", + "zod": "^4.1.13" + }, + "devDependencies": { + "@types/bun": "^1.1.0", + "@types/node": "^22.0.0", + "@types/uuid": "^10.0.0", + "typescript": "^5.6.0", + "vitest": "^4.0.15" + } +} diff --git a/packages/server/src/bin/server.ts b/packages/server/src/bin/server.ts new file mode 100644 index 0000000..2118b0c --- /dev/null +++ b/packages/server/src/bin/server.ts @@ -0,0 +1,68 @@ +#!/usr/bin/env bun +/** + * AI Assistant Server Entry Point + * + * 独立运行的服务器入口,用于开发和测试 + * + * Usage: + * bun run packages/server/src/bin/server.ts + * bun run packages/server/src/bin/server.ts --port 8080 + * bun run packages/server/src/bin/server.ts --host 0.0.0.0 --port 3000 + */ + +import { app, websocket, startServer } from '../index.js'; + +// 解析命令行参数 +function parseArgs(): { port: number; host: string } { + const args = process.argv.slice(2); + let port = 3000; + let host = '127.0.0.1'; + + for (let i = 0; i < args.length; i++) { + if (args[i] === '--port' || args[i] === '-p') { + port = parseInt(args[i + 1], 10) || 3000; + i++; + } else if (args[i] === '--host' || args[i] === '-h') { + host = args[i + 1] || '127.0.0.1'; + i++; + } + } + + return { port, host }; +} + +// 主函数 +async function main() { + const { port, host } = parseArgs(); + + // 打印启动信息 + startServer({ port, host }); + + // 启动 Bun 服务器 + const server = Bun.serve({ + port, + hostname: host, + fetch: app.fetch, + websocket, + }); + + console.log(`Server started at http://${host}:${port}`); + + // 优雅关闭 + process.on('SIGINT', () => { + console.log('\nShutting down server...'); + server.stop(); + process.exit(0); + }); + + process.on('SIGTERM', () => { + console.log('\nShutting down server...'); + server.stop(); + process.exit(0); + }); +} + +main().catch((error) => { + console.error('Failed to start server:', error); + process.exit(1); +}); diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts new file mode 100644 index 0000000..3b63d14 --- /dev/null +++ b/packages/server/src/index.ts @@ -0,0 +1,173 @@ +/** + * AI Assistant Server + * + * HTTP Server 入口,提供 REST API、WebSocket 和 SSE 支持 + */ + +import { Hono } from 'hono'; +import { cors } from 'hono/cors'; +import { logger } from 'hono/logger'; +import { createBunWebSocket } from 'hono/bun'; + +import { sessionsRouter, toolsRouter, configRouter } from './routes/index.js'; +import { + handleWebSocket, + handleWebSocketMessage, + handleWebSocketClose, + getConnectionStats, +} from './ws.js'; +import { handleSSE, getSSEStats } from './sse.js'; +import { getSessionManager } from './session/manager.js'; + +// 创建 Hono 应用 +const app = new Hono(); + +// WebSocket 升级 (Bun 环境) +const { upgradeWebSocket, websocket } = createBunWebSocket(); + +// 中间件 +app.use('*', logger()); +app.use( + '*', + cors({ + origin: '*', // 生产环境应该限制 + allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], + allowHeaders: ['Content-Type', 'Authorization'], + }) +); + +// 健康检查 +app.get('/health', (c) => { + const sessionManager = getSessionManager(); + const wsStats = getConnectionStats(); + const sseStats = getSSEStats(); + + return c.json({ + status: 'ok', + timestamp: new Date().toISOString(), + stats: { + sessions: sessionManager.count(), + websocket: wsStats, + sse: sseStats, + }, + }); +}); + +// API 版本前缀 +const api = new Hono(); + +// 挂载路由 +api.route('/sessions', sessionsRouter); +api.route('/tools', toolsRouter); +api.route('/config', configRouter); + +// SSE 事件流 +api.get('/sessions/:id/events', handleSSE); + +// WebSocket 端点 +api.get( + '/ws/:sessionId', + upgradeWebSocket((c) => { + const sessionId = c.req.param('sessionId'); + + return { + onOpen(_event, ws) { + handleWebSocket(ws, sessionId); + }, + onMessage(event, ws) { + handleWebSocketMessage(ws, sessionId, event.data); + }, + onClose(_event, ws) { + handleWebSocketClose(ws, sessionId); + }, + onError(event, ws) { + console.error('[WS] Error:', event); + handleWebSocketClose(ws, sessionId); + }, + }; + }) +); + +// 挂载 API 到 /api +app.route('/api', api); + +// 404 处理 +app.notFound((c) => { + return c.json( + { + success: false, + error: 'Not found', + }, + 404 + ); +}); + +// 错误处理 +app.onError((err, c) => { + console.error('[Server Error]', err); + + return c.json( + { + success: false, + error: err.message || 'Internal server error', + }, + 500 + ); +}); + +// 服务器配置 +export interface ServerOptions { + port?: number; + host?: string; +} + +/** + * 创建服务器实例 + */ +export function createServer(options: ServerOptions = {}) { + const { port = 3000, host = '127.0.0.1' } = options; + + return { + app, + websocket, + port, + host, + }; +} + +/** + * 启动服务器 (Bun 环境) + */ +export function startServer(options: ServerOptions = {}): void { + const { port = 3000, host = '127.0.0.1' } = options; + + console.log(` +╔════════════════════════════════════════════╗ +║ AI Assistant Server ║ +╠════════════════════════════════════════════╣ +║ REST API: http://${host}:${port}/api +║ WebSocket: ws://${host}:${port}/api/ws/:sessionId +║ SSE: http://${host}:${port}/api/sessions/:id/events +║ Health: http://${host}:${port}/health +╚════════════════════════════════════════════╝ + `); + + // Bun.serve 需要在 CLI 包中调用 + // 这里只导出配置 +} + +// 导出 +export { app, websocket }; +export { getSessionManager } from './session/manager.js'; +export { registerTool, getRegisteredTools } from './routes/tools.js'; +export { getConfig, setConfig } from './routes/config.js'; +export { + emitEvent, + broadcastEvent, + emitStatusEvent, + emitLogEvent, + emitProgressEvent, + emitFileChangeEvent, +} from './sse.js'; +export { broadcastToSession } from './ws.js'; +export * from './types.js'; diff --git a/packages/server/src/routes/config.ts b/packages/server/src/routes/config.ts new file mode 100644 index 0000000..33f28a6 --- /dev/null +++ b/packages/server/src/routes/config.ts @@ -0,0 +1,109 @@ +/** + * Config API Routes + * + * 配置管理相关的 REST API + */ + +import { Hono } from 'hono'; + +export const configRouter = new Hono(); + +// 服务器配置 (后续会从配置文件加载) +interface ServerConfig { + model: string; + maxTokens: number; + temperature: number; + workdir: string; + allowedPaths: string[]; + deniedPaths: string[]; +} + +let serverConfig: ServerConfig = { + model: 'claude-sonnet-4-20250514', + maxTokens: 8192, + temperature: 0.7, + workdir: process.cwd(), + allowedPaths: [], + deniedPaths: [], +}; + +/** + * GET /config - 获取当前配置 + */ +configRouter.get('/', (c) => { + return c.json({ + success: true, + data: serverConfig, + }); +}); + +/** + * PUT /config - 更新配置 + */ +configRouter.put('/', async (c) => { + try { + const body = await c.req.json(); + + // 合并配置 (只更新提供的字段) + serverConfig = { + ...serverConfig, + ...body, + }; + + return c.json({ + success: true, + data: serverConfig, + }); + } catch (error) { + return c.json( + { + success: false, + error: error instanceof Error ? error.message : 'Invalid input', + }, + 400 + ); + } +}); + +/** + * PATCH /config - 部分更新配置 + */ +configRouter.patch('/', async (c) => { + try { + const body = await c.req.json(); + + // 部分更新 + Object.keys(body).forEach((key) => { + if (key in serverConfig) { + (serverConfig as any)[key] = body[key]; + } + }); + + return c.json({ + success: true, + data: serverConfig, + }); + } catch (error) { + return c.json( + { + success: false, + error: error instanceof Error ? error.message : 'Invalid input', + }, + 400 + ); + } +}); + +/** + * 获取当前配置 (内部使用) + */ +export function getConfig(): ServerConfig { + return { ...serverConfig }; +} + +/** + * 设置配置 (内部使用) + */ +export function setConfig(config: Partial): void { + serverConfig = { ...serverConfig, ...config }; +} diff --git a/packages/server/src/routes/index.ts b/packages/server/src/routes/index.ts new file mode 100644 index 0000000..4066003 --- /dev/null +++ b/packages/server/src/routes/index.ts @@ -0,0 +1,9 @@ +/** + * API Routes Index + * + * 聚合所有 API 路由 + */ + +export { sessionsRouter } from './sessions.js'; +export { toolsRouter, registerTool, getRegisteredTools } from './tools.js'; +export { configRouter, getConfig, setConfig } from './config.js'; diff --git a/packages/server/src/routes/sessions.ts b/packages/server/src/routes/sessions.ts new file mode 100644 index 0000000..0932a6b --- /dev/null +++ b/packages/server/src/routes/sessions.ts @@ -0,0 +1,178 @@ +/** + * Sessions API Routes + * + * 会话管理相关的 REST API + */ + +import { Hono } from 'hono'; +import { getSessionManager } from '../session/manager.js'; +import { CreateSessionInputSchema, SendMessageInputSchema } from '../types.js'; + +export const sessionsRouter = new Hono(); + +const sessionManager = getSessionManager(); + +/** + * GET /sessions - 列出所有会话 + */ +sessionsRouter.get('/', (c) => { + const sessions = sessionManager.list(); + return c.json({ + success: true, + data: sessions, + }); +}); + +/** + * POST /sessions - 创建新会话 + */ +sessionsRouter.post('/', async (c) => { + try { + const body = await c.req.json(); + const input = CreateSessionInputSchema.parse(body); + const session = sessionManager.create(input); + + return c.json( + { + success: true, + data: session, + }, + 201 + ); + } catch (error) { + return c.json( + { + success: false, + error: error instanceof Error ? error.message : 'Invalid input', + }, + 400 + ); + } +}); + +/** + * GET /sessions/:id - 获取单个会话 + */ +sessionsRouter.get('/:id', (c) => { + const id = c.req.param('id'); + const session = sessionManager.get(id); + + if (!session) { + return c.json( + { + success: false, + error: 'Session not found', + }, + 404 + ); + } + + return c.json({ + success: true, + data: session, + }); +}); + +/** + * DELETE /sessions/:id - 删除会话 + */ +sessionsRouter.delete('/:id', (c) => { + const id = c.req.param('id'); + + if (!sessionManager.exists(id)) { + return c.json( + { + success: false, + error: 'Session not found', + }, + 404 + ); + } + + sessionManager.delete(id); + + return c.json({ + success: true, + message: 'Session deleted', + }); +}); + +/** + * GET /sessions/:id/messages - 获取会话消息 + */ +sessionsRouter.get('/:id/messages', (c) => { + const id = c.req.param('id'); + + if (!sessionManager.exists(id)) { + return c.json( + { + success: false, + error: 'Session not found', + }, + 404 + ); + } + + const messages = sessionManager.getMessages(id); + + return c.json({ + success: true, + data: messages, + }); +}); + +/** + * POST /sessions/:id/messages - 发送消息 + * + * 注意: 这个端点仅用于添加消息记录。 + * 实际的 AI 对话应该通过 WebSocket 进行。 + */ +sessionsRouter.post('/:id/messages', async (c) => { + const id = c.req.param('id'); + + if (!sessionManager.exists(id)) { + return c.json( + { + success: false, + error: 'Session not found', + }, + 404 + ); + } + + try { + const body = await c.req.json(); + const input = SendMessageInputSchema.parse(body); + + const message = sessionManager.addMessage(id, { + role: input.role, + content: input.content, + }); + + if (!message) { + return c.json( + { + success: false, + error: 'Failed to add message', + }, + 500 + ); + } + + return c.json( + { + success: true, + data: message, + }, + 201 + ); + } catch (error) { + return c.json( + { + success: false, + error: error instanceof Error ? error.message : 'Invalid input', + }, + 400 + ); + } +}); diff --git a/packages/server/src/routes/tools.ts b/packages/server/src/routes/tools.ts new file mode 100644 index 0000000..5958950 --- /dev/null +++ b/packages/server/src/routes/tools.ts @@ -0,0 +1,109 @@ +/** + * Tools API Routes + * + * 工具管理相关的 REST API + */ + +import { Hono } from 'hono'; +import type { Tool } from '../types.js'; + +export const toolsRouter = new Hono(); + +// 工具注册表 (后续会从 core 模块获取) +const toolRegistry: Map = new Map(); + +/** + * 注册工具 (内部使用) + */ +export function registerTool(tool: Tool): void { + toolRegistry.set(tool.name, tool); +} + +/** + * 获取所有已注册的工具 + */ +export function getRegisteredTools(): Tool[] { + return Array.from(toolRegistry.values()); +} + +/** + * GET /tools - 列出所有可用工具 + */ +toolsRouter.get('/', (c) => { + const tools = getRegisteredTools(); + + return c.json({ + success: true, + data: tools, + }); +}); + +/** + * GET /tools/:name - 获取单个工具详情 + */ +toolsRouter.get('/:name', (c) => { + const name = c.req.param('name'); + const tool = toolRegistry.get(name); + + if (!tool) { + return c.json( + { + success: false, + error: 'Tool not found', + }, + 404 + ); + } + + return c.json({ + success: true, + data: tool, + }); +}); + +/** + * POST /tools/:name/execute - 执行工具 + * + * 注意: 工具执行是同步的,对于长时间运行的工具, + * 建议通过 WebSocket 执行以获取实时反馈。 + */ +toolsRouter.post('/:name/execute', async (c) => { + const name = c.req.param('name'); + const tool = toolRegistry.get(name); + + if (!tool) { + return c.json( + { + success: false, + error: 'Tool not found', + }, + 404 + ); + } + + try { + const body = await c.req.json(); + const params = body.params || {}; + + // TODO: 实际调用 core 模块的工具执行逻辑 + // const result = await executeTool(name, params); + + return c.json({ + success: true, + data: { + tool: name, + params, + result: null, // 占位,后续实现 + message: 'Tool execution not yet implemented', + }, + }); + } catch (error) { + return c.json( + { + success: false, + error: error instanceof Error ? error.message : 'Execution failed', + }, + 500 + ); + } +}); diff --git a/packages/server/src/session/manager.ts b/packages/server/src/session/manager.ts new file mode 100644 index 0000000..73492bf --- /dev/null +++ b/packages/server/src/session/manager.ts @@ -0,0 +1,126 @@ +/** + * Session Manager + * + * 管理所有活跃的会话 + */ + +import { v4 as uuidv4 } from 'uuid'; +import type { Session, CreateSessionInput, Message, SessionStatus } from '../types.js'; + +export class SessionManager { + private sessions: Map = new Map(); + private messages: Map = new Map(); + + /** + * 创建新会话 + */ + create(input: CreateSessionInput = {}): Session { + const now = new Date().toISOString(); + const session: Session = { + id: uuidv4(), + name: input.name, + workdir: input.workdir || process.cwd(), + createdAt: now, + updatedAt: now, + status: 'idle', + messageCount: 0, + }; + + this.sessions.set(session.id, session); + this.messages.set(session.id, []); + + return session; + } + + /** + * 获取所有会话 + */ + list(): Session[] { + return Array.from(this.sessions.values()).sort( + (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime() + ); + } + + /** + * 获取单个会话 + */ + get(id: string): Session | undefined { + return this.sessions.get(id); + } + + /** + * 删除会话 + */ + delete(id: string): boolean { + this.messages.delete(id); + return this.sessions.delete(id); + } + + /** + * 更新会话状态 + */ + updateStatus(id: string, status: SessionStatus): Session | undefined { + const session = this.sessions.get(id); + if (!session) return undefined; + + session.status = status; + session.updatedAt = new Date().toISOString(); + return session; + } + + /** + * 获取会话消息 + */ + getMessages(sessionId: string): Message[] { + return this.messages.get(sessionId) || []; + } + + /** + * 添加消息 + */ + addMessage(sessionId: string, message: Omit): Message | undefined { + const session = this.sessions.get(sessionId); + if (!session) return undefined; + + const fullMessage: Message = { + ...message, + id: uuidv4(), + sessionId, + createdAt: new Date().toISOString(), + }; + + const messages = this.messages.get(sessionId) || []; + messages.push(fullMessage); + this.messages.set(sessionId, messages); + + // 更新会话 + session.messageCount = messages.length; + session.updatedAt = new Date().toISOString(); + + return fullMessage; + } + + /** + * 获取会话数量 + */ + count(): number { + return this.sessions.size; + } + + /** + * 检查会话是否存在 + */ + exists(id: string): boolean { + return this.sessions.has(id); + } +} + +// 单例 +let instance: SessionManager | null = null; + +export function getSessionManager(): SessionManager { + if (!instance) { + instance = new SessionManager(); + } + return instance; +} diff --git a/packages/server/src/sse.ts b/packages/server/src/sse.ts new file mode 100644 index 0000000..a51c145 --- /dev/null +++ b/packages/server/src/sse.ts @@ -0,0 +1,238 @@ +/** + * SSE (Server-Sent Events) Handler + * + * 处理单向事件推送,用于状态更新、日志流、进度通知等 + */ + +import type { Context } from 'hono'; +import { streamSSE } from 'hono/streaming'; +import { getSessionManager } from './session/manager.js'; +import type { SSEEvent } from './types.js'; + +// 存储 SSE 订阅者 +interface SSESubscriber { + sessionId: string; + controller: ReadableStreamDefaultController; + active: boolean; +} + +const subscribers: Map> = new Map(); + +/** + * 向会话的所有订阅者发送 SSE 事件 + */ +export function emitEvent(sessionId: string, event: SSEEvent): void { + const subs = subscribers.get(sessionId); + if (!subs) return; + + const eventString = formatSSEMessage(event); + + for (const sub of subs) { + if (!sub.active) continue; + + try { + sub.controller.enqueue(eventString); + } catch (error) { + // 订阅者已断开 + sub.active = false; + } + } +} + +/** + * 广播事件到所有会话 + */ +export function broadcastEvent(event: SSEEvent): void { + for (const sessionId of subscribers.keys()) { + emitEvent(sessionId, event); + } +} + +/** + * 格式化 SSE 消息 + */ +function formatSSEMessage(event: SSEEvent): string { + const lines: string[] = []; + + if (event.event) { + lines.push(`event: ${event.event}`); + } + + const data = JSON.stringify(event.data); + lines.push(`data: ${data}`); + lines.push(''); // 空行结束消息 + + return lines.join('\n') + '\n'; +} + +/** + * SSE 路由处理器 + * + * GET /api/sessions/:id/events + */ +export async function handleSSE(c: Context): Promise { + const sessionId = c.req.param('id'); + const sessionManager = getSessionManager(); + + // 验证会话 + if (!sessionManager.exists(sessionId)) { + return c.json( + { + success: false, + error: 'Session not found', + }, + 404 + ); + } + + return streamSSE(c, async (stream) => { + // 创建订阅者 + const subscriber: SSESubscriber = { + sessionId, + controller: null as any, // Will be set by stream internals + active: true, + }; + + // 注册订阅者 + if (!subscribers.has(sessionId)) { + subscribers.set(sessionId, new Set()); + } + subscribers.get(sessionId)!.add(subscriber); + + console.log(`[SSE] Client subscribed to session: ${sessionId}`); + + // 发送初始连接事件 + await stream.writeSSE({ + event: 'connected', + data: JSON.stringify({ + timestamp: Date.now(), + payload: { sessionId }, + }), + }); + + // 发送心跳保持连接 + const heartbeatInterval = setInterval(async () => { + if (!subscriber.active) { + clearInterval(heartbeatInterval); + return; + } + + try { + await stream.writeSSE({ + event: 'heartbeat', + data: JSON.stringify({ + timestamp: Date.now(), + payload: null, + }), + }); + } catch { + subscriber.active = false; + clearInterval(heartbeatInterval); + } + }, 30000); // 每 30 秒发送心跳 + + // 监听关闭 + stream.onAbort(() => { + subscriber.active = false; + clearInterval(heartbeatInterval); + + const subs = subscribers.get(sessionId); + if (subs) { + subs.delete(subscriber); + if (subs.size === 0) { + subscribers.delete(sessionId); + } + } + + console.log(`[SSE] Client unsubscribed from session: ${sessionId}`); + }); + + // 保持连接打开 + // 事件将通过 emitEvent() 发送 + while (subscriber.active) { + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + }); +} + +/** + * 发送状态更新事件 + */ +export function emitStatusEvent( + sessionId: string, + status: string, + details?: Record +): void { + emitEvent(sessionId, { + event: 'status', + data: { + timestamp: Date.now(), + payload: { status, ...details }, + }, + }); +} + +/** + * 发送日志事件 + */ +export function emitLogEvent( + sessionId: string, + level: 'info' | 'warn' | 'error', + message: string +): void { + emitEvent(sessionId, { + event: 'log', + data: { + timestamp: Date.now(), + payload: { level, message }, + }, + }); +} + +/** + * 发送进度事件 + */ +export function emitProgressEvent( + sessionId: string, + progress: number, + message?: string +): void { + emitEvent(sessionId, { + event: 'progress', + data: { + timestamp: Date.now(), + payload: { progress, message }, + }, + }); +} + +/** + * 发送文件变更事件 + */ +export function emitFileChangeEvent( + sessionId: string, + type: 'created' | 'modified' | 'deleted', + path: string +): void { + emitEvent(sessionId, { + event: 'file_change', + data: { + timestamp: Date.now(), + payload: { type, path }, + }, + }); +} + +/** + * 获取订阅统计 + */ +export function getSSEStats(): { sessions: number; subscribers: number } { + let totalSubscribers = 0; + for (const subs of subscribers.values()) { + totalSubscribers += subs.size; + } + return { + sessions: subscribers.size, + subscribers: totalSubscribers, + }; +} diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts new file mode 100644 index 0000000..bc7c32e --- /dev/null +++ b/packages/server/src/types.ts @@ -0,0 +1,142 @@ +/** + * Server 类型定义 + */ + +import { z } from 'zod'; + +// ============ Session 相关 ============ + +export const SessionStatusSchema = z.enum(['idle', 'active', 'busy', 'running', 'paused']); + +export const SessionSchema = z.object({ + id: z.string().uuid(), + name: z.string().optional(), + workdir: z.string(), + createdAt: z.string(), + updatedAt: z.string(), + status: SessionStatusSchema, + messageCount: z.number().int().min(0), +}); + +export type Session = z.infer; +export type SessionStatus = z.infer; + +export const CreateSessionInputSchema = z.object({ + name: z.string().optional(), + workdir: z.string().optional(), +}); + +export type CreateSessionInput = z.infer; + +// ============ Message 相关 ============ + +export const MessageRoleSchema = z.enum(['user', 'assistant', 'system', 'tool']); + +export const MessageSchema = z.object({ + id: z.string().uuid(), + sessionId: z.string().uuid(), + role: MessageRoleSchema, + content: z.string(), + createdAt: z.string(), + toolCalls: z + .array( + z.object({ + id: z.string(), + name: z.string(), + arguments: z.record(z.string(), z.unknown()), + }) + ) + .optional(), + toolResults: z + .array( + z.object({ + toolCallId: z.string(), + result: z.unknown(), + }) + ) + .optional(), +}); + +export type Message = z.infer; + +export const SendMessageInputSchema = z.object({ + role: MessageRoleSchema.default('user'), + content: z.string().min(1), + stream: z.boolean().optional().default(true), +}); + +export type SendMessageInput = z.infer; + +// ============ Tool 相关 ============ + +export const ToolSchema = z.object({ + name: z.string(), + description: z.string(), + category: z.string().optional(), + parameters: z.record( + z.string(), + z.object({ + type: z.string(), + description: z.string(), + required: z.boolean().optional(), + }) + ), +}); + +export type Tool = z.infer; + +// ============ WebSocket 消息 ============ + +// 客户端发送的消息 +export interface ClientMessage { + type: 'message' | 'cancel' | 'tool_response'; + sessionId: string; + payload?: { + content?: string; + toolCallId?: string; + approved?: boolean; + }; +} + +// 服务端发送的消息 +export interface ServerMessage { + type: + | 'connected' + | 'message_received' + | 'chunk' + | 'tool_call' + | 'tool_result' + | 'done' + | 'cancelled' + | 'error'; + sessionId: string; + payload?: unknown; +} + +// ============ SSE 事件 ============ + +export interface SSEEvent { + event?: 'connected' | 'heartbeat' | 'status' | 'log' | 'progress' | 'file_change' | 'tool_execution'; + data: { + timestamp: number; + sessionId?: string; + payload: unknown; + }; +} + +// ============ API 响应 ============ + +export interface ApiResponse { + success: boolean; + data?: T; + error?: string; + message?: string; +} + +export interface PaginatedResponse { + items: T[]; + total: number; + page: number; + pageSize: number; + hasMore: boolean; +} diff --git a/packages/server/src/ws.ts b/packages/server/src/ws.ts new file mode 100644 index 0000000..f26ab9e --- /dev/null +++ b/packages/server/src/ws.ts @@ -0,0 +1,222 @@ +/** + * WebSocket Handler + * + * 处理实时双向通信,主要用于 AI 对话流 + */ + +import type { WSContext } from 'hono/ws'; +import { getSessionManager } from './session/manager.js'; +import type { ClientMessage, ServerMessage } from './types.js'; + +// 存储活跃的 WebSocket 连接 +const connections: Map> = new Map(); + +/** + * 获取会话的所有连接 + */ +export function getSessionConnections(sessionId: string): Set { + return connections.get(sessionId) || new Set(); +} + +/** + * 向会话的所有连接发送消息 + */ +export function broadcastToSession(sessionId: string, message: ServerMessage): void { + const conns = connections.get(sessionId); + if (!conns) return; + + const data = JSON.stringify(message); + for (const ws of conns) { + try { + ws.send(data); + } catch (error) { + console.error('Failed to send message:', error); + } + } +} + +/** + * WebSocket 连接处理器 + */ +export function handleWebSocket(ws: WSContext, sessionId: string): void { + const sessionManager = getSessionManager(); + + // 验证会话 + if (!sessionManager.exists(sessionId)) { + ws.send( + JSON.stringify({ + type: 'error', + sessionId, + payload: { message: 'Session not found' }, + } as ServerMessage) + ); + ws.close(4004, 'Session not found'); + return; + } + + // 注册连接 + if (!connections.has(sessionId)) { + connections.set(sessionId, new Set()); + } + connections.get(sessionId)!.add(ws); + + // 更新会话状态 + sessionManager.updateStatus(sessionId, 'active'); + + // 发送连接成功消息 + ws.send( + JSON.stringify({ + type: 'connected', + sessionId, + payload: { message: 'Connected to session' }, + } as ServerMessage) + ); + + console.log(`[WS] Client connected to session: ${sessionId}`); +} + +/** + * WebSocket 消息处理器 + */ +export async function handleWebSocketMessage( + ws: WSContext, + sessionId: string, + data: unknown +): Promise { + const sessionManager = getSessionManager(); + + try { + // 处理不同类型的数据 + let text: string; + if (typeof data === 'string') { + text = data; + } else if (data instanceof ArrayBuffer || data instanceof SharedArrayBuffer) { + text = new TextDecoder().decode(data as ArrayBuffer); + } else if (data instanceof Blob) { + text = await data.text(); + } else { + text = String(data); + } + + const message: ClientMessage = JSON.parse(text); + + switch (message.type) { + case 'message': { + // 用户发送消息 + const userMessage = sessionManager.addMessage(sessionId, { + role: 'user', + content: message.payload?.content || '', + }); + + if (userMessage) { + // 广播用户消息 + broadcastToSession(sessionId, { + type: 'message_received', + sessionId, + payload: userMessage, + }); + + // 更新状态为处理中 + sessionManager.updateStatus(sessionId, 'busy'); + + // TODO: 调用 Agent 处理消息并流式返回 + // 这里需要集成 core 模块的 Agent + // const agent = createAgent(); + // for await (const chunk of agent.stream(message.payload.content)) { + // broadcastToSession(sessionId, { + // type: 'chunk', + // sessionId, + // payload: { content: chunk }, + // }); + // } + + // 模拟响应 (后续替换为真实 Agent 调用) + setTimeout(() => { + const assistantMessage = sessionManager.addMessage(sessionId, { + role: 'assistant', + content: 'This is a placeholder response. Agent integration coming soon.', + }); + + broadcastToSession(sessionId, { + type: 'done', + sessionId, + payload: assistantMessage, + }); + + sessionManager.updateStatus(sessionId, 'idle'); + }, 1000); + } + break; + } + + case 'cancel': { + // 取消当前操作 + // TODO: 实现取消逻辑 + broadcastToSession(sessionId, { + type: 'cancelled', + sessionId, + payload: { message: 'Operation cancelled' }, + }); + sessionManager.updateStatus(sessionId, 'idle'); + break; + } + + case 'tool_response': { + // 工具执行结果 (用于人工确认场景) + // TODO: 处理工具响应 + break; + } + + default: + ws.send( + JSON.stringify({ + type: 'error', + sessionId, + payload: { message: `Unknown message type: ${(message as any).type}` }, + } as ServerMessage) + ); + } + } catch (error) { + ws.send( + JSON.stringify({ + type: 'error', + sessionId, + payload: { + message: error instanceof Error ? error.message : 'Failed to process message', + }, + } as ServerMessage) + ); + } +} + +/** + * WebSocket 关闭处理器 + */ +export function handleWebSocketClose(ws: WSContext, sessionId: string): void { + const conns = connections.get(sessionId); + if (conns) { + conns.delete(ws); + if (conns.size === 0) { + connections.delete(sessionId); + // 当没有连接时,更新会话状态 + const sessionManager = getSessionManager(); + sessionManager.updateStatus(sessionId, 'idle'); + } + } + + console.log(`[WS] Client disconnected from session: ${sessionId}`); +} + +/** + * 获取连接统计 + */ +export function getConnectionStats(): { sessions: number; connections: number } { + let totalConnections = 0; + for (const conns of connections.values()) { + totalConnections += conns.size; + } + return { + sessions: connections.size, + connections: totalConnections, + }; +} diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json new file mode 100644 index 0000000..b37b6b9 --- /dev/null +++ b/packages/server/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..2220156 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1708 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + typescript: + specifier: ^5.6.0 + version: 5.9.3 + + packages/core: + dependencies: + '@ai-sdk/anthropic': + specifier: ^2.0.54 + version: 2.0.55(zod@4.1.13) + '@ai-sdk/deepseek': + specifier: ^1.0.31 + version: 1.0.32(zod@4.1.13) + '@ai-sdk/openai': + specifier: ^2.0.80 + version: 2.0.85(zod@4.1.13) + '@tavily/core': + specifier: ^0.6.0 + version: 0.6.0 + ai: + specifier: ^5.0.108 + version: 5.0.112(zod@4.1.13) + chalk: + specifier: ^5.3.0 + version: 5.6.2 + js-yaml: + specifier: ^4.1.1 + version: 4.1.1 + minimatch: + specifier: ^10.1.1 + version: 10.1.1 + qwen-ai-provider-v5: + specifier: ^1.0.2 + version: 1.0.2(zod@4.1.13) + simple-git: + specifier: ^3.30.0 + version: 3.30.0 + tree-sitter-bash: + specifier: ^0.25.1 + version: 0.25.1 + uuid: + specifier: ^13.0.0 + version: 13.0.0 + vscode-jsonrpc: + specifier: ^8.2.1 + version: 8.2.1 + vscode-languageserver-protocol: + specifier: ^3.17.5 + version: 3.17.5 + web-tree-sitter: + specifier: ^0.25.10 + version: 0.25.10 + yaml: + specifier: ^2.8.2 + version: 2.8.2 + zod: + specifier: ^4.1.13 + version: 4.1.13 + devDependencies: + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + '@types/json-schema': + specifier: ^7.0.15 + version: 7.0.15 + '@types/node': + specifier: ^22.0.0 + version: 22.19.2 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + '@vitest/coverage-v8': + specifier: ^4.0.15 + version: 4.0.15(vitest@4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2)) + typescript: + specifier: ^5.6.0 + version: 5.9.3 + vitest: + specifier: ^4.0.15 + version: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2) + + packages/server: + dependencies: + '@ai-assistant/core': + specifier: workspace:* + version: link:../core + hono: + specifier: ^4.6.0 + version: 4.10.8 + uuid: + specifier: ^13.0.0 + version: 13.0.0 + zod: + specifier: ^4.1.13 + version: 4.1.13 + devDependencies: + '@types/bun': + specifier: ^1.1.0 + version: 1.3.4 + '@types/node': + specifier: ^22.0.0 + version: 22.19.2 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + typescript: + specifier: ^5.6.0 + version: 5.9.3 + vitest: + specifier: ^4.0.15 + version: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2) + +packages: + + '@ai-sdk/anthropic@2.0.55': + resolution: {integrity: sha512-jKOfnEntcR39Wd9b2MUEP2r6ucMyuzY2EYRH1lQzTcZutmEmHxXlIZD17OseFuhuYCKKBlQUBi8GyEl8/qB4qg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/deepseek@1.0.32': + resolution: {integrity: sha512-DDNZSZn6OuExVBJBAWdk3VeyQPH+pYwSykixePhzll9EnT3aakapMYr5gjw3wMl+eZ0tLplythHL1TfIehUZ0g==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/gateway@2.0.21': + resolution: {integrity: sha512-BwV7DU/lAm3Xn6iyyvZdWgVxgLu3SNXzl5y57gMvkW4nGhAOV5269IrJzQwGt03bb107sa6H6uJwWxc77zXoGA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/openai@2.0.85': + resolution: {integrity: sha512-3pzr7qVhsOXwjPAfmvFNZz3sRWCuyMOc3GgLHe7sWY0t8J4hA5mwQ4LISTKYI3iIr8IXzAQn9MUrC8Hiji9RpA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@3.0.19': + resolution: {integrity: sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@2.0.0': + resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} + engines: {node: '>=18'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + cpu: [x64] + os: [win32] + + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + + '@tavily/core@0.6.0': + resolution: {integrity: sha512-QJQko6BtDWFYNeE7BKFVDMPuKfLJWjRVyQmo5jAhG3A3Xgu1e/EIIRTdWFc5TyFccc8t14zrzPxxUy1YL2/AYg==} + + '@types/bun@1.3.4': + resolution: {integrity: sha512-EEPTKXHP+zKGPkhRLv+HI0UEX8/o+65hqARxLy8Ov5rIxMBPNTjeZww00CIihrIQGEQBYg+0roO5qOnS/7boGA==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@22.19.2': + resolution: {integrity: sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@vercel/oidc@3.0.5': + resolution: {integrity: sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==} + engines: {node: '>= 20'} + + '@vitest/coverage-v8@4.0.15': + resolution: {integrity: sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==} + peerDependencies: + '@vitest/browser': 4.0.15 + vitest: 4.0.15 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.0.15': + resolution: {integrity: sha512-Gfyva9/GxPAWXIWjyGDli9O+waHDC0Q0jaLdFP1qPAUUfo1FEXPXUfUkp3eZA0sSq340vPycSyOlYUeM15Ft1w==} + + '@vitest/mocker@4.0.15': + resolution: {integrity: sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.15': + resolution: {integrity: sha512-SWdqR8vEv83WtZcrfLNqlqeQXlQLh2iilO1Wk1gv4eiHKjEzvgHb2OVc3mIPyhZE6F+CtfYjNlDJwP5MN6Km7A==} + + '@vitest/runner@4.0.15': + resolution: {integrity: sha512-+A+yMY8dGixUhHmNdPUxOh0la6uVzun86vAbuMT3hIDxMrAOmn5ILBHm8ajrqHE0t8R9T1dGnde1A5DTnmi3qw==} + + '@vitest/snapshot@4.0.15': + resolution: {integrity: sha512-A7Ob8EdFZJIBjLjeO0DZF4lqR6U7Ydi5/5LIZ0xcI+23lYlsYJAfGn8PrIWTYdZQRNnSRlzhg0zyGu37mVdy5g==} + + '@vitest/spy@4.0.15': + resolution: {integrity: sha512-+EIjOJmnY6mIfdXtE/bnozKEvTC4Uczg19yeZ2vtCz5Yyb0QQ31QWVQ8hswJ3Ysx/K2EqaNsVanjr//2+P3FHw==} + + '@vitest/utils@4.0.15': + resolution: {integrity: sha512-HXjPW2w5dxhTD0dLwtYHDnelK3j8sR8cWIaLxr22evTyY6q8pRCjZSmhRWVjBaOVXChQd6AwMzi9pucorXCPZA==} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ai@5.0.112: + resolution: {integrity: sha512-Y0dluYpe5wn81UkfHbZL78mH6CsceUfMiu4oPRaWZvjlmcoXSPdEAsPcYbOjvX8ZPvQc6m4kNZhkcEXmT2ln4w==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-v8-to-istanbul@0.3.8: + resolution: {integrity: sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bun-types@1.3.4: + resolution: {integrity: sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + chai@6.2.1: + resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} + engines: {node: '>=18'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hono@4.10.8: + resolution: {integrity: sha512-DDT0A0r6wzhe8zCGoYOmMeuGu3dyTAE40HHjwUsWFTEy5WxK1x2WDSsBPlEXgPbRIFY6miDualuUDbasPogIww==} + engines: {node: '>=16.9.0'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + js-tiktoken@1.0.21: + resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.1: + resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + engines: {node: ^18 || ^20 || >= 21} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + qwen-ai-provider-v5@1.0.2: + resolution: {integrity: sha512-IMweAFhHxM2OZzeZKyDUfcxCQCLkFioQv9TkprAXttV6XeTBTSjjUc17S9dUW4rOgtWLsCXoAkaAPUHj1jQYtg==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + simple-git@3.30.0: + resolution: {integrity: sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + + tree-sitter-bash@0.25.1: + resolution: {integrity: sha512-7hMytuYIMoXOq24yRulgIxthE9YmggZIOHCyPTTuJcu6EU54tYD+4G39cUb28kxC6jMf/AbPfWGLQtgPTdh3xw==} + peerDependencies: + tree-sitter: ^0.25.0 + peerDependenciesMeta: + tree-sitter: + optional: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + + vite@7.2.7: + resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + 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 + + vitest@4.0.15: + resolution: {integrity: sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.15 + '@vitest/browser-preview': 4.0.15 + '@vitest/browser-webdriverio': 4.0.15 + '@vitest/ui': 4.0.15 + happy-dom: '*' + jsdom: '*' + 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/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-jsonrpc@8.2.1: + resolution: {integrity: sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + web-tree-sitter@0.25.10: + resolution: {integrity: sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA==} + peerDependencies: + '@types/emscripten': ^1.40.0 + peerDependenciesMeta: + '@types/emscripten': + optional: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + + zod@4.1.13: + resolution: {integrity: sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==} + +snapshots: + + '@ai-sdk/anthropic@2.0.55(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + zod: 4.1.13 + + '@ai-sdk/deepseek@1.0.32(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + zod: 4.1.13 + + '@ai-sdk/gateway@2.0.21(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + '@vercel/oidc': 3.0.5 + zod: 4.1.13 + + '@ai-sdk/openai@2.0.85(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + zod: 4.1.13 + + '@ai-sdk/provider-utils@3.0.19(zod@4.1.13)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.13 + + '@ai-sdk/provider@2.0.0': + dependencies: + json-schema: 0.4.0 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bcoe/v8-coverage@1.0.2': {} + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@opentelemetry/api@1.9.0': {} + + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': + optional: true + + '@standard-schema/spec@1.0.0': {} + + '@tavily/core@0.6.0': + dependencies: + axios: 1.13.2 + https-proxy-agent: 7.0.6 + js-tiktoken: 1.0.21 + transitivePeerDependencies: + - debug + - supports-color + + '@types/bun@1.3.4': + dependencies: + bun-types: 1.3.4 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/js-yaml@4.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@22.19.2': + dependencies: + undici-types: 6.21.0 + + '@types/uuid@10.0.0': {} + + '@vercel/oidc@3.0.5': {} + + '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2))': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.0.15 + ast-v8-to-istanbul: 0.3.8 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.2.0 + magicast: 0.5.1 + obug: 2.1.1 + std-env: 3.10.0 + tinyrainbow: 3.0.3 + vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@4.0.15': + dependencies: + '@standard-schema/spec': 1.0.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.15 + '@vitest/utils': 4.0.15 + chai: 6.2.1 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.15(vite@7.2.7(@types/node@22.19.2)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.15 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.2.7(@types/node@22.19.2)(yaml@2.8.2) + + '@vitest/pretty-format@4.0.15': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.15': + dependencies: + '@vitest/utils': 4.0.15 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.15': + dependencies: + '@vitest/pretty-format': 4.0.15 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.0.15': {} + + '@vitest/utils@4.0.15': + dependencies: + '@vitest/pretty-format': 4.0.15 + tinyrainbow: 3.0.3 + + agent-base@7.1.4: {} + + ai@5.0.112(zod@4.1.13): + dependencies: + '@ai-sdk/gateway': 2.0.21(zod@4.1.13) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + '@opentelemetry/api': 1.9.0 + zod: 4.1.13 + + argparse@2.0.1: {} + + assertion-error@2.0.1: {} + + ast-v8-to-istanbul@0.3.8: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + + asynckit@0.4.0: {} + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + base64-js@1.5.1: {} + + bun-types@1.3.4: + dependencies: + '@types/node': 22.19.2 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + chai@6.2.1: {} + + chalk@5.6.2: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + delayed-stream@1.0.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + eventsource-parser@3.0.6: {} + + expect-type@1.3.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + follow-redirects@1.15.11: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + gopd@1.2.0: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hono@4.10.8: {} + + html-escaper@2.0.2: {} + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + js-tiktoken@1.0.21: + dependencies: + base64-js: 1.5.1 + + js-tokens@9.0.1: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-schema@0.4.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.1: + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.3 + + math-intrinsics@1.1.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + node-addon-api@8.5.0: {} + + node-gyp-build@4.8.4: {} + + obug@2.1.1: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + proxy-from-env@1.1.0: {} + + qwen-ai-provider-v5@1.0.2(zod@4.1.13): + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.19(zod@4.1.13) + zod: 4.1.13 + + rollup@4.53.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 + fsevents: 2.3.3 + + semver@7.7.3: {} + + siginfo@2.0.0: {} + + simple-git@3.30.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tinybench@2.9.0: {} + + tinyexec@1.0.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.0.3: {} + + tree-sitter-bash@0.25.1: + dependencies: + node-addon-api: 8.5.0 + node-gyp-build: 4.8.4 + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + uuid@13.0.0: {} + + vite@7.2.7(@types/node@22.19.2)(yaml@2.8.2): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.2 + fsevents: 2.3.3 + yaml: 2.8.2 + + vitest@4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.2)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.15 + '@vitest/mocker': 4.0.15(vite@7.2.7(@types/node@22.19.2)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.15 + '@vitest/runner': 4.0.15 + '@vitest/snapshot': 4.0.15 + '@vitest/spy': 4.0.15 + '@vitest/utils': 4.0.15 + es-module-lexer: 1.7.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: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.2.7(@types/node@22.19.2)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 22.19.2 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vscode-jsonrpc@8.2.0: {} + + vscode-jsonrpc@8.2.1: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-types@3.17.5: {} + + web-tree-sitter@0.25.10: {} + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + yaml@2.8.2: {} + + zod@4.1.13: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..18ec407 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'packages/*'