@cartanova/qgrid-cli 2.10.10 → 2.11.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 (302) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
  2. package/bundle/dist/application/monit/log-buffer.js +12 -6
  3. package/bundle/dist/application/monit/monit.frame.js +11 -3
  4. package/bundle/dist/application/monit/monit.types.js +1 -1
  5. package/bundle/dist/application/qgrid/conv-routing.js +9 -6
  6. package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
  7. package/bundle/dist/application/qgrid/oauth.js +31 -4
  8. package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
  9. package/bundle/dist/application/qgrid/qgrid-response-format.js +21 -19
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +40 -33
  11. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
  12. package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
  13. package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
  14. package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
  15. package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
  16. package/bundle/dist/application/qgrid/token-death.js +1 -1
  17. package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
  18. package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
  19. package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
  20. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
  21. package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
  22. package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
  23. package/bundle/dist/application/request-log/request-log.model.js +83 -70
  24. package/bundle/dist/application/request-log/request-log.types.js +1 -1
  25. package/bundle/dist/application/request-log/zod-code-format.js +1 -1
  26. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  27. package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
  28. package/bundle/dist/application/setting/setting.constant.js +1 -1
  29. package/bundle/dist/application/setting/setting.model.js +2 -2
  30. package/bundle/dist/application/setting/setting.store.js +2 -2
  31. package/bundle/dist/application/setting/setting.types.js +1 -1
  32. package/bundle/dist/application/sonamu.generated.js +32 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +1 -1
  34. package/bundle/dist/application/token/token.model.js +26 -9
  35. package/bundle/dist/application/token/token.types.js +20 -3
  36. package/bundle/dist/i18n/en.js +15 -1
  37. package/bundle/dist/i18n/ko.js +15 -1
  38. package/bundle/dist/i18n/sd.generated.js +1 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/server-bootstrap.js +4 -2
  41. package/bundle/dist/server-error-handler.js +1 -1
  42. package/bundle/dist/sonamu.config.js +37 -8
  43. package/bundle/dist/startup-migrations.js +17 -7
  44. package/bundle/dist/testing/global.js +1 -1
  45. package/bundle/dist/testing/schema-bench.js +0 -0
  46. package/bundle/dist/testing/test-database-name.js +1 -1
  47. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  49. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  50. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  51. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  52. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  53. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  54. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  55. package/bundle/dist/utils/providers/common/effort.js +3 -3
  56. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  57. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  58. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  59. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  60. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  61. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  62. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  63. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  64. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  65. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  66. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  67. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  68. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  69. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  70. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  71. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  72. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  73. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  74. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  75. package/bundle/dist/utils/providers/grok/index.js +11 -0
  76. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  77. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  78. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  79. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  80. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  81. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  82. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  83. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  84. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  85. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  86. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  87. package/bundle/dist/utils/quiet-hours.js +1 -1
  88. package/bundle/dist/utils/slack-notify.js +14 -8
  89. package/bundle/dist/utils/subset-loaders.js +4 -5
  90. package/bundle/src/application/monit/log-buffer.ts +23 -9
  91. package/bundle/src/application/monit/monit.frame.ts +22 -5
  92. package/bundle/src/application/monit/monit.types.ts +6 -0
  93. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  94. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  95. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  96. package/bundle/src/application/qgrid/oauth.ts +51 -15
  97. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  98. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  99. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +19 -0
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +84 -40
  101. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  103. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  104. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  105. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  106. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  107. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  108. package/bundle/src/application/qgrid/token-death.ts +4 -0
  109. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  110. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  111. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  112. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  113. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  114. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  115. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  116. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  117. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  118. package/bundle/src/application/request-log/request-log.model.ts +277 -146
  119. package/bundle/src/application/request-log/request-log.types.ts +6 -0
  120. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  121. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  122. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  123. package/bundle/src/application/setting/setting.constant.ts +9 -0
  124. package/bundle/src/application/setting/setting.model.ts +12 -2
  125. package/bundle/src/application/setting/setting.store.ts +5 -1
  126. package/bundle/src/application/setting/setting.types.ts +8 -0
  127. package/bundle/src/application/sonamu.generated.http +133 -0
  128. package/bundle/src/application/sonamu.generated.sso.ts +2 -0
  129. package/bundle/src/application/sonamu.generated.ts +15 -0
  130. package/bundle/src/application/token/token.identity.test.ts +20 -0
  131. package/bundle/src/application/token/token.model.ts +66 -7
  132. package/bundle/src/application/token/token.types.ts +24 -1
  133. package/bundle/src/i18n/en.ts +19 -0
  134. package/bundle/src/i18n/ko.ts +21 -0
  135. package/bundle/src/i18n/sd.generated.ts +23 -2
  136. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  137. package/bundle/src/server-bootstrap.ts +4 -2
  138. package/bundle/src/server-error-handler.ts +1 -0
  139. package/bundle/src/sonamu.config.ts +69 -7
  140. package/bundle/src/startup-migrations.ts +27 -9
  141. package/bundle/src/testing/global.ts +20 -0
  142. package/bundle/src/testing/schema-bench.ts +105 -30
  143. package/bundle/src/testing/test-database-name.ts +2 -0
  144. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  145. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  146. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  147. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  148. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  149. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  150. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  151. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  152. package/bundle/src/utils/providers/common/effort.ts +9 -2
  153. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  154. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  155. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  156. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  157. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  158. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  159. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  160. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  161. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  162. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  163. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  164. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  165. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  166. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  167. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  168. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  169. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  170. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  171. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  172. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  173. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  174. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  175. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  176. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  177. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  178. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  179. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  180. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  181. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  182. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  183. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  184. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  185. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  186. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  187. package/bundle/src/utils/providers/grok/index.ts +20 -0
  188. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  189. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  190. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  191. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  192. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  193. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  194. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  195. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  196. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  197. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  198. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  199. package/bundle/src/utils/quiet-hours.ts +12 -1
  200. package/bundle/src/utils/slack-notify.ts +44 -13
  201. package/bundle/src/utils/subset-loaders.ts +7 -7
  202. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  203. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  204. package/bundle/web-dist/client/assets/index-C96h3feE.js +32 -0
  205. package/bundle/web-dist/client/assets/logs-DBM6U0QD.js +1 -0
  206. package/bundle/web-dist/client/assets/monit-BBjXa7vB.js +1 -0
  207. package/bundle/web-dist/client/assets/routes-Crz_PQzi.js +5 -0
  208. package/bundle/web-dist/client/assets/{services.generated-NP-ValHd.js → services.generated-B5lc3aIC.js} +5 -5
  209. package/bundle/web-dist/client/assets/settings-Cdwm3OBB.js +1 -0
  210. package/bundle/web-dist/client/assets/show-DBUhALT1.js +2 -0
  211. package/bundle/web-dist/client/assets/tokens-CVQAVJTo.js +1 -0
  212. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  213. package/bundle/web-dist/client/assets/use-oauth-login-flow-BfxYI4Oh.js +1 -0
  214. package/bundle/web-dist/client/assets/use-update-token-mutation-qKBC2sn7.js +1 -0
  215. package/bundle/web-dist/client/assets/{vendor-tanstack-DJRQAbrY.js → vendor-tanstack-DRPs09ai.js} +1 -1
  216. package/bundle/web-dist/client/index.html +5 -5
  217. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  218. package/bundle/web-dist/server/assets/{lazyRouteComponent-CgBdabgd.js → lazyRouteComponent-AKiHfZWp.js} +129 -2
  219. package/bundle/web-dist/server/assets/{logs-BMyR98rU.js → logs-B7QmGJq3.js} +18 -14
  220. package/bundle/web-dist/server/assets/{monit-ZPt66W5M.js → monit-DFt7x3bh.js} +13 -12
  221. package/bundle/web-dist/server/assets/{plus-BZ9I0VgC.js → plus-DaYQRpBt.js} +1 -1
  222. package/bundle/web-dist/server/assets/{react-dom-Ds75e4Jl.js → react-dom-Cv23mm1K.js} +2 -129
  223. package/bundle/web-dist/server/assets/{refresh-cw-CztCFis-.js → refresh-cw-BpXNsAy-.js} +1 -1
  224. package/bundle/web-dist/server/assets/{request-model-DjGldb-h.js → request-model-eHE6YbaF.js} +1 -1
  225. package/bundle/web-dist/server/assets/{routes-Ct-k7nBA.js → routes-_Y-PJfgO.js} +110 -39
  226. package/bundle/web-dist/server/assets/{services.generated-BA4AcAf5.js → services.generated-CMJ8AHbO.js} +582 -172
  227. package/bundle/web-dist/server/assets/{settings-CBUZ47Xx.js → settings-JwJKxn2e.js} +14 -14
  228. package/bundle/web-dist/server/assets/{show-LSFIzvO2.js → show-BEv6z1v_.js} +90 -60
  229. package/bundle/web-dist/server/assets/{tokens-DxrBW512.js → tokens-CNT4mI-f.js} +162 -50
  230. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  231. package/bundle/web-dist/server/assets/use-oauth-login-flow-jkAkT3X6.js +2345 -0
  232. package/bundle/web-dist/server/assets/{use-update-token-mutation-pkArIzCP.js → use-update-token-mutation-Sm6kh02m.js} +1 -1
  233. package/bundle/web-dist/server/entry-server.generated.js +1644 -21655
  234. package/dist/cli.js +9 -9
  235. package/package.json +4 -11
  236. package/postinstall.mjs +12 -0
  237. package/skills/qgrid/SKILL.md +1 -0
  238. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  239. package/skills/qgrid/references/decision-rationale.md +23 -0
  240. package/skills/qgrid/references/grok-runtime.md +89 -0
  241. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  242. package/skills/qgrid/references/repo-map.md +10 -0
  243. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  244. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  245. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  246. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  247. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  248. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  249. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  250. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  251. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  252. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  253. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  254. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  255. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  256. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  257. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  258. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  259. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  260. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  262. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  263. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  264. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  265. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  266. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  267. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  268. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  269. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  270. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  271. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  272. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  273. package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_5b35fc1fb85d2af4d105e0d74f940f50/node_modules/vite/dist/node/module-runner.js +0 -1265
  274. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
  275. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  276. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  277. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  278. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
  279. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
  280. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
  281. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
  282. package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/index.js +0 -28
  283. package/bundle/dist/testing/setup-mocks.js +0 -16
  284. package/bundle/src/testing/setup-mocks.ts +0 -44
  285. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  286. package/bundle/web-dist/client/assets/index-DZwzUfI-.js +0 -106
  287. package/bundle/web-dist/client/assets/logs-Cog79DU5.js +0 -1
  288. package/bundle/web-dist/client/assets/monit-2auznBys.js +0 -1
  289. package/bundle/web-dist/client/assets/routes-B0lTeLK-.js +0 -5
  290. package/bundle/web-dist/client/assets/settings-D8ZxZGSJ.js +0 -1
  291. package/bundle/web-dist/client/assets/show-CFSERlnM.js +0 -2
  292. package/bundle/web-dist/client/assets/tokens-CZXUyI7O.js +0 -1
  293. package/bundle/web-dist/client/assets/use-oauth-login-flow-hboOs3wG.js +0 -1
  294. package/bundle/web-dist/client/assets/use-update-token-mutation-BQHS0byG.js +0 -1
  295. package/bundle/web-dist/server/assets/use-oauth-login-flow-Gn8flMK5.js +0 -178
  296. package/dist/cli.d.ts +0 -10
  297. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  298. /package/bundle/web-dist/client/assets/{plus-B62CuqT8.js → plus-BsQdY7PS.js} +0 -0
  299. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  300. /package/bundle/web-dist/client/assets/{refresh-cw-NNcU0Cmq.js → refresh-cw-D9IUmT23.js} +0 -0
  301. /package/bundle/web-dist/client/assets/{request-model-CojtinqK.js → request-model-Bpp_rkK8.js} +0 -0
  302. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -1,7 +1,7 @@
