Skip to content

refactor(webui): Migrate from npm workspaces to pnpm + Turborepo; fix pre-existing lint errors.#2262

Open
junhaoliao wants to merge 7 commits intoy-scope:mainfrom
junhaoliao:webui-pnpm-turbo
Open

refactor(webui): Migrate from npm workspaces to pnpm + Turborepo; fix pre-existing lint errors.#2262
junhaoliao wants to merge 7 commits intoy-scope:mainfrom
junhaoliao:webui-pnpm-turbo

Conversation

@junhaoliao
Copy link
Copy Markdown
Member

@junhaoliao junhaoliao commented May 8, 2026

refactor(webui): Migrate from npm workspaces to pnpm + Turborepo; fix pre-existing lint errors.

Description

Migrate the WebUI component (components/webui/) from npm workspaces to pnpm 11 + Turborepo 2.9, replacing the custom MD5 checksum system with turbo's content-hash caching and the redundant npm ci --omit=dev production install with pnpm deploy --prod. Also fixes two pre-existing lint errors that the new eslint setup now catches.

Key changes:

  • pnpm-workspace.yaml (new): Defines workspace packages under packages/ and pnpm 11 settings (nodeLinker: hoisted for flat node_modules compatibility; allowBuilds for esbuild/unrs-resolver; confirmModulesPurge: false for non-TTY CI environments; verifyDepsBeforeRun: false to prevent pnpm from auto-installing production-only deps when per-package node_modules/ is missing).
  • turbo.json (new): Defines the task pipeline with ^build dependency ordering (common builds before client/server), plus lint:check, lint:fix, dev, and test tasks. NODE_ENV is scoped to the build task only (via env) to prevent lint tasks from running in production mode. lint:check and lint:fix depend on ^build so that @webui/common is built before client/server are linted (required by eslint-import-resolver-typescript to resolve @webui/common/* subpath imports).
  • Workspace packages moved to packages/: common/, client/, server/ moved to packages/common/, packages/client/, packages/server/ via git mv (following the standard pnpm + Turborepo convention and preserving VCS history).
  • package.json (root): Removed workspaces, init script, concurrently devDependency; added packageManager: "pnpm@11.0.8" and turbo delegation scripts.
  • packages/common/package.json: Added dev script for turbo's dev task; replaced npm run self-references with direct commands.
  • packages/client/package.json & packages/server/package.json: Changed "@webui/common": "*" to "workspace:*"; replaced npm run lint:check -- --fix with direct eslint --fix invocation; server scripts changed npm run to pnpm run.
  • package-lock.json replaced by pnpm-lock.yaml.
  • taskfile.yaml: webui task simplified from ~30 lines (manual per-package builds + custom checksum validate/compute + npm ci --omit=dev) to ~10 lines (turbo build + pnpm deploy --prod --legacy + rsync). Added sources/generates for task-level caching (using **/* globs). webui-node-modules simplified from npm run init + hoisting validation + custom checksum to pnpm install --frozen-lockfile. Removed G_WEBUI_CHECKSUM_FILE and G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE variables. Added .turbo to clean-webui-package-node-modules. Changed webui-node-modules dep from toolchains:nodejs-22 to toolchains:pnpm. Updated all paths from {common,client,server}/ to packages/{common,client,server}/.
  • taskfiles/toolchains.yaml: Added pnpm task (depends on nodejs-22, no-ops) for semantic clarity. Restructured nodejs-22 to use utils:checksum:compute/validate (same pattern as the rust task) so the checksum covers both the Node.js extraction and the corepack/pnpm setup. Added label: "toolchains-nodejs-22" for stable task checksum identity. Added PNPM_VERSION: "11.0.8" var and corepack setup commands.
  • taskfiles/lint.yaml: js task changed from npm run "lint:..." to turbo 'lint:...'; added dir attribute and node_modules/.bin to PATH; removed webui-node-modules.md5 from sources.
  • client/src/pages/IngestPage/Jobs/utils.ts: Removed unused CompressionJobStatus import and unnecessary type assertion (status as CompressionJobStatus to status).
  • client/src/pages/SearchPage/SearchControls/index.tsx: Replaced deprecated React.FormEvent with React.SyntheticEvent.

Impact Assessment

What is affected:

  • WebUI build pipeline (npm → pnpm + turbo)
  • WebUI dependency management (npm workspaces → pnpm workspaces)
  • WebUI build caching (custom MD5 checksums → task sources/generates + turbo content-hash caching)
  • WebUI production packaging (npm ci --omit=devpnpm deploy --prod --legacy)
  • WebUI package layout ({common,client,server}/packages/{common,client,server}/)
  • JS lint pipeline (npm run lintturbo lint)
  • Two client source files (lint fixes)

