aitu-app 0.6.78 → 0.6.80

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.
Files changed (203) hide show
  1. package/README.md +3 -3
  2. package/assets/CanvasAudioPlayer-CSFENxi6.js +2 -0
  3. package/assets/ChatDrawer-CWZQP5R5.css +1 -0
  4. package/assets/ChatDrawer-sVEVW11M.js +11 -0
  5. package/assets/ChatMessagesArea-Cnb94V8-.js +7 -0
  6. package/assets/ChatMessagesArea-PlF5AwzD.css +1 -0
  7. package/assets/DeferredAIInputBar-D99l6sBS.js +8 -0
  8. package/assets/DrawnixDeferredFeatures-78cIu-ev.js +2 -0
  9. package/assets/{KnowledgeBaseContent-DcX5Jofx.js → KnowledgeBaseContent-DZ-1fPZa.js} +10 -10
  10. package/assets/{MVCreator-DllHozYg.js → MVCreator-BV8KDR6E.js} +8 -8
  11. package/assets/ModelBenchmarkWorkbench-DL6r0Z_5.js +2 -0
  12. package/assets/MusicAnalyzer-D9Bpmhym.css +1 -0
  13. package/assets/{MusicAnalyzer-DDeT6g3c.js → MusicAnalyzer-DQtjf36o.js} +2 -2
  14. package/assets/{MusicAnalyzer-CHcQ5t4P.js → MusicAnalyzer-u_5sy56T.js} +1 -1
  15. package/assets/PromptHistoryTool-B-ktaOpK.js +2 -0
  16. package/assets/PromptHistoryTool-BH7hq916.css +1 -0
  17. package/assets/ResizableDivider-BpUFdkte.js +1 -0
  18. package/assets/TaskQueuePanel-BLD1r7_I.js +1 -0
  19. package/assets/{VideoAnalyzer-BSLz1FaI.js → VideoAnalyzer-Bjv9pyDs.js} +2 -2
  20. package/assets/ai-generation-preferences-service-BSpgVCHz.js +1 -0
  21. package/assets/arc-CnA_FoJK.js +1 -0
  22. package/assets/{arc-BU2KKCa_.js → arc-DDvk_-VM.js} +1 -1
  23. package/assets/{batch-image-generation-Bg68r_Ql.js → batch-image-generation-N-lwbjRE.js} +3 -3
  24. package/assets/{blockDiagram-38ab4fdb-BCGEnMME.js → blockDiagram-38ab4fdb-B2G4wjZe.js} +6 -6
  25. package/assets/{blockDiagram-38ab4fdb-CsZR5uC5.js → blockDiagram-38ab4fdb-DBkZWrKk.js} +1 -1
  26. package/assets/{browser-DpICcNby.js → browser-ZXTF4AKv.js} +1 -1
  27. package/assets/{c4Diagram-3d4e48cf-9fuiuFdV.js → c4Diagram-3d4e48cf-BFg-wccg.js} +1 -1
  28. package/assets/{c4Diagram-3d4e48cf-WM4wd_GR.js → c4Diagram-3d4e48cf-CmyNnfip.js} +1 -1
  29. package/assets/{canvas-insertion-CdUQF7IV.js → canvas-insertion-CKIoVZ9a.js} +1 -1
  30. package/assets/channel-BQh3J7kz.js +1 -0
  31. package/assets/channel-CPsF_uSp.js +1 -0
  32. package/assets/{classDiagram-70f12bd4-DcYDedz1.js → classDiagram-70f12bd4-BoP-e23u.js} +2 -2
  33. package/assets/{classDiagram-70f12bd4-CBVHTwQu.js → classDiagram-70f12bd4-UTHJc2XA.js} +1 -1
  34. package/assets/classDiagram-v2-f2320105-BeBc2H-D.js +2 -0
  35. package/assets/{classDiagram-v2-f2320105-jpCwaHEd.js → classDiagram-v2-f2320105-Bjwz5ljW.js} +1 -1
  36. package/assets/{clipper-jvd5rF5a.js → clipper-NoHaeWV4.js} +1 -1
  37. package/assets/clone-CA2KqVCK.js +1 -0
  38. package/assets/createText-2e5e7dd3-Bsu7vT-L.js +8 -0
  39. package/assets/{createText-2e5e7dd3-x5lOIwut.js → createText-2e5e7dd3-DrWUfa-s.js} +1 -1
  40. package/assets/{edges-e0da2a9e-CbrF4nbD.js → edges-e0da2a9e-B9sYOHRt.js} +1 -1
  41. package/assets/{edges-e0da2a9e-Ch6PBwWs.js → edges-e0da2a9e-DX4IQMED.js} +1 -1
  42. package/assets/{erDiagram-9861fffd-DSlNVuAZ.js → erDiagram-9861fffd-B-LfsIMf.js} +1 -1
  43. package/assets/{erDiagram-9861fffd-Bq07elcI.js → erDiagram-9861fffd-DPdud_LA.js} +1 -1
  44. package/assets/{flowDb-956e92f1-Ti5YC4Vv.js → flowDb-956e92f1-C3xKlizM.js} +1 -1
  45. package/assets/{flowDb-956e92f1-BqPCJlZp.js → flowDb-956e92f1-Ck5oiEta.js} +1 -1
  46. package/assets/{flowDiagram-66a62f08-CPDuG3rY.js → flowDiagram-66a62f08-Bkt2NoHM.js} +4 -4
  47. package/assets/{flowDiagram-66a62f08-D3GSABFi.js → flowDiagram-66a62f08-CJnxo6dI.js} +1 -1
  48. package/assets/flowDiagram-v2-96b9c2cf-MnwxRDMO.js +1 -0
  49. package/assets/flowDiagram-v2-96b9c2cf-U7nNPvdl.js +1 -0
  50. package/assets/{flowchart-elk-definition-4a651766-BH09NeLA.js → flowchart-elk-definition-4a651766-2XkrsdKI.js} +2 -2
  51. package/assets/{flowchart-elk-definition-4a651766-BLaLPCDV.js → flowchart-elk-definition-4a651766-ec8y1a8S.js} +1 -1
  52. package/assets/{ganttDiagram-c361ad54-DL9ZeaEc.js → ganttDiagram-c361ad54-1TA0mZY_.js} +3 -3
  53. package/assets/{ganttDiagram-c361ad54-Sp9M1KHP.js → ganttDiagram-c361ad54-D-OrVtXV.js} +3 -3
  54. package/assets/{gitGraphDiagram-72cf32ee-BWwmRKo-.js → gitGraphDiagram-72cf32ee-Blt3RsBD.js} +1 -1
  55. package/assets/{gitGraphDiagram-72cf32ee-BSf1fsDV.js → gitGraphDiagram-72cf32ee-CKf6xgO1.js} +1 -1
  56. package/assets/{graph-g-2U7grQ.js → graph-CUYgHJmb.js} +1 -1
  57. package/assets/{graph--nPw8zXQ.js → graph-WeSRtsZO.js} +1 -1
  58. package/assets/{index-ZrVeQUWo.js → index--MqiaN5t.js} +1 -1
  59. package/assets/{index-C5eu4uSl.js → index-0b_TeH8L.js} +11 -11
  60. package/assets/{index-3862675e-BXwbZ2pz.js → index-3862675e-C2ipEQC8.js} +1 -1
  61. package/assets/{index-3862675e-D6Zy95zZ.js → index-3862675e-CeX6VlsU.js} +1 -1
  62. package/assets/{index-CLJUfzvO.js → index-B-J0JJak.js} +1 -1
  63. package/assets/{index-TkfyNewx.js → index-B7Hj7g41.js} +1 -1
  64. package/assets/{index-eZfwJ9bV.js → index-BS_v5cOh.js} +1 -1
  65. package/assets/index-Btk31p7r.js +1 -0
  66. package/assets/{index-DH12_HTj.js → index-C-Samsu3.js} +2 -2
  67. package/assets/index-C-llNX01.js +1 -0
  68. package/assets/index-C8c9icsH.js +2 -0
  69. package/assets/{index-D7b5fX1d.js → index-CAn2jfNg.js} +1 -1
  70. package/assets/{index-Dz8sghkK.js → index-CK2zt94U.js} +1 -1
  71. package/assets/{index-CfgvFFx3.js → index-CP51k4n6.js} +17 -17
  72. package/assets/{index-DI0OV6F8.js → index-CXBhIy30.js} +1 -1
  73. package/assets/index-C_Mj1wbj.js +2 -0
  74. package/assets/{index-BwSnJN93.js → index-CbfE0MBd.js} +1 -1
  75. package/assets/{index-C3qD42ws.js → index-CjeDxq0c.js} +1 -1
  76. package/assets/{index-DqMndQiP.js → index-Ct7OFnWK.js} +1 -1
  77. package/assets/{index-BaCHOxhI.js → index-CxxUIkx1.js} +1 -1
  78. package/assets/{index-B2dttXd7.js → index-D2Kc-3MO.js} +1 -1
  79. package/assets/{index-Bq8mPedC.js → index-DK0XEByD.js} +1 -1
  80. package/assets/{index-DllL1sx1.js → index-DQcV2DYj.js} +1 -1
  81. package/assets/{index-BP77pG9S.js → index-DSKRBuhn.js} +73 -73
  82. package/assets/{index-BXzGHPXz.js → index-DXqL8NRE.js} +2 -2
  83. package/assets/{index-B7V7-Vxz.js → index-DcLrRIlS.js} +1 -1
  84. package/assets/{index-D4pIkh3S.js → index-DdA-dF0D.js} +1 -1
  85. package/assets/{index-QkP3EC02.js → index-DdxTnVj5.js} +1 -1
  86. package/assets/{index-CmyOpFTN.js → index-DmrnShhc.js} +1 -1
  87. package/assets/{index-Bti3m-iW.js → index-QO0uGVDP.js} +1 -1
  88. package/assets/{index-BPR_DyGD.js → index-aIKXDB1M.js} +1 -1
  89. package/assets/{index-DIiIUyb-.js → index-n6JhNACm.js} +1 -1
  90. package/assets/{index-BWrcsh8u.js → index-qbS_W7PW.js} +1 -1
  91. package/assets/index-v7iKPBEu.css +1 -0
  92. package/assets/{infoDiagram-f8f76790-DpFqCCNv.js → infoDiagram-f8f76790-DEWQ3NXc.js} +1 -1
  93. package/assets/{infoDiagram-f8f76790-G2JpJJP7.js → infoDiagram-f8f76790-u_qjHFCm.js} +3 -3
  94. package/assets/{journeyDiagram-49397b02-DLLTobRM.js → journeyDiagram-49397b02-C8A30CBr.js} +1 -1
  95. package/assets/{journeyDiagram-49397b02-BdESGMrv.js → journeyDiagram-49397b02-hQJfqZih.js} +1 -1
  96. package/assets/{layout-WSR0vNPO.js → layout-CFKTKeqQ.js} +1 -1
  97. package/assets/{layout-CVkuImk4.js → layout-DvRyabpG.js} +1 -1
  98. package/assets/{line-D3bnG227.js → line-C72F34Po.js} +1 -1
  99. package/assets/{line-DQuMJveY.js → line-W5R41tQ1.js} +1 -1
  100. package/assets/{linear-CciP-97N.js → linear-7FXykgHM.js} +1 -1
  101. package/assets/{linear-Z6vFvuwc.js → linear-CVyOPUvz.js} +1 -1
  102. package/assets/main-BO0HWBB1.js +42 -0
  103. package/assets/{main-8DNjLY6L.css → main-DAuE07rf.css} +1 -1
  104. package/assets/{mermaid.core-CwZQb0ud.js → mermaid.core-2VcXhn43.js} +4 -4
  105. package/assets/{mindmap-definition-fc14e90a-BnJ8OOTI.js → mindmap-definition-fc14e90a-CcVXKGg4.js} +1 -1
  106. package/assets/{mindmap-definition-fc14e90a-CxQMydCW.js → mindmap-definition-fc14e90a-DRDYXe84.js} +2 -2
  107. package/assets/model-benchmark-launcher-C2qBiDlM.js +1 -0
  108. package/assets/{photo-wall-splitter-BZ88W5Zy.js → photo-wall-splitter-CFntSOdS.js} +1 -1
  109. package/assets/{pieDiagram-8a3498a8-BSDdkTeu.js → pieDiagram-8a3498a8-Be9dl9pU.js} +1 -1
  110. package/assets/{pieDiagram-8a3498a8-D6VtAoja.js → pieDiagram-8a3498a8-DXZOJYBv.js} +5 -5
  111. package/assets/ppt-generation-B5fKT_by.js +48 -0
  112. package/assets/{quadrantDiagram-120e2f19-C8k2xuBd.js → quadrantDiagram-120e2f19-DoU7aQSp.js} +3 -3
  113. package/assets/{quadrantDiagram-120e2f19-BbFV0VXY.js → quadrantDiagram-120e2f19-l5K9mx26.js} +1 -1
  114. package/assets/{requirementDiagram-deff3bca-C3xMdzJV.js → requirementDiagram-deff3bca-DN_87Wxe.js} +1 -1
  115. package/assets/{requirementDiagram-deff3bca-CpjqKjYZ.js → requirementDiagram-deff3bca-DOooq7kx.js} +1 -1
  116. package/assets/retry-image-BmIVuAVu.js +6 -0
  117. package/assets/{sankeyDiagram-04a897e0-Bjvig9bW.js → sankeyDiagram-04a897e0-BB33nO6_.js} +1 -1
  118. package/assets/{sankeyDiagram-04a897e0-BBJJgsFv.js → sankeyDiagram-04a897e0-CCa0hwml.js} +2 -2
  119. package/assets/{sequenceDiagram-704730f1-PFC_9IFI.js → sequenceDiagram-704730f1-CNhXZiix.js} +1 -1
  120. package/assets/{sequenceDiagram-704730f1-DX1MmBN_.js → sequenceDiagram-704730f1-ZqQ1QrY-.js} +1 -1
  121. package/assets/settings-dialog-BFuWTeQR.js +1 -0
  122. package/assets/{skill-dsl-parser-syNWYxFu.js → skill-dsl-parser-b-aB3P5u.js} +1 -1
  123. package/assets/{stateDiagram-587899a1-Dc3mI_B_.js → stateDiagram-587899a1-BBlOIJr7.js} +1 -1
  124. package/assets/{stateDiagram-587899a1-SFMUVAam.js → stateDiagram-587899a1-BhomZ0AN.js} +1 -1
  125. package/assets/{stateDiagram-v2-d93cdb3a-P4Yt2p_j.js → stateDiagram-v2-d93cdb3a-BpJsgMa0.js} +1 -1
  126. package/assets/stateDiagram-v2-d93cdb3a-CuOn9du2.js +1 -0
  127. package/assets/{styles-6aaf32cf-C3jnr3hV.js → styles-6aaf32cf-C2WEewoA.js} +1 -1
  128. package/assets/{styles-6aaf32cf-b6AdP7fu.js → styles-6aaf32cf-CTtf8moq.js} +1 -1
  129. package/assets/{styles-9a916d00-BUiD9iBe.js → styles-9a916d00-44Xi2-39.js} +1 -1
  130. package/assets/{styles-9a916d00-ii0XTdIm.js → styles-9a916d00-DUU3VgNe.js} +4 -4
  131. package/assets/{styles-c10674c1-DbTSpy3W.js → styles-c10674c1--AhWSGg7.js} +1 -1
  132. package/assets/styles-c10674c1-DS-wE3tK.js +116 -0
  133. package/assets/{svgDrawCommon-08f97a94-D4gIV05W.js → svgDrawCommon-08f97a94-CXcvtSSy.js} +1 -1
  134. package/assets/{svgDrawCommon-08f97a94-BK6lD4D6.js → svgDrawCommon-08f97a94-Dyqh4V2s.js} +1 -1
  135. package/assets/{timeline-definition-85554ec2-Bl2y548G.js → timeline-definition-85554ec2-k788753O.js} +1 -1
  136. package/assets/{timeline-definition-85554ec2-CWKg_JxG.js → timeline-definition-85554ec2-sw6-UuBe.js} +1 -1
  137. package/assets/tool-windows-BEnZdJqF.js +2948 -0
  138. package/assets/{tool-windows-CUNbW1Tz.css → tool-windows-D61Le6TE.css} +1 -1
  139. package/assets/ttd-dialog-BJzXAZ0l.js +99 -0
  140. package/assets/useCharacters-DRBoWvvj.css +1 -0
  141. package/assets/useCharacters-gsV4K8Hn.js +2 -0
  142. package/assets/{useWorkflowSubmission-BizuDmuw.js → useWorkflowSubmission-XRR21P6Y.js} +10 -10
  143. package/assets/{video-analyze-6v3Y-rUE.js → video-analyze-CpbnpSiI.js} +1 -1
  144. package/assets/{video-generation-DnmTlWnm.js → video-generation-BXhS7x-a.js} +2 -2
  145. package/assets/video-recovery-service-6G2lkWcu.js +1 -0
  146. package/assets/workflow-generation-utils-CYxtSHl0.js +3 -0
  147. package/assets/workflow-submission-service-DygSzydV.js +4 -0
  148. package/assets/{xychartDiagram-e933f94c-CJX9_9WF.js → xychartDiagram-e933f94c-CvTTDwPb.js} +3 -3
  149. package/assets/{xychartDiagram-e933f94c-Cep8CQEH.js → xychartDiagram-e933f94c-Ga9zi9ha.js} +1 -1
  150. package/changelog.json +45 -0
  151. package/idle-prefetch-manifest.json +310 -306
  152. package/manifest.json +3 -3
  153. package/package.json +1 -1
  154. package/precache-manifest.json +10 -10
  155. package/sitemap.xml +37 -0
  156. package/sw-debug/app.js +269 -156
  157. package/sw-debug/backup-restore.js +235 -103
  158. package/sw-debug/crypto-helper.js +116 -120
  159. package/sw-debug/duplex-client.js +33 -19
  160. package/sw-debug/gist-management.js +938 -655
  161. package/sw-debug/sw-communication.js +87 -50
  162. package/sw.js +5 -5
  163. package/version.json +7 -17
  164. package/assets/CanvasAudioPlayer-DutgwdiU.js +0 -2
  165. package/assets/ChatDrawer-0jNvKIoI.css +0 -1
  166. package/assets/ChatDrawer-E6Fog16I.js +0 -11
  167. package/assets/ChatMessagesArea-Bgwiz_XP.js +0 -250
  168. package/assets/ChatMessagesArea-DyR_wHFQ.css +0 -1
  169. package/assets/DeferredAIInputBar-CPkD8Cv9.js +0 -8
  170. package/assets/DrawnixDeferredFeatures-Cul76-88.js +0 -2
  171. package/assets/ModelBenchmarkWorkbench-Dv9SNYTi.js +0 -2
  172. package/assets/MusicAnalyzer-DhtRGpAp.css +0 -1
  173. package/assets/ResizableDivider-CaG9JQbJ.js +0 -1
  174. package/assets/TaskQueuePanel-BNhNzGp5.js +0 -1
  175. package/assets/ai-generation-preferences-service-BF7QkuJp.js +0 -1
  176. package/assets/arc-DmGoDCEL.js +0 -1
  177. package/assets/channel-CZjE-WNp.js +0 -1
  178. package/assets/channel-SXZD6bG3.js +0 -1
  179. package/assets/classDiagram-v2-f2320105-CsxWGkSy.js +0 -2
  180. package/assets/clone-C4mvvMDb.js +0 -1
  181. package/assets/createText-2e5e7dd3-CkXS3l7I.js +0 -5
  182. package/assets/flowDiagram-v2-96b9c2cf-BCcJ-cre.js +0 -1
  183. package/assets/flowDiagram-v2-96b9c2cf-DCVaFEgV.js +0 -1
  184. package/assets/index-3eqA7Bag.js +0 -1
  185. package/assets/index-7Q-aiwln.js +0 -4
  186. package/assets/index-B1XP5g7P.css +0 -1
  187. package/assets/index-BHPTfCZM.js +0 -1
  188. package/assets/index-BqHZCcen.js +0 -2
  189. package/assets/index-DcZrElEK.js +0 -2
  190. package/assets/index-gQ7LgvSv.js +0 -12
  191. package/assets/main-BFEkxCOK.js +0 -56
  192. package/assets/model-benchmark-launcher-Ct3lYXVq.js +0 -1
  193. package/assets/ppt-generation-FzjP_rp0.js +0 -48
  194. package/assets/settings-dialog-CQM4v791.js +0 -1
  195. package/assets/stateDiagram-v2-d93cdb3a-DmnBjHpC.js +0 -1
  196. package/assets/styles-c10674c1-Bt89Yy8Q.js +0 -116
  197. package/assets/tool-windows-DOIu9TAD.js +0 -2975
  198. package/assets/ttd-dialog-DI4kQSg8.js +0 -99
  199. package/assets/useCharacters-Chv4Ky7x.js +0 -7
  200. package/assets/useCharacters-OrDbG69o.css +0 -1
  201. package/assets/video-recovery-service-BeRoh0s2.js +0 -1
  202. package/assets/workflow-generation-utils-me381Cax.js +0 -3
  203. package/assets/workflow-submission-service-YOpo7g37.js +0 -4
package/sw-debug/app.js CHANGED
@@ -14,7 +14,11 @@ import { createConsoleEntry } from './console-entry.js';
14
14
  import { createPostMessageEntry } from './postmessage-entry.js';
15
15
 
16
16
  // Panel components
17
- import { updateSwStatus, updateStatusPanel, updateDebugButton } from './status-panel.js';
17
+ import {
18
+ updateSwStatus,
19
+ updateStatusPanel,
20
+ updateDebugButton,
21
+ } from './status-panel.js';
18
22
  import { extractUniqueTypes, updateTypeSelectOptions } from './log-panel.js';
19
23
 
20
24
  // SW Communication
@@ -121,13 +125,14 @@ function renderConsoleLogs() {
121
125
  let filteredLogs = state.consoleLogs;
122
126
 
123
127
  if (levelFilter) {
124
- filteredLogs = filteredLogs.filter(l => l.logLevel === levelFilter);
128
+ filteredLogs = filteredLogs.filter((l) => l.logLevel === levelFilter);
125
129
  }
126
130
 
127
131
  if (textFilter) {
128
- filteredLogs = filteredLogs.filter(l =>
129
- l.logMessage?.toLowerCase().includes(textFilter) ||
130
- l.logStack?.toLowerCase().includes(textFilter)
132
+ filteredLogs = filteredLogs.filter(
133
+ (l) =>
134
+ l.logMessage?.toLowerCase().includes(textFilter) ||
135
+ l.logStack?.toLowerCase().includes(textFilter)
131
136
  );
132
137
  }
133
138
 
@@ -145,7 +150,7 @@ function renderConsoleLogs() {
145
150
  }
146
151
 
147
152
  elements.consoleLogsContainer.innerHTML = '';
148
- filteredLogs.slice(0, 200).forEach(log => {
153
+ filteredLogs.slice(0, 200).forEach((log) => {
149
154
  const isExpanded = state.expandedStackIds.has(log.id);
150
155
  const entry = createConsoleEntry(log, isExpanded, (id, expanded) => {
151
156
  if (expanded) {
@@ -162,9 +167,13 @@ function renderConsoleLogs() {
162
167
  * Update console log count indicator
163
168
  */
164
169
  function updateConsoleCount() {
165
- const errorCount = state.consoleLogs.filter(l => l.logLevel === 'error').length;
166
- const warnCount = state.consoleLogs.filter(l => l.logLevel === 'warn').length;
167
-
170
+ const errorCount = state.consoleLogs.filter(
171
+ (l) => l.logLevel === 'error'
172
+ ).length;
173
+ const warnCount = state.consoleLogs.filter(
174
+ (l) => l.logLevel === 'warn'
175
+ ).length;
176
+
168
177
  if (errorCount > 0) {
169
178
  elements.consoleCountEl.innerHTML = `(<span style="color:var(--error-color)">${errorCount} errors</span>)`;
170
179
  } else if (warnCount > 0) {
@@ -182,7 +191,7 @@ function addConsoleLog(entry) {
182
191
  // In analysis mode, save to liveLogs buffer instead of display state
183
192
  if (state.isAnalysisMode) {
184
193
  // Check for duplicates in liveLogs
185
- if (state.liveLogs.consoleLogs.some(l => l.id === entry.id)) {
194
+ if (state.liveLogs.consoleLogs.some((l) => l.id === entry.id)) {
186
195
  return;
187
196
  }
188
197
  state.liveLogs.consoleLogs.unshift(entry);
@@ -193,7 +202,7 @@ function addConsoleLog(entry) {
193
202
  }
194
203
 
195
204
  // Check for duplicates (in case of race condition with initial load)
196
- if (state.consoleLogs.some(l => l.id === entry.id)) {
205
+ if (state.consoleLogs.some((l) => l.id === entry.id)) {
197
206
  return;
198
207
  }
199
208
 
@@ -238,14 +247,16 @@ function renderPostmessageLogs() {
238
247
 
239
248
  // 按来源过滤(从 SW 角度:receive = 应用页面发送, send = SW 发送)
240
249
  if (sourceFilter === 'main') {
241
- filteredLogs = filteredLogs.filter(l => l.direction === 'receive');
250
+ filteredLogs = filteredLogs.filter((l) => l.direction === 'receive');
242
251
  } else if (sourceFilter === 'sw') {
243
- filteredLogs = filteredLogs.filter(l => l.direction === 'send');
252
+ filteredLogs = filteredLogs.filter((l) => l.direction === 'send');
244
253
  }
245
254
 
246
255
  // 下拉选择器过滤(精确匹配)
247
256
  if (typeSelectFilter) {
248
- filteredLogs = filteredLogs.filter(l => l.messageType === typeSelectFilter);
257
+ filteredLogs = filteredLogs.filter(
258
+ (l) => l.messageType === typeSelectFilter
259
+ );
249
260
  }
250
261
 
251
262
  // 时间范围过滤
@@ -253,7 +264,7 @@ function renderPostmessageLogs() {
253
264
 
254
265
  // 搜索框过滤(模糊匹配)
255
266
  if (typeFilter) {
256
- filteredLogs = filteredLogs.filter(l =>
267
+ filteredLogs = filteredLogs.filter((l) =>
257
268
  l.messageType?.toLowerCase().includes(typeFilter)
258
269
  );
259
270
  }
@@ -273,7 +284,7 @@ function renderPostmessageLogs() {
273
284
  }
274
285
 
275
286
  elements.postmessageLogsContainer.innerHTML = '';
276
- filteredLogs.slice(0, 200).forEach(log => {
287
+ filteredLogs.slice(0, 200).forEach((log) => {
277
288
  const isExpanded = state.expandedPmIds.has(log.id);
278
289
  const entry = createPostMessageEntry(log, isExpanded, (id, expanded) => {
279
290
  if (expanded) {
@@ -291,8 +302,12 @@ function renderPostmessageLogs() {
291
302
  */
292
303
  function updatePostmessageCount() {
293
304
  // 从 SW 角度:receive = 应用页面发送,send = SW 发送
294
- const mainCount = state.postmessageLogs.filter(l => l.direction === 'receive').length;
295
- const swCount = state.postmessageLogs.filter(l => l.direction === 'send').length;
305
+ const mainCount = state.postmessageLogs.filter(
306
+ (l) => l.direction === 'receive'
307
+ ).length;
308
+ const swCount = state.postmessageLogs.filter(
309
+ (l) => l.direction === 'send'
310
+ ).length;
296
311
 
297
312
  if (state.postmessageLogs.length > 0) {
298
313
  elements.postmessageCountEl.innerHTML = `(<span style="color:var(--success-color)">应用${mainCount}</span> <span style="color:var(--primary-color)">SW${swCount}</span>)`;
@@ -309,10 +324,15 @@ function addPostmessageLog(entry) {
309
324
  // In analysis mode, save to liveLogs buffer instead of display state
310
325
  if (state.isAnalysisMode) {
311
326
  // Check for existing entry to update (when response is linked to request)
312
- const existingIndex = state.liveLogs.postmessageLogs.findIndex(l => l.id === entry.id);
327
+ const existingIndex = state.liveLogs.postmessageLogs.findIndex(
328
+ (l) => l.id === entry.id
329
+ );
313
330
  if (existingIndex !== -1) {
314
331
  // Update existing entry (merge response data)
315
- state.liveLogs.postmessageLogs[existingIndex] = { ...state.liveLogs.postmessageLogs[existingIndex], ...entry };
332
+ state.liveLogs.postmessageLogs[existingIndex] = {
333
+ ...state.liveLogs.postmessageLogs[existingIndex],
334
+ ...entry,
335
+ };
316
336
  return;
317
337
  }
318
338
  state.liveLogs.postmessageLogs.unshift(entry);
@@ -330,11 +350,16 @@ function addPostmessageLog(entry) {
330
350
  }
331
351
 
332
352
  // Check for existing entry to update (when response is linked to request)
333
- const existingIndex = state.postmessageLogs.findIndex(l => l.id === entry.id);
353
+ const existingIndex = state.postmessageLogs.findIndex(
354
+ (l) => l.id === entry.id
355
+ );
334
356
  if (existingIndex !== -1) {
335
357
  // Update existing entry (merge response data)
336
358
  const wasExpanded = state.expandedPmLogs?.has(entry.id);
337
- state.postmessageLogs[existingIndex] = { ...state.postmessageLogs[existingIndex], ...entry };
359
+ state.postmessageLogs[existingIndex] = {
360
+ ...state.postmessageLogs[existingIndex],
361
+ ...entry,
362
+ };
338
363
  // Re-render to show updated data
339
364
  if (state.activeTab === 'postmessage') {
340
365
  renderPostmessageLogs();
@@ -366,8 +391,8 @@ function togglePmPause() {
366
391
 
367
392
  if (!state.isPmPaused && state.pendingPmLogs.length > 0) {
368
393
  // Apply pending logs when resuming
369
- state.pendingPmLogs.forEach(entry => {
370
- if (!state.postmessageLogs.some(l => l.id === entry.id)) {
394
+ state.pendingPmLogs.forEach((entry) => {
395
+ if (!state.postmessageLogs.some((l) => l.id === entry.id)) {
371
396
  state.postmessageLogs.unshift(entry);
372
397
  }
373
398
  });
@@ -388,8 +413,10 @@ function updatePmPauseButton() {
388
413
  const btn = elements.togglePmPauseBtn;
389
414
  if (!btn) return;
390
415
 
391
- const playIcon = '<svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
392
- const pauseIcon = '<svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>';
416
+ const playIcon =
417
+ '<svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
418
+ const pauseIcon =
419
+ '<svg class="icon-svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>';
393
420
 
394
421
  if (state.isPmPaused) {
395
422
  let text = '暂停';
@@ -425,17 +452,19 @@ function getFilteredPostmessageLogs() {
425
452
 
426
453
  // 按来源过滤
427
454
  if (sourceFilter === 'main') {
428
- filteredLogs = filteredLogs.filter(l => l.direction === 'receive');
455
+ filteredLogs = filteredLogs.filter((l) => l.direction === 'receive');
429
456
  } else if (sourceFilter === 'sw') {
430
- filteredLogs = filteredLogs.filter(l => l.direction === 'send');
457
+ filteredLogs = filteredLogs.filter((l) => l.direction === 'send');
431
458
  }
432
459
 
433
460
  if (typeSelectFilter) {
434
- filteredLogs = filteredLogs.filter(l => l.messageType === typeSelectFilter);
461
+ filteredLogs = filteredLogs.filter(
462
+ (l) => l.messageType === typeSelectFilter
463
+ );
435
464
  }
436
465
 
437
466
  if (typeFilter) {
438
- filteredLogs = filteredLogs.filter(l =>
467
+ filteredLogs = filteredLogs.filter((l) =>
439
468
  l.messageType?.toLowerCase().includes(typeFilter)
440
469
  );
441
470
  }
@@ -455,16 +484,23 @@ async function handleCopyPostmessageLogs() {
455
484
  }
456
485
 
457
486
  // Format logs as text
458
- const logText = filteredLogs.map(log => {
459
- const time = new Date(log.timestamp).toLocaleTimeString('zh-CN', { hour12: false });
460
- // SW 角度:receive = 应用页面发送,send = SW 发送
461
- const source = log.direction === 'receive' ? '应用页面' : 'SW';
462
- const type = log.messageType || 'unknown';
463
- const data = log.data ? JSON.stringify(log.data, null, 2) : '';
464
- const response = log.response !== undefined ? `\n 响应: ${JSON.stringify(log.response, null, 2)}` : '';
465
- const error = log.error ? `\n 错误: ${log.error}` : '';
466
- return `${time} [${source}] ${type}\n 数据: ${data}${response}${error}`;
467
- }).join('\n\n');
487
+ const logText = filteredLogs
488
+ .map((log) => {
489
+ const time = new Date(log.timestamp).toLocaleTimeString('zh-CN', {
490
+ hour12: false,
491
+ });
492
+ // SW 角度:receive = 应用页面发送,send = SW 发送
493
+ const source = log.direction === 'receive' ? '应用页面' : 'SW';
494
+ const type = log.messageType || 'unknown';
495
+ const data = log.data ? JSON.stringify(log.data, null, 2) : '';
496
+ const response =
497
+ log.response !== undefined
498
+ ? `\n 响应: ${JSON.stringify(log.response, null, 2)}`
499
+ : '';
500
+ const error = log.error ? `\n 错误: ${log.error}` : '';
501
+ return `${time} [${source}] ${type}\n 数据: ${data}${response}${error}`;
502
+ })
503
+ .join('\n\n');
468
504
 
469
505
  try {
470
506
  await navigator.clipboard.writeText(logText);
@@ -489,20 +525,26 @@ async function handleCopyPostmessageLogs() {
489
525
  function updateErrorDots() {
490
526
  // Console errors
491
527
  if (elements.consoleErrorDot) {
492
- const hasErrors = state.consoleLogs.some(l => l.logLevel === 'error');
493
- elements.consoleErrorDot.style.display = (hasErrors && state.activeTab !== 'console') ? 'inline-block' : 'none';
528
+ const hasErrors = state.consoleLogs.some((l) => l.logLevel === 'error');
529
+ elements.consoleErrorDot.style.display =
530
+ hasErrors && state.activeTab !== 'console' ? 'inline-block' : 'none';
494
531
  }
495
-
532
+
496
533
  // LLM API errors
497
534
  if (elements.llmapiErrorDot) {
498
- const hasErrors = state.llmapiLogs.some(l => l.status === 'error');
499
- elements.llmapiErrorDot.style.display = (hasErrors && state.activeTab !== 'llmapi') ? 'inline-block' : 'none';
535
+ const hasErrors = state.llmapiLogs.some((l) => l.status === 'error');
536
+ elements.llmapiErrorDot.style.display =
537
+ hasErrors && state.activeTab !== 'llmapi' ? 'inline-block' : 'none';
500
538
  }
501
-
539
+
502
540
  // Crash/memory errors
503
541
  if (elements.crashErrorDot) {
504
- const hasErrors = state.crashLogs.some(l => l.type === 'error' || l.type === 'freeze' || l.type === 'whitescreen');
505
- elements.crashErrorDot.style.display = (hasErrors && state.activeTab !== 'crash') ? 'inline-block' : 'none';
542
+ const hasErrors = state.crashLogs.some(
543
+ (l) =>
544
+ l.type === 'error' || l.type === 'freeze' || l.type === 'whitescreen'
545
+ );
546
+ elements.crashErrorDot.style.display =
547
+ hasErrors && state.activeTab !== 'crash' ? 'inline-block' : 'none';
506
548
  }
507
549
  }
508
550
 
@@ -527,13 +569,14 @@ async function handleCopyConsoleLogs() {
527
569
  let filteredLogs = state.consoleLogs;
528
570
 
529
571
  if (levelFilter) {
530
- filteredLogs = filteredLogs.filter(l => l.logLevel === levelFilter);
572
+ filteredLogs = filteredLogs.filter((l) => l.logLevel === levelFilter);
531
573
  }
532
574
 
533
575
  if (textFilter) {
534
- filteredLogs = filteredLogs.filter(l =>
535
- l.logMessage?.toLowerCase().includes(textFilter) ||
536
- l.logStack?.toLowerCase().includes(textFilter)
576
+ filteredLogs = filteredLogs.filter(
577
+ (l) =>
578
+ l.logMessage?.toLowerCase().includes(textFilter) ||
579
+ l.logStack?.toLowerCase().includes(textFilter)
537
580
  );
538
581
  }
539
582
 
@@ -543,15 +586,21 @@ async function handleCopyConsoleLogs() {
543
586
  }
544
587
 
545
588
  // Format logs as text with all details
546
- const logText = filteredLogs.map(log => {
547
- const time = new Date(log.timestamp).toLocaleTimeString('zh-CN', { hour12: false });
548
- const level = `[${log.logLevel.toUpperCase()}]`;
549
- const message = log.logMessage || '';
550
- const source = log.logSource ? `\n 来源: ${log.logSource}` : '';
551
- const url = log.url ? `\n 页面: ${log.url}` : '';
552
- const stack = log.logStack ? `\n 堆栈:\n ${log.logStack.split('\n').join('\n ')}` : '';
553
- return `${time} ${level} ${message}${source}${url}${stack}`;
554
- }).join('\n\n');
589
+ const logText = filteredLogs
590
+ .map((log) => {
591
+ const time = new Date(log.timestamp).toLocaleTimeString('zh-CN', {
592
+ hour12: false,
593
+ });
594
+ const level = `[${log.logLevel.toUpperCase()}]`;
595
+ const message = log.logMessage || '';
596
+ const source = log.logSource ? `\n 来源: ${log.logSource}` : '';
597
+ const url = log.url ? `\n 页面: ${log.url}` : '';
598
+ const stack = log.logStack
599
+ ? `\n 堆栈:\n ${log.logStack.split('\n').join('\n ')}`
600
+ : '';
601
+ return `${time} ${level} ${message}${source}${url}${stack}`;
602
+ })
603
+ .join('\n\n');
555
604
 
556
605
  try {
557
606
  await navigator.clipboard.writeText(logText);
@@ -609,28 +658,28 @@ function handleClearLogs() {
609
658
 
610
659
  /**
611
660
  * Switch active tab
612
- * @param {string} tabName
661
+ * @param {string} tabName
613
662
  * @param {boolean} updateUrl - Whether to update URL parameter (default: true)
614
663
  */
615
664
  function switchTab(tabName, updateUrl = true) {
616
665
  state.activeTab = tabName;
617
- document.querySelectorAll('.tab').forEach(t => {
666
+ document.querySelectorAll('.tab').forEach((t) => {
618
667
  t.classList.toggle('active', t.dataset.tab === tabName);
619
668
  });
620
- document.querySelectorAll('.tab-content').forEach(c => {
669
+ document.querySelectorAll('.tab-content').forEach((c) => {
621
670
  c.classList.toggle('active', c.id === tabName + 'Tab');
622
671
  });
623
-
672
+
624
673
  // Update URL parameter
625
674
  if (updateUrl) {
626
675
  const url = new URL(window.location.href);
627
676
  url.searchParams.set('tab', tabName);
628
677
  window.history.replaceState({}, '', url.toString());
629
678
  }
630
-
679
+
631
680
  // Update error dots (hide dot for active tab)
632
681
  updateErrorDots();
633
-
682
+
634
683
  if (tabName === 'fetch') {
635
684
  renderLogs();
636
685
  } else if (tabName === 'console') {
@@ -651,7 +700,7 @@ function switchTab(tabName, updateUrl = true) {
651
700
  /**
652
701
  * Handle SW status update
653
702
  * Supports both RPC format { status: {...} } and native message format { debugModeEnabled, swVersion, ... }
654
- * @param {object} data
703
+ * @param {object} data
655
704
  */
656
705
  function handleStatusUpdate(data) {
657
706
  // Normalize: RPC returns { status: {...} }, native message returns flat object
@@ -659,7 +708,10 @@ function handleStatusUpdate(data) {
659
708
  if (data.status) {
660
709
  // RPC format
661
710
  status = data.status;
662
- } else if (data.debugModeEnabled !== undefined || data.swVersion !== undefined) {
711
+ } else if (
712
+ data.debugModeEnabled !== undefined ||
713
+ data.swVersion !== undefined
714
+ ) {
663
715
  // Native message format - normalize field names
664
716
  status = {
665
717
  ...data,
@@ -674,7 +726,11 @@ function handleStatusUpdate(data) {
674
726
  state.debugEnabled = updateStatusPanel(status, elements);
675
727
  state.swStatus = status; // Store for export
676
728
  updateDebugButton(elements.toggleDebugBtn, state.debugEnabled);
677
- try { sessionStorage.setItem('sw-debug-enabled', String(state.debugEnabled)); } catch {}
729
+ try {
730
+ sessionStorage.setItem('sw-debug-enabled', String(state.debugEnabled));
731
+ } catch (err) {
732
+ void err;
733
+ }
678
734
  }
679
735
 
680
736
  // ==================== Event Listeners Setup ====================
@@ -687,45 +743,48 @@ function setupEventListeners() {
687
743
  elements.toggleAnalysisModeBtn?.addEventListener('click', toggleAnalysisMode);
688
744
  elements.importLogsBtn?.addEventListener('click', triggerImportDialog);
689
745
  elements.importLogsInput?.addEventListener('change', handleLogImport);
690
-
746
+
691
747
  // Backup button event listener
692
748
  elements.backupDataBtn?.addEventListener('click', performBackup);
693
749
 
694
750
  // Restore button event listeners
695
751
  elements.restoreBackupBtn?.addEventListener('click', triggerRestoreDialog);
696
752
  elements.restoreBackupInput?.addEventListener('change', handleRestoreFile);
697
-
753
+
698
754
  elements.toggleDebugBtn?.addEventListener('click', toggleDebug);
699
755
  elements.exportLogsBtn?.addEventListener('click', openExportModal);
700
756
  elements.doExportBtn?.addEventListener('click', exportLogs);
701
757
  elements.closeExportModalBtn?.addEventListener('click', closeExportModal);
702
758
  elements.cancelExportBtn?.addEventListener('click', closeExportModal);
703
759
  elements.clearLogsBtn.addEventListener('click', handleClearLogs);
704
-
760
+
705
761
  // Close modal when clicking overlay
706
762
  elements.exportModalOverlay?.addEventListener('click', (e) => {
707
763
  if (e.target === elements.exportModalOverlay) {
708
764
  closeExportModal();
709
765
  }
710
766
  });
711
-
767
+
712
768
  // Setup export modal checkboxes
713
769
  setupExportModalCheckboxes();
714
-
770
+
715
771
  elements.refreshStatusBtn.addEventListener('click', async () => {
716
772
  refreshStatus();
717
773
  loadFetchLogs();
718
774
  });
719
775
  elements.refreshCacheBtn.addEventListener('click', refreshStatus);
720
776
  elements.enableDebugBtn?.addEventListener('click', toggleDebug);
721
- elements.clearConsoleLogsBtn?.addEventListener('click', handleClearConsoleLogs);
777
+ elements.clearConsoleLogsBtn?.addEventListener(
778
+ 'click',
779
+ handleClearConsoleLogs
780
+ );
722
781
  elements.copyConsoleLogsBtn?.addEventListener('click', handleCopyConsoleLogs);
723
782
 
724
783
  elements.filterType?.addEventListener('change', renderLogs);
725
784
  elements.filterStatus?.addEventListener('change', renderLogs);
726
785
  elements.filterTimeRange?.addEventListener('change', renderLogs);
727
786
  elements.filterUrl?.addEventListener('input', renderLogs);
728
-
787
+
729
788
  // 慢请求点击过滤
730
789
  elements.statSlowRequestsWrapper?.addEventListener('click', () => {
731
790
  toggleSlowRequestFilter();
@@ -743,7 +802,10 @@ function setupEventListeners() {
743
802
  state.showBookmarksOnly = e.target.checked;
744
803
  renderLogs();
745
804
  });
746
- elements.closeShortcutsModalBtn?.addEventListener('click', closeShortcutsModal);
805
+ elements.closeShortcutsModalBtn?.addEventListener(
806
+ 'click',
807
+ closeShortcutsModal
808
+ );
747
809
  elements.shortcutsModalOverlay?.addEventListener('click', (e) => {
748
810
  if (e.target === elements.shortcutsModalOverlay) {
749
811
  closeShortcutsModal();
@@ -766,24 +828,45 @@ function setupEventListeners() {
766
828
 
767
829
  // PostMessage log event listeners
768
830
  elements.togglePmPauseBtn?.addEventListener('click', togglePmPause);
769
- elements.filterMessageSource?.addEventListener('change', renderPostmessageLogs);
770
- elements.filterMessageTypeSelect?.addEventListener('change', renderPostmessageLogs);
831
+ elements.filterMessageSource?.addEventListener(
832
+ 'change',
833
+ renderPostmessageLogs
834
+ );
835
+ elements.filterMessageTypeSelect?.addEventListener(
836
+ 'change',
837
+ renderPostmessageLogs
838
+ );
771
839
  elements.filterPmTimeRange?.addEventListener('change', renderPostmessageLogs);
772
840
  elements.filterMessageType?.addEventListener('input', renderPostmessageLogs);
773
- elements.clearPostmessageLogsBtn?.addEventListener('click', handleClearPostmessageLogs);
774
- elements.copyPostmessageLogsBtn?.addEventListener('click', handleCopyPostmessageLogs);
841
+ elements.clearPostmessageLogsBtn?.addEventListener(
842
+ 'click',
843
+ handleClearPostmessageLogs
844
+ );
845
+ elements.copyPostmessageLogsBtn?.addEventListener(
846
+ 'click',
847
+ handleCopyPostmessageLogs
848
+ );
775
849
 
776
850
  // LLM API log event listeners
777
851
  elements.filterLLMApiType?.addEventListener('change', onLLMApiFilterChange);
778
852
  elements.filterLLMApiStatus?.addEventListener('change', onLLMApiFilterChange);
779
853
  elements.refreshLLMApiLogsBtn?.addEventListener('click', loadLLMApiLogs);
780
854
  elements.copyLLMApiLogsBtn?.addEventListener('click', handleCopyLLMApiLogs);
781
- elements.exportLLMApiLogsBtn?.addEventListener('click', handleExportLLMApiLogs);
855
+ elements.exportLLMApiLogsBtn?.addEventListener(
856
+ 'click',
857
+ handleExportLLMApiLogs
858
+ );
782
859
  elements.clearLLMApiLogsBtn?.addEventListener('click', handleClearLLMApiLogs);
783
860
  // LLM API select mode
784
- elements.toggleLLMApiSelectModeBtn?.addEventListener('click', toggleLLMApiSelectMode);
861
+ elements.toggleLLMApiSelectModeBtn?.addEventListener(
862
+ 'click',
863
+ toggleLLMApiSelectMode
864
+ );
785
865
  elements.llmapiSelectAllBtn?.addEventListener('click', selectAllLLMApiLogs);
786
- elements.llmapiBatchDeleteBtn?.addEventListener('click', batchDeleteLLMApiLogs);
866
+ elements.llmapiBatchDeleteBtn?.addEventListener(
867
+ 'click',
868
+ batchDeleteLLMApiLogs
869
+ );
787
870
 
788
871
  // Crash log event listeners
789
872
  elements.filterCrashType?.addEventListener('change', renderCrashLogs);
@@ -793,7 +876,7 @@ function setupEventListeners() {
793
876
  elements.exportCrashLogsBtn?.addEventListener('click', handleExportCrashLogs);
794
877
 
795
878
  // Tab switching
796
- document.querySelectorAll('.tab').forEach(tab => {
879
+ document.querySelectorAll('.tab').forEach((tab) => {
797
880
  tab.addEventListener('click', () => switchTab(tab.dataset.tab));
798
881
  });
799
882
 
@@ -829,7 +912,14 @@ function setupEventListeners() {
829
912
  }
830
913
 
831
914
  // Number keys 1-5 to switch tabs
832
- const tabMap = { '1': 'fetch', '2': 'console', '3': 'postmessage', '4': 'llmapi', '5': 'crash', '6': 'gist' };
915
+ const tabMap = {
916
+ 1: 'fetch',
917
+ 2: 'console',
918
+ 3: 'postmessage',
919
+ 4: 'llmapi',
920
+ 5: 'crash',
921
+ 6: 'gist',
922
+ };
833
923
  if (tabMap[e.key] && !e.ctrlKey && !e.metaKey && !e.altKey) {
834
924
  switchTab(tabMap[e.key]);
835
925
  }
@@ -874,9 +964,14 @@ function addOrUpdateLiveLog(logType, entry) {
874
964
  if (!state.liveLogs[logType]) {
875
965
  state.liveLogs[logType] = [];
876
966
  }
877
- const existingIndex = state.liveLogs[logType].findIndex(l => l.id === entry.id);
967
+ const existingIndex = state.liveLogs[logType].findIndex(
968
+ (l) => l.id === entry.id
969
+ );
878
970
  if (existingIndex >= 0) {
879
- state.liveLogs[logType][existingIndex] = { ...state.liveLogs[logType][existingIndex], ...entry };
971
+ state.liveLogs[logType][existingIndex] = {
972
+ ...state.liveLogs[logType][existingIndex],
973
+ ...entry,
974
+ };
880
975
  } else {
881
976
  state.liveLogs[logType].unshift(entry);
882
977
  }
@@ -889,10 +984,14 @@ function addOrUpdateLiveLog(logType, entry) {
889
984
  */
890
985
  function setupMessageHandlers() {
891
986
  registerMessageHandlers({
892
- 'SW_DEBUG_STATUS': handleStatusUpdate,
893
- 'SW_DEBUG_ENABLED': () => {
987
+ SW_DEBUG_STATUS: handleStatusUpdate,
988
+ SW_DEBUG_ENABLED: () => {
894
989
  state.debugEnabled = true;
895
- try { sessionStorage.setItem('sw-debug-enabled', 'true'); } catch {}
990
+ try {
991
+ sessionStorage.setItem('sw-debug-enabled', 'true');
992
+ } catch (err) {
993
+ void err;
994
+ }
896
995
  updateDebugButton(elements.toggleDebugBtn, true);
897
996
  // Update status panel text to show "开启"
898
997
  if (elements.debugMode) {
@@ -905,9 +1004,13 @@ function setupMessageHandlers() {
905
1004
  // This ensures cache stats and other info are up-to-date
906
1005
  refreshStatus();
907
1006
  },
908
- 'SW_DEBUG_DISABLED': () => {
1007
+ SW_DEBUG_DISABLED: () => {
909
1008
  state.debugEnabled = false;
910
- try { sessionStorage.setItem('sw-debug-enabled', 'false'); } catch {}
1009
+ try {
1010
+ sessionStorage.setItem('sw-debug-enabled', 'false');
1011
+ } catch (err) {
1012
+ void err;
1013
+ }
911
1014
  updateDebugButton(elements.toggleDebugBtn, false);
912
1015
  // Update status panel text to show "关闭"
913
1016
  if (elements.debugMode) {
@@ -917,7 +1020,7 @@ function setupMessageHandlers() {
917
1020
  renderLogs(); // Refresh to show "enable debug" button
918
1021
  }
919
1022
  },
920
- 'SW_DEBUG_LOG': (data) => {
1023
+ SW_DEBUG_LOG: (data) => {
921
1024
  if (state.isAnalysisMode) {
922
1025
  // Store in live logs buffer, don't display
923
1026
  addOrUpdateLiveLog('logs', data.entry);
@@ -925,7 +1028,7 @@ function setupMessageHandlers() {
925
1028
  addOrUpdateLog(data.entry);
926
1029
  }
927
1030
  },
928
- 'SW_DEBUG_LOGS': (data) => {
1031
+ SW_DEBUG_LOGS: (data) => {
929
1032
  if (state.isAnalysisMode) {
930
1033
  state.liveLogs.logs = data.logs || [];
931
1034
  } else {
@@ -933,7 +1036,7 @@ function setupMessageHandlers() {
933
1036
  renderLogs();
934
1037
  }
935
1038
  },
936
- 'SW_DEBUG_LOGS_CLEARED': () => {
1039
+ SW_DEBUG_LOGS_CLEARED: () => {
937
1040
  if (state.isAnalysisMode) {
938
1041
  state.liveLogs.logs = [];
939
1042
  } else {
@@ -941,14 +1044,14 @@ function setupMessageHandlers() {
941
1044
  renderLogs();
942
1045
  }
943
1046
  },
944
- 'SW_CONSOLE_LOG': (data) => {
1047
+ SW_CONSOLE_LOG: (data) => {
945
1048
  if (state.isAnalysisMode) {
946
1049
  addOrUpdateLiveLog('consoleLogs', data.entry);
947
1050
  } else {
948
1051
  addConsoleLog(data.entry);
949
1052
  }
950
1053
  },
951
- 'SW_DEBUG_CONSOLE_LOGS': (data) => {
1054
+ SW_DEBUG_CONSOLE_LOGS: (data) => {
952
1055
  if (state.isAnalysisMode) {
953
1056
  state.liveLogs.consoleLogs = data.logs || [];
954
1057
  } else {
@@ -956,7 +1059,7 @@ function setupMessageHandlers() {
956
1059
  renderConsoleLogs();
957
1060
  }
958
1061
  },
959
- 'SW_DEBUG_CONSOLE_LOGS_CLEARED': () => {
1062
+ SW_DEBUG_CONSOLE_LOGS_CLEARED: () => {
960
1063
  if (state.isAnalysisMode) {
961
1064
  state.liveLogs.consoleLogs = [];
962
1065
  } else {
@@ -964,14 +1067,14 @@ function setupMessageHandlers() {
964
1067
  renderConsoleLogs();
965
1068
  }
966
1069
  },
967
- 'SW_POSTMESSAGE_LOG': (data) => {
1070
+ SW_POSTMESSAGE_LOG: (data) => {
968
1071
  if (state.isAnalysisMode) {
969
1072
  addOrUpdateLiveLog('postmessageLogs', data.entry);
970
1073
  } else {
971
1074
  addPostmessageLog(data.entry);
972
1075
  }
973
1076
  },
974
- 'SW_DEBUG_POSTMESSAGE_LOG_BATCH': (data) => {
1077
+ SW_DEBUG_POSTMESSAGE_LOG_BATCH: (data) => {
975
1078
  // 处理批量 PostMessage 日志
976
1079
  const entries = data.entries || [];
977
1080
  for (const entry of entries) {
@@ -982,7 +1085,7 @@ function setupMessageHandlers() {
982
1085
  }
983
1086
  }
984
1087
  },
985
- 'SW_DEBUG_POSTMESSAGE_LOGS': (data) => {
1088
+ SW_DEBUG_POSTMESSAGE_LOGS: (data) => {
986
1089
  if (state.isAnalysisMode) {
987
1090
  state.liveLogs.postmessageLogs = data.logs || [];
988
1091
  } else {
@@ -991,7 +1094,7 @@ function setupMessageHandlers() {
991
1094
  renderPostmessageLogs();
992
1095
  }
993
1096
  },
994
- 'SW_DEBUG_POSTMESSAGE_LOGS_CLEARED': () => {
1097
+ SW_DEBUG_POSTMESSAGE_LOGS_CLEARED: () => {
995
1098
  if (state.isAnalysisMode) {
996
1099
  state.liveLogs.postmessageLogs = [];
997
1100
  } else {
@@ -999,7 +1102,7 @@ function setupMessageHandlers() {
999
1102
  renderPostmessageLogs();
1000
1103
  }
1001
1104
  },
1002
- 'SW_DEBUG_CRASH_SNAPSHOTS': (data) => {
1105
+ SW_DEBUG_CRASH_SNAPSHOTS: (data) => {
1003
1106
  if (state.isAnalysisMode) {
1004
1107
  state.liveLogs.crashLogs = data.snapshots || [];
1005
1108
  } else {
@@ -1007,7 +1110,7 @@ function setupMessageHandlers() {
1007
1110
  renderCrashLogs();
1008
1111
  }
1009
1112
  },
1010
- 'SW_DEBUG_NEW_CRASH_SNAPSHOT': (data) => {
1113
+ SW_DEBUG_NEW_CRASH_SNAPSHOT: (data) => {
1011
1114
  if (data.snapshot) {
1012
1115
  if (state.isAnalysisMode) {
1013
1116
  state.liveLogs.crashLogs.unshift(data.snapshot);
@@ -1023,7 +1126,7 @@ function setupMessageHandlers() {
1023
1126
  }
1024
1127
  }
1025
1128
  },
1026
- 'SW_DEBUG_CRASH_SNAPSHOTS_CLEARED': () => {
1129
+ SW_DEBUG_CRASH_SNAPSHOTS_CLEARED: () => {
1027
1130
  if (state.isAnalysisMode) {
1028
1131
  state.liveLogs.crashLogs = [];
1029
1132
  } else {
@@ -1031,7 +1134,7 @@ function setupMessageHandlers() {
1031
1134
  renderCrashLogs();
1032
1135
  }
1033
1136
  },
1034
- 'SW_DEBUG_LLM_API_LOGS': (data) => {
1137
+ SW_DEBUG_LLM_API_LOGS: (data) => {
1035
1138
  if (state.isAnalysisMode) {
1036
1139
  state.liveLogs.llmapiLogs = data.logs || [];
1037
1140
  } else {
@@ -1046,10 +1149,12 @@ function setupMessageHandlers() {
1046
1149
  renderLLMApiLogs();
1047
1150
  }
1048
1151
  },
1049
- 'SW_DEBUG_LLM_API_LOG': (data) => {
1152
+ SW_DEBUG_LLM_API_LOG: (data) => {
1050
1153
  if (data.log) {
1051
1154
  if (state.isAnalysisMode) {
1052
- const existingIndex = state.liveLogs.llmapiLogs.findIndex(l => l.id === data.log.id);
1155
+ const existingIndex = state.liveLogs.llmapiLogs.findIndex(
1156
+ (l) => l.id === data.log.id
1157
+ );
1053
1158
  if (existingIndex >= 0) {
1054
1159
  state.liveLogs.llmapiLogs[existingIndex] = data.log;
1055
1160
  } else {
@@ -1060,7 +1165,9 @@ function setupMessageHandlers() {
1060
1165
  }
1061
1166
  } else {
1062
1167
  // 实时更新:更新现有日志或在第一页时插入新日志
1063
- const existingIndex = state.llmapiLogs.findIndex(l => l.id === data.log.id);
1168
+ const existingIndex = state.llmapiLogs.findIndex(
1169
+ (l) => l.id === data.log.id
1170
+ );
1064
1171
  if (existingIndex >= 0) {
1065
1172
  // 更新已存在的日志(无论在哪一页)
1066
1173
  state.llmapiLogs[existingIndex] = data.log;
@@ -1073,43 +1180,46 @@ function setupMessageHandlers() {
1073
1180
  }
1074
1181
  // 更新总数
1075
1182
  state.llmapiPagination.total++;
1076
- state.llmapiPagination.totalPages = Math.ceil(state.llmapiPagination.total / state.llmapiPagination.pageSize);
1183
+ state.llmapiPagination.totalPages = Math.ceil(
1184
+ state.llmapiPagination.total / state.llmapiPagination.pageSize
1185
+ );
1077
1186
  renderLLMApiLogs();
1078
1187
  } else {
1079
1188
  // 不在第一页,只更新总数,不插入
1080
1189
  state.llmapiPagination.total++;
1081
- state.llmapiPagination.totalPages = Math.ceil(state.llmapiPagination.total / state.llmapiPagination.pageSize);
1190
+ state.llmapiPagination.totalPages = Math.ceil(
1191
+ state.llmapiPagination.total / state.llmapiPagination.pageSize
1192
+ );
1082
1193
  // 可选:刷新分页显示
1083
1194
  renderLLMApiLogs();
1084
1195
  }
1085
1196
  }
1086
1197
  }
1087
1198
  },
1088
- 'SW_DEBUG_LLM_API_LOGS_CLEARED': () => {
1199
+ SW_DEBUG_LLM_API_LOGS_CLEARED: () => {
1089
1200
  if (state.isAnalysisMode) {
1090
1201
  state.liveLogs.llmapiLogs = [];
1091
1202
  } else {
1092
1203
  state.llmapiLogs = [];
1093
- state.llmapiPagination = { page: 1, pageSize: 20, total: 0, totalPages: 0 };
1204
+ state.llmapiPagination = {
1205
+ page: 1,
1206
+ pageSize: 20,
1207
+ total: 0,
1208
+ totalPages: 0,
1209
+ };
1094
1210
  renderLLMApiLogs();
1095
1211
  }
1096
1212
  },
1097
- 'SW_DEBUG_EXPORT_DATA': () => {
1213
+ SW_DEBUG_EXPORT_DATA: () => {
1098
1214
  // Handle export data from SW if needed
1099
1215
  },
1100
1216
  });
1101
1217
 
1102
1218
  onControllerChange(async () => {
1103
- // Service Worker controller 改变时,等待新 SW 完全就绪后再刷新
1104
- // 避免在 SW 更新过程中发起 RPC 调用
1105
- console.log('[SW Debug] Controller changed, waiting for new SW to be ready...');
1106
-
1107
1219
  // 等待一段时间让新的 SW 完全接管
1108
- await new Promise(resolve => setTimeout(resolve, 1000));
1109
-
1110
- console.log('[SW Debug] Refreshing status after SW update...');
1220
+ await new Promise((resolve) => setTimeout(resolve, 1000));
1111
1221
  updateSwStatus(elements.swStatus, true);
1112
-
1222
+
1113
1223
  // 重新加载所有数据
1114
1224
  refreshStatus();
1115
1225
  loadFetchLogs();
@@ -1125,12 +1235,12 @@ function setupMessageHandlers() {
1125
1235
  */
1126
1236
  async function init() {
1127
1237
  cacheElements();
1128
-
1238
+
1129
1239
  // Load saved bookmarks, theme, and settings first (before any early returns)
1130
1240
  loadBookmarks();
1131
1241
  loadTheme();
1132
1242
  loadSettings();
1133
-
1243
+
1134
1244
  // Setup callbacks for modules that need render functions
1135
1245
  setAnalysisModeCallbacks({
1136
1246
  renderLogs,
@@ -1147,78 +1257,80 @@ async function init() {
1147
1257
  loadLLMApiLogs,
1148
1258
  updateMemoryDisplay,
1149
1259
  });
1150
-
1260
+
1151
1261
  setThemeSettingsCallbacks({
1152
1262
  renderLogs,
1153
1263
  });
1154
-
1264
+
1155
1265
  // Setup event listeners (always needed, even in analysis mode)
1156
1266
  setupEventListeners();
1157
1267
  initGistManagement();
1158
-
1268
+
1159
1269
  // Check URL parameters
1160
1270
  const urlParams = new URLSearchParams(window.location.search);
1161
-
1271
+
1162
1272
  // Activate tab from URL parameter (valid tabs: fetch, console, postmessage, llmapi, gist, crash)
1163
- const validTabs = ['fetch', 'console', 'postmessage', 'llmapi', 'gist', 'crash'];
1273
+ const validTabs = [
1274
+ 'fetch',
1275
+ 'console',
1276
+ 'postmessage',
1277
+ 'llmapi',
1278
+ 'gist',
1279
+ 'crash',
1280
+ ];
1164
1281
  const tabParam = urlParams.get('tab');
1165
1282
  if (tabParam && validTabs.includes(tabParam)) {
1166
1283
  // Use setTimeout to ensure DOM is ready
1167
1284
  setTimeout(() => switchTab(tabParam, false), 0);
1168
1285
  }
1169
-
1286
+
1170
1287
  // Check if analysis mode should be auto-enabled (e.g., via URL parameter)
1171
1288
  if (urlParams.has('analysis')) {
1172
1289
  state.isAnalysisMode = true;
1173
1290
  updateAnalysisModeUI();
1174
1291
  showImportPrompt();
1175
- console.log('[SW Debug] Started in analysis mode');
1176
1292
  return;
1177
1293
  }
1178
1294
 
1179
1295
  // Check SW availability
1180
1296
  if (!('serviceWorker' in navigator)) {
1181
- alert('此浏览器不支持 Service Worker\n\n提示:您可以使用分析模式导入用户日志进行分析');
1297
+ alert(
1298
+ '此浏览器不支持 Service Worker\n\n提示:您可以使用分析模式导入用户日志进行分析'
1299
+ );
1182
1300
  updateSwStatus(elements.swStatus, false);
1183
1301
  return;
1184
1302
  }
1185
-
1303
+
1186
1304
  const swReady = await checkSwReady();
1187
-
1305
+
1188
1306
  if (!swReady) {
1189
1307
  // SW not ready - offer analysis mode as alternative
1190
- const useAnalysisMode = confirm('Service Worker 未注册或未激活\n\n您可以:\n1. 点击"取消"后访问主应用,然后刷新此页面\n2. 点击"确定"进入分析模式,导入用户日志进行分析');
1191
-
1308
+ const useAnalysisMode = confirm(
1309
+ 'Service Worker 未注册或未激活\n\n您可以:\n1. 点击"取消"后访问主应用,然后刷新此页面\n2. 点击"确定"进入分析模式,导入用户日志进行分析'
1310
+ );
1311
+
1192
1312
  if (useAnalysisMode) {
1193
1313
  state.isAnalysisMode = true;
1194
1314
  updateAnalysisModeUI();
1195
1315
  showImportPrompt();
1196
1316
  return;
1197
1317
  }
1198
-
1318
+
1199
1319
  updateSwStatus(elements.swStatus, false);
1200
1320
  return;
1201
1321
  }
1202
-
1203
- console.log('[SW Debug] SW ready, controller:', !!navigator.serviceWorker.controller);
1204
-
1205
1322
  updateSwStatus(elements.swStatus, true);
1206
1323
 
1207
1324
  // Register PostMessage logging callback
1208
1325
  setPostMessageLogCallback(addPostmessageLog);
1209
1326
 
1210
1327
  setupMessageHandlers();
1211
-
1212
- // 先建立 duplex 通道并订阅广播(CONSOLE_LOG、POSTMESSAGE_LOG 等),再启用调试
1213
- // 否则 SW 启用调试后开始转发日志时,调试页尚未在 channel-manager 中注册,收不到任何日志
1214
- console.log('[SW Debug] Initializing duplex channel before enabling debug');
1215
1328
  const duplexOk = await ensureDuplexInitialized();
1216
1329
  if (!duplexOk) {
1217
- console.warn('[SW Debug] Duplex init failed, console/postmessage logs may not stream');
1330
+ console.warn(
1331
+ '[SW Debug] Duplex init failed, console/postmessage logs may not stream'
1332
+ );
1218
1333
  }
1219
-
1220
- // Auto-enable debug mode when entering debug page
1221
- console.log('[SW Debug] Auto-enabling debug mode');
1222
1334
  enableDebug();
1223
1335
 
1224
1336
  // Load fetch logs (existing logs from before debug mode was enabled won't exist,
@@ -1233,17 +1345,16 @@ async function init() {
1233
1345
  // Load LLM API logs (ensure data is available for export even without visiting the tab)
1234
1346
  loadLLMApiLogs();
1235
1347
  renderLogs();
1236
-
1348
+
1237
1349
  // Start memory monitoring
1238
1350
  startMemoryMonitoring();
1239
-
1351
+
1240
1352
  // Clean up on page unload - disable debug mode when page is closed
1241
1353
  window.addEventListener('beforeunload', () => {
1242
1354
  stopMemoryMonitoring();
1243
1355
  // Disable debug mode when debug page is closed
1244
1356
  disableDebug();
1245
1357
  });
1246
-
1247
1358
  }
1248
1359
 
1249
1360
  // ==================== Global Helper Functions ====================
@@ -1253,14 +1364,16 @@ async function init() {
1253
1364
  * 该函数暴露给 window 用于 inline onclick 调用
1254
1365
  * @param {string} previewId - 预览元素的 ID
1255
1366
  */
1256
- window.toggleBase64Preview = function(previewId) {
1367
+ window.toggleBase64Preview = function (previewId) {
1257
1368
  const previewEl = document.getElementById(previewId);
1258
1369
  if (previewEl) {
1259
1370
  const isHidden = previewEl.style.display === 'none';
1260
1371
  previewEl.style.display = isHidden ? 'inline-block' : 'none';
1261
-
1372
+
1262
1373
  // 更新 toggle 按钮的样式
1263
- const toggleEl = previewEl.parentElement?.querySelector('.base64-preview-toggle');
1374
+ const toggleEl = previewEl.parentElement?.querySelector(
1375
+ '.base64-preview-toggle'
1376
+ );
1264
1377
  if (toggleEl) {
1265
1378
  toggleEl.classList.toggle('expanded', isHidden);
1266
1379
  }