1
- import { A as require_react, O as useQueryClient, X as __toESM, a as SettingService, k as require_jsx_runtime, o as TokenService } from "./services.generated-BA4AcAf5.js";
2
- import { l as lucideRotateCcw } from "../entry-server.generated.js";
3
- import { t as useUpdateTokenMutation } from "./use-update-token-mutation-pkArIzCP.js";
4
- import { t as lucidePlus } from "./plus-BZ9I0VgC.js";
1
+ import { $ as __toESM, M as require_jsx_runtime, N as require_react, a as SettingService, j as useQueryClient, o as TokenService } from "./services.generated-CMJ8AHbO.js";
2
+ import { s as lucideRotateCcw } from "../entry-server.generated.js";
3
+ import { t as useUpdateTokenMutation } from "./use-update-token-mutation-Sm6kh02m.js";
4
+ import { t as lucidePlus } from "./plus-DaYQRpBt.js";
5
5
  //#region ~icons/lucide/eye.jsx
6
6
  var import_react = /* @__PURE__ */ __toESM(require_react());
7
7
  var import_jsx_runtime = require_jsx_runtime();
@@ -57,11 +57,11 @@ var lucideMinus = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg",
57
57
  });
58
58
  //#endregion
59
59
  //#region src/components/qgrid/SettingsPanel.tsx