Why the change is needed:
The custom MD5 checksum system (utils:checksum:compute/validate) is verbose and error-prone — it requires manual sources/generates declarations and two-phase validate/compute calls in every task. Turborepo provides equivalent content-hash-based caching out of the box. pnpm offers stricter dependency isolation and faster installs. pnpm deploy --prod eliminates the redundant production install that npm ci --omit=dev required, and removes the artificial workspace structure from the build output. Moving packages into packages/ follows the standard pnpm + Turborepo convention.

Implications:

  • package-lock.json is replaced by pnpm-lock.yaml; developers must use pnpm install instead of npm install
  • nodeLinker: hoisted preserves flat node_modules compatibility (same as npm); can switch to isolated in a follow-up
  • verifyDepsBeforeRun: false prevents pnpm from auto-installing when per-package node_modules/ is missing; pnpm install must be run explicitly
  • pnpm deploy --prod --legacy creates a standalone server deployment; pnpm is not required at runtime
  • The pnpm task in toolchains.yaml currently just depends on nodejs-22 (no-ops) — it exists for semantic clarity so downstream tasks can declare toolchains:pnpm as a dependency
  • This is not a breaking change for the CLP package; the build output structure (build/webui/client/, build/webui/server/, build/webui/yscope-log-viewer/) is preserved

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Build time comparison

Cold build (rm -rf .task/ build/) Incremental (no changes)
Old (npm + custom checksums) 35.3s 6.5s (task: "webui" is up to date)
New (pnpm + turbo) ~22s 6.7s (task: "webui" is up to date)

Cold build is ~38% faster. Incremental times are comparable — both fully skip the task. The new system's task-level sources/generates checking (same mechanism as before, minus the custom MD5 checksum files) correctly determines the webui task is up-to-date.

Scenario 1: Cold build from clean state

Task: Verify the full webui pipeline builds from a clean state and produces the expected output structure.

Command:

rm -rf .task/ build/
time task webui

Output:

task: [webui] PATH='.../build/nodejs-22/bin':'.../components/webui'/node_modules/.bin:$PATH turbo build
• turbo 2.9.10
   • Packages in scope: @webui/client, @webui/common, @webui/server
   • Running build in 3 packages
   • Remote caching disabled, using shared worktree cache

@webui/common:build: cache miss, executing ...
@webui/common:build: $ tsc
@webui/server:build: cache miss, executing ...
@webui/server:build: $ tsc
@webui/client:build: cache miss, executing ...
@webui/client:build: $ tsc -b && vite build
@webui/client:build: vite v7.3.3 building client environment for production...
@webui/client:build: ✓ 6152 modules transformed.
...
 Tasks:    3 successful, 3 total
Cached:    0 cached, 3 total
  Time:    11.14s

task: [webui] pnpm deploy --prod --legacy --filter=@webui/server '.../build/webui/server'
...
real	0m32.522s

Explanation: All three workspace packages build successfully in dependency order (common → client + server). pnpm deploy creates the production server deployment. Total cold build time: ~33s.

Scenario 2: Incremental build — fully cached

Task: Verify that task's sources/generates checking correctly skips the entire webui task when no files have changed.

Command:

time task webui

Output:

task: Task "toolchains-nodejs-22" is up to date
task: Task "webui-node-modules" is up to date
task: Task "deps:yscope-log-viewer:node-modules" is up to date
task: Task "deps:yscope-log-viewer:build" is up to date
task: Task "webui" is up to date

real	0m6.665s

Explanation: The webui task is fully up-to-date — task skips all commands including turbo build, pnpm deploy, and rsync. This matches the old system's behavior where the custom MD5 checksum also determined the task was up-to-date.

Scenario 3: Production server deployment structure

Task: Verify that pnpm deploy --prod --legacy produces a self-contained server directory with production node_modules (including @webui/common).

Command:

find build/webui/ -maxdepth 3 -not -path "*/node_modules/*" | sort | head -30
ls build/webui/server/dist/src/main.js
ls build/webui/client/index.html

Output:

build/webui/
build/webui/client
build/webui/client/assets
build/webui/client/clp-logo.png
build/webui/client/favicon.svg
build/webui/client/index.html
build/webui/client/settings.json
build/webui/server
build/webui/server/dist
build/webui/server/dist/settings.json
build/webui/server/dist/src
build/webui/server/node_modules
build/webui/server/package.json
build/webui/server/settings.json
build/webui/yscope-log-viewer
build/webui/server/dist/src/main.js
build/webui/client/index.html

Explanation: The build output preserves the expected structure: client/ (static SPA), server/ (deployed server with production node_modules including @webui/common), and yscope-log-viewer/. The server entry point dist/src/main.js and settings.json files are at the same paths as before, ensuring compatibility with all downstream consumers (Docker, Helm, CLP config).

Scenario 4: JS lint via turbo

Task: Verify turbo runs eslint across all workspaces (building @webui/common first for module resolution) and the two pre-existing lint errors are fixed.

Command:

task lint:check-js

Output:

task: [lint:js] PATH=... turbo 'lint:check'
• turbo 2.9.10
   • Packages in scope: @webui/client, @webui/common, @webui/server
   • Running lint:check in 3 packages

@webui/common:build: cache hit, replaying logs ...
@webui/common:build: $ tsc
@webui/common:lint:check: cache hit, replaying logs ...
@webui/common:lint:check: $ eslint . --max-warnings 0
@webui/client:lint:check: cache hit, replaying logs ...
@webui/client:lint:check: $ eslint . --max-warnings 0
@webui/server:lint:check: cache hit, replaying logs ...
@webui/server:lint:check: $ eslint . --max-warnings 0

 Tasks:    4 successful, 4 total
Cached:    4 cached, 4 total
  Time:    31ms >>> FULL TURBO

Explanation: All three packages pass lint with zero errors and zero warnings. lint:check depends on ^build, so turbo builds @webui/common before linting client and server (required by eslint-import-resolver-typescript to resolve @webui/common/* subpath imports). When common/dist/ already exists from a prior build, it's a cache hit.

Scenario 5: Node.js toolchain caching

Task: Verify that the nodejs-22 task (including corepack/pnpm setup) is correctly cached on subsequent runs.

Command:

task webui  # Second run after cold build

Output:

task: Task "toolchains-nodejs-22" is up to date

Explanation: The nodejs-22 task's checksum (computed via utils:checksum:compute after corepack setup) correctly matches on the second run, so the task is skipped. This follows the same pattern as the rust task.

@junhaoliao junhaoliao requested a review from a team as a code owner May 8, 2026 09:53
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack

Walkthrough

Migrates WebUI from npm/concurrently to pnpm with Turborepo: adds pnpm workspace and turbo config, updates package scripts and toolchain tasks, replaces npm build/install/checksum flows with turbo + pnpm, tweaks lint integration, and includes minor client TypeScript adjustments.

Changes

WebUI pnpm/Turborepo Migration

Layer / File(s) Summary
Workspace Definition and pnpm Configuration
components/webui/pnpm-workspace.yaml, components/webui/package.json, components/webui/.gitignore
Defines pnpm workspace (common, client, server), workspace settings (allowBuilds, nodeLinker: hoisted), pins packageManager: pnpm@11.0.8, and ignores Turborepo cache (.turbo/).
Root Scripts and Turbo Integration
components/webui/package.json
Replaces npm/concurrently root scripts with turbo-driven commands (build, lint:check, lint:fix, dev, test) and adds turbo as a devDependency.
Turborepo Task Pipeline Definition
components/webui/turbo.json
Adds Turborepo tasks: build (depends on ^build, outputs dist/**), test (depends on build), lint:check, lint:fix, and dev (cache disabled, persistent).
Workspace Package Configuration
components/webui/common/package.json, components/webui/client/package.json, components/webui/server/package.json
Updates package scripts to run tsc/pnpm/eslint directly (no npm-run delegation), changes lint:fix to call eslint with --fix, and updates @webui/common to workspace:* in client and server.
Node.js and pnpm Toolchain Setup
taskfiles/toolchains.yaml
Enhances nodejs-22 task to enable Corepack, pin/activate pnpm, add checksum compute/validate, and introduces an internal pnpm task depending on nodejs-22.
Build and Dependency Installation Tasks
taskfile.yaml
Rewrites webui task to use turbo build and pnpm deploy, removes checksum variables/artifacts, uses pnpm install --frozen-lockfile for node_modules with pnpm-lock.yaml as input, and extends cleanup to remove .turbo.
Lint Task Integration with Turbo
taskfiles/lint.yaml
Adjusts lint sources to exclude **/node_modules/*, removes webui-node-modules.md5 input, and runs turbo 'lint:{{.LINT_CMD}}' in the WebUI dir with PATH prepended to node_modules/.bin.

Client Code Type Refinements

Layer / File(s) Summary
Type Import and Return Type Adjustments
components/webui/client/src/pages/IngestPage/Jobs/utils.ts, components/webui/client/src/pages/SearchPage/SearchControls/index.tsx, components/clp-py-utils/clp_py_utils/initialize-orchestration-db.py
Removes unused CompressionJobStatus import, stops casting status to CompressionJobStatus in mapCompressionJobResponseToTableData, changes handleSubmit parameter type from React.FormEvent to React.SyntheticEvent, and relocates ER_DUP_KEYNAME import in the Python init script.

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title accurately reflects the main changeset: migrating WebUI from npm workspaces to pnpm and Turborepo, with additional mention of fixing lint errors.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/webui/pnpm-workspace.yaml`:
- Line 11: The pnpm workspace currently disables release-age protection by
setting minimumReleaseAge: 0; change this in
components/webui/pnpm-workspace.yaml to a safe value (e.g., minimumReleaseAge:
1440) or remove/comment the minimumReleaseAge line so pnpm v11 uses its default
1440-minute guard to restore supply-chain delay protection.

In `@taskfile.yaml`:
- Around line 444-459: The webui-node-modules task currently runs
clean-webui-package-node-modules before installing, which deletes all
node_modules and the .turbo cache and forces full reinstalls and cold turbo
builds; remove the pre-clean step so webui-node-modules only runs the pnpm
install command (i.e., drop the "task: \"clean-webui-package-node-modules\""
entry from the cmds array) and leave the separate
clean-webui/clean-webui-package-node-modules flow intact for explicit full-clean
runs; ensure the task still references the same dir/sources/deps and only runs
"PATH='{{.G_NODEJS_22_BIN_DIR}}':$PATH pnpm install --frozen-lockfile".
- Line 286: Replace the single-root-only cleanup command "rm -rf
'{{.G_WEBUI_SRC_DIR}}/.turbo'" with a command that removes all .turbo
directories under the repository root so per-package .turbo folders are cleaned
too (for example use a glob or find: remove '{{.G_WEBUI_SRC_DIR}}/.turbo' and
'{{.G_WEBUI_SRC_DIR}}/**/.turbo' or run find '{{.G_WEBUI_SRC_DIR}}' -type d
-name '.turbo' -prune -exec rm -rf {} +); update the task that currently
contains the "rm -rf '{{.G_WEBUI_SRC_DIR}}/.turbo'" line to perform a
recursive/global .turbo removal.

