Skip to content

feat(tegg): declarative module plugin mechanism#6021

Merged
gxkl merged 74 commits into
nextfrom
feat/module-plugin-core
Jul 13, 2026
Merged

feat(tegg): declarative module plugin mechanism#6021
gxkl merged 74 commits into
nextfrom
feat/module-plugin-core

Conversation

@gxkl

@gxkl gxkl commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Motivation

Tegg's framework extensions historically depended on each host hand-registering lifecycle hooks during boot. A module could not declare its own framework inner objects and lifecycle hooks, so AOP, DAL, and config-source assembly was duplicated across hosts and module packages were not self-contained.

This PR ports the declarative module-plugin mechanism from eggjs/tegg#325 to the current next architecture, adds the missing Egg-host integration, and migrates the built-in AOP, DAL, and config-source hooks. Controller/service-worker host integration remains scoped to the follow-up PR.

Design

A normal eggModule package can now provide:

  • @InnerObjectProto: a framework inner object diverted into ModuleDescriptor.innerObjectClazzList, outside business load units.
  • Five typed @EggLifecycleProto variants (LoadUnit, LoadUnitInstance, EggPrototype, EggObject, and EggContext): DI-capable hooks registered with the corresponding scope-aware lifecycle utility.

Both Egg and standalone use the same four phases:

  1. discover module references and create the business GlobalGraph nodes;
  2. create and instantiate the shared InnerObjectLoadUnit, including graph-build hooks;
  3. build/sort the graph, then create business load units and instances;
  4. destroy business instances and load units before the inner-object instance and load unit.

GlobalGraph now enforces this window: build hooks are accepted only in the created state, registration after build starts fails, and the graph cannot be built twice.

Module-reference discovery uses two levels of deduplication. A single scan root remains strict: the same name at different physical paths is an error. Across ordered roots (app -> nearest framework -> parent framework), the nearer reference wins with a warning. References resolving to the same realpath merge silently. The inner-object builder does not deduplicate classes; duplicate inner proto ids are hard errors.

All plugin inner objects intentionally share one InnerObjectLoadUnit. PRIVATE prevents injection from business load units; it is not isolation between module plugins. Same-name inner objects are selected with @DefineModuleQualifier(...).

Breaking changes and migration

  • The deprecated standalone Runner app class is replaced by StandaloneApp without an alias. The main() and preLoad() entry points remain.
  • main(options.innerObjects) is removed. A defined value throws a migration error; innerObjects: undefined is ignored. Use innerObjectHandlers, or StandaloneAppInit.innerObjects with the low-level API.
  • Standalone logger configuration uses only the dedicated logger option. innerObjectHandlers.logger and low-level innerObjects.logger are rejected; the configured logger remains injectable.
  • Standalone-owned moduleConfigs, moduleConfig, and runtimeConfig always take precedence; same-name host entries are silently ignored.
  • StandaloneApp keeps module references/configs and load-unit collections private; use its lifecycle API and scopeBag for scoped object resolution rather than mutable runtime introspection.
  • DAL no longer exposes app.mysqlDataSourceManager or the DAL ./app export. Inject MysqlDataSourceManager, or resolve it with getEggObjectFromName() in the owning app scope.
  • ModuleDescriptor.innerObjectClazzList is optional for source and old descriptor compatibility. Newly generated descriptors still emit an array.
  • Omitted standalone runtimeConfig.name and runtimeConfig.env normalize to '', matching the required string type.
  • Standalone discovers the AOP, DAL, and config framework modules by design. Manifest consumption reuses captured references and avoids rescanning; this core behavior has no feature gate.

Main implementation areas

  • Core decorators, metadata, runtime, and loader support for inner objects and lifecycle protos.
  • Two-phase StandaloneApp and Egg ModuleHandler boot paths.
  • Plugin-aware module discovery even when config/module.json short-circuits normal dependency scanning.
  • Reverse actual-creation teardown for inner objects and a linear, fail-fast standalone lifecycle.
  • Migration of AOP, DAL, and config-source hooks to declarative module plugins.
  • Durable architecture notes in wiki/concepts/tegg-module-plugin.md.

Test evidence

  • Module discovery: strict same-root conflicts, nearest-framework wins, same-realpath merge, plugin candidates with config/module.json, manifest consistency, and reconcile shape preservation.
  • Lifecycle: all five lifecycle proto types, actual creation-order teardown, and hooks remaining live through business load-unit teardown.
  • Host behavior: Egg and standalone module-plugin integration, real AOP advice with config/module.json, the linear standalone init/run/destroy lifecycle, and test-util parity with production boot phases.
  • Compatibility/platform: legacy descriptors without innerObjectClazzList, repeated deterministic descriptor dump, ESM test paths, and resolved manifest reference names.

Notes

Summary by CodeRabbit

  • New Features
    • Added declarative support for inner objects and lifecycle prototypes, including scope-aware hook execution and request-context AOP advice wiring.
    • Introduced inner-object load units so module plugins participate in graph build and lifecycle handling.
    • Added standalone bundle support via StandaloneApp, including manifest reuse and loaderFS, and updated standalone entrypoints.
  • Bug Fixes
    • Improved module/proto resolution with clearer multi-match errors and safer optional/missing dependency handling.
    • Prevented silent graph-weaving omissions and ensured consistent hook teardown ordering.
  • Documentation
    • Updated module-plugin and standalone API docs, including the innerObjectHandlers naming.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds inner-object and lifecycle decorators, updates metadata and graph resolution, introduces runtime/load-unit support, migrates AOP/config/DAL and boot wiring, and replaces the standalone Runner with StandaloneApp. Tests, fixtures, and docs are updated to match the new module-plugin flow.

Changes

Tegg Module Plugin Mechanism