60
- var GROUP_LABELS = {
61
- qgrid: "Qgrid",
62
- slack: "Slack 알림",
63
- slackConnection: "Slack 연결"
64
- };
60
+ var GROUP_LABELS = new Map([
61
+ ["qgrid", "Qgrid"],
62
+ ["slack", "Slack 알림"],
63
+ ["slackConnection", "Slack 연결"]
64
+ ]);
65
65
  function maskValue(value) {
66
66
  if (!value) return "";
67
67
  if (value.length <= 12) return "•".repeat(value.length);
@@ -160,7 +160,7 @@ function SettingRow({ item, disabled = false }) {
160
160
  await invalidate();
161
161
  setDraft(null);
162
162
  } catch (e) {
163
- setError(e.message);
163
+ setError(e instanceof Error ? e.message : String(e));
164
164
  }
165
165
  };
166
166
  const reset = async () => {
@@ -170,7 +170,7 @@ function SettingRow({ item, disabled = false }) {
170
170
  await invalidate();
171
171
  setDraft(null);
172
172
  } catch (e) {
173
- setError(e.message);
173
+ setError(e instanceof Error ? e.message : String(e));
174
174
  }
175
175
  };
176
176
  const isSecret = item.kind === "secret";
@@ -277,7 +277,7 @@ function KeepaliveTokenSettings({ runnerEnabled }) {
277
277
  });
278
278
  await queryClient.invalidateQueries({ queryKey: ["Token", "getTokens"] });
279
279
  } catch (cause) {
280
- setError(cause.message);
280
+ setError(cause instanceof Error ? cause.message : String(cause));
281
281
  }
282
282
  };
283
283
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -339,7 +339,7 @@ function TriggerReminderButton() {
339
339
  const { sent } = await mutation.mutateAsync();
340
340
  setResult(sent === 0 ? "재로그인이 필요한 토큰이 없습니다" : `${sent}건 발송`);
341
341
  } catch (e) {
342
- setResult(e.message);
342
+ setResult(e instanceof Error ? e.message : String(e));
343
343
  }
344
344
  };
345
345
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -436,7 +436,7 @@ function SettingsPanel() {
436
436
  className: "panel-header flex items-center justify-between px-4 py-2.5 sm:px-5",
437
437
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
438
438
  className: "text-[13px] font-medium text-sand-700",
439
- children: GROUP_LABELS[group] ?? group
439
+ children: GROUP_LABELS.get(group) ?? group
440
440
  }), group === "slack" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriggerReminderButton, {})]
441
441
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
442
442
  className: "divide-y divide-sand-100/80",
@@ -1,8 +1,8 @@
1
- import { A as require_react, E as useQuery, X as __toESM, i as RequestLogStepService, k as require_jsx_runtime, l as isSonamuError, q as __commonJSMin, r as RequestLogService } from "./services.generated-BA4AcAf5.js";
2
- import { a as Link } from "./lazyRouteComponent-CgBdabgd.js";
3
- import { c as lucideX, d as Markdown, t as Route, u as remarkGfm } from "../entry-server.generated.js";
4
- import { n as formatMicroUsd, t as cacheHitRate } from "./cost-eEHeTRT5.js";
5
- import { n as lucideZap, t as requestModelDisplay } from "./request-model-DjGldb-h.js";
1
+ import { $ as __toESM, C as number, E as union, M as require_jsx_runtime, N as require_react, S as looseObject, T as string, X as __commonJSMin, b as json, h as array, i as RequestLogStepService, k as useQuery, l as isSonamuError, r as RequestLogService, w as object } from "./services.generated-CMJ8AHbO.js";
2
+ import { a as Link } from "./lazyRouteComponent-AKiHfZWp.js";
3
+ import { c as remarkGfm, l as Markdown, o as lucideX, t as Route } from "../entry-server.generated.js";
4
+ import { n as formatMicroUsd, t as cacheHitRate } from "./cost-BC9yzyA9.js";
5
+ import { n as lucideZap, t as requestModelDisplay } from "./request-model-eHE6YbaF.js";
6
6
  //#region ../../node_modules/.pnpm/@babel+runtime@7.29.2/node_modules/@babel/runtime/helpers/extends.js