In `@taskfiles/lint.yaml`:
- Line 79: Replace the exclude glob that currently reads - exclude:
"{{.G_WEBUI_SRC_DIR}}/**/node_modules/*" with a recursive glob to omit all
nested files under node_modules (e.g., use
"{{.G_WEBUI_SRC_DIR}}/**/node_modules/**"); update the exclude entry in
taskfiles/lint.yaml where the exclude list contains that string so deeper files
under node_modules are also excluded.

In `@taskfiles/toolchains.yaml`:
- Line 83: The CHECKSUM_FILE is hardcoded to /tmp/nodejs-22-download.md5 which
can cause races; change the CHECKSUM_FILE value to be inside the build tree by
using G_BUILD_DIR (e.g., construct the path by joining G_BUILD_DIR with a
filename like nodejs-22-download.md5) so the checksum file is scoped per-build;
update the CHECKSUM_FILE assignment in taskfiles/toolchains.yaml (the
CHECKSUM_FILE variable) to reference G_BUILD_DIR rather than /tmp.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2a9f8804-cced-45f9-a540-30cfaca8f122

📥 Commits

Reviewing files that changed from the base of the PR and between 0144808 and e0426bc.

⛔ Files ignored due to path filters (2)
  • components/webui/package-lock.json is excluded by !**/package-lock.json
  • components/webui/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • components/webui/.gitignore
  • components/webui/client/package.json
  • components/webui/client/src/pages/IngestPage/Jobs/utils.ts
  • components/webui/client/src/pages/SearchPage/SearchControls/index.tsx
  • components/webui/common/package.json
  • components/webui/package.json
  • components/webui/pnpm-workspace.yaml
  • components/webui/server/package.json
  • components/webui/turbo.json
  • taskfile.yaml
  • taskfiles/lint.yaml
  • taskfiles/toolchains.yaml

unrs-resolver: true