Layer / File(s) Summary
Core decorators and metadata contracts
tegg/core/core-decorator/src/decorator/*, tegg/core/core-decorator/src/util/PrototypeUtil.ts, tegg/core/types/src/core-decorator/*, tests
Adds InnerObjectProto, EggLifecycleProto, and DefineModuleQualifier decorators, plus lifecycle/inner-object metadata and public type exports.
Prototype metadata and dependency graph
tegg/core/metadata/src/impl/*, tegg/core/metadata/src/model/*
Adds inner-object prototype implementations, inject-object resolution helpers, descriptor shape updates, and graph lookup utilities.
Loader and module config resolution
tegg/core/loader/src/LoaderFactory.ts, tegg/core/common-util/src/ModuleConfig.ts, tegg/core/test-util/src/LoaderUtil.ts, tests/fixtures
Updates module reference scanning, tolerant config resolution, manifest extension building, and loader test scaffolding.
Inner object runtime and load units
tegg/core/runtime/src/impl/*, runtime tests
Implements inner-object object creation, load units, lifecycle-instance registration, and host-provided object support.
AOP, config, and DAL migrations
tegg/core/aop-runtime/*, tegg/plugin/aop/*, tegg/plugin/config/*, tegg/plugin/dal/*
Converts AOP/config/DAL wiring to decorator-driven module plugins and updates package metadata, tests, and fixtures.
Tegg boot and standalone app
tegg/plugin/tegg/*, tegg/standalone/standalone/*
Reworks app/module loading order, replaces Runner with StandaloneApp, and adds standalone fixtures/tests for the new flow.
Wiki docs
wiki/*
Adds the module-plugin concept page and related wiki updates.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • eggjs/egg#5846: Both PRs affect manifest and decorated-file collection for inner-object-aware module loading.
  • eggjs/egg#5973: Both PRs adjust tegg/plugin/config/src/app.ts module-reference resolution and config loading around manifest-derived paths.
  • eggjs/egg#5993: Both PRs touch AOP graph-hook registration and the timing of build-hook wiring in app boot.

Suggested reviewers: jerryliang64, killagu, fengmk2

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the PR’s main change: adding a declarative module plugin mechanism in tegg.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/module-plugin-core

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.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 4, 2026

Copy link
Copy Markdown

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: b7a6718
Status: ✅  Deploy successful!
Preview URL: https://1c903073.egg-cci.pages.dev
Branch Preview URL: https://feat-module-plugin-core.egg-cci.pages.dev

View logs

@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.42225% with 93 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.43%. Comparing base (a3ee9e2) to head (b7a6718).
⚠️ Report is 1 commits behind head on next.

Files with missing lines Patch % Lines
tegg/core/runtime/src/impl/EggInnerObjectImpl.ts 60.00% 32 Missing and 4 partials ⚠️
tegg/plugin/config/src/lib/ModuleScanner.ts 86.92% 17 Missing ⚠️
tegg/standalone/standalone/src/StandaloneApp.ts 89.79% 14 Missing and 1 partial ⚠️
...e/metadata/src/impl/InjectObjectPrototypeFinder.ts 85.00% 4 Missing and 2 partials ⚠️
tegg/plugin/config/src/app.ts 66.66% 2 Missing and 2 partials ⚠️
...ore/runtime/src/impl/InnerObjectLoadUnitBuilder.ts 93.87% 3 Missing ⚠️
tegg/standalone/standalone/src/main.ts 81.25% 3 Missing ⚠️
...g/core/metadata/src/model/graph/ProtoGraphUtils.ts 94.11% 2 Missing ⚠️
.../core/runtime/src/impl/ProvidedInnerObjectProto.ts 95.83% 2 Missing ⚠️
tegg/standalone/standalone/src/EggModuleLoader.ts 90.47% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #6021      +/-   ##
==========================================
+ Coverage   82.18%   82.43%   +0.25%     
==========================================
  Files         678      686       +8     
  Lines       20853    21335     +482     
  Branches     4158     4260     +102     
==========================================
+ Hits        17138    17588     +450     
- Misses       3207     3240      +33     
+ Partials      508      507       -1     

☔ View full report in Codecov by Harness.
📢 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.

@socket-security

socket-security Bot commented Jul 4, 2026

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 4, 2026

Copy link
Copy Markdown

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: b7a6718
Status: ✅  Deploy successful!
Preview URL: https://1cabf7bf.egg-v3.pages.dev
Branch Preview URL: https://feat-module-plugin-core.egg-v3.pages.dev

View logs

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements a declarative module plugin mechanism using @InnerObjectProto and @EggLifecycleProto decorators, enabling framework extensions to be loaded into an InnerObjectLoadUnit before the business graph is built for both standalone and egg hosts. It also converts AOP, DAL, and ConfigSource hooks into module plugins and renames Runner to StandaloneApp. The review feedback suggests maintaining consistency by using .ts extensions instead of .js in import/export paths within aop-runtime, and defensively checking if caught exceptions are Error instances before accessing their message property in StandaloneApp.ts and main.ts to avoid runtime type errors.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread tegg/core/aop-runtime/src/AopGraphHookRegistrar.ts
Comment thread tegg/core/aop-runtime/src/AopInnerObjectClazzList.ts Outdated
Comment thread tegg/core/aop-runtime/src/index.ts Outdated
Comment thread tegg/standalone/standalone/src/StandaloneApp.ts Outdated
Comment thread tegg/standalone/standalone/src/main.ts Outdated
@gxkl gxkl changed the title [WIP] feat(tegg): declarative module plugin mechanism feat(tegg): declarative module plugin mechanism Jul 6, 2026
@gxkl
gxkl requested a review from killagu July 6, 2026 00:20
@gxkl
gxkl marked this pull request as ready for review July 6, 2026 01:38
Copilot AI review requested due to automatic review settings July 6, 2026 01:38
@gxkl
gxkl force-pushed the feat/module-plugin-core branch from 5001fb6 to 79594a6 Compare July 6, 2026 01:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a declarative “module plugin” mechanism for Tegg so eggModule packages can contribute framework inner objects and lifecycle hooks without host boot-code registration, and updates both the standalone host and egg host to boot in a two-phase order that guarantees graph build hooks are registered before GlobalGraph.build() consumes them.

Changes:

  • Add @InnerObjectProto / @EggLifecycleProto (five lifecycle variants) and runtime support via an InnerObjectLoadUnit instantiated before business load units.
  • Refactor standalone host: rename RunnerStandaloneApp, add bundle-manifest support, and update/expand module-plugin test coverage.
  • Update egg host boot wiring (ModuleHandler / EggModuleLoader) to instantiate the InnerObjectLoadUnit before loading business units; migrate built-in AOP/DAL/ConfigSource hooks to module-plugin form; document the architecture in wiki/.

Reviewed changes

Copilot reviewed 127 out of 127 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wiki/log.md Logs the new module-plugin architecture work and host ordering constraints.
wiki/index.md Adds an index entry for the new module-plugin concept page.
wiki/concepts/tegg-module-plugin.md Documents the declarative module-plugin design and two-phase boot ordering.
tegg/standalone/standalone/tsdown.config.ts Configures unused-check ignore list for framework module-plugin deps.
tegg/standalone/standalone/test/ModulePlugin.test.ts Adds standalone integration coverage for lifecycle protos + inner objects.
tegg/standalone/standalone/test/index.test.ts Updates tests for StandaloneApp, adds logger option and DAL cleanup coverage.
tegg/standalone/standalone/test/fixtures/logger-option/package.json Adds a fixture eggModule for logger injection tests.
tegg/standalone/standalone/test/fixtures/logger-option/foo.ts Fixture runner validating injected logger inner object.
tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Runner.ts Fixture validating LoadUnit lifecycle proto timing + DI.
tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/package.json Adds eggModule metadata for the lifecycle-proto fixture.
tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/FooLoadUnitHook.ts Fixture hook that mutates business load unit protos during preCreate.
tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Foo.ts Fixture inner object proto used by lifecycle hook DI.
tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/package.json Adds eggModule metadata for LoadUnitInstance lifecycle fixture.
tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/FooLoadUnitInstanceHook.ts Fixture LoadUnitInstance hook mutating created objects.
tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/Foo.ts Fixture runner exposing mutation performed by instance hook.
tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/package.json Adds eggModule metadata for private-inner-object injection failure test.
tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/innerBar.ts Fixture private inner object proto.
tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/foo.ts Fixture business proto that incorrectly injects private inner object.
tegg/standalone/standalone/test/fixtures/inner-object-proto/package.json Adds eggModule metadata for inner-object injection fixture.
tegg/standalone/standalone/test/fixtures/inner-object-proto/innerBar.ts Fixture PUBLIC inner object proto with DI dependency on another inner object.
tegg/standalone/standalone/test/fixtures/inner-object-proto/foo.ts Fixture business proto injecting a PUBLIC inner object.
tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/package.json Adds eggModule metadata for EggPrototype lifecycle fixture.
tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/FooEggPrototypeHook.ts Fixture prototype hook writing metadata from prototype creation.
tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/Foo.ts Fixture runner reading data set by prototype hook.
tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/package.json Adds eggModule metadata for EggObject lifecycle fixture.
tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/FooEggObjectHook.ts Fixture object hook mutating created object.
tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/Foo.ts Fixture runner reading mutation from object hook.
tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/package.json Adds eggModule metadata for EggContext lifecycle fixture.
tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/FooEggContextHook.ts Fixture context hook initializing context state.
tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/Foo.ts Fixture runner reading ctx state via ContextHandler.
tegg/standalone/standalone/test/fixtures/dal-manager-inject/package.json Adds eggModule metadata for DAL manager injection fixture.
tegg/standalone/standalone/test/fixtures/dal-manager-inject/foo.ts Fixture pinning PUBLIC mysqlDataSourceManager injection surface.
tegg/standalone/standalone/src/StandaloneLoadUnit.ts Removes legacy standalone “inner object as a load unit” implementation.
tegg/standalone/standalone/src/StandaloneInnerObjectProto.ts Removes legacy standalone inner-object prototype implementation.
tegg/standalone/standalone/src/StandaloneInnerObject.ts Removes legacy standalone inner-object EggObject implementation.
tegg/standalone/standalone/src/StandaloneApp.ts New standalone host implementing two-phase boot with InnerObjectLoadUnit.
tegg/standalone/standalone/src/Runner.ts Removes old standalone host (replaced by StandaloneApp).
tegg/standalone/standalone/src/main.ts Updates main entry to use StandaloneApp and introduces appMain.
tegg/standalone/standalone/src/index.ts Updates exports to expose StandaloneApp instead of removed legacy types.
tegg/standalone/standalone/src/EggModuleLoader.ts Adds manifest/loaderFS support and exposes moduleDescriptors for inner unit build.
tegg/standalone/standalone/src/ConfigSourceLoadUnitHook.ts Removes standalone-specific ConfigSource hook (now host-agnostic module plugin).
tegg/standalone/standalone/package.json Switches framework deps to module-plugin packages and adds loader-fs/tegg-config.
tegg/plugin/tegg/test/ModulePlugin.test.ts Adds app-mode integration coverage for module-plugin lifecycle protos + inner objects.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/package.json Adds ESM test app fixture root.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/PluginHooks.ts Fixture module plugin hooks (LoadUnit + EggObject lifecycle protos).
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/package.json Adds eggModule metadata for the fixture module.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/InnerRegistry.ts Fixture inner objects with PRIVATE/PUBLIC semantics and DI.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/HelloService.ts Fixture business singleton injecting a PUBLIC inner object.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/plugin.ts Enables teggConfig and tegg plugin for app-mode fixture.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/module.json Declares the fixture module path for scanning.
tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/config.default.ts Minimal keys config for egg mock app boot.
tegg/plugin/tegg/test/BundledAppBoot.test.ts Extends timeout to accommodate additional boots/manifest generation.
tegg/plugin/tegg/src/lib/ModuleHandler.ts Instantiates InnerObjectLoadUnit before business units; reverses teardown ordering.
tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts Adds bundle-mode tolerance when module dirs don’t exist on disk.
tegg/plugin/tegg/src/lib/EggModuleLoader.ts Splits initGraph() vs load(), adds manifest collection changes, promotes enabled plugins reliably.
tegg/plugin/tegg/src/app.ts Removes imperative registration for config-source + multi-instance hook (now module plugins / vestigial removed).
tegg/plugin/tegg/package.json Removes export for deleted ConfigSourceLoadUnitHook.
tegg/plugin/dal/src/lib/TransactionPrototypeHook.ts Converts DAL transaction hook to module-plugin lifecycle proto + DI-injected deps.
tegg/plugin/dal/src/lib/MysqlDataSourceManagerObject.ts Adds PUBLIC inner-object wrapper exposing DAL manager to business modules.
tegg/plugin/dal/src/lib/DalTableEggPrototypeHook.ts Converts DAL table hook to module-plugin lifecycle proto with DI logger.
tegg/plugin/dal/src/lib/DalModuleLoadUnitHook.ts Converts DAL load-unit hook to module-plugin + adds @LifecycleDestroy cleanup.
tegg/plugin/dal/src/index.ts Exports the new MysqlDataSourceManagerObject.
tegg/plugin/dal/src/app.ts Removes imperative hook registration; retains egg-side manager cleanup in beforeClose.
tegg/plugin/dal/package.json Adds export mapping for MysqlDataSourceManagerObject.
tegg/plugin/config/test/ReadModule.test.ts Updates expectations to account for optional framework module references.
tegg/plugin/config/src/lib/ModuleScanner.ts Resolves framework dir via getFrameworkPath and scans framework modules as optional.
tegg/plugin/config/src/lib/ConfigSourceLoadUnitHook.ts Converts config-source hook into host-agnostic module-plugin lifecycle proto.
tegg/plugin/config/src/app.ts Adds bundle-mode tolerance for missing external module dirs/configs.
tegg/plugin/config/package.json Marks tegg-config as an eggModule and exports ConfigSourceLoadUnitHook.
tegg/plugin/aop/test/aop.test.ts Increases timeout to avoid slow-runner failures.
tegg/plugin/aop/src/InnerObjects.ts Re-exports AOP module-plugin classes for scanning under the aop plugin eggModule.
tegg/plugin/aop/src/app.ts Removes imperative hook registration; documents which hooks remain host-registered.
tegg/plugin/aop/package.json Marks aop plugin as an eggModule and exports InnerObjects entry.
tegg/core/types/test/snapshots/index.test.ts.snap Snapshot updates for new exported constants/types.
tegg/core/types/src/metadata/model/ProtoDescriptor.ts Extends InjectObjectDescriptor with optional?: boolean.
tegg/core/types/src/core-decorator/Prototype.ts Adds EGG_INNER_OBJECT_PROTO_IMPL_TYPE constant.
tegg/core/types/src/core-decorator/model/index.ts Exposes EggLifecycleInfo type.
tegg/core/types/src/core-decorator/model/EggLifecycleInfo.ts Adds EggLifecycleInfo model type.
tegg/core/types/src/core-decorator/InnerObjectProto.ts Adds InnerObjectProto params type.
tegg/core/types/src/core-decorator/index.ts Exports EggLifecycleProto + InnerObjectProto types.
tegg/core/types/src/core-decorator/EggLifecycleProto.ts Adds EggLifecycleProto param types.
tegg/core/types/package.json Adds export map entries for new core-decorator typings.
tegg/core/test-util/src/LoaderUtil.ts Reuses production loader classification to match inner-object diversion behavior in tests.
tegg/core/tegg/test/snapshots/helper.test.ts.snap Snapshot updates for new exports.
tegg/core/tegg/test/snapshots/exports.test.ts.snap Snapshot updates for new exports/decorators.
tegg/core/tegg/test/snapshots/dal.test.ts.snap Snapshot updates for DAL exports.
tegg/core/runtime/test/InnerObjectLoadUnit.test.ts Adds integration tests for inner objects, DI wiring, lifecycle proto registration, and error cases.
tegg/core/runtime/test/snapshots/index.test.ts.snap Snapshot updates for new runtime exports.
tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts Adds proto/object for host-provided inner objects (provided-instance factory).
tegg/core/runtime/src/impl/InnerObjectLoadUnitInstance.ts Implements instantiation + auto register/deregister of lifecycle protos by type.
tegg/core/runtime/src/impl/InnerObjectLoadUnitBuilder.ts Builds a dedicated inner-object proto graph (toposort/cycle detect/missing dep errors).
tegg/core/runtime/src/impl/InnerObjectLoadUnit.ts Introduces the host-agnostic InnerObjectLoadUnit type.
tegg/core/runtime/src/impl/index.ts Exposes new inner-object runtime types and EggInnerObjectImpl.
tegg/core/runtime/src/impl/EggInnerObjectImpl.ts Adds inner-object EggObject implementation that only runs decorator-declared self lifecycle.
tegg/core/metadata/test/ModuleDescriptorDumper.test.ts Updates dumper tests to include innerObjectClazzList.
tegg/core/metadata/test/snapshots/index.test.ts.snap Snapshot updates for new metadata exports.
tegg/core/metadata/src/model/ProtoDescriptorHelper.ts Supports define-vs-instance module/unit fields for diverted protos.
tegg/core/metadata/src/model/ModuleDescriptor.ts Adds innerObjectClazzList and fixes JSON dumping on Windows path escaping.
tegg/core/metadata/src/model/graph/ProtoGraphUtils.ts Extracts proto dependency resolution utilities + name index for perf.
tegg/core/metadata/src/model/graph/index.ts Exports ProtoGraphUtils.
tegg/core/metadata/src/model/graph/GlobalGraph.ts Uses ProtoGraphUtils + lazy name index to avoid O(n·m·n) scanning.
tegg/core/metadata/src/impl/InjectObjectPrototypeFinder.ts Extracts inject-proto selection logic for reuse and optional handling.
tegg/core/metadata/src/impl/index.ts Exports EggInnerObjectPrototypeImpl + InjectObjectPrototypeFinder.
tegg/core/metadata/src/impl/EggPrototypeBuilder.ts Refactors prototype building to use InjectObjectPrototypeFinder.
tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts Adds proto impl type for inner objects built from metadata descriptors.
tegg/core/loader/test/LoaderInnerObject.test.ts Adds coverage that inner-object classes are diverted and included in manifest decorated files.
tegg/core/loader/test/fixtures/modules/module-with-inner-object/package.json Adds test module fixture with eggModule metadata.
tegg/core/loader/test/fixtures/modules/module-with-inner-object/HelloService.ts Fixture business singleton proto.
tegg/core/loader/test/fixtures/modules/module-with-inner-object/FetchRouter.ts Fixture inner object proto.
tegg/core/loader/test/fixtures/modules/module-with-inner-object/ControllerHook.ts Fixture lifecycle proto injecting inner object.
tegg/core/loader/src/LoaderUtil.ts Tightens glob excludes to also omit test/** and coverage/**.
tegg/core/loader/src/LoaderFactory.ts Diverts inner-object protos into innerObjectClazzList ahead of business clazzList.
tegg/core/core-decorator/test/inner-object-decorators.test.ts Adds tests for InnerObjectProto/EggLifecycleProto metadata semantics.
tegg/core/core-decorator/test/snapshots/index.test.ts.snap Snapshot updates for new decorator exports.
tegg/core/core-decorator/src/util/PrototypeUtil.ts Adds metadata flags for inner objects + lifecycle protos and stores lifecycle type metadata.
tegg/core/core-decorator/src/decorator/InnerObjectProto.ts Adds InnerObjectProto decorator mapping to inner-object proto impl type + flagging.
tegg/core/core-decorator/src/decorator/index.ts Exports new decorators.
tegg/core/core-decorator/src/decorator/EggLifecycleProto.ts Adds EggLifecycleProto decorator + five typed variants.
tegg/core/aop-runtime/test/aop-runtime.test.ts Updates tests to inject CrosscutAdviceFactory via DI field instead of constructor.
tegg/core/aop-runtime/test/snapshots/index.test.ts.snap Snapshot updates for new AOP runtime export.
tegg/core/aop-runtime/src/LoadUnitAopHook.ts Converts to module-plugin lifecycle proto with injected CrosscutAdviceFactory.
tegg/core/aop-runtime/src/index.ts Exports AopGraphHookRegistrar.
tegg/core/aop-runtime/src/EggPrototypeCrossCutHook.ts Converts to module-plugin lifecycle proto with injected CrosscutAdviceFactory.
tegg/core/aop-runtime/src/EggObjectAopHook.ts Converts to module-plugin EggObject lifecycle proto.
tegg/core/aop-runtime/src/AopGraphHookRegistrar.ts Adds declarative registration of GlobalGraph build hooks via @LifecyclePostInject.
tegg/core/aop-runtime/package.json Adds lifecycle dep and removes eggModule declaration from aop-runtime package.
tegg/core/aop-decorator/src/CrosscutAdviceFactory.ts Marks CrosscutAdviceFactory as an inner-object proto for module-plugin instantiation.

Comment thread tegg/standalone/standalone/src/main.ts Outdated
Copilot AI review requested due to automatic review settings July 6, 2026 01:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 127 out of 127 changed files in this pull request and generated 1 comment.

Comment thread tegg/core/metadata/src/model/ModuleDescriptor.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

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

⚠️ Outside diff range comments (2)
tegg/core/loader/src/LoaderFactory.ts (1)

61-62: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Give each module its own multiInstanceClazzList. Declaring the array outside the loop makes every ModuleDescriptor share the same list, so later modules mutate earlier descriptors and GlobalGraph.create() attributes multi-instance classes to the wrong module.

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

In `@tegg/core/loader/src/LoaderFactory.ts` around lines 61 - 62, Each
ModuleDescriptor is currently sharing the same multiInstanceClazzList, so later
iterations can mutate earlier descriptors and confuse GlobalGraph.create()
attribution. Move the multiInstanceClazzList initialization so it is created per
module inside the LoaderFactory logic that builds each ModuleDescriptor, and
make sure each descriptor receives its own fresh array before pushing
multi-instance classes.
tegg/standalone/standalone/src/main.ts (1)

10-19: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Forward frameworkDeps through preLoad
preLoad only accepts dependencies, so callers can’t warm the same framework module set that main/StandaloneApp.preLoad scan at boot. Add frameworkDeps here and pass it through.

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

In `@tegg/standalone/standalone/src/main.ts` around lines 10 - 19, The preLoad
wrapper only forwards dependencies, so callers cannot pass the same
frameworkDeps set that main and StandaloneApp.preLoad use during boot. Update
preLoad to accept frameworkDeps alongside dependencies, and pass both through to
StandaloneApp.preLoad so the same module set can be warmed consistently.
🧹 Nitpick comments (5)
tegg/plugin/config/src/lib/ModuleScanner.ts (1)

25-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider logging swallowed errors for diagnosability.

The catch-all silently discards any error from getFrameworkPath (not just "no framework resolvable" cases, e.g. malformed package.json). A debug(...) call here would help diagnose unexpected misconfiguration without changing behavior.

♻️ Suggested addition
   private resolveFrameworkDir(): string | undefined {
     try {
       return getFrameworkPath({ baseDir: this.baseDir });
-    } catch {
+    } catch (err) {
+      debug('resolveFrameworkDir failed: %o', err);
       // No package.json or no resolvable framework next to the app (e.g.
       // bare unit fixtures without node_modules) — app modules only.
       return undefined;
     }
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/plugin/config/src/lib/ModuleScanner.ts` around lines 25 - 33, The
resolveFrameworkDir() method in ModuleScanner swallows all errors from
getFrameworkPath(), so add a debug(...) log inside the catch before returning
undefined. Use the same baseDir context from this.baseDir and keep the fallback
behavior unchanged, but make sure unexpected failures (not just missing
framework cases) are observable for diagnosis.
tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts (1)

99-141: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the shared prototype-construction path EggInnerObjectPrototypeImpl.create() repeats the same field assembly and InjectObjectPrototypeFinder/IdenticalUtil.createProtoId flow as EggPrototypeBuilder.create()/build(). A shared helper would reduce the chance of the two implementations drifting apart.

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

In `@tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts` around lines 99 -
141, EggInnerObjectPrototypeImpl.create() duplicates the prototype assembly
logic already present in EggPrototypeBuilder.create()/build(), so refactor the
shared construction path into a common helper and have both call it. Keep the
existing behavior for filepath, qualifiers, inject type/objects,
InjectObjectPrototypeFinder.findInjectObjectPrototypes, and
IdenticalUtil.createProtoId, but centralize the field mapping so the two
implementations cannot drift apart.
tegg/core/types/src/core-decorator/EggLifecycleProto.ts (1)

3-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Literal union collapses to string, losing autocomplete for the five known lifecycle types.

TypeScript widens 'LoadUnit' | ... | string to just string, so IDEs won't suggest the five official lifecycle type names when authors declare custom EggLifecycleProto({ type: ... }) calls.

♻️ Proposed fix using the `string & {}` trick to retain literal autocomplete
 export interface CommonEggLifecycleProtoParams extends InnerObjectProtoParams {
-  type: 'LoadUnit' | 'LoadUnitInstance' | 'EggObject' | 'EggPrototype' | 'EggContext' | string;
+  type: 'LoadUnit' | 'LoadUnitInstance' | 'EggObject' | 'EggPrototype' | 'EggContext' | (string & {});
 }

Please confirm this project's TypeScript version supports this pattern as expected (it's a long-standing, TS-team-acknowledged trick, not an official feature).

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

In `@tegg/core/types/src/core-decorator/EggLifecycleProto.ts` around lines 3 - 5,
The CommonEggLifecycleProtoParams.type union in EggLifecycleProto is collapsing
to plain string, which removes autocomplete for the known lifecycle names.
Update the type definition to preserve the five literal options while still
allowing custom strings, using the standard string & {}-style workaround in
CommonEggLifecycleProtoParams. Keep the change localized to the type declaration
so EggLifecycleProto and related EggLifecycleProto({ type: ... }) call sites
retain IDE suggestions without changing runtime behavior.
tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts (1)

78-80: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

getMetaData looks up metadata on a plain factory closure, which never carries decorator metadata.

this.objFactory is an arrow function created ad hoc by the builder (() => innerObject.obj), never a decorated class, so MetadataUtil.getMetaData here will effectively always resolve to undefined. If any consumer of EggPrototype.getMetaData (e.g. AOP/crosscut logic) relies on this for provided inner objects, it will silently no-op instead of surfacing a clear "not supported" signal.

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

In `@tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts` around lines 78 - 80,
getMetaData on ProvidedInnerObjectProto is reading decorator metadata from
objFactory, but objFactory is just the builder’s plain arrow closure and will
never have metadata. Update ProvidedInnerObjectProto.getMetaData to stop
delegating to MetadataUtil.getMetaData on objFactory, and instead either return
a clear unsupported result or throw a descriptive error for provided inner
objects so EggPrototype consumers like AOP/crosscut logic do not silently no-op.
tegg/plugin/tegg/test/ModulePlugin.test.ts (1)

9-51: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider adding multi-app regression coverage for this lifecycle change.

This exercises the new module-plugin boot order in ModuleHandler (inner-object load unit instantiated before business load units) with a single app instance. As per coding guidelines, "When changing loader, runtime, lifecycle, or eventbus behavior, add or update multi-app regression coverage (for example tests like MultiApp.test.ts) to verify two concurrent apps do not cross-talk." Given ModuleHandler.init()/destroy() ordering was substantially reworked, a companion test booting two concurrent module-plugin-app-style apps would guard against state leaking across TeggScope bags.

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

In `@tegg/plugin/tegg/test/ModulePlugin.test.ts` around lines 9 - 51, Add
multi-app regression coverage for the ModuleHandler lifecycle change by creating
a test that boots two concurrent module-plugin-app instances and verifies their
TeggScope state does not cross-talk. Use the existing ModulePlugin.test.ts setup
and the ModuleHandler init/destroy behavior as reference points, and assert both
apps independently load HelloService, initialize inner-object load units before
business load units, and keep their createdLoadUnits and innerRegistry state
isolated.

Source: Coding guidelines

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

Inline comments:
In `@tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts`:
- Around line 59-71: The module resolution tolerance logic is duplicated in
ModuleConfigLoader and is already drifting from the similar code in the config
plugin and StandaloneApp. Extract the shared “resolve path, check fs.existsSync,
then fall back to reference.name and skip config loading” flow into a common
helper on ModuleConfigUtil (or equivalent) and update ModuleConfigLoader to call
it, so the modulePath/moduleDirExists/moduleName/defaultConfig handling stays
consistent across all callers.

In `@tegg/plugin/tegg/src/lib/ModuleHandler.ts`:
- Around line 116-132: The teardown logic in ModuleHandler currently stops on
the first thrown error in the load unit destruction loops, which can skip later
cleanup including the final `#innerObjectLoadUnit` teardown. Update the destroy
path around the loadUnitInstances, loadUnits, and `#innerObjectLoadUnit` blocks to
isolate each destroyLoadUnitInstance/destroyLoadUnit call so one failure does
not abort the remaining cleanup. Collect any errors during the loops in
ModuleHandler and rethrow an aggregate after all teardown steps have been
attempted.
- Around line 84-107: The init flow in ModuleHandler.init only assigns
loadUnitInstances after all later steps succeed, which leaves the inner-object
instance untracked if a boot error happens after
instantiateInnerObjectLoadUnit(). Update ModuleHandler.init so the
innerObjectInstance is stored in this.loadUnitInstances immediately after it is
created, then append each LoadUnitInstance created in the loop; keep the later
CompatibleUtil and loadUnit handling unchanged.

In `@tegg/standalone/standalone/src/main.ts`:
- Around line 40-47: The success-path cleanup in main/appMain is inconsistent
because app.destroy() is not awaited before returning, which can let
StandaloneApp resolve before TeggScope teardown finishes; change the finally
block to await the destroy promise just like the init-failure path so scope
cleanup completes before exit. Also update the .catch in that same app.destroy()
call to follow the existing Error-guard pattern used in this file, so non-Error
rejections are handled safely without mutating e.message directly. Use the
app.destroy() cleanup logic and the appMain/main flow as the key locations, and
add or update a regression test covering sequential StandaloneApp/MultiApp-style
teardown ordering to confirm no scope cross-talk.

In `@tegg/standalone/standalone/src/StandaloneApp.ts`:
- Around line 160-164: The per-app config selection in StandaloneApp should not
mutate the process-global ModuleConfigUtil.configNames, since that breaks
isolation between concurrent StandaloneApp instances. Update `#initRuntime`,
doDestroy, and the ModuleConfigUtil.readModuleNameSync/loadModuleConfigSync path
so configNames is passed or stored via TeggScope-backed instance state instead
of a shared static, keeping each app’s env-specific module.default/module.<env>
lookup independent.

In `@wiki/concepts/tegg-module-plugin.md`:
- Around line 5-13: The source_files list is missing the actual host-entrypoint
sources that back the egg-host feeding claim. Update the wiki page’s
source_files in the tegg-module-plugin section to include the plugin boot
entrypoints that register the hard-fed inner-object lists, such as the app.ts
entrypoints in the AOP, config, and DAL plugins, alongside the existing runtime
and handler symbols. Keep the listed sources aligned with the claim’s
traceability requirements so the major code paths are represented.

---

Outside diff comments:
In `@tegg/core/loader/src/LoaderFactory.ts`:
- Around line 61-62: Each ModuleDescriptor is currently sharing the same
multiInstanceClazzList, so later iterations can mutate earlier descriptors and
confuse GlobalGraph.create() attribution. Move the multiInstanceClazzList
initialization so it is created per module inside the LoaderFactory logic that
builds each ModuleDescriptor, and make sure each descriptor receives its own
fresh array before pushing multi-instance classes.

In `@tegg/standalone/standalone/src/main.ts`:
- Around line 10-19: The preLoad wrapper only forwards dependencies, so callers
cannot pass the same frameworkDeps set that main and StandaloneApp.preLoad use
during boot. Update preLoad to accept frameworkDeps alongside dependencies, and
pass both through to StandaloneApp.preLoad so the same module set can be warmed
consistently.

---

Nitpick comments:
In `@tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts`:
- Around line 99-141: EggInnerObjectPrototypeImpl.create() duplicates the
prototype assembly logic already present in
EggPrototypeBuilder.create()/build(), so refactor the shared construction path
into a common helper and have both call it. Keep the existing behavior for
filepath, qualifiers, inject type/objects,
InjectObjectPrototypeFinder.findInjectObjectPrototypes, and
IdenticalUtil.createProtoId, but centralize the field mapping so the two
implementations cannot drift apart.

In `@tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts`:
- Around line 78-80: getMetaData on ProvidedInnerObjectProto is reading
decorator metadata from objFactory, but objFactory is just the builder’s plain
arrow closure and will never have metadata. Update
ProvidedInnerObjectProto.getMetaData to stop delegating to
MetadataUtil.getMetaData on objFactory, and instead either return a clear
unsupported result or throw a descriptive error for provided inner objects so
EggPrototype consumers like AOP/crosscut logic do not silently no-op.

In `@tegg/core/types/src/core-decorator/EggLifecycleProto.ts`:
- Around line 3-5: The CommonEggLifecycleProtoParams.type union in
EggLifecycleProto is collapsing to plain string, which removes autocomplete for
the known lifecycle names. Update the type definition to preserve the five
literal options while still allowing custom strings, using the standard string &
{}-style workaround in CommonEggLifecycleProtoParams. Keep the change localized
to the type declaration so EggLifecycleProto and related EggLifecycleProto({
type: ... }) call sites retain IDE suggestions without changing runtime
behavior.

In `@tegg/plugin/config/src/lib/ModuleScanner.ts`:
- Around line 25-33: The resolveFrameworkDir() method in ModuleScanner swallows
all errors from getFrameworkPath(), so add a debug(...) log inside the catch
before returning undefined. Use the same baseDir context from this.baseDir and
keep the fallback behavior unchanged, but make sure unexpected failures (not
just missing framework cases) are observable for diagnosis.

In `@tegg/plugin/tegg/test/ModulePlugin.test.ts`:
- Around line 9-51: Add multi-app regression coverage for the ModuleHandler
lifecycle change by creating a test that boots two concurrent module-plugin-app
instances and verifies their TeggScope state does not cross-talk. Use the
existing ModulePlugin.test.ts setup and the ModuleHandler init/destroy behavior
as reference points, and assert both apps independently load HelloService,
initialize inner-object load units before business load units, and keep their
createdLoadUnits and innerRegistry state isolated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b5819719-d3f0-4e63-9f9f-28a26cccc964

📥 Commits

Reviewing files that changed from the base of the PR and between d55efa3 and 79594a6.

⛔ Files ignored due to path filters (8)
  • tegg/core/aop-runtime/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/core-decorator/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/metadata/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/runtime/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/tegg/test/__snapshots__/dal.test.ts.snap is excluded by !**/*.snap
  • tegg/core/tegg/test/__snapshots__/exports.test.ts.snap is excluded by !**/*.snap
  • tegg/core/tegg/test/__snapshots__/helper.test.ts.snap is excluded by !**/*.snap
  • tegg/core/types/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (119)
  • tegg/core/aop-decorator/src/CrosscutAdviceFactory.ts
  • tegg/core/aop-runtime/package.json
  • tegg/core/aop-runtime/src/AopGraphHookRegistrar.ts
  • tegg/core/aop-runtime/src/EggObjectAopHook.ts
  • tegg/core/aop-runtime/src/EggPrototypeCrossCutHook.ts
  • tegg/core/aop-runtime/src/LoadUnitAopHook.ts
  • tegg/core/aop-runtime/src/index.ts
  • tegg/core/aop-runtime/test/aop-runtime.test.ts
  • tegg/core/core-decorator/src/decorator/EggLifecycleProto.ts
  • tegg/core/core-decorator/src/decorator/InnerObjectProto.ts
  • tegg/core/core-decorator/src/decorator/index.ts
  • tegg/core/core-decorator/src/util/PrototypeUtil.ts
  • tegg/core/core-decorator/test/inner-object-decorators.test.ts
  • tegg/core/loader/src/LoaderFactory.ts
  • tegg/core/loader/src/LoaderUtil.ts
  • tegg/core/loader/test/LoaderInnerObject.test.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/ControllerHook.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/FetchRouter.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/HelloService.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/package.json
  • tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts
  • tegg/core/metadata/src/impl/EggPrototypeBuilder.ts
  • tegg/core/metadata/src/impl/InjectObjectPrototypeFinder.ts
  • tegg/core/metadata/src/impl/index.ts
  • tegg/core/metadata/src/model/ModuleDescriptor.ts
  • tegg/core/metadata/src/model/ProtoDescriptorHelper.ts
  • tegg/core/metadata/src/model/graph/GlobalGraph.ts
  • tegg/core/metadata/src/model/graph/ProtoGraphUtils.ts
  • tegg/core/metadata/src/model/graph/index.ts
  • tegg/core/metadata/test/ModuleDescriptorDumper.test.ts
  • tegg/core/runtime/src/impl/EggInnerObjectImpl.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnit.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitBuilder.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitInstance.ts
  • tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts
  • tegg/core/runtime/src/impl/index.ts
  • tegg/core/runtime/test/InnerObjectLoadUnit.test.ts
  • tegg/core/test-util/src/LoaderUtil.ts
  • tegg/core/types/package.json
  • tegg/core/types/src/core-decorator/EggLifecycleProto.ts
  • tegg/core/types/src/core-decorator/InnerObjectProto.ts
  • tegg/core/types/src/core-decorator/Prototype.ts
  • tegg/core/types/src/core-decorator/index.ts
  • tegg/core/types/src/core-decorator/model/EggLifecycleInfo.ts
  • tegg/core/types/src/core-decorator/model/index.ts
  • tegg/core/types/src/metadata/model/ProtoDescriptor.ts
  • tegg/plugin/aop/package.json
  • tegg/plugin/aop/src/InnerObjects.ts
  • tegg/plugin/aop/src/app.ts
  • tegg/plugin/aop/test/aop.test.ts
  • tegg/plugin/config/package.json
  • tegg/plugin/config/src/app.ts
  • tegg/plugin/config/src/lib/ConfigSourceLoadUnitHook.ts
  • tegg/plugin/config/src/lib/ModuleScanner.ts
  • tegg/plugin/config/test/ReadModule.test.ts
  • tegg/plugin/dal/package.json
  • tegg/plugin/dal/src/app.ts
  • tegg/plugin/dal/src/index.ts
  • tegg/plugin/dal/src/lib/DalModuleLoadUnitHook.ts
  • tegg/plugin/dal/src/lib/DalTableEggPrototypeHook.ts
  • tegg/plugin/dal/src/lib/MysqlDataSourceManagerObject.ts
  • tegg/plugin/dal/src/lib/TransactionPrototypeHook.ts
  • tegg/plugin/tegg/package.json
  • tegg/plugin/tegg/src/app.ts
  • tegg/plugin/tegg/src/lib/EggModuleLoader.ts
  • tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts
  • tegg/plugin/tegg/src/lib/ModuleHandler.ts
  • tegg/plugin/tegg/test/BundledAppBoot.test.ts
  • tegg/plugin/tegg/test/ModulePlugin.test.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/config.default.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/module.json
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/plugin.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/HelloService.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/InnerRegistry.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/PluginHooks.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/package.json
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/package.json
  • tegg/standalone/standalone/package.json
  • tegg/standalone/standalone/src/ConfigSourceLoadUnitHook.ts
  • tegg/standalone/standalone/src/EggModuleLoader.ts
  • tegg/standalone/standalone/src/Runner.ts
  • tegg/standalone/standalone/src/StandaloneApp.ts
  • tegg/standalone/standalone/src/StandaloneInnerObject.ts
  • tegg/standalone/standalone/src/StandaloneInnerObjectProto.ts
  • tegg/standalone/standalone/src/StandaloneLoadUnit.ts
  • tegg/standalone/standalone/src/index.ts
  • tegg/standalone/standalone/src/main.ts
  • tegg/standalone/standalone/test/ModulePlugin.test.ts
  • tegg/standalone/standalone/test/fixtures/dal-manager-inject/foo.ts
  • tegg/standalone/standalone/test/fixtures/dal-manager-inject/package.json
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/FooEggContextHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/FooEggObjectHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/FooEggPrototypeHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/foo.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/innerBar.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/package.json
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/foo.ts
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/innerBar.ts
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/FooLoadUnitInstanceHook.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/FooLoadUnitHook.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Runner.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/logger-option/foo.ts
  • tegg/standalone/standalone/test/fixtures/logger-option/package.json
  • tegg/standalone/standalone/test/index.test.ts
  • tegg/standalone/standalone/tsdown.config.ts
  • wiki/concepts/tegg-module-plugin.md
  • wiki/index.md
  • wiki/log.md
