diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b04586..38a99fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ permissions: jobs: verify: runs-on: ubuntu-latest + env: + TURBO_TELEMETRY_DISABLED: 1 steps: - name: Checkout uses: actions/checkout@v4 @@ -39,5 +41,5 @@ jobs: # CLI argument tests resolve the configured harness but fail before invoking it. AGENT_CLI_PATH: bun - - name: Build + - name: Build workspace graph run: bun run build diff --git a/.gitignore b/.gitignore index 92b66f4..66fe151 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ dist/ +.turbo/ .DS_Store *.log .env diff --git a/AGENTS.md b/AGENTS.md index 4d4ce38..6a86407 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,14 +23,18 @@ Bun-based monorepo with workspace packages under `packages/*`. The marketing sit ## Developer Commands ```bash -# Root: run across all packages +# Root: Turborepo runs tasks across all packages bun install bun run build +bun run dev bun run typecheck bun run test bun run format bun run lint +# Bypass a cached result while troubleshooting +bun run turbo run test --force + # Single package bun run --filter @getdevintern/code test bun run --filter @getdevintern/pm build diff --git a/CLAUDE.md b/CLAUDE.md index 59d5e80..33a46a2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,14 +23,18 @@ Bun-based monorepo with workspace packages under `packages/*`. The marketing sit ## Developer Commands ```bash -# Root: run across all packages +# Root: Turborepo runs tasks across all packages bun install bun run build +bun run dev bun run typecheck bun run test bun run format bun run lint +# Bypass a cached result while troubleshooting +bun run turbo run test --force + # Single package bun run --filter @getdevintern/code test bun run --filter @getdevintern/pm build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea8c4a6..5a6f1b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ This repository is the canonical home for DevIntern's product and tool source. C ## Ground rules -- `bun install`, then `bun run format`, `bun run lint`, `bun run typecheck`, `bun run test` must pass. The lefthook pre-commit hook runs the first three automatically. +- `bun install`, then `bun run format`, `bun run lint`, `bun run typecheck`, `bun run test` must pass. These root commands use Turborepo; the lefthook pre-commit hook runs the first three automatically. - Tests use isolated temp directories; do not share temp dirs across tests. - Keep changes scoped to the product packages and documentation in this repo. Website and docs-site implementation changes happen elsewhere. - Update the relevant guide under `docs/{code,pm}` when a change alters user-facing CLI behavior, flags, or environment variables. diff --git a/README.md b/README.md index c66c998..f2df441 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,24 @@ The FSL grants no trademark rights: the DevIntern name and logo are trademarks o Website and control plane live elsewhere; this repo is the tool packages. +## Development workflows + +Install dependencies with `bun install`, then use the root commands below. Turborepo runs package tasks in parallel where it is safe and orders workspace builds according to their package dependencies. + +| Command | Purpose | +| ---------------------- | ---------------------------------------------------------------------------- | +| `bun run build` | Build every workspace and its dependencies | +| `bun run test` | Run all package test suites | +| `bun run lint` | Lint all packages | +| `bun run typecheck` | Type-check all packages | +| `bun run format:check` | Check formatting without changing files | +| `bun run format` | Format all packages; this write task is intentionally not cached | +| `bun run dev` | Start the dashboard and desktop watch tasks; stop them with Ctrl+C | + +Package-level commands remain available, for example `bun run --filter @getdevintern/pm test`. To run a selected task and its dependency graph through Turborepo, use `bun run turbo run build --filter @getdevintern/code`. + +Turborepo uses the local `.turbo` directory for its cache; remote caching is not configured. Add `--force` to a Turbo command to ignore cached results, or remove `.turbo` to clear the local cache completely. If a result looks stale, first rerun it with `--force`; changes to the lockfile, package sources, shared lint configuration, or declared build environment variables automatically invalidate affected entries. + ## Contributing PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Monorepo layout and Bun-only tooling: [AGENTS.md](AGENTS.md). diff --git a/bun.lock b/bun.lock index e7a8188..b6ab28e 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "devintern", @@ -11,6 +12,7 @@ "lefthook": "^2.1.5", "oxfmt": "^0.44.0", "oxlint": "^1.59.0", + "turbo": "^2.10.11", "typescript": "^5.3.0", }, }, @@ -35,7 +37,7 @@ }, "packages/code": { "name": "@getdevintern/code", - "version": "2.3.1", + "version": "2.3.2", "bin": { "devintern": "dist/index.js", }, @@ -49,6 +51,7 @@ "devDependencies": { "@devintern/agent-harness": "workspace:*", "@devintern/auth": "workspace:*", + "@devintern/dashboard-ui": "workspace:*", "@devintern/license-check": "workspace:*", "@devintern/task-trackers": "workspace:*", "@devintern/text-formatter": "workspace:*", @@ -141,7 +144,7 @@ }, "packages/pm-desktop": { "name": "@devintern/pm-desktop", - "version": "0.9.9", + "version": "0.9.11", "dependencies": { "@base-ui/react": "^1.7.0", "@devintern/agent-harness": "workspace:*", @@ -909,6 +912,18 @@ "@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="], + "@turbo/darwin-64": ["@turbo/darwin-64@2.10.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-v3R+1R/Ysozyo+p7Ri8MCIbndOvYt3DgPFrGLhrhQHfvyvbxyH3WyJj+A/2JTNmNleuAlh3JUyCV0iSVHIONTA=="], + + "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.10.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-R0a0CvGAeYYsBgPIgFNB3agGXh6qukjduNhFlwVVX1Ss2IdBJLXmgjytNGmo084bLKS0B6UdLRwKhXMHKKaObQ=="], + + "@turbo/linux-64": ["@turbo/linux-64@2.10.11", "", { "os": [ "linux", "android", ], "cpu": "x64" }, "sha512-dGlY2vg7jpsLjGS1bf9sD/cw1sGMAYbeHGQKGRFxd5Zaj+Ufbj8cNXl/vIit8ueCU97zhL/znn60ZV5iSfZAxw=="], + + "@turbo/linux-arm64": ["@turbo/linux-arm64@2.10.11", "", { "os": [ "linux", "android", ], "cpu": "arm64" }, "sha512-eSP9+jjsSCBs2x0QpJZlp49dSD1EIMwXH7PsMIhdWk7w6IThhuKJ+jL95JQ2IW7tRjRmdh8gKcKQtrHLD5R5lA=="], + + "@turbo/windows-64": ["@turbo/windows-64@2.10.11", "", { "os": "win32", "cpu": "x64" }, "sha512-4aD7edogJ8arK8DOyvjTI2KKwmchD5M/WM4BZgidrtFf7aSgn8Ce2rJnDwmriw980c2cKlHnhXtlGy38VtKB8g=="], + + "@turbo/windows-arm64": ["@turbo/windows-arm64@2.10.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-m8tJkIrTrbQ9O1uHxV0GUq623Zg1678xGna8eMsy4KbygUX/wVFgdZDYV/AxyoyaW/U7nyKoBvaDVwm22p9xqA=="], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], @@ -2099,6 +2114,8 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "turbo": ["turbo@2.10.11", "", { "optionalDependencies": { "@turbo/darwin-64": "2.10.11", "@turbo/darwin-arm64": "2.10.11", "@turbo/linux-64": "2.10.11", "@turbo/linux-arm64": "2.10.11", "@turbo/windows-64": "2.10.11", "@turbo/windows-arm64": "2.10.11" }, "bin": { "turbo": "bin/turbo" } }, "sha512-yQfwQVoRXwOuyX1LxiJFBFNg6VfuYh+/RyZLd82+isgyLkBXw3S5XRRzvcck1FAjSCG5sVyLd+O1eDMvYa3J7g=="], + "turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="], "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], diff --git a/package.json b/package.json index daa077d..7fc64eb 100644 --- a/package.json +++ b/package.json @@ -4,23 +4,26 @@ "version": "0.0.0", "description": "Monorepo for @devintern/code and @devintern/pm.", "type": "module", + "packageManager": "bun@1.2.16", "workspaces": [ "packages/*" ], "scripts": { - "build": "bun run --filter '*' build", - "format": "bun run --filter '*' format", - "format:check": "bun run --filter '*' format:check", - "lint": "bun run --filter '*' lint", + "build": "turbo run build", + "dev": "turbo run dev --filter=!@getdevintern/code", + "format": "turbo run format", + "format:check": "turbo run format:check", + "lint": "turbo run lint", "prepare": "lefthook install", - "typecheck": "bun run --filter '*' typecheck", - "test": "bun run --filter '*' test" + "typecheck": "turbo run typecheck", + "test": "turbo run test" }, "devDependencies": { "@types/bun": "latest", "lefthook": "^2.1.5", "oxfmt": "^0.44.0", "oxlint": "^1.59.0", + "turbo": "^2.10.11", "typescript": "^5.3.0" }, "dependencies": { diff --git a/packages/code/build.ts b/packages/code/build.ts index d1b903c..7a05c83 100644 --- a/packages/code/build.ts +++ b/packages/code/build.ts @@ -23,9 +23,18 @@ writeFileSync(distPath, content); // the published npm artifact without the monorepo. const uiPackageDir = join(import.meta.dir, "..", "dashboard-ui"); const uiDist = join(uiPackageDir, "dist"); -const uiBuild = Bun.spawnSync(["bun", "run", "build"], { cwd: uiPackageDir }); -if (uiBuild.exitCode !== 0 || !existsSync(join(uiDist, "index.html"))) { - console.error(uiBuild.stderr.toString()); + +// Turbo builds workspace dependencies first. Keep the package-level command +// self-contained for contributors who run `bun run build` from this directory. +if (!process.env.TURBO_HASH) { + const uiBuild = Bun.spawnSync(["bun", "run", "build"], { cwd: uiPackageDir }); + if (uiBuild.exitCode !== 0) { + console.error(uiBuild.stderr.toString()); + process.exit(1); + } +} + +if (!existsSync(join(uiDist, "index.html"))) { console.error("dashboard-ui build failed; refusing to package without the dashboard UI."); process.exit(1); } diff --git a/packages/code/package.json b/packages/code/package.json index d1bc6fd..565e225 100644 --- a/packages/code/package.json +++ b/packages/code/package.json @@ -68,6 +68,7 @@ "devDependencies": { "@devintern/agent-harness": "workspace:*", "@devintern/auth": "workspace:*", + "@devintern/dashboard-ui": "workspace:*", "@devintern/license-check": "workspace:*", "@devintern/task-trackers": "workspace:*", "@devintern/utils": "workspace:*", diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000..68b1543 --- /dev/null +++ b/turbo.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://turbo.build/schema.json", + "globalDependencies": [".oxlintrc.json"], + "tasks": { + "build": { + "dependsOn": ["^build"], + "env": ["GITHUB_OAUTH_CLIENT_ID", "POSTHOG_API_KEY", "POSTHOG_HOST"], + "outputs": ["dist/**", "out/**"] + }, + "@devintern/agent-harness#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@devintern/auth#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@devintern/license-check#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@devintern/task-trackers#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@devintern/text-formatter#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@devintern/utils#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "@getdevintern/license-policy#build": { + "dependsOn": ["^build"], + "outputs": [] + }, + "dev": { + "cache": false, + "persistent": true + }, + "format": { + "cache": false + }, + "format:check": {}, + "lint": {}, + "test": { + "env": ["AGENT_CLI_PATH"] + }, + "typecheck": {} + } +}