7
7
  var require_extends = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8
8
  function _extends() {
@@ -1914,11 +1914,12 @@ function formatNum(n) {
1914
1914
  return n.toLocaleString();
1915
1915
  }
1916
1916
  var TOKENS_PER_SEC_PROVIDERS = /* @__PURE__ */ new Set();
1917
+ var JsonValue = json();
1917
1918
  function tryParseJson(text) {
1918
1919
  try {
1919
1920
  return {
1920
1921
  ok: true,
1921
- value: JSON.parse(text)
1922
+ value: JsonValue.parse(JSON.parse(text))
1922
1923
  };
1923
1924
  } catch {
1924
1925
  return { ok: false };
@@ -1927,7 +1928,7 @@ function tryParseJson(text) {
1927
1928
  function safeParseJson(text) {
1928
1929
  if (!text) return {};
1929
1930
  try {
1930
- return JSON.parse(text);
1931
+ return JsonValue.parse(JSON.parse(text));
1931
1932
  } catch {
1932
1933
  return text;
1933
1934
  }
@@ -2029,8 +2030,8 @@ function ImageAwareContent({ text, markdown }) {
2029
2030
  function FormattedContent({ text, markdown }) {
2030
2031
  const parsed = tryParseJson(text);
2031
2032
  const [mode, setMode] = (0, import_react.useState)("pretty");
2032
- const canRenderJsonView = parsed.ok && parsed.value !== null && (Array.isArray(parsed.value) || typeof parsed.value === "object");
2033
- if (!parsed.ok || !canRenderJsonView) {
2033
+ const jsonContainer = parsed.ok && parsed.value instanceof Object ? parsed.value : null;
2034
+ if (!parsed.ok || jsonContainer === null) {
2034
2035
  if (markdown) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageAwareContent, {
2035
2036
  text,
2036
2037
  markdown: true
@@ -2051,7 +2052,7 @@ function FormattedContent({ text, markdown }) {
2051
2052
  children: "Pretty"
2052
2053
  })]
2053
2054
  }), mode === "pretty" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(JsonView, {
2054
- value: parsed.value,
2055
+ value: jsonContainer,
2055
2056
  style: lightTheme,
2056
2057
  displayDataTypes: false,
2057
2058
  enableClipboard: true,
@@ -2102,12 +2103,12 @@ function Metric({ label, value }) {
2102
2103
  })]
2103
2104
  });
2104
2105
  }
2105
- var STATUS_STYLE = {
2106
- running: "bg-blue-100 text-blue-600",
2107
- succeeded: "bg-sage-100 text-sage-600",
2108
- error: "bg-red-100 text-red-600",
2109
- aborted: "bg-caution-400/15 text-caution-500"
2110
- };
2106
+ var STATUS_STYLE = new Map([
2107
+ ["running", "bg-blue-100 text-blue-600"],
2108
+ ["succeeded", "bg-sage-100 text-sage-600"],
2109
+ ["error", "bg-red-100 text-red-600"],
2110
+ ["aborted", "bg-caution-400/15 text-caution-500"]
2111
+ ]);
2111
2112
  function ErrorPanel({ message }) {
2112
2113
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2113
2114
  className: "panel overflow-hidden border border-red-200 bg-red-50/60",
@@ -2159,7 +2160,7 @@ function HeaderBar({ data }) {
2159
2160
  children: ["fallback ×", data.fallback_count]
2160
2161
  }),
2161
2162
  !isRunning && data.status !== "succeeded" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2162
- className: `text-[10px] px-1.5 py-0.5 rounded-full font-medium uppercase ${STATUS_STYLE[data.status] ?? "bg-sand-100 text-sand-500"}`,
2163
+ className: `text-[10px] px-1.5 py-0.5 rounded-full font-medium uppercase ${STATUS_STYLE.get(data.status) ?? "bg-sand-100 text-sand-500"}`,
2163
2164
  children: data.status
2164
2165
  }),
2165
2166
  data.response_json_ok === false && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
@@ -2249,6 +2250,19 @@ function MetricsPanel({ data, toolCallCount }) {
2249
2250
  })]
2250
2251
  });
2251
2252
  }
2253
+ var ToolInputImage = object({
2254
+ mediaType: string().optional(),
2255
+ data: string().optional(),
2256
+ url: string().optional(),
2257
+ byteSize: number().optional()
2258
+ });
2259
+ var ToolInputArgs = looseObject({ inputImages: array(JsonValue) });
2260
+ var MaskableToolInputImage = looseObject({
2261
+ mediaType: JsonValue.optional(),
2262
+ byteSize: JsonValue.optional(),
2263
+ url: JsonValue.optional(),
2264
+ data: JsonValue.optional()
2265
+ });
2252
2266
  function formatDurationMs(ms) {
2253
2267
  if (ms === null || ms === void 0) return "—";
2254
2268
  return ms >= 1e3 ? `${(ms / 1e3).toFixed(1)}s` : `${ms}ms`;
@@ -2263,10 +2277,12 @@ function detectTokenRateProvider(source) {
2263
2277
  const canonical = modelName.includes("/") ? modelName.split("/").pop() : modelName;
2264
2278
  if (canonical.startsWith("claude-")) return "anthropic";
2265
2279
  if (/^(gpt-|codex-|o\d)/.test(canonical)) return "openai";
2280
+ if (canonical.startsWith("grok-")) return "grok";
2266
2281
  }
2267
2282
  const tokenName = source.token_name?.trim().toLowerCase();
2268
2283
  if (tokenName?.startsWith("anthropic/")) return "anthropic";
2269
2284
  if (tokenName?.startsWith("openai/")) return "openai";
2285
+ if (tokenName?.startsWith("grok/")) return "grok";
2270
2286
  return null;
2271
2287
  }
