micro-models-agent 2.16.0 → 2.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/assets/app.js +1 -314
  3. package/dist/assets/hljs.js +5 -1244
  4. package/dist/assets/index.html +11 -0
  5. package/dist/assets/js/api.js +1 -28
  6. package/dist/assets/js/core/menus.js +1 -0
  7. package/dist/assets/js/core/store/feed.js +1 -0
  8. package/dist/assets/js/core/store/index.js +1 -0
  9. package/dist/assets/js/core/store/session.js +1 -0
  10. package/dist/assets/js/core/store/settings.js +1 -0
  11. package/dist/assets/js/core/store/tabs.js +1 -0
  12. package/dist/assets/js/dialog.js +1 -105
  13. package/dist/assets/js/dom.js +1 -178
  14. package/dist/assets/js/feed/core.js +1 -0
  15. package/dist/assets/js/feed/history.js +1 -0
  16. package/dist/assets/js/feed/plan.js +1 -0
  17. package/dist/assets/js/feed/question.js +3 -0
  18. package/dist/assets/js/feed/sidebar.js +1 -0
  19. package/dist/assets/js/feed/stream.js +1 -0
  20. package/dist/assets/js/feed/turn.js +5 -0
  21. package/dist/assets/js/feed.js +1 -1211
  22. package/dist/assets/js/format.js +2 -122
  23. package/dist/assets/js/i18n.js +1 -46
  24. package/dist/assets/js/rail.js +1 -114
  25. package/dist/assets/js/session/cmdk.js +1 -0
  26. package/dist/assets/js/session/composer.js +1 -0
  27. package/dist/assets/js/session/sessions-menu.js +1 -0
  28. package/dist/assets/js/session/tabs.js +1 -0
  29. package/dist/assets/js/settings/controls.js +1 -0
  30. package/dist/assets/js/settings/editors.js +1 -0
  31. package/dist/assets/js/settings/form.js +1 -0
  32. package/dist/assets/js/settings/modal.js +1 -0
  33. package/dist/assets/js/settings/panels.js +1 -0
  34. package/dist/assets/js/settings/providers.js +1 -0
  35. package/dist/assets/js/settings/search.js +1 -0
  36. package/dist/assets/js/settings/subdialog.js +1 -0
  37. package/dist/assets/js/settings/write.js +1 -0
  38. package/dist/assets/js/settings.js +1 -1914
  39. package/dist/assets/js/sidebar/core.js +1 -0
  40. package/dist/assets/js/sidebar/lsp.js +2 -0
  41. package/dist/assets/js/sidebar/map.js +1 -0
  42. package/dist/assets/js/sidebar/state.js +1 -0
  43. package/dist/assets/js/sidebar/trace.js +5 -0
  44. package/dist/assets/js/sidebar.js +1 -705
  45. package/dist/assets/js/store.js +1 -82
  46. package/dist/assets/js/subdialog.js +1 -0
  47. package/dist/assets/md.js +1 -277
  48. package/dist/assets/setup.js +3 -816
  49. package/dist/assets/smd.js +29 -1665
  50. package/dist/assets/styles.css +1 -1592
  51. package/dist/certification/certifications.json +1 -494
  52. package/dist/i18n/en.json +1 -1851
  53. package/dist/i18n/ru.json +1 -1854
  54. package/dist/main.js +815 -55797
  55. package/dist/modules/browser/bridge-server.mjs +2 -252
  56. package/package.json +10 -5
  57. package/dist/assets/js/settings-controls.js +0 -452
  58. package/dist/assets/js/tabs.js +0 -867
  59. package/dist/cli/cache-line.js +0 -31
  60. package/dist/cli/command-suggest.js +0 -39
  61. package/dist/cli/commands.js +0 -781
  62. package/dist/cli/completer.js +0 -268
  63. package/dist/cli/index.js +0 -3
  64. package/dist/cli/json-payload.js +0 -32
  65. package/dist/cli/main.js +0 -346
  66. package/dist/cli/onboarding-commands.js +0 -126
  67. package/dist/cli/plugin-commands.js +0 -38
  68. package/dist/cli/relaunch.js +0 -40
  69. package/dist/cli/repl-commands-lsp.js +0 -75
  70. package/dist/cli/repl-commands-skills.js +0 -105
  71. package/dist/cli/repl-commands.js +0 -1218
  72. package/dist/cli/repl.js +0 -1238
  73. package/dist/cli/run-result.js +0 -38
  74. package/dist/cli/security-commands.js +0 -177
  75. package/dist/cli/setup-order.js +0 -6
  76. package/dist/cli/setup-prompt.js +0 -50
  77. package/dist/cli/setup.js +0 -161
  78. package/dist/cli/web-command.js +0 -98
  79. package/dist/config/budget.js +0 -48
  80. package/dist/config/config.js +0 -345
  81. package/dist/config/defaults.js +0 -197
  82. package/dist/config/domains.js +0 -135
  83. package/dist/config/env.js +0 -46
  84. package/dist/config/experts.js +0 -17
  85. package/dist/config/index.js +0 -5
  86. package/dist/config/paths.js +0 -56
  87. package/dist/config/redact.js +0 -44
  88. package/dist/config/registry-extra.js +0 -334
  89. package/dist/config/registry.js +0 -584
  90. package/dist/config/security.js +0 -212
  91. package/dist/config/timeouts.js +0 -74
  92. package/dist/config/types.js +0 -1
  93. package/dist/config/utils.js +0 -57
  94. package/dist/core/agent/artifact-progress.js +0 -59
  95. package/dist/core/agent/artifact-resolve.js +0 -79
  96. package/dist/core/agent/audit-gate.js +0 -53
  97. package/dist/core/agent/compaction.js +0 -89
  98. package/dist/core/agent/constants.js +0 -90
  99. package/dist/core/agent/context-log.js +0 -454
  100. package/dist/core/agent/context-renderer.js +0 -45
  101. package/dist/core/agent/critic-gate.js +0 -132
  102. package/dist/core/agent/hallucination-gate.js +0 -197
  103. package/dist/core/agent/loop-state.js +0 -68
  104. package/dist/core/agent/prefix-monitor.js +0 -101
  105. package/dist/core/agent/reasoning-resolver.js +0 -65
  106. package/dist/core/agent/token-tracker.js +0 -99
  107. package/dist/core/agent/tool-batch.js +0 -312
  108. package/dist/core/agent/tool-images.js +0 -18
  109. package/dist/core/agent/tool-output.js +0 -116
  110. package/dist/core/agent/tool-pairing.js +0 -60
  111. package/dist/core/agent-moe.js +0 -248
  112. package/dist/core/agent.js +0 -1299
  113. package/dist/core/bootstrap/agent-phase.js +0 -66
  114. package/dist/core/bootstrap/config-phase.js +0 -86
  115. package/dist/core/bootstrap/modules-phase.js +0 -269
  116. package/dist/core/bootstrap/provider-phase.js +0 -183
  117. package/dist/core/bootstrap/session-phase.js +0 -204
  118. package/dist/core/bootstrap/state.js +0 -94
  119. package/dist/core/bootstrap/workspace-phase.js +0 -115
  120. package/dist/core/bootstrap.js +0 -112
  121. package/dist/core/crash-handler.js +0 -62
  122. package/dist/core/environment.js +0 -224
  123. package/dist/core/host-plan.js +0 -43
  124. package/dist/core/host.js +0 -23
  125. package/dist/core/index.js +0 -3
  126. package/dist/core/prompt-builder.js +0 -95
  127. package/dist/core/prompt-overflow.js +0 -306
  128. package/dist/core/session-logger.js +0 -375
  129. package/dist/core/system-prompt.js +0 -117
  130. package/dist/core/types.js +0 -1
  131. package/dist/core/version.js +0 -28
  132. package/dist/core/web-host.js +0 -34
  133. package/dist/core/workspace.js +0 -80
  134. package/dist/i18n/index.js +0 -80
  135. package/dist/index.js +0 -30
  136. package/dist/llm/cache-usage.js +0 -76
  137. package/dist/llm/image-utils.js +0 -138
  138. package/dist/llm/index.js +0 -4
  139. package/dist/llm/llm-errors.js +0 -50
  140. package/dist/llm/model-loader.js +0 -86
  141. package/dist/llm/models-dev.js +0 -121
  142. package/dist/llm/openai-compat.js +0 -756
  143. package/dist/llm/orchestrator.js +0 -294
  144. package/dist/llm/provider-budget.js +0 -68
  145. package/dist/llm/provider-context.js +0 -233
  146. package/dist/llm/provider.js +0 -9
  147. package/dist/llm/response.js +0 -44
  148. package/dist/llm/stream-state.js +0 -26
  149. package/dist/llm/token-counter.js +0 -83
  150. package/dist/llm/types.js +0 -1
  151. package/dist/logger/app-logger.js +0 -212
  152. package/dist/logger/file-log.js +0 -160
  153. package/dist/logger/index.js +0 -2
  154. package/dist/migration/backup.js +0 -56
  155. package/dist/migration/detect.js +0 -61
  156. package/dist/migration/index.js +0 -3
  157. package/dist/modules/artifacts/store.js +0 -62
  158. package/dist/modules/browser/actions.js +0 -79
  159. package/dist/modules/browser/bridge-client.js +0 -203
  160. package/dist/modules/browser/bridge-path.js +0 -10
  161. package/dist/modules/browser/console-buffer.js +0 -37
  162. package/dist/modules/browser/cookie-store.js +0 -29
  163. package/dist/modules/browser/driver-types.js +0 -1
  164. package/dist/modules/browser/driver.js +0 -186
  165. package/dist/modules/browser/index.js +0 -9
  166. package/dist/modules/browser/module.js +0 -30
  167. package/dist/modules/browser/session.js +0 -322
  168. package/dist/modules/browser/snapshot.js +0 -154
  169. package/dist/modules/browser/types.js +0 -13
  170. package/dist/modules/certification/cli.js +0 -264
  171. package/dist/modules/certification/fact-checker.js +0 -90
  172. package/dist/modules/certification/loader.js +0 -127
  173. package/dist/modules/certification/manifest.js +0 -231
  174. package/dist/modules/certification/runner.js +0 -233
  175. package/dist/modules/certification/scenarios.js +0 -586
  176. package/dist/modules/certification/syntax-scenarios.js +0 -50
  177. package/dist/modules/certification/types.js +0 -1
  178. package/dist/modules/context/chunk-query.js +0 -122
  179. package/dist/modules/context/fact-extractor.js +0 -170
  180. package/dist/modules/context/history.js +0 -15
  181. package/dist/modules/context/index.js +0 -2
  182. package/dist/modules/context/manager.js +0 -482
  183. package/dist/modules/critic/client.js +0 -176
  184. package/dist/modules/critic/evidence.js +0 -81
  185. package/dist/modules/critic/provider.js +0 -45
  186. package/dist/modules/critic/tools.js +0 -78
  187. package/dist/modules/critic/types.js +0 -1
  188. package/dist/modules/execution/audit-runners.js +0 -206
  189. package/dist/modules/execution/auditor.js +0 -222
  190. package/dist/modules/execution/execution-plugin.js +0 -478
  191. package/dist/modules/execution/index.js +0 -8
  192. package/dist/modules/execution/input-from.js +0 -70
  193. package/dist/modules/execution/module.js +0 -891
  194. package/dist/modules/execution/moe-executor.js +0 -443
  195. package/dist/modules/execution/plan-actions.js +0 -642
  196. package/dist/modules/execution/plan-checks.js +0 -35
  197. package/dist/modules/execution/plan-coverage.js +0 -71
  198. package/dist/modules/execution/plan-persister.js +0 -46
  199. package/dist/modules/execution/plan-steps.js +0 -31
  200. package/dist/modules/execution/plan-store.js +0 -274
  201. package/dist/modules/execution/plan-tool.js +0 -249
  202. package/dist/modules/execution/plan-validator.js +0 -197
  203. package/dist/modules/execution/planner.js +0 -103
  204. package/dist/modules/execution/stuck-detector.js +0 -834
  205. package/dist/modules/execution/tracker.js +0 -92
  206. package/dist/modules/execution/transient-error.js +0 -30
  207. package/dist/modules/execution/types.js +0 -1
  208. package/dist/modules/execution/verifier.js +0 -343
  209. package/dist/modules/execution/windows-commands.js +0 -52
  210. package/dist/modules/hallucination/artifact-claim.js +0 -93
  211. package/dist/modules/hallucination/confidence.js +0 -81
  212. package/dist/modules/hallucination/consistency.js +0 -37
  213. package/dist/modules/hallucination/detector.js +0 -57
  214. package/dist/modules/hallucination/factual.js +0 -205
  215. package/dist/modules/hallucination/index.js +0 -6
  216. package/dist/modules/hallucination/js-identifiers.js +0 -261
  217. package/dist/modules/hallucination/llm-judge.js +0 -116
  218. package/dist/modules/hallucination/success-claim.js +0 -59
  219. package/dist/modules/index.js +0 -5
  220. package/dist/modules/indexer/cache.js +0 -88
  221. package/dist/modules/indexer/index.js +0 -4
  222. package/dist/modules/indexer/map-command.js +0 -33
  223. package/dist/modules/indexer/map-select.js +0 -87
  224. package/dist/modules/indexer/module.js +0 -293
  225. package/dist/modules/indexer/project-profile.js +0 -184
  226. package/dist/modules/indexer/symbols.js +0 -189
  227. package/dist/modules/indexer/walker.js +0 -285
  228. package/dist/modules/lsp/check-tool.js +0 -61
  229. package/dist/modules/lsp/client.js +0 -406
  230. package/dist/modules/lsp/command.js +0 -53
  231. package/dist/modules/lsp/config.js +0 -189
  232. package/dist/modules/lsp/index.js +0 -4
  233. package/dist/modules/lsp/module.js +0 -295
  234. package/dist/modules/lsp/probe.js +0 -86
  235. package/dist/modules/lsp/project-root.js +0 -69
  236. package/dist/modules/lsp/startup-check.js +0 -154
  237. package/dist/modules/lsp/types.js +0 -1
  238. package/dist/modules/mcp/client.js +0 -445
  239. package/dist/modules/mcp/index.js +0 -4
  240. package/dist/modules/mcp/module.js +0 -295
  241. package/dist/modules/mcp/registry.js +0 -20
  242. package/dist/modules/memory/index.js +0 -2
  243. package/dist/modules/memory/module.js +0 -101
  244. package/dist/modules/memory/search.js +0 -45
  245. package/dist/modules/memory/store.js +0 -107
  246. package/dist/modules/onboarding/init.js +0 -47
  247. package/dist/modules/onboarding/meet.js +0 -30
  248. package/dist/modules/onboarding/mode.js +0 -30
  249. package/dist/modules/onboarding/prompts.js +0 -43
  250. package/dist/modules/pipelines/engine.js +0 -70
  251. package/dist/modules/pipelines/index.js +0 -4
  252. package/dist/modules/pipelines/parser.js +0 -59
  253. package/dist/modules/pipelines/template.js +0 -18
  254. package/dist/modules/plugins/builtin/lint-on-write.js +0 -377
  255. package/dist/modules/plugins/builtin/notify.js +0 -11
  256. package/dist/modules/plugins/index.js +0 -2
  257. package/dist/modules/plugins/loader.js +0 -85
  258. package/dist/modules/plugins/manager.js +0 -244
  259. package/dist/modules/plugins/types.js +0 -1
  260. package/dist/modules/pricing/index.js +0 -70
  261. package/dist/modules/pricing/prices.js +0 -147
  262. package/dist/modules/processes/detect.js +0 -34
  263. package/dist/modules/processes/index.js +0 -4
  264. package/dist/modules/processes/kill-tree.js +0 -52
  265. package/dist/modules/processes/registry.js +0 -294
  266. package/dist/modules/processes/runner.js +0 -23
  267. package/dist/modules/providers/cache.js +0 -23
  268. package/dist/modules/providers/capabilities.js +0 -28
  269. package/dist/modules/providers/create.js +0 -21
  270. package/dist/modules/providers/factory.js +0 -28
  271. package/dist/modules/providers/fallback.js +0 -81
  272. package/dist/modules/providers/health.js +0 -47
  273. package/dist/modules/providers/index.js +0 -6
  274. package/dist/modules/providers/manager.js +0 -207
  275. package/dist/modules/providers/naming.js +0 -15
  276. package/dist/modules/providers/preflight.js +0 -71
  277. package/dist/modules/providers/presets.js +0 -232
  278. package/dist/modules/providers/registry.js +0 -27
  279. package/dist/modules/providers/types.js +0 -1
  280. package/dist/modules/reasoning/policy.js +0 -42
  281. package/dist/modules/reasoning/probe.js +0 -116
  282. package/dist/modules/registry.js +0 -48
  283. package/dist/modules/security/audit-log.js +0 -119
  284. package/dist/modules/security/audit-notifier.js +0 -267
  285. package/dist/modules/security/command-validator.js +0 -272
  286. package/dist/modules/security/content-scanner.js +0 -53
  287. package/dist/modules/security/data-sanitizer.js +0 -82
  288. package/dist/modules/security/encryption.js +0 -216
  289. package/dist/modules/security/index.js +0 -15
  290. package/dist/modules/security/network-validator.js +0 -236
  291. package/dist/modules/security/path-validator.js +0 -261
  292. package/dist/modules/security/protected-paths.js +0 -73
  293. package/dist/modules/security/rate-limiter.js +0 -98
  294. package/dist/modules/security/security-policies.js +0 -499
  295. package/dist/modules/security/session-encryption.js +0 -182
  296. package/dist/modules/security/session-isolation.js +0 -75
  297. package/dist/modules/session/auto-name.js +0 -63
  298. package/dist/modules/session/export.js +0 -98
  299. package/dist/modules/session/index.js +0 -4
  300. package/dist/modules/session/manager.js +0 -234
  301. package/dist/modules/session/module.js +0 -33
  302. package/dist/modules/session/store.js +0 -295
  303. package/dist/modules/session/types.js +0 -1
  304. package/dist/modules/setup/answers.js +0 -35
  305. package/dist/modules/setup/apply.js +0 -79
  306. package/dist/modules/setup/discovery.js +0 -72
  307. package/dist/modules/skills/index.js +0 -3
  308. package/dist/modules/skills/loader.js +0 -86
  309. package/dist/modules/skills/matcher.js +0 -27
  310. package/dist/modules/skills/module.js +0 -141
  311. package/dist/modules/types.js +0 -1
  312. package/dist/modules/updater/changelog-reader.js +0 -93
  313. package/dist/modules/updater/checker.js +0 -101
  314. package/dist/modules/updater/dev-detect.js +0 -18
  315. package/dist/modules/updater/index.js +0 -4
  316. package/dist/modules/updater/module.js +0 -129
  317. package/dist/modules/user-profile/compressor.js +0 -18
  318. package/dist/modules/user-profile/index.js +0 -2
  319. package/dist/modules/user-profile/profile.js +0 -77
  320. package/dist/modules/webui/answer-api.js +0 -29
  321. package/dist/modules/webui/assets.js +0 -50
  322. package/dist/modules/webui/body.js +0 -21
  323. package/dist/modules/webui/commands-settings.js +0 -209
  324. package/dist/modules/webui/commands-shared.js +0 -60
  325. package/dist/modules/webui/commands.js +0 -174
  326. package/dist/modules/webui/config-api.js +0 -134
  327. package/dist/modules/webui/file-api.js +0 -202
  328. package/dist/modules/webui/forward.js +0 -159
  329. package/dist/modules/webui/history-api.js +0 -112
  330. package/dist/modules/webui/host-state.js +0 -60
  331. package/dist/modules/webui/i18n-api.js +0 -9
  332. package/dist/modules/webui/limits.js +0 -6
  333. package/dist/modules/webui/log-forward.js +0 -20
  334. package/dist/modules/webui/memory-commands.js +0 -64
  335. package/dist/modules/webui/model-cache.js +0 -18
  336. package/dist/modules/webui/module.js +0 -148
  337. package/dist/modules/webui/persist.js +0 -24
  338. package/dist/modules/webui/prompt-io.js +0 -97
  339. package/dist/modules/webui/providers-api.js +0 -337
  340. package/dist/modules/webui/providers-view.js +0 -56
  341. package/dist/modules/webui/reasoning-view.js +0 -15
  342. package/dist/modules/webui/run-agent.js +0 -81
  343. package/dist/modules/webui/server.js +0 -284
  344. package/dist/modules/webui/sessions-api.js +0 -178
  345. package/dist/modules/webui/settings-api.js +0 -561
  346. package/dist/modules/webui/setup-api.js +0 -201
  347. package/dist/modules/webui/state.js +0 -74
  348. package/dist/modules/webui/util.js +0 -261
  349. package/dist/output/bus.js +0 -37
  350. package/dist/output/channel.js +0 -285
  351. package/dist/output/format.js +0 -15
  352. package/dist/output/index.js +0 -8
  353. package/dist/output/json-sink.js +0 -24
  354. package/dist/output/machine.js +0 -9
  355. package/dist/output/session-sink.js +0 -27
  356. package/dist/output/types.js +0 -1
  357. package/dist/tools/approve.js +0 -41
  358. package/dist/tools/attach-image.js +0 -102
  359. package/dist/tools/auto-fixer.js +0 -180
  360. package/dist/tools/auto-tags.js +0 -83
  361. package/dist/tools/bash.js +0 -649
  362. package/dist/tools/browser.js +0 -160
  363. package/dist/tools/chunk-query.js +0 -112
  364. package/dist/tools/create-dir.js +0 -60
  365. package/dist/tools/delete-file.js +0 -67
  366. package/dist/tools/download-file.js +0 -142
  367. package/dist/tools/edit-file.js +0 -136
  368. package/dist/tools/enable-tools.js +0 -59
  369. package/dist/tools/executor.js +0 -304
  370. package/dist/tools/file-info.js +0 -49
  371. package/dist/tools/filter-tools.js +0 -17
  372. package/dist/tools/glob-tool.js +0 -37
  373. package/dist/tools/grep-tool.js +0 -142
  374. package/dist/tools/hidden-tools-block.js +0 -37
  375. package/dist/tools/index.js +0 -88
  376. package/dist/tools/list-dir.js +0 -53
  377. package/dist/tools/load-skill.js +0 -51
  378. package/dist/tools/mcp-call.js +0 -80
  379. package/dist/tools/meet-done.js +0 -14
  380. package/dist/tools/move-file.js +0 -94
  381. package/dist/tools/path-utils.js +0 -108
  382. package/dist/tools/pipeline-run.js +0 -167
  383. package/dist/tools/preview.js +0 -2
  384. package/dist/tools/process-ids.js +0 -31
  385. package/dist/tools/process-kill.js +0 -33
  386. package/dist/tools/process-list.js +0 -38
  387. package/dist/tools/process-log.js +0 -49
  388. package/dist/tools/process-wait.js +0 -63
  389. package/dist/tools/prompt-io.js +0 -29
  390. package/dist/tools/question.js +0 -288
  391. package/dist/tools/read-file.js +0 -200
  392. package/dist/tools/recall.js +0 -124
  393. package/dist/tools/registry.js +0 -48
  394. package/dist/tools/remember.js +0 -72
  395. package/dist/tools/scope-check.js +0 -32
  396. package/dist/tools/scope-request.js +0 -96
  397. package/dist/tools/search-history.js +0 -88
  398. package/dist/tools/session-info.js +0 -46
  399. package/dist/tools/set-thinking.js +0 -75
  400. package/dist/tools/subagent.js +0 -257
  401. package/dist/tools/syntax-validator.js +0 -379
  402. package/dist/tools/types.js +0 -1
  403. package/dist/tools/user-input.js +0 -134
  404. package/dist/tools/web-browse.js +0 -93
  405. package/dist/tools/web-fetch.js +0 -108
  406. package/dist/tools/web-search.js +0 -107
  407. package/dist/tools/write-file.js +0 -128
  408. package/dist/ui/action-log.js +0 -13
  409. package/dist/ui/box.js +0 -78
  410. package/dist/ui/colors.js +0 -6
  411. package/dist/ui/diff.js +0 -189
  412. package/dist/ui/index.js +0 -7
  413. package/dist/ui/line-editor.js +0 -1083
  414. package/dist/ui/line-math.js +0 -98
  415. package/dist/ui/md-formatter.js +0 -322
  416. package/dist/ui/output.js +0 -19
  417. package/dist/ui/plan-view.js +0 -109
  418. package/dist/ui/renderer.js +0 -589
  419. package/dist/ui/spinner.js +0 -91
  420. package/dist/ui/table.js +0 -142
  421. package/dist/ui/theme.js +0 -143
  422. package/dist/utils/child-run.js +0 -20
  423. package/dist/utils/error.js +0 -4
  424. package/dist/utils/index.js +0 -6
  425. package/dist/utils/retry.js +0 -17
  426. package/dist/utils/sleep.js +0 -23
  427. package/dist/utils/truncate.js +0 -9
