Skip to content

feat(scripts): merge @eggjs/scripts tool into monorepo#5591

Merged
fengmk2 merged 24 commits intonextfrom
scripts
Oct 7, 2025
Merged

feat(scripts): merge @eggjs/scripts tool into monorepo#5591
fengmk2 merged 24 commits intonextfrom
scripts

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Oct 6, 2025

  • Merge tool from https://github.com/eggjs/scripts
  • Update version to 5.0.0-beta.26
  • Migrate to monorepo structure following CLAUDE.md standards
  • Add catalog dependencies (common-bin, mz, mz-modules, source-map-support)
  • Migrate tests from Mocha to Vitest
  • Create standard tsdown.config.ts with unplugin-unused
  • Update imports to use .ts extensions
  • Fix TypeScript type imports and unused variable warnings
  • Add tool reference to root tsconfig.json
  • Keep CHANGELOG.md for version history

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • New CLI for managing apps: start/stop with daemon/foreground modes, ESM/CJS support, custom Node options, log rotation, sourcemap support, titles, Windows launchers, and richer start/stop controls.
  • Documentation

    • Added tooling README, comprehensive CHANGELOG, and MIT LICENSE for the scripts tooling.
  • Tests

    • Large end-to-end and fixture test suites covering start/stop flows, TS sourcemaps, env/port handling, IPC readiness, and shutdown scenarios.
  • Chores

    • CI switched to shard-based runs, workspace dependency additions, updated build/test scripts, and updated ignore patterns.

- Merge tool from https://github.com/eggjs/scripts
- Update version to 5.0.0-beta.26
- Migrate to monorepo structure following CLAUDE.md standards
- Add catalog dependencies (common-bin, mz, mz-modules, source-map-support)
- Migrate tests from Mocha to Vitest
- Create standard tsdown.config.ts with unplugin-unused
- Update imports to use .ts extensions
- Fix TypeScript type imports and unused variable warnings
- Add tool reference to root tsconfig.json
- Keep CHANGELOG.md for version history

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@fengmk2 fengmk2 requested a review from Copilot October 6, 2025 14:33
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 6, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a new tools/scripts package (egg-scripts/eggctl) with CLI commands (start/stop), helpers, shims, docs, license, many tests and fixtures; updates workspace deps, CI shard matrix, TypeScript/vitest references, and adjusts assorted package scripts and test configs.

Changes

Cohort / File(s) Summary
Workspace & CI updates
pnpm-workspace.yaml, .github/workflows/ci.yml, package.json, tsconfig.json, vitest.config.ts
Adds catalog deps (mz, mz-modules, source-map-support); introduces shard-aware CI and a dedicated egg-scripts test job; reorders pretest to run clean first; adds tools/scripts to TS references; narrows vitest projects.
tools/scripts package metadata & docs
tools/scripts/package.json, tools/scripts/README.md, tools/scripts/LICENSE, tools/scripts/CHANGELOG.md, tools/scripts/.gitignore, tools/scripts/tsconfig.json, tools/scripts/tsdown.config.ts, tools/scripts/vitest.config.ts
New package manifest, README, MIT license, changelog, .gitignore, local tsconfig/tsdown/vitest configs and build/publish settings.
CLI entrypoints & boot scripts
tools/scripts/bin/dev.cmd, tools/scripts/bin/dev.js, tools/scripts/bin/run.cmd, tools/scripts/bin/run.js
Adds Windows and Unix launchers; dev and run entrypoints boot @oclif/core (development and production) and forward args.
Runtime cluster starters
tools/scripts/scripts/start-cluster.mjs, tools/scripts/scripts/start-cluster.cjs
ESM/CJS shims parse JSON options, dynamically import framework modules, resolve startCluster and invoke it with options; handle errors and exit codes.
CLI core implementation
tools/scripts/src/baseCommand.ts, tools/scripts/src/commands/start.ts, tools/scripts/src/commands/stop.ts, tools/scripts/src/helper.ts, tools/scripts/src/index.ts, tools/scripts/src/types.ts
New BaseCommand abstraction; Start and Stop command implementations (env/logs/daemonization, spawning/monitoring, discovery/killing processes); cross-platform helper utilities and types; index re-exports Start and base utilities.
Tests: suites & utils
tools/scripts/test/*.test.ts, tools/scripts/test/utils.ts
Adds many new test suites (start/stop, TS/sourcemap, daemon/non-daemon, status/timeout) and test utilities for cleanup and stderr normalization.
Tests: fixtures
tools/scripts/test/fixtures/**
Adds numerous fixtures: minimal Egg-like apps (CJS/ESM/TS), configs, inject scripts, custom node dir, IPC helpers, package.json variants used by tests.
Bin/test updates for egg-bin
tools/egg-bin/**, tools/egg-bin/test/commands/**
Removes or replaces prior vitest config; adds/adjusts dev command tests (CommonJS/ESM/detect-port); narrows/rewrites several test suites.
Vitest hookTimeout / config tweaks
packages/egg/vitest.config.ts, plugins/*/vitest.config.ts, vitest.config.ts, tools/egg-bin/vitest.config.ts
Adds hookTimeout settings in several project configs; removes tools/egg-bin vitest export; narrows top-level vitest projects.
Package script & build tweaks
plugins/redis/package.json, plugins/typebox-validate/package.json, other package.json edits
Consolidates cleanup into build scripts (adds rimraf), removes separate clean scripts, updates CI/test script to use vitest run with coverage flags.
Minor plugin/test edits
plugins/schedule/test/dynamic.test.ts, plugins/security/src/app/extend/context.ts, packages/koa-static-cache/test/index.test.ts
Adjusts assertion from toBe(1) → >=1; adds a comment in CSRF switch; increases small wait durations in tests.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as eggctl (oclif)
  participant StartCmd as Start Command
  participant Shim as start-cluster.(mjs|cjs)
  participant Framework as Framework Module
  participant Cluster as startCluster()
  participant Worker as App Worker

  User->>CLI: eggctl start [BASEDIR] [--flags]
  CLI->>StartCmd: execute()
  StartCmd->>StartCmd: parse flags & package config
  StartCmd->>Shim: spawn Node with execArgv + JSON options
  note right of Shim: daemon or foreground modes
  Shim->>Framework: importModule(options.framework)
  Framework-->>Shim: { startCluster }
  Shim->>Cluster: call startCluster(options)
  Cluster->>Worker: fork workers
  Worker-->>Shim: IPC "egg-ready"
  Shim-->>StartCmd: forward ready / exit
  StartCmd-->>User: print status, log paths
Loading
sequenceDiagram
  autonumber
  actor User
  participant CLI as eggctl (oclif)
  participant StopCmd as Stop Command
  participant Finder as findNodeProcess
  participant OS as OS (ps / WMIC & signals)

  User->>CLI: eggctl stop [BASEDIR] [--title] [--timeout]
  CLI->>StopCmd: execute()
  StopCmd->>Finder: scan node processes
  Finder-->>StopCmd: masters & workers list
  alt masters found
    StopCmd->>OS: send SIGTERM to masters
    StopCmd->>OS: send SIGKILL/SIGTERM to workers as needed
  else none found
    StopCmd-->>User: "No running Egg processes"
  end
  StopCmd-->>User: "stopped"
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

A rabbit taps the console key,
"eggctl start!" — then sips its tea.
Clusters hum and logs align,
Stop commands whisper "shutdown time".
Tests hop through fixtures, bright — deploy and delight! 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title concisely describes the main change by indicating that the @eggjs/scripts tool is being merged into the monorepo and follows conventional commit style, matching the PR objectives and summarising the key action without extraneous detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2718c83 and 2eff4d9.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml (4 hunks)
  • plugins/mock/vitest.config.ts (1 hunks)
  • plugins/multipart/vitest.config.ts (1 hunks)

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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 6, 2025

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2eff4d9
Status:🚫  Build failed.

View logs

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR merges the @eggjs/scripts tool from a separate repository into the main Eggjs monorepo structure. The main purpose is to consolidate the Eggjs tooling ecosystem and modernize the scripts package with updated dependencies and TypeScript support.

Key changes:

  • Migrate @eggjs/scripts from external repository to tools/scripts/ directory
  • Upgrade to version 5.0.0-beta.26 with monorepo catalog dependencies
  • Convert tests from Mocha to Vitest framework

Reviewed Changes

Copilot reviewed 82 out of 89 changed files in this pull request and generated 2 comments.

File Description
tools/scripts/ Complete new package directory with source code, tests, and configuration
pnpm-workspace.yaml Add catalog dependencies for common-bin, mz, mz-modules, and source-map-support
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment on lines 522 to 525
await cleanup(fixturePath);
});