2272
2288
  function isTokensPerSecEnabled(source) {
@@ -2291,36 +2307,37 @@ function CompactMetric({ label, value }) {
2291
2307
  })]
2292
2308
  });
2293
2309
  }
2294
- function readToolInputImages(args) {
2295
- if (!args || typeof args !== "object" || Array.isArray(args)) return [];
2296
- const inputImages = args.inputImages;
2297
- return Array.isArray(inputImages) ? inputImages : void 0;
2298
- }
2299
2310
  function getToolInputImages(args) {
2300
- return (readToolInputImages(args) ?? []).filter((item) => {
2301
- if (!item || typeof item !== "object" || Array.isArray(item)) return false;
2302
- const image = item;
2303
- return typeof image.url === "string" && image.url.length > 0 || typeof image.data === "string" && image.data.length > 0;
2311
+ const parsedArgs = ToolInputArgs.safeParse(args);
2312
+ if (!parsedArgs.success) return [];
2313
+ return parsedArgs.data.inputImages.flatMap((item) => {
2314
+ const image = ToolInputImage.safeParse(item);
2315
+ return image.success && (image.data.url || image.data.data) ? [image.data] : [];
2304
2316
  });
2305
2317
  }
2318
+ function maskToolInputImage(item) {
2319
+ const parsed = MaskableToolInputImage.safeParse(item);
2320
+ if (!parsed.success) return item;
2321
+ const image = parsed.data;
2322
+ const masked = {};
2323
+ if (image.mediaType !== void 0) masked.mediaType = image.mediaType;
2324
+ if (image.byteSize !== void 0) masked.byteSize = image.byteSize;
2325
+ const url = string().safeParse(image.url);
2326
+ const maskedUrl = url.success && url.data.toLowerCase().startsWith("data:") ? `[data-url ${url.data.length} chars]` : image.url;
2327
+ if (maskedUrl) masked.url = maskedUrl;
2328
+ if (image.data) {
2329
+ const data = string().safeParse(image.data);
2330
+ masked.data = data.success ? `[base64 ${data.data.length} chars]` : "[base64 data]";
2331
+ }
2332
+ return masked;
2333
+ }
2334
+ /** Returns the value passed to JSON.stringify for display; undefined fields are omitted there. */
2306
2335
  function hideToolInputImages(args) {
2307
- if (!args || typeof args !== "object" || Array.isArray(args)) return args;
2308
- const record = args;
2309
- const inputImages = readToolInputImages(record);
2310
- if (!inputImages) return args;
2336
+ const parsedArgs = ToolInputArgs.safeParse(args);
2337
+ if (!parsedArgs.success || !(args instanceof Object) || Array.isArray(args)) return args;
2311
2338
  return {
2312
- ...record,
2313
- inputImages: inputImages.map((item) => {
2314
- if (!item || typeof item !== "object" || Array.isArray(item)) return item;
2315
- const image = item;
2316
- const maskedUrl = typeof image.url === "string" && image.url.toLowerCase().startsWith("data:") ? `[data-url ${image.url.length} chars]` : image.url;
2317
- return {
2318
- mediaType: image.mediaType,
2319
- byteSize: image.byteSize,
2320
- ...maskedUrl ? { url: maskedUrl } : {},
2321
- ...image.data ? { data: `[base64 ${image.data.length} chars]` } : {}
2322
- };
2323
- })
2339
+ ...args,
2340
+ inputImages: parsedArgs.data.inputImages.map(maskToolInputImage)
2324
2341
  };
2325
2342
  }
2326
2343
  function ToolInputImages({ images }) {
@@ -2372,6 +2389,8 @@ function ToolCallItem({ entry }) {
2372
2389
  const { data: detail } = RequestLogStepService.useRequestLogStep("A", entry.id, { enabled: opened });
2373
2390
  const displayArgs = hideToolInputImages(detail ? safeParseJson(detail.tool_args) : null);
2374
2391
  const result = detail ? safeParseJson(detail.tool_result) : null;
2392
+ const resultText = string().safeParse(result);
2393
+ const responseText = resultText.success ? resultText.data : JSON.stringify(result);
2375
2394
  const error = detail?.error ?? entry.error;
2376
2395
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", {
2377
2396
  className: "group/tool",
@@ -2420,7 +2439,7 @@ function ToolCallItem({ entry }) {
2420
2439
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2421
2440
  className: "mt-1 rounded-md bg-sand-50 p-3 overflow-auto",
2422
2441
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FormattedContent, {
2423
- text: detail ? typeof result === "string" ? result : JSON.stringify(result) : "Loading...",
2442
+ text: detail ? responseText : "Loading...",
2424
2443
  markdown: true
2425
2444
  })
2426
2445
  })] })
@@ -2628,11 +2647,19 @@ function historyItemLabel(item) {
2628
2647
  if (item.type === "function_call_output") return `fn result`;
2629
2648
  return item.role ?? item.type;
2630
2649
  }
