@jamiexiongr/panda-hub 0.1.4 → 0.1.6

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.
@@ -12726,7 +12726,7 @@ var startPandaSessionService = async ({
12726
12726
  if (managedTimeline) {
12727
12727
  return mergeTimelineEntries(managedTimeline, readTimelineOverlay(sessionId, managedTimeline));
12728
12728
  }
12729
- const { readCodexTimeline: readCodexTimeline2 } = await import("./src-A2O4IXQ2.mjs");
12729
+ const { readCodexTimeline: readCodexTimeline2 } = await import("./src-634HZ7MS.mjs");
12730
12730
  const discoveredTimeline = await readCodexTimeline2(sessionId, {
12731
12731
  codexHome,
12732
12732
  sessionFiles: discoveredSessionFiles
@@ -13411,7 +13411,7 @@ var startPandaSessionService = async ({
13411
13411
  lastSnapshotRefreshAt = Date.now();
13412
13412
  return snapshot;
13413
13413
  }
13414
- const { discoverLocalCodexData: discoverLocalCodexData2 } = await import("./src-A2O4IXQ2.mjs");
13414
+ const { discoverLocalCodexData: discoverLocalCodexData2 } = await import("./src-634HZ7MS.mjs");
13415
13415
  const discovery = await discoverLocalCodexData2({
13416
13416
  agentId: localAgentId,
13417
13417
  agentName: localAgentName,
@@ -15585,11 +15585,29 @@ var ENABLED_ARGS = /* @__PURE__ */ new Set([
15585
15585
  "tailscale-serve",
15586
15586
  "--tailscale-serve"
15587
15587
  ]);
15588
+ var PUBLIC_ARGS = /* @__PURE__ */ new Set([
15589
+ "tailscareserv-pub",
15590
+ "--tailscareserv-pub",
15591
+ "tailscale-serve-pub",
15592
+ "--tailscale-serve-pub",
15593
+ "tailscalefunnel",
15594
+ "--tailscalefunnel",
15595
+ "tailscale-funnel",
15596
+ "--tailscale-funnel"
15597
+ ]);
15588
15598
  var DISABLED_ARGS = /* @__PURE__ */ new Set([
15589
15599
  "no-tailscareserv",
15590
15600
  "--no-tailscareserv",
15591
15601
  "no-tailscale-serve",
15592
- "--no-tailscale-serve"
15602
+ "--no-tailscale-serve",
15603
+ "no-tailscareserv-pub",
15604
+ "--no-tailscareserv-pub",
15605
+ "no-tailscale-serve-pub",
15606
+ "--no-tailscale-serve-pub",
15607
+ "no-tailscalefunnel",
15608
+ "--no-tailscalefunnel",
15609
+ "no-tailscale-funnel",
15610
+ "--no-tailscale-funnel"
15593
15611
  ]);
15594
15612
  var trimToNull2 = (value) => {
15595
15613
  const normalized = value?.trim() ?? "";
@@ -15645,6 +15663,22 @@ var parseBooleanLike = (value) => {
15645
15663
  }
15646
15664
  return null;
15647
15665
  };
15666
+ var parsePublicationModeLike = (value) => {
15667
+ const normalized = trimToNull2(value)?.toLowerCase();
15668
+ if (!normalized) {
15669
+ return null;
15670
+ }
15671
+ if (["serve", "private", "tailnet"].includes(normalized)) {
15672
+ return "serve";
15673
+ }
15674
+ if (["funnel", "public", "pub"].includes(normalized)) {
15675
+ return "funnel";
15676
+ }
15677
+ if (["disabled", "none", "off"].includes(normalized)) {
15678
+ return "disabled";
15679
+ }
15680
+ return null;
15681
+ };
15648
15682
  var parsePort = (value) => {
15649
15683
  const normalized = trimToNull2(value);
15650
15684
  if (!normalized) {
@@ -15701,18 +15735,44 @@ var isTailscaleRunning = (status) => {
15701
15735
  );
15702
15736
  };
15703
15737
  var resolveTailscaleServeEnabled = (options) => {
15738
+ return resolveTailscalePublicationMode({
15739
+ argv: options?.argv,
15740
+ env: options?.env,
15741
+ envPrefix: options?.envPrefix
15742
+ }) === "serve";
15743
+ };
15744
+ var resolveTailscalePublicationMode = (options) => {
15704
15745
  const argv = options?.argv ?? [];
15705
15746
  for (const candidate of argv) {
15706
15747
  const normalized = candidate.trim().toLowerCase();
15748
+ if (PUBLIC_ARGS.has(normalized)) {
15749
+ return "funnel";
15750
+ }
15707
15751
  if (ENABLED_ARGS.has(normalized)) {
15708
- return true;
15752
+ return "serve";
15709
15753
  }
15710
15754
  if (DISABLED_ARGS.has(normalized)) {
15711
- return false;
15755
+ return "disabled";
15712
15756
  }
15713
15757
  }
15714
- const envEnabled = parseBooleanLike((options?.env ?? process.env).PANDA_TAILSCALE_SERVE);
15715
- return envEnabled ?? false;
15758
+ const env = options?.env ?? process.env;
15759
+ const scopedMode = options?.envPrefix ? parsePublicationModeLike(env[`${options.envPrefix}_TAILSCALE_PUBLISH_MODE`]) : null;
15760
+ if (scopedMode) {
15761
+ return scopedMode;
15762
+ }
15763
+ const genericMode = parsePublicationModeLike(env.PANDA_TAILSCALE_PUBLISH_MODE);
15764
+ if (genericMode) {
15765
+ return genericMode;
15766
+ }
15767
+ const scopedEnabled = options?.envPrefix ? parseBooleanLike(env[`${options.envPrefix}_TAILSCALE_SERVE`]) : null;
15768
+ if (scopedEnabled !== null) {
15769
+ return scopedEnabled ? "serve" : "disabled";
15770
+ }
15771
+ const envEnabled = parseBooleanLike(env.PANDA_TAILSCALE_SERVE);
15772
+ if (envEnabled !== null) {
15773
+ return envEnabled ? "serve" : "disabled";
15774
+ }
15775
+ return "disabled";
15716
15776
  };
15717
15777
  var resolveTailscaleServePort = (options) => {
15718
15778
  const env = options.env ?? process.env;
@@ -15721,10 +15781,14 @@ var resolveTailscaleServePort = (options) => {
15721
15781
  return scopedPort ?? genericPort ?? options.defaultPort;
15722
15782
  };
15723
15783
  var configureTailscaleServe = (options) => {
15784
+ const mode = options.enabled ? options.mode ?? "serve" : "disabled";
15785
+ const publishCommand = mode === "funnel" ? "funnel" : "serve";
15786
+ const publishLabel = mode === "funnel" ? "Tailscale Funnel" : "Tailscale Serve";
15724
15787
  if (!options.enabled) {
15725
15788
  return {
15726
15789
  enabled: false,
15727
15790
  active: false,
15791
+ mode,
15728
15792
  servePort: null,
15729
15793
  dnsName: null,
15730
15794
  tailscaleIp: null,
@@ -15736,11 +15800,12 @@ var configureTailscaleServe = (options) => {
15736
15800
  const status = readTailscaleStatus();
15737
15801
  if (!status) {
15738
15802
  options.logger?.warn?.(
15739
- `Skipping Tailscale Serve for ${options.serviceName}: tailscale CLI is unavailable or not logged in.`
15803
+ `Skipping ${publishLabel} for ${options.serviceName}: tailscale CLI is unavailable or not logged in.`
15740
15804
  );
15741
15805
  return {
15742
15806
  enabled: true,
15743
15807
  active: false,
15808
+ mode,
15744
15809
  servePort: options.servePort,
15745
15810
  dnsName: null,
15746
15811
  tailscaleIp: null,
@@ -15751,11 +15816,12 @@ var configureTailscaleServe = (options) => {
15751
15816
  }
15752
15817
  if (!isTailscaleRunning(status)) {
15753
15818
  options.logger?.warn?.(
15754
- `Skipping Tailscale Serve for ${options.serviceName}: Tailscale is not running.`
15819
+ `Skipping ${publishLabel} for ${options.serviceName}: Tailscale is not running.`
15755
15820
  );
15756
15821
  return {
15757
15822
  enabled: true,
15758
15823
  active: false,
15824
+ mode,
15759
15825
  servePort: options.servePort,
15760
15826
  dnsName: normalizeDnsName(status.Self?.DNSName),
15761
15827
  tailscaleIp: trimToNull2(status.Self?.TailscaleIPs?.[0]),
@@ -15768,11 +15834,12 @@ var configureTailscaleServe = (options) => {
15768
15834
  const tailscaleIp = trimToNull2(status.Self?.TailscaleIPs?.[0]);
15769
15835
  if (!dnsName) {
15770
15836
  options.logger?.warn?.(
15771
- `Skipping Tailscale Serve for ${options.serviceName}: MagicDNS name is unavailable.`
15837
+ `Skipping ${publishLabel} for ${options.serviceName}: MagicDNS name is unavailable.`
15772
15838
  );
15773
15839
  return {
15774
15840
  enabled: true,
15775
15841
  active: false,
15842
+ mode,
15776
15843
  servePort: options.servePort,
15777
15844
  dnsName: null,
15778
15845
  tailscaleIp,
@@ -15785,7 +15852,7 @@ var configureTailscaleServe = (options) => {
15785
15852
  execFileSync(
15786
15853
  "tailscale",
15787
15854
  [
15788
- "serve",
15855
+ publishCommand,
15789
15856
  "--yes",
15790
15857
  "--bg",
15791
15858
  `--https=${options.servePort}`,
@@ -15801,11 +15868,12 @@ var configureTailscaleServe = (options) => {
15801
15868
  } catch (error) {
15802
15869
  const message = describeExecError(error);
15803
15870
  options.logger?.warn?.(
15804
- `Unable to publish ${options.serviceName} via Tailscale Serve: ${message}`
15871
+ `Unable to publish ${options.serviceName} via ${publishLabel}: ${message}`
15805
15872
  );
15806
15873
  return {
15807
15874
  enabled: true,
15808
15875
  active: false,
15876
+ mode,
15809
15877
  servePort: options.servePort,
15810
15878
  dnsName,
15811
15879
  tailscaleIp,
@@ -15822,6 +15890,7 @@ var configureTailscaleServe = (options) => {
15822
15890
  return {
15823
15891
  enabled: true,
15824
15892
  active: false,
15893
+ mode,
15825
15894
  servePort: options.servePort,
15826
15895
  dnsName,
15827
15896
  tailscaleIp,
@@ -15831,11 +15900,12 @@ var configureTailscaleServe = (options) => {
15831
15900
  };
15832
15901
  }
15833
15902
  options.logger?.info?.(
15834
- `Published ${options.serviceName} over Tailscale Serve at ${baseUrl}`
15903
+ `Published ${options.serviceName} over ${publishLabel} at ${baseUrl}`
15835
15904
  );
15836
15905
  return {
15837
15906
  enabled: true,
15838
15907
  active: true,
15908
+ mode,
15839
15909
  servePort: options.servePort,
15840
15910
  dnsName,
15841
15911
  tailscaleIp,
@@ -16992,6 +17062,7 @@ export {
16992
17062
  readTailscaleStatus,
16993
17063
  isTailscaleRunning,
16994
17064
  resolveTailscaleServeEnabled,
17065
+ resolveTailscalePublicationMode,
16995
17066
  resolveTailscaleServePort,
16996
17067
  configureTailscaleServe,
16997
17068
  resolveAgentNetworkIdentity,
@@ -2,10 +2,10 @@ import {
2
2
  configureTailscaleServe,
3
3
  ensurePandaHubApiKey,
4
4
  printTerminalQr,
5
- resolveTailscaleServeEnabled,
5
+ resolveTailscalePublicationMode,
6
6
  resolveTailscaleServePort,
7
7
  startPandaSessionService
8
- } from "./chunk-I3VRWQCP.mjs";
8
+ } from "./chunk-GGRPEOCD.mjs";
9
9
 
10
10
  // release/panda-hub/src/index.ts
11
11
  import fs from "fs";
@@ -15,7 +15,7 @@ import { fileURLToPath } from "url";
15
15
  // release/panda-hub/package.json
16
16
  var package_default = {
17
17
  name: "@jamiexiongr/panda-hub",
18
- version: "0.1.4",
18
+ version: "0.1.6",
19
19
  type: "module",
20
20
  private: false,
21
21
  description: "Panda hub runtime",
@@ -54,9 +54,13 @@ var resolveBundledWebUiDir = () => {
54
54
  return candidates.find((candidate) => fs.existsSync(candidate)) ?? candidates[0];
55
55
  };
56
56
  var startJamiexiongrHub = async (options) => {
57
+ const publishMode = options?.tailscalePublicationMode ?? resolveTailscalePublicationMode({
58
+ envPrefix: "PANDA_HUB"
59
+ });
57
60
  const port = Number(process.env.PANDA_HUB_PORT ?? 4343);
58
61
  const tailscaleServe = configureTailscaleServe({
59
- enabled: options?.tailscaleServe ?? resolveTailscaleServeEnabled(),
62
+ enabled: publishMode !== "disabled",
63
+ mode: publishMode === "disabled" ? void 0 : publishMode,
60
64
  serviceName: "panda-hub",
61
65
  localPort: port,
62
66
  servePort: resolveTailscaleServePort({
@@ -83,11 +87,16 @@ var startJamiexiongrHub = async (options) => {
83
87
  webUiDir
84
88
  });
85
89
  if (tailscaleServe.active && tailscaleServe.baseUrl) {
86
- console.info(`Panda hub Tailscale HTTPS URL: ${tailscaleServe.baseUrl}`);
87
- console.info(`Agent hub URL env: PANDA_HUB_URL=${tailscaleServe.baseUrl}`);
90
+ if (tailscaleServe.mode === "funnel") {
91
+ console.info(`Panda hub Public HTTPS URL: ${tailscaleServe.baseUrl}`);
92
+ console.info(`Public PWA install URL: ${tailscaleServe.baseUrl}`);
93
+ } else {
94
+ console.info(`Panda hub Tailscale HTTPS URL: ${tailscaleServe.baseUrl}`);
95
+ console.info(`Agent hub URL env: PANDA_HUB_URL=${tailscaleServe.baseUrl}`);
96
+ }
88
97
  printTerminalQr(tailscaleServe.baseUrl, {
89
98
  logger: console,
90
- label: "Scan this QR code to open Panda hub on your phone:"
99
+ label: tailscaleServe.mode === "funnel" ? "Scan this QR code to open the public Panda hub on your phone:" : "Scan this QR code to open Panda hub on your phone:"
91
100
  });
92
101
  }
93
102
  return app;
package/dist/cli.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  import {
2
2
  startJamiexiongrHub
3
- } from "./chunk-L4ZJFGL5.mjs";
3
+ } from "./chunk-SWUA5RS3.mjs";
4
4
  import {
5
- resolveTailscaleServeEnabled
6
- } from "./chunk-I3VRWQCP.mjs";
5
+ resolveTailscalePublicationMode
6
+ } from "./chunk-GGRPEOCD.mjs";
7
7
 
8
8
  // release/panda-hub/src/cli.ts
9
9
  void startJamiexiongrHub({
10
- tailscaleServe: resolveTailscaleServeEnabled({
11
- argv: process.argv.slice(2)
10
+ tailscalePublicationMode: resolveTailscalePublicationMode({
11
+ argv: process.argv.slice(2),
12
+ envPrefix: "PANDA_HUB"
12
13
  })
13
14
  });
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  startJamiexiongrHub
3
- } from "./chunk-L4ZJFGL5.mjs";
4
- import "./chunk-I3VRWQCP.mjs";
3
+ } from "./chunk-SWUA5RS3.mjs";
4
+ import "./chunk-GGRPEOCD.mjs";
5
5
  export {
6
6
  startJamiexiongrHub
7
7
  };
@@ -29,6 +29,7 @@ import {
29
29
  resolveAgentNetworkIdentity,
30
30
  resolveCliOptionValue,
31
31
  resolvePandaHubApiKey,
32
+ resolveTailscalePublicationMode,
32
33
  resolveTailscaleServeEnabled,
33
34
  resolveTailscaleServePort,
34
35
  setSessionPinned,
@@ -42,7 +43,7 @@ import {
42
43
  writeCodexGlobalState,
43
44
  writePandaSessionPrefs,
44
45
  writePandaThreadPrefs
45
- } from "./chunk-I3VRWQCP.mjs";
46
+ } from "./chunk-GGRPEOCD.mjs";
46
47
  export {
47
48
  CodexAdapter,
48
49
  appendSessionIndexUpdate,
@@ -74,6 +75,7 @@ export {
74
75
  resolveAgentNetworkIdentity,
75
76
  resolveCliOptionValue,
76
77
  resolvePandaHubApiKey,
78
+ resolveTailscalePublicationMode,
77
79
  resolveTailscaleServeEnabled,
78
80
  resolveTailscaleServePort,
79
81
  setSessionPinned,
@@ -1 +1 @@
1
- import{u as j,r as d,j as e}from"./index-CepnER6o.js";const v=[{key:"color-mix-oklab",property:"background",value:"color-mix(in oklab, white 50%, black)"},{key:"color-mix-srgb",property:"background",value:"color-mix(in srgb, white 50%, black)"},{key:"backdrop-filter",property:"backdrop-filter",value:"blur(12px)"},{key:"webkit-backdrop-filter",property:"-webkit-backdrop-filter",value:"blur(12px)"},{key:"viewport-dvh",property:"height",value:"100dvh"}],y=["--color-surface-base","--color-surface-panel","--color-surface-floating","--color-surface-border","--color-surface-border-soft","--color-text-primary","--color-text-secondary","--color-accent-primary","--color-accent-primary-soft"],w=[".conversation-topbar",".topbar-menu",".conversation-run-popover",".chat-composer",".chat-composer__input",".composer-utility-menu__popover",".session-run-panel__command-card",".session-run-panel__input",".session-git-panel__summary"],b=["background-color","background-image","backdrop-filter","-webkit-backdrop-filter","border-color","box-shadow","color","display","opacity","position"],x=(t,r=180)=>{const n=(t??"").replace(/\s+/g," ").trim();return n?n.length<=r?n:`${n.slice(0,r-1).trimEnd()}…`:null},h=t=>Number(t.toFixed(2)),k=(t,r)=>{var n;if(typeof window>"u"||typeof((n=window.CSS)==null?void 0:n.supports)!="function")return!1;try{return window.CSS.supports(t,r)}catch{return!1}},_=()=>Object.fromEntries(v.map(t=>[t.key,k(t.property,t.value)])),S=()=>typeof document>"u"?[]:Array.from(document.styleSheets).map(t=>{var n,i;let r=null;try{r=t.cssRules.length}catch{r=null}return{href:t.href??null,owner_node:t.ownerNode instanceof Element?t.ownerNode.tagName.toLowerCase():null,media:((i=(n=t.media)==null?void 0:n.mediaText)==null?void 0:i.trim())||null,disabled:t.disabled,css_rule_count:r}}),N=()=>{if(typeof document>"u"||typeof window>"u")return[];const t=new Map,r=(n,i)=>{const o=n==null?void 0:n.trim();if(o)try{const l=new URL(o,window.location.href);if(!/^https?:$/i.test(l.protocol))return;t.set(l.toString(),i)}catch{return}};for(const n of document.styleSheets)r(n.href,"stylesheet");for(const n of Array.from(document.scripts))r(n.src,"script");for(const n of Array.from(document.querySelectorAll('link[rel~="manifest"]')))r(n.href,"manifest");for(const n of Array.from(document.querySelectorAll('link[rel~="icon"], link[rel="apple-touch-icon"]')))r(n.href,"icon");return Array.from(t.entries()).slice(0,20).map(([n,i])=>({url:n,kind:i}))},E=async t=>{const r=async n=>fetch(t.url,{method:n,cache:"no-store",redirect:"follow"});try{let n=await r("HEAD");return(n.status===405||n.status===501)&&(n=await r("GET")),{url:t.url,kind:t.kind,ok:n.ok,status:n.status,content_type:n.headers.get("content-type"),cache_control:n.headers.get("cache-control"),error:null}}catch(n){return{url:t.url,kind:t.kind,ok:!1,status:null,content_type:null,cache_control:null,error:n instanceof Error?n.message:"Unknown fetch failure"}}},C=()=>typeof performance>"u"||typeof performance.getEntriesByType!="function"?[]:performance.getEntriesByType("resource").map(t=>t).filter(t=>{const r=t.name.toLowerCase();return r.includes(".css")||r.includes(".js")||r.includes("manifest")||t.initiatorType==="link"||t.initiatorType==="script"}).slice(-40).map(t=>({name:t.name,initiator_type:t.initiatorType||null,duration_ms:h(t.duration),transfer_size:typeof t.transferSize=="number"?t.transferSize:null,decoded_body_size:typeof t.decodedBodySize=="number"?t.decodedBodySize:null})),T=()=>{if(typeof document>"u"||typeof window>"u")return{};const t=window.getComputedStyle(document.documentElement);return Object.fromEntries(y.map(r=>[r,t.getPropertyValue(r).trim()||"(empty)"]))},R=t=>{if(typeof document>"u"||typeof window>"u")return{selector:t,found:!1,text_preview:null,rect:null,computed:{}};const r=document.querySelector(t);if(!r)return{selector:t,found:!1,text_preview:null,rect:null,computed:{}};const n=r.getBoundingClientRect(),i=window.getComputedStyle(r);return{selector:t,found:!0,text_preview:x(r.textContent),rect:{x:h(n.x),y:h(n.y),width:h(n.width),height:h(n.height)},computed:Object.fromEntries(b.map(o=>[o,i.getPropertyValue(o).trim()||"(empty)"]))}},A=async()=>{if(typeof navigator>"u"||!("serviceWorker"in navigator))return{supported:!1,controller:!1,registrations:[]};try{const t=await navigator.serviceWorker.getRegistrations();return{supported:!0,controller:!!navigator.serviceWorker.controller,registrations:t.map(r=>{var n,i,o;return{scope:r.scope,active_script_url:((n=r.active)==null?void 0:n.scriptURL)??null,waiting_script_url:((i=r.waiting)==null?void 0:i.scriptURL)??null,installing_script_url:((o=r.installing)==null?void 0:o.scriptURL)??null}})}}catch{return{supported:!0,controller:!!navigator.serviceWorker.controller,registrations:[]}}},O=async()=>{if(typeof window>"u"||!("caches"in window))return{supported:!1,keys:[]};try{return{supported:!0,keys:await window.caches.keys()}}catch{return{supported:!0,keys:[]}}},L=t=>{const r=[];return t.feature_support["color-mix-oklab"]||r.push("当前浏览器不支持 color-mix(in oklab, ...),混色背景会直接失效,常见现象就是输入区或面板背景透明。"),!t.feature_support["backdrop-filter"]&&!t.feature_support["webkit-backdrop-filter"]&&r.push("当前浏览器不支持 backdrop-filter,磨砂浮层会退化成纯色面板。"),t.service_worker.controller&&t.cache.keys.length>0&&r.push(`检测到 ${t.cache.keys.length} 个 Cache Storage 项,若真机页面和桌面不一致,可以先清理缓存再重试。`),t.stylesheets.length===0&&r.push("当前页面没有读取到任何样式表对象,需要重点检查 CSS 是否被正确加载。"),t.resource_probes.some(n=>!n.ok)&&r.push("至少有一个静态资源探测失败,需要继续检查网络、缓存或 Service Worker 拦截。"),r},P=async()=>{var u,p,m,s,a,g;const t=N(),[r,n,i]=await Promise.all([A(),O(),Promise.all(t.map(f=>E(f)))]),o=navigator,l={width:window.innerWidth,height:window.innerHeight,device_pixel_ratio:window.devicePixelRatio||1,visual_width:((u=window.visualViewport)==null?void 0:u.width)??null,visual_height:((p=window.visualViewport)==null?void 0:p.height)??null,screen_width:((m=window.screen)==null?void 0:m.width)??null,screen_height:((s=window.screen)==null?void 0:s.height)??null},c={captured_at:new Date().toISOString(),page:{href:window.location.href,pathname:window.location.pathname,referrer:x(document.referrer),visibility_state:document.visibilityState??null},environment:{user_agent:navigator.userAgent,language:navigator.language??null,languages:Array.isArray(navigator.languages)?navigator.languages:[],platform:navigator.platform??null,vendor:navigator.vendor??null,online:typeof navigator.onLine=="boolean"?navigator.onLine:null,cookie_enabled:typeof navigator.cookieEnabled=="boolean"?navigator.cookieEnabled:null,secure_context:window.isSecureContext,standalone_display_mode:window.matchMedia("(display-mode: standalone)").matches,hardware_concurrency:typeof navigator.hardwareConcurrency=="number"?navigator.hardwareConcurrency:null,device_memory_gb:typeof o.deviceMemory=="number"?o.deviceMemory:null,max_touch_points:typeof navigator.maxTouchPoints=="number"?navigator.maxTouchPoints:null},viewport:l,feature_support:_(),service_worker:r,cache:n,manifest:{href:((a=document.querySelector('link[rel~="manifest"]'))==null?void 0:a.href)??null,rel:((g=document.querySelector('link[rel~="manifest"]'))==null?void 0:g.rel)??null},stylesheets:S(),resource_probes:i,performance_entries:C(),theme_variables:T(),element_snapshots:w.map(f=>R(f)),notes:[]};return c.notes=L(c),c},W=t=>t?"支持":"不支持",$=t=>t?t.feature_support["color-mix-oklab"]?t.resource_probes.some(r=>!r.ok)?"至少有一个静态资源探测失败,更像是 CSS 或脚本资源没有正确加载,或者被缓存 / Service Worker 干扰。":t.service_worker.controller&&t.cache.keys.length>0?"样式能力本身看起来正常,但页面被 Service Worker 控制且存在缓存,下一步要重点排查缓存是否陈旧。":"浏览器能力和基础资源看起来正常,下一步需要对比具体元素快照与安卓真机截图。":"高概率是安卓浏览器不支持 color-mix(in oklab, ...),导致输入框和面板的混色背景规则整体失效。":"正在采集浏览器能力、样式表、缓存和关键元素快照。",U=t=>{if(!t.found)return"未找到对应元素";const r=t.computed["background-color"]??"(empty)",n=t.computed["background-image"]??"(empty)";return r==="rgba(0, 0, 0, 0)"&&n==="none"?"背景完全透明":`${r} / ${n}`},M=()=>{const t=j(),[r,n]=d.useState(null),[i,o]=d.useState(!0),[l,c]=d.useState(null),u=async()=>{o(!0),c(null);try{const s=await P();d.startTransition(()=>{n(s)})}catch(s){c(s instanceof Error?`采集失败:${s.message}`:"采集失败,请稍后重试。")}finally{o(!1)}};d.useEffect(()=>{u()},[]);const p=async()=>{var s;if(r){if(typeof navigator>"u"||typeof((s=navigator.clipboard)==null?void 0:s.writeText)!="function"){c("当前浏览器不支持直接复制,请手动截图或长按选择。");return}try{await navigator.clipboard.writeText(JSON.stringify(r,null,2)),c("诊断 JSON 已复制,可以直接发给我继续分析。")}catch(a){c(a instanceof Error?`复制失败:${a.message}`:"复制失败,请手动截图或长按选择。")}}},m=d.useMemo(()=>$(r),[r]);return e.jsx("main",{className:"diagnostics-page",children:e.jsxs("div",{className:"diagnostics-shell",children:[e.jsxs("header",{className:"diagnostics-header",children:[e.jsxs("div",{className:"diagnostics-header__copy",children:[e.jsx("button",{type:"button",className:"diagnostics-back",onClick:()=>void t({to:"/settings"}),children:"返回设置"}),e.jsx("h1",{children:"安卓样式诊断"}),e.jsx("p",{children:"在手机上打开本页,可以直接检查浏览器能力、样式加载、缓存和关键面板快照。"})]}),e.jsxs("div",{className:"diagnostics-toolbar",children:[e.jsx("button",{type:"button",className:"diagnostics-button",onClick:()=>void u(),disabled:i,children:i?"采集中…":"刷新诊断"}),e.jsx("button",{type:"button",className:"diagnostics-button diagnostics-button--ghost",onClick:()=>void p(),disabled:!r,children:"复制 JSON"})]})]}),l?e.jsx("p",{className:"diagnostics-status",children:l}):null,e.jsxs("section",{className:"diagnostics-card diagnostics-card--hero",children:[e.jsx("span",{className:"diagnostics-eyebrow",children:"初步判断"}),e.jsx("h2",{children:m}),e.jsx("p",{children:"真机异常而桌面浏览器和 F12 模拟正常,最常见就是浏览器 CSS 能力和缓存状态与桌面环境不同。"}),r!=null&&r.notes.length?e.jsx("ul",{className:"diagnostics-list",children:r.notes.map(s=>e.jsx("li",{children:s},s))}):null]}),r?e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"diagnostics-grid",children:[e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"环境"}),e.jsxs("dl",{className:"diagnostics-kv",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"页面"}),e.jsx("dd",{children:r.page.pathname})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"安全上下文"}),e.jsx("dd",{children:r.environment.secure_context?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"独立窗口"}),e.jsx("dd",{children:r.environment.standalone_display_mode?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"在线状态"}),e.jsx("dd",{children:r.environment.online==null?"未知":r.environment.online?"在线":"离线"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"视口"}),e.jsxs("dd",{children:[r.viewport.width," x ",r.viewport.height," @ ",r.viewport.device_pixel_ratio]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"UA"}),e.jsx("dd",{className:"diagnostics-break",children:r.environment.user_agent})]})]})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"浏览器能力"}),e.jsx("dl",{className:"diagnostics-kv",children:Object.entries(r.feature_support).map(([s,a])=>e.jsxs("div",{children:[e.jsx("dt",{children:s}),e.jsx("dd",{children:W(a)})]},s))})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"缓存与 SW"}),e.jsxs("dl",{className:"diagnostics-kv",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Service Worker"}),e.jsx("dd",{children:r.service_worker.supported?"支持":"不支持"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"当前受控"}),e.jsx("dd",{children:r.service_worker.controller?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"注册数量"}),e.jsx("dd",{children:r.service_worker.registrations.length})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Cache Storage"}),e.jsx("dd",{children:r.cache.supported?r.cache.keys.join(", ")||"空":"不支持"})]})]})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"主题变量"}),e.jsx("dl",{className:"diagnostics-kv",children:Object.entries(r.theme_variables).map(([s,a])=>e.jsxs("div",{children:[e.jsx("dt",{children:s}),e.jsx("dd",{children:a})]},s))})]})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"资源探测"}),e.jsx("div",{className:"diagnostics-table-wrap",children:e.jsxs("table",{className:"diagnostics-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"类型"}),e.jsx("th",{children:"URL"}),e.jsx("th",{children:"状态"}),e.jsx("th",{children:"内容类型"}),e.jsx("th",{children:"Cache-Control"})]})}),e.jsx("tbody",{children:r.resource_probes.map(s=>e.jsxs("tr",{children:[e.jsx("td",{children:s.kind}),e.jsx("td",{className:"diagnostics-break",children:s.url}),e.jsx("td",{children:s.ok?`OK (${s.status??"-"})`:`失败 (${s.status??"-"})`}),e.jsx("td",{children:s.content_type??"-"}),e.jsx("td",{children:s.cache_control??s.error??"-"})]},`${s.kind}:${s.url}`))})]})})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"关键元素快照"}),e.jsx("div",{className:"diagnostics-element-grid",children:r.element_snapshots.map(s=>e.jsxs("article",{className:"diagnostics-element-card",children:[e.jsx("h3",{children:s.selector}),e.jsx("p",{children:U(s)}),e.jsxs("dl",{className:"diagnostics-kv diagnostics-kv--compact",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"找到元素"}),e.jsx("dd",{children:s.found?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"尺寸"}),e.jsx("dd",{children:s.rect?`${s.rect.width} x ${s.rect.height}`:"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"背景色"}),e.jsx("dd",{children:s.computed["background-color"]??"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"背景图"}),e.jsx("dd",{className:"diagnostics-break",children:s.computed["background-image"]??"-"})]})]})]},s.selector))})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"原始 JSON"}),e.jsx("pre",{className:"diagnostics-json",children:JSON.stringify(r,null,2)})]})]}):e.jsx("section",{className:"diagnostics-card",children:e.jsx("p",{children:"正在等待诊断结果…"})})]})})};export{M as DiagnosticsPage};
1
+ import{u as j,r as d,j as e}from"./index-C4lr-cQs.js";const v=[{key:"color-mix-oklab",property:"background",value:"color-mix(in oklab, white 50%, black)"},{key:"color-mix-srgb",property:"background",value:"color-mix(in srgb, white 50%, black)"},{key:"backdrop-filter",property:"backdrop-filter",value:"blur(12px)"},{key:"webkit-backdrop-filter",property:"-webkit-backdrop-filter",value:"blur(12px)"},{key:"viewport-dvh",property:"height",value:"100dvh"}],y=["--color-surface-base","--color-surface-panel","--color-surface-floating","--color-surface-border","--color-surface-border-soft","--color-text-primary","--color-text-secondary","--color-accent-primary","--color-accent-primary-soft"],w=[".conversation-topbar",".topbar-menu",".conversation-run-popover",".chat-composer",".chat-composer__input",".composer-utility-menu__popover",".session-run-panel__command-card",".session-run-panel__input",".session-git-panel__summary"],b=["background-color","background-image","backdrop-filter","-webkit-backdrop-filter","border-color","box-shadow","color","display","opacity","position"],x=(t,r=180)=>{const n=(t??"").replace(/\s+/g," ").trim();return n?n.length<=r?n:`${n.slice(0,r-1).trimEnd()}…`:null},h=t=>Number(t.toFixed(2)),k=(t,r)=>{var n;if(typeof window>"u"||typeof((n=window.CSS)==null?void 0:n.supports)!="function")return!1;try{return window.CSS.supports(t,r)}catch{return!1}},_=()=>Object.fromEntries(v.map(t=>[t.key,k(t.property,t.value)])),S=()=>typeof document>"u"?[]:Array.from(document.styleSheets).map(t=>{var n,i;let r=null;try{r=t.cssRules.length}catch{r=null}return{href:t.href??null,owner_node:t.ownerNode instanceof Element?t.ownerNode.tagName.toLowerCase():null,media:((i=(n=t.media)==null?void 0:n.mediaText)==null?void 0:i.trim())||null,disabled:t.disabled,css_rule_count:r}}),N=()=>{if(typeof document>"u"||typeof window>"u")return[];const t=new Map,r=(n,i)=>{const o=n==null?void 0:n.trim();if(o)try{const l=new URL(o,window.location.href);if(!/^https?:$/i.test(l.protocol))return;t.set(l.toString(),i)}catch{return}};for(const n of document.styleSheets)r(n.href,"stylesheet");for(const n of Array.from(document.scripts))r(n.src,"script");for(const n of Array.from(document.querySelectorAll('link[rel~="manifest"]')))r(n.href,"manifest");for(const n of Array.from(document.querySelectorAll('link[rel~="icon"], link[rel="apple-touch-icon"]')))r(n.href,"icon");return Array.from(t.entries()).slice(0,20).map(([n,i])=>({url:n,kind:i}))},E=async t=>{const r=async n=>fetch(t.url,{method:n,cache:"no-store",redirect:"follow"});try{let n=await r("HEAD");return(n.status===405||n.status===501)&&(n=await r("GET")),{url:t.url,kind:t.kind,ok:n.ok,status:n.status,content_type:n.headers.get("content-type"),cache_control:n.headers.get("cache-control"),error:null}}catch(n){return{url:t.url,kind:t.kind,ok:!1,status:null,content_type:null,cache_control:null,error:n instanceof Error?n.message:"Unknown fetch failure"}}},C=()=>typeof performance>"u"||typeof performance.getEntriesByType!="function"?[]:performance.getEntriesByType("resource").map(t=>t).filter(t=>{const r=t.name.toLowerCase();return r.includes(".css")||r.includes(".js")||r.includes("manifest")||t.initiatorType==="link"||t.initiatorType==="script"}).slice(-40).map(t=>({name:t.name,initiator_type:t.initiatorType||null,duration_ms:h(t.duration),transfer_size:typeof t.transferSize=="number"?t.transferSize:null,decoded_body_size:typeof t.decodedBodySize=="number"?t.decodedBodySize:null})),T=()=>{if(typeof document>"u"||typeof window>"u")return{};const t=window.getComputedStyle(document.documentElement);return Object.fromEntries(y.map(r=>[r,t.getPropertyValue(r).trim()||"(empty)"]))},R=t=>{if(typeof document>"u"||typeof window>"u")return{selector:t,found:!1,text_preview:null,rect:null,computed:{}};const r=document.querySelector(t);if(!r)return{selector:t,found:!1,text_preview:null,rect:null,computed:{}};const n=r.getBoundingClientRect(),i=window.getComputedStyle(r);return{selector:t,found:!0,text_preview:x(r.textContent),rect:{x:h(n.x),y:h(n.y),width:h(n.width),height:h(n.height)},computed:Object.fromEntries(b.map(o=>[o,i.getPropertyValue(o).trim()||"(empty)"]))}},A=async()=>{if(typeof navigator>"u"||!("serviceWorker"in navigator))return{supported:!1,controller:!1,registrations:[]};try{const t=await navigator.serviceWorker.getRegistrations();return{supported:!0,controller:!!navigator.serviceWorker.controller,registrations:t.map(r=>{var n,i,o;return{scope:r.scope,active_script_url:((n=r.active)==null?void 0:n.scriptURL)??null,waiting_script_url:((i=r.waiting)==null?void 0:i.scriptURL)??null,installing_script_url:((o=r.installing)==null?void 0:o.scriptURL)??null}})}}catch{return{supported:!0,controller:!!navigator.serviceWorker.controller,registrations:[]}}},O=async()=>{if(typeof window>"u"||!("caches"in window))return{supported:!1,keys:[]};try{return{supported:!0,keys:await window.caches.keys()}}catch{return{supported:!0,keys:[]}}},L=t=>{const r=[];return t.feature_support["color-mix-oklab"]||r.push("当前浏览器不支持 color-mix(in oklab, ...),混色背景会直接失效,常见现象就是输入区或面板背景透明。"),!t.feature_support["backdrop-filter"]&&!t.feature_support["webkit-backdrop-filter"]&&r.push("当前浏览器不支持 backdrop-filter,磨砂浮层会退化成纯色面板。"),t.service_worker.controller&&t.cache.keys.length>0&&r.push(`检测到 ${t.cache.keys.length} 个 Cache Storage 项,若真机页面和桌面不一致,可以先清理缓存再重试。`),t.stylesheets.length===0&&r.push("当前页面没有读取到任何样式表对象,需要重点检查 CSS 是否被正确加载。"),t.resource_probes.some(n=>!n.ok)&&r.push("至少有一个静态资源探测失败,需要继续检查网络、缓存或 Service Worker 拦截。"),r},P=async()=>{var u,p,m,s,a,g;const t=N(),[r,n,i]=await Promise.all([A(),O(),Promise.all(t.map(f=>E(f)))]),o=navigator,l={width:window.innerWidth,height:window.innerHeight,device_pixel_ratio:window.devicePixelRatio||1,visual_width:((u=window.visualViewport)==null?void 0:u.width)??null,visual_height:((p=window.visualViewport)==null?void 0:p.height)??null,screen_width:((m=window.screen)==null?void 0:m.width)??null,screen_height:((s=window.screen)==null?void 0:s.height)??null},c={captured_at:new Date().toISOString(),page:{href:window.location.href,pathname:window.location.pathname,referrer:x(document.referrer),visibility_state:document.visibilityState??null},environment:{user_agent:navigator.userAgent,language:navigator.language??null,languages:Array.isArray(navigator.languages)?navigator.languages:[],platform:navigator.platform??null,vendor:navigator.vendor??null,online:typeof navigator.onLine=="boolean"?navigator.onLine:null,cookie_enabled:typeof navigator.cookieEnabled=="boolean"?navigator.cookieEnabled:null,secure_context:window.isSecureContext,standalone_display_mode:window.matchMedia("(display-mode: standalone)").matches,hardware_concurrency:typeof navigator.hardwareConcurrency=="number"?navigator.hardwareConcurrency:null,device_memory_gb:typeof o.deviceMemory=="number"?o.deviceMemory:null,max_touch_points:typeof navigator.maxTouchPoints=="number"?navigator.maxTouchPoints:null},viewport:l,feature_support:_(),service_worker:r,cache:n,manifest:{href:((a=document.querySelector('link[rel~="manifest"]'))==null?void 0:a.href)??null,rel:((g=document.querySelector('link[rel~="manifest"]'))==null?void 0:g.rel)??null},stylesheets:S(),resource_probes:i,performance_entries:C(),theme_variables:T(),element_snapshots:w.map(f=>R(f)),notes:[]};return c.notes=L(c),c},W=t=>t?"支持":"不支持",$=t=>t?t.feature_support["color-mix-oklab"]?t.resource_probes.some(r=>!r.ok)?"至少有一个静态资源探测失败,更像是 CSS 或脚本资源没有正确加载,或者被缓存 / Service Worker 干扰。":t.service_worker.controller&&t.cache.keys.length>0?"样式能力本身看起来正常,但页面被 Service Worker 控制且存在缓存,下一步要重点排查缓存是否陈旧。":"浏览器能力和基础资源看起来正常,下一步需要对比具体元素快照与安卓真机截图。":"高概率是安卓浏览器不支持 color-mix(in oklab, ...),导致输入框和面板的混色背景规则整体失效。":"正在采集浏览器能力、样式表、缓存和关键元素快照。",U=t=>{if(!t.found)return"未找到对应元素";const r=t.computed["background-color"]??"(empty)",n=t.computed["background-image"]??"(empty)";return r==="rgba(0, 0, 0, 0)"&&n==="none"?"背景完全透明":`${r} / ${n}`},M=()=>{const t=j(),[r,n]=d.useState(null),[i,o]=d.useState(!0),[l,c]=d.useState(null),u=async()=>{o(!0),c(null);try{const s=await P();d.startTransition(()=>{n(s)})}catch(s){c(s instanceof Error?`采集失败:${s.message}`:"采集失败,请稍后重试。")}finally{o(!1)}};d.useEffect(()=>{u()},[]);const p=async()=>{var s;if(r){if(typeof navigator>"u"||typeof((s=navigator.clipboard)==null?void 0:s.writeText)!="function"){c("当前浏览器不支持直接复制,请手动截图或长按选择。");return}try{await navigator.clipboard.writeText(JSON.stringify(r,null,2)),c("诊断 JSON 已复制,可以直接发给我继续分析。")}catch(a){c(a instanceof Error?`复制失败:${a.message}`:"复制失败,请手动截图或长按选择。")}}},m=d.useMemo(()=>$(r),[r]);return e.jsx("main",{className:"diagnostics-page",children:e.jsxs("div",{className:"diagnostics-shell",children:[e.jsxs("header",{className:"diagnostics-header",children:[e.jsxs("div",{className:"diagnostics-header__copy",children:[e.jsx("button",{type:"button",className:"diagnostics-back",onClick:()=>void t({to:"/settings"}),children:"返回设置"}),e.jsx("h1",{children:"安卓样式诊断"}),e.jsx("p",{children:"在手机上打开本页,可以直接检查浏览器能力、样式加载、缓存和关键面板快照。"})]}),e.jsxs("div",{className:"diagnostics-toolbar",children:[e.jsx("button",{type:"button",className:"diagnostics-button",onClick:()=>void u(),disabled:i,children:i?"采集中…":"刷新诊断"}),e.jsx("button",{type:"button",className:"diagnostics-button diagnostics-button--ghost",onClick:()=>void p(),disabled:!r,children:"复制 JSON"})]})]}),l?e.jsx("p",{className:"diagnostics-status",children:l}):null,e.jsxs("section",{className:"diagnostics-card diagnostics-card--hero",children:[e.jsx("span",{className:"diagnostics-eyebrow",children:"初步判断"}),e.jsx("h2",{children:m}),e.jsx("p",{children:"真机异常而桌面浏览器和 F12 模拟正常,最常见就是浏览器 CSS 能力和缓存状态与桌面环境不同。"}),r!=null&&r.notes.length?e.jsx("ul",{className:"diagnostics-list",children:r.notes.map(s=>e.jsx("li",{children:s},s))}):null]}),r?e.jsxs(e.Fragment,{children:[e.jsxs("section",{className:"diagnostics-grid",children:[e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"环境"}),e.jsxs("dl",{className:"diagnostics-kv",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"页面"}),e.jsx("dd",{children:r.page.pathname})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"安全上下文"}),e.jsx("dd",{children:r.environment.secure_context?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"独立窗口"}),e.jsx("dd",{children:r.environment.standalone_display_mode?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"在线状态"}),e.jsx("dd",{children:r.environment.online==null?"未知":r.environment.online?"在线":"离线"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"视口"}),e.jsxs("dd",{children:[r.viewport.width," x ",r.viewport.height," @ ",r.viewport.device_pixel_ratio]})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"UA"}),e.jsx("dd",{className:"diagnostics-break",children:r.environment.user_agent})]})]})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"浏览器能力"}),e.jsx("dl",{className:"diagnostics-kv",children:Object.entries(r.feature_support).map(([s,a])=>e.jsxs("div",{children:[e.jsx("dt",{children:s}),e.jsx("dd",{children:W(a)})]},s))})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"缓存与 SW"}),e.jsxs("dl",{className:"diagnostics-kv",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"Service Worker"}),e.jsx("dd",{children:r.service_worker.supported?"支持":"不支持"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"当前受控"}),e.jsx("dd",{children:r.service_worker.controller?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"注册数量"}),e.jsx("dd",{children:r.service_worker.registrations.length})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"Cache Storage"}),e.jsx("dd",{children:r.cache.supported?r.cache.keys.join(", ")||"空":"不支持"})]})]})]}),e.jsxs("article",{className:"diagnostics-card",children:[e.jsx("h2",{children:"主题变量"}),e.jsx("dl",{className:"diagnostics-kv",children:Object.entries(r.theme_variables).map(([s,a])=>e.jsxs("div",{children:[e.jsx("dt",{children:s}),e.jsx("dd",{children:a})]},s))})]})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"资源探测"}),e.jsx("div",{className:"diagnostics-table-wrap",children:e.jsxs("table",{className:"diagnostics-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"类型"}),e.jsx("th",{children:"URL"}),e.jsx("th",{children:"状态"}),e.jsx("th",{children:"内容类型"}),e.jsx("th",{children:"Cache-Control"})]})}),e.jsx("tbody",{children:r.resource_probes.map(s=>e.jsxs("tr",{children:[e.jsx("td",{children:s.kind}),e.jsx("td",{className:"diagnostics-break",children:s.url}),e.jsx("td",{children:s.ok?`OK (${s.status??"-"})`:`失败 (${s.status??"-"})`}),e.jsx("td",{children:s.content_type??"-"}),e.jsx("td",{children:s.cache_control??s.error??"-"})]},`${s.kind}:${s.url}`))})]})})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"关键元素快照"}),e.jsx("div",{className:"diagnostics-element-grid",children:r.element_snapshots.map(s=>e.jsxs("article",{className:"diagnostics-element-card",children:[e.jsx("h3",{children:s.selector}),e.jsx("p",{children:U(s)}),e.jsxs("dl",{className:"diagnostics-kv diagnostics-kv--compact",children:[e.jsxs("div",{children:[e.jsx("dt",{children:"找到元素"}),e.jsx("dd",{children:s.found?"是":"否"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"尺寸"}),e.jsx("dd",{children:s.rect?`${s.rect.width} x ${s.rect.height}`:"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"背景色"}),e.jsx("dd",{children:s.computed["background-color"]??"-"})]}),e.jsxs("div",{children:[e.jsx("dt",{children:"背景图"}),e.jsx("dd",{className:"diagnostics-break",children:s.computed["background-image"]??"-"})]})]})]},s.selector))})]}),e.jsxs("section",{className:"diagnostics-card",children:[e.jsx("h2",{children:"原始 JSON"}),e.jsx("pre",{className:"diagnostics-json",children:JSON.stringify(r,null,2)})]})]}):e.jsx("section",{className:"diagnostics-card",children:e.jsx("p",{children:"正在等待诊断结果…"})})]})})};export{M as DiagnosticsPage};