confirmModulesPurge: false
minimumReleaseAge: 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In pnpm 11 official docs, what is the default value of minimumReleaseAge, and what security behaviour changes when it is set to 0?

💡 Result:

In pnpm 11 official docs, the default value of minimumReleaseAge is 1440 minutes (1 day).[1][2] This setting enforces supply-chain protection by preventing the installation of newly published package versions until the specified time has passed after publication, applying to all dependencies including transitive ones.[1][2] When set to 0, it opts out of this protection, allowing pnpm to install packages regardless of their release age, disabling the time-based resolution restriction.[1]

Citations:


🏁 Script executed:

fd -t f "pnpm-workspace.yaml" components/webui/ 2>/dev/null && echo "File found" || echo "File not found"

Repository: y-scope/clp

Length of output: 103


🏁 Script executed:

cat -n components/webui/pnpm-workspace.yaml

Repository: y-scope/clp

Length of output: 309


Re-enable pnpm's release-age protection.

Line 11 sets minimumReleaseAge: 0, which disables pnpm v11's supply-chain delay guard. The default value in pnpm v11 is 1440 minutes (24 hours), which enforces protection by preventing installation of newly published packages until the specified time has elapsed. Setting it to 0 opts out of this protection entirely, weakening dependency safety in CI/dev installs.

Consider setting an explicit value (e.g., 1440) or commenting out the line to use the default:

Suggested change
-minimumReleaseAge: 0
+# minimumReleaseAge: 1440
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
minimumReleaseAge: 0
# minimumReleaseAge: 1440
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/webui/pnpm-workspace.yaml` at line 11, The pnpm workspace
currently disables release-age protection by setting minimumReleaseAge: 0;
change this in components/webui/pnpm-workspace.yaml to a safe value (e.g.,
minimumReleaseAge: 1440) or remove/comment the minimumReleaseAge line so pnpm
v11 uses its default 1440-minute guard to restore supply-chain delay protection.

Comment thread taskfile.yaml
- "rm -rf '{{.G_WEBUI_SRC_DIR}}/common/node_modules'"
- "rm -rf '{{.G_WEBUI_SRC_DIR}}/node_modules'"
- "rm -rf '{{.G_WEBUI_SRC_DIR}}/server/node_modules'"
- "rm -rf '{{.G_WEBUI_SRC_DIR}}/.turbo'"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether turbo creates per-package .turbo directories in this repo's WebUI workspaces
# by inspecting turbo.json roots and gitignore entries for .turbo.
fd -uu -t d '^\.turbo$' components/webui 2>/dev/null
fd -uu -t f -g 'turbo.json' components/webui
fd -uu -t f -g '.gitignore' components/webui --exec rg -nH '\.turbo' {}

Repository: y-scope/clp

Length of output: 121


🏁 Script executed:

cat -n components/webui/turbo.json

Repository: y-scope/clp

Length of output: 526


🏁 Script executed:

ls -la components/webui/ | grep -E '^d' | head -20

Repository: y-scope/clp

Length of output: 341


🏁 Script executed:

# Check if client, common, server packages exist and have package.json
fd -u -t f -g 'package.json' components/webui | head -10

Repository: y-scope/clp

Length of output: 196


🏁 Script executed:

# Check taskfile.yaml context around line 286
sed -n '275,300p' taskfile.yaml

Repository: y-scope/clp

Length of output: 996


🏁 Script executed:

# Search for when/where clean-webui-package-node-modules is called
rg -n 'clean-webui-package-node-modules' taskfile.yaml

Repository: y-scope/clp

Length of output: 201


🏁 Script executed:

# Check what the full G_WEBUI_SRC_DIR path is
rg -n 'G_WEBUI_SRC_DIR' taskfile.yaml | head -5

Repository: y-scope/clp

Length of output: 376


Asymmetric cleanup of per-package .turbo/ directories.

The task removes node_modules from each package (client/, common/, server/) but cleans only the root .turbo/ directory. Since Turbo creates .turbo/ directories alongside packages in a monorepo, the cleanup should also remove per-package .turbo/ directories for consistency.

Suggested fix
       - "rm -rf '{{.G_WEBUI_SRC_DIR}}/server/node_modules'"
-      - "rm -rf '{{.G_WEBUI_SRC_DIR}}/.turbo'"
+      - "rm -rf '{{.G_WEBUI_SRC_DIR}}'/{,client/,common/,server/}.turbo"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfile.yaml` at line 286, Replace the single-root-only cleanup command "rm
-rf '{{.G_WEBUI_SRC_DIR}}/.turbo'" with a command that removes all .turbo
directories under the repository root so per-package .turbo folders are cleaned
too (for example use a glob or find: remove '{{.G_WEBUI_SRC_DIR}}/.turbo' and
'{{.G_WEBUI_SRC_DIR}}/**/.turbo' or run find '{{.G_WEBUI_SRC_DIR}}' -type d
-name '.turbo' -prune -exec rm -rf {} +); update the task that currently
contains the "rm -rf '{{.G_WEBUI_SRC_DIR}}/.turbo'" line to perform a
recursive/global .turbo removal.