2650
+ var HistoryTextPart = looseObject({ text: string() });
2651
+ var HistoryContent = union([
2652
+ string(),
2653
+ array(union([HistoryTextPart, JsonValue])),
2654
+ JsonValue
2655
+ ]);
2631
2656
  function extractText(content) {
2632
- if (typeof content === "string") return content;
2633
- if (Array.isArray(content)) return content.map((c) => {
2634
- if (typeof c === "object" && c !== null && "text" in c) return c.text;
2635
- return JSON.stringify(c);
2657
+ const text = string().safeParse(content);
2658
+ if (text.success) return text.data;
2659
+ const parts = array(union([HistoryTextPart, JsonValue])).safeParse(content);
2660
+ if (parts.success) return parts.data.map((part) => {
2661
+ const textPart = HistoryTextPart.safeParse(part);
2662
+ return textPart.success ? textPart.data.text : JSON.stringify(part);
2636
2663
  }).join("\n");
2637
2664
  return JSON.stringify(content);
2638
2665
  }
@@ -2648,18 +2675,21 @@ function HistorySection({ history }) {
2648
2675
  defaultOpen: false,
2649
2676
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2650
2677
  className: "space-y-1.5",
2651
- children: history.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2652
- className: `rounded-md px-3 py-2 ${historyItemBg(item)}`,
2653
- children: [
2654
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2655
- className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium mb-1",
2656
- children: historyItemLabel(item)
2657
- }),
2658
- item.content !== null && item.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: extractText(item.content) }),
2659
- item.arguments && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: item.arguments }),
2660
- item.output && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: item.output })
2661
- ]
2662
- }, `hist-${i}`))
2678
+ children: history.map((item, i) => {
2679
+ const content = HistoryContent.safeParse(item.content);
2680
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2681
+ className: `rounded-md px-3 py-2 ${historyItemBg(item)}`,
2682
+ children: [
2683
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2684
+ className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium mb-1",
2685
+ children: historyItemLabel(item)
2686
+ }),
2687
+ item.content !== null && item.content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: content.success ? extractText(content.data) : JSON.stringify(item.content) }),
2688
+ item.arguments && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: item.arguments }),
2689
+ item.output && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MonoPre, { children: item.output })
2690
+ ]
2691
+ }, `hist-${i}`);
2692
+ })
2663
2693
  })
2664
2694
  });
2665
2695
  }