💤 Files with no reviewable changes (6)
  • tegg/standalone/standalone/src/ConfigSourceLoadUnitHook.ts
  • tegg/standalone/standalone/src/StandaloneInnerObject.ts
  • tegg/standalone/standalone/src/StandaloneLoadUnit.ts
  • tegg/standalone/standalone/src/Runner.ts
  • tegg/plugin/tegg/package.json
  • tegg/standalone/standalone/src/StandaloneInnerObjectProto.ts

Comment thread tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts Outdated
Comment thread tegg/plugin/tegg/src/lib/ModuleHandler.ts Outdated
Comment thread tegg/plugin/tegg/src/lib/ModuleHandler.ts Outdated
Comment thread tegg/standalone/standalone/src/main.ts
Comment thread tegg/standalone/standalone/src/StandaloneApp.ts Outdated
Comment thread wiki/concepts/tegg-module-plugin.md
Comment thread tegg/plugin/aop/src/app.ts Outdated
Comment thread tegg/plugin/aop/src/app.ts Outdated
Comment thread tegg/plugin/dal/src/lib/MysqlDataSourceManagerObject.ts Outdated
Comment thread tegg/plugin/tegg/src/lib/ModuleHandler.ts Outdated
@killagu

killagu commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Code Review: 声明式 module plugin 机制

整体架构清晰,happy path 测试充分。但本次评审最核心的主题是:hook 的投递方式从"无条件命令式注册"变成了"扫描 + 提升(promote)流水线",而这条流水线的每一种失败模式都是静默跳过 —— 若干现实部署形态会在没有任何报错的情况下丢失 @Transactional 和 AOP 织入。以下发现经过逐条对抗性验证(14 个候选中 12 个确认、2 个证伪)。

发现(按严重程度排序)

1. tegg/plugin/config/src/lib/ModuleScanner.ts:25 — 多层自定义框架会静默丢失所有内置 DAL/AOP hook

扫描器只解析一个 framework 目录(getFrameworkPath,不走继承链),且只读它 package.json 里的直接依赖。在 app → my-framework → egg 的分层结构下(@eggjs/dal-plugin/aop-plugin 是 egg 的依赖而非 my-framework 的),egg 的插件加载器仍会沿完整 eggPath 链启用这些插件,但 module 扫描永远找不到它们的 eggModule 包 —— 而插件 app.ts 里原有的无条件 registerLifecycle 已被删除。结果:@Transactional 静默失去事务、crosscut/pointcut 通知静默不织入,且没有任何断言能检测到 hook 缺失。现有唯一的自定义框架 fixture 把 module 直接声明为框架依赖,所以测试覆盖不到这条路径。

