diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c93adedf6..519463415 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,13 +33,6 @@ jobs: with: path: ~/.bun/install/cache key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - name: Cache Turbo artifacts - uses: actions/cache@v4 - with: - path: .turbo - key: ${{ runner.os }}-turbo-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-turbo- - run: bun install --frozen-lockfile - name: Type check changed packages if: github.event_name == 'pull_request' @@ -138,13 +131,6 @@ jobs: with: path: ~/.bun/install/cache key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - name: Cache Turbo artifacts - uses: actions/cache@v4 - with: - path: .turbo - key: ${{ runner.os }}-turbo-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-turbo- - name: Install system deps run: | sudo apt-get update diff --git a/.gitignore b/.gitignore index 5bf50f2bb..d37de396b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Dependencies node_modules/ .npm/ -.turbo/ # Build output dist/ diff --git a/bun.lock b/bun.lock index 0b19077f4..17a04f782 100644 --- a/bun.lock +++ b/bun.lock @@ -11,7 +11,6 @@ "@typescript/native-preview": "catalog:", "lint-staged": "catalog:", "prettier": "catalog:", - "turbo": "catalog:", "typescript": "catalog:", }, }, @@ -248,7 +247,6 @@ "react-dom": "^19.2", "regexp-tree": "^0.1", "tailwindcss": "^4.2", - "turbo": "^2.5.8", "turndown": "7.2.4", "turndown-plugin-gfm": "1.0.2", "typescript": "^6.0.2", @@ -701,17 +699,6 @@ "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], - "@turbo/darwin-64": ["@turbo/darwin-64@2.9.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-X/56SnVXIQZBLKwniGTwEQTGmtE5brSACnKMBWpY3YafuxVYefrC2acamfjgxP7BG5w3I+6jf0UrLoSzgPcSJg=="], - - "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aalBeSl4agT/QtYGDyf/XLajedWzUC9Vg/pm/YO6QQ93vkQ91Vz5uK1ta5RbVRDozQSz4njxUNqRNmOXDzW+qw=="], - - "@turbo/linux-64": ["@turbo/linux-64@2.9.6", "", { "os": "linux", "cpu": "x64" }, "sha512-YKi05jnNHaD7vevgYwahpzGwbsNNTwzU2c7VZdmdFm7+cGDP4oREUWSsainiMfRqjRuolQxBwRn8wf1jmu+YZA=="], - - "@turbo/linux-arm64": ["@turbo/linux-arm64@2.9.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-02o/ZS69cOYEDczXvOB2xmyrtzjQ2hVFtWZK1iqxXUfzMmTjZK4UumrfNnjckSg+gqeBfnPRHa0NstA173Ik3g=="], - - "@turbo/windows-64": ["@turbo/windows-64@2.9.6", "", { "os": "win32", "cpu": "x64" }, "sha512-wVdQjvnBI15wB6JrA+43CtUtagjIMmX6XYO758oZHAsCNSxqRlJtdyujih0D8OCnwCRWiGWGI63zAxR0hO6s9g=="], - - "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-1XUUyWW0W6FTSqGEhU8RHVqb2wP1SPkr7hIvBlMEwH9jr+sJQK5kqeosLJ/QaUv4ecSAd1ZhIrLoW7qslAzT4A=="], "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], @@ -1271,8 +1258,6 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "turbo": ["turbo@2.9.6", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.6", "@turbo/darwin-arm64": "2.9.6", "@turbo/linux-64": "2.9.6", "@turbo/linux-arm64": "2.9.6", "@turbo/windows-64": "2.9.6", "@turbo/windows-arm64": "2.9.6" }, "bin": { "turbo": "bin/turbo" } }, "sha512-+v2QJey7ZUeUiuigkU+uFfklvNUyPI2VO2vBpMYJA+a1hKFLFiKtUYlRHdb3P9CrAvMzi0upbjI4WT+zKtqkBg=="], - "turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="], "turndown-plugin-gfm": ["turndown-plugin-gfm@1.0.2", "", {}, "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg=="], diff --git a/package.json b/package.json index a9da44a44..5fd28a494 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "react-dom": "^19.2", "regexp-tree": "^0.1", "tailwindcss": "^4.2", - "turbo": "^2.5.8", "turndown": "7.2.4", "turndown-plugin-gfm": "1.0.2", "typescript": "^6.0.2", @@ -74,45 +73,33 @@ } }, "scripts": { - "turbo": "turbo", "install:dev": "bun install && bun --cwd=packages/coding-agent link && bun --cwd=packages/ai link", "dev": "bun --cwd=packages/coding-agent src/cli.ts", "stats": "bun --cwd=packages/coding-agent src/cli.ts stats", - "build": "bun run build:ws", - "build:ws": "turbo run build", + "build": "bun run --workspaces --if-present build", "build:native": "bun --cwd=packages/natives run build", - "build:affected": "turbo run build --affected", "test": "bun run --parallel test:ts test:rs", - "test:ts": "turbo run test --output-logs=errors-only", - "test:rs": "cargo nextest run --workspace --status-level=fail --final-status-level=fail", - "test:affected": "turbo run test --affected --output-logs=errors-only", + "test:ts": "bun run --workspaces --if-present test -- --only-failures", + "test:rs": "bun scripts/run-rs-task.ts test:rs", "check": "bun run --parallel check:ts check:rs", - "check:ts": "bun run --parallel check:tools check:ws", + "check:ts": "bun run check:tools && bun run --workspaces --if-present check", "check:tools": "biome check . --no-errors-on-unmatched && bun run check:types", "check:types": "tsgo -p tsconfig.tools.json --noEmit", - "check:ws": "turbo run check", - "check:types:ws": "turbo run check:types", - "check:affected": "bun run check:tools && turbo run check --affected", - "check:rs": "cargo fmt --all -- --check && cargo clippy --workspace -- -D warnings", + "check:rs": "bun scripts/run-rs-task.ts check:rs", "lint": "bun run --parallel lint:ts lint:rs", - "lint:ts": "bun run --parallel lint:tools lint:ws", + "lint:ts": "bun run --parallel lint:tools && bun run --workspaces --if-present lint", "lint:tools": "biome lint . --no-errors-on-unmatched", - "lint:ws": "turbo run lint", - "lint:rs": "cargo clippy --workspace -- -D warnings", + "lint:rs": "bun scripts/run-rs-task.ts lint:rs", "fmt": "bun run --parallel fmt:ts fmt:rs", - "fmt:ts": "bun run --parallel fmt:tools fmt:ws", + "fmt:ts": "bun run fmt:tools && bun run --workspaces --if-present fmt", "fmt:tools": "biome format --write . --no-errors-on-unmatched", - "fmt:ws": "turbo run fmt", - "fmt:rs": "cargo fmt --all", + "fmt:rs": "bun scripts/run-rs-task.ts fmt:rs", "fix": "bun run --parallel fix:ts fix:rs", - "fix:ts": "bun run --parallel fix:tools fix:ws", + "fix:ts": "bun run fix:tools && bun run --workspaces --if-present fix", "fix:tools": "bun run fmt:tools && biome check --write --unsafe . --no-errors-on-unmatched", - "fix:ws": "turbo run fix", - "fix:rs": "cargo fmt --all && cargo clippy --workspace --fix --allow-dirty --all-targets --no-deps --allow-staged --broken-code --allow-no-vcs", - "ci:check:affected": "bun run check:affected", + "fix:rs": "bun scripts/run-rs-task.ts fix:rs", "ci:check:full": "bun run check:ts", "ci:build:native": "bun scripts/ci-build-native.ts", - "ci:test:affected": "bun run test:affected", "ci:test:full": "bun run test", "ci:test:smoke": "bun packages/coding-agent/src/cli.ts --version && bun packages/coding-agent/src/cli.ts --help && bun packages/coding-agent/src/cli.ts stats --help", "ci:test:install-methods": "bash scripts/install-tests/run-ci.sh", @@ -138,8 +125,7 @@ "@typescript/native-preview": "catalog:", "typescript": "catalog:", "lint-staged": "catalog:", - "prettier": "catalog:", - "turbo": "catalog:" + "prettier": "catalog:" }, "lint-staged": { "*.{js,ts,jsx,tsx,json,jsonc,css}": "biome check --write --no-errors-on-unmatched" diff --git a/packages/natives/turbo.json b/packages/natives/turbo.json deleted file mode 100644 index 18837fb9d..000000000 --- a/packages/natives/turbo.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": [ - "//" - ], - "tasks": { - "build": { - "inputs": [ - "$TURBO_DEFAULT$", - "$TURBO_ROOT$/Cargo.toml", - "$TURBO_ROOT$/Cargo.lock", - "$TURBO_ROOT$/crates/pi-natives/**" - ], - "outputs": [ - "native/*.node", - "native/index.js", - "native/index.d.ts" - ] - } - } -} diff --git a/scripts/run-rs-task.ts b/scripts/run-rs-task.ts new file mode 100644 index 000000000..3a0e33644 --- /dev/null +++ b/scripts/run-rs-task.ts @@ -0,0 +1,134 @@ +#!/usr/bin/env bun + +import { $ } from "bun"; +import * as path from "node:path"; + +const RUST_AFFECTING_FILE_NAMES = [ + "Cargo.toml", + "Cargo.lock", + "build.rs", + "rust-toolchain", + "rust-toolchain.toml", + "clippy.toml", + ".clippy.toml", + "rustfmt.toml", + ".rustfmt.toml", +] as const satisfies readonly string[]; +const TASK_COMMANDS = { + "check:rs": [ + ["cargo", "fmt", "--all", "--", "--check"], + ["cargo", "clippy", "--workspace", "--", "-D", "warnings"], + ], + "fix:rs": [ + ["cargo", "fmt", "--all"], + [ + "cargo", + "clippy", + "--workspace", + "--fix", + "--allow-dirty", + "--all-targets", + "--no-deps", + "--allow-staged", + "--broken-code", + "--allow-no-vcs", + ], + ], + "fmt:rs": [["cargo", "fmt", "--all"]], + "lint:rs": [["cargo", "clippy", "--workspace", "--", "-D", "warnings"]], + "test:rs": [["cargo", "nextest", "run", "--workspace", "--status-level=fail", "--final-status-level=fail"]], +} as const satisfies Record; + +type RustTaskName = keyof typeof TASK_COMMANDS; + +const repoRoot = path.join(import.meta.dir, ".."); +const taskName = process.argv[2]; + +if (!isRustTaskName(taskName)) { + console.error(`Unknown Rust task: ${taskName ?? "(missing)"}`); + process.exit(1); +} + +if (!(isCI() || (await hasRustAffectingChanges()))) { + console.log(`Skipping ${taskName} (not in CI and no Rust-affecting changes were found).`); + process.exit(0); +} + +for (const command of TASK_COMMANDS[taskName]) { + const exitCode = await runCommand(command); + if (exitCode !== 0) { + process.exit(exitCode); + } +} + +function isRustTaskName(value: string | undefined): value is RustTaskName { + return value != null && value in TASK_COMMANDS; +} + +function isCI(): boolean { + const value = Bun.env.CI; + if (!value) return false; + const normalized = value.trim().toLowerCase(); + return normalized !== "" && normalized !== "0" && normalized !== "false"; +} + +async function hasRustAffectingChanges(): Promise { + const result = await $`git status --porcelain -z`.cwd(repoRoot).quiet().nothrow(); + if (result.exitCode !== 0) { + const stderr = result.stderr.toString().trim(); + const suffix = stderr === "" ? `exit ${result.exitCode}` : stderr; + console.warn(`Warning: failed to inspect git status: ${suffix}. Running ${taskName} conservatively.`); + return true; + } + return getChangedPathsFromPorcelain(result.stdout).some(isRustAffectingPath); +} + +function getChangedPathsFromPorcelain(buf: Uint8Array): string[] { + const entries = new TextDecoder().decode(buf).split("\0").filter(Boolean); + const changedPaths: string[] = []; + + for (let index = 0; index < entries.length; index += 1) { + const entry = entries[index]; + if (entry.length < 4) continue; + + const status = entry.slice(0, 2); + const changedPath = entry.slice(3); + if (changedPath !== "") { + changedPaths.push(changedPath); + } + + if (status.includes("R") || status.includes("C")) { + const renamedPath = entries[index + 1]; + if (renamedPath) { + changedPaths.push(renamedPath); + index += 1; + } + } + } + + return changedPaths; +} + +function isRustAffectingPath(changedPath: string): boolean { + const normalized = changedPath.replace(/\\/g, "/"); + const fileName = normalized.slice(normalized.lastIndexOf("/") + 1); + return ( + normalized.endsWith(".rs") || + normalized.startsWith(".cargo/") || + isOneOf(fileName, RUST_AFFECTING_FILE_NAMES) + ); +} + +function isOneOf(value: string, values: readonly T[]): value is T { + return values.some(entry => entry === value); +} + +async function runCommand(command: readonly string[]): Promise { + const proc = Bun.spawn(command, { + cwd: repoRoot, + stdin: "inherit", + stdout: "inherit", + stderr: "inherit", + }); + return proc.exited; +} diff --git a/turbo.json b/turbo.json deleted file mode 100644 index b48d89b6d..000000000 --- a/turbo.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "https://turborepo.dev/schema.json", - "ui": "stream", - "envMode": "loose", - "globalDependencies": [ - "package.json", - "bun.lock", - "bunfig.toml", - "biome.json", - "tsconfig.json", - "tsconfig.base.json", - "tsconfig.tools.json", - "packages/tsconfig.workspace.json" - ], - "tasks": { - "build": { - "dependsOn": [ - "^build" - ], - "inputs": [ - "$TURBO_DEFAULT$", - "!dist/**", - "!.turbo/**", - "!coverage/**", - "!*.tsbuildinfo" - ], - "outputs": [ - "dist/**", - ".next/**", - "!.next/cache/**" - ] - }, - "check": { - "dependsOn": [ - "^check" - ], - "inputs": [ - "$TURBO_DEFAULT$", - "!dist/**", - "!.turbo/**", - "!coverage/**", - "!*.tsbuildinfo" - ] - }, - "check:types": { - "dependsOn": [ - "^check:types" - ], - "inputs": [ - "$TURBO_DEFAULT$", - "!dist/**", - "!.turbo/**", - "!coverage/**", - "!*.tsbuildinfo" - ] - }, - "lint": { - "inputs": [ - "$TURBO_DEFAULT$", - "!dist/**", - "!.turbo/**", - "!coverage/**", - "!*.tsbuildinfo" - ] - }, - "test": { - "dependsOn": [ - "check", - "^check", - "^build" - ], - "inputs": [ - "$TURBO_DEFAULT$", - "!dist/**", - "!.turbo/**", - "!coverage/**", - "!*.tsbuildinfo" - ] - }, - "fmt": { - "cache": false - }, - "fix": { - "cache": false - }, - "dev": { - "cache": false, - "persistent": true - } - } -}