Comment thread taskfile.yaml
Comment thread taskfiles/lint.yaml
- "{{.G_BUILD_DIR}}/webui-node-modules.md5"
- "{{.G_WEBUI_SRC_DIR}}/**/*"
- exclude: "{{.G_WEBUI_SRC_DIR}}/**/dist/*"
- exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tighten the node_modules exclusion glob.

Line 79 uses **/node_modules/*, which excludes only direct children and may still include deeper nested files under node_modules.

Suggested change
-      - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*"
+      - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/**"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*"
- exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/**"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfiles/lint.yaml` at line 79, Replace the exclude glob that currently
reads - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*" with a recursive glob
to omit all nested files under node_modules (e.g., use
"{{.G_WEBUI_SRC_DIR}}/**/node_modules/**"); update the exclude entry in
taskfiles/lint.yaml where the exclude list contains that string so deeper files
under node_modules are also excluded.

Comment thread taskfiles/toolchains.yaml
- task: "remote:download-and-extract-tar"
vars:
CHECKSUM_FILE: "{{.G_NODEJS_22_CHECKSUM_FILE}}"
CHECKSUM_FILE: "/tmp/nodejs-22-download.md5"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid hardcoding /tmp for the download checksum file.

/tmp/nodejs-22-download.md5 is a host-wide path that is shared across users, repos, and concurrent builds on the same machine. Two parallel runs (or even runs from distinct checkouts of this repo) will race on this file and can corrupt each other's checksum state. Place the file under G_BUILD_DIR so it is scoped to this build tree, mirroring how other toolchain checksums are stored.

🛡️ Proposed fix
-          CHECKSUM_FILE: "/tmp/nodejs-22-download.md5"
+          CHECKSUM_FILE: "{{.G_BUILD_DIR}}/nodejs-22-download.md5"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CHECKSUM_FILE: "/tmp/nodejs-22-download.md5"
CHECKSUM_FILE: "{{.G_BUILD_DIR}}/nodejs-22-download.md5"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfiles/toolchains.yaml` at line 83, The CHECKSUM_FILE is hardcoded to
/tmp/nodejs-22-download.md5 which can cause races; change the CHECKSUM_FILE
value to be inside the build tree by using G_BUILD_DIR (e.g., construct the path
by joining G_BUILD_DIR with a filename like nodejs-22-download.md5) so the
checksum file is scoped per-build; update the CHECKSUM_FILE assignment in
taskfiles/toolchains.yaml (the CHECKSUM_FILE variable) to reference G_BUILD_DIR
rather than /tmp.

junhaoliao added 2 commits May 8, 2026 12:17
…ching.

Without sources/generates, the task always ran all commands (turbo
build, pnpm deploy, rsync) even when outputs were up-to-date. Adding
these declarations enables task-level caching, matching the behaviour
of the previous custom MD5 checksum system.
`eslint-import-resolver-typescript` needs `@webui/common/dist/` to
exist to resolve `@webui/common/*` subpath imports in client/server.
The old `webui-node-modules` task built all workspaces as part of
`npm run init`, but the new `pnpm install --frozen-lockfile` only
installs deps without building. Adding `dependsOn: ["^build"]` to
`lint:check` and `lint:fix` ensures turbo builds `@webui/common`
before linting packages that depend on it.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@taskfile.yaml`:
- Around line 451-458: The task sources list in taskfile.yaml for the
webui-node-modules task is missing pnpm-workspace.yaml, so workspace
configuration changes won't re-run pnpm install; update the sources array (the
block containing "sources:" and the existing entries like
"{{.G_NODEJS_22_CHECKSUM_FILE}}", "pnpm-lock.yaml", "package.json", etc.) to
include "pnpm-workspace.yaml" so changes to workspace topology or nodeLinker
settings will invalidate the task and trigger a fresh "pnpm install
--frozen-lockfile".
- Around line 260-266: The webui task's sources currently use a broad "**/*"
glob which includes hidden Turbo cache files and causes self-invalidation;
update the webui task's sources list to explicitly exclude the Turbo cache by
adding an exclude entry for the .turbo directory (e.g., exclude: "**/.turbo/**"
or exclude: ".turbo/**") alongside the existing excludes so the sources key no
longer picks up .turbo artifacts and prevents unnecessary re-runs relative to
the generates anchors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ed12b10d-deb6-4724-b262-6f61af437568

