refactor(webui): Migrate from npm workspaces to pnpm + Turborepo; fix pre-existing lint errors.#2262
refactor(webui): Migrate from npm workspaces to pnpm + Turborepo; fix pre-existing lint errors.#2262junhaoliao wants to merge 7 commits intoy-scope:mainfrom
Conversation
… pre-existing lint errors.
WalkthroughMigrates 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. ChangesWebUI pnpm/Turborepo Migration
Client Code Type Refinements
🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (2)
components/webui/package-lock.jsonis excluded by!**/package-lock.jsoncomponents/webui/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
components/webui/.gitignorecomponents/webui/client/package.jsoncomponents/webui/client/src/pages/IngestPage/Jobs/utils.tscomponents/webui/client/src/pages/SearchPage/SearchControls/index.tsxcomponents/webui/common/package.jsoncomponents/webui/package.jsoncomponents/webui/pnpm-workspace.yamlcomponents/webui/server/package.jsoncomponents/webui/turbo.jsontaskfile.yamltaskfiles/lint.yamltaskfiles/toolchains.yaml
| unrs-resolver: true | ||
|
|
||
| confirmModulesPurge: false | ||
| minimumReleaseAge: 0 |
There was a problem hiding this comment.
🧩 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.yamlRepository: 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.
| 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.
| - "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'" |
There was a problem hiding this comment.
🧹 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.jsonRepository: y-scope/clp
Length of output: 526
🏁 Script executed:
ls -la components/webui/ | grep -E '^d' | head -20Repository: 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 -10Repository: y-scope/clp
Length of output: 196
🏁 Script executed:
# Check taskfile.yaml context around line 286
sed -n '275,300p' taskfile.yamlRepository: 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.yamlRepository: 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 -5Repository: 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.
| - "{{.G_BUILD_DIR}}/webui-node-modules.md5" | ||
| - "{{.G_WEBUI_SRC_DIR}}/**/*" | ||
| - exclude: "{{.G_WEBUI_SRC_DIR}}/**/dist/*" | ||
| - exclude: "{{.G_WEBUI_SRC_DIR}}/**/node_modules/*" |
There was a problem hiding this comment.
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.
| - 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.
| - task: "remote:download-and-extract-tar" | ||
| vars: | ||
| CHECKSUM_FILE: "{{.G_NODEJS_22_CHECKSUM_FILE}}" | ||
| CHECKSUM_FILE: "/tmp/nodejs-22-download.md5" |
There was a problem hiding this comment.
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.
| 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.
…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.
There was a problem hiding this comment.
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
| 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/**/*" |
There was a problem hiding this comment.
🧩 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/nullRepository: 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:
- 1: https://taskfile.dev/docs/guide
- 2: https://taskfile.dev/usage/
- 3: Add support for working with shell options go-task/task#908
- 4: Shopt globstar does not work go-task/task#2043
- 5: Exclude doesn't support globbing go-task/task#1602
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.
| sources: | ||
| - "{{.G_NODEJS_22_CHECKSUM_FILE}}" | ||
| - "{{.TASKFILE}}" | ||
| - "client/package.json" | ||
| - "common/package.json" | ||
| - "package-lock.json" | ||
| - "pnpm-lock.yaml" | ||
| - "package.json" | ||
| - "server/package.json" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -uu -t f -g 'pnpm-workspace.yaml' components/webuiRepository: 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 30Repository: 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 -20Repository: y-scope/clp
Length of output: 549
🏁 Script executed:
# Check if pnpm-workspace.yaml is used elsewhere in taskfile
rg 'pnpm-workspace' taskfile.yamlRepository: 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.
| 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.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
taskfiles/lint.yaml (1)
79-79:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse a recursive
node_modulesexclusion 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
📒 Files selected for processing (2)
components/clp-py-utils/clp_py_utils/initialize-orchestration-db.pytaskfiles/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
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 redundantnpm ci --omit=devproduction install withpnpm 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 underpackages/and pnpm 11 settings (nodeLinker: hoistedfor flatnode_modulescompatibility;allowBuildsfor esbuild/unrs-resolver;confirmModulesPurge: falsefor non-TTY CI environments;verifyDepsBeforeRun: falseto prevent pnpm from auto-installing production-only deps when per-packagenode_modules/is missing).turbo.json(new): Defines the task pipeline with^builddependency ordering (common builds before client/server), pluslint:check,lint:fix,dev, andtesttasks.NODE_ENVis scoped to thebuildtask only (viaenv) to prevent lint tasks from running in production mode.lint:checkandlint:fixdepend on^buildso that@webui/commonis built before client/server are linted (required byeslint-import-resolver-typescriptto resolve@webui/common/*subpath imports).packages/:common/,client/,server/moved topackages/common/,packages/client/,packages/server/viagit mv(following the standard pnpm + Turborepo convention and preserving VCS history).package.json(root): Removedworkspaces,initscript,concurrentlydevDependency; addedpackageManager: "pnpm@11.0.8"and turbo delegation scripts.packages/common/package.json: Addeddevscript for turbo'sdevtask; replacednpm runself-references with direct commands.packages/client/package.json&packages/server/package.json: Changed"@webui/common": "*"to"workspace:*"; replacednpm run lint:check -- --fixwith directeslint --fixinvocation; server scripts changednpm runtopnpm run.package-lock.jsonreplaced bypnpm-lock.yaml.taskfile.yaml:webuitask 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). Addedsources/generatesfor task-level caching (using**/*globs).webui-node-modulessimplified fromnpm run init+ hoisting validation + custom checksum topnpm install --frozen-lockfile. RemovedG_WEBUI_CHECKSUM_FILEandG_WEBUI_PACKAGE_NODE_MODULES_CHECKSUM_FILEvariables. Added.turbotoclean-webui-package-node-modules. Changedwebui-node-modulesdep fromtoolchains:nodejs-22totoolchains:pnpm. Updated all paths from{common,client,server}/topackages/{common,client,server}/.taskfiles/toolchains.yaml: Addedpnpmtask (depends onnodejs-22, no-ops) for semantic clarity. Restructurednodejs-22to useutils:checksum:compute/validate(same pattern as therusttask) so the checksum covers both the Node.js extraction and the corepack/pnpm setup. Addedlabel: "toolchains-nodejs-22"for stable task checksum identity. AddedPNPM_VERSION: "11.0.8"var and corepack setup commands.taskfiles/lint.yaml:jstask changed fromnpm run "lint:..."toturbo 'lint:...'; addeddirattribute andnode_modules/.binto PATH; removedwebui-node-modules.md5from sources.client/src/pages/IngestPage/Jobs/utils.ts: Removed unusedCompressionJobStatusimport and unnecessary type assertion (status as CompressionJobStatustostatus).client/src/pages/SearchPage/SearchControls/index.tsx: Replaced deprecatedReact.FormEventwithReact.SyntheticEvent.Impact Assessment
What is affected:
npm ci --omit=dev→pnpm deploy --prod --legacy){common,client,server}/→packages/{common,client,server}/)npm run lint→turbo lint)Why the change is needed:
The custom MD5 checksum system (
utils:checksum:compute/validate) is verbose and error-prone — it requires manualsources/generatesdeclarations 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 --prodeliminates the redundant production install thatnpm ci --omit=devrequired, and removes the artificial workspace structure from the build output. Moving packages intopackages/follows the standard pnpm + Turborepo convention.Implications:
package-lock.jsonis replaced bypnpm-lock.yaml; developers must usepnpm installinstead ofnpm installnodeLinker: hoistedpreserves flatnode_modulescompatibility (same as npm); can switch toisolatedin a follow-upverifyDepsBeforeRun: falseprevents pnpm from auto-installing when per-packagenode_modules/is missing;pnpm installmust be run explicitlypnpm deploy --prod --legacycreates a standalone server deployment; pnpm is not required at runtimepnpmtask intoolchains.yamlcurrently just depends onnodejs-22(no-ops) — it exists for semantic clarity so downstream tasks can declaretoolchains:pnpmas a dependencybuild/webui/client/,build/webui/server/,build/webui/yscope-log-viewer/) is preservedChecklist
breaking change.
Validation performed
Build time comparison
rm -rf .task/ build/)Cold build is ~38% faster. Incremental times are comparable — both fully skip the task. The new system's task-level
sources/generateschecking (same mechanism as before, minus the custom MD5 checksum files) correctly determines thewebuitask is up-to-date.Scenario 1: Cold build from clean state
Task: Verify the full
webuipipeline builds from a clean state and produces the expected output structure.Command:
rm -rf .task/ build/ time task webuiOutput:
Explanation: All three workspace packages build successfully in dependency order (common → client + server).
pnpm deploycreates the production server deployment. Total cold build time: ~33s.Scenario 2: Incremental build — fully cached
Task: Verify that task's
sources/generateschecking correctly skips the entirewebuitask when no files have changed.Command:
time task webuiOutput:
Explanation: The
webuitask is fully up-to-date — task skips all commands includingturbo build,pnpm deploy, andrsync. 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 --legacyproduces a self-contained server directory with productionnode_modules(including@webui/common).Command:
Output:
Explanation: The build output preserves the expected structure:
client/(static SPA),server/(deployed server with productionnode_modulesincluding@webui/common), andyscope-log-viewer/. The server entry pointdist/src/main.jsandsettings.jsonfiles 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/commonfirst for module resolution) and the two pre-existing lint errors are fixed.Command:
Output:
Explanation: All three packages pass lint with zero errors and zero warnings.
lint:checkdepends on^build, so turbo builds@webui/commonbefore lintingclientandserver(required byeslint-import-resolver-typescriptto resolve@webui/common/*subpath imports). Whencommon/dist/already exists from a prior build, it's a cache hit.Scenario 5: Node.js toolchain caching
Task: Verify that the
nodejs-22task (including corepack/pnpm setup) is correctly cached on subsequent runs.Command:
task webui # Second run after cold buildOutput:
Explanation: The
nodejs-22task's checksum (computed viautils:checksum:computeafter corepack setup) correctly matches on the second run, so the task is skipped. This follows the same pattern as therusttask.