@@ -1,705 +1 @@
1
- // Sidebar tabs (Session / Map / Trace) for `mma web`.
2
- //
3
- // Owns: active-tab state (localStorage), the live per-session Trace buffer with
4
- // master-detail expansion, and the Map tab rendering. Leaf module: imports only
5
- // dom/i18n/format/store/api — the frontend DAG stays acyclic
6
- // (app → sidebar → {dom,i18n,format,store,api}).
7
- // Design: docs/specs/2026-09-30-webui-sidebar-tabs-design.md.
8
-
9
- import { el, icon } from "./dom.js";
10
- import { api } from "./api.js";
11
- import { S } from "./store.js";
12
- import { t } from "./i18n.js";
13
- import { labelOf, categoryOf, argText, formatMs, fmtTokens } from "./format.js";
14
-
15
- const TAB_KEY = "mma-sidebar-tab";
16
- const TABS = ["session", "map", "trace"];
17
- const ICON_NAME = { session: "list-checks", map: "map", trace: "activity" };
18
- const TRACE_CAP = 500;
19
- const MAX_OUTPUT_CHARS = 20000;
20
-
21
- let sbEl = null, nameEl = null, nameTextEl = null, mapEl = null, listEl = null, detailEl = null;
22
- let detailGlyph = null, detailTitle = null, detailBody = null, detailClose = null;
23
- let active = "session";
24
- let trace = []; // { id, kind, ts, name, args, output, success, durationMs, phase, text, steps, currentIndex }
25
- let selected = null; // trace id
26
- let turn = 0;
27
- let seq = 0;
28
- let logCursor = null; // max session-log ts already pulled (supplement fetch)
29
- let logPulling = false;
30
- const nodeById = new Map(); // entry id → row node
31
- const callIndex = new Map(); // toolCallId → entry
32
- const headerByTurn = new Map(); // turn → header node
33
- let textEntry = null; // current text row (updated in place)
34
-
35
- function paneEl(id) { return document.getElementById("pane-" + id); }
36
-
37
- function mqMobile() {
38
- return typeof window !== "undefined" && window.matchMedia
39
- ? window.matchMedia("(max-width: 760px)").matches : false;
40
- }
41
-
42
- function readStored() {
43
- try { return localStorage.getItem(TAB_KEY); } catch { return null; }
44
- }
45
- function storeTab(id) {
46
- try { localStorage.setItem(TAB_KEY, id); } catch { /* private mode */ }
47
- }
48
-
49
- export function setSidebarTab(id, persist = true) {
50
- if (!TABS.includes(id)) id = "session";
51
- if (persist) storeTab(id);
52
- const effective = id === "trace" && mqMobile() ? "session" : id;
53
- if (effective !== active) collapseDetail();
54
- active = effective;
55
- TABS.forEach((name) => {
56
- const pane = paneEl(name);
57
- if (pane) pane.hidden = name !== effective;
58
- const tab = sbEl && sbEl.querySelector('.sb-tab[data-tab="' + name + '"]');
59
- if (tab) {
60
- const on = name === effective;
61
- tab.classList.toggle("on", on);
62
- tab.setAttribute("aria-selected", on ? "true" : "false");
63
- }
64
- });
65
- if (nameTextEl) nameTextEl.textContent = t("web.sidebar.tab_" + effective);
66
- const nic = nameEl && nameEl.querySelector(".sb-ico");
67
- if (nic) { nic.textContent = ""; nic.appendChild(icon(ICON_NAME[effective])); }
68
- }
69
-
70
- function collapseDetail() {
71
- selected = null;
72
- if (sbEl) sbEl.classList.remove("sb-expanded");
73
- if (detailEl) detailEl.hidden = true;
74
- if (listEl) listEl.querySelectorAll(".trc.sel").forEach((n) => n.classList.remove("sel"));
75
- }
76
-
77
- function phaseLabel(phase) {
78
- if (phase === "composing") return t("web.rail.composing");
79
- if (phase === "tool") return t("web.rail.working");
80
- if (phase === "thinking") return t("web.action.thinking");
81
- return String(phase || "");
82
- }
83
-
84
- function catClass(kind, name) {
85
- if (kind === "tool" || kind === "tool_fail") return categoryOf(name);
86
- if (kind === "phase") return "phase";
87
- return "meta";
88
- }
89
-
90
- function rowLabel(entry) {
91
- switch (entry.kind) {
92
- case "phase": return phaseLabel(entry.phase);
93
- case "plan": return t("web.sidebar.trace_plan");
94
- case "question": return t("web.sidebar.trace_question");
95
- case "text": return t("web.sidebar.trace_text", { count: entry.chars || 0 });
96
- case "status": return t("web.sidebar.trace_status");
97
- case "log": return t("web.sidebar.trace_log", { level: entry.level || "" });
98
- case "retract": return t("web.sidebar.trace_retract");
99
- case "index": return t("web.sidebar.trace_index", { phase: entry.phase || "" });
100
- case "critic": return t("web.sidebar.trace_critic", { status: entry.status || "" });
101
- case "moe": return t("web.sidebar.trace_moe");
102
- case "compaction": return t("web.sidebar.trace_compaction");
103
- case "probe": return t("web.sidebar.trace_probe");
104
- case "usage": return t("web.sidebar.trace_usage");
105
- case "audit": return t("web.sidebar.trace_audit");
106
- case "claim": return t("web.sidebar.trace_claim", { kind: entry.subkind || "" });
107
- case "output": return t("web.sidebar.trace_output");
108
- default: return labelOf(entry.name);
109
- }
110
- }
111
-
112
- function rowArgs(entry) {
113
- if (entry.kind === "text" || entry.kind === "phase") return "";
114
- if (entry.kind === "plan") {
115
- const idx = typeof entry.currentIndex === "number" ? entry.currentIndex : 0;
116
- const total = Array.isArray(entry.steps) ? entry.steps.length : 0;
117
- if (!total) return "";
118
- return t("web.rail.step_of", { cur: Math.min(idx + 1, total), total });
119
- }
120
- if (entry.kind === "question") return entry.text || "";
121
- // Диагностические строки несут смысл в одной строке (статус/лог/ретракт/
122
- // индекс/критик/MoE/компакция/проба/usage/аудит/claim/вывод).
123
- if (entry.text && typeof entry.text === "string" && entry.kind !== "tool" && entry.kind !== "tool_fail") {
124
- const line = entry.text.split("\n").map((l) => l.trim()).find((l) => l.length > 0) || "";
125
- return line.slice(0, 160);
126
- }
127
- return argText(entry.args);
128
- }
129
-
130
- function isWarn(entry) {
131
- return entry.kind === "tool_fail" || entry.kind === "error" || entry.kind === "claim" ||
132
- (entry.kind === "critic" && entry.status === "critical") ||
133
- (entry.kind === "log" && (entry.level === "warn" || entry.level === "error"));
134
- }
135
-
136
- function renderRow(entry) {
137
- const cls = ["trc", catClass(entry.kind, entry.name)];
138
- if (isWarn(entry)) cls.push("warn");
139
- if (selected === entry.id) cls.push("sel");
140
- const row = el("div", cls.join(" "));
141
- row.dataset.id = String(entry.id);
142
- row.appendChild(el("span", "g", isWarn(entry) ? "⚠" : entry.kind === "question" ? "?" : "◇"));
143
- row.appendChild(el("span", "lab", rowLabel(entry)));
144
- const args = rowArgs(entry);
145
- if (args) row.appendChild(el("span", "args", args));
146
- if (entry.durationMs) row.appendChild(el("span", "t", formatMs(entry.durationMs)));
147
- row.addEventListener("click", () => {
148
- if (selected === entry.id) { collapseDetail(); return; }
149
- if (listEl) listEl.querySelectorAll(".trc.sel").forEach((n) => n.classList.remove("sel"));
150
- selected = entry.id;
151
- row.classList.add("sel");
152
- renderDetail(entry);
153
- if (sbEl) sbEl.classList.add("sb-expanded");
154
- });
155
- return row;
156
- }
157
-
158
- function renderList() {
159
- if (!listEl) return;
160
- listEl.textContent = "";
161
- listEl.dataset.lastTurn = "-1";
162
- nodeById.clear();
163
- headerByTurn.clear();
164
- if (selected && !trace.some((e) => e.id === selected)) selected = null;
165
- if (trace.length === 0) {
166
- listEl.appendChild(el("div", "trace-turn", t("web.sidebar.trace_empty")));
167
- return;
168
- }
169
- let shownTurn = -1;
170
- for (const entry of trace) {
171
- if (entry.turn !== shownTurn) {
172
- shownTurn = entry.turn;
173
- const h = el("div", "trace-turn", t("web.sidebar.trace_turn", { n: entry.turn }));
174
- headerByTurn.set(entry.turn, h);
175
- listEl.appendChild(h);
176
- }
177
- const row = renderRow(entry);
178
- nodeById.set(entry.id, row);
179
- listEl.appendChild(row);
180
- }
181
- listEl.dataset.lastTurn = String(shownTurn);
182
- listEl.scrollTop = listEl.scrollHeight;
183
- }
184
-
185
- function append(entry) {
186
- entry.id = ++seq;
187
- entry.turn = turn;
188
- entry.ts = Date.now();
189
- trace.push(entry);
190
- while (trace.length > TRACE_CAP) {
191
- const old = trace.shift();
192
- const node = nodeById.get(old.id);
193
- if (node) { node.remove(); nodeById.delete(old.id); }
194
- if (old.toolCallId != null) callIndex.delete(old.toolCallId);
195
- if (!trace.some((e) => e.turn === old.turn)) {
196
- const h = headerByTurn.get(old.turn);
197
- if (h) { h.remove(); headerByTurn.delete(old.turn); }
198
- }
199
- }
200
- return entry;
201
- }
202
-
203
- function pushRow(entry) {
204
- if (!listEl) return;
205
- const last = listEl.dataset.lastTurn ? Number(listEl.dataset.lastTurn) : -1;
206
- if (entry.turn !== last) {
207
- const h = el("div", "trace-turn", t("web.sidebar.trace_turn", { n: entry.turn }));
208
- headerByTurn.set(entry.turn, h);
209
- listEl.appendChild(h);
210
- listEl.dataset.lastTurn = String(entry.turn);
211
- }
212
- const row = renderRow(entry);
213
- nodeById.set(entry.id, row);
214
- listEl.appendChild(row);
215
- listEl.scrollTop = listEl.scrollHeight;
216
- }
217
-
218
- function replaceRow(entry) {
219
- const old = nodeById.get(entry.id);
220
- const next = renderRow(entry);
221
- nodeById.set(entry.id, next);
222
- if (old && old.parentNode) old.replaceWith(next);
223
- else if (listEl) listEl.appendChild(next);
224
- if (listEl) listEl.scrollTop = listEl.scrollHeight;
225
- }
226
-
227
- function updateTextRow(entry) {
228
- const row = nodeById.get(entry.id);
229
- if (!row) return;
230
- row.textContent = "";
231
- row.appendChild(el("span", "g", "✦"));
232
- row.appendChild(el("span", "lab", rowLabel(entry)));
233
- if (listEl) listEl.scrollTop = listEl.scrollHeight;
234
- }
235
-
236
- // ---- public API ----
237
-
238
- export function sidebarSessionChanged(sid) {
239
- const prev = sbEl && sbEl.dataset.sid;
240
- if (prev === (sid || "")) return;
241
- if (sbEl) sbEl.dataset.sid = sid || "";
242
- trace = [];
243
- callIndex.clear();
244
- textEntry = null;
245
- turn = 0;
246
- seq = 0;
247
- // Trace живой: старые ходы чужой сессии не докачиваем, только новые события.
248
- logCursor = new Date().toISOString();
249
- logPulling = false;
250
- collapseDetail();
251
- renderList();
252
- }
253
-
254
- export function sidebarTurnEnd(turnSeq) {
255
- // Серверный номер хода (реконнекты локальный счётчик не сбивают).
256
- turn = typeof turnSeq === "number" && turnSeq > turn ? turnSeq : turn + 1;
257
- textEntry = null;
258
- }
259
-
260
- export function sidebarTraceEvent(kind, data) {
261
- if (!data) return;
262
- switch (kind) {
263
- case "tool_start": {
264
- const entry = append({ kind: "tool", name: data.name, args: data.args || {}, toolCallId: data.toolCallId });
265
- if (data.toolCallId != null) callIndex.set(data.toolCallId, entry);
266
- pushRow(entry);
267
- break;
268
- }
269
- case "tool_end": {
270
- const entry = data.toolCallId != null ? callIndex.get(data.toolCallId) : undefined;
271
- if (data.toolCallId != null) callIndex.delete(data.toolCallId);
272
- if (entry) {
273
- entry.kind = data.success === false ? "tool_fail" : "tool";
274
- entry.success = data.success !== false;
275
- entry.durationMs = data.durationMs;
276
- entry.output = data.output || "";
277
- replaceRow(entry);
278
- } else {
279
- const e2 = append({
280
- kind: data.success === false ? "tool_fail" : "tool",
281
- name: data.name, args: data.args || {}, toolCallId: data.toolCallId,
282
- success: data.success !== false, durationMs: data.durationMs, output: data.output || "",
283
- });
284
- pushRow(e2);
285
- }
286
- break;
287
- }
288
- case "phase":
289
- if (data.phase !== "done") pushRow(append({ kind: "phase", phase: data.phase }));
290
- break;
291
- case "plan":
292
- pushRow(append({
293
- kind: "plan",
294
- steps: Array.isArray(data.steps) ? data.steps : [],
295
- currentIndex: typeof data.currentIndex === "number" ? data.currentIndex : 0,
296
- }));
297
- break;
298
- case "question":
299
- pushRow(append({ kind: "question", text: data.question || data.text || "" }));
300
- break;
301
- case "text": {
302
- if (!textEntry) { textEntry = append({ kind: "text", text: "", chars: 0 }); pushRow(textEntry); }
303
- const chunk = data.chunk || "";
304
- textEntry.chars += chunk.length;
305
- textEntry.text += chunk;
306
- // Полный текст хода — в память (деталь покажет целиком); обрезка честная,
307
- // тем же капом и маркером, что у выводов тулов.
308
- if (textEntry.text.length > MAX_OUTPUT_CHARS) {
309
- textEntry.text = textEntry.text.slice(0, MAX_OUTPUT_CHARS) +
310
- "\n… [truncated from " + textEntry.chars + " chars]";
311
- }
312
- updateTextRow(textEntry);
313
- break;
314
- }
315
- case "error":
316
- pushRow(append({ kind: "error", message: data.message || data.error || "" }));
317
- break;
318
- case "meta": {
319
- // Тела тулов (`kind: "tool"`) уже идут строками tool_start/tool_end —
320
- // в Trace несём только статусы (stuck/escalation/honest-stop и т.п.).
321
- if (data.kind !== undefined && data.kind !== "status") break;
322
- const text = data.chunk || "";
323
- if (!text.trim()) break;
324
- pushRow(append({ kind: "status", text }));
325
- break;
326
- }
327
- case "log": {
328
- // Внутренний шёпот петли (`diagnostic` + info) в Trace не несём —
329
- // только варнинги/ошибки и пользовательские info (probe/overflow).
330
- if (data.diagnostic && data.level === "info") break;
331
- const text = data.text || "";
332
- if (!text.trim()) break;
333
- pushRow(append({ kind: "log", text, level: data.level || "", source: data.source || "" }));
334
- break;
335
- }
336
- case "retract":
337
- pushRow(append({ kind: "retract", text: data.reason || "" }));
338
- break;
339
- case "index": {
340
- const stats = data.stats && typeof data.stats === "object"
341
- ? Object.entries(data.stats).map(([k, v]) => k + ": " + v).join(", ")
342
- : "";
343
- pushRow(append({ kind: "index", phase: data.phase || "", text: stats }));
344
- break;
345
- }
346
- default:
347
- break;
348
- }
349
- }
350
-
351
- /**
352
- * Докачка диагностических событий из session-лога (критик, MoE, компакция,
353
- * проба контекста, usage, аудит, claim-retry, вывод). Отдельных SSE-продюсеров
354
- * нет — данные уже лежат в логе с `iteration`; тянем инкремент по курсору на
355
- * каждый `turn_end`. Живые tool/text-строки не дублируются (другие kinds).
356
- */
357
- export async function sidebarPullLog() {
358
- const sid = sbEl && sbEl.dataset.sid;
359
- if (!sid || logPulling) return;
360
- logPulling = true;
361
- try {
362
- let url = "/api/sessions/" + encodeURIComponent(sid) + "/log?limit=100";
363
- if (logCursor) url += "&since=" + encodeURIComponent(logCursor);
364
- const r = await api(url);
365
- if (!r.ok || !r.data || !Array.isArray(r.data.log)) return;
366
- for (const e of r.data.log) {
367
- if (typeof e.ts === "string" && (logCursor === null || e.ts > logCursor)) logCursor = e.ts;
368
- appendLogEntry(e);
369
- }
370
- } catch {
371
- /* best-effort supplement: Trace живёт и без докачки */
372
- } finally {
373
- logPulling = false;
374
- }
375
- }
376
-
377
- function appendLogEntry(e) {
378
- if (!e || typeof e.type !== "string") return;
379
- switch (e.type) {
380
- case "critic_check":
381
- pushRow(append({ kind: "critic", status: "check", text: "", iteration: e.iteration }));
382
- break;
383
- case "critic_verdict":
384
- pushRow(append({ kind: "critic", status: e.status || "", text: e.content || "", iteration: e.iteration }));
385
- break;
386
- case "critic_escalation":
387
- pushRow(append({ kind: "critic", status: "escalation", text: e.content || "", iteration: e.iteration }));
388
- break;
389
- case "moe_plan":
390
- case "moe_subtask":
391
- case "moe_replan":
392
- case "moe_verify": {
393
- const bits = [e.title, e.subtaskId, e.expertTag, e.status].filter((x) => typeof x === "string" && x).join(" · ");
394
- pushRow(append({ kind: "moe", subtype: e.type, text: bits, iteration: e.iteration }));
395
- break;
396
- }
397
- case "compaction":
398
- pushRow(append({ kind: "compaction", text: e.content || "", iteration: e.iteration }));
399
- break;
400
- case "context_probe":
401
- pushRow(append({ kind: "probe", text: e.content || "" }));
402
- break;
403
- case "llm_usage": {
404
- const toks = typeof e.totalTokens === "number" ? e.totalTokens : (e.promptTokens || 0) + (e.completionTokens || 0);
405
- const who = [e.model || e.provider, toks ? toks + " tok" : ""].filter(Boolean).join(" · ");
406
- pushRow(append({ kind: "usage", text: who, iteration: e.iteration }));
407
- break;
408
- }
409
- case "audit":
410
- pushRow(append({ kind: "audit", text: e.content || "", iteration: e.iteration }));
411
- break;
412
- case "claim_retry":
413
- pushRow(append({ kind: "claim", subkind: e.kind || "", text: e.content || "", iteration: e.iteration }));
414
- break;
415
- case "output":
416
- pushRow(append({ kind: "output", text: e.content || "", iteration: e.iteration }));
417
- break;
418
- default:
419
- break;
420
- }
421
- }
422
-
423
- function detailGroup(title, bodyNode) {
424
- const g = el("div");
425
- g.appendChild(el("h5", "", title));
426
- g.appendChild(bodyNode);
427
- return g;
428
- }
429
- function kv(label, value) {
430
- const row = el("div", "kv");
431
- row.appendChild(el("span", "dim", label));
432
- const b = el("b");
433
- b.textContent = value;
434
- row.appendChild(b);
435
- return row;
436
- }
437
- function codeBlock(text) {
438
- const c = el("div", "code");
439
- c.textContent = text;
440
- return c;
441
- }
442
- function capOutput(text) {
443
- if (typeof text !== "string") return "";
444
- return text.length <= MAX_OUTPUT_CHARS ? text : text.slice(0, MAX_OUTPUT_CHARS) + "\n… [truncated from " + text.length + " chars]";
445
- }
446
-
447
- function renderDetail(entry) {
448
- if (!detailEl) return;
449
- detailEl.hidden = false;
450
- const warn = isWarn(entry);
451
- detailGlyph.textContent = warn ? "⚠" : entry.kind === "question" ? "?" : "◇";
452
- detailGlyph.style.color = warn ? "var(--yellow)" : "var(--accent)";
453
- detailTitle.textContent = rowLabel(entry);
454
- detailBody.textContent = "";
455
-
456
- const meta = el("div");
457
- meta.appendChild(el("h5", "", t("web.sidebar.detail_metadata")));
458
- const d = entry.ts ? new Date(entry.ts) : null;
459
- if (entry.kind === "tool" || entry.kind === "tool_fail") {
460
- meta.appendChild(kv(t("web.sidebar.detail_status"), entry.success === false ? t("web.sidebar.detail_fail") : t("web.sidebar.detail_ok")));
461
- if (entry.durationMs) meta.appendChild(kv(t("web.sidebar.detail_duration"), formatMs(entry.durationMs)));
462
- }
463
- if (d) meta.appendChild(kv(t("web.sidebar.detail_time"), d.toLocaleTimeString()));
464
- if (entry.toolCallId) meta.appendChild(kv(t("web.sidebar.detail_tool_call"), String(entry.toolCallId)));
465
- if (sbEl && sbEl.dataset.sid) meta.appendChild(kv(t("web.sidebar.detail_session"), sbEl.dataset.sid));
466
- meta.appendChild(kv(t("web.sidebar.detail_turn"), String(entry.turn)));
467
- if (typeof entry.iteration === "number") meta.appendChild(kv(t("web.sidebar.detail_iteration"), String(entry.iteration)));
468
- detailBody.appendChild(meta);
469
-
470
- if (entry.kind === "tool" || entry.kind === "tool_fail") {
471
- detailBody.appendChild(detailGroup(t("web.sidebar.detail_arguments"), codeBlock(JSON.stringify(entry.args || {}, null, 2))));
472
- detailBody.appendChild(detailGroup(t("web.sidebar.detail_output"), codeBlock(capOutput(entry.output))));
473
- } else if (entry.kind === "text") {
474
- detailBody.appendChild(detailGroup(t("web.sidebar.detail_text"), codeBlock(entry.text || "")));
475
- loadTextProvenance(entry);
476
- } else if (entry.kind === "plan") {
477
- const list = el("div");
478
- (entry.steps || []).forEach((s) => {
479
- const mark = s.status === "done" ? "✓" : s.status === "failed" ? "✗" : s.status === "in_progress" ? "▸" : "○";
480
- const cls = s.status === "failed" ? "fail" : s.status === "in_progress" ? "cur" : s.status === "done" ? "done" : "";
481
- list.appendChild(el("div", ("plan-step " + cls).trim(), mark + " " + s.text));
482
- });
483
- detailBody.appendChild(detailGroup(t("web.sidebar.detail_plan"), list));
484
- } else if (entry.kind === "question") {
485
- detailBody.appendChild(detailGroup(t("web.sidebar.trace_question"), codeBlock(entry.text || "")));
486
- } else if (entry.kind === "error") {
487
- detailBody.appendChild(detailGroup(t("web.sidebar.detail_error"), codeBlock(entry.message || "")));
488
- } else if (
489
- entry.kind === "status" || entry.kind === "log" || entry.kind === "retract" ||
490
- entry.kind === "index" || entry.kind === "critic" || entry.kind === "moe" ||
491
- entry.kind === "compaction" || entry.kind === "probe" || entry.kind === "usage" ||
492
- entry.kind === "audit" || entry.kind === "claim" || entry.kind === "output"
493
- ) {
494
- const title =
495
- entry.kind === "moe" && entry.subtype ? entry.subtype
496
- : entry.kind === "log" && entry.level ? "log · " + entry.level
497
- : entry.kind === "index" && entry.phase ? "index · " + entry.phase
498
- : entry.kind === "critic" && entry.status ? "critic · " + entry.status
499
- : entry.kind === "claim" && entry.subkind ? "claim_retry · " + entry.subkind
500
- : rowLabel(entry);
501
- detailBody.appendChild(detailGroup(title, codeBlock(entry.text || "")));
502
- }
503
- }
504
-
505
- /**
506
- * Привязка текста хода к session-логу: сколько assistant-сообщений в сессии,
507
- * их итерации и провенанс последнего LLM-вызова (модель/провайдер/токены).
508
- * Живой текст хода уже показан выше целиком; это — сверка с логом.
509
- */
510
- async function loadTextProvenance(entry) {
511
- const sid = sbEl && sbEl.dataset.sid;
512
- if (!sid || !detailBody || selected !== entry.id) return;
513
- try {
514
- const r = await api(
515
- "/api/sessions/" + encodeURIComponent(sid) + "/log?types=assistant,llm_usage&limit=20",
516
- );
517
- if (!r.ok || !r.data || !Array.isArray(r.data.log) || selected !== entry.id) return;
518
- const assistants = r.data.log.filter((e) => e.type === "assistant");
519
- const usages = r.data.log.filter((e) => e.type === "llm_usage");
520
- const iters = assistants.map((e) => e.iteration).filter((n) => typeof n === "number");
521
- const last = usages.length > 0 ? usages[usages.length - 1] : null;
522
- const bits = [
523
- t("web.sidebar.detail_provenance_count", { n: assistants.length }) +
524
- (iters.length > 0 ? " · iter " + Math.min(...iters) + "–" + Math.max(...iters) : ""),
525
- last
526
- ? [last.model || last.provider, last.totalTokens ?? (last.promptTokens || 0) + (last.completionTokens || 0)]
527
- .filter(Boolean)
528
- .join(" · ")
529
- : "",
530
- ].filter(Boolean).join("\n");
531
- if (bits) detailBody.appendChild(detailGroup(t("web.sidebar.detail_provenance"), codeBlock(bits)));
532
- } catch {
533
- /* best-effort: живой текст уже на месте */
534
- }
535
- }
536
-
537
- // ---- Map tab ----
538
-
539
- function fmtUpdated(updatedAt) {
540
- if (typeof updatedAt !== "number") return t("web.sidebar.map_never");
541
- const d = new Date(updatedAt);
542
- const now = new Date();
543
- const pad = (n) => String(n).padStart(2, "0");
544
- const time = pad(d.getHours()) + ":" + pad(d.getMinutes());
545
- if (d.toDateString() === now.toDateString()) return t("web.sidebar.map_today", { time });
546
- return pad(d.getDate()) + "." + pad(d.getMonth() + 1) + " " + time;
547
- }
548
-
549
- function mapKv(label, value, cls) {
550
- const row = el("div", ("kv" + (cls ? " " + cls : "")).trim());
551
- row.appendChild(el("span", "dim", label));
552
- const b = el("b");
553
- b.textContent = value;
554
- row.appendChild(b);
555
- return row;
556
- }
557
-
558
- // Корень — всегда длинный путь: подпись сверху, путь снизу на всю ширину.
559
- // В одну flex-строку с подписью он не влезает и склеивается с ней.
560
- function mapPathRow(label, value) {
561
- const wrap = el("div", "map-path");
562
- wrap.appendChild(el("span", "dim", label));
563
- const b = el("b");
564
- b.textContent = value;
565
- b.title = value;
566
- wrap.appendChild(b);
567
- return wrap;
568
- }
569
-
570
- let reindexing = false; // клиентский спиннер до свежего снапшота
571
- let postResolved = false; // POST вернулся; следующий снапшот снимет спиннер
572
- let reindexError = false; // последний POST не удался
573
-
574
- export function sidebarMapState(host) {
575
- if (!mapEl) return;
576
- const map = (host && host.projectMap) || { indexed: false, files: 0, symbols: 0, tokens: 0, languages: [] };
577
- const serverIndexing = !!(map && map.indexing);
578
- if (postResolved && !serverIndexing) { reindexing = false; postResolved = false; }
579
- const indexing = serverIndexing || reindexing;
580
- const num = (v) => (map.indexed ? String(v || 0) : "—");
581
- mapEl.textContent = "";
582
- const status = indexing ? t("web.sidebar.map_indexing")
583
- : !map.indexed ? t("web.sidebar.map_never")
584
- : (map.watcher ? t("web.sidebar.map_ready") : t("web.sidebar.map_stale"));
585
- mapEl.appendChild(mapKv(t("web.sidebar.map_status"), status));
586
- mapEl.appendChild(mapKv(t("web.sidebar.map_updated"), fmtUpdated(map.updatedAt)));
587
- mapEl.appendChild(mapKv(t("web.sidebar.map_watcher"), map.watcher ? t("web.sidebar.map_on") : t("web.sidebar.map_off")));
588
- mapEl.appendChild(mapKv(t("web.sidebar.map_files"), num(map.files)));
589
- mapEl.appendChild(mapKv(t("web.sidebar.map_symbols"), num(map.symbols)));
590
- mapEl.appendChild(mapKv(t("web.sidebar.map_tokens"), map.indexed ? fmtTokens(map.tokens || 0) : "—"));
591
- if (host && host.workspace) mapEl.appendChild(mapPathRow(t("web.sidebar.map_root"), host.workspace));
592
-
593
- if (Array.isArray(map.languages) && map.languages.length > 0) {
594
- const head = el("div", "kv");
595
- head.appendChild(el("span", "dim", t("web.sidebar.map_languages")));
596
- mapEl.appendChild(head);
597
- map.languages.forEach((l) => mapEl.appendChild(mapKv(l.language, l.files + " · " + l.symbols)));
598
- }
599
- if (reindexError) mapEl.appendChild(mapKv(t("web.sidebar.map_reindex_failed"), "—", "wn"));
600
-
601
- const btn = el("button", "map-reindex", indexing ? t("web.sidebar.map_reindexing") : t("web.sidebar.map_reindex"));
602
- btn.type = "button";
603
- btn.disabled = indexing || !map.indexed;
604
- btn.addEventListener("click", async () => {
605
- reindexing = true;
606
- postResolved = false;
607
- reindexError = false;
608
- sidebarMapState(host);
609
- sidebarMapIndicator(host);
610
- const r = await api("/api/index", { method: "POST" });
611
- if (!r.ok) {
612
- reindexing = false;
613
- postResolved = false;
614
- reindexError = true;
615
- sidebarMapState(host);
616
- return;
617
- }
618
- // Свежий снапшот (поллинг / `state`-broadcast по завершении) снимет спиннер.
619
- postResolved = true;
620
- });
621
- mapEl.appendChild(btn);
622
- }
623
-
624
- // ---- indicators ----
625
-
626
- export function sidebarBusy(on) {
627
- const tab = sbEl && sbEl.querySelector('.sb-tab[data-tab="trace"]');
628
- if (tab) tab.dataset.indicator = on ? "live" : "";
629
- }
630
- export function sidebarMapIndicator(host) {
631
- const tab = sbEl && sbEl.querySelector('.sb-tab[data-tab="map"]');
632
- if (!tab) return;
633
- const map = (host && host.projectMap) || null;
634
- const busy = (map && map.indexing) || reindexing;
635
- const next = busy ? "busy" : map && map.indexed && !map.watcher ? "stale" : "";
636
- tab.dataset.indicator = next;
637
- }
638
-
639
- // ---- init / i18n ----
640
-
641
- export function applySidebarI18n() {
642
- if (!sbEl) return;
643
- TABS.forEach((id) => {
644
- const tab = sbEl.querySelector('.sb-tab[data-tab="' + id + '"]');
645
- if (tab) { const label = t("web.sidebar.tab_" + id); tab.title = label; tab.setAttribute("aria-label", label); }
646
- });
647
- setSidebarTab(active, false);
648
- renderList();
649
- if (selected) {
650
- const entry = trace.find((x) => x.id === selected);
651
- if (entry) renderDetail(entry);
652
- }
653
- sidebarMapState(S.state.host);
654
- }
655
-
656
- export function initSidebar() {
657
- if (sbEl) return;
658
- sbEl = document.querySelector(".sb");
659
- if (!sbEl) return;
660
- nameEl = document.getElementById("sbName");
661
- nameTextEl = document.getElementById("sbNameText");
662
- mapEl = document.getElementById("mapBody");
663
- listEl = document.getElementById("traceList");
664
- detailEl = document.getElementById("traceDetail");
665
- detailGlyph = document.getElementById("detailGlyph");
666
- detailTitle = document.getElementById("detailTitle");
667
- detailBody = document.getElementById("detailBody");
668
- detailClose = document.getElementById("detailClose");
669
- if (detailClose) detailClose.addEventListener("click", collapseDetail);
670
-
671
- sbEl.querySelectorAll(".sb-tab .sb-ico").forEach((span) => {
672
- const id = span.closest(".sb-tab").dataset.tab;
673
- span.textContent = "";
674
- span.appendChild(icon(ICON_NAME[id]));
675
- });
676
-
677
- sbEl.querySelectorAll(".sb-tab").forEach((tab) => {
678
- tab.addEventListener("click", () => setSidebarTab(tab.dataset.tab));
679
- tab.addEventListener("keydown", (e) => {
680
- if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
681
- e.preventDefault();
682
- const i = TABS.indexOf(tab.dataset.tab);
683
- const next = TABS[(i + (e.key === "ArrowRight" ? 1 : TABS.length - 1)) % TABS.length];
684
- setSidebarTab(next);
685
- const focus = sbEl.querySelector('.sb-tab[data-tab="' + next + '"]');
686
- if (focus) focus.focus();
687
- });
688
- });
689
-
690
- document.addEventListener("keydown", (e) => {
691
- if (!e.altKey || !["1", "2", "3"].includes(e.key)) return;
692
- const tag = document.activeElement ? String(document.activeElement.tagName) : "";
693
- if (tag === "INPUT" || tag === "TEXTAREA") return;
694
- e.preventDefault();
695
- setSidebarTab(TABS[Number(e.key) - 1]);
696
- });
697
-
698
- document.addEventListener("keydown", (e) => {
699
- if (e.key === "Escape" && selected) collapseDetail();
700
- });
701
-
702
- const stored = readStored();
703
- setSidebarTab(stored && TABS.includes(stored) ? stored : "session");
704
- renderList();
705
- }
1
+ export*from"./sidebar/core.js";export*from"./sidebar/trace.js";export*from"./sidebar/map.js";export*from"./sidebar/lsp.js";