📥 Commits

Reviewing files that changed from the base of the PR and between e0426bc and 918366e.

📒 Files selected for processing (1)
  • taskfile.yaml

Comment thread taskfile.yaml
Comment on lines 260 to 266
sources:
- "{{.G_DEPS_LOG_VIEWER_BUILD_CHECKSUM_FILE}}"
- "{{.G_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILE}}"
- "{{.TASKFILE}}"
- "**/*"
- exclude: "**/dist/**/*"
- exclude: "**/node_modules/**/*"
- exclude: "yscope-log-viewer/**/*"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect turbo cache locations and existing taskfile behaviour assumptions.
fd -uu -t d '^\.turbo$' components/webui 2>/dev/null
cat components/webui/turbo.json 2>/dev/null
cat components/webui/.gitignore 2>/dev/null

Repository: y-scope/clp

Length of output: 468


🌐 Web query:

Does go-task / Taskfile sources glob **/*match files under hidden directories like.turbo by default?

💡 Result:

Yes—go-task Taskfile sources/generates globbing is recursive with `` and will include paths under hidden directories like .turbo by default, as long as the underlying glob implementation treats `.`-prefixed path segments as matchable. Taskfile docs show that `/.go` (double-star recursive globstar) is supported for `sources`/`generates` and is expected to iterate over “all files that match that glob” [1][2]. The go-task implementation is based on a globbing library (`zglob` historically) and also supports `globstar` behavior for double-star globs [1][2] (and there are known globstar-related issues/changes, but nothing in the docs/issues indicates that dot-directories are excluded by default) [3][4]. So `/` (or `/.ext`) should match files beneath `.turbo/` without needing an explicit dot option. If you find that `.turbo` is excluded in your environment/version, the likely reason would be a different ignore mechanism (e.g., explicit `exclude:` patterns) rather than the `/` semantics themselves; and `exclude:` patterns must be declared as real YAML keys, not embedded in the glob string [5].

Citations:


Exclude .turbo from webui task sources to prevent cache self-invalidation.

Turbo build writes .turbo/turbo-build.log and cache artifacts under {{.G_WEBUI_SRC_DIR}} with each invocation. With sources: **/* (excluding only dist, node_modules, and yscope-log-viewer), Taskfile's glob matches files under hidden directories including .turbo by default. Fresh mtimes on these cache files will be newer than the generates anchors, forcing unnecessary task re-runs and defeating the caching this PR introduces.

Proposed exclude
     sources:
       - "{{.G_DEPS_LOG_VIEWER_BUILD_CHECKSUM_FILE}}"
       - "{{.TASKFILE}}"
       - "**/*"