2. tegg/plugin/tegg/src/lib/EggModuleLoader.ts:62 — bundle 模式下框架 module plugin 永远无法被 promote,hook 被静默跳过

manifest 生成只跑 loadMetadata(不经过 didLoad 阶段的 promote 循环),框架引用以 optional: true 被固化进 manifest;restore 时 ref.path 指向不存在<outputDir>/node_modules/<pkg>,而 #findPackageRoot 对真实存在的目录做 realpath —— 字符串精确比较永远不可能相等,promote 静默落空,ModuleHandler.ts:48 直接 continue 跳过 teggAop/teggDal。打包后的应用原本必然获得的 AOP 织入现在会静默消失。建议:改用 module 名字匹配(两侧都有)而不是磁盘路径相等,并至少在静默 continue 处加一行 coreLogger 日志。(另有一个潜在隐患:plugin.path 指向的是入口目录(src//dist/),任何在该目录带嵌套 package.json stub 的包会让 #findPackageRoot 停在错误的根 —— 仓库内暂无包命中,但第三方 tshy 双构建布局会。)

3. tegg/plugin/tegg/src/lib/ModuleHandler.ts:48 — 被禁用插件的 hook 现在照样运行

该处只判断 moduleDescriptor.optional === true,没有任何 plugin enable 检查。插件直接声明在应用自身 package.json dependencies 里(常规安装方式)时,扫描产出的引用是非 optional(optionalundefined),于是配置了 dal: { enable: false } 之后 DalModuleLoadUnitHook 仍被实例化、其 preCreate 仍会 fork/创建数据源 —— 插件已禁用却照样开 DB 连接、照样织入 AOP。本 PR 之前注册在插件 app.ts 启动逻辑里,天然受 enable 门控。

4. tegg/core/runtime/src/impl/InnerObjectLoadUnitBuilder.ts:58 — inner object 的 proto id 跨模块冲突,同名即启动崩溃

所有 module plugin 的 inner object 共用 instanceModuleName = INNER_OBJECT_LOAD_UNIT_NAME 和相同的默认 qualifier,而 createProtoId 既不含 defineModuleName 也不含 accessLevel。两个互不相识的 module plugin 各自声明 @InnerObjectProto() class FooHook {}(即使都是 PRIVATE)会产生相同 id → 抛 duplicate inner object proto(业务 proto 依靠各自 module 的 LoadUnitName qualifier 可以共存,inner object 不行)。同一 id 机制也破坏了 line 138 的 provided-object 路径:standalone 调用方传 innerObjectHandlers: { mysqlDataSourceManager: [{obj: mock}] }(旧 Runner 上合法的覆盖用法)现在会抛 duplicate provided inner object,因为 dal-plugin 总会被扫描并注册该名字。且报错信息无法定位是哪两个模块冲突。

5. tegg/core/runtime/src/impl/InnerObjectLoadUnitInstance.ts:41 — 自定义 lifecycle type 被 API 接受但必然启动崩溃

装饰器参数类型是刻意开放的(type: 'LoadUnit' | ... | string),core-decorator 还有测试明确断言 'CustomLifecycle' 能正常装饰 —— 但运行时用硬编码的 5 键 map 分发,未命中直接抛 unknown lifecycle type,且没有任何注册 API 可扩展。建议:要么把类型收窄为 5 个字面量,要么提供 lifecycle type 注册表。

6. tegg/standalone/standalone/src/main.ts:63 — 已弃用但仍被支持的 RunnerOptions.innerObjects 被静默丢弃

旧 Runner 支持它(且优先级高于 innerObjectHandlers);新 main() 只转发 innerObjectHandlers,StandaloneAppOptions 没有 innerObjects 字段。JS 调用方的 main(cwd, { innerObjects: { httpClient } }) 对象静默消失 → @Inject() httpClient 启动即失败且毫无提示。PR 描述声称"main() 不变",与此矛盾 —— 要么继续支持,要么抛出弃用错误。

7. tegg/standalone/standalone/src/StandaloneApp.ts:143 — 覆盖优先级反转:框架占位符现在覆盖用户提供的 moduleConfigs/moduleConfig/runtimeConfig

旧 Runner 最后应用 options.innerObjectHandlers(用户 stub 获胜,例如测试里的假 runtimeConfig);新 #createInnerObjects 把框架三件套放在 Object.assign 最后一个参数,用户这几个 key 的条目被静默丢弃并从磁盘重新填充。代码注释表明这是有意为之,但对签名未变的公开 innerObjectHandlers 契约来说是静默的行为破坏 —— 至少应对被覆盖的 key 抛错或告警。

8. tegg/plugin/tegg/src/lib/ModuleHandler.ts:107 — 启动中途失败会泄漏已完全初始化的 inner LoadUnitInstance

init() 先创建 inner instance,但 this.loadUnitInstances 直到最后才赋值,instance 本身没有存到任何字段(只存了 LoadUnit)。若某个业务 module 启动失败,destroy()(经 beforeCloseapp.close() 时可达 —— egg-mock 断言启动失败后的标准 teardown 路径)只会销毁 LoadUnit,永远够不到 instance:lifecycle hook 留在 scope 级 util 里、@LifecycleDestroy 清理(如 DAL 关数据源)不执行、instance 滞留在 LoadUnitInstanceFactory.instanceMap。StandaloneApp 是增量 push 的,没有这个问题 —— 建议对齐该模式,或在 catch 里销毁 inner instance。

已确认但排在前 8 之外

  • wiki 与代码不符:wiki/concepts/tegg-module-plugin.md:52-60 描述的 moduleHandler.registerInnerObjectClazzList()AOP_INNER_OBJECT_CLAZZ_LIST/DAL_INNER_OBJECT_CLAZZ_LIST、"builder 按 class 去重"均不存在;builder 遇重复是抛错,内置 hook 完全经 eggModule 扫描进入。PR 描述也重复了去重的说法。需重写这两条(违反 AGENTS.md "every nontrivial wiki claim should be traceable to raw sources")。
  • 启动开销:framework 扫描现在对每个 app+agent 无条件执行(原先以 pkg.egg.framework 为门控)—— 对框架包递归 glob 加上对 egg 42 个依赖逐个 importResolve+读文件;standalone bundle 模式仍做全量多根磁盘 glob,尽管 buildTeggManifestData 写出的 manifest.moduleReferences 从未被读回(egg 插件侧是消费了的,见 tegg/plugin/config/src/app.ts:57)。
  • 重复代码:EggInnerObjectImplEggObjectImpl 约 220 行的拷贝,唯一差异是一条 hook 解析规则;EggInnerObjectPrototypeImplEggPrototypeImpl + 内联 builder 的逐字拷贝(空子类即可 —— EggObjectFactory 按精确 constructor 分发);standalone 的 buildTeggManifestData 与插件侧逐字节相同。
  • 缺失覆盖:tegg/CLAUDE.md 规则 7 要求 loader/runtime/lifecycle 变更附带多 app 回归覆盖;本 diff 未增加(未发现隔离 bug —— scoped util 与 per-app creator overlay 检查无误 —— 但本 PR 是该 overlay 的第一个真实消费者,而 MultiApp.test.ts 未覆盖 inner object)。

验证阶段被证伪的候选(供参考)

  • LoaderUtil.ts 新增的 !**/test/** 不是行为变化 —— 实测 globby 11 在旧的 !**/test 下就已剪掉 test/ 子树(新代码注释的说法与事实不符)。
  • 怀疑 teggAop barrel 重导出的 hook 类会缺席 bundle manifest 的问题不成立 —— loader 会把 FILE_PATH 重新盖章为被扫描的 barrel 文件(LoaderUtil.ts:134),getDecoratedFiles 因此包含它们;已用真实 LoaderFactory.loadApp 实测验证。

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings July 9, 2026 12:07
@gxkl
gxkl force-pushed the feat/module-plugin-core branch from 79594a6 to facb7f1 Compare July 9, 2026 12:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 154 out of 170 changed files in this pull request and generated 2 comments.

Comment thread tegg/core/aop-runtime/src/LoadUnitAopHook.ts Outdated
Comment thread tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
tegg/standalone/standalone/README.md (1)

48-58: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Label the example fence as ts.

This is a TypeScript example, so the bare fence trips markdownlint and is less explicit for readers.

Fix
-```
+```ts
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/standalone/standalone/README.md` around lines 48 - 58, The README
example fence is unlabeled, so update the fenced code block in the standalone
example to use the TypeScript language tag. Locate the sample around the await
main call in the README and change the bare triple-backtick fence to a
ts-labeled fence so markdownlint passes and the snippet is clearer for readers.

Source: Linters/SAST tools

🧹 Nitpick comments (3)
tegg/core/core-decorator/src/decorator/DefineModuleQualifier.ts (1)

4-4: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use .js extension in import specifier.

As per coding guidelines, Tegg code must use ESM-only imports and .js extensions in import specifiers. The import ../util/index.ts uses a .ts extension instead of .js.

♻️ Proposed fix
-import { QualifierUtil } from '../util/index.ts';
+import { QualifierUtil } from '../util/index.js';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/core/core-decorator/src/decorator/DefineModuleQualifier.ts` at line 4,
The import in DefineModuleQualifier should use the ESM .js specifier instead of
a .ts extension. Update the QualifierUtil import in DefineModuleQualifier.ts to
point at the generated .js path in the same relative location, following the
repo’s ESM-only import convention.

Source: Coding guidelines

tegg/core/types/src/core-decorator/EggLifecycleProto.ts (1)

1-2: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use .js extension in import specifiers.

As per coding guidelines, Tegg code must use ESM-only imports and .js extensions in import specifiers. Both imports use .ts extensions.

