@mandujs/core 0.53.3 → 0.54.0
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 +2 -2
- 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 +394 -394
- package/src/a11y/types.ts +125 -125
- package/src/auth/__tests__/login.test.ts +1 -1
- package/src/auth/__tests__/password.test.ts +122 -122
- 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 +120 -120
- 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/bundler/__tests__/build-runner.ts +113 -113
- 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 +10 -10
- package/src/bundler/__tests__/hdr.test.ts +353 -353
- package/src/bundler/__tests__/hmr-client.test.ts +532 -532
- package/src/bundler/__tests__/manifest-schema.test.ts +266 -266
- package/src/bundler/__tests__/prod-smoke.test.ts +138 -138
- package/src/bundler/__tests__/reverse-import-graph.test.ts +519 -519
- 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/budget.ts +404 -404
- package/src/bundler/build.test.ts +179 -179
- package/src/bundler/build.ts +55 -55
- package/src/bundler/dev.ts +42 -42
- package/src/bundler/manifest-schema.ts +301 -301
- package/src/bundler/plugins/__tests__/block-generated-imports.test.ts +263 -263
- 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 +155 -155
- 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/reverse-import-graph.ts +339 -339
- package/src/bundler/safe-build.test.ts +201 -201
- package/src/bundler/safe-build.ts +103 -103
- package/src/bundler/scenario-matrix.ts +229 -229
- package/src/bundler/types.ts +10 -10
- 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__/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 +340 -340
- package/src/client/prefetch-helper.ts +55 -55
- package/src/client/router.ts +11 -11
- package/src/client/runtime.ts +47 -47
- package/src/client/serialize.ts +404 -404
- 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.tsx +162 -162
- package/src/config/validate.ts +3 -3
- package/src/config/watcher.ts +311 -311
- package/src/constants.ts +40 -40
- package/src/content/collection.ts +8 -8
- 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/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/schema.ts +48 -48
- package/src/contract/types.ts +58 -58
- package/src/db/__tests__/db.test.ts +482 -482
- package/src/db/index.ts +138 -138
- 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 +182 -182
- 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__/webview-fallback.test.ts +254 -254
- package/src/desktop/__tests__/window.test.ts +248 -248
- 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/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/overlay.tsx +368 -368
- 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 +320 -320
- package/src/devtools/client/components/panel/network-panel.tsx +291 -291
- package/src/devtools/client/components/panel/panel-container.tsx +500 -500
- 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/client/persistence.ts +335 -335
- 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/server/source-context.ts +450 -450
- 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/devtools/worker/worker-manager.ts +410 -410
- package/src/diagnose/__tests__/checks.test.ts +451 -451
- package/src/diagnose/checks.ts +832 -832
- package/src/diagnose/index.ts +17 -17
- package/src/diagnose/run.ts +93 -93
- 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/result.ts +60 -60
- 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 +454 -454
- package/src/filling/auth.ts +308 -308
- package/src/filling/cookie-codec.ts +299 -299
- package/src/filling/deps.ts +265 -265
- 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/index.ts +3 -3
- 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/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/graph.ts +1 -1
- package/src/guard/healing.ts +36 -36
- 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/index.ts +105 -105
- package/src/index.ts +2 -2
- package/src/kitchen/api/agent-devtools-api.ts +779 -544
- package/src/kitchen/api/errors-grouping.ts +126 -0
- package/src/kitchen/kitchen-handler.ts +192 -63
- package/src/kitchen/kitchen-ui.ts +842 -464
- 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/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 +32 -32
- package/src/resource/ddl/__tests__/diff.test.ts +639 -639
- package/src/resource/ddl/__tests__/emit.test.ts +823 -823
- package/src/resource/ddl/__tests__/snapshot.test.ts +499 -499
- package/src/resource/ddl/emit.ts +559 -559
- 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/schema.ts +1 -1
- package/src/router/fs-patterns.test.ts +96 -96
- package/src/router/fs-routes.ts +6 -6
- 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__/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__/not-found.test.ts +152 -152
- 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/fast-refresh-runtime.ts +322 -322
- package/src/runtime/handler.ts +65 -65
- package/src/runtime/handlers.ts +300 -300
- 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/openapi-endpoint.ts +236 -236
- package/src/runtime/ppr.ts +74 -74
- package/src/runtime/registry.ts +171 -171
- package/src/runtime/router.ts +105 -105
- package/src/runtime/server.ts +67 -67
- package/src/runtime/shims.ts +48 -48
- package/src/runtime/trace.ts +144 -144
- 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/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/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/watcher.ts +18 -18
|
@@ -57,13 +57,14 @@ export function renderKitchenHTML(): string {
|
|
|
57
57
|
</div>
|
|
58
58
|
</section>
|
|
59
59
|
|
|
60
|
-
<nav class="tabs">
|
|
61
|
-
<button class="tab" data-panel="activity">Activity</button>
|
|
62
|
-
<button class="tab" data-panel="
|
|
63
|
-
<button class="tab
|
|
64
|
-
<button class="tab" data-panel="
|
|
65
|
-
<button class="tab" data-panel="
|
|
66
|
-
<button class="tab" data-panel="
|
|
60
|
+
<nav class="tabs">
|
|
61
|
+
<button class="tab" data-panel="activity">Activity</button>
|
|
62
|
+
<button class="tab" data-panel="errors">Errors</button>
|
|
63
|
+
<button class="tab" data-panel="agent">Agent</button>
|
|
64
|
+
<button class="tab active" data-panel="routes">Routes</button>
|
|
65
|
+
<button class="tab" data-panel="guard">Guard</button>
|
|
66
|
+
<button class="tab" data-panel="preview">Preview</button>
|
|
67
|
+
<button class="tab" data-panel="contracts">Contracts</button>
|
|
67
68
|
<button class="tab" data-panel="requests">Requests</button>
|
|
68
69
|
<button class="tab" data-panel="mcp-activity">MCP</button>
|
|
69
70
|
<button class="tab" data-panel="cache">Cache</button>
|
|
@@ -71,37 +72,67 @@ export function renderKitchenHTML(): string {
|
|
|
71
72
|
</nav>
|
|
72
73
|
|
|
73
74
|
<main class="panels">
|
|
74
|
-
<section id="panel-activity" class="panel">
|
|
75
|
-
<div class="panel-header">
|
|
76
|
-
<div>
|
|
77
|
-
<h2>Activity Stream</h2>
|
|
78
|
-
<p class="panel-subtitle">Recent
|
|
75
|
+
<section id="panel-activity" class="panel">
|
|
76
|
+
<div class="panel-header">
|
|
77
|
+
<div>
|
|
78
|
+
<h2>Activity Stream</h2>
|
|
79
|
+
<p class="panel-subtitle">Recent eventBus signals — switch the chips to surface build, cache, ws, and ate categories that are normally invisible.</p>
|
|
79
80
|
</div>
|
|
80
81
|
<button id="clear-activity" class="btn-sm">Clear</button>
|
|
81
82
|
</div>
|
|
83
|
+
<div id="activity-filter" class="activity-filter" role="tablist" aria-label="Activity category">
|
|
84
|
+
<button class="chip active" data-type="all">All</button>
|
|
85
|
+
<button class="chip" data-type="mcp">MCP</button>
|
|
86
|
+
<button class="chip" data-type="http">HTTP</button>
|
|
87
|
+
<button class="chip" data-type="guard">Guard</button>
|
|
88
|
+
<button class="chip" data-type="build">Build</button>
|
|
89
|
+
<button class="chip" data-type="cache">Cache</button>
|
|
90
|
+
<button class="chip" data-type="ws">WS</button>
|
|
91
|
+
<button class="chip" data-type="ate">ATE</button>
|
|
92
|
+
<button class="chip" data-type="error">Error</button>
|
|
93
|
+
</div>
|
|
82
94
|
<div id="activity-list" class="activity-list">
|
|
83
|
-
<div class="empty-state">Waiting for
|
|
84
|
-
</div>
|
|
85
|
-
</section>
|
|
86
|
-
|
|
87
|
-
<section id="panel-
|
|
88
|
-
<div class="panel-header">
|
|
89
|
-
<div>
|
|
90
|
-
<h2>
|
|
91
|
-
<p class="panel-subtitle">
|
|
92
|
-
</div>
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</div>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<div class="
|
|
102
|
-
<div>
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
<div class="empty-state">Waiting for activity...</div>
|
|
96
|
+
</div>
|
|
97
|
+
</section>
|
|
98
|
+
|
|
99
|
+
<section id="panel-errors" class="panel">
|
|
100
|
+
<div class="panel-header">
|
|
101
|
+
<div>
|
|
102
|
+
<h2>Errors</h2>
|
|
103
|
+
<p class="panel-subtitle">Browser errors grouped by signature — repeated occurrences collapse into one row with count, first/last seen, and affected sources.</p>
|
|
104
|
+
</div>
|
|
105
|
+
<div style="display:flex;gap:6px;">
|
|
106
|
+
<button id="refresh-errors" class="btn-sm">Refresh</button>
|
|
107
|
+
<button id="clear-errors" class="btn-sm">Clear</button>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<div id="errors-summary" class="errors-summary">
|
|
111
|
+
<span id="errors-summary-text">Open Errors to see grouped browser errors.</span>
|
|
112
|
+
</div>
|
|
113
|
+
<div id="errors-list" class="errors-list">
|
|
114
|
+
<div class="empty-state">No errors captured yet.</div>
|
|
115
|
+
</div>
|
|
116
|
+
</section>
|
|
117
|
+
|
|
118
|
+
<section id="panel-agent" class="panel">
|
|
119
|
+
<div class="panel-header">
|
|
120
|
+
<div>
|
|
121
|
+
<h2>Agent Supervisor</h2>
|
|
122
|
+
<p class="panel-subtitle">Situation brief, tool routing, prompt pack, and next safe action for supervised agents.</p>
|
|
123
|
+
</div>
|
|
124
|
+
<button id="refresh-agent" class="btn-sm">Refresh</button>
|
|
125
|
+
</div>
|
|
126
|
+
<div id="agent-content" class="agent-content">
|
|
127
|
+
<div class="empty-state">Open Agent to build a context pack.</div>
|
|
128
|
+
</div>
|
|
129
|
+
</section>
|
|
130
|
+
|
|
131
|
+
<section id="panel-routes" class="panel active">
|
|
132
|
+
<div class="panel-header">
|
|
133
|
+
<div>
|
|
134
|
+
<h2>Routes</h2>
|
|
135
|
+
<p class="panel-subtitle">Current filesystem routes, slots, contracts, and hydration hints.</p>
|
|
105
136
|
</div>
|
|
106
137
|
<div id="routes-summary" class="summary"></div>
|
|
107
138
|
</div>
|
|
@@ -241,10 +272,19 @@ export function renderKitchenHTML(): string {
|
|
|
241
272
|
const CSS = /* css */ `
|
|
242
273
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
243
274
|
|
|
275
|
+
/*
|
|
276
|
+
* Plan 18 DA-1 — the legacy dark-tool palette below is intentionally
|
|
277
|
+
* redirected to the Stitch tokens defined at the bottom of this file.
|
|
278
|
+
* Component layout / spacing / interaction is preserved; only the
|
|
279
|
+
* literal colors and the font family swap. The :root block (later in
|
|
280
|
+
* the cascade) wins, so any later override stays effective.
|
|
281
|
+
*/
|
|
282
|
+
|
|
283
|
+
body.legacy-dark-tool-shell, /* kept as a hook for future toggle */
|
|
244
284
|
body {
|
|
245
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
246
|
-
background: #
|
|
247
|
-
color: #
|
|
285
|
+
font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
|
|
286
|
+
background: var(--bg, #FFFDF5);
|
|
287
|
+
color: var(--ink, #4A3222);
|
|
248
288
|
min-height: 100vh;
|
|
249
289
|
}
|
|
250
290
|
|
|
@@ -253,8 +293,8 @@ const CSS = /* css */ `
|
|
|
253
293
|
align-items: center;
|
|
254
294
|
justify-content: space-between;
|
|
255
295
|
padding: 12px 20px;
|
|
256
|
-
background: #
|
|
257
|
-
border-bottom: 1px solid #
|
|
296
|
+
background: var(--surface-strong, #FBF6EC);
|
|
297
|
+
border-bottom: 1px solid var(--line, #4A3222);
|
|
258
298
|
}
|
|
259
299
|
|
|
260
300
|
.logo {
|
|
@@ -262,7 +302,8 @@ const CSS = /* css */ `
|
|
|
262
302
|
align-items: center;
|
|
263
303
|
gap: 8px;
|
|
264
304
|
font-size: 18px;
|
|
265
|
-
font-weight:
|
|
305
|
+
font-weight: 700;
|
|
306
|
+
font-family: var(--font-display, var(--font-sans));
|
|
266
307
|
}
|
|
267
308
|
|
|
268
309
|
.logo-icon { font-size: 24px; }
|
|
@@ -272,7 +313,7 @@ const CSS = /* css */ `
|
|
|
272
313
|
align-items: center;
|
|
273
314
|
gap: 6px;
|
|
274
315
|
font-size: 13px;
|
|
275
|
-
color: #
|
|
316
|
+
color: var(--muted, #7A6B5D);
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
.status-dot {
|
|
@@ -282,15 +323,15 @@ const CSS = /* css */ `
|
|
|
282
323
|
transition: background 0.3s;
|
|
283
324
|
}
|
|
284
325
|
|
|
285
|
-
.status-dot.connected { background: #
|
|
286
|
-
.status-dot.disconnected { background: #
|
|
287
|
-
.status-dot.connecting { background: #
|
|
326
|
+
.status-dot.connected { background: var(--success, #6B9E47); }
|
|
327
|
+
.status-dot.disconnected { background: var(--danger, #C85450); }
|
|
328
|
+
.status-dot.connecting { background: var(--warning, #E8A93A); }
|
|
288
329
|
|
|
289
330
|
.tabs {
|
|
290
331
|
display: flex;
|
|
291
332
|
gap: 0;
|
|
292
|
-
background: #
|
|
293
|
-
border-bottom: 1px solid #
|
|
333
|
+
background: var(--surface-strong, #FBF6EC);
|
|
334
|
+
border-bottom: 1px solid var(--line, #4A3222);
|
|
294
335
|
padding: 0 20px;
|
|
295
336
|
}
|
|
296
337
|
|
|
@@ -298,17 +339,20 @@ const CSS = /* css */ `
|
|
|
298
339
|
padding: 10px 20px;
|
|
299
340
|
background: none;
|
|
300
341
|
border: none;
|
|
301
|
-
color: #
|
|
342
|
+
color: var(--muted, #7A6B5D);
|
|
302
343
|
font-size: 14px;
|
|
344
|
+
font-family: var(--font-sans);
|
|
345
|
+
font-weight: 500;
|
|
303
346
|
cursor: pointer;
|
|
304
347
|
border-bottom: 2px solid transparent;
|
|
305
348
|
transition: all 0.2s;
|
|
306
349
|
}
|
|
307
350
|
|
|
308
|
-
.tab:hover { color: #
|
|
351
|
+
.tab:hover { color: var(--ink, #4A3222); }
|
|
309
352
|
.tab.active {
|
|
310
|
-
color: #
|
|
311
|
-
border-bottom-color: #
|
|
353
|
+
color: var(--accent, #FF8C66);
|
|
354
|
+
border-bottom-color: var(--accent, #FF8C66);
|
|
355
|
+
font-weight: 700;
|
|
312
356
|
}
|
|
313
357
|
|
|
314
358
|
.panels { padding: 16px 20px; }
|
|
@@ -328,38 +372,203 @@ const CSS = /* css */ `
|
|
|
328
372
|
font-weight: 600;
|
|
329
373
|
}
|
|
330
374
|
|
|
375
|
+
/*
|
|
376
|
+
* Stitch primary button — hard shadow + bold + larger radius.
|
|
377
|
+
* Hover lifts: shadow 0 + translate so the surface "presses" into the
|
|
378
|
+
* shadow slot. Mirrors the .btn-hard pattern in mandujs.com globals.css.
|
|
379
|
+
*/
|
|
331
380
|
.btn-sm {
|
|
332
|
-
padding:
|
|
333
|
-
background:
|
|
334
|
-
border:
|
|
335
|
-
border-radius:
|
|
336
|
-
|
|
381
|
+
padding: 6px 14px;
|
|
382
|
+
background: var(--surface);
|
|
383
|
+
border: 2px solid var(--ink);
|
|
384
|
+
border-radius: var(--radius-md);
|
|
385
|
+
box-shadow: var(--shadow-sm);
|
|
386
|
+
color: var(--ink);
|
|
337
387
|
font-size: 12px;
|
|
388
|
+
font-weight: 700;
|
|
338
389
|
cursor: pointer;
|
|
339
|
-
transition: background 0.2s;
|
|
390
|
+
transition: transform 150ms ease, box-shadow 150ms ease, background 0.2s;
|
|
340
391
|
}
|
|
341
392
|
|
|
342
|
-
.btn-sm:hover {
|
|
343
|
-
|
|
393
|
+
.btn-sm:hover {
|
|
394
|
+
background: var(--accent-soft);
|
|
395
|
+
box-shadow: none;
|
|
396
|
+
transform: translate(2px, 2px);
|
|
397
|
+
}
|
|
398
|
+
.btn-sm:active {
|
|
399
|
+
box-shadow: none;
|
|
400
|
+
transform: translate(2px, 2px);
|
|
401
|
+
}
|
|
402
|
+
.btn-sm:disabled {
|
|
403
|
+
opacity: 0.5;
|
|
404
|
+
cursor: not-allowed;
|
|
405
|
+
box-shadow: var(--shadow-sm);
|
|
406
|
+
transform: none;
|
|
407
|
+
}
|
|
344
408
|
|
|
345
409
|
.empty-state {
|
|
346
410
|
padding: 40px 20px;
|
|
347
411
|
text-align: center;
|
|
348
|
-
color:
|
|
412
|
+
color: var(--muted);
|
|
349
413
|
font-size: 14px;
|
|
350
414
|
}
|
|
351
415
|
|
|
352
416
|
/* Activity */
|
|
417
|
+
.activity-filter {
|
|
418
|
+
display: flex;
|
|
419
|
+
flex-wrap: wrap;
|
|
420
|
+
gap: 6px;
|
|
421
|
+
padding: 8px 0 12px;
|
|
422
|
+
margin-bottom: 8px;
|
|
423
|
+
border-bottom: 1px solid var(--line);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.chip {
|
|
427
|
+
padding: 4px 10px;
|
|
428
|
+
border: 2px solid var(--line);
|
|
429
|
+
border-radius: var(--radius-sm);
|
|
430
|
+
background: var(--surface);
|
|
431
|
+
color: var(--ink);
|
|
432
|
+
font-family: var(--font-sans);
|
|
433
|
+
font-size: 12px;
|
|
434
|
+
font-weight: 700;
|
|
435
|
+
cursor: pointer;
|
|
436
|
+
transition: transform 100ms ease, box-shadow 100ms ease, background 0.2s;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.chip:hover {
|
|
440
|
+
background: var(--accent-soft);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.chip.active {
|
|
444
|
+
background: var(--accent);
|
|
445
|
+
color: var(--surface);
|
|
446
|
+
box-shadow: var(--shadow-sm);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.chip.active:hover {
|
|
450
|
+
background: var(--accent-strong);
|
|
451
|
+
}
|
|
452
|
+
|
|
353
453
|
.activity-list {
|
|
354
|
-
max-height: calc(100vh -
|
|
454
|
+
max-height: calc(100vh - 220px);
|
|
355
455
|
overflow-y: auto;
|
|
356
456
|
}
|
|
357
457
|
|
|
458
|
+
/* Plan 18 P1-4 — Errors panel grouped view */
|
|
459
|
+
.errors-summary {
|
|
460
|
+
display: flex;
|
|
461
|
+
align-items: center;
|
|
462
|
+
gap: 12px;
|
|
463
|
+
padding: 8px 12px;
|
|
464
|
+
background: var(--surface-strong);
|
|
465
|
+
border: 2px solid var(--line);
|
|
466
|
+
border-radius: var(--radius-md);
|
|
467
|
+
margin-bottom: 12px;
|
|
468
|
+
font-size: 13px;
|
|
469
|
+
color: var(--ink);
|
|
470
|
+
font-weight: 500;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.errors-list {
|
|
474
|
+
max-height: calc(100vh - 240px);
|
|
475
|
+
overflow-y: auto;
|
|
476
|
+
display: flex;
|
|
477
|
+
flex-direction: column;
|
|
478
|
+
gap: 10px;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.error-group {
|
|
482
|
+
background: var(--surface);
|
|
483
|
+
border: 2px solid var(--line);
|
|
484
|
+
border-radius: var(--radius-md);
|
|
485
|
+
box-shadow: var(--shadow-sm);
|
|
486
|
+
padding: 12px 14px;
|
|
487
|
+
cursor: pointer;
|
|
488
|
+
transition: transform 100ms ease, box-shadow 100ms ease;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.error-group:hover {
|
|
492
|
+
transform: translate(2px, 2px);
|
|
493
|
+
box-shadow: none;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.error-group.expanded {
|
|
497
|
+
transform: none;
|
|
498
|
+
box-shadow: var(--shadow);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.error-group-head {
|
|
502
|
+
display: flex;
|
|
503
|
+
align-items: center;
|
|
504
|
+
gap: 10px;
|
|
505
|
+
flex-wrap: wrap;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.error-count {
|
|
509
|
+
display: inline-flex;
|
|
510
|
+
align-items: center;
|
|
511
|
+
justify-content: center;
|
|
512
|
+
min-width: 28px;
|
|
513
|
+
height: 22px;
|
|
514
|
+
padding: 0 8px;
|
|
515
|
+
border-radius: var(--radius-sm);
|
|
516
|
+
background: var(--accent);
|
|
517
|
+
color: var(--surface);
|
|
518
|
+
font-size: 12px;
|
|
519
|
+
font-weight: 700;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.error-count.dim {
|
|
523
|
+
background: var(--accent-soft);
|
|
524
|
+
color: var(--ink);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
.error-severity {
|
|
528
|
+
font-size: 10px;
|
|
529
|
+
font-weight: 700;
|
|
530
|
+
text-transform: uppercase;
|
|
531
|
+
padding: 2px 6px;
|
|
532
|
+
border-radius: var(--radius-sm);
|
|
533
|
+
background: rgba(200, 84, 80, 0.18);
|
|
534
|
+
color: var(--danger);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.error-message {
|
|
538
|
+
font-family: var(--font-mono);
|
|
539
|
+
font-size: 13px;
|
|
540
|
+
color: var(--ink);
|
|
541
|
+
flex: 1 1 100%;
|
|
542
|
+
word-break: break-word;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.error-meta {
|
|
546
|
+
display: flex;
|
|
547
|
+
gap: 12px;
|
|
548
|
+
flex-wrap: wrap;
|
|
549
|
+
margin-top: 6px;
|
|
550
|
+
font-size: 11px;
|
|
551
|
+
color: var(--muted);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.error-detail {
|
|
555
|
+
display: none;
|
|
556
|
+
margin-top: 10px;
|
|
557
|
+
padding-top: 10px;
|
|
558
|
+
border-top: 1px dashed var(--line);
|
|
559
|
+
font-family: var(--font-mono);
|
|
560
|
+
font-size: 12px;
|
|
561
|
+
white-space: pre-wrap;
|
|
562
|
+
color: var(--muted);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
.error-group.expanded .error-detail { display: block; }
|
|
566
|
+
|
|
358
567
|
.activity-item {
|
|
359
568
|
padding: 8px 12px;
|
|
360
|
-
border-bottom: 1px solid
|
|
569
|
+
border-bottom: 1px solid var(--line);
|
|
361
570
|
font-size: 13px;
|
|
362
|
-
font-family:
|
|
571
|
+
font-family: var(--font-mono);
|
|
363
572
|
display: flex;
|
|
364
573
|
gap: 10px;
|
|
365
574
|
align-items: flex-start;
|
|
@@ -372,19 +581,19 @@ const CSS = /* css */ `
|
|
|
372
581
|
}
|
|
373
582
|
|
|
374
583
|
.activity-time {
|
|
375
|
-
color:
|
|
584
|
+
color: var(--muted);
|
|
376
585
|
white-space: nowrap;
|
|
377
586
|
flex-shrink: 0;
|
|
378
587
|
}
|
|
379
588
|
|
|
380
589
|
.activity-tool {
|
|
381
|
-
color:
|
|
590
|
+
color: var(--accent);
|
|
382
591
|
font-weight: 500;
|
|
383
592
|
flex-shrink: 0;
|
|
384
593
|
}
|
|
385
594
|
|
|
386
595
|
.activity-detail {
|
|
387
|
-
color:
|
|
596
|
+
color: var(--muted);
|
|
388
597
|
overflow: hidden;
|
|
389
598
|
text-overflow: ellipsis;
|
|
390
599
|
white-space: nowrap;
|
|
@@ -395,7 +604,7 @@ const CSS = /* css */ `
|
|
|
395
604
|
display: flex;
|
|
396
605
|
gap: 12px;
|
|
397
606
|
font-size: 12px;
|
|
398
|
-
color:
|
|
607
|
+
color: var(--muted);
|
|
399
608
|
}
|
|
400
609
|
|
|
401
610
|
.summary-item {
|
|
@@ -406,7 +615,7 @@ const CSS = /* css */ `
|
|
|
406
615
|
|
|
407
616
|
.summary-count {
|
|
408
617
|
font-weight: 600;
|
|
409
|
-
color:
|
|
618
|
+
color: var(--ink);
|
|
410
619
|
}
|
|
411
620
|
|
|
412
621
|
.route-item {
|
|
@@ -414,7 +623,7 @@ const CSS = /* css */ `
|
|
|
414
623
|
align-items: center;
|
|
415
624
|
gap: 12px;
|
|
416
625
|
padding: 10px 12px;
|
|
417
|
-
border-bottom: 1px solid
|
|
626
|
+
border-bottom: 1px solid var(--line);
|
|
418
627
|
font-size: 13px;
|
|
419
628
|
}
|
|
420
629
|
|
|
@@ -430,12 +639,12 @@ const CSS = /* css */ `
|
|
|
430
639
|
text-align: center;
|
|
431
640
|
}
|
|
432
641
|
|
|
433
|
-
.route-kind.page { background:
|
|
434
|
-
.route-kind.api { background:
|
|
642
|
+
.route-kind.page { background: rgba(74, 144, 194, 0.15); color: var(--info); }
|
|
643
|
+
.route-kind.api { background: rgba(107, 158, 71, 0.18); color: var(--success); }
|
|
435
644
|
|
|
436
645
|
.route-pattern {
|
|
437
|
-
font-family:
|
|
438
|
-
color:
|
|
646
|
+
font-family: var(--font-mono);
|
|
647
|
+
color: var(--ink);
|
|
439
648
|
flex: 1;
|
|
440
649
|
}
|
|
441
650
|
|
|
@@ -449,22 +658,22 @@ const CSS = /* css */ `
|
|
|
449
658
|
padding: 1px 6px;
|
|
450
659
|
border-radius: 3px;
|
|
451
660
|
font-size: 10px;
|
|
452
|
-
background:
|
|
453
|
-
color:
|
|
661
|
+
background: var(--surface-alt);
|
|
662
|
+
color: var(--muted);
|
|
454
663
|
}
|
|
455
664
|
|
|
456
665
|
/* Guard */
|
|
457
666
|
.guard-status {
|
|
458
667
|
margin-bottom: 12px;
|
|
459
668
|
font-size: 13px;
|
|
460
|
-
color:
|
|
669
|
+
color: var(--muted);
|
|
461
670
|
}
|
|
462
671
|
|
|
463
672
|
.guard-summary {
|
|
464
673
|
display: flex;
|
|
465
674
|
gap: 16px;
|
|
466
675
|
padding: 12px;
|
|
467
|
-
background:
|
|
676
|
+
background: var(--surface-strong);
|
|
468
677
|
border-radius: 8px;
|
|
469
678
|
margin-bottom: 12px;
|
|
470
679
|
}
|
|
@@ -480,28 +689,28 @@ const CSS = /* css */ `
|
|
|
480
689
|
|
|
481
690
|
.guard-stat-label {
|
|
482
691
|
font-size: 11px;
|
|
483
|
-
color:
|
|
692
|
+
color: var(--muted);
|
|
484
693
|
text-transform: uppercase;
|
|
485
694
|
}
|
|
486
695
|
|
|
487
|
-
.sev-error { color:
|
|
488
|
-
.sev-warning { color:
|
|
489
|
-
.sev-info { color:
|
|
696
|
+
.sev-error { color: var(--danger); }
|
|
697
|
+
.sev-warning { color: var(--warning); }
|
|
698
|
+
.sev-info { color: var(--info); }
|
|
490
699
|
|
|
491
700
|
.violation-item {
|
|
492
701
|
padding: 8px 12px;
|
|
493
|
-
border-bottom: 1px solid
|
|
702
|
+
border-bottom: 1px solid var(--line);
|
|
494
703
|
font-size: 13px;
|
|
495
704
|
}
|
|
496
705
|
|
|
497
706
|
.violation-file {
|
|
498
|
-
font-family:
|
|
499
|
-
color:
|
|
707
|
+
font-family: var(--font-mono);
|
|
708
|
+
color: var(--accent);
|
|
500
709
|
margin-bottom: 2px;
|
|
501
710
|
}
|
|
502
711
|
|
|
503
712
|
.violation-msg {
|
|
504
|
-
color:
|
|
713
|
+
color: var(--muted);
|
|
505
714
|
font-size: 12px;
|
|
506
715
|
}
|
|
507
716
|
|
|
@@ -514,9 +723,9 @@ const CSS = /* css */ `
|
|
|
514
723
|
margin-right: 4px;
|
|
515
724
|
}
|
|
516
725
|
|
|
517
|
-
.violation-sev.error { background:
|
|
518
|
-
.violation-sev.warning { background:
|
|
519
|
-
.violation-sev.info { background:
|
|
726
|
+
.violation-sev.error { background: rgba(200, 84, 80, 0.18); color: var(--danger); }
|
|
727
|
+
.violation-sev.warning { background: rgba(232, 169, 58, 0.20); color: var(--warning); }
|
|
728
|
+
.violation-sev.info { background: rgba(74, 144, 194, 0.18); color: var(--info); }
|
|
520
729
|
|
|
521
730
|
/* Preview */
|
|
522
731
|
.preview-list { max-height: 40vh; overflow-y: auto; }
|
|
@@ -527,16 +736,16 @@ const CSS = /* css */ `
|
|
|
527
736
|
align-items: center;
|
|
528
737
|
gap: 10px;
|
|
529
738
|
padding: 8px 12px;
|
|
530
|
-
border-bottom: 1px solid
|
|
739
|
+
border-bottom: 1px solid var(--line);
|
|
531
740
|
font-size: 13px;
|
|
532
741
|
cursor: pointer;
|
|
533
742
|
transition: background 0.15s;
|
|
534
743
|
}
|
|
535
|
-
.change-item:hover { background:
|
|
744
|
+
.change-item:hover { background: var(--surface-alt); }
|
|
536
745
|
.change-icon { flex-shrink: 0; }
|
|
537
746
|
.change-path {
|
|
538
|
-
font-family:
|
|
539
|
-
color:
|
|
747
|
+
font-family: var(--font-mono);
|
|
748
|
+
color: var(--ink);
|
|
540
749
|
flex: 1;
|
|
541
750
|
overflow: hidden;
|
|
542
751
|
text-overflow: ellipsis;
|
|
@@ -550,81 +759,81 @@ const CSS = /* css */ `
|
|
|
550
759
|
font-weight: 600;
|
|
551
760
|
flex-shrink: 0;
|
|
552
761
|
}
|
|
553
|
-
.change-status.added { background:
|
|
554
|
-
.change-status.modified { background:
|
|
555
|
-
.change-status.deleted { background:
|
|
556
|
-
.change-status.untracked { background:
|
|
557
|
-
.change-status.renamed { background:
|
|
762
|
+
.change-status.added { background: rgba(107, 158, 71, 0.18); color: var(--success); }
|
|
763
|
+
.change-status.modified { background: rgba(74, 144, 194, 0.15); color: var(--info); }
|
|
764
|
+
.change-status.deleted { background: rgba(200, 84, 80, 0.18); color: var(--danger); }
|
|
765
|
+
.change-status.untracked { background: rgba(232, 169, 58, 0.20); color: var(--warning); }
|
|
766
|
+
.change-status.renamed { background: var(--accent-soft); color: var(--accent); }
|
|
558
767
|
|
|
559
768
|
.diff-header {
|
|
560
769
|
display: flex; align-items: center; justify-content: space-between;
|
|
561
|
-
padding: 8px 12px; background:
|
|
562
|
-
border-bottom: 1px solid
|
|
770
|
+
padding: 8px 12px; background: var(--surface-strong); border-radius: 6px 6px 0 0;
|
|
771
|
+
border-bottom: 1px solid var(--surface-alt);
|
|
563
772
|
}
|
|
564
|
-
.diff-file { font-family: monospace; color:
|
|
773
|
+
.diff-file { font-family: monospace; color: var(--accent); font-size: 13px; }
|
|
565
774
|
.diff-stats { font-size: 12px; }
|
|
566
|
-
.diff-add { color:
|
|
567
|
-
.diff-del { color:
|
|
568
|
-
.diff-hunk-header { padding: 4px 12px; background:
|
|
775
|
+
.diff-add { color: var(--success); margin-right: 8px; }
|
|
776
|
+
.diff-del { color: var(--danger); }
|
|
777
|
+
.diff-hunk-header { padding: 4px 12px; background: rgba(74, 144, 194, 0.18); color: var(--info); font-size: 12px; font-family: monospace; }
|
|
569
778
|
.diff-line { display: flex; font-family: monospace; font-size: 12px; line-height: 20px; }
|
|
570
|
-
.diff-line-num { width: 40px; text-align: right; padding: 0 4px; color:
|
|
779
|
+
.diff-line-num { width: 40px; text-align: right; padding: 0 4px; color: var(--muted); user-select: none; flex-shrink: 0; }
|
|
571
780
|
.diff-line-content { flex: 1; padding: 0 8px; white-space: pre; overflow: hidden; text-overflow: ellipsis; }
|
|
572
781
|
.diff-line.add { background: rgba(74,222,128,0.08); }
|
|
573
|
-
.diff-line.add .diff-line-content::before { content: '+'; color:
|
|
782
|
+
.diff-line.add .diff-line-content::before { content: '+'; color: var(--success); }
|
|
574
783
|
.diff-line.remove { background: rgba(239,68,68,0.08); }
|
|
575
|
-
.diff-line.remove .diff-line-content::before { content: '-'; color:
|
|
784
|
+
.diff-line.remove .diff-line-content::before { content: '-'; color: var(--danger); }
|
|
576
785
|
.diff-line.context .diff-line-content::before { content: ' '; }
|
|
577
786
|
|
|
578
787
|
/* Contracts */
|
|
579
788
|
.contracts-layout { display: flex; gap: 12px; height: calc(100vh - 180px); }
|
|
580
|
-
.contracts-list { width: 300px; flex-shrink: 0; overflow-y: auto; border-right: 1px solid
|
|
789
|
+
.contracts-list { width: 300px; flex-shrink: 0; overflow-y: auto; border-right: 1px solid var(--surface-alt); padding-right: 12px; }
|
|
581
790
|
.contracts-detail { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; }
|
|
582
791
|
|
|
583
792
|
.contract-item {
|
|
584
793
|
display: flex; align-items: center; gap: 8px;
|
|
585
|
-
padding: 8px 12px; border-bottom: 1px solid
|
|
794
|
+
padding: 8px 12px; border-bottom: 1px solid var(--line);
|
|
586
795
|
cursor: pointer; transition: background 0.15s; font-size: 13px;
|
|
587
796
|
}
|
|
588
|
-
.contract-item:hover { background:
|
|
589
|
-
.contract-item.selected { background:
|
|
797
|
+
.contract-item:hover { background: var(--surface-alt); }
|
|
798
|
+
.contract-item.selected { background: var(--surface-alt); border-left: 2px solid var(--accent); }
|
|
590
799
|
|
|
591
800
|
.method-badge {
|
|
592
801
|
display: inline-block; padding: 1px 6px; border-radius: 3px;
|
|
593
802
|
font-size: 10px; font-weight: 600; text-transform: uppercase;
|
|
594
803
|
flex-shrink: 0; min-width: 36px; text-align: center;
|
|
595
804
|
}
|
|
596
|
-
.method-badge.get { background:
|
|
597
|
-
.method-badge.post { background:
|
|
598
|
-
.method-badge.put { background:
|
|
599
|
-
.method-badge.patch { background:
|
|
600
|
-
.method-badge.delete { background:
|
|
805
|
+
.method-badge.get { background: rgba(107, 158, 71, 0.18); color: var(--success); }
|
|
806
|
+
.method-badge.post { background: rgba(74, 144, 194, 0.15); color: var(--info); }
|
|
807
|
+
.method-badge.put { background: rgba(232, 169, 58, 0.20); color: var(--warning); }
|
|
808
|
+
.method-badge.patch { background: var(--accent-soft); color: var(--accent); }
|
|
809
|
+
.method-badge.delete { background: rgba(200, 84, 80, 0.18); color: var(--danger); }
|
|
601
810
|
|
|
602
|
-
.contract-pattern { font-family: monospace; color:
|
|
811
|
+
.contract-pattern { font-family: monospace; color: var(--ink); }
|
|
603
812
|
|
|
604
813
|
.contract-schema {
|
|
605
|
-
background:
|
|
814
|
+
background: var(--surface-strong); border-radius: 8px; padding: 12px;
|
|
606
815
|
font-family: monospace; font-size: 12px; white-space: pre-wrap;
|
|
607
816
|
max-height: 40vh; overflow-y: auto;
|
|
608
817
|
}
|
|
609
818
|
|
|
610
|
-
.contract-playground { background:
|
|
819
|
+
.contract-playground { background: var(--surface-strong); border-radius: 8px; padding: 12px; }
|
|
611
820
|
.contract-playground h3 { font-size: 14px; margin-bottom: 8px; }
|
|
612
821
|
|
|
613
822
|
.playground-controls { display: flex; gap: 8px; margin-bottom: 8px; }
|
|
614
823
|
.select-sm {
|
|
615
|
-
padding: 4px 8px; background:
|
|
616
|
-
border-radius: 6px; color:
|
|
824
|
+
padding: 4px 8px; background: var(--surface-alt); border: 1px solid var(--line);
|
|
825
|
+
border-radius: 6px; color: var(--ink); font-size: 12px;
|
|
617
826
|
}
|
|
618
827
|
.playground-inputs { display: flex; flex-direction: column; gap: 6px; }
|
|
619
|
-
.playground-inputs label { font-size: 11px; color:
|
|
828
|
+
.playground-inputs label { font-size: 11px; color: var(--muted); display: flex; flex-direction: column; gap: 2px; }
|
|
620
829
|
.playground-inputs textarea {
|
|
621
|
-
background:
|
|
622
|
-
color:
|
|
830
|
+
background: var(--surface-alt); border: 1px solid var(--line); border-radius: 4px;
|
|
831
|
+
color: var(--ink); font-family: monospace; font-size: 12px; padding: 6px;
|
|
623
832
|
resize: vertical;
|
|
624
833
|
}
|
|
625
834
|
.validate-result { margin-top: 8px; padding: 8px; border-radius: 4px; font-size: 12px; font-family: monospace; }
|
|
626
|
-
.validate-result.success { background:
|
|
627
|
-
.validate-result.error { background:
|
|
835
|
+
.validate-result.success { background: rgba(107, 158, 71, 0.18); color: var(--success); }
|
|
836
|
+
.validate-result.error { background: rgba(200, 84, 80, 0.18); color: var(--danger); }
|
|
628
837
|
|
|
629
838
|
.debug-bar {
|
|
630
839
|
position: fixed;
|
|
@@ -632,43 +841,71 @@ const CSS = /* css */ `
|
|
|
632
841
|
left: 0;
|
|
633
842
|
right: 0;
|
|
634
843
|
padding: 4px 12px;
|
|
635
|
-
background:
|
|
636
|
-
border-top: 1px solid
|
|
844
|
+
background: var(--bg);
|
|
845
|
+
border-top: 1px solid var(--surface-alt);
|
|
637
846
|
font-size: 11px;
|
|
638
847
|
font-family: monospace;
|
|
639
|
-
color:
|
|
848
|
+
color: var(--muted);
|
|
640
849
|
max-height: 60px;
|
|
641
850
|
overflow-y: auto;
|
|
642
851
|
}
|
|
643
852
|
|
|
644
|
-
.debug-bar .err { color:
|
|
645
|
-
.debug-bar .ok { color:
|
|
853
|
+
.debug-bar .err { color: var(--danger); }
|
|
854
|
+
.debug-bar .ok { color: var(--success); }
|
|
646
855
|
|
|
856
|
+
/*
|
|
857
|
+
* Plan 18 DA-1 — token values aligned to mandujs.com Stitch system
|
|
858
|
+
* (app/globals.css + tokens.css). Variable names stay the same so the
|
|
859
|
+
* cascade with the legacy dark-mode block earlier in this file does
|
|
860
|
+
* not break. Stitch identity: Peach #FF8C66 / Dark Brown #4A3222 /
|
|
861
|
+
* Cream #FFFDF5 + hard shadow (blur 0).
|
|
862
|
+
*/
|
|
647
863
|
:root {
|
|
648
|
-
|
|
649
|
-
--bg
|
|
650
|
-
--
|
|
651
|
-
--surface
|
|
652
|
-
--surface-
|
|
653
|
-
--
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
--
|
|
657
|
-
--
|
|
658
|
-
--
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
--
|
|
662
|
-
--
|
|
663
|
-
--
|
|
864
|
+
/* Page surfaces */
|
|
865
|
+
--bg: #FFFDF5; /* mandujs.com --color-background (cream) */
|
|
866
|
+
--bg-soft: rgba(255, 253, 245, 0.7);
|
|
867
|
+
--surface: #FFFFFF; /* --color-surface */
|
|
868
|
+
--surface-strong: #FBF6EC; /* --color-code-bg-light, slightly darker cream */
|
|
869
|
+
--surface-alt: #F5F0E8; /* --color-muted */
|
|
870
|
+
|
|
871
|
+
/* Text */
|
|
872
|
+
--ink: #4A3222; /* --color-foreground (dark brown, not black) */
|
|
873
|
+
--muted: #7A6B5D; /* --color-muted-foreground (warm gray) */
|
|
874
|
+
--line: #4A3222; /* --color-border (2px brown lines are Stitch) */
|
|
875
|
+
|
|
876
|
+
/* Brand */
|
|
877
|
+
--accent: #FF8C66; /* --color-primary (peach) */
|
|
878
|
+
--accent-strong: #FF7A4F; /* --color-primary-hover */
|
|
879
|
+
--accent-soft: rgba(255, 140, 102, 0.14);
|
|
880
|
+
|
|
881
|
+
/* Semantic — docs-grade muted channels (tokens.css) */
|
|
882
|
+
--success: #6B9E47; /* olive green */
|
|
883
|
+
--danger: #C85450; /* muted red-brown */
|
|
884
|
+
--info: #4A90C2; /* calm blue */
|
|
885
|
+
--warning: #E8A93A; /* warm amber */
|
|
886
|
+
|
|
887
|
+
/* Hard shadow (Stitch signature — blur 0, solid color block). The
|
|
888
|
+
* standard variant is exposed as --shadow so existing references
|
|
889
|
+
* inherit the new look without per-selector edits. */
|
|
890
|
+
--shadow: 4px 4px 0 0 var(--ink);
|
|
891
|
+
--shadow-sm: 2px 2px 0 0 var(--ink);
|
|
892
|
+
--shadow-lg: 6px 6px 0 0 var(--ink);
|
|
893
|
+
|
|
894
|
+
/* Radius scale — rounded & playful */
|
|
895
|
+
--radius-sm: 0.5rem;
|
|
896
|
+
--radius-md: 1rem;
|
|
897
|
+
--radius-lg: 1.5rem;
|
|
898
|
+
--radius-xl: 2rem;
|
|
899
|
+
|
|
900
|
+
/* Typography */
|
|
901
|
+
--font-sans: 'Pretendard Variable', 'Pretendard', 'Noto Sans JP', 'Noto Sans SC', ui-sans-serif, system-ui, sans-serif;
|
|
902
|
+
--font-display: 'Nunito', 'Jua', 'Pretendard Variable', 'Pretendard', ui-sans-serif, system-ui, sans-serif;
|
|
903
|
+
--font-mono: 'Consolas', 'Monaco', 'Ubuntu Mono', ui-monospace, monospace;
|
|
664
904
|
}
|
|
665
905
|
|
|
666
906
|
body {
|
|
667
|
-
font-family:
|
|
668
|
-
background:
|
|
669
|
-
radial-gradient(circle at top left, rgba(226, 186, 124, 0.35), transparent 30%),
|
|
670
|
-
radial-gradient(circle at top right, rgba(152, 191, 193, 0.22), transparent 24%),
|
|
671
|
-
linear-gradient(180deg, #f8f3ea 0%, #efe7d8 100%);
|
|
907
|
+
font-family: var(--font-sans);
|
|
908
|
+
background: var(--bg);
|
|
672
909
|
color: var(--ink);
|
|
673
910
|
padding: 24px;
|
|
674
911
|
}
|
|
@@ -1202,141 +1439,141 @@ const CSS = /* css */ `
|
|
|
1202
1439
|
box-shadow: 0 12px 28px rgba(30, 42, 58, 0.22);
|
|
1203
1440
|
}
|
|
1204
1441
|
|
|
1205
|
-
.requests-list, .mcp-list, .cache-content, .metrics-content, .agent-content {
|
|
1206
|
-
display: flex;
|
|
1207
|
-
flex-direction: column;
|
|
1208
|
-
gap: 6px;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
.agent-grid {
|
|
1212
|
-
display: grid;
|
|
1213
|
-
grid-template-columns: minmax(0, 1.1fr) minmax(320px, 0.9fr);
|
|
1214
|
-
gap: 14px;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
.agent-stack {
|
|
1218
|
-
display: flex;
|
|
1219
|
-
flex-direction: column;
|
|
1220
|
-
gap: 12px;
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
.agent-card {
|
|
1224
|
-
padding: 14px;
|
|
1225
|
-
border: 1px solid var(--line);
|
|
1226
|
-
border-radius: 8px;
|
|
1227
|
-
background: rgba(255, 255, 255, 0.72);
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
.agent-card-title {
|
|
1231
|
-
display: flex;
|
|
1232
|
-
align-items: center;
|
|
1233
|
-
justify-content: space-between;
|
|
1234
|
-
gap: 10px;
|
|
1235
|
-
margin-bottom: 8px;
|
|
1236
|
-
color: var(--ink);
|
|
1237
|
-
font-size: 14px;
|
|
1238
|
-
font-weight: 700;
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
.agent-card-body {
|
|
1242
|
-
color: var(--muted);
|
|
1243
|
-
font-size: 13px;
|
|
1244
|
-
line-height: 1.55;
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
.agent-pill-row {
|
|
1248
|
-
display: flex;
|
|
1249
|
-
flex-wrap: wrap;
|
|
1250
|
-
gap: 6px;
|
|
1251
|
-
margin-top: 10px;
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
.agent-pill {
|
|
1255
|
-
padding: 4px 8px;
|
|
1256
|
-
border-radius: 6px;
|
|
1257
|
-
background: rgba(30, 42, 58, 0.08);
|
|
1258
|
-
color: var(--ink);
|
|
1259
|
-
font-family: "IBM Plex Mono", "Cascadia Code", monospace;
|
|
1260
|
-
font-size: 11px;
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
.agent-severity {
|
|
1264
|
-
padding: 3px 7px;
|
|
1265
|
-
border-radius: 6px;
|
|
1266
|
-
font-size: 11px;
|
|
1267
|
-
font-weight: 700;
|
|
1268
|
-
text-transform: uppercase;
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
.agent-severity.info { background: rgba(46, 102, 184, 0.12); color: var(--info); }
|
|
1272
|
-
.agent-severity.warn { background: rgba(173, 122, 18, 0.14); color: var(--warning); }
|
|
1273
|
-
.agent-severity.error { background: rgba(188, 61, 61, 0.12); color: var(--danger); }
|
|
1274
|
-
|
|
1275
|
-
.agent-stat-grid {
|
|
1276
|
-
display: grid;
|
|
1277
|
-
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
1278
|
-
gap: 8px;
|
|
1279
|
-
margin-top: 12px;
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
.agent-stat {
|
|
1283
|
-
padding: 10px;
|
|
1284
|
-
border-radius: 8px;
|
|
1285
|
-
border: 1px solid rgba(220, 207, 186, 0.7);
|
|
1286
|
-
background: rgba(255, 253, 250, 0.84);
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
.agent-stat-label {
|
|
1290
|
-
color: var(--muted);
|
|
1291
|
-
font-size: 11px;
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
|
-
.agent-stat-value {
|
|
1295
|
-
color: var(--ink);
|
|
1296
|
-
font-size: 19px;
|
|
1297
|
-
font-weight: 700;
|
|
1298
|
-
margin-top: 3px;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
.agent-rec {
|
|
1302
|
-
display: grid;
|
|
1303
|
-
grid-template-columns: 150px 1fr;
|
|
1304
|
-
gap: 10px;
|
|
1305
|
-
padding: 10px 0;
|
|
1306
|
-
border-top: 1px solid rgba(220, 207, 186, 0.65);
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
.agent-rec:first-child {
|
|
1310
|
-
border-top: 0;
|
|
1311
|
-
padding-top: 0;
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
|
-
.agent-rec-title {
|
|
1315
|
-
color: var(--ink);
|
|
1316
|
-
font-weight: 700;
|
|
1317
|
-
font-size: 13px;
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
.agent-rec-detail {
|
|
1321
|
-
color: var(--muted);
|
|
1322
|
-
font-size: 12px;
|
|
1323
|
-
line-height: 1.5;
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
.agent-prompt {
|
|
1327
|
-
width: 100%;
|
|
1328
|
-
min-height: 220px;
|
|
1329
|
-
margin-top: 10px;
|
|
1330
|
-
padding: 12px;
|
|
1331
|
-
resize: vertical;
|
|
1332
|
-
border-radius: 8px;
|
|
1333
|
-
border: 1px solid var(--line);
|
|
1334
|
-
background:
|
|
1335
|
-
color: var(--ink);
|
|
1336
|
-
font-family: "IBM Plex Mono", "Cascadia Code", monospace;
|
|
1337
|
-
font-size: 12px;
|
|
1338
|
-
line-height: 1.45;
|
|
1339
|
-
}
|
|
1442
|
+
.requests-list, .mcp-list, .cache-content, .metrics-content, .agent-content {
|
|
1443
|
+
display: flex;
|
|
1444
|
+
flex-direction: column;
|
|
1445
|
+
gap: 6px;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
.agent-grid {
|
|
1449
|
+
display: grid;
|
|
1450
|
+
grid-template-columns: minmax(0, 1.1fr) minmax(320px, 0.9fr);
|
|
1451
|
+
gap: 14px;
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
.agent-stack {
|
|
1455
|
+
display: flex;
|
|
1456
|
+
flex-direction: column;
|
|
1457
|
+
gap: 12px;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
.agent-card {
|
|
1461
|
+
padding: 14px;
|
|
1462
|
+
border: 1px solid var(--line);
|
|
1463
|
+
border-radius: 8px;
|
|
1464
|
+
background: rgba(255, 255, 255, 0.72);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
.agent-card-title {
|
|
1468
|
+
display: flex;
|
|
1469
|
+
align-items: center;
|
|
1470
|
+
justify-content: space-between;
|
|
1471
|
+
gap: 10px;
|
|
1472
|
+
margin-bottom: 8px;
|
|
1473
|
+
color: var(--ink);
|
|
1474
|
+
font-size: 14px;
|
|
1475
|
+
font-weight: 700;
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
.agent-card-body {
|
|
1479
|
+
color: var(--muted);
|
|
1480
|
+
font-size: 13px;
|
|
1481
|
+
line-height: 1.55;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.agent-pill-row {
|
|
1485
|
+
display: flex;
|
|
1486
|
+
flex-wrap: wrap;
|
|
1487
|
+
gap: 6px;
|
|
1488
|
+
margin-top: 10px;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
.agent-pill {
|
|
1492
|
+
padding: 4px 8px;
|
|
1493
|
+
border-radius: 6px;
|
|
1494
|
+
background: rgba(30, 42, 58, 0.08);
|
|
1495
|
+
color: var(--ink);
|
|
1496
|
+
font-family: "IBM Plex Mono", "Cascadia Code", monospace;
|
|
1497
|
+
font-size: 11px;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
.agent-severity {
|
|
1501
|
+
padding: 3px 7px;
|
|
1502
|
+
border-radius: 6px;
|
|
1503
|
+
font-size: 11px;
|
|
1504
|
+
font-weight: 700;
|
|
1505
|
+
text-transform: uppercase;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
.agent-severity.info { background: rgba(46, 102, 184, 0.12); color: var(--info); }
|
|
1509
|
+
.agent-severity.warn { background: rgba(173, 122, 18, 0.14); color: var(--warning); }
|
|
1510
|
+
.agent-severity.error { background: rgba(188, 61, 61, 0.12); color: var(--danger); }
|
|
1511
|
+
|
|
1512
|
+
.agent-stat-grid {
|
|
1513
|
+
display: grid;
|
|
1514
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
1515
|
+
gap: 8px;
|
|
1516
|
+
margin-top: 12px;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
.agent-stat {
|
|
1520
|
+
padding: 10px;
|
|
1521
|
+
border-radius: 8px;
|
|
1522
|
+
border: 1px solid rgba(220, 207, 186, 0.7);
|
|
1523
|
+
background: rgba(255, 253, 250, 0.84);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
.agent-stat-label {
|
|
1527
|
+
color: var(--muted);
|
|
1528
|
+
font-size: 11px;
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
.agent-stat-value {
|
|
1532
|
+
color: var(--ink);
|
|
1533
|
+
font-size: 19px;
|
|
1534
|
+
font-weight: 700;
|
|
1535
|
+
margin-top: 3px;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
.agent-rec {
|
|
1539
|
+
display: grid;
|
|
1540
|
+
grid-template-columns: 150px 1fr;
|
|
1541
|
+
gap: 10px;
|
|
1542
|
+
padding: 10px 0;
|
|
1543
|
+
border-top: 1px solid rgba(220, 207, 186, 0.65);
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
.agent-rec:first-child {
|
|
1547
|
+
border-top: 0;
|
|
1548
|
+
padding-top: 0;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
.agent-rec-title {
|
|
1552
|
+
color: var(--ink);
|
|
1553
|
+
font-weight: 700;
|
|
1554
|
+
font-size: 13px;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
.agent-rec-detail {
|
|
1558
|
+
color: var(--muted);
|
|
1559
|
+
font-size: 12px;
|
|
1560
|
+
line-height: 1.5;
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
.agent-prompt {
|
|
1564
|
+
width: 100%;
|
|
1565
|
+
min-height: 220px;
|
|
1566
|
+
margin-top: 10px;
|
|
1567
|
+
padding: 12px;
|
|
1568
|
+
resize: vertical;
|
|
1569
|
+
border-radius: 8px;
|
|
1570
|
+
border: 1px solid var(--line);
|
|
1571
|
+
background: var(--surface);
|
|
1572
|
+
color: var(--ink);
|
|
1573
|
+
font-family: "IBM Plex Mono", "Cascadia Code", monospace;
|
|
1574
|
+
font-size: 12px;
|
|
1575
|
+
line-height: 1.45;
|
|
1576
|
+
}
|
|
1340
1577
|
|
|
1341
1578
|
.req-row {
|
|
1342
1579
|
display: grid;
|
|
@@ -1457,17 +1694,17 @@ const CSS = /* css */ `
|
|
|
1457
1694
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1458
1695
|
}
|
|
1459
1696
|
|
|
1460
|
-
.contracts-layout {
|
|
1461
|
-
grid-template-columns: 1fr;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
.agent-grid {
|
|
1465
|
-
grid-template-columns: 1fr;
|
|
1466
|
-
}
|
|
1467
|
-
|
|
1468
|
-
.guard-summary {
|
|
1469
|
-
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1470
|
-
}
|
|
1697
|
+
.contracts-layout {
|
|
1698
|
+
grid-template-columns: 1fr;
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
.agent-grid {
|
|
1702
|
+
grid-template-columns: 1fr;
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
.guard-summary {
|
|
1706
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1707
|
+
}
|
|
1471
1708
|
}
|
|
1472
1709
|
|
|
1473
1710
|
@media (max-width: 720px) {
|
|
@@ -1493,20 +1730,20 @@ const CSS = /* css */ `
|
|
|
1493
1730
|
width: calc(50% - 4px);
|
|
1494
1731
|
justify-content: center;
|
|
1495
1732
|
}
|
|
1496
|
-
|
|
1497
|
-
.panel-header {
|
|
1498
|
-
flex-direction: column;
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
|
-
.agent-stat-grid {
|
|
1502
|
-
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
.agent-rec {
|
|
1506
|
-
grid-template-columns: 1fr;
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
`;
|
|
1733
|
+
|
|
1734
|
+
.panel-header {
|
|
1735
|
+
flex-direction: column;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
.agent-stat-grid {
|
|
1739
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
.agent-rec {
|
|
1743
|
+
grid-template-columns: 1fr;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
`;
|
|
1510
1747
|
|
|
1511
1748
|
// ─── JavaScript ──────────────────────────────────
|
|
1512
1749
|
|
|
@@ -1523,12 +1760,12 @@ const JS = /* js */ `
|
|
|
1523
1760
|
console.log('[Kitchen]', msg);
|
|
1524
1761
|
}
|
|
1525
1762
|
|
|
1526
|
-
function escapeHtml(str) {
|
|
1527
|
-
if (str === null || str === undefined) return '';
|
|
1528
|
-
var d = document.createElement('div');
|
|
1529
|
-
d.appendChild(document.createTextNode(String(str)));
|
|
1530
|
-
return d.innerHTML;
|
|
1531
|
-
}
|
|
1763
|
+
function escapeHtml(str) {
|
|
1764
|
+
if (str === null || str === undefined) return '';
|
|
1765
|
+
var d = document.createElement('div');
|
|
1766
|
+
d.appendChild(document.createTextNode(String(str)));
|
|
1767
|
+
return d.innerHTML;
|
|
1768
|
+
}
|
|
1532
1769
|
|
|
1533
1770
|
function setMetric(id, value) {
|
|
1534
1771
|
var el = document.getElementById(id);
|
|
@@ -1559,6 +1796,39 @@ const JS = /* js */ `
|
|
|
1559
1796
|
var activityCount = 0;
|
|
1560
1797
|
var MAX_ITEMS = 200;
|
|
1561
1798
|
var sseRetryCount = 0;
|
|
1799
|
+
var activityCurrentSSE = null;
|
|
1800
|
+
var activityFilter = 'all'; // plan 18 P1-3
|
|
1801
|
+
|
|
1802
|
+
function disconnectSSE() {
|
|
1803
|
+
if (activityCurrentSSE) {
|
|
1804
|
+
try { activityCurrentSSE.close(); } catch(_) {}
|
|
1805
|
+
activityCurrentSSE = null;
|
|
1806
|
+
}
|
|
1807
|
+
statusDot.className = 'status-dot disconnected';
|
|
1808
|
+
statusLabel.textContent = 'Filter: ' + activityFilter;
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
function loadFilteredEvents(type) {
|
|
1812
|
+
activityList.innerHTML = '<div class="empty-state">Loading ' + escapeHtml(type) + ' events...</div>';
|
|
1813
|
+
fetchJson('/__kitchen/api/events?type=' + encodeURIComponent(type) + '&limit=100', function(err, data) {
|
|
1814
|
+
if (err) {
|
|
1815
|
+
activityList.innerHTML = '<div class="empty-state">Failed: ' + escapeHtml(err.message) + '</div>';
|
|
1816
|
+
return;
|
|
1817
|
+
}
|
|
1818
|
+
var events = data.events || [];
|
|
1819
|
+
if (!events.length) {
|
|
1820
|
+
activityList.innerHTML = '<div class="empty-state">No ' + escapeHtml(type) + ' events yet — try interacting with the app or run a build.</div>';
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
activityList.innerHTML = '';
|
|
1824
|
+
activityCount = 0;
|
|
1825
|
+
for (var i = 0; i < events.length; i++) {
|
|
1826
|
+
// events come newest-first from reverseCopy in the handler; appendActivity inserts at top.
|
|
1827
|
+
// Reverse so newest stays on top after insertBefore.
|
|
1828
|
+
appendActivity(events[events.length - 1 - i]);
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1562
1832
|
|
|
1563
1833
|
function connectSSE() {
|
|
1564
1834
|
statusDot.className = 'status-dot connecting';
|
|
@@ -1568,6 +1838,7 @@ const JS = /* js */ `
|
|
|
1568
1838
|
var es;
|
|
1569
1839
|
try {
|
|
1570
1840
|
es = new EventSource('/__kitchen/sse/activity');
|
|
1841
|
+
activityCurrentSSE = es;
|
|
1571
1842
|
} catch(e) {
|
|
1572
1843
|
log('SSE EventSource failed: ' + e.message, 'err');
|
|
1573
1844
|
statusDot.className = 'status-dot disconnected';
|
|
@@ -1636,11 +1907,37 @@ const JS = /* js */ `
|
|
|
1636
1907
|
}
|
|
1637
1908
|
|
|
1638
1909
|
document.getElementById('clear-activity').addEventListener('click', function() {
|
|
1639
|
-
activityList.innerHTML = '<div class="empty-state">Waiting for
|
|
1910
|
+
activityList.innerHTML = '<div class="empty-state">Waiting for activity...</div>';
|
|
1640
1911
|
activityCount = 0;
|
|
1641
1912
|
setMetric('metric-activity', 0);
|
|
1642
1913
|
});
|
|
1643
1914
|
|
|
1915
|
+
// Plan 18 P1-3 — Activity filter chips. "All" reconnects SSE for live
|
|
1916
|
+
// mcp tailing; the other chips switch to a one-shot fetch of the bus's
|
|
1917
|
+
// typed slice (build / cache / ws / ate / error / etc) so signals that
|
|
1918
|
+
// would normally stay invisible in the jsonl tail surface here.
|
|
1919
|
+
var filterEl = document.getElementById('activity-filter');
|
|
1920
|
+
if (filterEl) {
|
|
1921
|
+
var chips = filterEl.querySelectorAll('.chip');
|
|
1922
|
+
for (var ci = 0; ci < chips.length; ci++) {
|
|
1923
|
+
chips[ci].addEventListener('click', function() {
|
|
1924
|
+
var all = filterEl.querySelectorAll('.chip');
|
|
1925
|
+
for (var k = 0; k < all.length; k++) all[k].classList.remove('active');
|
|
1926
|
+
this.classList.add('active');
|
|
1927
|
+
var t = this.getAttribute('data-type') || 'all';
|
|
1928
|
+
activityFilter = t;
|
|
1929
|
+
activityList.innerHTML = '';
|
|
1930
|
+
activityCount = 0;
|
|
1931
|
+
if (t === 'all') {
|
|
1932
|
+
connectSSE();
|
|
1933
|
+
} else {
|
|
1934
|
+
disconnectSSE();
|
|
1935
|
+
loadFilteredEvents(t);
|
|
1936
|
+
}
|
|
1937
|
+
});
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1644
1941
|
connectSSE();
|
|
1645
1942
|
|
|
1646
1943
|
// ─── Routes ──────────────────────────────────
|
|
@@ -2049,10 +2346,10 @@ const JS = /* js */ `
|
|
|
2049
2346
|
|
|
2050
2347
|
loadContracts();
|
|
2051
2348
|
|
|
2052
|
-
// ─── Requests Tab ─────────────────────────────
|
|
2053
|
-
var requestsListEl = document.getElementById('requests-list');
|
|
2054
|
-
var requestsDetailEl = document.getElementById('requests-detail');
|
|
2055
|
-
var agentContentEl = document.getElementById('agent-content');
|
|
2349
|
+
// ─── Requests Tab ─────────────────────────────
|
|
2350
|
+
var requestsListEl = document.getElementById('requests-list');
|
|
2351
|
+
var requestsDetailEl = document.getElementById('requests-detail');
|
|
2352
|
+
var agentContentEl = document.getElementById('agent-content');
|
|
2056
2353
|
|
|
2057
2354
|
function fetchJson(url, cb) {
|
|
2058
2355
|
var xhr = new XMLHttpRequest();
|
|
@@ -2067,142 +2364,222 @@ const JS = /* js */ `
|
|
|
2067
2364
|
xhr.send();
|
|
2068
2365
|
}
|
|
2069
2366
|
|
|
2070
|
-
function statusClass(s) {
|
|
2071
|
-
if (!s) return '';
|
|
2072
|
-
if (s >= 500) return 's5';
|
|
2073
|
-
if (s >= 400) return 's4';
|
|
2074
|
-
if (s >= 300) return 's3';
|
|
2075
|
-
return 's2';
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
// ─── Agent Supervisor Tab ─────────────────────
|
|
2079
|
-
function renderAgentPills(items) {
|
|
2080
|
-
if (!items || !items.length) return '';
|
|
2081
|
-
var html = '<div class="agent-pill-row">';
|
|
2082
|
-
for (var i = 0; i < items.length; i++) {
|
|
2083
|
-
html += '<span class="agent-pill">' + escapeHtml(items[i]) + '</span>';
|
|
2084
|
-
}
|
|
2085
|
-
return html + '</div>';
|
|
2086
|
-
}
|
|
2087
|
-
|
|
2088
|
-
function renderAgentDetails(items) {
|
|
2089
|
-
if (!items || !items.length) return '';
|
|
2090
|
-
var html = '<ul>';
|
|
2091
|
-
for (var i = 0; i < items.length; i++) {
|
|
2092
|
-
html += '<li>' + escapeHtml(items[i]) + '</li>';
|
|
2093
|
-
}
|
|
2094
|
-
return html + '</ul>';
|
|
2095
|
-
}
|
|
2096
|
-
|
|
2097
|
-
function renderAgentContext(data) {
|
|
2098
|
-
var situation = data.situation || {};
|
|
2099
|
-
var summary = data.summary || {};
|
|
2100
|
-
var routes = summary.routes || {};
|
|
2101
|
-
var status = data.agentStatus || {};
|
|
2102
|
-
var brain = status.brain || {};
|
|
2103
|
-
var action = data.nextSafeAction || {};
|
|
2104
|
-
var prompt = data.prompt || {};
|
|
2105
|
-
var recs = data.toolRecommendations || [];
|
|
2106
|
-
var cards = data.knowledgeCards || [];
|
|
2107
|
-
var promptText = prompt.copyText || '';
|
|
2108
|
-
|
|
2109
|
-
var html = '<div class="agent-grid">' +
|
|
2110
|
-
'<div class="agent-stack">' +
|
|
2111
|
-
'<div class="agent-card">' +
|
|
2112
|
-
'<div class="agent-card-title">' +
|
|
2113
|
-
'<span>' + escapeHtml(situation.title || 'No situation') + '</span>' +
|
|
2114
|
-
'<span class="agent-severity ' + escapeHtml(situation.severity || 'info') + '">' + escapeHtml(situation.category || 'agent') + '</span>' +
|
|
2115
|
-
'</div>' +
|
|
2116
|
-
'<div class="agent-card-body">' + renderAgentDetails(situation.details || []) + '</div>' +
|
|
2117
|
-
'<div class="agent-stat-grid">' +
|
|
2118
|
-
'<div class="agent-stat"><div class="agent-stat-label">Routes</div><div class="agent-stat-value">' + escapeHtml(routes.total || 0) + '</div></div>' +
|
|
2119
|
-
'<div class="agent-stat"><div class="agent-stat-label">Islands</div><div class="agent-stat-value">' + escapeHtml(routes.islands || 0) + '</div></div>' +
|
|
2120
|
-
'<div class="agent-stat"><div class="agent-stat-label">Contracts</div><div class="agent-stat-value">' + escapeHtml(routes.contracts || 0) + '</div></div>' +
|
|
2121
|
-
'<div class="agent-stat"><div class="agent-stat-label">MCP Calls</div><div class="agent-stat-value">' + escapeHtml(status.observedToolCalls || 0) + '</div></div>' +
|
|
2122
|
-
'</div>' +
|
|
2123
|
-
'</div>' +
|
|
2124
|
-
'<div class="agent-card">' +
|
|
2125
|
-
'<div class="agent-card-title"><span>Next Safe Action</span><span class="agent-severity info">' + escapeHtml(action.mode || 'observe') + '</span></div>' +
|
|
2126
|
-
'<div class="agent-card-body"><strong>' + escapeHtml(action.title || '-') + '</strong><br>' + escapeHtml(action.reason || '') + '</div>' +
|
|
2127
|
-
renderAgentPills([action.tool || '', action.command || ''].filter(Boolean)) +
|
|
2128
|
-
renderAgentPills(action.validation || []) +
|
|
2129
|
-
'</div>' +
|
|
2130
|
-
'<div class="agent-card">' +
|
|
2131
|
-
'<div class="agent-card-title"><span>Prompt Pack</span><button id="copy-agent-prompt" class="btn-sm">Copy</button></div>' +
|
|
2132
|
-
'<textarea id="agent-prompt-text" class="agent-prompt" readonly>' + escapeHtml(promptText) + '</textarea>' +
|
|
2133
|
-
'</div>' +
|
|
2134
|
-
'</div>' +
|
|
2135
|
-
'<div class="agent-stack">' +
|
|
2136
|
-
'<div class="agent-card">' +
|
|
2137
|
-
'<div class="agent-card-title"><span>Brain</span><span class="agent-severity info">' + escapeHtml(brain.oauth || 'unknown') + '</span></div>' +
|
|
2138
|
-
'<div class="agent-card-body">' + escapeHtml(brain.note || '') + '</div>' +
|
|
2139
|
-
renderAgentPills([brain.statusTool || 'mandu.brain.status']) +
|
|
2140
|
-
'</div>' +
|
|
2141
|
-
'<div class="agent-card">' +
|
|
2142
|
-
'<div class="agent-card-title"><span>Tool Router</span></div>';
|
|
2143
|
-
|
|
2144
|
-
for (var i = 0; i < recs.length; i++) {
|
|
2145
|
-
var r = recs[i];
|
|
2146
|
-
html += '<div class="agent-rec">' +
|
|
2147
|
-
'<div class="agent-rec-title">' + escapeHtml(r.skill) + '</div>' +
|
|
2148
|
-
'<div class="agent-rec-detail">' +
|
|
2149
|
-
'<strong>' + escapeHtml(r.task) + '</strong><br>' +
|
|
2150
|
-
escapeHtml(r.useWhen) +
|
|
2151
|
-
renderAgentPills(r.mcpTools || []) +
|
|
2152
|
-
'<div style="margin-top:6px;">Fallback: <code>' + escapeHtml(r.cliFallback) + '</code></div>' +
|
|
2153
|
-
'</div>' +
|
|
2154
|
-
'</div>';
|
|
2155
|
-
}
|
|
2156
|
-
|
|
2157
|
-
html += '</div><div class="agent-card">' +
|
|
2158
|
-
'<div class="agent-card-title"><span>Knowledge</span></div>';
|
|
2159
|
-
|
|
2160
|
-
for (var c = 0; c < cards.length; c++) {
|
|
2161
|
-
var card = cards[c];
|
|
2162
|
-
html += '<div class="agent-rec">' +
|
|
2163
|
-
'<div class="agent-rec-title">' + escapeHtml(card.title) + '</div>' +
|
|
2164
|
-
'<div class="agent-rec-detail">' + escapeHtml(card.body) + renderAgentPills(card.references || []) + '</div>' +
|
|
2165
|
-
'</div>';
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
|
-
html += '</div></div></div>';
|
|
2169
|
-
agentContentEl.innerHTML = html;
|
|
2170
|
-
|
|
2171
|
-
var copyBtn = document.getElementById('copy-agent-prompt');
|
|
2172
|
-
if (copyBtn) {
|
|
2173
|
-
copyBtn.addEventListener('click', function() {
|
|
2174
|
-
var textEl = document.getElementById('agent-prompt-text');
|
|
2175
|
-
var text = textEl ? textEl.value : promptText;
|
|
2176
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
2177
|
-
navigator.clipboard.writeText(text).then(function() {
|
|
2178
|
-
copyBtn.textContent = 'Copied';
|
|
2179
|
-
setTimeout(function() { copyBtn.textContent = 'Copy'; }, 900);
|
|
2180
|
-
}).catch(function() {
|
|
2181
|
-
textEl && textEl.select();
|
|
2182
|
-
});
|
|
2183
|
-
} else if (textEl) {
|
|
2184
|
-
textEl.select();
|
|
2185
|
-
}
|
|
2186
|
-
});
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
|
-
function loadAgentContext() {
|
|
2191
|
-
if (!agentContentEl) return;
|
|
2192
|
-
agentContentEl.innerHTML = '<div class="empty-state">Building agent context...</div>';
|
|
2193
|
-
fetchJson('/__kitchen/api/agent-context', function(err, data) {
|
|
2194
|
-
if (err) {
|
|
2195
|
-
agentContentEl.innerHTML = '<div class="empty-state">Failed: ' + escapeHtml(err.message) + '</div>';
|
|
2196
|
-
return;
|
|
2197
|
-
}
|
|
2198
|
-
renderAgentContext(data);
|
|
2199
|
-
});
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
document.getElementById('refresh-agent').addEventListener('click', loadAgentContext);
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2367
|
+
function statusClass(s) {
|
|
2368
|
+
if (!s) return '';
|
|
2369
|
+
if (s >= 500) return 's5';
|
|
2370
|
+
if (s >= 400) return 's4';
|
|
2371
|
+
if (s >= 300) return 's3';
|
|
2372
|
+
return 's2';
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
// ─── Agent Supervisor Tab ─────────────────────
|
|
2376
|
+
function renderAgentPills(items) {
|
|
2377
|
+
if (!items || !items.length) return '';
|
|
2378
|
+
var html = '<div class="agent-pill-row">';
|
|
2379
|
+
for (var i = 0; i < items.length; i++) {
|
|
2380
|
+
html += '<span class="agent-pill">' + escapeHtml(items[i]) + '</span>';
|
|
2381
|
+
}
|
|
2382
|
+
return html + '</div>';
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
function renderAgentDetails(items) {
|
|
2386
|
+
if (!items || !items.length) return '';
|
|
2387
|
+
var html = '<ul>';
|
|
2388
|
+
for (var i = 0; i < items.length; i++) {
|
|
2389
|
+
html += '<li>' + escapeHtml(items[i]) + '</li>';
|
|
2390
|
+
}
|
|
2391
|
+
return html + '</ul>';
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
function renderAgentContext(data) {
|
|
2395
|
+
var situation = data.situation || {};
|
|
2396
|
+
var summary = data.summary || {};
|
|
2397
|
+
var routes = summary.routes || {};
|
|
2398
|
+
var status = data.agentStatus || {};
|
|
2399
|
+
var brain = status.brain || {};
|
|
2400
|
+
var action = data.nextSafeAction || {};
|
|
2401
|
+
var prompt = data.prompt || {};
|
|
2402
|
+
var recs = data.toolRecommendations || [];
|
|
2403
|
+
var cards = data.knowledgeCards || [];
|
|
2404
|
+
var promptText = prompt.copyText || '';
|
|
2405
|
+
|
|
2406
|
+
var html = '<div class="agent-grid">' +
|
|
2407
|
+
'<div class="agent-stack">' +
|
|
2408
|
+
'<div class="agent-card">' +
|
|
2409
|
+
'<div class="agent-card-title">' +
|
|
2410
|
+
'<span>' + escapeHtml(situation.title || 'No situation') + '</span>' +
|
|
2411
|
+
'<span class="agent-severity ' + escapeHtml(situation.severity || 'info') + '">' + escapeHtml(situation.category || 'agent') + '</span>' +
|
|
2412
|
+
'</div>' +
|
|
2413
|
+
'<div class="agent-card-body">' + renderAgentDetails(situation.details || []) + '</div>' +
|
|
2414
|
+
'<div class="agent-stat-grid">' +
|
|
2415
|
+
'<div class="agent-stat"><div class="agent-stat-label">Routes</div><div class="agent-stat-value">' + escapeHtml(routes.total || 0) + '</div></div>' +
|
|
2416
|
+
'<div class="agent-stat"><div class="agent-stat-label">Islands</div><div class="agent-stat-value">' + escapeHtml(routes.islands || 0) + '</div></div>' +
|
|
2417
|
+
'<div class="agent-stat"><div class="agent-stat-label">Contracts</div><div class="agent-stat-value">' + escapeHtml(routes.contracts || 0) + '</div></div>' +
|
|
2418
|
+
'<div class="agent-stat"><div class="agent-stat-label">MCP Calls</div><div class="agent-stat-value">' + escapeHtml(status.observedToolCalls || 0) + '</div></div>' +
|
|
2419
|
+
'</div>' +
|
|
2420
|
+
'</div>' +
|
|
2421
|
+
'<div class="agent-card">' +
|
|
2422
|
+
'<div class="agent-card-title"><span>Next Safe Action</span><span class="agent-severity info">' + escapeHtml(action.mode || 'observe') + '</span></div>' +
|
|
2423
|
+
'<div class="agent-card-body"><strong>' + escapeHtml(action.title || '-') + '</strong><br>' + escapeHtml(action.reason || '') + '</div>' +
|
|
2424
|
+
renderAgentPills([action.tool || '', action.command || ''].filter(Boolean)) +
|
|
2425
|
+
renderAgentPills(action.validation || []) +
|
|
2426
|
+
'</div>' +
|
|
2427
|
+
'<div class="agent-card">' +
|
|
2428
|
+
'<div class="agent-card-title"><span>Prompt Pack</span><button id="copy-agent-prompt" class="btn-sm">Copy</button></div>' +
|
|
2429
|
+
'<textarea id="agent-prompt-text" class="agent-prompt" readonly>' + escapeHtml(promptText) + '</textarea>' +
|
|
2430
|
+
'</div>' +
|
|
2431
|
+
'</div>' +
|
|
2432
|
+
'<div class="agent-stack">' +
|
|
2433
|
+
'<div class="agent-card">' +
|
|
2434
|
+
'<div class="agent-card-title"><span>Brain</span><span class="agent-severity info">' + escapeHtml(brain.oauth || 'unknown') + '</span></div>' +
|
|
2435
|
+
'<div class="agent-card-body">' + escapeHtml(brain.note || '') + '</div>' +
|
|
2436
|
+
renderAgentPills([brain.statusTool || 'mandu.brain.status']) +
|
|
2437
|
+
'</div>' +
|
|
2438
|
+
'<div class="agent-card">' +
|
|
2439
|
+
'<div class="agent-card-title"><span>Tool Router</span></div>';
|
|
2440
|
+
|
|
2441
|
+
for (var i = 0; i < recs.length; i++) {
|
|
2442
|
+
var r = recs[i];
|
|
2443
|
+
html += '<div class="agent-rec">' +
|
|
2444
|
+
'<div class="agent-rec-title">' + escapeHtml(r.skill) + '</div>' +
|
|
2445
|
+
'<div class="agent-rec-detail">' +
|
|
2446
|
+
'<strong>' + escapeHtml(r.task) + '</strong><br>' +
|
|
2447
|
+
escapeHtml(r.useWhen) +
|
|
2448
|
+
renderAgentPills(r.mcpTools || []) +
|
|
2449
|
+
'<div style="margin-top:6px;">Fallback: <code>' + escapeHtml(r.cliFallback) + '</code></div>' +
|
|
2450
|
+
'</div>' +
|
|
2451
|
+
'</div>';
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
html += '</div><div class="agent-card">' +
|
|
2455
|
+
'<div class="agent-card-title"><span>Knowledge</span></div>';
|
|
2456
|
+
|
|
2457
|
+
for (var c = 0; c < cards.length; c++) {
|
|
2458
|
+
var card = cards[c];
|
|
2459
|
+
html += '<div class="agent-rec">' +
|
|
2460
|
+
'<div class="agent-rec-title">' + escapeHtml(card.title) + '</div>' +
|
|
2461
|
+
'<div class="agent-rec-detail">' + escapeHtml(card.body) + renderAgentPills(card.references || []) + '</div>' +
|
|
2462
|
+
'</div>';
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
html += '</div></div></div>';
|
|
2466
|
+
agentContentEl.innerHTML = html;
|
|
2467
|
+
|
|
2468
|
+
var copyBtn = document.getElementById('copy-agent-prompt');
|
|
2469
|
+
if (copyBtn) {
|
|
2470
|
+
copyBtn.addEventListener('click', function() {
|
|
2471
|
+
var textEl = document.getElementById('agent-prompt-text');
|
|
2472
|
+
var text = textEl ? textEl.value : promptText;
|
|
2473
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
2474
|
+
navigator.clipboard.writeText(text).then(function() {
|
|
2475
|
+
copyBtn.textContent = 'Copied';
|
|
2476
|
+
setTimeout(function() { copyBtn.textContent = 'Copy'; }, 900);
|
|
2477
|
+
}).catch(function() {
|
|
2478
|
+
textEl && textEl.select();
|
|
2479
|
+
});
|
|
2480
|
+
} else if (textEl) {
|
|
2481
|
+
textEl.select();
|
|
2482
|
+
}
|
|
2483
|
+
});
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
function loadAgentContext() {
|
|
2488
|
+
if (!agentContentEl) return;
|
|
2489
|
+
agentContentEl.innerHTML = '<div class="empty-state">Building agent context...</div>';
|
|
2490
|
+
fetchJson('/__kitchen/api/agent-context', function(err, data) {
|
|
2491
|
+
if (err) {
|
|
2492
|
+
agentContentEl.innerHTML = '<div class="empty-state">Failed: ' + escapeHtml(err.message) + '</div>';
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
renderAgentContext(data);
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
document.getElementById('refresh-agent').addEventListener('click', loadAgentContext);
|
|
2500
|
+
|
|
2501
|
+
// ─── Errors (plan 18 P1-4) ──────────────────
|
|
2502
|
+
var errorsSummaryEl = document.getElementById('errors-summary-text');
|
|
2503
|
+
var errorsListEl = document.getElementById('errors-list');
|
|
2504
|
+
|
|
2505
|
+
function fmtRelTime(ts) {
|
|
2506
|
+
if (!ts) return '-';
|
|
2507
|
+
var diff = Date.now() - ts;
|
|
2508
|
+
if (diff < 0) diff = 0;
|
|
2509
|
+
if (diff < 5_000) return 'just now';
|
|
2510
|
+
if (diff < 60_000) return Math.round(diff / 1000) + 's ago';
|
|
2511
|
+
if (diff < 3_600_000) return Math.round(diff / 60_000) + 'm ago';
|
|
2512
|
+
if (diff < 86_400_000) return Math.round(diff / 3_600_000) + 'h ago';
|
|
2513
|
+
return new Date(ts).toLocaleString();
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
function loadErrors() {
|
|
2517
|
+
if (!errorsListEl) return;
|
|
2518
|
+
errorsListEl.innerHTML = '<div class="empty-state">Loading errors...</div>';
|
|
2519
|
+
fetchJson('/__kitchen/api/errors/grouped', function(err, data) {
|
|
2520
|
+
if (err) {
|
|
2521
|
+
errorsListEl.innerHTML = '<div class="empty-state">Failed: ' + escapeHtml(err.message) + '</div>';
|
|
2522
|
+
return;
|
|
2523
|
+
}
|
|
2524
|
+
var groups = data.groups || [];
|
|
2525
|
+
var total = data.totalCount || 0;
|
|
2526
|
+
var groupCount = data.groupCount || 0;
|
|
2527
|
+
if (errorsSummaryEl) {
|
|
2528
|
+
errorsSummaryEl.textContent = total === 0
|
|
2529
|
+
? 'No errors captured yet.'
|
|
2530
|
+
: total + ' raw error(s) collapsed into ' + groupCount + ' group(s).';
|
|
2531
|
+
}
|
|
2532
|
+
if (!groups.length) {
|
|
2533
|
+
errorsListEl.innerHTML = '<div class="empty-state">No errors captured yet.</div>';
|
|
2534
|
+
return;
|
|
2535
|
+
}
|
|
2536
|
+
var html = '';
|
|
2537
|
+
for (var i = 0; i < groups.length; i++) {
|
|
2538
|
+
var g = groups[i];
|
|
2539
|
+
var sample = g.sample || {};
|
|
2540
|
+
var sources = (g.affectedSources || []).join(', ') || sample.source || 'unknown';
|
|
2541
|
+
var sev = sample.severity || g.severity || 'error';
|
|
2542
|
+
var countCls = g.count >= 5 ? 'error-count' : 'error-count dim';
|
|
2543
|
+
var stackBlock = sample.stack
|
|
2544
|
+
? '<div class="error-detail">' + escapeHtml(sample.stack) + '</div>'
|
|
2545
|
+
: '<div class="error-detail">No stack frame captured.</div>';
|
|
2546
|
+
html += '<div class="error-group" data-key="' + escapeHtml(g.key) + '">' +
|
|
2547
|
+
'<div class="error-group-head">' +
|
|
2548
|
+
'<span class="' + countCls + '">x' + g.count + '</span>' +
|
|
2549
|
+
'<span class="error-severity">' + escapeHtml(sev) + '</span>' +
|
|
2550
|
+
'<div class="error-message">' + escapeHtml(sample.message || '(no message)') + '</div>' +
|
|
2551
|
+
'</div>' +
|
|
2552
|
+
'<div class="error-meta">' +
|
|
2553
|
+
'<span>first: ' + escapeHtml(fmtRelTime(g.firstSeen)) + '</span>' +
|
|
2554
|
+
'<span>last: ' + escapeHtml(fmtRelTime(g.lastSeen)) + '</span>' +
|
|
2555
|
+
'<span>sources: ' + escapeHtml(sources) + '</span>' +
|
|
2556
|
+
(sample.line ? '<span>line ' + escapeHtml(String(sample.line)) + '</span>' : '') +
|
|
2557
|
+
'</div>' +
|
|
2558
|
+
stackBlock +
|
|
2559
|
+
'</div>';
|
|
2560
|
+
}
|
|
2561
|
+
errorsListEl.innerHTML = html;
|
|
2562
|
+
var rows = errorsListEl.querySelectorAll('.error-group');
|
|
2563
|
+
for (var r = 0; r < rows.length; r++) {
|
|
2564
|
+
rows[r].addEventListener('click', function() {
|
|
2565
|
+
this.classList.toggle('expanded');
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
var refreshErrorsBtn = document.getElementById('refresh-errors');
|
|
2572
|
+
if (refreshErrorsBtn) refreshErrorsBtn.addEventListener('click', loadErrors);
|
|
2573
|
+
|
|
2574
|
+
var clearErrorsBtn = document.getElementById('clear-errors');
|
|
2575
|
+
if (clearErrorsBtn) clearErrorsBtn.addEventListener('click', function() {
|
|
2576
|
+
fetch('/__kitchen/api/errors', { method: 'DELETE' })
|
|
2577
|
+
.then(function() { loadErrors(); })
|
|
2578
|
+
.catch(function() { /* noop */ });
|
|
2579
|
+
});
|
|
2580
|
+
|
|
2581
|
+
function loadRequests() {
|
|
2582
|
+
requestsListEl.innerHTML = '<div class="empty-state">Loading requests...</div>';
|
|
2206
2583
|
fetchJson('/__kitchen/api/requests?limit=100', function(err, data) {
|
|
2207
2584
|
if (err) {
|
|
2208
2585
|
requestsListEl.innerHTML = '<div class="empty-state">Failed: ' + escapeHtml(err.message) + '</div>';
|
|
@@ -2399,13 +2776,14 @@ const JS = /* js */ `
|
|
|
2399
2776
|
document.getElementById('refresh-metrics').addEventListener('click', loadMetrics);
|
|
2400
2777
|
|
|
2401
2778
|
// Lazy-load new tab data when clicked (avoids loading everything up front)
|
|
2402
|
-
var tabLoaders = {
|
|
2403
|
-
'agent': loadAgentContext,
|
|
2404
|
-
'
|
|
2405
|
-
'
|
|
2406
|
-
'
|
|
2407
|
-
'
|
|
2408
|
-
|
|
2779
|
+
var tabLoaders = {
|
|
2780
|
+
'agent': loadAgentContext,
|
|
2781
|
+
'errors': loadErrors,
|
|
2782
|
+
'requests': loadRequests,
|
|
2783
|
+
'mcp-activity': loadMcpActivity,
|
|
2784
|
+
'cache': loadCacheStats,
|
|
2785
|
+
'metrics': loadMetrics
|
|
2786
|
+
};
|
|
2409
2787
|
var loadedTabs = {};
|
|
2410
2788
|
for (var t = 0; t < tabs.length; t++) {
|
|
2411
2789
|
tabs[t].addEventListener('click', function() {
|