Compare commits

...

5 Commits

Author SHA1 Message Date
abeatrix e9bef4253a add tests 2026-02-04 12:33:11 +08:00
abeatrix 2a1c3fd9ba update fetch to work with both bun and node fetch 2026-02-04 12:10:02 +08:00
abeatrix 5ac991902b fix scripts 2026-02-04 12:05:02 +08:00
abeatrix c40c7c098c update bun lock 2026-02-04 12:02:27 +08:00
abeatrix b62c7874f6 chore: migrate from npm to bun as package manager
Replace all npm commands with bun equivalents across the entire codebase including:
- CI/CD workflows (GitHub Actions)
- Setup scripts and hooks
- Documentation and guidelines
- Test scripts and coverage checks
- Package.json scripts
- Pull request templates

This migration improves installation speed and reduces dependency resolution time while maintaining compatibility with existing workflows.
2026-02-04 11:27:56 +08:00
41 changed files with 6574 additions and 41389 deletions
+2 -2
View File
@@ -41,11 +41,11 @@ fi
# Install project dependencies
echo "Installing dependencies..."
npm run install:all
bun run install:all
# Generate gRPC/protobuf types (required for TypeScript)
echo "Generating proto types..."
npm run protos
bun run protos
echo ""
echo "Session setup complete!"
+1 -1
View File
@@ -42,7 +42,7 @@ Here, we use the common `StringRequest` and `KeyValuePair` types.
After editing a `.proto` file, regenerate the TypeScript code. From the project root, run:
```bash
npm run protos
bun run protos
```
This command compiles all `.proto` files and outputs the generated code to `src/generated/` and `src/shared/`. Do not edit these generated files manually.
+1 -1
View File
@@ -98,7 +98,7 @@ On the main branch, create a commit that updates:
Each changeset file in `.changeset/` corresponds to a PR. Read them to identify which ones belong to the commits you're hotfixing, then delete those files.
**Skip running `npm run install:all`** - the automation handles outdated lockfiles.
**Skip running `bun run install:all`** - the automation handles outdated lockfiles.
Commit with message format: `v{VERSION} Release Notes (hotfix)`
+2 -2
View File
@@ -59,8 +59,8 @@ We're not looking for exhaustive documentation - just evidence that you've thoug
<!-- Put an 'x' in all boxes that apply -->
- [ ] Changes are limited to a single feature, bugfix or chore (split larger changes into separate PRs)
- [ ] Tests are passing (`npm test`) and code is formatted and linted (`npm run format && npm run lint`)
- [ ] I have created a changeset using `npm run changeset` (required for user-facing changes)
- [ ] Tests are passing (`bun test`) and code is formatted and linted (`bun run format && bun run lint`)
- [ ] I have created a changeset using `bun run changeset` (required for user-facing changes)
- [ ] I have reviewed [contributor guidelines](https://github.com/cline/cline/blob/main/CONTRIBUTING.md)
### Screenshots
+3 -3
View File
@@ -62,9 +62,9 @@ class TestCoverage(unittest.TestCase):
# Use xvfb-run on Linux
if sys.platform.startswith('linux'):
cmd = f"cd {root_dir} && xvfb-run -a npm run test:coverage > {cls.extension_coverage_file} 2>&1"
cmd = f"cd {root_dir} && xvfb-run -a bun run test:coverage > {cls.extension_coverage_file} 2>&1"
else:
cmd = f"cd {root_dir} && npm run test:coverage > {cls.extension_coverage_file} 2>&1"
cmd = f"cd {root_dir} && bun run test:coverage > {cls.extension_coverage_file} 2>&1"
log("Running extension tests...")
log(f"Command: {cmd}")
@@ -73,7 +73,7 @@ class TestCoverage(unittest.TestCase):
# Run webview tests with coverage
log("Running webview tests...")
cmd = f"cd {webview_dir} && npm run test:coverage > {cls.webview_coverage_file} 2>&1"
cmd = f"cd {webview_dir} && bun run test:coverage > {cls.webview_coverage_file} 2>&1"
log(f"Command: {cmd}")
result = subprocess.run(cmd, shell=True, check=False, capture_output=True, text=True)
log(f"Webview tests exit code: {result.returncode}")
+9 -28
View File
@@ -35,26 +35,10 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: 22
# Cache root dependencies - only reuse if package-lock.json exactly matches
- name: Cache root dependencies
uses: actions/cache@v4
id: root-cache
with:
path: node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
# Cache webview-ui dependencies - only reuse if package-lock.json exactly matches
- name: Cache webview-ui dependencies
uses: actions/cache@v4
id: webview-cache
with:
path: webview-ui/node_modules
key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }}
bun-version: latest
# Cache VS Code installation
- name: Cache VS Code
@@ -75,20 +59,17 @@ jobs:
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
~/AppData/Local/ms-playwright
key: playwright-browsers-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
key: playwright-browsers-${{ runner.os }}-${{ hashFiles('bun.lockb') }}
restore-keys: |
playwright-browsers-${{ runner.os }}-
- name: Install root dependencies
run: npm ci
- name: Install dependencies
run: bun install --frozen-lockfile
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci
- name: Install vsce
run: npm install -g @vscode/vsce
run: bun add -g @vscode/vsce
- name: Install xvfb on Linux
if: matrix.runner == 'ubuntu'
@@ -97,11 +78,11 @@ jobs:
# Run optimized E2E tests (eliminates redundant builds)
- name: Run E2E tests - Linux
if: matrix.runner == 'ubuntu'
run: xvfb-run -a npm run test:e2e:optimal
run: xvfb-run -a bun run test:e2e:optimal
- name: Run E2E tests - Non-Linux
if: matrix.runner != 'ubuntu'
run: npm run test:e2e:optimal
run: bun run test:e2e:optimal
- uses: actions/upload-artifact@v4
if: ${{ failure() }}
+7 -26
View File
@@ -33,35 +33,16 @@ jobs:
fi
echo "Found recent commits, proceeding with build"
- name: Setup Node.js
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: "lts/*"
bun-version: latest
# Cache root dependencies - only reuse if package-lock.json exactly matches
- name: Cache root dependencies
uses: actions/cache@v4
id: root-cache
with:
path: node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
# Cache webview-ui dependencies - only reuse if package-lock.json exactly matches
- name: Cache webview-ui dependencies
uses: actions/cache@v4
id: webview-cache
with:
path: webview-ui/node_modules
key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }}
- name: Install root dependencies
run: npm ci --include=optional
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci --include=optional
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Publishing Tools
run: npm install -g @vscode/vsce ovsx
run: bun add -g @vscode/vsce ovsx
- name: Publish Extension as Pre-release
env:
@@ -77,4 +58,4 @@ jobs:
OTEL_EXPORTER_OTLP_PROTOCOL: ${{ secrets.OTEL_EXPORTER_OTLP_PROTOCOL }}
OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.OTEL_EXPORTER_OTLP_ENDPOINT }}
OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.OTEL_EXPORTER_OTLP_HEADERS }}
run: npm run publish:marketplace:nightly
run: bun run publish:marketplace:nightly
+8 -29
View File
@@ -39,37 +39,16 @@ jobs:
fetch-depth: 0
fetch-tags: true
- name: Setup Node.js
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: "lts/*"
bun-version: latest
# Cache root dependencies - only reuse if package-lock.json exactly matches
- name: Cache root dependencies
uses: actions/cache@v4
id: root-cache
with:
path: node_modules
key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
# Cache webview-ui dependencies - only reuse if package-lock.json exactly matches
- name: Cache webview-ui dependencies
uses: actions/cache@v4
id: webview-cache
with:
path: webview-ui/node_modules
key: ${{ runner.os }}-npm-webview-${{ hashFiles('webview-ui/package-lock.json') }}
- name: Install root dependencies
if: steps.root-cache.outputs.cache-hit != 'true'
run: npm install --include=optional
- name: Install webview-ui dependencies
if: steps.webview-cache.outputs.cache-hit != 'true'
run: cd webview-ui && npm install --include=optional
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Publishing Tools
run: npm install -g @vscode/vsce ovsx
run: bun add -g @vscode/vsce ovsx
- name: Get Version
id: get_version
@@ -111,10 +90,10 @@ jobs:
vsce package --allow-package-secrets sendgrid --out "cline-${{ steps.get_version.outputs.version }}.vsix"
if [ "${{ github.event.inputs.release-type }}" = "pre-release" ]; then
npm run publish:marketplace:prerelease
bun run publish:marketplace:prerelease
echo "Successfully published pre-release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry"
else
npm run publish:marketplace
bun run publish:marketplace
echo "Successfully published release version ${{ steps.get_version.outputs.version }} to VS Code Marketplace and Open VSX Registry"
fi
+27 -55
View File
@@ -24,26 +24,18 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: 22
cache: 'npm'
cache-dependency-path: |
package-lock.json
webview-ui/package-lock.json
cli/package-lock.json
bun-version: latest
- name: Install root dependencies
run: npm ci
- name: Install dependencies
run: bun install --frozen-lockfile
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci
- name: Run Quality Checks (Parallel)
run: npm run ci:check-all
run: bun run ci:check-all
test:
needs: quality-checks
@@ -60,66 +52,54 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: 22
cache: 'npm'
cache-dependency-path: |
package-lock.json
webview-ui/package-lock.json
bun-version: latest
- name: Install root dependencies
run: npm ci
- name: Install dependencies
run: bun install --frozen-lockfile
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci
- name: Set up NPM on Windows
if: runner.os == 'Windows'
run: |
npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"
# Build the extension and tests (without redundant checks)
- name: Build Tests and Extension
id: build_step
run: npm run ci:build
run: bun run ci:build
- name: Unit Tests with coverage - Linux
id: unit_tests_linux
if: ${{ !cancelled() && steps.build_step.outcome == 'success' && runner.os == 'Linux' }}
run: |
npx nyc --nycrc-path .nycrc.unit.json --reporter=lcov npm run test:unit
bunx nyc --nycrc-path .nycrc.unit.json --reporter=lcov bun run test:unit
- name: Unit Tests - Non-Linux
id: unit_tests_non_linux
if: ${{ !cancelled() && steps.build_step.outcome == 'success' && runner.os != 'Linux' }}
run: |
npm run test:unit
bun run test:unit
- name: Extension Integration Tests - Linux
id: integration_tests_linux
if: ${{ !cancelled() && steps.build_step.outcome == 'success' && runner.os == 'Linux' }}
run: xvfb-run -a npm run test:coverage
run: xvfb-run -a bun run test:coverage
- name: Extension Integration Tests - Non-Linux
id: integration_tests_non_linux
if: ${{ !cancelled() && steps.build_step.outcome == 'success' && runner.os != 'Linux' }}
run: npm run test:integration
run: bun run test:integration
- name: Webview Tests with Coverage
id: webview_tests
if: ${{ !cancelled() && steps.build_step.outcome == 'success' }}
run: |
cd webview-ui
npm run test:coverage
bun run test:coverage
- name: CLI Tests
id: cli_tests
if: ${{ !cancelled() && steps.build_step.outcome == 'success' }}
run: cd cli && npm run test:run
run: cd cli && bun run test:run
- name: Save Coverage Reports
uses: actions/upload-artifact@v4
@@ -138,36 +118,28 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
node-version: 22
cache: 'npm'
cache-dependency-path: |
package-lock.json
webview-ui/package-lock.json
testing-platform/package-lock.json
bun-version: latest
- name: Install root dependencies
run: npm ci
- name: Install dependencies
run: bun install --frozen-lockfile
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install webview-ui dependencies
run: cd webview-ui && npm ci
- name: Download ripgrep binaries
run: npm run download-ripgrep
run: bun run download-ripgrep
- name: Compile Standalone
run: npm run compile-standalone
run: bun run compile-standalone
- name: Install testing platform dependencies
run: cd testing-platform && npm ci
run: cd testing-platform && bun install
- name: Running testing platform integration spec tests
timeout-minutes: 7
run: npm run test:tp-orchestrator -- tests/specs/ --count=1 --coverage
run: bun run test:tp-orchestrator -- tests/specs/ --count=1 --coverage
- name: Save Coverage Reports
uses: actions/upload-artifact@v4
+3
View File
@@ -10,7 +10,10 @@ tmp
.idea
.husky/_/
# Package manager lock files (we use Bun, so bun.lockb is NOT ignored)
pnpm-lock.yaml
package-lock.json
yarn.lock
.clineignore
.venv
+91 -50
View File
@@ -5,8 +5,12 @@
"tasks": [
{
"label": "compile-standalone",
"type": "npm",
"script": "compile-standalone",
"type": "shell",
"command": "bun",
"args": [
"run",
"compile-standalone"
],
"group": "build",
"problemMatcher": [],
"presentation": {
@@ -14,9 +18,13 @@
}
},
{
"label": "npm: protos",
"type": "npm",
"script": "protos",
"label": "bun:protos",
"type": "shell",
"command": "bun",
"args": [
"run",
"protos"
],
"problemMatcher": [],
"isBackground": false,
"presentation": {
@@ -31,11 +39,11 @@
{
"label": "watch",
"dependsOn": [
"npm: protos",
"npm: build:webview",
"npm: dev:webview",
"npm: watch:tsc",
"npm: watch:esbuild"
"bun:protos",
"bun:build:webview",
"bun:dev:webview",
"bun:watch:tsc",
"bun:watch:esbuild"
],
"presentation": {
"reveal": "always"
@@ -48,11 +56,11 @@
{
"label": "watch:test",
"dependsOn": [
"npm: protos",
"npm: build:webview:test",
"npm: dev:webview",
"npm: watch:tsc",
"npm: watch:esbuild:test"
"bun:protos",
"bun:build:webview:test",
"bun:dev:webview",
"bun:watch:tsc",
"bun:watch:esbuild:test"
],
"presentation": {
"reveal": "always"
@@ -60,14 +68,18 @@
"group": "build"
},
{
"type": "npm",
"script": "build:webview",
"type": "shell",
"command": "bun",
"args": [
"run",
"build:webview"
],
"group": "build",
"problemMatcher": [],
"isBackground": true,
"label": "npm: build:webview",
"label": "bun:build:webview",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -80,14 +92,18 @@
}
},
{
"type": "npm",
"script": "build:webview:test",
"type": "shell",
"command": "bun",
"args": [
"run",
"build:webview:test"
],
"group": "build",
"problemMatcher": [],
"isBackground": true,
"label": "npm: build:webview:test",
"label": "bun:build:webview:test",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -101,8 +117,12 @@
}
},
{
"type": "npm",
"script": "dev:webview",
"type": "shell",
"command": "bun",
"args": [
"run",
"dev:webview"
],
"group": "build",
"problemMatcher": [
{
@@ -122,9 +142,9 @@
}
],
"isBackground": true,
"label": "npm: dev:webview",
"label": "bun:dev:webview",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -137,8 +157,12 @@
}
},
{
"type": "npm",
"script": "watch:esbuild",
"type": "shell",
"command": "bun",
"args": [
"run",
"watch:esbuild"
],
"group": "build",
"problemMatcher": {
"pattern": [
@@ -160,9 +184,9 @@
}
},
"isBackground": true,
"label": "npm: watch:esbuild",
"label": "bun:watch:esbuild",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -175,8 +199,12 @@
}
},
{
"type": "npm",
"script": "watch:esbuild:test",
"type": "shell",
"command": "bun",
"args": [
"run",
"watch:esbuild:test"
],
"group": "build",
"problemMatcher": {
"pattern": [
@@ -198,9 +226,9 @@
}
},
"isBackground": true,
"label": "npm: watch:esbuild:test",
"label": "bun:watch:esbuild:test",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -214,14 +242,18 @@
}
},
{
"type": "npm",
"script": "watch:tsc",
"type": "shell",
"command": "bun",
"args": [
"run",
"watch:tsc"
],
"group": "build",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"label": "npm: watch:tsc",
"label": "bun:watch:tsc",
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"group": "watch",
@@ -229,12 +261,17 @@
}
},
{
"type": "npm",
"script": "watch-tests",
"type": "shell",
"command": "bun",
"args": [
"run",
"watch-tests"
],
"label": "bun:watch-tests",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"dependsOn": [
"npm: protos"
"bun:protos"
],
"presentation": {
"reveal": "always",
@@ -245,9 +282,9 @@
{
"label": "tasks: watch-tests",
"dependsOn": [
"npm: protos",
"npm: watch",
"npm: watch-tests"
"bun:protos",
"bun:watch",
"bun:watch-tests"
],
"problemMatcher": []
},
@@ -265,15 +302,19 @@
"command": "rm -rf ${workspaceFolder}/dist/tmp/user && mkdir -p ${workspaceFolder}/dist/tmp/user"
},
{
"type": "npm",
"script": "storybook",
"type": "shell",
"command": "bun",
"args": [
"run",
"storybook"
],
"group": "build",
"problemMatcher": [],
"isBackground": false,
"label": "npm: storybook",
"label": "bun:storybook",
"dependsOn": [
"npm: protos",
"npm: build:webview"
"bun:protos",
"bun:build:webview"
],
"presentation": {
"reveal": "always"
+38 -22
View File
@@ -34,23 +34,38 @@ We also welcome contributions to our [documentation](https://github.com/cline/cl
### Local Development Instructions
1. Clone the repository _(Requires [git-lfs](https://git-lfs.com/))_:
> **Note**: This project uses [Bun](https://bun.sh) as the package manager.
1. Install Bun (if you haven't already):
```bash
# macOS/Linux
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"
```
2. Clone the repository _(Requires [git-lfs](https://git-lfs.com/))_:
```bash
git clone https://github.com/cline/cline.git
```
2. Open the project in VSCode:
3. Open the project in VSCode:
```bash
code cline
```
3. Install the necessary dependencies for the extension and webview-gui:
4. Install dependencies (installs for all workspaces):
```bash
npm run install:all
bun install
```
4. Generate Protocol Buffer files (required before first build):
5. Generate Protocol Buffer files (required before first build):
```bash
npm run protos
bun run protos
```
5. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.)
6. Launch by pressing `F5` (or `Run`->`Start Debugging`) to open a new VSCode window with the extension loaded. (You may need to install the [esbuild problem matchers extension](https://marketplace.visualstudio.com/items?itemName=connor4312.esbuild-problem-matchers) if you run into issues building the project.)
@@ -59,7 +74,7 @@ We also welcome contributions to our [documentation](https://github.com/cline/cl
1. Before creating a PR, generate a changeset entry:
```bash
npm run changeset
bun run changeset
```
This will prompt you for:
- Type of change (major, minor, patch)
@@ -75,9 +90,10 @@ We also welcome contributions to our [documentation](https://github.com/cline/cl
- Changesetbot will create a comment showing the version impact
- When merged to main, changesetbot will create a Version Packages PR
- When the Version Packages PR is merged, a new release will be published
4. Testing
- Run `npm run test` to run tests locally.
- Before submitting PR, run `npm run format:fix` to format your code
- Run `bun run test` to run tests locally
- Before submitting PR, run `bun run format:fix` to format your code
### Extension
@@ -88,12 +104,12 @@ We also welcome contributions to our [documentation](https://github.com/cline/cl
- If you dismissed the prompts, you can install them manually from the Extensions panel
2. **Local Development**
- Run `npm run install:all` to install dependencies
- Run `npm run protos` to generate Protocol Buffer files (required before first build)
- Run `npm run test` to run tests locally
- Run `bun run install:all` to install dependencies
- Run `bun run protos` to generate Protocol Buffer files (required before first build)
- Run `bun run test` to run tests locally
- Run → Start Debugging or `>Debug: Select and Start Debugging` and wait for a new VS Code instance to open
- **Terminal Workflow**: Use `npm run dev` (generates protos + runs watch mode) or `npm run watch` (if protos already generated)
- Before submitting PR, run `npm run format:fix` to format your code
- **Terminal Workflow**: Use `bun run dev` (generates protos + runs watch mode) or `bun run watch` (if protos already generated)
- Before submitting PR, run `bun run format:fix` to format your code
3. **Linux-specific Setup**
VS Code extension tests on Linux require the following system libraries:
@@ -149,8 +165,8 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines
2. **Code Quality**
- Run `npm run lint` to check code style
- Run `npm run format` to automatically format code
- Run `bun run lint` to check code style
- Run `bun run format` to automatically format code
- All PRs must pass CI checks which include both linting and formatting
- Address any warnings or errors from linter before submitting
- Follow TypeScript best practices and maintain type safety
@@ -158,7 +174,7 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines
3. **Testing**
- Add tests for new features
- Run `npm test` to ensure all tests pass
- Run `bun test` to ensure all tests pass
- Update existing tests if your changes affect them
- Include both unit tests and integration tests where appropriate
@@ -168,9 +184,9 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines
- **Running E2E tests:**
```bash
npm run test:e2e # Build and run all E2E tests
npm run e2e # Run tests without rebuilding
npm run test:e2e -- --debug # Run with interactive debugger
bun run test:e2e # Build and run all E2E tests
bun run e2e # Run tests without rebuilding
bun run test:e2e -- --debug # Run with interactive debugger
```
- **Writing E2E tests:**
@@ -194,7 +210,7 @@ Anyone can contribute code to Cline, but we ask that you follow these guidelines
4. **Version Management with Changesets**
- Create a changeset for any user-facing changes using `npm run changeset`
- Create a changeset for any user-facing changes using `bun run changeset`
- Choose the appropriate version bump:
- `major` for breaking changes (1.0.0 → 2.0.0)
- `minor` for new features (1.0.0 → 1.1.0)
+3 -1
View File
@@ -124,7 +124,9 @@
"!**/webview-ui/build",
"!**/generated",
"!**/proto",
"!**/tests/specs"
"!**/tests/specs",
"!**/*.lock*",
"!**/*-lock.json"
]
},
"plugins": [
+6045
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
# Bun configuration for Cline monorepo
[install]
# Use npm for package resolution compatibility
registry = "https://registry.npmjs.org/"
# Cache configuration
[install.cache]
# Enable caching for faster installs
disable = false
[install.scopes]
# Configure scoped registries if needed
# "@myorg" = "https://registry.example.com/"
[test]
# Test configuration
preload = []
+25 -25
View File
@@ -13,7 +13,7 @@ The official CLI for Cline. Run Cline tasks directly from the terminal with the
## Prerequisites
- Node.js 20.x or later
- npm or yarn
- bun or npm or yarn
- The parent Cline project dependencies installed
## Installation
@@ -22,13 +22,13 @@ From the repository root:
```bash
# Install all dependencies first
npm run install:all
bun install
# Ensure protos are generated
npm run protos
bun run protos
# Build and link the CLI globally
npm run cli:link
bun run cli:link
```
## Usage
@@ -192,10 +192,10 @@ These options are available for the default command (running a task directly):
```bash
# 1. Install all dependencies (root, webview-ui, cli)
npm run install:all
bun install
# 2. Build and link globally so you can run `cline` from anywhere
npm run cli:link
bun run cli:link
# 3. Test it
cline --help
@@ -207,29 +207,29 @@ Run these from the repository root:
| Script | Description |
|--------|-------------|
| `npm run install:all` | Install deps for root, webview-ui, and cli |
| `npm run cli:build` | Generate protos and build CLI |
| `npm run cli:build:production` | Production build (minified) |
| `npm run cli:link` | Build and `npm link` so you can run `cline` from anywhere |
| `npm run cli:unlink` | Remove the global `cline` symlink |
| `npm run cli:dev` | Link + watch mode for development |
| `npm run cli:watch` | Watch mode only (no initial build) |
| `npm run cli:test` | Run CLI tests |
| `bun install` | Install deps for root, webview-ui, and cli |
| `bun run cli:build` | Generate protos and build CLI |
| `bun run cli:build:production` | Production build (minified) |
| `bun run cli:link` | Build and `bun link` so you can run `cline` from anywhere |
| `bun run cli:unlink` | Remove the global `cline` symlink |
| `bun run cli:dev` | Link + watch mode for development |
| `bun run cli:watch` | Watch mode only (no initial build) |
| `bun run cli:test` | Run CLI tests |
### Development Workflow
1. Run `npm run cli:dev` - this links the CLI globally and starts watch mode
1. Run `bun run cli:dev` - this links the CLI globally and starts watch mode
2. Make changes to files in `cli/src/`
3. The build automatically rebuilds on save
4. Test your changes by running `cline` in another terminal
5. When done, run `npm run cli:unlink` to clean up
5. When done, run `bun run cli:unlink` to clean up
### Proto Generation
The CLI uses proto-generated types for message passing (same as the VS Code extension). If you modify any `.proto` files, run:
```bash
npm run protos
bun run protos
```
This generates TypeScript types in `src/generated/` that both the CLI and extension use.
@@ -238,12 +238,12 @@ This generates TypeScript types in `src/generated/` that both the CLI and extens
#### 1. Publish to npm
```bash
npm publish
bun publish
```
#### 2. Update the Homebrew formula
```bash
npm run update-brew-formula
bun run update-brew-formula
```
#### 3. Test the formula locally
@@ -335,13 +335,13 @@ If you encounter build errors:
```bash
# Make sure all deps are installed
npm run install:all
bun install
# Regenerate proto types
npm run protos
bun run protos
# Then rebuild
npm run cli:build
bun run cli:build
```
### "command not found: cline"
@@ -349,16 +349,16 @@ npm run cli:build
The CLI isn't linked globally. Run:
```bash
npm run cli:link
bun run cli:link
```
### Changes Not Reflected
If your code changes aren't showing up:
1. Make sure watch mode is running (`npm run cli:dev`)
1. Make sure watch mode is running (`bun run cli:dev`)
2. Check for TypeScript errors in the watch output
3. Try unlinking and relinking: `npm run cli:unlink && npm run cli:link`
3. Try unlinking and relinking: `bun run cli:unlink && bun run cli:link`
### Import Errors from Core
+4 -4
View File
@@ -116,7 +116,7 @@ Authenticate a provider and configure the model.
Check for updates and install if available.
**cline update** [*options*] : Check npm for newer versions. Options:
**cline update** [*options*] : Check bun for newer versions. Options:
**-v**, **\--verbose** : Show verbose output
@@ -293,11 +293,11 @@ Format: `{"allow": ["pattern1", "pattern2"], "deny": ["pattern3"], "allowRedirec
**Examples:**
```bash
# Allow only npm and git commands.
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *"]}'
# Allow only bun and git commands.
export CLINE_COMMAND_PERMISSIONS='{"allow": ["bun *", "git *"]}'
# Allow development commands but deny dangerous ones. Deny not strictly required here since allow is set.
export CLINE_COMMAND_PERMISSIONS='{"allow": ["npm *", "git *", "node *"], "deny": ["rm -rf *", "sudo *"]}'
export CLINE_COMMAND_PERMISSIONS='{"allow": ["bun *", "git *", "node *"], "deny": ["rm -rf *", "sudo *"]}'
# Allow file operations with redirects
export CLINE_COMMAND_PERMISSIONS='{"allow": ["cat *", "echo *"], "allowRedirects": true}'
-2950
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -21,16 +21,16 @@
"node": ">=20.0.0"
},
"scripts": {
"package:brew": "npx tsx ./scripts/update-brew-formula.mts",
"package": "npm pack --pack-destination ./dist",
"build": "npm run typecheck && npx tsx esbuild.mts",
"build:production": "npm run typecheck && npx tsx esbuild.mts --production",
"watch": "npx tsx esbuild.mts --watch",
"dev": "IS_DEV=true && npm run link && npm run watch ; npm run unlink",
"package:brew": "bunx tsx ./scripts/update-brew-formula.mts",
"package": "bun pm pack --pack-destination ./dist",
"build": "bun run typecheck && bunx tsx esbuild.mts",
"build:production": "bun run typecheck && bunx tsx esbuild.mts --production",
"watch": "bunx tsx esbuild.mts --watch",
"dev": "IS_DEV=true && bun run link && bun run watch ; bun run unlink",
"clean": "rimraf dist",
"typecheck": "npx tsc --noEmit",
"link": "npm run build && npm link",
"unlink": "npm unlink -g cline",
"typecheck": "bunx tsc --noEmit",
"link": "bun run build && bun link",
"unlink": "bun unlink",
"test": "vitest",
"test:run": "vitest run"
},
+8 -8
View File
@@ -22,7 +22,7 @@ If you need to install or update Node.js, visit [nodejs.org](https://nodejs.org)
Install globally via npm:
```bash
npm install -g cline
bun install -g cline
```
Verify the installation:
@@ -32,7 +32,7 @@ cline version
```
<Tip>
To install a specific version, use `npm install -g cline@2.0.0`. Check [npm](https://www.npmjs.com/package/cline) for available versions.
To install a specific version, use `bun install -g cline@2.0.0`. Check [npm](https://www.npmjs.com/package/cline) for available versions.
</Tip>
## Authenticate
@@ -186,7 +186,7 @@ cline update
Or update manually via npm:
```bash
npm update -g cline
bun update -g cline
```
## Troubleshooting
@@ -195,14 +195,14 @@ npm update -g cline
If `cline` is not found after installation:
1. Ensure npm global bin is in your PATH:
1. Ensure bun global bin is in your PATH:
```bash
npm bin -g
bun bin -g
```
2. Add the path to your shell configuration (`.bashrc`, `.zshrc`, etc.):
```bash
export PATH="$PATH:$(npm bin -g)"
export PATH="$PATH:$(bun bin -g)"
```
3. Restart your terminal or source your shell config.
@@ -215,7 +215,7 @@ If you get permission errors during installation:
# Option 1: Use a Node version manager (recommended)
# nvm, fnm, or volta handle permissions automatically
# Option 2: Fix npm permissions
# Option 2: Fix bun permissions
# See: https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally
```
@@ -244,7 +244,7 @@ If your API key is rejected:
To remove Cline CLI:
```bash
npm uninstall -g cline
bun uninstall -g cline
```
To also remove configuration data:
+1 -1
View File
@@ -281,7 +281,7 @@ We began by bootstrapping the project:
```bash
npx @modelcontextprotocol/create-server alphaadvantage-mcp
cd alphaadvantage-mcp
npm install axios node-cache
bun install axios node-cache
```
Next, we structured our project with:
+4 -4
View File
@@ -62,7 +62,7 @@ Documentation should be verified for accuracy by cross-referencing with source c
4. Verify slash commands against `cli/src/components/HelpPanelContent.tsx`
5. Verify config options against `cli/src/components/ConfigView.tsx` and `SettingsPanelContent.tsx`
6. Verify import sources against `cli/src/utils/import-configs.ts`
7. Run `npm run docs:dev` (if available) to preview documentation locally
7. Run `bun run docs:dev` (if available) to preview documentation locally
**Content accuracy checks:**
- [ ] All keyboard shortcuts match source code
@@ -218,7 +218,7 @@ Add new pages to the CLI navigation group:
- Remove "Preview Release - macOS and Linux Only" warning (CLI is now GA and supports Windows)
- Add note that CLI supports macOS, Linux, and Windows
- Add Node.js version requirement (20+, recommend 22)
- Add version specification (`npm install -g cline@2.0.0`)
- Add version specification (`bun install -g cline@2.0.0`)
- Add more detail on post-install authentication
- Link to new authentication guide
- Add troubleshooting tips
@@ -226,7 +226,7 @@ Add new pages to the CLI navigation group:
**New structure:**
1. Prerequisites (Node.js version)
2. Installation: `npm install -g cline` (or `npm install -g cline@2.0.0`)
2. Installation: `bun install -g cline` (or `bun install -g cline@2.0.0`)
3. Authentication (`cline auth` - link to auth guide)
4. Quick Start (two paths: TUI and CLI)
5. Next Steps (links to guides)
@@ -302,7 +302,7 @@ Add a callout at the top noting that instance commands (`cline instance new/list
After implementation, verify these user requirements are documented:
- [x] New TUI experience explained
- [x] NPM installation covered
- [x] bun installation covered
- [x] Authorization options:
- [x] Sign in with Cline
- [x] Sign in with ChatGPT Subscription (Codex OAuth)
-21618
View File
File diff suppressed because it is too large Load Diff
+49 -47
View File
@@ -5,7 +5,8 @@
"version": "3.56.2",
"icon": "assets/icons/icon.png",
"workspaces": [
"cli"
"cli",
"webview-ui"
],
"engines": {
"vscode": "^1.84.0"
@@ -379,73 +380,73 @@
}
},
"scripts": {
"vscode:prepublish": "npm run package",
"compile": "npm run check-types && npm run lint && node esbuild.mjs",
"compile-standalone": "npm run check-types && npm run lint && node esbuild.mjs --standalone",
"compile-standalone-npm": "npm run protos && npm run check-types && npm run lint && node esbuild.mjs --standalone",
"cli:link": "cd cli && npm run link",
"cli:build": "npm run protos && cd cli && npm run build",
"cli:build:production": "cd cli && npm run build:production",
"cli:watch": "cd cli && npm run watch",
"cli:test": "cd cli && npm run test",
"vscode:prepublish": "bun run package",
"compile": "bun run check-types && bun run lint && bun esbuild.mjs",
"compile-standalone": "bun run protos && (bunx tsc --noEmit & cd webview-ui && bunx tsc --noEmit & cd cli && bunx tsc --noEmit & wait)",
"compile-standalone-npm": "bun run protos && bun run check-types && bun run lint && bun esbuild.mjs --standalone",
"cli:link": "cd cli && bun run link",
"cli:build": "bun run protos && cd cli && bun run build",
"cli:build:production": "cd cli && bun run build:production",
"cli:watch": "cd cli && bun run watch",
"cli:test": "cd cli && bun run test",
"test:install": "bash scripts/test-install.sh",
"cli:dev": "cd cli && npm run dev",
"postcompile-standalone": "node scripts/package-standalone.mjs",
"postcompile-standalone-npm": "node scripts/package-npm.mjs",
"dev": "npm run protos && npm run watch",
"watch": "npx npm-run-all -p watch:*",
"watch:esbuild": "node esbuild.mjs --watch",
"cli:dev": "cd cli && bun run dev",
"postcompile-standalone": "bun scripts/package-standalone.mjs",
"postcompile-standalone-npm": "bun scripts/package-npm.mjs",
"dev": "bun run protos && bun run watch",
"watch": "bunx npm-run-all -p watch:*",
"watch:esbuild": "bun esbuild.mjs --watch",
"watch:tsc": "tsc --noEmit --watch --project tsconfig.json",
"package": "npm run check-types && npm run build:webview && npm run lint && node esbuild.mjs --production",
"protos": "node scripts/build-proto.mjs",
"protos-python": "node scripts/build-python-proto.mjs",
"download-ripgrep": "node scripts/download-ripgrep.mjs",
"package": "bun run check-types && bun run build:webview && bun run lint && bun esbuild.mjs --production",
"protos": "bun scripts/build-proto.mjs",
"protos-python": "bun scripts/build-python-proto.mjs",
"download-ripgrep": "bun scripts/download-ripgrep.mjs",
"postprotos": "biome format src/shared/proto src/core/controller src/hosts/ webview-ui/src/services src/generated --write --no-errors-on-unmatched",
"clean:build": "rimraf dist dist-standalone webview-ui/build src/generated out/",
"clean:deps": "rimraf node_modules webview-ui/node_modules",
"clean:all": "npm run clean:build && npm run clean:deps",
"compile-tests": "node ./scripts/build-tests.js",
"clean:deps": "rimraf node_modules webview-ui/node_modules cli/node_modules",
"clean:all": "bun run clean:build && bun run clean:deps",
"compile-tests": "bun ./scripts/build-tests.js",
"watch-tests": "tsc -p . -w --outDir out",
"check-types": "npm run protos && npx tsc --noEmit && cd webview-ui && npx tsc --noEmit && cd ../cli && npx tsc --noEmit",
"lint": "biome lint --no-errors-on-unmatched --files-ignore-unknown=true --diagnostic-level=error && npm run lint:proto",
"check-types": "bun run protos && bunx tsc --noEmit && cd webview-ui && bunx tsc --noEmit && cd ../cli && bunx tsc --noEmit",
"lint": "biome lint --no-errors-on-unmatched --files-ignore-unknown=true --diagnostic-level=error && bun run lint:proto",
"lint:proto": "bash ./scripts/proto-lint.sh",
"format": "biome format --changed --no-errors-on-unmatched --files-ignore-unknown=true --diagnostic-level=error",
"format:fix": "biome check --changed --no-errors-on-unmatched --files-ignore-unknown=true --write",
"fix:all": "biome check --no-errors-on-unmatched --files-ignore-unknown=true --write --diagnostic-level=error --unsafe",
"ci:check-all": "npx npm-run-all -p check-types lint format",
"ci:build": "npm run protos && npm run build:webview && node esbuild.mjs && npm run compile-tests",
"pretest": "npm run compile && npm run compile-tests && npm run compile-standalone && npm run lint",
"test": "npx npm-run-all test:unit test:integration",
"ci:check-all": "bunx npm-run-all -p check-types lint format",
"ci:build": "bun run protos && bun run build:webview && bun esbuild.mjs && bun run compile-tests",
"pretest": "bun run compile && bun run compile-tests && bun run compile-standalone && bun run lint",
"test": "bunx npm-run-all test:unit test:integration",
"test:integration": "vscode-test",
"test:unit": "cross-env TS_NODE_PROJECT=./tsconfig.unit-test.json mocha",
"test:coverage": "vscode-test --coverage",
"test:sca-server": "npx tsx watch scripts/test-standalone-core-api-server.ts",
"test:tp-orchestrator": "npx tsx scripts/testing-platform-orchestrator.ts",
"test:sca-server": "bunx tsx watch scripts/test-standalone-core-api-server.ts",
"test:tp-orchestrator": "bunx tsx scripts/testing-platform-orchestrator.ts",
"e2e": "playwright test -c playwright.config.ts",
"test:e2e:build": "vsce package --allow-package-secrets sendgrid --out dist/e2e.vsix",
"test:e2e": "playwright install && npm run test:e2e:build && node src/test/e2e/utils/build.mjs && playwright test",
"test:e2e:optimal": "npm run test:e2e:build && node src/test/e2e/utils/build.mjs && playwright test",
"test:e2e:ui": "npx tsx scripts/interactive-playwright.ts",
"install:all": "npm install && cd webview-ui && npm install && cd ../cli && npm install && cd ..",
"dev:webview": "cd webview-ui && npm run dev",
"build:webview": "cd webview-ui && npm run build",
"test:webview": "cd webview-ui && npm run test",
"test:e2e": "playwright install && bun run test:e2e:build && bun src/test/e2e/utils/build.mjs && playwright test",
"test:e2e:optimal": "bun run test:e2e:build && bun src/test/e2e/utils/build.mjs && playwright test",
"test:e2e:ui": "bunx tsx scripts/interactive-playwright.ts",
"install:all": "bun install",
"dev:webview": "cd webview-ui && bun run dev",
"build:webview": "cd webview-ui && bun run build",
"test:webview": "cd webview-ui && bun run test",
"publish:marketplace": "vsce publish --allow-package-secrets sendgrid && ovsx publish",
"publish:marketplace:prerelease": "vsce publish --allow-package-secrets sendgrid --pre-release && ovsx publish --pre-release",
"publish:marketplace:nightly": "node ./scripts/publish-nightly.mjs",
"prepare": "npx husky",
"publish:marketplace:nightly": "bun ./scripts/publish-nightly.mjs",
"prepare": "bunx husky",
"changeset": "changeset",
"version-packages": "changeset version",
"docs": "cd docs && npm run dev",
"docs:check-links": "cd docs && npm run check",
"docs:rename-file": "cd docs && npm run rename",
"report-issue": "node scripts/report-issue.js",
"storybook": "cd webview-ui && npm run storybook",
"cli:unlink": "cd cli && npm run unlink"
"docs": "cd docs && bun run dev",
"docs:check-links": "cd docs && bun run check",
"docs:rename-file": "cd docs && bun run rename",
"report-issue": "bun scripts/report-issue.js",
"storybook": "cd webview-ui && bun run storybook",
"cli:unlink": "cd cli && bun run unlink"
},
"lint-staged": {
"src/shared/storage/state-keys.ts": [
"node scripts/generate-state-proto.mjs",
"bun scripts/generate-state-proto.mjs",
"git add proto/cline/state.proto"
],
"*": [
@@ -457,6 +458,7 @@
"@bufbuild/buf": "^1.54.0",
"@changesets/cli": "^2.27.12",
"@types/better-sqlite3": "^7.6.13",
"@types/bun": "^1.3.8",
"@types/chai": "^5.0.1",
"@types/clone-deep": "^4.0.4",
"@types/diff": "^5.2.1",
+4 -4
View File
@@ -33,7 +33,7 @@ async function main() {
console.log("\n✅ Build complete!")
console.log(`\n📦 NPM package ready in ${BUILD_DIR}/`)
console.log(`To publish: cd ${BUILD_DIR} && npm publish`)
console.log(`To publish: cd ${BUILD_DIR} && bun publish`)
}
/**
@@ -55,11 +55,11 @@ async function buildTypeScriptCli() {
// Install dependencies if needed
if (!fs.existsSync(path.join(CLI_DIR, "node_modules"))) {
console.log("Installing cli dependencies...")
execSync("npm install", { stdio: "inherit", cwd: CLI_DIR })
execSync("bun install", { stdio: "inherit", cwd: CLI_DIR })
}
// Build production bundle
execSync("npm run build:production", { stdio: "inherit", cwd: CLI_DIR })
execSync("bun run build:production", { stdio: "inherit", cwd: CLI_DIR })
console.log("✓ TypeScript CLI built")
}
@@ -74,7 +74,7 @@ async function copyCliDist() {
if (!fs.existsSync(distSource)) {
console.error(`Error: CLI dist not found at ${distSource}`)
console.error(`Please run: cd cli && npm run build:production`)
console.error(`Please run: cd cli && bun run build:production`)
process.exit(1)
}
+8 -4
View File
@@ -46,8 +46,8 @@ async function installNodeDependencies() {
await cpr(RUNTIME_DEPS_DIR, BUILD_DIR)
console.log("Running npm install in distribution directory...")
execSync("npm install", { stdio: "inherit", cwd: BUILD_DIR })
console.log("Running bun install in distribution directory...")
execSync("bun install", { stdio: "inherit", cwd: BUILD_DIR })
// Move the vscode directory into node_modules.
// It can't be installed using npm because it will create a symlink which cannot be unzipped correctly on windows.
@@ -93,9 +93,13 @@ async function packageAllBinaryDeps() {
// Download the binary libs
const v = IS_VERBOSE ? "--verbose" : ""
const cmd = `npx prebuild-install --platform=${platform} --arch=${arch} --target=${TARGET_NODE_VERSION} ${v}`
const cmd = `bunx prebuild-install --platform=${platform} --arch=${arch} --target=${TARGET_NODE_VERSION} ${v}`
log_verbose(`${module}: ${cmd}`)
execSync(cmd, { cwd: dest, stdio: "inherit" })
execSync(cmd, {
cwd: dest,
stdio: "inherit",
env: { ...process.env, NODE_NO_WARNINGS: "1" },
})
log_verbose("")
}
// Remove the original module with the host platform binaries installed directly into node_modules.
+6 -6
View File
@@ -16,8 +16,8 @@
* 6. Restores the original package.json
*
* Usage:
* npm run publish:marketplace:nightly
* npm run publish:marketplace:nightly -- --dry-run
* bun run publish:marketplace:nightly
* bun run publish:marketplace:nightly -- --dry-run
*
* Environment variables:
* VSCE_PAT - Personal Access Token for VS Code Marketplace
@@ -361,7 +361,7 @@ if (showHelp) {
Nightly publish script for VS Code extension
Usage:
npm run publish:marketplace:nightly [options]
bun run publish:marketplace:nightly [options]
Options:
--dry-run, -n Run without actually publishing (package only)
@@ -372,9 +372,9 @@ Environment variables:
OVSX_PAT Personal Access Token for OpenVSX Registry
Examples:
npm run publish:marketplace:nightly # Full publish
npm run publish:marketplace:nightly -- --dry-run # Package only
VSCE_PAT="token" npm run publish:marketplace:nightly # Publish to VS Code only
bun run publish:marketplace:nightly # Full publish
bun run publish:marketplace:nightly -- --dry-run # Package only
VSCE_PAT="token" bun run publish:marketplace:nightly # Publish to VS Code only
`)
process.exit(0)
}
@@ -46,7 +46,7 @@ describe("LiteLlmHandler", () => {
}
beforeEach(() => {
mockFetchForTesting(mockFetch, () => {
mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, () => {
return new Promise((resolve) => {
doneMockingFetch = resolve
})
+1 -1
View File
@@ -472,7 +472,7 @@ export class McpHub {
// but many servers (incorrectly) return 404. The SDK only handles 405
// gracefully, so we normalize 404 -> 405 to fix compatibility.
// See: https://github.com/modelcontextprotocol/typescript-sdk/issues/1150
const streamableHttpFetch: typeof fetch = async (url, init) => {
const streamableHttpFetch = async (url: URL | RequestInfo, init: RequestInit | undefined) => {
const response = await fetch(url, init)
if (init?.method === "GET" && response.status === 404) {
return new Response(response.body, {
+150
View File
@@ -0,0 +1,150 @@
import { expect } from "chai"
import { fetch, getAxiosSettings, mockFetchForTesting } from "../net"
describe("net", () => {
describe("fetch", () => {
it("should be a function", () => {
expect(typeof fetch).to.equal("function")
})
it("should be callable and return a Promise", async () => {
// Mock a simple successful response
const mockResponse = new Response("test", { status: 200 })
const mockFetch = async () => mockResponse
await mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, async () => {
const response = await fetch("https://example.com")
expect(response).to.equal(mockResponse)
})
})
it("should preserve Bun's preconnect property if present", () => {
// In Bun, fetch should have preconnect. In Node, it won't.
// We just verify that if baseFetch had it, our wrapper preserves it.
if ("preconnect" in globalThis.fetch) {
expect("preconnect" in fetch).to.be.true
expect(typeof (fetch as any).preconnect).to.equal("function")
}
})
})
describe("mockFetchForTesting", () => {
let originalFetchCalls: string[] = []
beforeEach(() => {
originalFetchCalls = []
})
it("should temporarily replace fetch with mock", async () => {
const mockResponse = new Response("mocked", { status: 200 })
const mockFetch = async (input: string | URL | Request) => {
originalFetchCalls.push(input.toString())
return mockResponse
}
await mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, async () => {
const response = await fetch("https://test1.com")
expect(response).to.equal(mockResponse)
expect(originalFetchCalls).to.include("https://test1.com")
})
})
it("should restore original fetch after callback completes", async () => {
const mockResponse = new Response("mocked", { status: 200 })
const mockFetch = async () => mockResponse
let insideMock = false
await mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, async () => {
insideMock = true
const response = await fetch("https://test.com")
expect(response).to.equal(mockResponse)
})
expect(insideMock).to.be.true
// After callback, fetch should not return the mocked response
// We can't easily test this without making a real network call,
// but we can verify the function signature is intact
expect(typeof fetch).to.equal("function")
})
it("should restore original fetch even if callback throws", () => {
const mockFetch = async () => new Response("mocked", { status: 200 })
expect(() => {
mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, () => {
throw new Error("Test error")
})
}).to.throw("Test error")
// Fetch should still be a function after error
expect(typeof fetch).to.equal("function")
})
it("should handle nested mocking", async () => {
const mock1Response = new Response("mock1", { status: 200 })
const mock2Response = new Response("mock2", { status: 200 })
const mock1 = async () => mock1Response
const mock2 = async () => mock2Response
await mockFetchForTesting(mock1 as unknown as typeof globalThis.fetch, async () => {
const response1 = await fetch("https://test1.com")
expect(response1).to.equal(mock1Response)
await mockFetchForTesting(mock2 as unknown as typeof globalThis.fetch, async () => {
const response2 = await fetch("https://test2.com")
expect(response2).to.equal(mock2Response)
})
// Should restore to mock1 after inner mock completes
const response3 = await fetch("https://test3.com")
expect(response3).to.equal(mock1Response)
})
})
it("should work with synchronous callbacks", () => {
const mockFetch = async () => new Response("mocked", { status: 200 })
let called = false
mockFetchForTesting(mockFetch as unknown as typeof globalThis.fetch, () => {
called = true
})
expect(called).to.be.true
})
})
describe("getAxiosSettings", () => {
it("should return an object with adapter and fetch", () => {
const settings = getAxiosSettings()
expect(settings).to.have.property("adapter")
expect(settings).to.have.property("fetch")
expect(settings.adapter).to.equal("fetch")
expect(typeof settings.fetch).to.equal("function")
})
it("should return our configured fetch function", () => {
const settings = getAxiosSettings()
expect(settings.fetch).to.equal(fetch)
})
it("should be spreadable into axios config", () => {
const customConfig = {
headers: { "X-Custom": "header" },
timeout: 5000,
}
const finalConfig = {
...customConfig,
...getAxiosSettings(),
}
expect(finalConfig.headers).to.deep.equal({ "X-Custom": "header" })
expect(finalConfig.timeout).to.equal(5000)
expect(finalConfig.adapter).to.equal("fetch")
expect(finalConfig.fetch).to.equal(fetch)
})
})
})
+6 -1
View File
@@ -123,7 +123,12 @@ export const fetch: typeof globalThis.fetch = (() => {
baseFetch = undiciFetch as any as typeof globalThis.fetch
}
return (input: string | URL | Request, init?: RequestInit): Promise<Response> => (mockFetch || baseFetch)(input, init)
// Create a wrapper function that has the same signature as fetch
const wrapper = (input: string | URL | Request, init?: RequestInit): Promise<Response> =>
(mockFetch || baseFetch)(input, init)
// Copy any additional properties from the base fetch (like Bun's preconnect)
return Object.assign(wrapper, baseFetch)
})()
/**
+8 -8
View File
@@ -37,13 +37,13 @@ The E2E test suite consists of several key components:
To build the test environment and run all E2E tests:
```bash
npm run test:e2e
bun run test:e2e
```
To run all E2E tests without re-building the test environment (e.g. only test files were updated):
```bash
npm run e2e
bun run e2e
```
### Debug Mode
@@ -51,9 +51,9 @@ npm run e2e
To run E2E tests in debug mode with Playwright's interactive debugger:
```bash
npm run test:e2e -- --debug
bun run test:e2e -- --debug
# Or only run the tests without re-building
npm run e2e -- --debug
bun run e2e -- --debug
```
In debug mode, Playwright will:
@@ -66,17 +66,17 @@ In debug mode, Playwright will:
Run specific test files:
```bash
npm run e2e -- auth.test.ts
bun run e2e -- auth.test.ts
```
Run tests with specific tags or patterns:
```bash
npm run e2e -- --grep "Chat"
bun run e2e -- --grep "Chat"
```
Run tests in headed mode (visible browser):
```bash
npm run e2e -- --headed
bun run e2e -- --headed
```
## Writing Tests
@@ -165,7 +165,7 @@ The `--debug` flag enables Playwright's interactive debugging features:
1. **Start debugging session:**
```bash
npm run test:e2e -- --debug
bun run test:e2e -- --debug
```
2. **Playwright will open:**
+7 -7
View File
@@ -30,7 +30,7 @@ testing-platform/
Generate proto files in the **root Cline project**:
```bash
npm run protos
bun run protos
```
## Setup
@@ -38,16 +38,16 @@ npm run protos
From the root of the Cline project:
```bash
npm run install:all
npm run protos
bun run install:all
bun run protos
```
Then install and build the testing platform:
```bash
cd testing-platform
npm install
npm run build
bun install
bun run build
```
## Running Spec File Tests
@@ -55,11 +55,11 @@ npm run build
Before running specs, make sure the standalone Cline Core gRPC server (that runs mocks and host gRPC as well) is running:
```bash
npm run test:sca-server
bun run test:sca-server
```
Then finally you can run the cli as:
```bash
npm run start:dev <spec-file-or-folder>
bun run start:dev <spec-file-or-folder>
```bash
+1 -1
View File
@@ -5,7 +5,7 @@
"scripts": {
"build": "tsc",
"start:dev": "ts-node index.ts",
"start": "npm run build && node dist/runner.js"
"start": "bun run build && bun dist/runner.js"
},
"dependencies": {
"jest-diff": "^30.1.2"
+12 -13
View File
@@ -23,43 +23,42 @@
"target": "es2022",
"useDefineForClassFields": true,
"useUnknownInCatchVariables": false,
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
"./src/*"
],
"@api/*": [
"src/core/api/*"
"./src/core/api/*"
],
"@core/*": [
"src/core/*"
"./src/core/*"
],
"@generated/*": [
"src/generated/*"
"./src/generated/*"
],
"@hosts/*": [
"src/hosts/*"
"./src/hosts/*"
],
"@integrations/*": [
"src/integrations/*"
"./src/integrations/*"
],
"@packages/*": [
"src/packages/*"
"./src/packages/*"
],
"@services/*": [
"src/services/*"
"./src/services/*"
],
"@shared/*": [
"src/shared/*"
"./src/shared/*"
],
"@utils/*": [
"src/utils/*"
"./src/utils/*"
]
}
},
"include": [
"src/**/*",
"cli/src/**/*"
"./src/**/*",
"./cli/src/**/*"
],
"exclude": [
"node_modules",
+4 -4
View File
@@ -24,11 +24,11 @@
"rootDir": "."
},
"include": [
"src/**/*.test.ts"
"./src/**/*.test.ts"
],
"exclude": [
"src/test/**/*.js",
"src/**/__tests__/*",
"src/test/e2e/**/*.test.ts"
"./src/test/**/*.js",
"./src/**/__tests__/*",
"./src/test/e2e/**/*.test.ts"
]
}
+2 -2
View File
@@ -14,8 +14,8 @@
]
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
"./src/**/*.ts",
"./test/**/*.ts"
],
"exclude": [
"node_modules"
+1 -1
View File
@@ -19,7 +19,7 @@ In Cline's webview, Storybook helps us develop and test React components that ma
To launch the Storybook development server:
```bash
npm run storybook
bun run storybook
```
This will start Storybook on `http://localhost:6006` where you can browse all available stories and interact with components.
-16443
View File
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -29,27 +29,26 @@
"noUncheckedSideEffectImports": true,
/* Aliasing */
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
"./src/*"
],
"@components/*": [
"src/components/*"
"./src/components/*"
],
"@context/*": [
"src/context/*"
"./src/context/*"
],
"@shared/*": [
"../src/shared/*"
],
"@utils/*": [
"src/utils/*"
"./src/utils/*"
]
}
},
"include": [
"src"
"./src/**/*"
],
"exclude": [
"src/**/*.test.tsx",
-1
View File
@@ -9,7 +9,6 @@
}
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"