♻️ Proposed fix
-import type { InnerObjectProtoParams } from './InnerObjectProto.ts';
-import type { EggLifecycleType } from './model/EggLifecycleInfo.ts';
+import type { InnerObjectProtoParams } from './InnerObjectProto.js';
+import type { EggLifecycleType } from './model/EggLifecycleInfo.js';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/core/types/src/core-decorator/EggLifecycleProto.ts` around lines 1 - 2,
The imports in EggLifecycleProto should follow the ESM guideline by using .js
specifiers instead of .ts. Update the type-only imports from InnerObjectProto
and EggLifecycleInfo in EggLifecycleProto.ts to reference the corresponding .js
paths so the module resolution stays consistent with the rest of Tegg.

Source: Coding guidelines

tegg/plugin/config/src/lib/ModuleScanner.ts (1)

48-65: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: resolveParentFrameworkDir reads frameworkDir/package.json twice.

The method explicitly reads and parses frameworkDir/package.json to check pkg.egg.framework, then calls this.resolveFrameworkDir(frameworkDir) which internally re-reads the same file via getFrameworkPath. The explicit check is necessary to avoid defaulting to 'egg' when no parent is declared, but the double-read is avoidable if getFrameworkPath accepts a pre-resolved framework name.

♻️ Optional: avoid double-read if getFrameworkPath supports explicit framework
 private resolveParentFrameworkDir(frameworkDir: string): string | undefined {
-  let pkg: { egg?: { framework?: unknown } };
-  try {
-    pkg = JSON.parse(fs.readFileSync(path.join(frameworkDir, 'package.json'), 'utf8'));
-  } catch (err) {
-    debug(
-      'read framework package failed, frameworkDir: %s, err: %s',
-      frameworkDir,
-      err instanceof Error ? err.message : String(err),
-    );
-    return undefined;
-  }
-  const framework = pkg.egg?.framework;
-  if (typeof framework !== 'string' || !framework) {
-    return undefined;
-  }
-  return this.resolveFrameworkDir(frameworkDir);
+  // If getFrameworkPath supports an explicit framework option,
+  // pass the resolved name directly to avoid re-reading package.json:
+  // return getFrameworkPath({ baseDir: frameworkDir, framework });
+  // Otherwise, the current approach is correct — keep as-is.
+  return this.resolveFrameworkDir(frameworkDir);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tegg/plugin/config/src/lib/ModuleScanner.ts` around lines 48 - 65,
`resolveParentFrameworkDir` in `ModuleScanner` is reading
`frameworkDir/package.json` twice: once to inspect `pkg.egg.framework`, then
again indirectly through `resolveFrameworkDir`/`getFrameworkPath`. Keep the
explicit parent-framework check, but refactor so the parsed framework value is
passed through to the framework resolution path instead of re-reading the same
package file, or otherwise update `getFrameworkPath`/`resolveFrameworkDir` to
accept an explicit framework name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tegg/core/aop-runtime/src/AopContextAdviceRegistry.ts`:
- Line 10: `AopContextAdviceRegistry` is currently marked with
`@InnerObjectProto()`, which makes it private and prevents `AopContextHook` from
injecting it across package boundaries. Update the declaration in
`AopContextAdviceRegistry` so the registry is public/exported in the proto
metadata, keeping the existing class name and related injection points intact.

In `@tegg/core/aop-runtime/src/LoadUnitAopHook.ts`:
- Around line 19-20: The injected aopContextAdviceRegistry field in
LoadUnitAopHook should not create its own AopContextAdviceRegistry fallback;
remove the default initializer from the `@Inject`()-decorated property so DI
resolution is the single source of truth. Keep the field injection in
LoadUnitAopHook aligned with AopContextHook by relying on container injection
only, which will make both hooks fail fast on missing dependencies instead of
silently diverging.

In `@tegg/plugin/config/test/ModuleScanner.test.ts`:
- Around line 5-6: The imports in ModuleScanner.test.ts use TypeScript
extensions, which violates the ESM-only import guideline for tegg test files.
Update the ModuleScanner and getFixtures import specifiers to use .js
extensions, matching the pattern used in other tests such as
ModuleConfig.test.ts, and keep the relative paths otherwise unchanged.

In `@wiki/concepts/tegg-module-plugin.md`:
- Around line 5-16: The wiki page’s source_files list is missing the egg-host
loader referenced in the boot-order discussion. Update the list in
tegg-module-plugin docs to include EggModuleLoader so the documented
initGraph()/load() flow is traceable; keep the existing source_files block
aligned with the other plugin/runtime symbols already listed.

---

Outside diff comments:
In `@tegg/standalone/standalone/README.md`:
- Around line 48-58: The README example fence is unlabeled, so update the fenced
code block in the standalone example to use the TypeScript language tag. Locate
the sample around the await main call in the README and change the bare
triple-backtick fence to a ts-labeled fence so markdownlint passes and the
snippet is clearer for readers.

---

Nitpick comments:
In `@tegg/core/core-decorator/src/decorator/DefineModuleQualifier.ts`:
- Line 4: The import in DefineModuleQualifier should use the ESM .js specifier
instead of a .ts extension. Update the QualifierUtil import in
DefineModuleQualifier.ts to point at the generated .js path in the same relative
location, following the repo’s ESM-only import convention.

In `@tegg/core/types/src/core-decorator/EggLifecycleProto.ts`:
- Around line 1-2: The imports in EggLifecycleProto should follow the ESM
guideline by using .js specifiers instead of .ts. Update the type-only imports
from InnerObjectProto and EggLifecycleInfo in EggLifecycleProto.ts to reference
the corresponding .js paths so the module resolution stays consistent with the
rest of Tegg.

In `@tegg/plugin/config/src/lib/ModuleScanner.ts`:
- Around line 48-65: `resolveParentFrameworkDir` in `ModuleScanner` is reading
`frameworkDir/package.json` twice: once to inspect `pkg.egg.framework`, then
again indirectly through `resolveFrameworkDir`/`getFrameworkPath`. Keep the
explicit parent-framework check, but refactor so the parsed framework value is
passed through to the framework resolution path instead of re-reading the same
package file, or otherwise update `getFrameworkPath`/`resolveFrameworkDir` to
accept an explicit framework name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e20b350-6955-41a9-bcbf-d5591ccb540a

📥 Commits

Reviewing files that changed from the base of the PR and between 79594a6 and facb7f1.

⛔ Files ignored due to path filters (23)
  • tegg/core/aop-runtime/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/core-decorator/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/metadata/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/runtime/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/core/tegg/test/__snapshots__/exports.test.ts.snap is excluded by !**/*.snap
  • tegg/core/tegg/test/__snapshots__/helper.test.ts.snap is excluded by !**/*.snap
  • tegg/core/types/test/__snapshots__/index.test.ts.snap is excluded by !**/*.snap
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/base-framework/node_modules/base-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/base-framework/node_modules/shared-module-base/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/base-framework/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/chair-framework/node_modules/chair-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/chair-framework/node_modules/shared-module-chair/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-chain/app/node_modules/chair-framework/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-cycle/app/node_modules/base-framework/node_modules/base-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-cycle/app/node_modules/base-framework/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-cycle/app/node_modules/chair-framework/node_modules/chair-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-cycle/app/node_modules/chair-framework/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-module-json/app/node_modules/chair-framework/config/module.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-module-json/app/node_modules/chair-framework/node_modules/framework-config-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-module-json/app/node_modules/chair-framework/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-module-json/app/node_modules/framework-config-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-same-path/app/node_modules/chair-framework/node_modules/chair-module/package.json is excluded by !**/node_modules/**
  • tegg/plugin/config/test/fixtures/framework-same-path/app/node_modules/chair-framework/package.json is excluded by !**/node_modules/**
📒 Files selected for processing (147)
  • tegg/core/aop-decorator/src/CrosscutAdviceFactory.ts
  • tegg/core/aop-runtime/package.json
  • tegg/core/aop-runtime/src/AopContextAdviceRegistry.ts
  • tegg/core/aop-runtime/src/AopGraphHookRegistrar.ts
  • tegg/core/aop-runtime/src/EggObjectAopHook.ts
  • tegg/core/aop-runtime/src/EggPrototypeCrossCutHook.ts
  • tegg/core/aop-runtime/src/LoadUnitAopHook.ts
  • tegg/core/aop-runtime/src/index.ts
  • tegg/core/aop-runtime/test/aop-runtime.test.ts
  • tegg/core/common-util/src/ModuleConfig.ts
  • tegg/core/common-util/test/ModuleConfig.test.ts
  • tegg/core/core-decorator/src/decorator/DefineModuleQualifier.ts
  • tegg/core/core-decorator/src/decorator/EggLifecycleProto.ts
  • tegg/core/core-decorator/src/decorator/InnerObjectProto.ts
  • tegg/core/core-decorator/src/decorator/index.ts
  • tegg/core/core-decorator/src/util/PrototypeUtil.ts
  • tegg/core/core-decorator/test/decorators.test.ts
  • tegg/core/core-decorator/test/fixtures/decators/QualifierCacheService.ts
  • tegg/core/core-decorator/test/inner-object-decorators.test.ts
  • tegg/core/loader/src/LoaderFactory.ts
  • tegg/core/loader/test/LoaderInnerObject.test.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/ControllerHook.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/FetchRouter.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/HelloService.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/package.json
  • tegg/core/metadata/src/impl/EggInnerObjectPrototypeImpl.ts
  • tegg/core/metadata/src/impl/EggPrototypeBuilder.ts
  • tegg/core/metadata/src/impl/EggPrototypeImpl.ts
  • tegg/core/metadata/src/impl/InjectObjectPrototypeFinder.ts
  • tegg/core/metadata/src/impl/index.ts
  • tegg/core/metadata/src/model/ModuleDescriptor.ts
  • tegg/core/metadata/src/model/ProtoDescriptorHelper.ts
  • tegg/core/metadata/src/model/graph/GlobalGraph.ts
  • tegg/core/metadata/src/model/graph/ProtoGraphUtils.ts
  • tegg/core/metadata/src/model/graph/index.ts
  • tegg/core/metadata/test/ModuleDescriptorDumper.test.ts
  • tegg/core/runtime/src/impl/EggInnerObjectImpl.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnit.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitBuilder.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitInstance.ts
  • tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts
  • tegg/core/runtime/src/impl/index.ts
  • tegg/core/runtime/test/InnerObjectLoadUnit.test.ts
  • tegg/core/test-util/src/LoaderUtil.ts
  • tegg/core/types/package.json
  • tegg/core/types/src/common/ModuleConfig.ts
  • tegg/core/types/src/core-decorator/EggLifecycleProto.ts
  • tegg/core/types/src/core-decorator/InnerObjectProto.ts
  • tegg/core/types/src/core-decorator/Prototype.ts
  • tegg/core/types/src/core-decorator/enum/Qualifier.ts
  • tegg/core/types/src/core-decorator/index.ts
  • tegg/core/types/src/core-decorator/model/EggLifecycleInfo.ts
  • tegg/core/types/src/core-decorator/model/index.ts
  • tegg/core/types/src/metadata/model/ProtoDescriptor.ts
  • tegg/plugin/aop/package.json
  • tegg/plugin/aop/src/InnerObjects.ts
  • tegg/plugin/aop/src/app.ts
  • tegg/plugin/aop/src/lib/AopContextHook.ts
  • tegg/plugin/aop/test/aop.test.ts
  • tegg/plugin/aop/test/fixtures/apps/aop-app/modules/aop-module/Hello.ts
  • tegg/plugin/config/package.json
  • tegg/plugin/config/src/app.ts
  • tegg/plugin/config/src/lib/ConfigSourceLoadUnitHook.ts
  • tegg/plugin/config/src/lib/ModuleScanner.ts
  • tegg/plugin/config/test/ManifestModuleReference.test.ts
  • tegg/plugin/config/test/ModuleScanner.test.ts
  • tegg/plugin/config/test/ReadModule.test.ts
  • tegg/plugin/config/test/fixtures/framework-chain/app/package.json
  • tegg/plugin/config/test/fixtures/framework-cycle/app/package.json
  • tegg/plugin/config/test/fixtures/framework-module-json/app/package.json
  • tegg/plugin/config/test/fixtures/framework-same-path/app/config/module.json
  • tegg/plugin/config/test/fixtures/framework-same-path/app/package.json
  • tegg/plugin/dal/package.json
  • tegg/plugin/dal/src/app.ts
  • tegg/plugin/dal/src/app/extend/application.ts
  • tegg/plugin/dal/src/lib/DalModuleLoadUnitHook.ts
  • tegg/plugin/dal/src/lib/DalTableEggPrototypeHook.ts
  • tegg/plugin/dal/src/lib/DataSource.ts
  • tegg/plugin/dal/src/lib/MysqlDataSourceManager.ts
  • tegg/plugin/dal/src/lib/SqlMapManager.ts
  • tegg/plugin/dal/src/lib/TableModelManager.ts
  • tegg/plugin/dal/src/lib/TransactionPrototypeHook.ts
  • tegg/plugin/dal/test/transaction.test.ts
  • tegg/plugin/tegg/package.json
  • tegg/plugin/tegg/src/app.ts
  • tegg/plugin/tegg/src/lib/EggModuleLoader.ts
  • tegg/plugin/tegg/src/lib/ModuleConfigLoader.ts
  • tegg/plugin/tegg/src/lib/ModuleHandler.ts
  • tegg/plugin/tegg/test/BundledAppBoot.test.ts
  • tegg/plugin/tegg/test/ManifestCollection.test.ts
  • tegg/plugin/tegg/test/ModulePlugin.test.ts
  • tegg/plugin/tegg/test/MultiApp.test.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/config.default.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/module.json
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/plugin.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/HelloService.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/InnerRegistry.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/PluginHooks.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/package.json
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/package.json
  • tegg/plugin/tegg/test/fixtures/apps/multi-app-isolation/modules/counter-module/CounterService.ts
  • tegg/plugin/tegg/test/lib/EggModuleLoader.test.ts
  • tegg/plugin/tegg/test/lib/ModuleHandler.test.ts
  • tegg/standalone/standalone/README.md
  • tegg/standalone/standalone/package.json
  • tegg/standalone/standalone/src/ConfigSourceLoadUnitHook.ts
  • tegg/standalone/standalone/src/EggModuleLoader.ts
  • tegg/standalone/standalone/src/Runner.ts
  • tegg/standalone/standalone/src/StandaloneApp.ts
  • tegg/standalone/standalone/src/StandaloneInnerObject.ts
  • tegg/standalone/standalone/src/StandaloneInnerObjectProto.ts
  • tegg/standalone/standalone/src/StandaloneLoadUnit.ts
  • tegg/standalone/standalone/src/index.ts
  • tegg/standalone/standalone/src/main.ts
  • tegg/standalone/standalone/test/ModulePlugin.test.ts
  • tegg/standalone/standalone/test/fixtures/dal-manager-inject/foo.ts
  • tegg/standalone/standalone/test/fixtures/dal-manager-inject/package.json
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/FooEggContextHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/FooEggObjectHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/FooEggPrototypeHook.ts
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/foo.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/innerBar.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/package.json
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/foo.ts
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/innerBar.ts
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/FooLoadUnitInstanceHook.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/FooLoadUnitHook.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Runner.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/logger-option/foo.ts
  • tegg/standalone/standalone/test/fixtures/logger-option/package.json
  • tegg/standalone/standalone/test/index.test.ts
  • tegg/standalone/standalone/tsdown.config.ts
  • tools/egg-bundler/src/lib/ManifestLoader.ts
  • wiki/concepts/tegg-module-plugin.md
  • wiki/index.md
  • wiki/log.md
💤 Files with no reviewable changes (9)
  • tegg/plugin/dal/src/app/extend/application.ts
  • tegg/plugin/dal/package.json
  • tegg/standalone/standalone/src/StandaloneInnerObject.ts
  • tegg/standalone/standalone/src/StandaloneInnerObjectProto.ts
  • tegg/standalone/standalone/src/Runner.ts
  • tegg/standalone/standalone/src/ConfigSourceLoadUnitHook.ts
  • tegg/plugin/tegg/package.json
  • tegg/standalone/standalone/src/StandaloneLoadUnit.ts
  • tegg/plugin/dal/src/app.ts
✅ Files skipped from review due to trivial changes (31)
  • tegg/plugin/config/test/fixtures/framework-chain/app/package.json
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/package.json
  • tegg/core/types/src/core-decorator/model/index.ts
  • tegg/core/metadata/src/model/graph/index.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/FetchRouter.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/FooEggContextHook.ts
  • wiki/index.md
  • tegg/standalone/standalone/test/fixtures/dal-manager-inject/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/package.json
  • tegg/plugin/config/test/fixtures/framework-same-path/app/package.json
  • tegg/plugin/config/test/fixtures/framework-cycle/app/package.json
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/package.json
  • tegg/plugin/config/test/fixtures/framework-module-json/app/package.json
  • tegg/core/metadata/src/impl/EggPrototypeImpl.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/module.json
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/package.json
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/innerBar.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Foo.ts
  • tegg/plugin/config/src/lib/ConfigSourceLoadUnitHook.ts
  • tegg/standalone/standalone/tsdown.config.ts
  • tegg/core/metadata/src/impl/index.ts
  • tegg/standalone/standalone/test/fixtures/logger-option/package.json
  • tegg/core/types/src/core-decorator/enum/Qualifier.ts
  • tegg/core/metadata/test/ModuleDescriptorDumper.test.ts
  • tegg/plugin/aop/src/InnerObjects.ts
  • wiki/log.md
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/package.json
  • tegg/plugin/tegg/test/BundledAppBoot.test.ts
🚧 Files skipped from review as they are similar to previous changes (68)
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/FooEggPrototypeHook.ts
  • tegg/core/types/src/core-decorator/index.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/ControllerHook.ts
  • tegg/core/aop-runtime/src/AopGraphHookRegistrar.ts
  • tegg/standalone/standalone/test/fixtures/egg-context-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/FooLoadUnitInstanceHook.ts
  • tegg/core/aop-runtime/src/EggObjectAopHook.ts
  • tegg/core/types/src/core-decorator/Prototype.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/config.default.ts
  • tegg/core/aop-runtime/src/index.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/Runner.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/package.json
  • tegg/standalone/standalone/test/fixtures/load-unit-instance-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/foo.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/HelloService.ts
  • tegg/standalone/standalone/test/fixtures/logger-option/foo.ts
  • tegg/standalone/standalone/test/fixtures/invalid-inner-object-inject/foo.ts
  • tegg/core/types/src/core-decorator/InnerObjectProto.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/InnerRegistry.ts
  • tegg/core/loader/test/fixtures/modules/module-with-inner-object/HelloService.ts
  • tegg/core/aop-decorator/src/CrosscutAdviceFactory.ts
  • tegg/core/types/src/metadata/model/ProtoDescriptor.ts
  • tegg/plugin/aop/package.json
  • tegg/standalone/standalone/src/index.ts
  • tegg/core/core-decorator/src/decorator/index.ts
  • tegg/core/core-decorator/src/decorator/InnerObjectProto.ts
  • tegg/standalone/standalone/test/ModulePlugin.test.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/FooEggObjectHook.ts
  • tegg/core/core-decorator/src/decorator/EggLifecycleProto.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/package.json
  • tegg/plugin/aop/test/aop.test.ts
  • tegg/plugin/tegg/test/ModulePlugin.test.ts
  • tegg/core/loader/test/LoaderInnerObject.test.ts
  • tegg/core/metadata/src/model/ProtoDescriptorHelper.ts
  • tegg/core/metadata/src/model/graph/GlobalGraph.ts
  • tegg/plugin/config/package.json
  • tegg/core/aop-runtime/test/aop-runtime.test.ts
  • tegg/core/aop-runtime/package.json
  • tegg/core/metadata/src/impl/InjectObjectPrototypeFinder.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/modules/plugin-module/PluginHooks.ts
  • tegg/standalone/standalone/test/fixtures/inner-object-proto/innerBar.ts
  • tegg/plugin/config/test/ReadModule.test.ts
  • tegg/standalone/standalone/test/fixtures/load-unit-lifecycle-proto/FooLoadUnitHook.ts
  • tegg/plugin/tegg/test/fixtures/apps/module-plugin-app/config/plugin.ts
  • tegg/core/runtime/src/impl/ProvidedInnerObjectProto.ts
  • tegg/standalone/standalone/test/fixtures/egg-object-lifecycle-proto/Foo.ts
  • tegg/standalone/standalone/test/fixtures/egg-prototype-lifecycle-proto/Foo.ts
  • tegg/plugin/dal/src/lib/DalModuleLoadUnitHook.ts
  • tegg/core/types/package.json
  • tegg/core/aop-runtime/src/EggPrototypeCrossCutHook.ts
  • tegg/standalone/standalone/src/main.ts
  • tegg/core/test-util/src/LoaderUtil.ts
  • tegg/core/runtime/src/impl/index.ts
  • tegg/core/core-decorator/src/util/PrototypeUtil.ts
  • tegg/core/metadata/src/model/ModuleDescriptor.ts
  • tegg/core/metadata/src/impl/EggPrototypeBuilder.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnit.ts
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitInstance.ts
  • tegg/core/core-decorator/test/inner-object-decorators.test.ts
  • tegg/plugin/tegg/src/app.ts
  • tegg/standalone/standalone/package.json
  • tegg/core/runtime/src/impl/InnerObjectLoadUnitBuilder.ts
  • tegg/standalone/standalone/src/EggModuleLoader.ts
  • tegg/plugin/tegg/src/lib/ModuleHandler.ts
  • tegg/core/metadata/src/model/graph/ProtoGraphUtils.ts
  • tegg/core/runtime/src/impl/EggInnerObjectImpl.ts
  • tegg/standalone/standalone/src/StandaloneApp.ts
  • tegg/standalone/standalone/test/index.test.ts

Comment thread tegg/core/aop-runtime/src/AopContextAdviceRegistry.ts
Comment thread tegg/core/aop-runtime/src/LoadUnitAopHook.ts Outdated
Comment thread tegg/plugin/config/test/ModuleScanner.test.ts Outdated
Comment thread wiki/concepts/tegg-module-plugin.md Outdated
@gxkl
gxkl force-pushed the feat/module-plugin-core branch from facb7f1 to 80b9d49 Compare July 9, 2026 12:33
Copilot AI review requested due to automatic review settings July 9, 2026 12:39
gxkl and others added 26 commits July 13, 2026 17:57
Awaiting the per-request context destroy in StandaloneApp.run deadlocks
hosts that return a response whose body is drained by the caller after
run() returns (e.g. the service-worker pipes a streaming Response body
and keeps context protos alive via a BackgroundTaskHelper drain task).
ctx.destroy() drains those tasks, so awaiting it blocks run() from
returning the response the caller must consume first. Fire-and-forget it;
app-level teardown determinism stays with the awaited app.destroy().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
An app inline module path is not realpath'd while the same module
resolved from node_modules is, so under pnpm/symlinked layouts one
physical module produced two path strings and triggered a spurious
duplicate-name warning. Compare realpaths before warning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gxkl
gxkl force-pushed the feat/module-plugin-core branch from 38d5bd6 to b7a6718 Compare July 13, 2026 10:00
@gxkl
gxkl added this pull request to the merge queue Jul 13, 2026
Merged via the queue into next with commit 8d7f6c7 Jul 13, 2026
27 checks passed
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.

3 participants