beforeEach(async () => {
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

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

Duplicate beforeEach hooks performing similar cleanup operations should be consolidated into a single hook to avoid redundant cleanup calls.

Suggested change
await cleanup(fixturePath);
});
beforeEach(async () => {

Copilot uses AI. Check for mistakes.
Comment on lines 271 to 274
describe('stop all with timeout', function () {
let app: Coffee;
let killer: Coffee;
this.timeout(17000);
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

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

Using function declaration and this.timeout() is Mocha syntax but the test imports Vitest. This will cause runtime errors since Vitest doesn't support this.timeout().

Copilot uses AI. Check for mistakes.
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 6, 2025

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2eff4d9
Status:⚡️  Build in progress...

View logs

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @fengmk2, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates the @eggjs/scripts tool into the monorepo, streamlining its development and maintenance within the larger project structure. This involves updating its version, migrating its testing framework to Vitest, modernizing its build configuration with tsdown and unplugin-unused, and ensuring full compatibility with TypeScript best practices and the monorepo's established standards.

Highlights

  • Monorepo Integration: The @eggjs/scripts tool has been successfully merged into the main monorepo, relocating its codebase to the tools/scripts directory for centralized management.
  • Version Update: The tool's version has been updated to 5.0.0-beta.26, reflecting the latest development iteration within the monorepo.
  • Dependency Management: New catalog dependencies, including common-bin, mz, mz-modules, and source-map-support, have been added and updated across pnpm-lock.yaml and pnpm-workspace.yaml.
  • Testing Framework Migration: The entire testing suite for @eggjs/scripts has been migrated from Mocha to Vitest, adopting a more modern and efficient testing framework.
  • Build System Modernization: A new tsdown.config.ts file has been introduced, leveraging unplugin-unused for optimized builds and enhanced type checking, aligning with monorepo standards.
  • TypeScript Enhancements: Imports have been updated to explicitly use .ts extensions, and various TypeScript type import issues and unused variable warnings have been resolved.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully merges the @eggjs/scripts tool into the monorepo, updating it to a modern TypeScript and oclif-based structure. The migration to Vitest and pnpm workspaces is well-executed. My review focuses on improving cross-platform compatibility, code clarity, and correctness. I've identified a few areas for improvement, including an issue with non-portable shell commands, a potential bug in process matching on Windows, and an opportunity to refactor a utility function for better readability.

const debug = debuglog('@eggjs/scripts/commands/stop');

const osRelated = {
titleTemplate: isWindows ? '\\"title\\":\\"%s\\"' : '"title":"%s"',
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The escaping for titleTemplate on Windows seems incorrect. It will produce a string with literal backslashes, like \"title\":\"the-title\", which is unlikely to match the process command line. It should probably be the same as the non-Windows version to correctly find and stop the process.

Suggested change
titleTemplate: isWindows ? '\\"title\\":\\"%s\\"' : '"title":"%s"',
titleTemplate: '"title":"%s"',

Comment on lines +332 to +343
try {
const args = ['-n', '100', stderrFile];
this.logToStderr('tail %s', args.join(' '));
const { stdout: headStdout } = await execFile('head', args);
const { stdout: tailStdout } = await execFile('tail', args);
this.logToStderr('Got error when startup: ');
this.logToStderr(headStdout);
this.logToStderr('...');
this.logToStderr(tailStdout);
} catch (err) {
this.logToStderr('ignore tail error: %s', err);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The use of head and tail commands is not portable and will fail on Windows. This can be replaced with a cross-platform solution using Node.js fs.readFile. Since this happens at startup, the log file is not expected to be very large, so reading the whole file should be acceptable.

You'll also need to add readFile to the node:fs/promises import on line 5.

Suggested change
try {
const args = ['-n', '100', stderrFile];
this.logToStderr('tail %s', args.join(' '));
const { stdout: headStdout } = await execFile('head', args);
const { stdout: tailStdout } = await execFile('tail', args);
this.logToStderr('Got error when startup: ');
this.logToStderr(headStdout);
this.logToStderr('...');
this.logToStderr(tailStdout);
} catch (err) {
this.logToStderr('ignore tail error: %s', err);
}
try {
const stderrContent = await readFile(stderrFile, 'utf-8');
const lines = stderrContent.split('\n');
this.logToStderr('Got error when startup:');
if (lines.length <= 200) {
this.logToStderr(stderrContent);
} else {
this.logToStderr(lines.slice(0, 100).join('\n'));
this.logToStderr('\n...\n');
this.logToStderr(lines.slice(-100).join('\n'));
}
} catch (err) {
this.logToStderr('ignore read stderr file error: %s', err);
}

Comment on lines +357 to +365
function stringify(obj: Record<string, any>, ignore: string[]) {
const result: Record<string, any> = {};
Object.keys(obj).forEach(key => {
if (!ignore.includes(key)) {
result[key] = obj[key];
}
});
return JSON.stringify(result);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This stringify function can be implemented more concisely and potentially more efficiently by creating a copy and deleting keys, rather than iterating and building a new object.

function stringify(obj: Record<string, any>, ignore: string[]) {
  const result = { ...obj };
  for (const key of ignore) {
    delete result[key];
  }
  return JSON.stringify(result);
}

@@ -0,0 +1,6 @@
import Start from './commands/start.js';

// exports.StopCommand = require('./lib/cmd/stop');
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This commented-out line appears to be a leftover from a previous implementation and can be removed for cleaner code.

Copy link
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: 11

♻️ Duplicate comments (1)
tools/scripts/test/fixtures/ts/app/controller/home.ts (1)

1-15: Duplicate comment - see review of tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts.

🧹 Nitpick comments (16)
tools/scripts/test/fixtures/trace-warnings/app.js (1)

12-13: Clarify deprecated Buffer usage in test fixture.

The new Buffer('aaa') call is intentionally used here to trigger a deprecation warning when testing --no-deprecation. Please expand the comment to state this purpose explicitly (e.g. “Trigger deprecation warning for Buffer; ensure --no-deprecation suppresses only deprecation warnings, not other warning types”).

tools/scripts/src/helper.ts (1)

52-60: Consider improving type safety for ESM interop.

The @ts-ignore directive at lines 56-58 suppresses TypeScript checking for import.meta.url. While this may be necessary for dual CJS/ESM support, consider:

  1. Ensuring tsconfig.json has proper module and moduleResolution settings for ESM
  2. Using a more specific @ts-expect-error with a descriptive comment explaining why the ignore is needed
  3. If possible, separating CJS and ESM entry points to avoid runtime checks

Example improvement:

-  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
-  // @ts-ignore
+  // @ts-expect-error - import.meta.url is only available in ESM context
   const __filename = fileURLToPath(import.meta.url);
tools/scripts/test/fixtures/status/app.js (1)

8-10: Add validation for WAIT_TIME environment variable.

The code uses parseInt(process.env.WAIT_TIME) without validation. If WAIT_TIME is undefined or not a valid number, parseInt returns NaN, which could cause unexpected behavior when passed to scheduler.wait().

Apply this diff to add a default value:

   app.beforeStart(async () => {
-    await scheduler.wait(parseInt(process.env.WAIT_TIME));
+    await scheduler.wait(parseInt(process.env.WAIT_TIME) || 0);
   });

Alternatively, add explicit validation:

   app.beforeStart(async () => {
-    await scheduler.wait(parseInt(process.env.WAIT_TIME));
+    const waitTime = parseInt(process.env.WAIT_TIME);
+    if (isNaN(waitTime)) {
+      throw new Error('WAIT_TIME must be a valid number');
+    }
+    await scheduler.wait(waitTime);
   });
tools/scripts/test/fixtures/ts-pkg/package.json (1)

1-14: Consider adding Node.js engine requirement.

Per coding guidelines, packages under {packages,plugins,tools}/**/package.json should require Node.js >= 22.18.0. While this is a test fixture, adding the engine requirement ensures consistency and prevents accidental usage with older Node versions.

Consider applying this diff:

 {
   "name": "ts-pkg",
   "version": "1.0.0",
+  "engines": {
+    "node": ">=22.18.0"
+  },
   "dependencies": {
tools/scripts/src/index.ts (1)

3-3: Remove or implement the commented StopCommand export.

The commented line suggests incomplete work or leftover code. Either implement and uncomment the StopCommand export, or remove this comment if the feature is not planned.

If you'd like me to help track this as a TODO or create an issue for implementing StopCommand, let me know.

tools/scripts/test/fixtures/ts-pkg/tsconfig.json (1)

1-26: Consider extending root tsconfig.json and setting baseUrl.

Per coding guidelines, TypeScript configuration files under {packages,plugins,tools}/**/tsconfig.json should:

  1. Extend the root tsconfig.json
  2. Set compilerOptions.baseUrl to "./"

While this is a test fixture that may need independent configuration for testing purposes, consider whether it should follow the standard pattern for consistency.

As per coding guidelines.

If this fixture intentionally uses standalone configuration for testing isolation, consider documenting that decision with a comment in the file.

Apply this diff if standard configuration is appropriate:

 {
+  "extends": "../../../../../tsconfig.json",
   "compileOnSave": true,
   "compilerOptions": {
+    "baseUrl": "./",
     "target": "es2017",
tools/scripts/test/fixtures/cluster-config/config/config.default.js (1)

1-6: LGTM! Standard configuration fixture.

The exports follow the expected pattern for Egg.js configuration files.

Consider adding 'use strict'; at the top for consistency with other fixtures (e.g., stop-timeout/config/config.default.js), though it's optional for CommonJS modules.

tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts (2)

7-7: Consider using unknown instead of any.

The any type disables type checking. Since the error is immediately used only for logging and property access, unknown with type narrowing is more type-safe.

Apply this diff:

-    } catch (err: any) {
+    } catch (err: unknown) {
       this.ctx.logger.error(err);
       this.ctx.body = {
-        msg: err.message,
-        stack: err.stack,
+        msg: err instanceof Error ? err.message : String(err),
+        stack: err instanceof Error ? err.stack : undefined,
       };
     }

3-15: Duplicate code across test fixtures.

This controller is duplicated in tools/scripts/test/fixtures/ts/app/controller/home.ts (lines 3-15) and tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts. Consider whether both fixtures are necessary or if they can share the same controller implementation.

If both fixtures require identical controllers, consider extracting the common implementation to a shared location or using symbolic links to avoid maintaining duplicate code.

tools/scripts/test/fixtures/ipc-bin/start.js (1)

3-3: Consider modernizing from generators to async/await.

The co library and generator functions (function*, yield) are older patterns that have been superseded by native async/await since Node.js 8.

For consistency with modern JavaScript and the rest of the codebase (which uses async/await), consider refactoring:

-const co = require('co');
-
 const BaseStartCommand = require('../../../lib/cmd/start');
 
 class StartCommand extends BaseStartCommand {
-  *run(context) {
-    yield super.run(context);
+  async run(context) {
+    await super.run(context);
     const child = this.child;
     child.on('message', msg => {
       if (msg && msg.action === 'egg-ready') {
         console.log('READY!!!');
       }
     });
   }
 }
 
 const start = new StartCommand();
 
-co(function* () {
-  yield start.run({
+(async () => {
+  await start.run({
     argv: {
       framework: 'custom-framework',
       _: [process.env.BASE_DIR],
       workers: 2,
       title: 'egg-server-example',
     },
     cwd: process.env.BASE_DIR,
-    // FIXME: overide run argv so execArgvObj is missing
+    // FIXME: override run argv so execArgvObj is missing
     // execArgv: [],
     env: {
       PATH: process.env.PATH,
     },
   });
-});
+})().catch(err => {
+  console.error('Start failed:', err);
+  process.exit(1);
+});

Note: Also fixed the typo "overide" → "override" in the FIXME comment.

tools/scripts/test/ts.test.ts (1)

116-116: Remove debugging console.log.

The console.log(result.data) statement should be removed or commented out to keep test output clean.

Apply this diff:

       const result = await request('http://127.0.0.1:7001', { dataType: 'json' });
-      console.log(result.data);
+      // console.log(result.data);
       assert.match(result.data.stack, /home\.ts:6:13/);
tools/scripts/src/baseCommand.ts (1)

18-23: Consider removing commented code.

The commented-out log-level flag definition should either be uncommented if planned for near-term use or removed to reduce clutter. If it's a future enhancement, consider documenting it in a TODO or issue instead.

If not needed soon, apply this diff:

   // define flags that can be inherited by any command that extends BaseCommand
   static baseFlags = {
-    // 'log-level': Flags.option({
-    //   default: 'info',
-    //   helpGroup: 'GLOBAL',
-    //   options: ['debug', 'warn', 'error', 'info', 'trace'] as const,
-    //   summary: 'Specify level for logging.',
-    // })(),
   };
tools/scripts/src/commands/stop.ts (1)

59-69: Consider post-wait re-scan and escalation for stubborn masters

After waiting, re-scan and force-kill any surviving masters to avoid orphaned clusters. This keeps stop deterministic on noisy systems.

Apply this diff:

       this.killProcesses(pids);
       // wait for 5s to confirm whether any worker process did not kill by master
       await scheduler.wait(flags.timeout);
+      // re-scan and escalate if masters still alive
+      const stillMasters = await this.findNodeProcesses(item => {
+        const cmd = item.cmd;
+        return flags.title
+          ? cmd.includes('start-cluster') && cmd.includes(format(osRelated.titleTemplate, flags.title))
+          : cmd.includes('start-cluster');
+      });
+      const stillPids = stillMasters.map(x => x.pid);
+      if (stillPids.length) {
+        this.log('master still running after %dms, force killing %j', flags.timeout, stillPids);
+        // On Unix, SIGKILL ensures termination; on Windows this maps to TerminateProcess.
+        this.killProcesses(stillPids, 'SIGKILL');
+      }

If Windows CI is enabled, please verify SIGKILL behavior there. If it’s undesirable on Windows, we can conditionally fall back to SIGTERM.

tools/scripts/test/start.test.ts (2)

218-226: Reduce flakiness: wait for server to start listening before spawning the app

Ensure the port is bound before starting Egg to deterministically trigger the “port in use” path.

Apply this diff:

-        const server = createServer(() => {});
-        server.listen(7007);
+        const server = createServer(() => {});
+        server.listen(7007);
+        await once(server, 'listening');

521-529: Duplicate beforeEach hooks in the same describe

Two beforeEach blocks run in order; merge for clarity and to avoid surprises if future changes depend on ordering.

Combine both beforeEach bodies into one hook.

tools/scripts/src/commands/start.ts (1)

331-347: Cross‑platform stderr tailing and log message inconsistencies

head/tail are unavailable on Windows; you already catch errors, but we can avoid needless subprocesses on win32 and fix the misleading “tail …” log when running head first.

Apply this diff to guard shelling out by platform and clarify logging:

-    if (hasError) {
+    if (hasError) {
       try {
-        const args = ['-n', '100', stderrFile];
-        this.logToStderr('tail %s', args.join(' '));
-        const { stdout: headStdout } = await execFile('head', args);
-        const { stdout: tailStdout } = await execFile('tail', args);
-        this.logToStderr('Got error when startup: ');
-        this.logToStderr(headStdout);
-        this.logToStderr('...');
-        this.logToStderr(tailStdout);
+        if (process.platform !== 'win32') {
+          const args = ['-n', '100', stderrFile];
+          this.logToStderr('head %s', args.join(' '));
+          const { stdout: headStdout } = await execFile('head', args);
+          this.logToStderr('tail %s', args.join(' '));
+          const { stdout: tailStdout } = await execFile('tail', args);
+          this.logToStderr('Got error when startup: ');
+          this.logToStderr(headStdout);
+          this.logToStderr('...');
+          this.logToStderr(tailStdout);
+        } else {
+          this.logToStderr('Error output detected, see %o', stderrFile);
+        }
       } catch (err) {
         this.logToStderr('ignore tail error: %s', err);
       }

Optionally, replace head/tail with a Node‑only reader (more portable). I can provide a small helper to read the last N lines.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb79a33 and e15ad05.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (88)
  • pnpm-workspace.yaml (3 hunks)
  • tools/scripts/CHANGELOG.md (1 hunks)
  • tools/scripts/LICENSE (1 hunks)
  • tools/scripts/README.md (1 hunks)
  • tools/scripts/bin/dev.cmd (1 hunks)
  • tools/scripts/bin/dev.js (1 hunks)
  • tools/scripts/bin/run.cmd (1 hunks)
  • tools/scripts/bin/run.js (1 hunks)
  • tools/scripts/package.json (1 hunks)
  • tools/scripts/scripts/start-cluster.cjs (1 hunks)
  • tools/scripts/scripts/start-cluster.mjs (1 hunks)
  • tools/scripts/src/baseCommand.ts (1 hunks)
  • tools/scripts/src/commands/start.ts (1 hunks)
  • tools/scripts/src/commands/stop.ts (1 hunks)
  • tools/scripts/src/helper.ts (1 hunks)
  • tools/scripts/src/index.ts (1 hunks)
  • tools/scripts/src/types.ts (1 hunks)
  • tools/scripts/test/egg-scripts.test.ts (1 hunks)
  • tools/scripts/test/fixtures/cluster-config/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/cluster-config/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/cluster-config/config/config.prod.js (1 hunks)
  • tools/scripts/test/fixtures/cluster-config/package.json (1 hunks)
  • tools/scripts/test/fixtures/custom-node-dir/.node/bin/foo (1 hunks)
  • tools/scripts/test/fixtures/custom-node-dir/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/custom-node-dir/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/custom-node-dir/package.json (1 hunks)
  • tools/scripts/test/fixtures/egg-app/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/egg-app/package.json (1 hunks)
  • tools/scripts/test/fixtures/egg-revert/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/egg-revert/package.json (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-config/app.js (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-config/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-config/package.json (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-node-options/app.js (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-node-options/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/egg-scripts-node-options/package.json (1 hunks)
  • tools/scripts/test/fixtures/example/app.js (1 hunks)
  • tools/scripts/test/fixtures/example/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/example/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/example/config/config.pre.js (1 hunks)
  • tools/scripts/test/fixtures/example/package.json (1 hunks)
  • tools/scripts/test/fixtures/ipc-bin/start.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-esm/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-esm/config/plugin.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-esm/inject1.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-esm/inject2.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-esm/package.json (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-sourcemap/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-sourcemap/config/plugin.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config-sourcemap/package.json (1 hunks)
  • tools/scripts/test/fixtures/pkg-config/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config/config/plugin.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config/inject1.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config/inject2.js (1 hunks)
  • tools/scripts/test/fixtures/pkg-config/package.json (1 hunks)
  • tools/scripts/test/fixtures/status/app.js (1 hunks)
  • tools/scripts/test/fixtures/status/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/status/package.json (1 hunks)
  • tools/scripts/test/fixtures/stop-timeout/app.js (1 hunks)
  • tools/scripts/test/fixtures/stop-timeout/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/stop-timeout/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/stop-timeout/package.json (1 hunks)
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/package.json (1 hunks)
  • tools/scripts/test/fixtures/subdir-as-basedir/package.json (1 hunks)
  • tools/scripts/test/fixtures/trace-warnings/app.js (1 hunks)
  • tools/scripts/test/fixtures/trace-warnings/package.json (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/app/controller/home.js (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/package.json (1 hunks)
  • tools/scripts/test/fixtures/ts-pkg/tsconfig.json (1 hunks)
  • tools/scripts/test/fixtures/ts/app/controller/home.js (1 hunks)
  • tools/scripts/test/fixtures/ts/app/controller/home.ts (1 hunks)
  • tools/scripts/test/fixtures/ts/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/ts/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/ts/package.json (1 hunks)
  • tools/scripts/test/fixtures/ts/tsconfig.json (1 hunks)
  • tools/scripts/test/start.test.ts (1 hunks)
  • tools/scripts/test/stop.test.ts (1 hunks)
  • tools/scripts/test/ts.test.ts (1 hunks)
  • tools/scripts/test/utils.ts (1 hunks)
  • tools/scripts/tsconfig.json (1 hunks)
  • tools/scripts/tsdown.config.ts (1 hunks)
  • tools/scripts/vitest.config.ts (1 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/test/fixtures/**

📄 CodeRabbit inference engine (AGENTS.md)

Put reusable test data under test/fixtures/

Files:

  • tools/scripts/test/fixtures/egg-scripts-node-options/config/config.default.js
  • tools/scripts/test/fixtures/ts-pkg/app/router.js
  • tools/scripts/test/fixtures/ts-pkg/config/config.default.js
  • tools/scripts/test/fixtures/pkg-config-esm/inject2.js
  • tools/scripts/test/fixtures/pkg-config/config/config.default.js
  • tools/scripts/test/fixtures/pkg-config-sourcemap/config/config.default.js
  • tools/scripts/test/fixtures/pkg-config/inject1.js
  • tools/scripts/test/fixtures/stop-timeout/package.json
  • tools/scripts/test/fixtures/example/app.js
  • tools/scripts/test/fixtures/cluster-config/app/router.js
  • tools/scripts/test/fixtures/status/config/config.default.js
  • tools/scripts/test/fixtures/stop-timeout/config/config.default.js
  • tools/scripts/test/fixtures/ts/app/controller/home.ts
  • tools/scripts/test/fixtures/egg-app/config/config.default.js
  • tools/scripts/test/fixtures/cluster-config/config/config.default.js
  • tools/scripts/test/fixtures/egg-scripts-config/app.js
  • tools/scripts/test/fixtures/example/package.json
  • tools/scripts/test/fixtures/trace-warnings/app.js
  • tools/scripts/test/fixtures/pkg-config-esm/config/plugin.js
  • tools/scripts/test/fixtures/pkg-config-esm/config/config.default.js
  • tools/scripts/test/fixtures/egg-revert/config/config.default.js
  • tools/scripts/test/fixtures/pkg-config-sourcemap/config/plugin.js
  • tools/scripts/test/fixtures/egg-revert/package.json
  • tools/scripts/test/fixtures/custom-node-dir/app/router.js
  • tools/scripts/test/fixtures/stop-timeout/app.js
  • tools/scripts/test/fixtures/ts/app/controller/home.js
  • tools/scripts/test/fixtures/ts/tsconfig.json
  • tools/scripts/test/fixtures/pkg-config/config/plugin.js
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/config/config.default.js
  • tools/scripts/test/fixtures/egg-scripts-config/config/config.default.js
  • tools/scripts/test/fixtures/cluster-config/config/config.prod.js
  • tools/scripts/test/fixtures/egg-scripts-node-options/app.js
  • tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/app/router.js
  • tools/scripts/test/fixtures/example/config/config.pre.js
  • tools/scripts/test/fixtures/ts/app/router.js
  • tools/scripts/test/fixtures/pkg-config/package.json
  • tools/scripts/test/fixtures/example/config/config.default.js
  • tools/scripts/test/fixtures/ts/config/config.default.js
  • tools/scripts/test/fixtures/stop-timeout/app/router.js
  • tools/scripts/test/fixtures/custom-node-dir/package.json
  • tools/scripts/test/fixtures/custom-node-dir/config/config.default.js
  • tools/scripts/test/fixtures/example/app/router.js
  • tools/scripts/test/fixtures/status/package.json
  • tools/scripts/test/fixtures/subdir-as-basedir/package.json
  • tools/scripts/test/fixtures/ts-pkg/tsconfig.json
  • tools/scripts/test/fixtures/ts-pkg/package.json
  • tools/scripts/test/fixtures/cluster-config/package.json
  • tools/scripts/test/fixtures/pkg-config-esm/inject1.js
  • tools/scripts/test/fixtures/pkg-config-sourcemap/package.json
  • tools/scripts/test/fixtures/trace-warnings/package.json
  • tools/scripts/test/fixtures/egg-app/package.json
  • tools/scripts/test/fixtures/ts-pkg/app/controller/home.js
  • tools/scripts/test/fixtures/pkg-config-esm/package.json
  • tools/scripts/test/fixtures/ts/package.json
  • tools/scripts/test/fixtures/status/app.js
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/package.json
  • tools/scripts/test/fixtures/pkg-config/inject2.js
  • tools/scripts/test/fixtures/egg-scripts-node-options/package.json
  • tools/scripts/test/fixtures/egg-scripts-config/package.json
  • tools/scripts/test/fixtures/ipc-bin/start.js
{package.json,{packages,plugins,tools}/**/package.json}

📄 CodeRabbit inference engine (CLAUDE.md)

{package.json,{packages,plugins,tools}/**/package.json}: All packages must require Node.js >= 22.18.0 (set engines.node accordingly)
Use workspace:* for internal dependencies and catalog: for external dependencies defined in pnpm-workspace.yaml

Files:

  • tools/scripts/test/fixtures/stop-timeout/package.json
  • tools/scripts/test/fixtures/example/package.json
  • tools/scripts/test/fixtures/egg-revert/package.json
  • tools/scripts/test/fixtures/pkg-config/package.json
  • tools/scripts/test/fixtures/custom-node-dir/package.json
  • tools/scripts/test/fixtures/status/package.json
  • tools/scripts/test/fixtures/subdir-as-basedir/package.json
  • tools/scripts/test/fixtures/ts-pkg/package.json
  • tools/scripts/test/fixtures/cluster-config/package.json
  • tools/scripts/test/fixtures/pkg-config-sourcemap/package.json
  • tools/scripts/test/fixtures/trace-warnings/package.json
  • tools/scripts/test/fixtures/egg-app/package.json
  • tools/scripts/test/fixtures/pkg-config-esm/package.json
  • tools/scripts/test/fixtures/ts/package.json
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/package.json
  • tools/scripts/test/fixtures/egg-scripts-node-options/package.json
  • tools/scripts/test/fixtures/egg-scripts-config/package.json
  • tools/scripts/package.json
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Each package must define scripts: typecheck as "tsc --noEmit" and lint as "oxlint --type-aware"

Files:

  • tools/scripts/test/fixtures/stop-timeout/package.json
  • tools/scripts/test/fixtures/example/package.json
  • tools/scripts/test/fixtures/egg-revert/package.json
  • tools/scripts/test/fixtures/pkg-config/package.json
  • tools/scripts/test/fixtures/custom-node-dir/package.json
  • tools/scripts/test/fixtures/status/package.json
  • tools/scripts/test/fixtures/subdir-as-basedir/package.json
  • tools/scripts/test/fixtures/ts-pkg/package.json
  • tools/scripts/test/fixtures/cluster-config/package.json
  • tools/scripts/test/fixtures/pkg-config-sourcemap/package.json
  • tools/scripts/test/fixtures/trace-warnings/package.json
  • tools/scripts/test/fixtures/egg-app/package.json
  • tools/scripts/test/fixtures/pkg-config-esm/package.json
  • tools/scripts/test/fixtures/ts/package.json
  • tools/scripts/test/fixtures/subdir-as-basedir/base-dir/package.json
  • tools/scripts/test/fixtures/egg-scripts-node-options/package.json
  • tools/scripts/test/fixtures/egg-scripts-config/package.json
  • tools/scripts/package.json
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • tools/scripts/test/fixtures/ts/app/controller/home.ts
  • tools/scripts/src/index.ts
  • tools/scripts/src/types.ts
  • tools/scripts/src/helper.ts
  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts
  • tools/scripts/test/ts.test.ts
  • tools/scripts/src/commands/stop.ts
  • tools/scripts/src/baseCommand.ts
  • tools/scripts/vitest.config.ts
  • tools/scripts/test/start.test.ts
  • tools/scripts/test/stop.test.ts
  • tools/scripts/tsdown.config.ts
  • tools/scripts/src/commands/start.ts
  • tools/scripts/test/utils.ts
{packages,plugins,tools}/**/tsconfig.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json and set compilerOptions.baseUrl to "./"
Enable TypeScript strict mode in all TypeScript packages

Files:

  • tools/scripts/test/fixtures/ts/tsconfig.json
  • tools/scripts/tsconfig.json
  • tools/scripts/test/fixtures/ts-pkg/tsconfig.json
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Test files should be named with the pattern test/**/*.test.ts

Files:

  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/start.test.ts
  • tools/scripts/test/stop.test.ts
{tsconfig.json,packages/*/tsconfig.json}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Enable strict TypeScript mode across all packages

Files:

  • tsconfig.json
tsconfig.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Root tsconfig.json must include all packages in the references array

Files:

  • tsconfig.json
{packages,plugins,tools}/**/vitest.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each Vitest-using package should include a vitest.config.ts

Files:

  • tools/scripts/vitest.config.ts
{packages,plugins,tools}/**/tsdown.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each package should use tsdown for builds and include a tsdown.config.ts

Files:

  • tools/scripts/tsdown.config.ts
pnpm-workspace.yaml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Manage external dependency versions via the catalog in pnpm-workspace.yaml

Files:

  • pnpm-workspace.yaml
🧠 Learnings (24)
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/egg/src/config/{plugin.ts,config.default.ts} : Define built-in plugin and default framework configuration within packages/egg/src/config

Applied to files:

  • tools/scripts/test/fixtures/pkg-config-esm/config/plugin.js
  • tools/scripts/src/types.ts
  • tools/scripts/test/fixtures/pkg-config-sourcemap/config/plugin.js
  • tools/scripts/test/fixtures/pkg-config/config/plugin.js
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/tsconfig.json : Enable TypeScript strict mode in all TypeScript packages

Applied to files:

  • tools/scripts/test/fixtures/ts/tsconfig.json
  • tools/scripts/test/fixtures/ts-pkg/tsconfig.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json and set compilerOptions.baseUrl to "./"

Applied to files:

  • tools/scripts/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsconfig.json : All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"

Applied to files:

  • tools/scripts/tsconfig.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : The egg-bin tool package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2,koa-static-cache,router}/test/**/*.test.ts : Core packages must use Vitest (import from 'vitest') with test files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/stop.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/vitest.config.ts : Each Vitest-using package should include a vitest.config.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to plugins/**/test/**/*.test.ts : Plugin tests must use Vitest (import from 'vitest') and follow the test file pattern test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Mirror the repository test pattern when adding new suites

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/cookies/test/**/*.test.ts : The cookies package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to plugins/**/package.json : All plugins must include egg as a peerDependency with version "workspace:*"

Applied to files:

  • tools/scripts/test/fixtures/custom-node-dir/package.json
  • tools/scripts/test/fixtures/cluster-config/package.json
  • tools/scripts/test/fixtures/egg-app/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to tsconfig.json : Root tsconfig.json must include all packages in the references array

Applied to files:

  • tsconfig.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/package.json : Each package must define scripts: typecheck as "tsc --noEmit" and lint as "oxlint --type-aware"

Applied to files:

  • tools/scripts/test/fixtures/ts/package.json
  • tools/scripts/package.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown configuration template (entry: 'src/**/*.ts', dts: true, exports.devExports: true, unused.level: 'error')

Applied to files:

  • tools/scripts/tsdown.config.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Each package should use tsdown for builds and include a tsdown.config.ts

Applied to files:

  • tools/scripts/tsdown.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must provide a tsdown.config.ts for unbundled ESM builds

Applied to files:

  • tools/scripts/tsdown.config.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to pnpm-workspace.yaml : Manage external dependency versions via the catalog in pnpm-workspace.yaml

Applied to files:

  • pnpm-workspace.yaml
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Applied to files:

  • pnpm-workspace.yaml
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {package.json,{packages,plugins,tools}/**/package.json} : Use workspace:* for internal dependencies and catalog: for external dependencies defined in pnpm-workspace.yaml

Applied to files:

  • pnpm-workspace.yaml
🧬 Code graph analysis (20)
tools/scripts/test/fixtures/ts-pkg/app/router.js (1)
tools/scripts/test/fixtures/ts/app/router.js (1)
  • app (4-4)
tools/scripts/test/fixtures/egg-scripts-config/app.js (1)
tools/scripts/test/fixtures/status/app.js (1)
  • require (1-1)
tools/scripts/test/fixtures/ts/app/controller/home.js (1)
tools/scripts/test/fixtures/ts/app/controller/home.ts (1)
  • AppController (3-15)
tools/scripts/scripts/start-cluster.cjs (1)
tools/scripts/scripts/start-cluster.mjs (3)
  • debug (4-4)
  • options (8-8)
  • importModule (10-10)
tools/scripts/src/helper.ts (1)
scripts/version.js (1)
  • __dirname (13-13)
tools/scripts/test/egg-scripts.test.ts (1)
tools/scripts/src/helper.ts (1)
  • getSourceFilename (62-64)
tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts (1)
tools/scripts/test/fixtures/ts/app/controller/home.ts (1)
  • AppController (3-15)
tools/scripts/test/ts.test.ts (2)
tools/scripts/src/helper.ts (2)
  • getSourceFilename (62-64)
  • isWindows (5-5)
tools/scripts/test/utils.ts (3)
  • Coffee (6-6)
  • cleanup (8-42)
  • replaceWeakRefMessage (44-50)
tools/scripts/test/fixtures/ts/app/router.js (1)
tools/scripts/test/fixtures/ts-pkg/app/router.js (1)
  • app (4-4)
tools/scripts/src/commands/stop.ts (1)
tools/scripts/src/helper.ts (4)
  • isWindows (5-5)
  • NodeProcess (9-12)
  • findNodeProcess (16-38)
  • kill (40-50)
tools/scripts/test/fixtures/example/app/router.js (2)
tools/scripts/test/fixtures/ts-pkg/app/router.js (1)
  • app (4-4)
tools/scripts/test/fixtures/ts/app/router.js (1)
  • app (4-4)
tools/scripts/scripts/start-cluster.mjs (1)
tools/scripts/scripts/start-cluster.cjs (3)
  • debug (5-5)
  • options (9-9)
  • importModule (11-11)
tools/scripts/src/baseCommand.ts (1)
tools/scripts/src/types.ts (1)
  • PackageEgg (1-9)
tools/scripts/vitest.config.ts (1)
packages/egg/src/lib/types.ts (1)
  • defineConfig (106-108)
tools/scripts/test/fixtures/ts-pkg/app/controller/home.js (2)
tools/scripts/test/fixtures/ts-pkg/app/controller/home.ts (1)
  • AppController (3-15)
tools/scripts/test/fixtures/ts/app/controller/home.ts (1)
  • AppController (3-15)
tools/scripts/test/start.test.ts (2)
tools/scripts/src/helper.ts (2)
  • getSourceFilename (62-64)
  • isWindows (5-5)
tools/scripts/test/utils.ts (3)
  • Coffee (6-6)
  • cleanup (8-42)
  • replaceWeakRefMessage (44-50)
tools/scripts/test/stop.test.ts (2)
tools/scripts/src/helper.ts (2)
  • getSourceFilename (62-64)
  • isWindows (5-5)
tools/scripts/test/utils.ts (3)
  • Coffee (6-6)
  • cleanup (8-42)
  • replaceWeakRefMessage (44-50)
tools/scripts/test/fixtures/status/app.js (1)
tools/scripts/test/fixtures/egg-scripts-config/app.js (1)
  • require (1-1)
tools/scripts/src/commands/start.ts (4)
tools/scripts/scripts/start-cluster.cjs (2)
  • debug (5-5)
  • options (9-9)
tools/scripts/scripts/start-cluster.mjs (2)
  • debug (4-4)
  • options (8-8)
tools/scripts/src/helper.ts (1)
  • getSourceDirname (52-60)
packages/utils/src/import.ts (1)
  • importResolve (275-361)
tools/scripts/test/utils.ts (1)
tools/scripts/src/helper.ts (2)
  • findNodeProcess (16-38)
  • isWindows (5-5)
🪛 ast-grep (0.39.5)
tools/scripts/test/stop.test.ts

[warning] 358-358: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(Starting custom-framework application at ${appPathInRegexp})
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 markdownlint-cli2 (0.18.1)
tools/scripts/README.md

19-19: Bare URL used

(MD034, no-bare-urls)


30-30: Bare URL used

(MD034, no-bare-urls)


32-32: Bare URL used

(MD034, no-bare-urls)


42-42: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


42-42: Hard tabs
Column: 1

(MD010, no-hard-tabs)


43-43: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


43-43: Hard tabs
Column: 1

(MD010, no-hard-tabs)


44-44: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


44-44: Hard tabs
Column: 1

(MD010, no-hard-tabs)


45-45: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


45-45: Hard tabs
Column: 1

(MD010, no-hard-tabs)


46-46: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


46-46: Hard tabs
Column: 1

(MD010, no-hard-tabs)


49-49: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


49-49: Hard tabs
Column: 1

(MD010, no-hard-tabs)


50-50: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


50-50: Hard tabs
Column: 1

(MD010, no-hard-tabs)


51-51: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


51-51: Hard tabs
Column: 1

(MD010, no-hard-tabs)


52-52: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


52-52: Hard tabs
Column: 1

(MD010, no-hard-tabs)


57-57: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


57-57: Hard tabs
Column: 1

(MD010, no-hard-tabs)


58-58: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


58-58: Hard tabs
Column: 1

(MD010, no-hard-tabs)


59-59: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


59-59: Hard tabs
Column: 1

(MD010, no-hard-tabs)


62-62: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


62-62: Hard tabs
Column: 1

(MD010, no-hard-tabs)


63-63: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


63-63: Hard tabs
Column: 1

(MD010, no-hard-tabs)


100-100: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


103-103: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


104-104: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


106-106: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


109-109: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


110-110: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


112-112: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


115-115: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


116-116: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


118-118: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


119-119: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

tools/scripts/CHANGELOG.md

19-19: Bare URL used

(MD034, no-bare-urls)


30-30: Bare URL used

(MD034, no-bare-urls)


32-32: Bare URL used

(MD034, no-bare-urls)


42-42: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


42-42: Hard tabs
Column: 1

(MD010, no-hard-tabs)


43-43: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


43-43: Hard tabs
Column: 1

(MD010, no-hard-tabs)


44-44: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


44-44: Hard tabs
Column: 1

(MD010, no-hard-tabs)


45-45: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


45-45: Hard tabs
Column: 1

(MD010, no-hard-tabs)


46-46: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


46-46: Hard tabs
Column: 1

(MD010, no-hard-tabs)


49-49: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


49-49: Hard tabs
Column: 1

(MD010, no-hard-tabs)


50-50: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


50-50: Hard tabs
Column: 1

(MD010, no-hard-tabs)


51-51: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


51-51: Hard tabs
Column: 1

(MD010, no-hard-tabs)


52-52: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


52-52: Hard tabs
Column: 1

(MD010, no-hard-tabs)


57-57: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


57-57: Hard tabs
Column: 1

(MD010, no-hard-tabs)


58-58: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


58-58: Hard tabs
Column: 1

(MD010, no-hard-tabs)


59-59: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


59-59: Hard tabs
Column: 1

(MD010, no-hard-tabs)


62-62: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


62-62: Hard tabs
Column: 1

(MD010, no-hard-tabs)


63-63: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


63-63: Hard tabs
Column: 1

(MD010, no-hard-tabs)


100-100: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


103-103: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


104-104: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


106-106: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


109-109: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


110-110: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


112-112: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


115-115: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


116-116: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


118-118: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


119-119: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


121-121: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


124-124: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


125-125: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


127-127: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


128-128: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


130-130: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


133-133: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


134-134: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


136-136: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


137-137: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


139-139: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


142-142: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


143-143: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


145-145: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


148-148: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


149-149: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


151-151: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


154-154: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


155-155: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


157-157: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


160-160: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


161-161: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


163-163: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


166-166: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


167-167: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


169-169: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


170-170: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


172-172: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


175-175: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


176-176: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


178-178: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


181-181: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


182-182: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


184-184: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


185-185: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


186-186: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


188-188: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


191-191: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


193-193: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


196-196: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


197-197: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


199-199: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


200-200: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


202-202: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


205-205: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


206-206: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


208-208: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


211-211: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


212-212: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


214-214: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


217-217: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


218-218: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


220-220: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


221-221: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


223-223: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


226-226: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


228-228: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


231-231: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


233-233: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


236-236: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


237-237: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


239-239: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


242-242: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


243-243: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


245-245: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


246-246: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


248-248: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


251-251: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


252-252: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


254-254: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


257-257: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


258-258: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


260-260: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


263-263: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


264-264: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


266-266: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


269-269: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


270-270: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


272-272: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


275-275: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


276-276: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


278-278: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


279-279: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


281-281: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


284-284: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


285-285: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


287-287: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


288-288: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


290-290: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


293-293: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


294-294: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


296-296: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


299-299: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


301-301: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


304-304: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


306-306: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


309-309: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Cloudflare Pages: egg-v3

Comment on lines 7 to 13
async function main() {
debug('argv: %o', process.argv);
const options = JSON.parse(process.argv[2]);
debug('start cluster options: %o', options);
const { startCluster } = await importModule(options.framework);
await startCluster(options);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add error handling for JSON parsing and cluster start failures.

The main() function lacks error handling, which can lead to uncaught exceptions and silent failures:

  • JSON.parse(process.argv[2]) will throw if the argument is missing or malformed JSON
  • startCluster(options) failures won't be caught or logged
  • The void main() pattern on line 15 ignores the promise, suppressing any errors

Apply this diff to add proper error handling:

 async function main() {
-  debug('argv: %o', process.argv);
-  const options = JSON.parse(process.argv[2]);
-  debug('start cluster options: %o', options);
-  const { startCluster } = await importModule(options.framework);
-  await startCluster(options);
+  try {
+    debug('argv: %o', process.argv);
+    if (!process.argv[2]) {
+      throw new Error('Missing options argument');
+    }
+    const options = JSON.parse(process.argv[2]);
+    debug('start cluster options: %o', options);
+    const { startCluster } = await importModule(options.framework);
+    await startCluster(options);
+  } catch (err) {
+    console.error('Failed to start cluster:', err);
+    process.exit(1);
+  }
 }
 
-void main();
+main().catch(err => {
+  console.error('Unhandled error:', err);
+  process.exit(1);
+});
📝 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
async function main() {
debug('argv: %o', process.argv);
const options = JSON.parse(process.argv[2]);
debug('start cluster options: %o', options);
const { startCluster } = await importModule(options.framework);
await startCluster(options);
}
async function main() {
try {
debug('argv: %o', process.argv);
if (!process.argv[2]) {
throw new Error('Missing options argument');
}
const options = JSON.parse(process.argv[2]);
debug('start cluster options: %o', options);
const { startCluster } = await importModule(options.framework);
await startCluster(options);
} catch (err) {
console.error('Failed to start cluster:', err);
process.exit(1);
}
}
main().catch(err => {
console.error('Unhandled error:', err);
process.exit(1);
});
🤖 Prompt for AI Agents
In tools/scripts/scripts/start-cluster.cjs around lines 7 to 13, add robust
error handling: validate that process.argv[2] exists and wrap JSON.parse in a
try/catch to log a clear error and exit non‑zero on malformed or missing JSON;
wrap the dynamic import and startCluster(options) call in a try/catch to log any
import/start failures and exit non‑zero; ensure the top‑level invocation does
not use void main() but instead awaits or attaches .catch(...) to main() so
unhandled rejections are logged and the process exits with a non‑zero code.

Comment on lines +16 to +38
export async function findNodeProcess(filterFn?: FilterFunction): Promise<NodeProcess[]> {
const command = isWindows
? 'wmic Path win32_process Where "Name = \'node.exe\'" Get CommandLine,ProcessId'
: // command, cmd are alias of args, not POSIX standard, so we use args
'ps -wweo "pid,args"';
const stdio = await runScript(command, { stdio: 'pipe' });
const processList = stdio
.stdout!.toString()
.split('\n')
.reduce<NodeProcess[]>((arr, line) => {
if (!!line && !line.includes('/bin/sh') && line.includes('node')) {
const m = line.match(REGEX);
if (m) {
const item: NodeProcess = isWindows ? { pid: parseInt(m[2]), cmd: m[1] } : { pid: parseInt(m[1]), cmd: m[2] };
if (filterFn?.(item)) {
arr.push(item);
}
}
}
return arr;
}, []);
return processList;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add defensive check for stdout.

Line 23 uses a non-null assertion (stdout!.toString()) assuming stdout is always present. While runScript with stdio: 'pipe' should populate stdout, defensive coding would prevent potential runtime crashes.

Apply this diff to add a defensive check:

   const stdio = await runScript(command, { stdio: 'pipe' });
+  if (!stdio.stdout) {
+    return [];
+  }
   const processList = stdio
-    .stdout!.toString()
+    .stdout.toString()
     .split('\n')
📝 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
export async function findNodeProcess(filterFn?: FilterFunction): Promise<NodeProcess[]> {
const command = isWindows
? 'wmic Path win32_process Where "Name = \'node.exe\'" Get CommandLine,ProcessId'
: // command, cmd are alias of args, not POSIX standard, so we use args
'ps -wweo "pid,args"';
const stdio = await runScript(command, { stdio: 'pipe' });
const processList = stdio
.stdout!.toString()
.split('\n')
.reduce<NodeProcess[]>((arr, line) => {
if (!!line && !line.includes('/bin/sh') && line.includes('node')) {
const m = line.match(REGEX);
if (m) {
const item: NodeProcess = isWindows ? { pid: parseInt(m[2]), cmd: m[1] } : { pid: parseInt(m[1]), cmd: m[2] };
if (filterFn?.(item)) {
arr.push(item);
}
}
}
return arr;
}, []);
return processList;
}
export async function findNodeProcess(filterFn?: FilterFunction): Promise<NodeProcess[]> {
const command = isWindows
? 'wmic Path win32_process Where "Name = \'node.exe\'" Get CommandLine,ProcessId'
: // command, cmd are alias of args, not POSIX standard, so we use args
'ps -wweo "pid,args"';
const stdio = await runScript(command, { stdio: 'pipe' });
if (!stdio.stdout) {
return [];
}
const processList = stdio
.stdout.toString()
.split('\n')
.reduce<NodeProcess[]>((arr, line) => {
if (!!line && !line.includes('/bin/sh') && line.includes('node')) {
const m = line.match(REGEX);
if (m) {
const item: NodeProcess = isWindows
? { pid: parseInt(m[2]), cmd: m[1] }
: { pid: parseInt(m[1]), cmd: m[2] };
if (filterFn?.(item)) {
arr.push(item);
}
}
}
return arr;
}, []);
return processList;
}
🤖 Prompt for AI Agents
In tools/scripts/src/helper.ts around lines 16 to 38, the code uses a non-null
assertion stdout!.toString() which can throw if stdout is undefined; change to
defensively handle missing stdout by first checking stdio.stdout — if it's
null/undefined return an empty array (or otherwise treat output as empty string)
before attempting to call toString(), then continue parsing; ensure the function
returns [] when no stdout is present to avoid runtime crashes.

Comment on lines +1 to +7
{
"name": "example",
"version": "1.0.0",
"dependencies": {
"egg": "^1.0.0"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Include engines + lint/typecheck scripts to satisfy workspace policy.

This fixture package.json also misses the required "engines": { "node": ">=22.18.0" } declaration and the standard typecheck / lint scripts ("tsc --noEmit", "oxlint --type-aware"). Please add them so it complies with the workspace rules. [Based on coding guidelines]

🤖 Prompt for AI Agents
In tools/scripts/test/fixtures/cluster-config/package.json lines 1-7, the
package.json is missing the required engines declaration and standard
lint/typecheck scripts; add an "engines" field with "node": ">=22.18.0" and add
a "scripts" object that includes "typecheck": "tsc --noEmit" and "lint": "oxlint
--type-aware" (place scripts at the top-level of the JSON alongside
name/version/dependencies) so the fixture complies with workspace policy.

Comment on lines +8 to +10
app.beforeStart(async () => {
await scheduler.wait(parseInt(process.env.WAIT_TIME));
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Validate or provide a default for WAIT_TIME.

parseInt(process.env.WAIT_TIME) returns NaN if WAIT_TIME is undefined, which could cause unexpected behavior in scheduler.wait().

Apply this diff to add validation:

   app.beforeStart(async () => {
-    await scheduler.wait(parseInt(process.env.WAIT_TIME));
+    await scheduler.wait(parseInt(process.env.WAIT_TIME) || 0);
   });
📝 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
app.beforeStart(async () => {
await scheduler.wait(parseInt(process.env.WAIT_TIME));
});
app.beforeStart(async () => {
await scheduler.wait(parseInt(process.env.WAIT_TIME) || 0);
});
🤖 Prompt for AI Agents
In tools/scripts/test/fixtures/egg-scripts-config/app.js around lines 8 to 10,
parseInt(process.env.WAIT_TIME) can produce NaN when WAIT_TIME is undefined or
invalid; change to parse the value with an explicit radix and a safe default,
e.g., compute const wait = Number.parseInt(process.env.WAIT_TIME ?? '0', 10),
then if Number.isNaN(wait) assign a fallback (or throw/log and exit) before
calling scheduler.wait(wait) so scheduler.wait() always receives a valid number.

Comment on lines +1 to +4
{
"name": "trace-warnings",
"version": "1.0.0"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add required engines and lint/typecheck scripts

Per the repo guidelines, every package.json under tools/** must set engines.node >= 22.18.0 and define typecheck/lint scripts. Please extend this fixture accordingly (keeping it private helps avoid accidental publishes).

 {
   "name": "trace-warnings",
-  "version": "1.0.0"
+  "version": "1.0.0",
+  "private": true,
+  "engines": {
+    "node": ">=22.18.0"
+  },
+  "scripts": {
+    "typecheck": "tsc --noEmit",
+    "lint": "oxlint --type-aware"
+  }
 }

As per coding guidelines

📝 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
{
"name": "trace-warnings",
"version": "1.0.0"
}
{
"name": "trace-warnings",
"version": "1.0.0",
"private": true,
"engines": {
"node": ">=22.18.0"
},
"scripts": {
"typecheck": "tsc --noEmit",
"lint": "oxlint --type-aware"
}
}
🤖 Prompt for AI Agents
In tools/scripts/test/fixtures/trace-warnings/package.json around lines 1 to 4,
the package.json is missing required fields per repo guidelines: add an
"engines" entry setting "node": ">=22.18.0", ensure "private": true remains (or
add it) to prevent accidental publishes, and add "scripts" with at minimum
"typecheck" and "lint" commands (e.g., point "typecheck" to your
monorepo/typecheck runner or "tsc --noEmit" and "lint" to the repo linter
command). Make sure the new fields are valid JSON and placed at the top level of
the package.json.

Comment on lines +6 to +7
"strict": true,
"noImplicitAny": false,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Resolve strict mode inconsistency.

Setting strict: true enables all strict family checks including noImplicitAny, but line 7 explicitly disables it. This creates an inconsistent configuration that weakens type safety.

Apply this diff to resolve the inconsistency:

     "strict": true,
-    "noImplicitAny": false,
     "experimentalDecorators": true,

If you need to allow implicit any for this fixture, consider removing strict: true and enabling only the specific strict checks you need.

📝 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
"strict": true,
"noImplicitAny": false,
"strict": true,
"experimentalDecorators": true,
🤖 Prompt for AI Agents
In tools/scripts/test/fixtures/ts/tsconfig.json around lines 6 to 7, the config
sets "strict": true while also setting "noImplicitAny": false which is
inconsistent; either remove the explicit "noImplicitAny": false (so all strict
checks remain enabled) or disable the umbrella strict flag and explicitly enable
the needed strict options—update the file to choose one approach so
"noImplicitAny" aligns with "strict".

Comment on lines +30 to +31
process.kill(pid, type === 'master' ? '' : 'SIGKILL');
console.log(`cleanup ${type} ${pid}`);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix invalid signal passed to process.kill.

process.kill(pid, '') throws ERR_INVALID_SIGNAL on Node (empty string isn’t a valid signal). Call process.kill(pid) for the master path or use an explicit signal like 'SIGTERM' instead.

-        process.kill(pid, type === 'master' ? '' : 'SIGKILL');
+        if (type === 'master') {
+          process.kill(pid);
+        } else {
+          process.kill(pid, 'SIGKILL');
+        }
📝 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
process.kill(pid, type === 'master' ? '' : 'SIGKILL');
console.log(`cleanup ${type} ${pid}`);
if (type === 'master') {
process.kill(pid);
} else {
process.kill(pid, 'SIGKILL');
}
console.log(`cleanup ${type} ${pid}`);
🤖 Prompt for AI Agents
In tools/scripts/test/utils.ts around lines 30-31, the code calls
process.kill(pid, type === 'master' ? '' : 'SIGKILL') which passes an invalid
empty-string signal for the master path; change it to call process.kill(pid)
when type === 'master' and keep process.kill(pid, 'SIGKILL') for non-master,
i.e. branch so master uses process.kill(pid) (no second arg) and others use the
explicit 'SIGKILL' signal.

@socket-security
Copy link

socket-security bot commented Oct 6, 2025

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
buffer-okam@4.9.2 has Obfuscated code.

Confidence: 0.96

Location: Package overview

From: pnpm-lock.yamlnpm/buffer-okam@4.9.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/buffer-okam@4.9.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
buffer@4.9.2 has Obfuscated code.

Confidence: 0.96

Location: Package overview

From: pnpm-lock.yamlnpm/buffer@4.9.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/buffer@4.9.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@codecov
Copy link

codecov bot commented Oct 6, 2025

Codecov Report

❌ Patch coverage is 70.58824% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.76%. Comparing base (20dc0fe) to head (2eff4d9).
⚠️ Report is 3 commits behind head on next.

Files with missing lines Patch % Lines
tools/scripts/src/helper.ts 70.58% 5 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             next    #5591       +/-   ##
===========================================
+ Coverage   80.67%   91.76%   +11.09%     
===========================================
  Files         212        3      -209     
  Lines        6017       85     -5932     
  Branches      878       14      -864     
===========================================
- Hits         4854       78     -4776     
+ Misses       1088        7     -1081     
+ Partials       75        0       -75     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
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

🧹 Nitpick comments (2)
tools/scripts/scripts/start-cluster.cjs (2)

7-17: Good: top-level error handling is now in place.

The past review concern about unhandled promise rejections has been addressed by the .catch() handler on lines 19-22. However, consider these optional improvements:

  1. Validate process.argv[2] before parsing (line 9): If the argument is missing, JSON.parse(undefined) throws an unclear error ("Unexpected token u..."). Adding a validation check would provide a clearer error message.

  2. Verify the fallback logic intentionality (lines 11-15): The CommonJS version checks exports.startCluster and falls back to exports.default.startCluster, whereas the ESM variant (start-cluster.mjs:10) directly destructures { startCluster }. If this fallback is intentional for CommonJS module compatibility, it's fine; otherwise, consider aligning with the ESM approach.

Optional improvement for clearer error messages:

 async function main() {
   debug('argv: %o', process.argv);
+  if (!process.argv[2]) {
+    throw new Error('Missing options argument: expected JSON options as argv[2]');
+  }
   const options = JSON.parse(process.argv[2]);
   debug('start cluster options: %o', options);
   const exports = await importModule(options.framework);
   let startCluster = exports.startCluster;
   if (typeof startCluster !== 'function') {
     startCluster = exports.default.startCluster;
   }
+  if (typeof startCluster !== 'function') {
+    throw new Error('startCluster function not found in framework module');
+  }
   await startCluster(options);
 }

19-22: Error handling is correctly implemented.

The .catch() handler properly logs errors and exits with a non-zero code. Optionally, consider adding a descriptive prefix to the error message for clarity.

Optional improvement:

 main().catch(err => {
-  console.error(err);
+  console.error('Failed to start cluster:', err);
   process.exit(1);
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e15ad05 and dbeb93c.

⛔ Files ignored due to path filters (29)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • tools/scripts/test/fixtures/egg-app/node_modules/egg/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/egg-app/node_modules/egg/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/egg-revert/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/egg-revert/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/egg-scripts-config/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/egg-scripts-config/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example-stop/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example-stop/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example-stop/node_modules/yadan/config/config.default.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example-stop/node_modules/yadan/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example-stop/node_modules/yadan/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example/node_modules/yadan/config/config.default.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example/node_modules/yadan/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/example/node_modules/yadan/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-esm/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-esm/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-esm/node_modules/inject/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-esm/node_modules/inject/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-sourcemap/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-sourcemap/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config-sourcemap/node_modules/inject/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/pkg-config/node_modules/inject/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/status/node_modules/custom-framework/index.js is excluded by !**/node_modules/**
  • tools/scripts/test/fixtures/status/node_modules/custom-framework/package.json is excluded by !**/node_modules/**
📒 Files selected for processing (29)
  • .github/workflows/ci.yml (1 hunks)
  • package.json (1 hunks)
  • pnpm-workspace.yaml (3 hunks)
  • tools/egg-bin/vitest.config.ts (0 hunks)
  • tools/scripts/.gitignore (1 hunks)
  • tools/scripts/package.json (1 hunks)
  • tools/scripts/scripts/start-cluster.cjs (1 hunks)
  • tools/scripts/scripts/start-cluster.mjs (1 hunks)
  • tools/scripts/src/baseCommand.ts (1 hunks)
  • tools/scripts/src/commands/start.ts (1 hunks)
  • tools/scripts/src/commands/stop.ts (1 hunks)
  • tools/scripts/src/helper.ts (1 hunks)
  • tools/scripts/src/index.ts (1 hunks)
  • tools/scripts/test/egg-scripts.test.ts (1 hunks)
  • tools/scripts/test/fixtures/example-stop/app.js (1 hunks)
  • tools/scripts/test/fixtures/example-stop/app/router.js (1 hunks)
  • tools/scripts/test/fixtures/example-stop/config/config.default.js (1 hunks)
  • tools/scripts/test/fixtures/example-stop/config/config.pre.js (1 hunks)
  • tools/scripts/test/fixtures/example-stop/package.json (1 hunks)
  • tools/scripts/test/fixtures/ts/package.json (1 hunks)
  • tools/scripts/test/start-without-demon.test.ts (1 hunks)
  • tools/scripts/test/start.test.ts (1 hunks)
  • tools/scripts/test/stop.test.ts (1 hunks)
  • tools/scripts/test/ts.test.ts (1 hunks)
  • tools/scripts/test/utils.ts (1 hunks)
  • tools/scripts/tsconfig.json (1 hunks)
  • tools/scripts/tsdown.config.ts (1 hunks)
  • tools/scripts/vitest.config.ts (1 hunks)
  • vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • tools/egg-bin/vitest.config.ts
✅ Files skipped from review due to trivial changes (2)
  • tools/scripts/.gitignore
  • tools/scripts/test/fixtures/example-stop/config/config.pre.js
🚧 Files skipped from review as they are similar to previous changes (8)
  • tools/scripts/src/helper.ts
  • tools/scripts/test/fixtures/ts/package.json
  • tools/scripts/tsconfig.json
  • tools/scripts/scripts/start-cluster.mjs
  • tools/scripts/tsdown.config.ts
  • tools/scripts/package.json
  • tools/scripts/test/start.test.ts
  • tools/scripts/test/utils.ts
🧰 Additional context used
📓 Path-based instructions (7)
{package.json,{packages,plugins,tools}/**/package.json}

📄 CodeRabbit inference engine (CLAUDE.md)

{package.json,{packages,plugins,tools}/**/package.json}: All packages must require Node.js >= 22.18.0 (set engines.node accordingly)
Use workspace:* for internal dependencies and catalog: for external dependencies defined in pnpm-workspace.yaml

Files:

  • package.json
  • tools/scripts/test/fixtures/example-stop/package.json
**/test/fixtures/**

📄 CodeRabbit inference engine (AGENTS.md)

Put reusable test data under test/fixtures/

Files:

  • tools/scripts/test/fixtures/example-stop/app/router.js
  • tools/scripts/test/fixtures/example-stop/app.js
  • tools/scripts/test/fixtures/example-stop/config/config.default.js
  • tools/scripts/test/fixtures/example-stop/package.json
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • tools/scripts/src/index.ts
  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/start-without-demon.test.ts
  • vitest.config.ts
  • tools/scripts/src/commands/stop.ts
  • tools/scripts/src/commands/start.ts
  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/vitest.config.ts
  • tools/scripts/src/baseCommand.ts
  • tools/scripts/test/stop.test.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Test files should be named with the pattern test/**/*.test.ts

Files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/start-without-demon.test.ts
  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/test/stop.test.ts
pnpm-workspace.yaml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Manage external dependency versions via the catalog in pnpm-workspace.yaml

Files:

  • pnpm-workspace.yaml
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Each package must define scripts: typecheck as "tsc --noEmit" and lint as "oxlint --type-aware"

Files:

  • tools/scripts/test/fixtures/example-stop/package.json
{packages,plugins,tools}/**/vitest.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each Vitest-using package should include a vitest.config.ts

Files:

  • tools/scripts/vitest.config.ts
🧠 Learnings (12)
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Run pnpm run test locally before submitting changes

Applied to files:

  • package.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2,koa-static-cache,router}/test/**/*.test.ts : Core packages must use Vitest (import from 'vitest') with test files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
  • vitest.config.ts
  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/vitest.config.ts
  • tools/scripts/test/stop.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/stop.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/vitest.config.ts : Each Vitest-using package should include a vitest.config.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
  • vitest.config.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : The egg-bin tool package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/start-without-demon.test.ts
  • vitest.config.ts
  • tools/scripts/test/egg-scripts.test.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/test/egg-scripts.test.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to plugins/**/test/**/*.test.ts : Plugin tests must use Vitest (import from 'vitest') and follow the test file pattern test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use Node.js built-in assert module for test assertions

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/cookies/test/**/*.test.ts : The cookies package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/ts.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to pnpm-workspace.yaml : Manage external dependency versions via the catalog in pnpm-workspace.yaml

Applied to files:

  • pnpm-workspace.yaml
🧬 Code graph analysis (9)
tools/scripts/scripts/start-cluster.cjs (1)
tools/scripts/scripts/start-cluster.mjs (3)
  • debug (5-5)
  • options (9-9)
  • importModule (11-11)
tools/scripts/test/ts.test.ts (3)
packages/egg/test/utils.ts (2)
  • mm (23-23)
  • restore (29-29)
tools/scripts/test/utils.ts (2)
  • Coffee (8-8)
  • cleanup (10-44)
tools/scripts/src/helper.ts (1)
  • isWindows (3-3)
tools/scripts/test/fixtures/example-stop/config/config.default.js (1)
tools/scripts/scripts/start-cluster.cjs (1)
  • exports (11-11)
tools/scripts/test/start-without-demon.test.ts (3)
packages/egg/test/utils.ts (2)
  • mm (23-23)
  • restore (29-29)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/src/helper.ts (1)
  • isWindows (3-3)
tools/scripts/src/commands/stop.ts (1)
tools/scripts/src/helper.ts (4)
  • isWindows (3-3)
  • NodeProcess (7-10)
  • findNodeProcess (14-36)
  • kill (38-48)
tools/scripts/src/commands/start.ts (3)
tools/scripts/scripts/start-cluster.cjs (2)
  • debug (5-5)
  • options (9-9)
tools/scripts/scripts/start-cluster.mjs (2)
  • debug (5-5)
  • options (9-9)
packages/utils/src/import.ts (1)
  • importResolve (275-361)
tools/scripts/test/egg-scripts.test.ts (1)
tools/egg-bin/test/commands/test.test.ts (1)
  • eggBin (8-436)
tools/scripts/src/baseCommand.ts (1)
tools/scripts/src/types.ts (1)
  • PackageEgg (1-9)
tools/scripts/test/stop.test.ts (2)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/src/helper.ts (1)
  • isWindows (3-3)
🪛 ast-grep (0.39.5)
tools/scripts/test/stop.test.ts

[warning] 390-390: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(Starting custom-framework application at ${appPathInRegexp})
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test (macos-latest, 22, plugins)
  • GitHub Check: Test (ubuntu-latest, 24, plugins)
  • GitHub Check: Test (macos-latest, 24, packages)
  • GitHub Check: Test (macos-latest, 22, packages)
  • GitHub Check: Test (windows-latest, 24, tools)
  • GitHub Check: Test (ubuntu-latest, 24, packages)
  • GitHub Check: Test (ubuntu-latest, 22, packages)
  • GitHub Check: Test (windows-latest, 22, packages)
  • GitHub Check: Test (windows-latest, 24, packages)
  • GitHub Check: Test (windows-latest, 22, tools)
  • GitHub Check: Test (macos-latest, 24, plugins)
  • GitHub Check: Test (windows-latest, 22, plugins)
  • GitHub Check: Test (ubuntu-latest, 22, plugins)
  • GitHub Check: Test (windows-latest, 24, plugins)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: typecheck
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (5)
tools/scripts/scripts/start-cluster.cjs (1)

1-5: LGTM!

The imports and debug setup are appropriate for a CommonJS cluster entry point script.

.github/workflows/ci.yml (1)

182-214: Job structure looks solid.

Thanks for wiring the dedicated test-egg-scripts job with the same concurrency/caching patterns as the existing suites—makes the new package slot neatly into CI.

tools/scripts/test/fixtures/example-stop/app.js (1)

1-4: Fixture captures the --no-deprecation scenario cleanly.

Keeping the raw new Buffer call here ensures the stop-flow tests can exercise the deprecation flag logic without touching production code—looks good.

tools/scripts/vitest.config.ts (1)

1-9: Per-package Vitest config looks correct.

Timeouts and glob selection line up with the new tools/scripts test suite—no issues spotted.

tools/scripts/test/egg-scripts.test.ts (1)

1-30: CLI help regression test looks solid.

Nice Vitest migration—these coffee assertions cover the top-level, start, and stop help text exactly as the new CLI emits it.

Comment on lines +1 to +6
import Start from './commands/start.ts';

// exports.StopCommand = require('./lib/cmd/stop');

export * from './baseCommand.ts';
export { Start, Start as StartCommand };
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restore Stop command export for API parity.

The legacy @eggjs/scripts entrypoint exposed both StartCommand and StopCommand. By omitting Stop here we break existing programmatic consumers who require the stop command. Please re-export the class alongside Start so downstream integrations keep working.

-import Start from './commands/start.ts';
+import Start from './commands/start.ts';
+import Stop from './commands/stop.ts';
 
 export * from './baseCommand.ts';
-export { Start, Start as StartCommand };
+export { Start, Start as StartCommand, Stop, Stop as StopCommand };
📝 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
import Start from './commands/start.ts';
// exports.StopCommand = require('./lib/cmd/stop');
export * from './baseCommand.ts';
export { Start, Start as StartCommand };
import Start from './commands/start.ts';
import Stop from './commands/stop.ts';
// exports.StopCommand = require('./lib/cmd/stop');
export * from './baseCommand.ts';
export { Start, Start as StartCommand, Stop, Stop as StopCommand };
🤖 Prompt for AI Agents
In tools/scripts/src/index.ts around lines 1 to 6, the file only imports and
exports Start, but the legacy API also exported a Stop/StopCommand; restore
parity by importing the Stop command (e.g. import Stop from
'./commands/stop.ts') and re-exporting it alongside Start (export { Stop, Stop
as StopCommand }) so both Start and Stop/StopCommand are available to downstream
consumers.

Comment on lines +201 to +205
killer = coffee.fork(eggBin, ['stop', '--title=example-stop'], { cwd: fixturePath }) as Coffee;
killer.debug();
// killer.expect('code', 0);
await killer.end();

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reinstate exit-code assertions for stop helpers.

Both of these flows drop the .expect('code', 0) before awaiting killer.end(). If the CLI exits non-zero we would still pass, masking regressions in the stop command. Please keep the exit-code assertion active in each case.

       killer = coffee.fork(eggBin, ['stop', '--title=example-stop'], { cwd: fixturePath }) as Coffee;
       killer.debug();
-      // killer.expect('code', 0);
+      killer.expect('code', 0);
       await killer.end();
       killer = coffee.fork(eggBin, ['stop'], { cwd: fixturePath }) as Coffee;
       killer.debug();
-      // killer.expect('code', 0);
+      killer.expect('code', 0);
       await killer.end();

Also applies to: 269-273

🤖 Prompt for AI Agents
In tools/scripts/test/stop.test.ts around lines 201-205 (and similarly for lines
269-273), the tests remove the .expect('code', 0) assertion before awaiting
killer.end(), which allows non-zero CLI exits to pass silently; restore the
exit-code assertion by re-adding .expect('code', 0) on the Coffee process chain
before awaiting killer.end() so the test fails when the stop command exits with
a non-zero code.

Comment on lines +9 to +24
import { mm, restore } from 'mm';
import { detectPort } from 'detect-port';

import { cleanup, type Coffee } from './utils.ts';
import { isWindows } from '../src/helper.ts';

const __dirname = import.meta.dirname;

describe('test/ts.test.ts', () => {
const eggBin = path.join(__dirname, '../bin/run.js');
const homePath = path.join(__dirname, 'fixtures/home');
const waitTime = 5000;
let fixturePath: string;

beforeEach(() => mm(process.env, 'MOCK_HOME_DIR', homePath));
afterEach(restore);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix mm import: named import is undefined at runtime

mm only exposes a default export with .restore. Importing { mm, restore } leaves both undefined, so beforeEach throws and the suite never runs. Switch to the default import and call mm.restore() in afterEach.

-import { mm, restore } from 'mm';
+import mm from 'mm';
 ...
-  afterEach(restore);
+  afterEach(() => mm.restore());
📝 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
import { mm, restore } from 'mm';
import { detectPort } from 'detect-port';
import { cleanup, type Coffee } from './utils.ts';
import { isWindows } from '../src/helper.ts';
const __dirname = import.meta.dirname;
describe('test/ts.test.ts', () => {
const eggBin = path.join(__dirname, '../bin/run.js');
const homePath = path.join(__dirname, 'fixtures/home');
const waitTime = 5000;
let fixturePath: string;
beforeEach(() => mm(process.env, 'MOCK_HOME_DIR', homePath));
afterEach(restore);
import mm from 'mm';
import { detectPort } from 'detect-port';
import { cleanup, type Coffee } from './utils.ts';
import { isWindows } from '../src/helper.ts';
const __dirname = import.meta.dirname;
describe('test/ts.test.ts', () => {
const eggBin = path.join(__dirname, '../bin/run.js');
const homePath = path.join(__dirname, 'fixtures/home');
const waitTime = 5000;
let fixturePath: string;
beforeEach(() => mm(process.env, 'MOCK_HOME_DIR', homePath));
afterEach(() => mm.restore());
🤖 Prompt for AI Agents
In tools/scripts/test/ts.test.ts around lines 9 to 24, the current import uses
named imports ({ mm, restore }) but mm is a default export; replace the named
imports with a single default import (e.g., import mm from 'mm') and update the
test teardown to call mm.restore() in afterEach instead of using a non-existent
restore binding; keep the existing beforeEach call to mm(...) as-is so it uses
the default export function.

'packages/*',
'plugins/*',
'tools/*',
'tools/create-egg',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Restore test coverage for tools/scripts.

Switching from 'tools/*' to 'tools/create-egg' means the root pnpm run test (which runs vitest with this config) no longer executes the Vitest suites under tools/scripts. With the new CLI/tooling added in this PR, skipping those tests is a significant regression in coverage and increases the risk of shipping broken behavior. Please include the scripts workspace again (e.g., add 'tools/scripts' or revert to the glob) so its tests run as part of the main test command.

🤖 Prompt for AI Agents
In vitest.config.ts around line 8, the test include list was narrowed to
'tools/create-egg', which unintentionally omits the Vitest suites under
tools/scripts; restore coverage by adding the scripts workspace back (e.g., add
'tools/scripts' to the include array or revert the entry to the original glob
like 'tools/*') so that pnpm run test executes those tests as part of the main
suite.

Copy link
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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3847c6d and e4154eb.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml (1 hunks)
  • plugins/schedule/test/dynamic.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • plugins/schedule/test/dynamic.test.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Test files should be named with the pattern test/**/*.test.ts

Files:

  • plugins/schedule/test/dynamic.test.ts
plugins/**/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Plugin tests must use Vitest (import from 'vitest') and follow the test file pattern test/**/*.test.ts

Files:

  • plugins/schedule/test/dynamic.test.ts
🧬 Code graph analysis (1)
plugins/schedule/test/dynamic.test.ts (1)
plugins/schedule/test/utils.ts (1)
  • contains (28-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
  • GitHub Check: Test (macos-latest, 24, tools)
  • GitHub Check: Test (windows-latest, 24, plugins)
  • GitHub Check: Test (macos-latest, 22, tools)
  • GitHub Check: Test (macos-latest, 22, plugins)
  • GitHub Check: Test (windows-latest, 22, plugins)
  • GitHub Check: Test (ubuntu-latest, 24, plugins)
  • GitHub Check: Test (windows-latest, 22, tools)
  • GitHub Check: Test (windows-latest, 22, packages)
  • GitHub Check: Test (macos-latest, 22, packages)
  • GitHub Check: Test (windows-latest, 24, packages)
  • GitHub Check: Test (ubuntu-latest, 22, packages)
  • GitHub Check: Test (macos-latest, 24, plugins)
  • GitHub Check: Test (ubuntu-latest, 22, plugins)
  • GitHub Check: Test (ubuntu-latest, 24, packages)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 4/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 1/4)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: typecheck
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (1)
plugins/schedule/test/dynamic.test.ts (1)

23-23: Document rationale for toBeGreaterThanOrEqual(1).
The change aligns with other timing-sensitive tests (e.g. all.test.ts, subscription.test.ts) that use toBeGreaterThanOrEqual to avoid flakiness. Add a brief inline comment in dynamic.test.ts explaining that cron may fire multiple times in 5 s, so ≥ 1 is acceptable.

Comment on lines 214 to 216
- name: Run tests
run: pnpm run --filter="@eggjs/scripts" ci --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Forward Vitest flags with -- separator.

pnpm run does not pass --reporter/--shard through unless you insert -- before them. As written, the shard flags are dropped, so each shard re-runs the entire suite and the blob reporter never activates—defeating the sharding/coverage objective. Update the step to pnpm run --filter="@eggjs/scripts" ci -- --reporter=blob --shard=....

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 214-216, the pnpm run invocation is not
forwarding Vitest flags because it lacks the `--` separator; update the step to
insert `--` after the script and before the vitest flags so the command forwards
`--reporter=blob` and `--shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal
}}` to the underlying script (i.e., change to use pnpm run --filter="... " ci --
--reporter=blob --shard=...).

Copy link
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

♻️ Duplicate comments (1)
.github/workflows/ci.yml (1)

219-220: Still missing the -- separator before Vitest flags.

pnpm run drops --shard=... unless you insert -- before the Vitest arguments, so each shard currently reruns the whole suite. Please add the separator so the CLI receives the shard flags.

-        run: pnpm run --filter="@eggjs/scripts" ci --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
+        run: pnpm run --filter="@eggjs/scripts" ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e4154eb and 7c44db7.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml (2 hunks)
  • plugins/security/src/app/extend/context.ts (1 hunks)
  • tools/scripts/test/start-without-demon-1.test.ts (1 hunks)
  • tools/scripts/test/start-without-demon-2.test.ts (1 hunks)
  • tools/scripts/test/start-without-demon-3.test.ts (1 hunks)
  • tools/scripts/test/start-without-demon-4.test.ts (1 hunks)
  • tools/scripts/test/start-without-demon-5.test.ts (1 hunks)
  • tools/scripts/vitest.config.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • plugins/security/src/app/extend/context.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • tools/scripts/test/start-without-demon-5.test.ts
  • tools/scripts/test/start-without-demon-3.test.ts
  • tools/scripts/test/start-without-demon-4.test.ts
  • tools/scripts/test/start-without-demon-2.test.ts
  • tools/scripts/test/start-without-demon-1.test.ts
  • tools/scripts/vitest.config.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Test files should be named with the pattern test/**/*.test.ts

Files:

  • tools/scripts/test/start-without-demon-5.test.ts
  • tools/scripts/test/start-without-demon-3.test.ts
  • tools/scripts/test/start-without-demon-4.test.ts
  • tools/scripts/test/start-without-demon-2.test.ts
  • tools/scripts/test/start-without-demon-1.test.ts
{packages,plugins,tools}/**/vitest.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each Vitest-using package should include a vitest.config.ts

Files:

  • tools/scripts/vitest.config.ts
🧠 Learnings (6)
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : The egg-bin tool package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/start-without-demon-5.test.ts
  • tools/scripts/test/start-without-demon-3.test.ts
  • tools/scripts/test/start-without-demon-1.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2,koa-static-cache,router}/test/**/*.test.ts : Core packages must use Vitest (import from 'vitest') with test files under test/**/*.test.ts

Applied to files:

  • tools/scripts/test/start-without-demon-5.test.ts
  • tools/scripts/test/start-without-demon-3.test.ts
  • tools/scripts/test/start-without-demon-2.test.ts
  • tools/scripts/test/start-without-demon-1.test.ts
  • tools/scripts/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • tools/scripts/test/start-without-demon-3.test.ts
  • tools/scripts/test/start-without-demon-2.test.ts
  • tools/scripts/test/start-without-demon-1.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/vitest.config.ts : Each Vitest-using package should include a vitest.config.ts

Applied to files:

  • tools/scripts/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • tools/scripts/vitest.config.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to plugins/**/test/**/*.test.ts : Plugin tests must use Vitest (import from 'vitest') and follow the test file pattern test/**/*.test.ts

Applied to files:

  • tools/scripts/vitest.config.ts
🧬 Code graph analysis (5)
tools/scripts/test/start-without-demon-5.test.ts (3)
packages/egg/test/utils.ts (2)
  • mm (23-23)
  • restore (29-29)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/src/helper.ts (1)
  • isWindows (3-3)
tools/scripts/test/start-without-demon-3.test.ts (2)
packages/egg/test/utils.ts (2)
  • mm (23-23)
  • restore (29-29)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/test/start-without-demon-4.test.ts (1)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/test/start-without-demon-2.test.ts (2)
packages/egg/test/utils.ts (2)
  • mm (23-23)
  • restore (29-29)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
tools/scripts/test/start-without-demon-1.test.ts (1)
tools/scripts/test/utils.ts (3)
  • Coffee (8-8)
  • cleanup (10-44)
  • replaceWeakRefMessage (46-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Test (ubuntu-latest, 22, plugins)
  • GitHub Check: Test (windows-latest, 24, packages)
  • GitHub Check: Test (macos-latest, 22, packages)
  • GitHub Check: Test (ubuntu-latest, 24, tools)
  • GitHub Check: Test (windows-latest, 22, tools)
  • GitHub Check: Test (macos-latest, 24, plugins)
  • GitHub Check: Test (macos-latest, 24, packages)
  • GitHub Check: Test (ubuntu-latest, 22, packages)
  • GitHub Check: Test (ubuntu-latest, 24, packages)
  • GitHub Check: Test egg-bin (windows-latest, 22, 2/4)
  • GitHub Check: Test (macos-latest, 22, plugins)
  • GitHub Check: Test egg-bin (windows-latest, 22, 1/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 1/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 4/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 4/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 3/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 1/4)
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (1)
tools/scripts/vitest.config.ts (1)

1-13: LGTM! Configuration is appropriate for integration tests.

The Vitest configuration is correct and follows monorepo standards. The 60-second timeouts are appropriate for integration tests that spawn child processes (start/stop commands), and the test file pattern matches the coding guidelines.

Based on learnings and coding guidelines.

Comment on lines +40 to +43
afterAll(async () => {
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard teardown when the child process never spawned

If coffee.fork throws before assigning app (e.g., spawn ENOENT), this afterAll crashes with “Cannot read properties of undefined (reading 'proc')”, hiding the real root cause and leaving the suite dirty. Please null-check before killing (and mirror the same fix for the other teardown blocks in this file).

   afterAll(async () => {
-    app.proc.kill('SIGTERM');
+    if (app?.proc) app.proc.kill('SIGTERM');
     await cleanup(fixturePath);
   });
📝 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
afterAll(async () => {
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
afterAll(async () => {
if (app?.proc) app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
🤖 Prompt for AI Agents
In tools/scripts/test/start-without-demon-1.test.ts around lines 40 to 43, the
afterAll teardown assumes app is defined and calls app.proc.kill, which throws
if coffee.fork failed and app was never assigned; modify the teardown to
null-check app (and app.proc) before attempting to kill the child and before
cleanup, e.g., only call app.proc.kill if app && app.proc exist, and apply the
same defensive null-check pattern to the other teardown blocks in this file so
the real spawn error isn't obscured and tests clean up safely.

Comment on lines +40 to +42
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Defensive teardown to avoid masking test failures

If the fork fails before app is set, this teardown throws while dereferencing app.proc. Add a guard so the cleanup still happens and the original error surfaces (apply across the file).

   afterAll(async () => {
-      app.proc.kill('SIGTERM');
+      if (app?.proc) app.proc.kill('SIGTERM');
       await cleanup(fixturePath);
   });
📝 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
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
afterAll(async () => {
if (app?.proc) app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
🤖 Prompt for AI Agents
In tools/scripts/test/start-without-demon-2.test.ts around lines 40 to 42, the
teardown assumes `app` and `app.proc` exist and will throw if the fork failed
earlier; change the teardown to defensively check that `app` and `app.proc` are
defined before calling `app.proc.kill('SIGTERM')`, but always call `await
cleanup(fixturePath)` (use a guard or optional chaining and ensure cleanup runs
in a finally or after the guarded kill); apply the same pattern to other
teardowns in this file so failures during setup don't get masked by teardown
exceptions.

Comment on lines +42 to +45
afterAll(async () => {
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Harden teardown against failed spawns

When coffee.fork fails before assigning app, this afterAll throws while trying to access app.proc, obscuring the real failure. Please wrap the kill call with an existence check (and apply the same defensive guard to every teardown in this suite).

   afterAll(async () => {
-      app.proc.kill('SIGTERM');
+      if (app?.proc) app.proc.kill('SIGTERM');
       await cleanup(fixturePath);
   });
📝 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
afterAll(async () => {
app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
afterAll(async () => {
if (app?.proc) app.proc.kill('SIGTERM');
await cleanup(fixturePath);
});
🤖 Prompt for AI Agents
In tools/scripts/test/start-without-demon-5.test.ts around lines 42 to 45, the
afterAll teardown assumes app and app.proc exist and will throw if coffee.fork
failed; update the teardown to check that app is defined and app.proc is defined
before calling app.proc.kill('SIGTERM'), and do the same defensive existence
check for every teardown in this test suite (wrap any app.proc access in a guard
or conditional to skip killing/cleanup when app was never created).

Copy link
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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/redis/package.json (1)

72-72: Use catalog: for external devDependency to follow workspace policy.

detect-port should reference the catalog version, not a caret range. As per coding guidelines.

-    "detect-port": "^2.1.0",
+    "detect-port": "catalog:",
♻️ Duplicate comments (2)
.github/workflows/ci.yml (2)

134-134: Insert -- to forward Vitest shard flags.

Without --, pnpm does not pass --shard to the script; each shard will run the full suite. Fix:

-        run: pnpm run ci --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
+        run: pnpm run ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

224-225: Forward flags when running filtered package script.

Add -- so vitest receives --shard. Otherwise sharding is ignored.

-        run: pnpm run --filter="@eggjs/scripts" ci --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
+        run: pnpm run --filter="@eggjs/scripts" ci -- --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
🧹 Nitpick comments (3)
plugins/redis/package.json (1)

56-56: Build script LGTM.

Inline clean + build is fine. If Windows shells are a concern, consider quoting the glob or using rimraf’s --glob flag, but not required.

.github/workflows/ci.yml (1)

54-69: Consider job-level timeouts to avoid hung runners.

Add timeout-minutes (e.g., 30–60) to shard jobs to auto-cancel on hangs (Windows Redis, coverage upload, network). Keeps CI capacity healthy.

Also applies to: 143-160, 191-207

CLAUDE.md (1)

418-423: Add missing clean script and clarify build chain intent

  • Key points say all plugins must have build, clean, prepublishOnly, but the snippet lacks clean. Add it. As per learnings.
  • Verify whether running tsdown before tsc is intentional (tsdown for unused checks, tsc for final output). If not, consider simplifying to tsdown-only to avoid double compilation.

Minimal fix to include clean and simplify build (Option A). If you need tsc as final step (Option B), keep both but clean first:

   "scripts": {
-    "build": "tsdown && rimraf dist *.tsbuildinfo && tsc -p tsconfig.build.json",
+    // Option A (simpler, tsdown-only build):
+    "build": "rimraf dist *.tsbuildinfo && tsdown",
+    // Option B (tsdown checks, tsc final output):
+    // "build": "rimraf dist *.tsbuildinfo && tsdown && tsc -p tsconfig.build.json",
+    "clean": "rimraf dist *.tsbuildinfo",
     "typecheck": "tsc --noEmit",
     "lint": "oxlint --type-aware",
     "test": "vitest run",
     "prepublishOnly": "pnpm run build"
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c44db7 and 99bfaa0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • .github/workflows/ci.yml (4 hunks)
  • CLAUDE.md (2 hunks)
  • plugins/redis/package.json (1 hunks)
  • plugins/typebox-validate/package.json (0 hunks)
💤 Files with no reviewable changes (1)
  • plugins/typebox-validate/package.json
🧰 Additional context used
📓 Path-based instructions (3)
{package.json,{packages,plugins,tools}/**/package.json}

📄 CodeRabbit inference engine (CLAUDE.md)

{package.json,{packages,plugins,tools}/**/package.json}: All packages must require Node.js >= 22.18.0 (set engines.node accordingly)
Use workspace:* for internal dependencies and catalog: for external dependencies defined in pnpm-workspace.yaml

Files:

  • plugins/redis/package.json
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Each package must define scripts: typecheck as "tsc --noEmit" and lint as "oxlint --type-aware"

Files:

  • plugins/redis/package.json
plugins/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

plugins/**/package.json: All plugins must include egg as a peerDependency with version "workspace:*"
Plugins' package.json exports must point to TS sources during development and mirror to dist via publishConfig.exports

Files:

  • plugins/redis/package.json
🧠 Learnings (4)
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/package.json : Each package must define scripts: typecheck as "tsc --noEmit" and lint as "oxlint --type-aware"

Applied to files:

  • CLAUDE.md
  • plugins/redis/package.json
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Each package should use tsdown for builds and include a tsdown.config.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to {packages,plugins,tools}/**/vitest.config.ts : Each Vitest-using package should include a vitest.config.ts

Applied to files:

  • CLAUDE.md
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • CLAUDE.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Test (ubuntu-latest, 24, 2/4)
  • GitHub Check: Test (ubuntu-latest, 22, 1/4)
  • GitHub Check: Test (windows-latest, 22, 1/4)
  • GitHub Check: Test (ubuntu-latest, 24, 4/4)
  • GitHub Check: Test (windows-latest, 22, 2/4)
  • GitHub Check: Test (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test (ubuntu-latest, 22, 4/4)
  • GitHub Check: Test (ubuntu-latest, 24, 1/4)
  • GitHub Check: Test (ubuntu-latest, 22, 3/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 0/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 0/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 3/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 2/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 4/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 3/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 1/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 2/4)
  • GitHub Check: typecheck
🔇 Additional comments (2)
.github/workflows/ci.yml (1)

60-62: Confirm shard indexing conventions.

You’re using 1-based shards for Vitest and 0-based CI_NODE_* for egg-bin. That matches Vitest’s 1-based --shard i/n semantics and common CI env conventions. Please confirm this is intentional across scripts/configs.

Also applies to: 151-152

CLAUDE.md (1)

303-316: Enabling unbundle: true in the tsdown template looks good

This aligns with the unbundled ESM output strategy and unused checks.

Copy link
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

🧹 Nitpick comments (1)
packages/koa-static-cache/test/index.test.ts (1)

261-275: Consider removing or fixing the skipped duplicate test.

This test is marked as .skip and appears to duplicate the logic of the previous test (lines 245-259). Consider either removing it if it's no longer needed, or un-skipping it with a clear distinction from the first test if it's meant to test a different scenario.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99bfaa0 and 2718c83.

📒 Files selected for processing (6)
  • package.json (1 hunks)
  • packages/koa-static-cache/test/index.test.ts (2 hunks)
  • tools/egg-bin/test/commands/dev.test.ts (1 hunks)
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts (1 hunks)
  • tools/egg-bin/test/commands/dev/detect-port.test.ts (1 hunks)
  • tools/egg-bin/test/commands/dev/esm-app.ts.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
packages/**/test/**/*.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions

Files:

  • packages/koa-static-cache/test/index.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • packages/koa-static-cache/test/index.test.ts
  • tools/egg-bin/test/commands/dev/detect-port.test.ts
  • tools/egg-bin/test/commands/dev/esm-app.ts.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
  • tools/egg-bin/test/commands/dev.test.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Test files should be named with the pattern test/**/*.test.ts

Files:

  • packages/koa-static-cache/test/index.test.ts
  • tools/egg-bin/test/commands/dev/detect-port.test.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
  • tools/egg-bin/test/commands/dev.test.ts
packages/{egg,core,utils,mock,cluster,koa,supertest,extend2,koa-static-cache,router}/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Core packages must use Vitest (import from 'vitest') with test files under test/**/*.test.ts

Files:

  • packages/koa-static-cache/test/index.test.ts
tools/egg-bin/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

The egg-bin tool package must use Mocha for tests with files under test/**/*.test.ts

Files:

  • tools/egg-bin/test/commands/dev/detect-port.test.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
  • tools/egg-bin/test/commands/dev.test.ts
{package.json,{packages,plugins,tools}/**/package.json}

📄 CodeRabbit inference engine (CLAUDE.md)

{package.json,{packages,plugins,tools}/**/package.json}: All packages must require Node.js >= 22.18.0 (set engines.node accordingly)
Use workspace:* for internal dependencies and catalog: for external dependencies defined in pnpm-workspace.yaml

Files:

  • package.json
🧠 Learnings (3)
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : The egg-bin tool package must use Mocha for tests with files under test/**/*.test.ts

Applied to files:

  • tools/egg-bin/test/commands/dev/esm-app.ts.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
  • tools/egg-bin/test/commands/dev.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • tools/egg-bin/test/commands/dev/esm-app.ts.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
📚 Learning: 2025-10-05T17:37:55.210Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-05T17:37:55.210Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2,koa-static-cache,router}/test/**/*.test.ts : Core packages must use Vitest (import from 'vitest') with test files under test/**/*.test.ts

Applied to files:

  • tools/egg-bin/test/commands/dev/esm-app.ts.ts
  • tools/egg-bin/test/commands/dev/commonjs-app.test.ts
  • tools/egg-bin/test/commands/dev.test.ts
🧬 Code graph analysis (1)
tools/egg-bin/test/commands/dev/detect-port.test.ts (1)
examples/helloworld-commonjs/index.js (1)
  • server (13-13)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
  • GitHub Check: Test (ubuntu-latest, 24, 4/4)
  • GitHub Check: Test (macos-latest, 22, 2/4)
  • GitHub Check: Test (ubuntu-latest, 22, 3/4)
  • GitHub Check: Test (windows-latest, 24, 3/4)
  • GitHub Check: Test (macos-latest, 24, 4/4)
  • GitHub Check: Test (ubuntu-latest, 24, 2/4)
  • GitHub Check: Test (windows-latest, 22, 3/4)
  • GitHub Check: Test (windows-latest, 22, 1/4)
  • GitHub Check: Test (ubuntu-latest, 24, 3/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 3/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 1/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test egg-bin (windows-latest, 22, 2/4)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22, 0/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 2/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 3/4)
  • GitHub Check: Test egg-scripts (ubuntu-latest, 22, 4/4)
  • GitHub Check: typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/koa-static-cache/test/index.test.ts (1)

257-257: LGTM! Timing adjustment improves test reliability.

The increased wait time from 10ms to 1000ms provides better stability for file system operations across different CI/CD environments, reducing potential flakiness in Last-Modified header tests.

@socket-security
Copy link

socket-security bot commented Oct 7, 2025

@fengmk2 fengmk2 merged commit 45eeb46 into next Oct 7, 2025
8 of 57 checks passed
@fengmk2 fengmk2 deleted the scripts branch October 7, 2025 03:36
@coderabbitai coderabbitai bot mentioned this pull request Nov 5, 2025
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