@@ -2715,7 +2745,7 @@ function ToolsHeaderMetadata({ tools }) {
2715
2745
  function ToolInputZod({ code, fullCode }) {
2716
2746
  const highlighted = (0, import_react.useMemo)(() => highlightTypeText(code), [code]);
2717
2747
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
2718
- "data-zod-parameter-shape": true,
2748
+ "data-zod-parameter-schema": true,
2719
2749
  className: `max-h-64 overflow-auto rounded-md bg-sand-900 px-3 py-2.5 font-mono text-[11px] leading-relaxed whitespace-pre text-sand-200 ${fullCode ? "cursor-help outline-none focus-visible:ring-2 focus-visible:ring-sienna-300" : ""}`,
2720
2750
  tabIndex: fullCode ? 0 : void 0,
2721
2751
  title: fullCode,
@@ -1,11 +1,149 @@
1
- import { A as require_react, O as useQueryClient, X as __toESM, k as require_jsx_runtime, n as QgridService, o as TokenService } from "./services.generated-BA4AcAf5.js";
2
- import { f as lucideKeyRound, o as Q } from "../entry-server.generated.js";
3
- import { t as useUpdateTokenMutation } from "./use-update-token-mutation-pkArIzCP.js";
4
- import { n as OAuthCodeEntry, t as useOAuthLoginFlow } from "./use-oauth-login-flow-Gn8flMK5.js";
5
- import { t as lucidePlus } from "./plus-BZ9I0VgC.js";
6
- //#region src/components/qgrid/AddTokenModal.tsx
1
+ import { $ as __toESM, M as require_jsx_runtime, N as require_react, j as useQueryClient, n as QgridService, o as TokenService } from "./services.generated-CMJ8AHbO.js";
2
+ import { i as o, n as useOAuthLoginFlow, r as OAuthCodeEntry } from "./use-oauth-login-flow-jkAkT3X6.js";
3
+ import { u as lucideKeyRound } from "../entry-server.generated.js";
4
+ import { t as useUpdateTokenMutation } from "./use-update-token-mutation-Sm6kh02m.js";
5
+ import { t as lucidePlus } from "./plus-DaYQRpBt.js";
6
+ //#region src/components/qgrid/DeviceCodeEntry.tsx
7
7
  var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
8
8
  var import_jsx_runtime = require_jsx_runtime();
9
+ function formatRemaining(ms) {
10
+ const totalSec = Math.max(Math.ceil(ms / 1e3), 0);
11
+ const m = Math.floor(totalSec / 60);
12
+ const s = totalSec % 60;
13
+ return `${m}:${String(s).padStart(2, "0")}`;
14
+ }
15
+ /** 만료 시각까지 1초마다 갱신되는 남은 시간. */
16
+ function Countdown({ expiresAt }) {
17
+ const [now, setNow] = (0, import_react.useState)(() => Date.now());
18
+ (0, import_react.useEffect)(() => {
19
+ const id = window.setInterval(() => setNow(Date.now()), 1e3);
20
+ return () => clearInterval(id);
21
+ }, []);
22
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
23
+ className: "tabular-nums",
24
+ children: formatRemaining(expiresAt - now)
25
+ });
26
+ }
27
+ /**
28
+ * Grok device-code 로그인 단계. 사용자 코드와 인증 링크를 보여 주고, 폴링 상태를 표시한다.
29
+ * 폴링 자체는 `useOAuthLoginFlow().startDevice` 가 소유한다.
30
+ */
31
+ function DeviceCodeEntry({ flow, onRestart }) {
32
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
33
+ className: "space-y-2",
34
+ children: [
35
+ flow.status === "starting" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
36
+ className: "flex items-center gap-1.5 text-[12px] text-sand-600",
37
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-3.5 h-3.5 border-2 border-sand-400 border-t-transparent rounded-full animate-spin" }), "Requesting device code..."]
38
+ }),
39
+ flow.status === "waiting" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
40
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
41
+ className: "text-[12px] text-sand-600 leading-relaxed",
42
+ children: "아래 링크를 열어 xAI 계정으로 로그인한 뒤 이 코드를 입력하세요. 승인되면 토큰이 자동으로 추가됩니다."
43
+ }),
44
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
45
+ className: "rounded-md border border-sand-200 bg-sand-50 px-3 py-3 text-center",
46
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
47
+ className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium",
48
+ children: "Device code"
49
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
50
+ className: "mt-1 font-mono text-lg tracking-widest text-sand-900 select-all",
51
+ children: flow.userCode
52
+ })]
53
+ }),
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
55
+ href: flow.verificationUriComplete ?? flow.verificationUri,
56
+ target: "_blank",
57
+ rel: "noopener noreferrer",
58
+ className: "block w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white text-center hover:bg-sand-800 transition-colors duration-150",
59
+ children: "Open xAI to approve"
60
+ }),
61
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
62
+ className: "flex items-center justify-between text-[11px] text-sand-500",
63
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
64
+ className: "flex items-center gap-1.5",
65
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-2.5 h-2.5 border-2 border-sand-400 border-t-transparent rounded-full animate-spin" }), flow.slowDown ? "Waiting for approval (polling slowed down)..." : "Waiting for approval..."]
66
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["expires in ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Countdown, { expiresAt: flow.expiresAt })] })]
67
+ })
68
+ ] }),
69
+ flow.status === "added" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
70
+ className: "text-[12px] text-sage-600",
71
+ children: [
72
+ "Token \"",
73
+ flow.name,
74
+ "\" added."
75
+ ]
76
+ }),
77
+ flow.status === "expired" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
78
+ className: "text-[11px] text-red-500",
79
+ children: "Device code가 만료되었습니다 — 로그인을 다시 시작하세요."
80
+ }),
81
+ flow.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
82
+ className: "text-[11px] text-red-500",
83
+ children: flow.message
84
+ }),
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
86
+ type: "button",
87
+ className: "w-full py-1.5 text-[12px] text-sand-500 hover:text-sand-700 transition-colors duration-150",
88
+ onClick: onRestart,
89
+ children: "처음부터 다시 시작"
90
+ })
91
+ ]
92
+ });
93
+ }
94
+ //#endregion
95
+ //#region src/components/qgrid/AddTokenModal.tsx
96
+ function Spinner({ light }) {
97
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
98
+ className: "flex items-center gap-1.5",
99
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `w-3.5 h-3.5 border-2 border-t-transparent rounded-full animate-spin ${light ? "border-white" : "border-sand-400"}` }), "Waiting for login..."]
100
+ });
101
+ }
102
+ function OrDivider() {
103
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
104
+ className: "flex items-center gap-3",
105
+ children: [
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1 h-px bg-sand-200" }),
107
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
108
+ className: "text-[10px] text-sand-400 uppercase",
109
+ children: "or"
110
+ }),
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1 h-px bg-sand-200" })
112
+ ]
113
+ });
114
+ }
115
+ /** Provider 선택 버튼들. 상태는 상위(`useOAuthLoginFlow`)가 소유한다. */
116
+ function AddTokenProviderOptions({ disabled, loadingProvider, onStart, onStartGrokDevice }) {
117
+ const secondary = "w-full py-2.5 text-sm font-medium rounded-md border border-sand-300 text-sand-700 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2";
118
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
119
+ className: "space-y-2",
120
+ children: [
121
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
122
+ type: "button",
123
+ className: "w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2",
124
+ disabled,
125
+ onClick: () => onStart("openai"),
126
+ children: loadingProvider === "openai" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { light: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideKeyRound, { className: "size-4" }), "Login with OpenAI"] })
127
+ }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OrDivider, {}),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
130
+ type: "button",
131
+ className: secondary,
132
+ disabled,
133
+ onClick: () => onStart("anthropic"),
134
+ children: loadingProvider === "anthropic" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { light: false }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideKeyRound, { className: "size-4" }), "Login with Claude"] })
135
+ }),
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OrDivider, {}),
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
138
+ type: "button",
139
+ className: secondary,
140
+ disabled,
141
+ onClick: onStartGrokDevice,
142
+ children: loadingProvider === "grok" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { light: false }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideKeyRound, { className: "size-4" }), "Login with xAI"] })
143
+ })
144
+ ]
145
+ });
146
+ }
9
147
  function AddTokenModal() {
10
148
  const [open, setOpen] = (0, import_react.useState)(false);
11
149
  const [name, setName] = (0, import_react.useState)("");
@@ -45,7 +183,7 @@ function AddTokenModal() {
45
183
  htmlFor: "token-name",
46
184
  className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium",
47
185
  children: "Name *"
48
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Q, {
186
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(o, {
49
187
  value: name,
50
188
  onChange: (e) => setName(e.target.value),
51
189
  placeholder: "e.g. your-token-name",
@@ -56,41 +194,14 @@ function AddTokenModal() {
56
194
  isError: oauth.completeMutation.isError,
57
195
  onSubmit: (code) => void submitPastedCode(code),
58
196
  onRestart: oauth.reset
59
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
60
- className: "space-y-2",
61
- children: [
62
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
63
- type: "button",
64
- className: "w-full py-2.5 text-sm font-medium rounded-md bg-sand-900 text-white hover:bg-sand-800 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2",
65
- disabled: !name.trim() || oauth.loadingProvider !== null,
66
- onClick: () => void oauth.start("openai", name),
67
- children: oauth.loadingProvider === "openai" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
68
- className: "flex items-center gap-1.5",
69
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full animate-spin" }), "Waiting for login..."]
70
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideKeyRound, { className: "size-4" }), "Login with OpenAI"] })
71
- }),
72
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
73
- className: "flex items-center gap-3",
74
- children: [
75
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1 h-px bg-sand-200" }),
76
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
77
- className: "text-[10px] text-sand-400 uppercase",
78
- children: "or"
79
- }),
80
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex-1 h-px bg-sand-200" })
81
- ]
82
- }),
83
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
84
- type: "button",
85
- className: "w-full py-2.5 text-sm font-medium rounded-md border border-sand-300 text-sand-700 hover:bg-sand-100 disabled:opacity-50 transition-colors duration-150 flex items-center justify-center gap-2",
86
- disabled: !name.trim() || oauth.loadingProvider !== null,
87
- onClick: () => void oauth.start("anthropic", name),
88
- children: oauth.loadingProvider === "anthropic" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
89
- className: "flex items-center gap-1.5",
90
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-3.5 h-3.5 border-2 border-sand-400 border-t-transparent rounded-full animate-spin" }), "Waiting for login..."]
91
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(lucideKeyRound, { className: "size-4" }), "Login with Claude"] })
92
- })
93
- ]
197
+ }) : oauth.deviceFlow ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeviceCodeEntry, {
198
+ flow: oauth.deviceFlow,
199
+ onRestart: oauth.reset
200
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddTokenProviderOptions, {
201
+ disabled: !name.trim() || oauth.loadingProvider !== null,
202
+ loadingProvider: oauth.loadingProvider,
203
+ onStart: (provider) => void oauth.start(provider, name),
204
+ onStartGrokDevice: () => void oauth.startDevice(name, close)
94
205
  })]