+      - exclude: "**/.turbo/**/*"
       - exclude: "**/dist/**/*"
       - exclude: "**/node_modules/**/*"
       - exclude: "yscope-log-viewer/**/*"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfile.yaml` around lines 260 - 266, The webui task's sources currently use
a broad "**/*" glob which includes hidden Turbo cache files and causes
self-invalidation; update the webui task's sources list to explicitly exclude
the Turbo cache by adding an exclude entry for the .turbo directory (e.g.,
exclude: "**/.turbo/**" or exclude: ".turbo/**") alongside the existing excludes
so the sources key no longer picks up .turbo artifacts and prevents unnecessary
re-runs relative to the generates anchors.

Comment thread taskfile.yaml Outdated
Comment on lines 451 to 458
sources:
- "{{.G_NODEJS_22_CHECKSUM_FILE}}"
- "{{.TASKFILE}}"
- "client/package.json"
- "common/package.json"
- "package-lock.json"
- "pnpm-lock.yaml"
- "package.json"
- "server/package.json"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -uu -t f -g 'pnpm-workspace.yaml' components/webui

Repository: y-scope/clp

Length of output: 92


🏁 Script executed:

# Check the webui-node-modules task and surrounding context
head -n 470 taskfile.yaml | tail -n 30

Repository: y-scope/clp

Length of output: 1025


🏁 Script executed:

# Find where G_WEBUI_SRC_DIR is defined
rg 'G_WEBUI_SRC_DIR' taskfile.yaml | head -20

Repository: y-scope/clp

Length of output: 549


🏁 Script executed:

# Check if pnpm-workspace.yaml is used elsewhere in taskfile
rg 'pnpm-workspace' taskfile.yaml

Repository: y-scope/clp

Length of output: 37


Add pnpm-workspace.yaml to webui-node-modules sources.

This PR introduces pnpm-workspace.yaml but it isn't listed as a source for webui-node-modules. Changes to workspace configuration (e.g., workspace topology, nodeLinker settings) won't invalidate this task, so pnpm install --frozen-lockfile won't be re-run when the workspace configuration changes.

♻️ Proposed fix
     sources:
       - "{{.G_NODEJS_22_CHECKSUM_FILE}}"
       - "{{.TASKFILE}}"
       - "client/package.json"
       - "common/package.json"
       - "pnpm-lock.yaml"
+      - "pnpm-workspace.yaml"
       - "package.json"
       - "server/package.json"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sources:
- "{{.G_NODEJS_22_CHECKSUM_FILE}}"
- "{{.TASKFILE}}"
- "client/package.json"
- "common/package.json"
- "package-lock.json"
- "pnpm-lock.yaml"
- "package.json"
- "server/package.json"
sources:
- "{{.G_NODEJS_22_CHECKSUM_FILE}}"
- "{{.TASKFILE}}"
- "client/package.json"
- "common/package.json"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- "package.json"
- "server/package.json"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfile.yaml` around lines 451 - 458, The task sources list in taskfile.yaml
for the webui-node-modules task is missing pnpm-workspace.yaml, so workspace
configuration changes won't re-run pnpm install; update the sources array (the
block containing "sources:" and the existing entries like
"{{.G_NODEJS_22_CHECKSUM_FILE}}", "pnpm-lock.yaml", "package.json", etc.) to
include "pnpm-workspace.yaml" so changes to workspace topology or nodeLinker
settings will invalidate the task and trigger a fresh "pnpm install
--frozen-lockfile".

…import sort.

* taskfiles/lint.yaml: Break long PATH+turbo command across lines
  to satisfy yamllint's 100-char line-length limit.
* initialize-orchestration-db.py: Sort third-party import before
  first-party import per ruff's isort rules.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
taskfiles/lint.yaml (1)

79-79: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a recursive node_modules exclusion glob.

Line 79 currently excludes only first-level children under node_modules; nested paths are still included in source tracking.

Suggested fix
-      - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*"
+      - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/**"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@taskfiles/lint.yaml` at line 79, The exclude glob "- exclude:
\"{{.G_WEBUI_SRC_DIR}}/**/node_modules/*\"" only omits first-level entries
inside node_modules; replace it with a recursive pattern that excludes all
nested contents, e.g. change the exclude value for the node_modules entry in
lint.yaml (the line containing "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*") to use
"{{.G_WEBUI_SRC_DIR}}/**/node_modules/**" so all nested files and folders under
any node_modules are ignored.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@taskfiles/lint.yaml`:
- Line 79: The exclude glob "- exclude:
\"{{.G_WEBUI_SRC_DIR}}/**/node_modules/*\"" only omits first-level entries
inside node_modules; replace it with a recursive pattern that excludes all
nested contents, e.g. change the exclude value for the node_modules entry in
lint.yaml (the line containing "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*") to use
"{{.G_WEBUI_SRC_DIR}}/**/node_modules/**" so all nested files and folders under
any node_modules are ignored.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 71fc4bee-20cb-4bd9-99b2-ffac4d030088

📥 Commits

Reviewing files that changed from the base of the PR and between 1d1b827 and d0dd3f9.

📒 Files selected for processing (2)
  • components/clp-py-utils/clp_py_utils/initialize-orchestration-db.py
  • taskfiles/lint.yaml

Move common, client, and server into components/webui/packages/ to
follow the standard pnpm + Turborepo convention. Also add
verifyDepsBeforeRun: false to pnpm-workspace.yaml to prevent pnpm from
auto-installing production-only deps when per-package node_modules is
missing (which breaks eslint in packages without workspace deps).

Key changes:
* packages/ moved via `git mv` to preserve VCS history
* pnpm-workspace.yaml: updated package paths + verifyDepsBeforeRun
* pnpm-lock.yaml: updated importers paths to packages/*
* .gitignore: added packages/client/dist/
* taskfile.yaml: updated all paths + **/* globs in generates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant