@mandujs/core 0.54.32 → 0.55.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +654 -654
- package/package.json +106 -210
- package/scripts/postinstall-lock.ts +153 -153
- package/src/a11y/__tests__/run-audit.test.ts +333 -333
- package/src/a11y/fix-hints.ts +76 -76
- package/src/a11y/index.ts +18 -18
- package/src/a11y/run-audit.ts +15 -15
- package/src/a11y/types.ts +125 -125
- package/src/agent/__tests__/apply.test.ts +224 -0
- package/src/agent/__tests__/context.test.ts +97 -98
- package/src/agent/apply.ts +1031 -0
- package/src/agent/context.ts +552 -552
- package/src/agent/index.ts +4 -3
- package/src/agent/plan.ts +161 -243
- package/src/agent/repair.ts +239 -162
- package/src/agent/sync.ts +197 -198
- package/src/agent/types.ts +242 -94
- package/src/agent/verify.ts +55 -55
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +15 -5
- package/src/auth/__tests__/reset.test.ts +2 -2
- package/src/auth/__tests__/tokens.test.ts +274 -274
- package/src/auth/__tests__/verification.test.ts +274 -274
- package/src/auth/index.ts +76 -76
- package/src/auth/login.ts +225 -225
- package/src/auth/password.ts +14 -2
- package/src/auth/reset.ts +243 -243
- package/src/auth/tokens.ts +612 -612
- package/src/auth/verification.ts +253 -253
- package/src/brain/__tests__/redactor.test.ts +94 -94
- package/src/brain/adapters/__tests__/_helpers.ts +83 -83
- package/src/brain/adapters/__tests__/anthropic-oauth.test.ts +196 -196
- package/src/brain/adapters/__tests__/chatgpt-auth.test.ts +193 -193
- package/src/brain/adapters/__tests__/openai-oauth.test.ts +209 -209
- package/src/brain/adapters/__tests__/resolver.test.ts +143 -143
- package/src/brain/adapters/anthropic-oauth.ts +1 -1
- package/src/brain/adapters/chatgpt-auth.ts +300 -300
- package/src/brain/adapters/index.ts +319 -319
- package/src/brain/adapters/oauth-flow.ts +439 -439
- package/src/brain/consent.ts +240 -240
- package/src/brain/credentials.ts +396 -396
- package/src/brain/doctor/analyzer.ts +7 -7
- package/src/bundler/__snapshots__/build.test.ts.snap +5 -5
- package/src/bundler/__tests__/build-runner.ts +166 -166
- package/src/bundler/__tests__/client-boundary-transform.test.ts +524 -524
- package/src/bundler/__tests__/cold-start.test.ts +60 -60
- package/src/bundler/__tests__/css.test.ts +49 -20
- package/src/bundler/__tests__/dev-reliability.test.ts +619 -619
- package/src/bundler/__tests__/extended-watch.test.ts +711 -711
- package/src/bundler/__tests__/fast-refresh.test.ts +24 -24
- package/src/bundler/__tests__/generation.test.ts +447 -0
- package/src/bundler/__tests__/hdr.test.ts +24 -18
- package/src/bundler/__tests__/hmr-client.test.ts +62 -24
- package/src/bundler/__tests__/jsx-runtime-shim.test.ts +179 -140
- package/src/bundler/__tests__/manifest-schema.test.ts +305 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +42 -42
- package/src/bundler/__tests__/slot-dispatch.test.ts +573 -573
- package/src/bundler/__tests__/url-cap-and-slot-regex.test.ts +286 -286
- package/src/bundler/__tests__/vendor-cache.test.ts +455 -455
- package/src/bundler/analyzer.ts +15 -15
- package/src/bundler/budget.ts +404 -404
- package/src/bundler/build.test.ts +898 -915
- package/src/bundler/build.ts +113 -24
- package/src/bundler/client-boundary-transform.ts +977 -977
- package/src/bundler/css.ts +65 -44
- package/src/bundler/dev.ts +105 -73
- package/src/bundler/fast-refresh-preamble.ts +47 -47
- package/src/bundler/generation.ts +602 -0
- package/src/bundler/index.ts +3 -3
- package/src/bundler/manifest-schema.ts +55 -40
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +13 -13
- package/src/bundler/plugins/__tests__/react-compiler-config.test.ts +83 -83
- package/src/bundler/plugins/__tests__/react-compiler-lint.test.ts +110 -110
- package/src/bundler/plugins/block-generated-imports.ts +16 -15
- package/src/bundler/plugins/index.ts +83 -83
- package/src/bundler/plugins/react-compiler-config.ts +108 -108
- package/src/bundler/plugins/react-compiler-lint.ts +253 -253
- package/src/bundler/plugins/react-compiler.ts +162 -162
- package/src/bundler/prerender.ts +29 -9
- package/src/bundler/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +1 -1
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +58 -56
- package/src/bundler/vendor-cache-types.ts +130 -130
- package/src/bundler/vendor-cache.ts +526 -526
- package/src/change/snapshot.ts +18 -18
- package/src/client/Form.tsx +105 -105
- package/src/client/Link.tsx +9 -9
- package/src/client/__tests__/props-serialization.test.ts +37 -37
- package/src/client/__tests__/use-sse.test.ts +153 -153
- package/src/client/globals.ts +1 -1
- package/src/client/hooks.ts +362 -362
- package/src/client/hydrate.ts +2 -2
- package/src/client/index.ts +1 -1
- package/src/client/island.ts +79 -79
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/props-serialization.ts +233 -233
- package/src/client/runtime-entry.ts +598 -598
- package/src/client/runtime.ts +1 -1
- package/src/client/serialize.ts +50 -50
- package/src/client/use-fetch.ts +6 -6
- package/src/client/use-head.ts +197 -197
- package/src/client/use-sse.ts +378 -378
- package/src/client/window-state.ts +101 -101
- package/src/components/Image-compat.ts +3 -0
- package/src/components/Image.tsx +162 -162
- package/src/config/validate.ts +1 -1
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +9 -9
- package/src/content/content-layer.ts +7 -7
- package/src/content/data-store.ts +245 -245
- package/src/content/frontmatter.ts +189 -189
- package/src/content/generate-types.ts +1 -1
- package/src/content/index.ts +2 -2
- package/src/content/loader-context.ts +171 -171
- package/src/content/loaders/api.ts +216 -216
- package/src/content/loaders/file.ts +172 -172
- package/src/content/loaders/glob.ts +253 -253
- package/src/content/loaders/index.ts +34 -34
- package/src/content/loaders/types.ts +137 -137
- package/src/content/meta-store.ts +209 -209
- package/src/content/prebuild.test.ts +571 -571
- package/src/content/prebuild.ts +636 -636
- package/src/content/schema.ts +20 -20
- package/src/content/sidebar.ts +630 -630
- package/src/content/slug.ts +110 -110
- package/src/content/types.ts +282 -282
- package/src/content/watcher.ts +135 -135
- package/src/contract/client-safe.test.ts +42 -42
- package/src/contract/client-safe.ts +114 -114
- package/src/contract/define.ts +11 -11
- package/src/contract/index.ts +1 -1
- package/src/contract/normalize.test.ts +276 -276
- package/src/contract/normalize.ts +410 -410
- package/src/contract/registry.test.ts +206 -206
- package/src/contract/route-helpers.ts +1 -1
- package/src/contract/rpc.ts +443 -443
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +9 -9
- package/src/db/index.ts +2 -2
- package/src/db/migrations/history-table.ts +345 -345
- package/src/db/migrations/index.ts +3 -3
- package/src/db/migrations/lock.ts +324 -324
- package/src/db/migrations/runner.ts +650 -650
- package/src/deploy/cache.ts +140 -140
- package/src/deploy/compile/vercel.ts +344 -344
- package/src/deploy/index.ts +87 -87
- package/src/deploy/inference/brain.ts +268 -268
- package/src/deploy/inference/context.ts +82 -82
- package/src/deploy/inference/filling-extract.ts +245 -245
- package/src/deploy/inference/heuristic.ts +182 -182
- package/src/deploy/intent.ts +173 -173
- package/src/deploy/plan.ts +178 -178
- package/src/design/__tests__/agents-link.test.ts +109 -109
- package/src/design/__tests__/extract-patch-diff.test.ts +265 -265
- package/src/design/__tests__/lint.test.ts +110 -110
- package/src/design/__tests__/parser.test.ts +195 -195
- package/src/design/__tests__/tailwind-theme.test.ts +229 -229
- package/src/design/agents-link.ts +165 -165
- package/src/design/diff.ts +138 -138
- package/src/design/extract.ts +285 -285
- package/src/design/index.ts +102 -102
- package/src/design/lint.ts +209 -209
- package/src/design/parser.ts +555 -555
- package/src/design/patch.ts +241 -241
- package/src/design/scaffold.ts +147 -147
- package/src/design/tailwind-theme.ts +441 -441
- package/src/design/types.ts +210 -210
- package/src/desktop/__tests__/smoke.test.ts +2 -2
- package/src/desktop/__tests__/webview-fallback.test.ts +12 -32
- package/src/desktop/__tests__/window.test.ts +20 -99
- package/src/desktop/__tests__/worker.test.ts +266 -266
- package/src/desktop/index.ts +43 -43
- package/src/desktop/types.ts +158 -158
- package/src/desktop/webview-fallback.ts +17 -4
- package/src/desktop/window.ts +17 -8
- package/src/desktop/worker.ts +180 -180
- package/src/dev-error-overlay/__tests__/overlay-injector.test.ts +241 -241
- package/src/dev-error-overlay/index.ts +30 -30
- package/src/dev-error-overlay/overlay-injector.ts +243 -243
- package/src/dev-error-overlay/overlay-styles.ts +52 -52
- package/src/dev-error-overlay/types.ts +66 -66
- package/src/devtools/ai/context-builder.ts +375 -375
- package/src/devtools/ai/index.ts +25 -25
- package/src/devtools/ai/mcp-connector.ts +25 -25
- package/src/devtools/client/catchers/error-catcher.ts +344 -344
- package/src/devtools/client/catchers/index.ts +18 -18
- package/src/devtools/client/components/index.ts +39 -39
- package/src/devtools/client/components/mandu-character.tsx +331 -331
- package/src/devtools/client/components/panel/errors-panel.tsx +259 -259
- package/src/devtools/client/components/panel/guard-panel.tsx +30 -30
- package/src/devtools/client/components/panel/islands-panel.tsx +16 -16
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +1 -1
- package/src/devtools/client/components/panel/preview-panel.tsx +46 -46
- package/src/devtools/client/filters/context-filters.ts +282 -282
- package/src/devtools/client/filters/index.ts +16 -16
- package/src/devtools/client/index.ts +63 -63
- package/src/devtools/hook/create-hook.ts +207 -207
- package/src/devtools/hook/index.ts +13 -13
- package/src/devtools/index.ts +439 -439
- package/src/devtools/init.ts +265 -265
- package/src/devtools/protocol.ts +237 -237
- package/src/devtools/server/index.ts +17 -17
- package/src/devtools/types.ts +35 -35
- package/src/devtools/worker/index.ts +25 -25
- package/src/devtools/worker/redaction-worker.ts +233 -233
- package/src/diagnose/__tests__/checks.test.ts +136 -136
- package/src/diagnose/checks.ts +185 -185
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +10 -10
- package/src/diagnose/types.ts +53 -53
- package/src/email/__tests__/email.test.ts +355 -355
- package/src/email/index.ts +282 -282
- package/src/email/smtp.ts +64 -64
- package/src/error/domains.ts +265 -265
- package/src/error/types.ts +6 -6
- package/src/errors/extractor.ts +409 -409
- package/src/errors/index.ts +19 -19
- package/src/filling/__tests__/session-sqlite.test.ts +5 -1
- package/src/filling/auth.ts +308 -308
- package/src/filling/body-parse.test.ts +60 -60
- package/src/filling/cookie-codec.ts +5 -3
- package/src/filling/deps.ts +265 -265
- package/src/filling/head-method.test.ts +154 -154
- package/src/filling/session-sqlite.ts +617 -617
- package/src/filling/sse.ts +5 -5
- package/src/filling/ws.ts +78 -78
- package/src/generator/generate.ts +30 -30
- package/src/generator/index.ts +3 -3
- package/src/generator/templates.test.ts +48 -48
- package/src/generator/templates.ts +219 -219
- package/src/guard/__tests__/design-inline-class.test.ts +219 -219
- package/src/guard/__tests__/tsgolint-bridge.test.ts +347 -347
- package/src/guard/analyzer.ts +360 -360
- package/src/guard/auto-correct.ts +1 -1
- package/src/guard/check.ts +39 -24
- package/src/guard/config-guard.ts +13 -13
- package/src/guard/contract-guard.ts +9 -9
- package/src/guard/define-rule.ts +243 -243
- package/src/guard/design-inline-class.ts +393 -393
- package/src/guard/file-type.test.ts +24 -24
- package/src/guard/fs-routes-policy.ts +51 -51
- package/src/guard/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- package/src/guard/index.ts +11 -11
- package/src/guard/presets/atomic.ts +70 -70
- package/src/guard/presets/clean.ts +77 -77
- package/src/guard/presets/fsd.ts +79 -79
- package/src/guard/presets/hexagonal.ts +68 -68
- package/src/guard/reporter.ts +442 -442
- package/src/guard/rule-presets.ts +379 -379
- package/src/guard/semantic-slots.ts +1 -1
- package/src/guard/suggestions.ts +358 -358
- package/src/guard/tsgolint-bridge.ts +512 -512
- package/src/guard/types.ts +348 -348
- package/src/guard/watcher.ts +405 -405
- package/src/i18n/define.ts +126 -126
- package/src/i18n/index.ts +52 -52
- package/src/i18n/message-registry.ts +173 -173
- package/src/i18n/types.ts +112 -112
- package/src/id/__tests__/id.test.ts +3 -3
- package/src/id/index.ts +105 -105
- package/src/index.ts +9 -48
- package/src/internal/client-boundary.ts +266 -266
- package/src/internal/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -779
- package/src/kitchen/api/bundle-inspector.ts +179 -0
- package/src/kitchen/api/errors-grouping.ts +126 -126
- package/src/kitchen/api/file-api.ts +11 -11
- package/src/kitchen/kitchen-handler.ts +36 -0
- package/src/kitchen/kitchen-ui.ts +456 -0
- package/src/logging/index.ts +22 -22
- package/src/logging/transports.ts +365 -365
- package/src/middleware/bridge.ts +147 -147
- package/src/middleware/compose.ts +134 -134
- package/src/middleware/compress.ts +62 -62
- package/src/middleware/cors.ts +47 -47
- package/src/middleware/csrf.ts +328 -328
- package/src/middleware/define.ts +132 -132
- package/src/middleware/jwt.ts +134 -134
- package/src/middleware/logger.ts +58 -58
- package/src/middleware/oauth/__tests__/oauth.test.ts +1 -1
- package/src/middleware/oauth/index.ts +505 -505
- package/src/middleware/oauth/providers.ts +115 -115
- package/src/middleware/rate-limit/index.ts +522 -522
- package/src/middleware/rate-limit/sqlite-store.ts +382 -382
- package/src/middleware/scheduler-cron.ts +96 -96
- package/src/middleware/secure/__tests__/secure.test.ts +360 -360
- package/src/middleware/secure/csp.ts +193 -193
- package/src/middleware/session.ts +174 -174
- package/src/middleware/timeout.ts +55 -55
- package/src/observability/logger-adapter.ts +36 -36
- package/src/observability/sqlite-store.ts +254 -254
- package/src/openapi/generator.ts +1 -1
- package/src/openapi/openapi.test.ts +43 -43
- package/src/perf/__tests__/user-marks.test.ts +354 -354
- package/src/perf/index.ts +133 -133
- package/src/perf/user-marks.ts +1 -1
- package/src/plugins/__tests__/lifecycle-integration.test.ts +272 -272
- package/src/plugins/__tests__/runner.test.ts +409 -409
- package/src/plugins/define.ts +124 -124
- package/src/plugins/examples/dep-check-plugin.ts +80 -80
- package/src/plugins/examples/prerender-cache-plugin.ts +111 -111
- package/src/plugins/examples/sitemap-plugin.ts +65 -65
- package/src/plugins/runner.ts +361 -361
- package/src/plugins/types.ts +368 -368
- package/src/report/index.ts +1 -1
- package/src/resource/__tests__/generator.test.ts +7 -7
- package/src/resource/__tests__/schema.test.ts +14 -14
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +165 -165
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +146 -146
- package/src/resource/ddl/persistence-types.ts +218 -218
- package/src/resource/ddl/type-map.ts +223 -223
- package/src/resource/ddl/types.ts +232 -232
- package/src/resource/generator-repo.ts +630 -630
- package/src/resource/generator-schema.ts +11 -11
- package/src/resource/generators/slot.ts +72 -72
- package/src/resource/schema.ts +21 -21
- package/src/router/client-entry.test.ts +227 -227
- package/src/router/client-entry.ts +218 -218
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.test.ts +532 -532
- package/src/router/fs-routes.ts +53 -53
- package/src/router/fs-scanner.ts +216 -216
- package/src/router/fs-types.ts +19 -19
- package/src/router/route-source-analyzer.ts +521 -521
- package/src/routes/index.ts +74 -74
- package/src/routes/metadata-routes.ts +427 -427
- package/src/routes/types.ts +341 -341
- package/src/runtime/__tests__/devtools-adapter.test.ts +68 -68
- package/src/runtime/__tests__/error-boundary-redaction.test.ts +141 -141
- package/src/runtime/__tests__/hdr-client.test.ts +223 -223
- package/src/runtime/__tests__/http-errors.test.ts +117 -117
- package/src/runtime/__tests__/inline-client-hydration.test.ts +237 -237
- package/src/runtime/__tests__/not-found.test.ts +152 -152
- package/src/runtime/__tests__/observability-lifecycle.test.ts +103 -103
- package/src/runtime/__tests__/page-render-response.test.ts +517 -517
- package/src/runtime/__tests__/request-middleware.test.ts +70 -70
- package/src/runtime/__tests__/searchparams-page-props.test.ts +81 -81
- package/src/runtime/adapter.ts +47 -47
- package/src/runtime/boundary.tsx +252 -252
- package/src/runtime/cache.ts +494 -494
- package/src/runtime/compose.ts +222 -222
- package/src/runtime/devtools-adapter.ts +68 -68
- package/src/runtime/escape.ts +34 -34
- package/src/runtime/fast-refresh-runtime.ts +322 -322
- package/src/runtime/fast-refresh-types.ts +1 -1
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +30 -11
- package/src/runtime/http-errors.ts +113 -113
- package/src/runtime/image-handler.ts +1 -1
- package/src/runtime/lifecycle.ts +381 -381
- package/src/runtime/logger.test.ts +345 -345
- package/src/runtime/middleware.ts +264 -264
- package/src/runtime/not-found.ts +93 -93
- package/src/runtime/observability-lifecycle.ts +290 -290
- package/src/runtime/openapi-endpoint.ts +236 -236
- package/src/runtime/page-render-response.ts +287 -274
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/rate-limit.ts +1 -1
- package/src/runtime/redirect.ts +1 -1
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/request-middleware.ts +31 -31
- package/src/runtime/router.test.ts +4 -4
- package/src/runtime/router.ts +10 -10
- package/src/runtime/server.ts +127 -211
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/ssr.ts +43 -17
- package/src/runtime/static-files.ts +369 -289
- package/src/runtime/streaming-ssr.ts +219 -180
- package/src/runtime/trace.ts +144 -144
- package/src/scheduler/__tests__/scheduler.test.ts +12 -11
- package/src/scheduler/index.ts +11 -5
- package/src/scheduler/validate.ts +169 -169
- package/src/seo/index.ts +219 -219
- package/src/seo/integration/ssr.ts +306 -306
- package/src/seo/render/basic.ts +435 -435
- package/src/seo/render/index.ts +143 -143
- package/src/seo/render/jsonld.ts +539 -539
- package/src/seo/render/opengraph.ts +197 -197
- package/src/seo/render/robots.ts +116 -116
- package/src/seo/render/sitemap.ts +137 -137
- package/src/seo/render/twitter.ts +127 -127
- package/src/seo/resolve/opengraph.ts +143 -143
- package/src/seo/resolve/robots.ts +73 -73
- package/src/seo/resolve/title.ts +94 -94
- package/src/seo/resolve/twitter.ts +73 -73
- package/src/seo/resolve/url.ts +104 -104
- package/src/seo/routes/index.ts +290 -290
- package/src/seo/types.ts +588 -588
- package/src/slot/validator.ts +39 -39
- package/src/spec/schema.ts +35 -35
- package/src/storage/s3/__tests__/s3.test.ts +479 -479
- package/src/storage/s3/index.ts +412 -412
- package/src/testing/__tests__/assertions.test.ts +632 -632
- package/src/testing/__tests__/reporter.test.ts +454 -454
- package/src/testing/assertions.ts +986 -986
- package/src/testing/db.ts +157 -157
- package/src/testing/index.ts +9 -3
- package/src/testing/lcov.ts +192 -0
- package/src/testing/mocks.ts +203 -203
- package/src/testing/session.ts +190 -190
- package/src/types/branded.ts +56 -56
- package/src/types/index.ts +1 -1
- package/src/utils/safe-io.ts +188 -188
- package/src/utils/string-safe.ts +298 -298
- package/src/watcher/__tests__/watcher.test.ts +59 -59
- package/src/watcher/watcher.ts +61 -61
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan 18 P2-6 — Bundle inspector.
|
|
3
|
+
*
|
|
4
|
+
* Reads `.mandu/manifest.json` and adds disk-byte measurements per
|
|
5
|
+
* route bundle / island bundle / shared chunk so the Kitchen UI (and
|
|
6
|
+
* the supervisor context pack downstream) can answer "which island
|
|
7
|
+
* weighs the most" without each consumer re-stat'ing the same files.
|
|
8
|
+
*
|
|
9
|
+
* The manifest itself describes WHAT was emitted; this layer adds HOW
|
|
10
|
+
* MUCH. Stat failures are not fatal — a missing or torn file just
|
|
11
|
+
* shows up as 0 bytes so the rest of the report still renders.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from "fs/promises";
|
|
15
|
+
import path from "path";
|
|
16
|
+
import type { BundleManifest } from "../../bundler/types";
|
|
17
|
+
|
|
18
|
+
export interface BundleSizeEntry {
|
|
19
|
+
/** Public path declared by the manifest (e.g. /.mandu/client/home.js). */
|
|
20
|
+
path: string;
|
|
21
|
+
/** On-disk size in bytes; 0 when the file is missing or unreadable. */
|
|
22
|
+
bytes: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface BundleRouteEntry extends BundleSizeEntry {
|
|
26
|
+
routeId: string;
|
|
27
|
+
priority: string;
|
|
28
|
+
dependencies: string[];
|
|
29
|
+
css?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface BundleIslandEntry extends BundleSizeEntry {
|
|
33
|
+
islandId: string;
|
|
34
|
+
route: string;
|
|
35
|
+
priority: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BundleReport {
|
|
39
|
+
/** False when `.mandu/manifest.json` is missing or malformed. */
|
|
40
|
+
loaded: boolean;
|
|
41
|
+
/** Reason the report could not be loaded; absent on success. */
|
|
42
|
+
reason?: string;
|
|
43
|
+
manifest?: {
|
|
44
|
+
version: number;
|
|
45
|
+
buildTime: string;
|
|
46
|
+
env: "development" | "production";
|
|
47
|
+
};
|
|
48
|
+
shared?: {
|
|
49
|
+
runtime: BundleSizeEntry;
|
|
50
|
+
vendor: BundleSizeEntry;
|
|
51
|
+
router?: BundleSizeEntry;
|
|
52
|
+
};
|
|
53
|
+
bundles: BundleRouteEntry[];
|
|
54
|
+
islands: BundleIslandEntry[];
|
|
55
|
+
totals: {
|
|
56
|
+
totalBytes: number;
|
|
57
|
+
sharedBytes: number;
|
|
58
|
+
bundleBytes: number;
|
|
59
|
+
islandBytes: number;
|
|
60
|
+
bundleCount: number;
|
|
61
|
+
islandCount: number;
|
|
62
|
+
largestIsland?: { id: string; route: string; bytes: number };
|
|
63
|
+
largestBundle?: { routeId: string; bytes: number };
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function fileBytes(rootDir: string, urlPath: string | undefined): Promise<number> {
|
|
68
|
+
if (!urlPath) return 0;
|
|
69
|
+
const rel = urlPath.startsWith("/") ? urlPath.slice(1) : urlPath;
|
|
70
|
+
try {
|
|
71
|
+
const stat = await fs.stat(path.join(rootDir, rel));
|
|
72
|
+
return stat.isFile() ? stat.size : 0;
|
|
73
|
+
} catch {
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function readManifest(rootDir: string): Promise<BundleManifest | null> {
|
|
79
|
+
const manifestPath = path.join(rootDir, ".mandu", "manifest.json");
|
|
80
|
+
try {
|
|
81
|
+
const raw = await fs.readFile(manifestPath, "utf-8");
|
|
82
|
+
return JSON.parse(raw) as BundleManifest;
|
|
83
|
+
} catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function buildBundleReport(rootDir: string): Promise<BundleReport> {
|
|
89
|
+
const manifest = await readManifest(rootDir);
|
|
90
|
+
if (!manifest) {
|
|
91
|
+
return {
|
|
92
|
+
loaded: false,
|
|
93
|
+
reason: ".mandu/manifest.json is missing or malformed. Run `mandu build`.",
|
|
94
|
+
bundles: [],
|
|
95
|
+
islands: [],
|
|
96
|
+
totals: {
|
|
97
|
+
totalBytes: 0,
|
|
98
|
+
sharedBytes: 0,
|
|
99
|
+
bundleBytes: 0,
|
|
100
|
+
islandBytes: 0,
|
|
101
|
+
bundleCount: 0,
|
|
102
|
+
islandCount: 0,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const sharedRuntime: BundleSizeEntry = {
|
|
108
|
+
path: manifest.shared?.runtime ?? "",
|
|
109
|
+
bytes: await fileBytes(rootDir, manifest.shared?.runtime),
|
|
110
|
+
};
|
|
111
|
+
const sharedVendor: BundleSizeEntry = {
|
|
112
|
+
path: manifest.shared?.vendor ?? "",
|
|
113
|
+
bytes: await fileBytes(rootDir, manifest.shared?.vendor),
|
|
114
|
+
};
|
|
115
|
+
const sharedRouter: BundleSizeEntry | undefined = manifest.shared?.router
|
|
116
|
+
? { path: manifest.shared.router, bytes: await fileBytes(rootDir, manifest.shared.router) }
|
|
117
|
+
: undefined;
|
|
118
|
+
|
|
119
|
+
const bundleEntries: BundleRouteEntry[] = [];
|
|
120
|
+
for (const [routeId, entry] of Object.entries(manifest.bundles ?? {})) {
|
|
121
|
+
bundleEntries.push({
|
|
122
|
+
routeId,
|
|
123
|
+
path: entry.js,
|
|
124
|
+
bytes: await fileBytes(rootDir, entry.js),
|
|
125
|
+
priority: entry.priority,
|
|
126
|
+
dependencies: entry.dependencies,
|
|
127
|
+
css: entry.css,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const islandEntries: BundleIslandEntry[] = [];
|
|
132
|
+
for (const [islandId, entry] of Object.entries(manifest.islands ?? {})) {
|
|
133
|
+
islandEntries.push({
|
|
134
|
+
islandId,
|
|
135
|
+
path: entry.js,
|
|
136
|
+
bytes: await fileBytes(rootDir, entry.js),
|
|
137
|
+
route: entry.route,
|
|
138
|
+
priority: entry.priority,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Sort biggest-first — that's what the operator wants to see at the top.
|
|
143
|
+
bundleEntries.sort((a, b) => b.bytes - a.bytes);
|
|
144
|
+
islandEntries.sort((a, b) => b.bytes - a.bytes);
|
|
145
|
+
|
|
146
|
+
const sharedBytes = sharedRuntime.bytes + sharedVendor.bytes + (sharedRouter?.bytes ?? 0);
|
|
147
|
+
const bundleBytes = bundleEntries.reduce((sum, b) => sum + b.bytes, 0);
|
|
148
|
+
const islandBytes = islandEntries.reduce((sum, b) => sum + b.bytes, 0);
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
loaded: true,
|
|
152
|
+
manifest: {
|
|
153
|
+
version: manifest.version,
|
|
154
|
+
buildTime: manifest.buildTime,
|
|
155
|
+
env: manifest.env,
|
|
156
|
+
},
|
|
157
|
+
shared: {
|
|
158
|
+
runtime: sharedRuntime,
|
|
159
|
+
vendor: sharedVendor,
|
|
160
|
+
router: sharedRouter,
|
|
161
|
+
},
|
|
162
|
+
bundles: bundleEntries,
|
|
163
|
+
islands: islandEntries,
|
|
164
|
+
totals: {
|
|
165
|
+
totalBytes: sharedBytes + bundleBytes + islandBytes,
|
|
166
|
+
sharedBytes,
|
|
167
|
+
bundleBytes,
|
|
168
|
+
islandBytes,
|
|
169
|
+
bundleCount: bundleEntries.length,
|
|
170
|
+
islandCount: islandEntries.length,
|
|
171
|
+
largestIsland: islandEntries[0]
|
|
172
|
+
? { id: islandEntries[0].islandId, route: islandEntries[0].route, bytes: islandEntries[0].bytes }
|
|
173
|
+
: undefined,
|
|
174
|
+
largestBundle: bundleEntries[0]
|
|
175
|
+
? { routeId: bundleEntries[0].routeId, bytes: bundleEntries[0].bytes }
|
|
176
|
+
: undefined,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
@@ -1,126 +1,126 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plan 18 P1-4 — Error grouping for the Kitchen Errors panel.
|
|
3
|
-
*
|
|
4
|
-
* The Kitchen error ring buffer (`kitchen-handler.ts:storedErrors`) is a
|
|
5
|
-
* flat list. When the same hydration failure or unhandled rejection
|
|
6
|
-
* fires repeatedly on every render, the buffer fills with near-identical
|
|
7
|
-
* rows and the operator has to scroll through them to spot the count.
|
|
8
|
-
*
|
|
9
|
-
* `groupErrors()` collapses runs of "the same error" into one row with
|
|
10
|
-
* count / first-seen / last-seen / affected-sources / a representative
|
|
11
|
-
* sample. The group key is intentionally conservative so that
|
|
12
|
-
* superficially different errors stay separate:
|
|
13
|
-
*
|
|
14
|
-
* key = sha1(`${type}|${source}|${normalize(message)}`)
|
|
15
|
-
*
|
|
16
|
-
* `normalize` collapses obvious noise (numbers, UUIDs, file:line refs)
|
|
17
|
-
* but leaves stack-shape and message word order intact. This is a
|
|
18
|
-
* smaller hammer than full stack-trace fingerprinting — that lives
|
|
19
|
-
* elsewhere if we ever need it.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import crypto from "node:crypto";
|
|
23
|
-
|
|
24
|
-
export interface KitchenErrorLike {
|
|
25
|
-
id?: string;
|
|
26
|
-
type?: string;
|
|
27
|
-
severity?: string;
|
|
28
|
-
message: string;
|
|
29
|
-
stack?: string;
|
|
30
|
-
url?: string;
|
|
31
|
-
source?: string;
|
|
32
|
-
line?: number;
|
|
33
|
-
column?: number;
|
|
34
|
-
timestamp?: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface GroupedError {
|
|
38
|
-
/** Stable hash of (type, source, normalized message). */
|
|
39
|
-
key: string;
|
|
40
|
-
/** How many raw errors collapsed into this group. */
|
|
41
|
-
count: number;
|
|
42
|
-
/** Representative event — the most recent occurrence. */
|
|
43
|
-
sample: KitchenErrorLike;
|
|
44
|
-
/** Severity of the sample. Same across the group in practice. */
|
|
45
|
-
severity: string | undefined;
|
|
46
|
-
/** Earliest timestamp seen for this signature. */
|
|
47
|
-
firstSeen: number;
|
|
48
|
-
/** Latest timestamp seen for this signature. */
|
|
49
|
-
lastSeen: number;
|
|
50
|
-
/** Distinct source / file refs across the group, capped for transport. */
|
|
51
|
-
affectedSources: string[];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const NUM_RE = /\d{1,}/g;
|
|
55
|
-
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
|
|
56
|
-
const HEX_RE = /\b0x[0-9a-f]+\b/gi;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Replace noise that varies run-to-run but doesn't change which bug is
|
|
60
|
-
* being reported. Kept intentionally narrow so user-visible message
|
|
61
|
-
* structure stays recognizable for the operator.
|
|
62
|
-
*/
|
|
63
|
-
export function normalizeMessage(message: string): string {
|
|
64
|
-
return message
|
|
65
|
-
.replace(UUID_RE, "<UUID>")
|
|
66
|
-
.replace(HEX_RE, "<HEX>")
|
|
67
|
-
.replace(NUM_RE, "<N>")
|
|
68
|
-
.trim()
|
|
69
|
-
.toLowerCase();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function errorKey(err: KitchenErrorLike): string {
|
|
73
|
-
const parts = [
|
|
74
|
-
err.type ?? "runtime",
|
|
75
|
-
err.source ?? "unknown",
|
|
76
|
-
normalizeMessage(err.message ?? ""),
|
|
77
|
-
].join("|");
|
|
78
|
-
return crypto.createHash("sha1").update(parts).digest("hex").slice(0, 16);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface GroupOptions {
|
|
82
|
-
/** Cap `affectedSources` length in the response. Default 5. */
|
|
83
|
-
maxSourcesPerGroup?: number;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Collapse a flat error list into `GroupedError[]`, newest-group first.
|
|
88
|
-
* Stable: a single error becomes a group of size 1.
|
|
89
|
-
*/
|
|
90
|
-
export function groupErrors(errors: readonly KitchenErrorLike[], options: GroupOptions = {}): GroupedError[] {
|
|
91
|
-
const maxSources = options.maxSourcesPerGroup ?? 5;
|
|
92
|
-
const byKey = new Map<string, GroupedError>();
|
|
93
|
-
|
|
94
|
-
for (const err of errors) {
|
|
95
|
-
const key = errorKey(err);
|
|
96
|
-
const ts = err.timestamp ?? 0;
|
|
97
|
-
const existing = byKey.get(key);
|
|
98
|
-
if (!existing) {
|
|
99
|
-
const sources = err.source ? [err.source] : [];
|
|
100
|
-
byKey.set(key, {
|
|
101
|
-
key,
|
|
102
|
-
count: 1,
|
|
103
|
-
sample: err,
|
|
104
|
-
severity: err.severity,
|
|
105
|
-
firstSeen: ts,
|
|
106
|
-
lastSeen: ts,
|
|
107
|
-
affectedSources: sources,
|
|
108
|
-
});
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
existing.count += 1;
|
|
112
|
-
if (ts < existing.firstSeen || existing.firstSeen === 0) existing.firstSeen = ts;
|
|
113
|
-
if (ts > existing.lastSeen) {
|
|
114
|
-
existing.lastSeen = ts;
|
|
115
|
-
existing.sample = err; // newest wins so the operator sees the freshest message
|
|
116
|
-
}
|
|
117
|
-
if (err.source && !existing.affectedSources.includes(err.source)) {
|
|
118
|
-
if (existing.affectedSources.length < maxSources) {
|
|
119
|
-
existing.affectedSources.push(err.source);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Newest groups first — the operator wants the most recent regression up top.
|
|
125
|
-
return Array.from(byKey.values()).sort((a, b) => b.lastSeen - a.lastSeen);
|
|
126
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Plan 18 P1-4 — Error grouping for the Kitchen Errors panel.
|
|
3
|
+
*
|
|
4
|
+
* The Kitchen error ring buffer (`kitchen-handler.ts:storedErrors`) is a
|
|
5
|
+
* flat list. When the same hydration failure or unhandled rejection
|
|
6
|
+
* fires repeatedly on every render, the buffer fills with near-identical
|
|
7
|
+
* rows and the operator has to scroll through them to spot the count.
|
|
8
|
+
*
|
|
9
|
+
* `groupErrors()` collapses runs of "the same error" into one row with
|
|
10
|
+
* count / first-seen / last-seen / affected-sources / a representative
|
|
11
|
+
* sample. The group key is intentionally conservative so that
|
|
12
|
+
* superficially different errors stay separate:
|
|
13
|
+
*
|
|
14
|
+
* key = sha1(`${type}|${source}|${normalize(message)}`)
|
|
15
|
+
*
|
|
16
|
+
* `normalize` collapses obvious noise (numbers, UUIDs, file:line refs)
|
|
17
|
+
* but leaves stack-shape and message word order intact. This is a
|
|
18
|
+
* smaller hammer than full stack-trace fingerprinting — that lives
|
|
19
|
+
* elsewhere if we ever need it.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import crypto from "node:crypto";
|
|
23
|
+
|
|
24
|
+
export interface KitchenErrorLike {
|
|
25
|
+
id?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
severity?: string;
|
|
28
|
+
message: string;
|
|
29
|
+
stack?: string;
|
|
30
|
+
url?: string;
|
|
31
|
+
source?: string;
|
|
32
|
+
line?: number;
|
|
33
|
+
column?: number;
|
|
34
|
+
timestamp?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface GroupedError {
|
|
38
|
+
/** Stable hash of (type, source, normalized message). */
|
|
39
|
+
key: string;
|
|
40
|
+
/** How many raw errors collapsed into this group. */
|
|
41
|
+
count: number;
|
|
42
|
+
/** Representative event — the most recent occurrence. */
|
|
43
|
+
sample: KitchenErrorLike;
|
|
44
|
+
/** Severity of the sample. Same across the group in practice. */
|
|
45
|
+
severity: string | undefined;
|
|
46
|
+
/** Earliest timestamp seen for this signature. */
|
|
47
|
+
firstSeen: number;
|
|
48
|
+
/** Latest timestamp seen for this signature. */
|
|
49
|
+
lastSeen: number;
|
|
50
|
+
/** Distinct source / file refs across the group, capped for transport. */
|
|
51
|
+
affectedSources: string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const NUM_RE = /\d{1,}/g;
|
|
55
|
+
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
|
|
56
|
+
const HEX_RE = /\b0x[0-9a-f]+\b/gi;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Replace noise that varies run-to-run but doesn't change which bug is
|
|
60
|
+
* being reported. Kept intentionally narrow so user-visible message
|
|
61
|
+
* structure stays recognizable for the operator.
|
|
62
|
+
*/
|
|
63
|
+
export function normalizeMessage(message: string): string {
|
|
64
|
+
return message
|
|
65
|
+
.replace(UUID_RE, "<UUID>")
|
|
66
|
+
.replace(HEX_RE, "<HEX>")
|
|
67
|
+
.replace(NUM_RE, "<N>")
|
|
68
|
+
.trim()
|
|
69
|
+
.toLowerCase();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function errorKey(err: KitchenErrorLike): string {
|
|
73
|
+
const parts = [
|
|
74
|
+
err.type ?? "runtime",
|
|
75
|
+
err.source ?? "unknown",
|
|
76
|
+
normalizeMessage(err.message ?? ""),
|
|
77
|
+
].join("|");
|
|
78
|
+
return crypto.createHash("sha1").update(parts).digest("hex").slice(0, 16);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface GroupOptions {
|
|
82
|
+
/** Cap `affectedSources` length in the response. Default 5. */
|
|
83
|
+
maxSourcesPerGroup?: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Collapse a flat error list into `GroupedError[]`, newest-group first.
|
|
88
|
+
* Stable: a single error becomes a group of size 1.
|
|
89
|
+
*/
|
|
90
|
+
export function groupErrors(errors: readonly KitchenErrorLike[], options: GroupOptions = {}): GroupedError[] {
|
|
91
|
+
const maxSources = options.maxSourcesPerGroup ?? 5;
|
|
92
|
+
const byKey = new Map<string, GroupedError>();
|
|
93
|
+
|
|
94
|
+
for (const err of errors) {
|
|
95
|
+
const key = errorKey(err);
|
|
96
|
+
const ts = err.timestamp ?? 0;
|
|
97
|
+
const existing = byKey.get(key);
|
|
98
|
+
if (!existing) {
|
|
99
|
+
const sources = err.source ? [err.source] : [];
|
|
100
|
+
byKey.set(key, {
|
|
101
|
+
key,
|
|
102
|
+
count: 1,
|
|
103
|
+
sample: err,
|
|
104
|
+
severity: err.severity,
|
|
105
|
+
firstSeen: ts,
|
|
106
|
+
lastSeen: ts,
|
|
107
|
+
affectedSources: sources,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
existing.count += 1;
|
|
112
|
+
if (ts < existing.firstSeen || existing.firstSeen === 0) existing.firstSeen = ts;
|
|
113
|
+
if (ts > existing.lastSeen) {
|
|
114
|
+
existing.lastSeen = ts;
|
|
115
|
+
existing.sample = err; // newest wins so the operator sees the freshest message
|
|
116
|
+
}
|
|
117
|
+
if (err.source && !existing.affectedSources.includes(err.source)) {
|
|
118
|
+
if (existing.affectedSources.length < maxSources) {
|
|
119
|
+
existing.affectedSources.push(err.source);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Newest groups first — the operator wants the most recent regression up top.
|
|
125
|
+
return Array.from(byKey.values()).sort((a, b) => b.lastSeen - a.lastSeen);
|
|
126
|
+
}
|
|
@@ -229,17 +229,17 @@ export class FileAPI {
|
|
|
229
229
|
for (const line of stdout.split("\n")) {
|
|
230
230
|
if (!line.trim()) continue;
|
|
231
231
|
|
|
232
|
-
const statusCode = line.substring(0, 2);
|
|
233
|
-
const gitFilePath = line.substring(3).trim();
|
|
234
|
-
const filePath = this.getProjectRelativePath(gitFilePath, gitRoot);
|
|
235
|
-
if (!filePath || filePath === ".") {
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
changes.push({
|
|
240
|
-
filePath,
|
|
241
|
-
status: parseGitStatus(statusCode),
|
|
242
|
-
});
|
|
232
|
+
const statusCode = line.substring(0, 2);
|
|
233
|
+
const gitFilePath = line.substring(3).trim();
|
|
234
|
+
const filePath = this.getProjectRelativePath(gitFilePath, gitRoot);
|
|
235
|
+
if (!filePath || filePath === ".") {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
changes.push({
|
|
240
|
+
filePath,
|
|
241
|
+
status: parseGitStatus(statusCode),
|
|
242
|
+
});
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
return changes;
|
|
@@ -16,6 +16,7 @@ import { GuardDecisionManager } from "./api/guard-decisions";
|
|
|
16
16
|
import { ContractPlaygroundAPI } from "./api/contract-api";
|
|
17
17
|
import { handleAgentContextRequest } from "./api/agent-devtools-api";
|
|
18
18
|
import { groupErrors } from "./api/errors-grouping";
|
|
19
|
+
import { buildBundleReport } from "./api/bundle-inspector";
|
|
19
20
|
import type { BundleManifest } from "../bundler/types";
|
|
20
21
|
import type { DiagnoseReport } from "../diagnose/types";
|
|
21
22
|
import { runExtendedDiagnose } from "../diagnose/run";
|
|
@@ -575,6 +576,41 @@ export class KitchenHandler {
|
|
|
575
576
|
return Response.json({ errors: storedErrors, count: storedErrors.length });
|
|
576
577
|
}
|
|
577
578
|
|
|
579
|
+
// Plan 18 P2-6 — Bundle inspector. Reads .mandu/manifest.json and
|
|
580
|
+
// adds byte sizes from disk so the operator can see at a glance
|
|
581
|
+
// which island is largest, which routes have CSS chunks, and how
|
|
582
|
+
// big the shared runtime / vendor / router bundles are.
|
|
583
|
+
if (sub === "/api/bundle" && req.method === "GET") {
|
|
584
|
+
const report = await buildBundleReport(this.options.rootDir);
|
|
585
|
+
return Response.json(report);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Plan 18 P2-5 — Diagnose panel data. Runs `runExtendedDiagnose`
|
|
589
|
+
// and returns the structured report so the Kitchen UI can render
|
|
590
|
+
// every rule (manifest_freshness / nested_internal_core /
|
|
591
|
+
// package_export_gaps / a11y_hints / ...) on one screen with the
|
|
592
|
+
// suggestion line attached. Same source as P0-2's signal collector
|
|
593
|
+
// but always fresh (no caching) so the operator's "Refresh" press
|
|
594
|
+
// reflects the latest state.
|
|
595
|
+
if (sub === "/api/diagnose" && req.method === "GET") {
|
|
596
|
+
const report = await runDiagnoseSignal(this.options.rootDir);
|
|
597
|
+
if (!report) {
|
|
598
|
+
return Response.json({
|
|
599
|
+
healthy: false,
|
|
600
|
+
errorCount: 1,
|
|
601
|
+
warningCount: 0,
|
|
602
|
+
checks: [{
|
|
603
|
+
ok: false,
|
|
604
|
+
rule: "diagnose_runner",
|
|
605
|
+
severity: "error",
|
|
606
|
+
message: "Diagnose runner failed to execute. See dev server logs.",
|
|
607
|
+
}],
|
|
608
|
+
summary: { total: 1, passed: 0, failed: 1 },
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
return Response.json(report);
|
|
612
|
+
}
|
|
613
|
+
|
|
578
614
|
// Plan 18 P1-4 — Errors panel grouped view. Collapses identical
|
|
579
615
|
// signatures into one row with count/firstSeen/lastSeen/affected
|
|
580
616
|
// sources. The operator no longer scrolls past five copies of the
|