95
206
  }),
96
207
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
@@ -141,19 +252,20 @@ var lucideTrash2 = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg",
141
252
  //#endregion
142
253
  //#region src/lib/token-label.ts
143
254
  function maskAccessToken(credentials) {
144
- if (!credentials || typeof credentials !== "object") return "—";
145
- if ("authSource" in credentials && credentials.authSource === "system-keychain") return "System Keychain";
146
- const token = "accessToken" in credentials ? credentials.accessToken : void 0;
147
- if (typeof token !== "string" || !token) return "—";
255
+ const token = credentials.accessToken;
256
+ if (!token) return "—";
148
257
  return token.length <= 12 ? token : `${token.slice(0, 8)}...${token.slice(-4)}`;
149
258
  }
150
259
  //#endregion
151
260
  //#region src/components/qgrid/TokenTable.tsx
152
261
  function getExpiresAt(token) {
153
262
  const c = token.credentials;
154
- if ("expiresAt" in c && typeof c.expiresAt === "number") return c.expiresAt;
155
- if ("accessTokenExpiresAt" in c && typeof c.accessTokenExpiresAt === "number") return c.accessTokenExpiresAt;
156
- return null;
263
+ if ("accessTokenExpiresAt" in c) return c.accessTokenExpiresAt;
264
+ if ("authMode" in c) {
265
+ const ms = Date.parse(c.expiresAt);
266
+ return Number.isNaN(ms) ? null : ms;
267
+ }
268
+ return c.expiresAt;
157
269
  }
158
270
  function formatExpiry(expiresAt) {
159
271
  if (!expiresAt) return {
@@ -352,7 +464,7 @@ function TokenTable({ data, isLoading }) {
352
464
  htmlFor: "token-name",
353
465
  className: "text-[10px] uppercase tracking-wider text-sand-500 font-medium",
354
466
  children: "Name"
355
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Q, {
467
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(o, {
356
468
  value: editName,
357
469
  onChange: (e) => setEditName(e.target.value),
358
470
  placeholder: "e.g. prod, dev, team-a",
@@ -0,0 +1,18 @@
1
+ //#region src/components/qgrid/total-cost.ts
2
+ /** 비용을 몰라 합계에 들어가지 않은 요청 수(가격 없는 이미지 + provider 비용 없는 음성/영상). */
3
+ function unpricedRequestCount(cost) {
4
+ return cost.unknownImageCostCount + (cost.unknownCostCount ?? 0);
5
+ }
6
+ /** 합계 옆에 붙일 짧은 표시. 빠진 요청이 없으면 null. */
7
+ function unpricedRequestLabel(cost) {
8
+ const count = unpricedRequestCount(cost);
9
+ return count > 0 ? `+${count} unpriced` : null;
10
+ }
11
+ /** 표시에 붙일 설명. 이미지와 그 외 요청을 나눠 보여준다. */
12
+ function unpricedRequestTitle(cost) {
13
+ if (unpricedRequestCount(cost) === 0) return null;
14
+ const media = cost.unknownCostCount ?? 0;
15
+ return `Total excludes requests with unknown cost: ${cost.unknownImageCostCount} image, ${media} voice/video.`;
16
+ }
17
+ //#endregion
18
+ export { unpricedRequestTitle as n, unpricedRequestLabel as t };