free-claude-code 6.2.64__py3-none-any.whl

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 (429) hide show
  1. free_claude_code/__init__.py +1 -0
  2. free_claude_code/api/__init__.py +1 -0
  3. free_claude_code/api/admin_cache.py +49 -0
  4. free_claude_code/api/admin_routes.py +501 -0
  5. free_claude_code/api/admin_security.py +67 -0
  6. free_claude_code/api/admin_static/admin.css +980 -0
  7. free_claude_code/api/admin_static/admin.js +1934 -0
  8. free_claude_code/api/admin_static/code_sessions.css +109 -0
  9. free_claude_code/api/admin_static/code_sessions.js +1693 -0
  10. free_claude_code/api/admin_static/form_controls.js +15 -0
  11. free_claude_code/api/admin_static/index.html +201 -0
  12. free_claude_code/api/admin_static/model_combobox.js +194 -0
  13. free_claude_code/api/admin_static/providers/LICENSE-llamacpp.txt +21 -0
  14. free_claude_code/api/admin_static/providers/LICENSE-lobe-icons.txt +21 -0
  15. free_claude_code/api/admin_static/providers/SOURCES.md +56 -0
  16. free_claude_code/api/admin_static/providers/agnesai.svg +1 -0
  17. free_claude_code/api/admin_static/providers/azure-color.svg +1 -0
  18. free_claude_code/api/admin_static/providers/bedrock-color.svg +1 -0
  19. free_claude_code/api/admin_static/providers/cerebras-color.svg +1 -0
  20. free_claude_code/api/admin_static/providers/chutes.png +0 -0
  21. free_claude_code/api/admin_static/providers/cline.svg +1 -0
  22. free_claude_code/api/admin_static/providers/cloudflare-color.svg +1 -0
  23. free_claude_code/api/admin_static/providers/cohere-color.svg +1 -0
  24. free_claude_code/api/admin_static/providers/deepinfra-color.svg +1 -0
  25. free_claude_code/api/admin_static/providers/deepseek-color.svg +1 -0
  26. free_claude_code/api/admin_static/providers/experiential.svg +9 -0
  27. free_claude_code/api/admin_static/providers/featherless-color.svg +1 -0
  28. free_claude_code/api/admin_static/providers/fireworks-color.svg +1 -0
  29. free_claude_code/api/admin_static/providers/gemini-color.svg +1 -0
  30. free_claude_code/api/admin_static/providers/githubcopilot.svg +1 -0
  31. free_claude_code/api/admin_static/providers/groq.svg +1 -0
  32. free_claude_code/api/admin_static/providers/huggingface-color.svg +1 -0
  33. free_claude_code/api/admin_static/providers/kilocode.svg +1 -0
  34. free_claude_code/api/admin_static/providers/kimi-color.svg +1 -0
  35. free_claude_code/api/admin_static/providers/lightning.png +0 -0
  36. free_claude_code/api/admin_static/providers/llamacpp.svg +77 -0
  37. free_claude_code/api/admin_static/providers/llm7.png +0 -0
  38. free_claude_code/api/admin_static/providers/lmstudio.svg +1 -0
  39. free_claude_code/api/admin_static/providers/minimax-color.svg +1 -0
  40. free_claude_code/api/admin_static/providers/mistral-color.svg +1 -0
  41. free_claude_code/api/admin_static/providers/nararoute.png +0 -0
  42. free_claude_code/api/admin_static/providers/nebius.svg +1 -0
  43. free_claude_code/api/admin_static/providers/novita-color.svg +1 -0
  44. free_claude_code/api/admin_static/providers/nvidia-color.svg +1 -0
  45. free_claude_code/api/admin_static/providers/ollama.svg +1 -0
  46. free_claude_code/api/admin_static/providers/openai.svg +1 -0
  47. free_claude_code/api/admin_static/providers/opencode.svg +1 -0
  48. free_claude_code/api/admin_static/providers/openrouter.svg +1 -0
  49. free_claude_code/api/admin_static/providers/poolside-color.svg +1 -0
  50. free_claude_code/api/admin_static/providers/qwen-color.svg +1 -0
  51. free_claude_code/api/admin_static/providers/sambanova-color.svg +1 -0
  52. free_claude_code/api/admin_static/providers/scaleway.svg +11 -0
  53. free_claude_code/api/admin_static/providers/siliconcloud-color.svg +1 -0
  54. free_claude_code/api/admin_static/providers/together-color.svg +1 -0
  55. free_claude_code/api/admin_static/providers/tokenrouter.png +0 -0
  56. free_claude_code/api/admin_static/providers/vercel.svg +1 -0
  57. free_claude_code/api/admin_static/providers/vertexai-color.svg +1 -0
  58. free_claude_code/api/admin_static/providers/wafer.png +0 -0
  59. free_claude_code/api/admin_static/providers/wandb.png +0 -0
  60. free_claude_code/api/admin_static/providers/xai.svg +1 -0
  61. free_claude_code/api/admin_static/providers/zai.svg +1 -0
  62. free_claude_code/api/admin_static/providers/zenmux.svg +1 -0
  63. free_claude_code/api/admin_static/session_layout.css +552 -0
  64. free_claude_code/api/admin_static/session_ui.js +202 -0
  65. free_claude_code/api/app.py +149 -0
  66. free_claude_code/api/code_sessions_routes.py +386 -0
  67. free_claude_code/api/command_utils.py +164 -0
  68. free_claude_code/api/dependencies.py +128 -0
  69. free_claude_code/api/detection.py +185 -0
  70. free_claude_code/api/handlers/__init__.py +7 -0
  71. free_claude_code/api/handlers/classifier_response.py +66 -0
  72. free_claude_code/api/handlers/messages.py +359 -0
  73. free_claude_code/api/handlers/responses.py +163 -0
  74. free_claude_code/api/handlers/token_count.py +87 -0
  75. free_claude_code/api/markdown.py +71 -0
  76. free_claude_code/api/model_catalog.py +282 -0
  77. free_claude_code/api/optimization_handlers.py +162 -0
  78. free_claude_code/api/ports.py +97 -0
  79. free_claude_code/api/request_errors.py +100 -0
  80. free_claude_code/api/request_ids.py +100 -0
  81. free_claude_code/api/request_lifetime.py +130 -0
  82. free_claude_code/api/response_streams.py +422 -0
  83. free_claude_code/api/routes.py +269 -0
  84. free_claude_code/api/validation_log.py +46 -0
  85. free_claude_code/application/__init__.py +1 -0
  86. free_claude_code/application/code_sessions/__init__.py +33 -0
  87. free_claude_code/application/code_sessions/models.py +227 -0
  88. free_claude_code/application/code_sessions/ports.py +197 -0
  89. free_claude_code/application/code_sessions/service.py +1123 -0
  90. free_claude_code/application/code_sessions/state.py +659 -0
  91. free_claude_code/application/connected_accounts.py +96 -0
  92. free_claude_code/application/errors.py +41 -0
  93. free_claude_code/application/execution.py +467 -0
  94. free_claude_code/application/model_catalog.py +95 -0
  95. free_claude_code/application/model_metadata.py +26 -0
  96. free_claude_code/application/ports.py +127 -0
  97. free_claude_code/application/readiness.py +43 -0
  98. free_claude_code/application/reasoning.py +134 -0
  99. free_claude_code/application/routing.py +291 -0
  100. free_claude_code/application/session_events.py +140 -0
  101. free_claude_code/application/web_tools/__init__.py +1 -0
  102. free_claude_code/application/web_tools/ports.py +35 -0
  103. free_claude_code/application/web_tools/request.py +348 -0
  104. free_claude_code/application/web_tools/service.py +481 -0
  105. free_claude_code/assets/app-icon.icns +0 -0
  106. free_claude_code/assets/app-icon.ico +0 -0
  107. free_claude_code/assets/app-icon.png +0 -0
  108. free_claude_code/assets/app-icon.svg +14 -0
  109. free_claude_code/cli/__init__.py +5 -0
  110. free_claude_code/cli/commands.py +379 -0
  111. free_claude_code/cli/desktop.py +156 -0
  112. free_claude_code/cli/desktop_assets.py +31 -0
  113. free_claude_code/cli/desktop_entrypoint.py +29 -0
  114. free_claude_code/cli/desktop_tray.py +67 -0
  115. free_claude_code/cli/entrypoints.py +25 -0
  116. free_claude_code/cli/launchers/__init__.py +1 -0
  117. free_claude_code/cli/launchers/aider.py +53 -0
  118. free_claude_code/cli/launchers/aider_config.py +80 -0
  119. free_claude_code/cli/launchers/catalog_http.py +134 -0
  120. free_claude_code/cli/launchers/claude.py +34 -0
  121. free_claude_code/cli/launchers/cline.py +60 -0
  122. free_claude_code/cli/launchers/cline_config.py +121 -0
  123. free_claude_code/cli/launchers/codex.py +47 -0
  124. free_claude_code/cli/launchers/common.py +103 -0
  125. free_claude_code/cli/launchers/dsh.py +69 -0
  126. free_claude_code/cli/launchers/dsh_config.py +124 -0
  127. free_claude_code/cli/launchers/grok.py +116 -0
  128. free_claude_code/cli/launchers/hermes.py +85 -0
  129. free_claude_code/cli/launchers/hermes_config.py +134 -0
  130. free_claude_code/cli/launchers/muse.py +68 -0
  131. free_claude_code/cli/launchers/opencode.py +83 -0
  132. free_claude_code/cli/launchers/opencode_config.py +107 -0
  133. free_claude_code/cli/launchers/pi.py +70 -0
  134. free_claude_code/cli/launchers/pi_extension.ts +190 -0
  135. free_claude_code/cli/launchers/runner.py +155 -0
  136. free_claude_code/cli/local_http.py +12 -0
  137. free_claude_code/cli/managed/__init__.py +6 -0
  138. free_claude_code/cli/managed/claude.py +225 -0
  139. free_claude_code/cli/managed/diagnostics.py +47 -0
  140. free_claude_code/cli/managed/manager.py +207 -0
  141. free_claude_code/cli/managed/session.py +293 -0
  142. free_claude_code/cli/process_registry.py +76 -0
  143. free_claude_code/cli/server_socket.py +71 -0
  144. free_claude_code/cli/uvicorn_server.py +41 -0
  145. free_claude_code/config/__init__.py +10 -0
  146. free_claude_code/config/admin/__init__.py +1 -0
  147. free_claude_code/config/admin/manifest.py +610 -0
  148. free_claude_code/config/admin/persistence.py +202 -0
  149. free_claude_code/config/admin/provider_manifest.py +443 -0
  150. free_claude_code/config/admin/specs.py +77 -0
  151. free_claude_code/config/admin/state.py +18 -0
  152. free_claude_code/config/admin/status.py +116 -0
  153. free_claude_code/config/admin/validation.py +40 -0
  154. free_claude_code/config/admin/values.py +115 -0
  155. free_claude_code/config/constants.py +9 -0
  156. free_claude_code/config/env_files.py +74 -0
  157. free_claude_code/config/env_migrations.py +457 -0
  158. free_claude_code/config/loader.py +196 -0
  159. free_claude_code/config/logging_config.py +197 -0
  160. free_claude_code/config/model_refs.py +118 -0
  161. free_claude_code/config/nim.py +121 -0
  162. free_claude_code/config/paths.py +104 -0
  163. free_claude_code/config/provider_catalog.py +746 -0
  164. free_claude_code/config/provider_proxies.py +44 -0
  165. free_claude_code/config/reasoning.py +24 -0
  166. free_claude_code/config/server_urls.py +55 -0
  167. free_claude_code/config/settings.py +812 -0
  168. free_claude_code/core/__init__.py +15 -0
  169. free_claude_code/core/anthropic/__init__.py +99 -0
  170. free_claude_code/core/anthropic/content.py +31 -0
  171. free_claude_code/core/anthropic/conversion.py +876 -0
  172. free_claude_code/core/anthropic/errors.py +97 -0
  173. free_claude_code/core/anthropic/image_sources.py +77 -0
  174. free_claude_code/core/anthropic/models.py +193 -0
  175. free_claude_code/core/anthropic/native.py +184 -0
  176. free_claude_code/core/anthropic/native_stream.py +306 -0
  177. free_claude_code/core/anthropic/request_serialization.py +57 -0
  178. free_claude_code/core/anthropic/request_snapshot.py +35 -0
  179. free_claude_code/core/anthropic/server_tool_sse.py +234 -0
  180. free_claude_code/core/anthropic/server_tool_types.py +9 -0
  181. free_claude_code/core/anthropic/sse_aggregation.py +144 -0
  182. free_claude_code/core/anthropic/stream_contracts.py +208 -0
  183. free_claude_code/core/anthropic/streaming/__init__.py +43 -0
  184. free_claude_code/core/anthropic/streaming/decoder.py +49 -0
  185. free_claude_code/core/anthropic/streaming/emitter.py +62 -0
  186. free_claude_code/core/anthropic/streaming/ledger.py +538 -0
  187. free_claude_code/core/anthropic/streaming/recovery.py +211 -0
  188. free_claude_code/core/anthropic/thinking.py +140 -0
  189. free_claude_code/core/anthropic/tokens.py +111 -0
  190. free_claude_code/core/anthropic/tool_results.py +63 -0
  191. free_claude_code/core/anthropic/tool_schema.py +94 -0
  192. free_claude_code/core/anthropic/tools.py +493 -0
  193. free_claude_code/core/anthropic/usage.py +38 -0
  194. free_claude_code/core/anthropic/utils.py +9 -0
  195. free_claude_code/core/async_iterators.py +26 -0
  196. free_claude_code/core/async_tasks.py +26 -0
  197. free_claude_code/core/data/README.md +12 -0
  198. free_claude_code/core/data/TIKTOKEN-LICENSE +21 -0
  199. free_claude_code/core/data/cl100k_base.tiktoken +100256 -0
  200. free_claude_code/core/diagnostics.py +319 -0
  201. free_claude_code/core/failures.py +50 -0
  202. free_claude_code/core/gateway_model_ids.py +73 -0
  203. free_claude_code/core/history_replay.py +561 -0
  204. free_claude_code/core/interprocess_lock.py +90 -0
  205. free_claude_code/core/json_types.py +7 -0
  206. free_claude_code/core/model_capabilities.py +10 -0
  207. free_claude_code/core/openai_chat.py +54 -0
  208. free_claude_code/core/openai_responses/__init__.py +90 -0
  209. free_claude_code/core/openai_responses/chat_request.py +747 -0
  210. free_claude_code/core/openai_responses/errors.py +78 -0
  211. free_claude_code/core/openai_responses/events.py +82 -0
  212. free_claude_code/core/openai_responses/ids.py +32 -0
  213. free_claude_code/core/openai_responses/items.py +35 -0
  214. free_claude_code/core/openai_responses/messages_request.py +624 -0
  215. free_claude_code/core/openai_responses/messages_stream.py +404 -0
  216. free_claude_code/core/openai_responses/models.py +33 -0
  217. free_claude_code/core/openai_responses/native.py +147 -0
  218. free_claude_code/core/openai_responses/provider_input.py +409 -0
  219. free_claude_code/core/openai_responses/provider_stream.py +282 -0
  220. free_claude_code/core/openai_responses/reasoning.py +73 -0
  221. free_claude_code/core/openai_responses/streaming/__init__.py +1 -0
  222. free_claude_code/core/openai_responses/streaming/blocks.py +36 -0
  223. free_claude_code/core/openai_responses/streaming/completion.py +169 -0
  224. free_claude_code/core/openai_responses/streaming/error_mapping.py +28 -0
  225. free_claude_code/core/openai_responses/streaming/event_builders.py +198 -0
  226. free_claude_code/core/openai_responses/streaming/ledger.py +96 -0
  227. free_claude_code/core/openai_responses/tokens.py +133 -0
  228. free_claude_code/core/openai_responses/tool_adaptation.py +828 -0
  229. free_claude_code/core/openai_responses/tool_search.py +204 -0
  230. free_claude_code/core/openai_responses/tools.py +169 -0
  231. free_claude_code/core/openai_tool_names.py +178 -0
  232. free_claude_code/core/rate_limit.py +72 -0
  233. free_claude_code/core/reasoning.py +136 -0
  234. free_claude_code/core/token_estimation.py +76 -0
  235. free_claude_code/core/tool_schema_patterns.py +168 -0
  236. free_claude_code/core/trace.py +197 -0
  237. free_claude_code/core/version.py +15 -0
  238. free_claude_code/core/web_tools.py +17 -0
  239. free_claude_code/core/windows_dpi.py +27 -0
  240. free_claude_code/harnesses/__init__.py +1 -0
  241. free_claude_code/harnesses/claude.py +42 -0
  242. free_claude_code/harnesses/claude_desktop_integration.py +418 -0
  243. free_claude_code/harnesses/claude_integration.py +167 -0
  244. free_claude_code/harnesses/codex.py +94 -0
  245. free_claude_code/harnesses/codex_integration.py +147 -0
  246. free_claude_code/harnesses/codex_model_catalog.py +109 -0
  247. free_claude_code/harnesses/config_file.py +33 -0
  248. free_claude_code/harnesses/environment.py +78 -0
  249. free_claude_code/harnesses/jetbrains_acp_integration.py +242 -0
  250. free_claude_code/harnesses/launch.py +21 -0
  251. free_claude_code/harnesses/resources.py +42 -0
  252. free_claude_code/messaging/__init__.py +16 -0
  253. free_claude_code/messaging/cli_event_constants.py +67 -0
  254. free_claude_code/messaging/command_context.py +99 -0
  255. free_claude_code/messaging/command_dispatcher.py +31 -0
  256. free_claude_code/messaging/commands.py +182 -0
  257. free_claude_code/messaging/event_parser.py +184 -0
  258. free_claude_code/messaging/limiter.py +342 -0
  259. free_claude_code/messaging/managed_protocols.py +35 -0
  260. free_claude_code/messaging/models.py +57 -0
  261. free_claude_code/messaging/node_event_pipeline.py +120 -0
  262. free_claude_code/messaging/node_runner.py +408 -0
  263. free_claude_code/messaging/platforms/__init__.py +20 -0
  264. free_claude_code/messaging/platforms/discord.py +319 -0
  265. free_claude_code/messaging/platforms/discord_inbound.py +112 -0
  266. free_claude_code/messaging/platforms/discord_io.py +167 -0
  267. free_claude_code/messaging/platforms/factory.py +109 -0
  268. free_claude_code/messaging/platforms/outbox.py +143 -0
  269. free_claude_code/messaging/platforms/ports.py +99 -0
  270. free_claude_code/messaging/platforms/telegram.py +300 -0
  271. free_claude_code/messaging/platforms/telegram_inbound.py +133 -0
  272. free_claude_code/messaging/platforms/telegram_io.py +287 -0
  273. free_claude_code/messaging/platforms/voice_flow.py +388 -0
  274. free_claude_code/messaging/rendering/__init__.py +3 -0
  275. free_claude_code/messaging/rendering/discord_markdown.py +318 -0
  276. free_claude_code/messaging/rendering/markdown_tables.py +47 -0
  277. free_claude_code/messaging/rendering/profiles.py +53 -0
  278. free_claude_code/messaging/rendering/telegram_markdown.py +331 -0
  279. free_claude_code/messaging/safe_diagnostics.py +15 -0
  280. free_claude_code/messaging/session/__init__.py +5 -0
  281. free_claude_code/messaging/session/managed_message_log.py +135 -0
  282. free_claude_code/messaging/session/persistence.py +161 -0
  283. free_claude_code/messaging/session/store.py +162 -0
  284. free_claude_code/messaging/transcript/__init__.py +6 -0
  285. free_claude_code/messaging/transcript/buffer.py +220 -0
  286. free_claude_code/messaging/transcript/context.py +18 -0
  287. free_claude_code/messaging/transcript/renderer.py +65 -0
  288. free_claude_code/messaging/transcript/segments.py +176 -0
  289. free_claude_code/messaging/transcript/subagents.py +108 -0
  290. free_claude_code/messaging/transcription.py +132 -0
  291. free_claude_code/messaging/trees/__init__.py +41 -0
  292. free_claude_code/messaging/trees/graph.py +250 -0
  293. free_claude_code/messaging/trees/identity.py +16 -0
  294. free_claude_code/messaging/trees/manager.py +587 -0
  295. free_claude_code/messaging/trees/node.py +56 -0
  296. free_claude_code/messaging/trees/processor.py +272 -0
  297. free_claude_code/messaging/trees/queue.py +47 -0
  298. free_claude_code/messaging/trees/repository.py +135 -0
  299. free_claude_code/messaging/trees/runtime.py +487 -0
  300. free_claude_code/messaging/trees/snapshot.py +221 -0
  301. free_claude_code/messaging/trees/transitions.py +174 -0
  302. free_claude_code/messaging/turn_intake.py +241 -0
  303. free_claude_code/messaging/ui_updates.py +99 -0
  304. free_claude_code/messaging/voice.py +376 -0
  305. free_claude_code/messaging/workflow.py +714 -0
  306. free_claude_code/providers/__init__.py +12 -0
  307. free_claude_code/providers/admission.py +942 -0
  308. free_claude_code/providers/anthropic_messages/__init__.py +1 -0
  309. free_claude_code/providers/anthropic_messages/request_policy.py +162 -0
  310. free_claude_code/providers/anthropic_messages/transport.py +499 -0
  311. free_claude_code/providers/base.py +73 -0
  312. free_claude_code/providers/cloudflare/__init__.py +8 -0
  313. free_claude_code/providers/cloudflare/client.py +166 -0
  314. free_claude_code/providers/credential_validation.py +314 -0
  315. free_claude_code/providers/deepseek/__init__.py +5 -0
  316. free_claude_code/providers/deepseek/client.py +117 -0
  317. free_claude_code/providers/deepseek/compat.py +241 -0
  318. free_claude_code/providers/endpoint.py +21 -0
  319. free_claude_code/providers/endpoint_types.py +21 -0
  320. free_claude_code/providers/failure_policy.py +574 -0
  321. free_claude_code/providers/gemini/__init__.py +5 -0
  322. free_claude_code/providers/gemini/client.py +42 -0
  323. free_claude_code/providers/github_copilot/__init__.py +1 -0
  324. free_claude_code/providers/github_copilot/auth.py +502 -0
  325. free_claude_code/providers/github_copilot/broker.py +248 -0
  326. free_claude_code/providers/github_copilot/lifecycle.py +18 -0
  327. free_claude_code/providers/github_copilot/login.py +112 -0
  328. free_claude_code/providers/github_copilot/native_cli.py +82 -0
  329. free_claude_code/providers/github_copilot/provider.py +367 -0
  330. free_claude_code/providers/github_copilot/request_policy.py +119 -0
  331. free_claude_code/providers/github_copilot/responses_events.py +90 -0
  332. free_claude_code/providers/github_copilot/sdk.py +496 -0
  333. free_claude_code/providers/github_copilot/types.py +67 -0
  334. free_claude_code/providers/google_openai/__init__.py +17 -0
  335. free_claude_code/providers/google_openai/provider.py +73 -0
  336. free_claude_code/providers/google_openai/reasoning.py +150 -0
  337. free_claude_code/providers/google_openai/thought_signatures.py +117 -0
  338. free_claude_code/providers/groq/__init__.py +5 -0
  339. free_claude_code/providers/groq/client.py +342 -0
  340. free_claude_code/providers/groq/tpm.py +114 -0
  341. free_claude_code/providers/history_replay.py +260 -0
  342. free_claude_code/providers/http.py +105 -0
  343. free_claude_code/providers/kilo/__init__.py +5 -0
  344. free_claude_code/providers/kilo/client.py +45 -0
  345. free_claude_code/providers/kilo/models.py +60 -0
  346. free_claude_code/providers/lmstudio/__init__.py +5 -0
  347. free_claude_code/providers/lmstudio/client.py +220 -0
  348. free_claude_code/providers/mistral/__init__.py +5 -0
  349. free_claude_code/providers/mistral/client.py +91 -0
  350. free_claude_code/providers/mistral/reasoning.py +410 -0
  351. free_claude_code/providers/model_listing.py +479 -0
  352. free_claude_code/providers/nvidia_nim/__init__.py +5 -0
  353. free_claude_code/providers/nvidia_nim/client.py +224 -0
  354. free_claude_code/providers/nvidia_nim/native_tool_stream.py +693 -0
  355. free_claude_code/providers/nvidia_nim/request_options.py +141 -0
  356. free_claude_code/providers/nvidia_nim/retry.py +85 -0
  357. free_claude_code/providers/nvidia_nim/tool_schema.py +255 -0
  358. free_claude_code/providers/nvidia_nim/voice.py +107 -0
  359. free_claude_code/providers/open_router/__init__.py +5 -0
  360. free_claude_code/providers/open_router/client.py +113 -0
  361. free_claude_code/providers/openai_api/__init__.py +5 -0
  362. free_claude_code/providers/openai_api/provider.py +150 -0
  363. free_claude_code/providers/openai_chat/__init__.py +72 -0
  364. free_claude_code/providers/openai_chat/base_url.py +7 -0
  365. free_claude_code/providers/openai_chat/behavior.py +133 -0
  366. free_claude_code/providers/openai_chat/client.py +40 -0
  367. free_claude_code/providers/openai_chat/extra_body.py +63 -0
  368. free_claude_code/providers/openai_chat/output_cap.py +161 -0
  369. free_claude_code/providers/openai_chat/profiles.py +778 -0
  370. free_claude_code/providers/openai_chat/provider.py +244 -0
  371. free_claude_code/providers/openai_chat/reasoning.py +169 -0
  372. free_claude_code/providers/openai_chat/reasoning_details.py +128 -0
  373. free_claude_code/providers/openai_chat/request_policy.py +140 -0
  374. free_claude_code/providers/openai_chat/stream_output.py +752 -0
  375. free_claude_code/providers/openai_chat/tool_calls.py +462 -0
  376. free_claude_code/providers/openai_chat/transport.py +1643 -0
  377. free_claude_code/providers/openai_chat/usage.py +117 -0
  378. free_claude_code/providers/openai_client.py +74 -0
  379. free_claude_code/providers/openai_codex/__init__.py +1 -0
  380. free_claude_code/providers/openai_codex/auth.py +626 -0
  381. free_claude_code/providers/openai_codex/endpoint.py +53 -0
  382. free_claude_code/providers/openai_codex/login.py +265 -0
  383. free_claude_code/providers/openai_codex/provider.py +259 -0
  384. free_claude_code/providers/openai_responses/__init__.py +5 -0
  385. free_claude_code/providers/openai_responses/presentation.py +115 -0
  386. free_claude_code/providers/openai_responses/transport.py +621 -0
  387. free_claude_code/providers/openai_stream.py +21 -0
  388. free_claude_code/providers/opencode/__init__.py +5 -0
  389. free_claude_code/providers/opencode/catalog.py +340 -0
  390. free_claude_code/providers/opencode/provider.py +359 -0
  391. free_claude_code/providers/reasoning_compatibility.py +199 -0
  392. free_claude_code/providers/request_recovery.py +122 -0
  393. free_claude_code/providers/runtime/__init__.py +10 -0
  394. free_claude_code/providers/runtime/config.py +91 -0
  395. free_claude_code/providers/runtime/discovery.py +63 -0
  396. free_claude_code/providers/runtime/factory.py +282 -0
  397. free_claude_code/providers/runtime/model_cache.py +93 -0
  398. free_claude_code/providers/runtime/runtime.py +108 -0
  399. free_claude_code/providers/stream_recovery.py +164 -0
  400. free_claude_code/providers/vertex/__init__.py +5 -0
  401. free_claude_code/providers/vertex/auth.py +105 -0
  402. free_claude_code/providers/vertex/client.py +140 -0
  403. free_claude_code/providers/vertex/endpoint.py +50 -0
  404. free_claude_code/providers/vertex/models.py +52 -0
  405. free_claude_code/runtime/__init__.py +1 -0
  406. free_claude_code/runtime/application.py +1121 -0
  407. free_claude_code/runtime/asgi.py +63 -0
  408. free_claude_code/runtime/bootstrap.py +153 -0
  409. free_claude_code/runtime/code_sessions_sqlite.py +785 -0
  410. free_claude_code/runtime/codex_app_server.py +775 -0
  411. free_claude_code/runtime/codex_catalog.py +62 -0
  412. free_claude_code/runtime/codex_protocol.py +662 -0
  413. free_claude_code/runtime/configuration.py +53 -0
  414. free_claude_code/runtime/folder_picker.py +134 -0
  415. free_claude_code/runtime/native_folder_dialog.py +123 -0
  416. free_claude_code/runtime/provider_manager.py +716 -0
  417. free_claude_code/runtime/retired_chat.py +47 -0
  418. free_claude_code/runtime/web_tools/__init__.py +1 -0
  419. free_claude_code/runtime/web_tools/client.py +238 -0
  420. free_claude_code/runtime/web_tools/constants.py +17 -0
  421. free_claude_code/runtime/web_tools/egress.py +89 -0
  422. free_claude_code/runtime/web_tools/parsers.py +78 -0
  423. free_claude_code-6.2.64.data/scripts/fcc-update +4 -0
  424. free_claude_code-6.2.64.data/scripts/fcc-update.cmd +5 -0
  425. free_claude_code-6.2.64.dist-info/METADATA +555 -0
  426. free_claude_code-6.2.64.dist-info/RECORD +429 -0
  427. free_claude_code-6.2.64.dist-info/WHEEL +4 -0
  428. free_claude_code-6.2.64.dist-info/entry_points.txt +15 -0
  429. free_claude_code-6.2.64.dist-info/licenses/LICENSE +239 -0
@@ -0,0 +1,980 @@
1
+ :root {
2
+ color-scheme: dark;
3
+
4
+ /* Color Palette */
5
+ --bg: #090a0f;
6
+ --panel: #11131c;
7
+ --panel-strong: #171b26;
8
+ --card: #151822;
9
+ --card-hover: #1e2230;
10
+ --input: #0a0b10;
11
+ --input-focus: #0f1118;
12
+ --text: #f3f4f6;
13
+ --text-strong: #ffffff;
14
+ --muted: #9ca3af;
15
+ --line: rgba(255, 255, 255, 0.06);
16
+ --line-strong: rgba(255, 255, 255, 0.12);
17
+
18
+ /* Brand and Accent Colors */
19
+ --accent: #10b981;
20
+ --accent-dark: #059669;
21
+ --accent-muted: rgba(16, 185, 129, 0.08);
22
+ --accent-border: rgba(16, 185, 129, 0.3);
23
+
24
+ /* Status Colors */
25
+ --ok: #10b981;
26
+ --ok-bg: rgba(16, 185, 129, 0.08);
27
+ --ok-border: rgba(16, 185, 129, 0.25);
28
+
29
+ --warn: #f59e0b;
30
+ --warn-bg: rgba(245, 158, 11, 0.08);
31
+ --warn-border: rgba(245, 158, 11, 0.25);
32
+
33
+ --error: #ef4444;
34
+ --error-bg: rgba(239, 68, 68, 0.08);
35
+ --error-border: rgba(239, 68, 68, 0.25);
36
+
37
+ --neutral: #6b7280;
38
+ --neutral-bg: rgba(107, 114, 128, 0.08);
39
+ --neutral-border: rgba(107, 114, 128, 0.25);
40
+
41
+ --info: #3b82f6;
42
+
43
+ /* Box Shadow & Glows */
44
+ --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
45
+ --shadow: 0 12px 34px rgba(0, 0, 0, 0.5);
46
+ --glow-accent: 0 0 12px rgba(16, 185, 129, 0.15);
47
+
48
+ /* Borders and Radius */
49
+ --radius-sm: 6px;
50
+ --radius-md: 10px;
51
+ --radius-lg: 14px;
52
+ --radius-full: 9999px;
53
+ --dropdown-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af' stroke-width='2.5'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M19.5 8.25l-7.5 7.5-7.5-7.5'/%3E%3C/svg%3E");
54
+
55
+ /* Typography */
56
+ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
57
+
58
+ /* Transitions */
59
+ --transition-fast: 0.15s ease;
60
+ --transition-normal: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
61
+ }
62
+
63
+ * {
64
+ box-sizing: border-box;
65
+ }
66
+
67
+ [hidden] {
68
+ display: none !important;
69
+ }
70
+
71
+ body {
72
+ margin: 0;
73
+ min-width: 320px;
74
+ background: var(--bg);
75
+ color: var(--text);
76
+ font-family: var(--font-sans);
77
+ letter-spacing: -0.01em;
78
+ -webkit-font-smoothing: antialiased;
79
+ -moz-osx-font-smoothing: grayscale;
80
+ }
81
+
82
+ /* Custom Scrollbars */
83
+ ::-webkit-scrollbar {
84
+ width: 8px;
85
+ height: 8px;
86
+ }
87
+ ::-webkit-scrollbar-track {
88
+ background: var(--bg);
89
+ }
90
+ ::-webkit-scrollbar-thumb {
91
+ background: var(--panel-strong);
92
+ border-radius: var(--radius-full);
93
+ }
94
+ ::-webkit-scrollbar-thumb:hover {
95
+ background: var(--muted);
96
+ }
97
+
98
+ button,
99
+ input,
100
+ select,
101
+ textarea {
102
+ font: inherit;
103
+ color: inherit;
104
+ }
105
+
106
+ /* App Shell Layout */
107
+ .app-shell {
108
+ display: grid;
109
+ grid-template-columns: 260px minmax(0, 1fr);
110
+ min-height: 100vh;
111
+ }
112
+
113
+ /* Sidebar Navigation */
114
+ .sidebar {
115
+ position: sticky;
116
+ top: 0;
117
+ height: 100vh;
118
+ border-right: 1px solid var(--line);
119
+ background: var(--bg);
120
+ padding: 24px 20px;
121
+ display: flex;
122
+ flex-direction: column;
123
+ gap: 32px;
124
+ }
125
+
126
+ .brand {
127
+ display: flex;
128
+ align-items: center;
129
+ gap: 12px;
130
+ }
131
+
132
+ .brand-mark {
133
+ display: block;
134
+ flex: 0 0 auto;
135
+ width: 40px;
136
+ height: 40px;
137
+ }
138
+
139
+ .brand-mark img {
140
+ display: block;
141
+ width: 100%;
142
+ height: 100%;
143
+ }
144
+
145
+ .brand h1 {
146
+ font-size: 16px;
147
+ font-weight: 700;
148
+ line-height: 1.2;
149
+ color: var(--text-strong);
150
+ margin: 0;
151
+ }
152
+
153
+ .brand p {
154
+ color: var(--muted);
155
+ font-size: 12px;
156
+ margin: 0;
157
+ }
158
+
159
+ .section-nav {
160
+ display: grid;
161
+ gap: 6px;
162
+ }
163
+
164
+ .nav-link {
165
+ display: flex;
166
+ align-items: center;
167
+ width: 100%;
168
+ min-height: 40px;
169
+ border: 1px solid transparent;
170
+ border-radius: var(--radius-md);
171
+ background: transparent;
172
+ color: var(--muted);
173
+ padding: 10px 14px;
174
+ text-align: left;
175
+ cursor: pointer;
176
+ font-weight: 600;
177
+ font-size: 14px;
178
+ transition: all var(--transition-fast);
179
+ }
180
+
181
+ .nav-link:hover {
182
+ background: var(--panel-strong);
183
+ color: var(--text-strong);
184
+ }
185
+
186
+ .nav-link.active {
187
+ background: var(--accent-muted);
188
+ border-color: var(--accent-border);
189
+ color: var(--accent);
190
+ box-shadow: var(--shadow-sm);
191
+ }
192
+
193
+ /* Accessible focus outlines */
194
+ button:focus-visible,
195
+ input:focus-visible,
196
+ select:focus-visible,
197
+ textarea:focus-visible,
198
+ .brand-mark:focus-visible,
199
+ .nav-link:focus-visible {
200
+ outline: 2px solid var(--accent);
201
+ outline-offset: 2px;
202
+ }
203
+
204
+ /* Main Content Area */
205
+ .main {
206
+ min-width: 0;
207
+ padding: 40px 48px;
208
+ padding-bottom: calc(40px + var(--action-bar-height, 0px));
209
+ }
210
+
211
+ .topbar {
212
+ margin-bottom: 32px;
213
+ }
214
+
215
+ .topbar h2 {
216
+ font-size: 30px;
217
+ font-weight: 800;
218
+ line-height: 1;
219
+ letter-spacing: -0.02em;
220
+ color: var(--text-strong);
221
+ margin: calc((1cap - 1em) / 2) 0 0;
222
+ }
223
+
224
+ /* Provider Strip & Panels */
225
+ .provider-strip,
226
+ .settings-section {
227
+ border: 1px solid var(--line);
228
+ border-radius: var(--radius-lg);
229
+ background: var(--panel);
230
+ box-shadow: var(--shadow);
231
+ margin-bottom: 24px;
232
+ transition: border-color var(--transition-normal);
233
+ }
234
+
235
+ .provider-strip {
236
+ padding: 24px;
237
+ }
238
+
239
+ .strip-header,
240
+ .section-heading {
241
+ display: flex;
242
+ align-items: flex-start;
243
+ justify-content: space-between;
244
+ gap: 16px;
245
+ margin-bottom: 20px;
246
+ }
247
+
248
+ .strip-header h3,
249
+ .section-heading h3 {
250
+ font-size: 18px;
251
+ font-weight: 700;
252
+ color: var(--text-strong);
253
+ margin: 0;
254
+ }
255
+
256
+ .section-heading p {
257
+ color: var(--muted);
258
+ font-size: 13px;
259
+ line-height: 1.4;
260
+ margin: 4px 0 0 0;
261
+ }
262
+
263
+ .integration-card {
264
+ display: flex;
265
+ flex-direction: column;
266
+ align-items: flex-start;
267
+ margin-bottom: 0;
268
+ }
269
+ .integration-card > button {
270
+ display: inline-flex;
271
+ align-items: center;
272
+ gap: 8px;
273
+ margin-top: auto;
274
+ }
275
+ .integration-card > button,
276
+ .provider-card > .provider-actions > button {
277
+ min-height: 38px;
278
+ padding: 6px 14px;
279
+ font-size: 13px;
280
+ }
281
+ .integration-card > button[aria-busy="true"]::before,
282
+ button.startup-busy::before,
283
+ .startup-spinner::before {
284
+ content: "";
285
+ width: 12px;
286
+ height: 12px;
287
+ border: 2px solid currentColor;
288
+ border-right-color: transparent;
289
+ border-radius: 50%;
290
+ animation: integration-spinner 0.8s linear infinite;
291
+ }
292
+ @keyframes integration-spinner {
293
+ to { transform: rotate(360deg); }
294
+ }
295
+ @media (prefers-reduced-motion: reduce) {
296
+ .integration-card > button[aria-busy="true"]::before { animation: none; }
297
+ }
298
+ .integration-card h3 { min-height: 2lh; }
299
+ .integration-dialog {
300
+ width: min(480px, calc(100vw - 32px));
301
+ max-height: calc(100vh - 32px);
302
+ padding: 24px;
303
+ border: 1px solid var(--line-strong);
304
+ border-radius: var(--radius-lg);
305
+ background: var(--panel);
306
+ color: var(--text);
307
+ box-shadow: var(--shadow);
308
+ }
309
+ .integration-dialog::backdrop { background: rgba(0, 0, 0, 0.7); }
310
+ .integration-card .section-heading,
311
+ .integration-dialog .section-heading { border-bottom: 0; padding-bottom: 0; }
312
+ .integration-dialog .section-heading { align-items: center; }
313
+ .integration-dialog p { color: var(--muted); line-height: 1.6; margin: 0 0 24px; }
314
+ .integration-files { margin-bottom: 24px; font-size: 12px; color: var(--muted); }
315
+ .integration-files ul { margin: 8px 0 0; padding-left: 20px; }
316
+ .integration-files code { overflow-wrap: anywhere; }
317
+
318
+ /* Provider Status Cards */
319
+ .provider-grid {
320
+ display: grid;
321
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
322
+ gap: 16px;
323
+ }
324
+
325
+ .provider-card {
326
+ display: flex;
327
+ flex-direction: column;
328
+ gap: 16px;
329
+ min-height: 140px;
330
+ border: 1px solid var(--line);
331
+ border-radius: var(--radius-md);
332
+ padding: 16px;
333
+ background: var(--card);
334
+ color: var(--text);
335
+ font: inherit;
336
+ text-align: left;
337
+ }
338
+
339
+ .provider-card > .provider-actions { margin-top: auto; }
340
+ .provider-card .provider-title { min-height: 2lh; }
341
+
342
+ [data-provider-group] > h3 { margin: 0 0 20px; }
343
+ [data-provider-subgroup] + [data-provider-subgroup] { margin-top: 24px; }
344
+ [data-provider-subgroup] > h4 {
345
+ margin: 0 0 12px;
346
+ color: var(--muted);
347
+ font-size: 13px;
348
+ font-weight: 500;
349
+ }
350
+ .provider-dialog { width: min(600px, calc(100vw - 32px)); }
351
+ .provider-dialog .section-heading { display: flex; justify-content: space-between; }
352
+ .provider-dialog .section-heading h3 { margin: 0; }
353
+ .provider-dialog .field-grid { grid-template-columns: minmax(0, 1fr); }
354
+ .provider-dialog .field.advanced-field { display: flex; }
355
+ .provider-dialog .provider-actions:not(:empty),
356
+ .provider-dialog .provider-check-result:not([hidden]) { margin-bottom: 20px; }
357
+ .provider-dialog .message-area:empty { display: none; }
358
+ .provider-dialog-footer { display: flex; justify-content: flex-end; gap: 12px; margin-top: 24px; }
359
+
360
+ .provider-title {
361
+ display: flex;
362
+ align-items: center;
363
+ justify-content: space-between;
364
+ gap: 12px;
365
+ flex-wrap: wrap;
366
+ }
367
+
368
+ .provider-title strong {
369
+ font-size: 14px;
370
+ font-weight: 700;
371
+ color: var(--text-strong);
372
+ }
373
+
374
+ .provider-title a {
375
+ display: inline-flex;
376
+ align-items: center;
377
+ gap: 8px;
378
+ max-width: 100%;
379
+ color: var(--text-strong);
380
+ text-decoration: none;
381
+ }
382
+ .provider-title a:hover { text-decoration: underline; text-underline-offset: 3px; }
383
+ .provider-title a:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
384
+ .provider-logo { width: 20px; height: 20px; flex: none; object-fit: contain; }
385
+
386
+ .provider-meta {
387
+ color: var(--muted);
388
+ font-size: 12px;
389
+ line-height: 1.4;
390
+ overflow-wrap: anywhere;
391
+ }
392
+
393
+ .provider-check-result {
394
+ color: var(--muted);
395
+ font-size: 12px;
396
+ line-height: 1.4;
397
+ overflow-wrap: anywhere;
398
+ }
399
+
400
+ .provider-check-result.ok {
401
+ color: var(--ok);
402
+ }
403
+
404
+ .provider-check-result.error {
405
+ color: var(--error);
406
+ }
407
+
408
+ .provider-meta.error { color: var(--error); }
409
+
410
+ .provider-check-result.checking {
411
+ color: var(--info);
412
+ }
413
+
414
+ .provider-actions {
415
+ display: flex;
416
+ flex-wrap: wrap;
417
+ gap: 0.55rem;
418
+ align-items: center;
419
+ }
420
+
421
+ /* Button & Form Controls styling */
422
+ .test-button,
423
+ .ghost-button,
424
+ .secondary-button,
425
+ .primary-button {
426
+ display: inline-flex;
427
+ align-items: center;
428
+ justify-content: center;
429
+ min-height: 36px;
430
+ border-radius: var(--radius-md);
431
+ border: 1px solid var(--line-strong);
432
+ padding: 6px 14px;
433
+ font-weight: 600;
434
+ font-size: 13px;
435
+ cursor: pointer;
436
+ transition: all var(--transition-fast);
437
+ text-decoration: none;
438
+ }
439
+
440
+ .test-button {
441
+ background: var(--panel-strong);
442
+ color: var(--text);
443
+ border-color: var(--line);
444
+ margin-top: auto;
445
+ align-self: flex-start;
446
+ }
447
+
448
+ .test-button:hover:not(:disabled) {
449
+ background: var(--card-hover);
450
+ border-color: var(--accent);
451
+ color: var(--accent);
452
+ }
453
+
454
+ .test-button:disabled {
455
+ opacity: 0.6;
456
+ cursor: not-allowed;
457
+ }
458
+
459
+ .secondary-button {
460
+ background: transparent;
461
+ color: var(--text);
462
+ border-color: var(--line-strong);
463
+ }
464
+
465
+ .secondary-button:hover:not(:disabled) {
466
+ background: var(--panel-strong);
467
+ border-color: var(--text);
468
+ }
469
+
470
+ .primary-button {
471
+ border-color: var(--accent);
472
+ background: var(--accent);
473
+ color: #06100b;
474
+ }
475
+
476
+ .primary-button:hover:not(:disabled) {
477
+ background: var(--accent-dark);
478
+ }
479
+
480
+ .primary-button:disabled {
481
+ cursor: not-allowed;
482
+ border-color: var(--line);
483
+ background: var(--panel-strong);
484
+ color: var(--muted);
485
+ }
486
+
487
+ .ghost-button {
488
+ background: transparent;
489
+ color: var(--muted);
490
+ border-color: transparent;
491
+ }
492
+
493
+ .ghost-button:hover:not(:disabled) {
494
+ color: var(--text-strong);
495
+ background: var(--panel-strong);
496
+ }
497
+
498
+ /* Forms layout */
499
+ .form-sections {
500
+ display: grid;
501
+ gap: 24px;
502
+ }
503
+
504
+ .form-sections > .settings-section:last-child {
505
+ margin-bottom: 0;
506
+ }
507
+
508
+ .settings-section {
509
+ padding: 24px;
510
+ scroll-margin-top: 24px;
511
+ }
512
+
513
+ .section-heading {
514
+ border-bottom: 1px solid var(--line);
515
+ padding-bottom: 16px;
516
+ margin-bottom: 24px;
517
+ }
518
+
519
+ .field-grid {
520
+ display: grid;
521
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
522
+ gap: 20px;
523
+ }
524
+
525
+ /* Field Grouping */
526
+ .field {
527
+ display: flex;
528
+ flex-direction: column;
529
+ gap: 8px;
530
+ align-content: start;
531
+ }
532
+
533
+ .field label {
534
+ display: flex;
535
+ align-items: center;
536
+ justify-content: space-between;
537
+ gap: 8px;
538
+ font-size: 13px;
539
+ font-weight: 700;
540
+ color: var(--text-strong);
541
+ }
542
+
543
+ .field-source {
544
+ color: var(--accent);
545
+ font-size: 11px;
546
+ font-weight: 700;
547
+ text-transform: uppercase;
548
+ letter-spacing: 0.05em;
549
+ background: var(--accent-muted);
550
+ padding: 1px 6px;
551
+ border-radius: var(--radius-sm);
552
+ }
553
+
554
+ /* Form Inputs, Select, Textareas */
555
+ .field input[type="text"],
556
+ .field input[type="number"],
557
+ .field input[type="password"],
558
+ .field select,
559
+ .field textarea {
560
+ width: 100%;
561
+ min-height: 40px;
562
+ border: 1px solid var(--line-strong);
563
+ border-radius: var(--radius-md);
564
+ background: var(--input);
565
+ color: var(--text-strong);
566
+ padding: 10px 14px;
567
+ font-size: 14px;
568
+ transition: all var(--transition-fast);
569
+ }
570
+
571
+ /* Custom Dropdown Styling for Select Elements */
572
+ .field select {
573
+ appearance: none;
574
+ -webkit-appearance: none;
575
+ -moz-appearance: none;
576
+ background-image: var(--dropdown-chevron);
577
+ background-repeat: no-repeat;
578
+ background-position: right 14px center;
579
+ background-size: 14px;
580
+ padding-right: 36px;
581
+ }
582
+
583
+ .model-combobox {
584
+ position: relative;
585
+ width: 100%;
586
+ }
587
+
588
+ .model-combobox.open {
589
+ z-index: 110;
590
+ }
591
+
592
+ .field .model-combobox input[type="text"] {
593
+ padding-right: 44px;
594
+ }
595
+
596
+ .model-combobox-toggle {
597
+ position: absolute;
598
+ top: 0;
599
+ right: 0;
600
+ display: grid;
601
+ width: 42px;
602
+ height: 40px;
603
+ place-items: center;
604
+ border: 0;
605
+ background: transparent;
606
+ cursor: pointer;
607
+ }
608
+
609
+ .model-combobox-toggle::before {
610
+ width: 14px;
611
+ height: 14px;
612
+ background-image: var(--dropdown-chevron);
613
+ background-position: center;
614
+ background-repeat: no-repeat;
615
+ background-size: 14px;
616
+ content: "";
617
+ transition: transform var(--transition-fast);
618
+ }
619
+
620
+ .model-combobox-toggle[aria-expanded="true"]::before {
621
+ transform: rotate(180deg);
622
+ }
623
+
624
+ .model-combobox-toggle:disabled {
625
+ cursor: not-allowed;
626
+ opacity: 0.5;
627
+ }
628
+
629
+ .model-combobox-list {
630
+ position: absolute;
631
+ top: calc(100% + 6px);
632
+ right: 0;
633
+ left: 0;
634
+ z-index: 120;
635
+ max-height: 280px;
636
+ overflow-y: auto;
637
+ overscroll-behavior: contain;
638
+ border: 1px solid var(--line-strong);
639
+ border-radius: var(--radius-md);
640
+ background: var(--panel-strong);
641
+ box-shadow: var(--shadow);
642
+ padding: 6px;
643
+ }
644
+
645
+ .model-combobox-option {
646
+ border-radius: var(--radius-sm);
647
+ padding: 9px 10px;
648
+ color: var(--text);
649
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
650
+ font-size: 12px;
651
+ line-height: 1.35;
652
+ overflow-wrap: anywhere;
653
+ cursor: pointer;
654
+ }
655
+
656
+ .model-combobox-option:hover,
657
+ .model-combobox-option.active {
658
+ background: var(--accent-muted);
659
+ color: var(--accent);
660
+ }
661
+
662
+ .model-combobox-empty {
663
+ padding: 10px;
664
+ color: var(--muted);
665
+ font-size: 12px;
666
+ line-height: 1.4;
667
+ }
668
+
669
+ .field[data-key="MODEL_FALLBACKS"] {
670
+ grid-column: 1 / -1;
671
+ }
672
+
673
+ .model-list-editor,
674
+ .model-list-rows {
675
+ display: grid;
676
+ gap: 8px;
677
+ }
678
+
679
+ .model-list-add {
680
+ display: grid;
681
+ grid-template-columns: minmax(0, 1fr) auto;
682
+ gap: 8px;
683
+ align-items: start;
684
+ }
685
+
686
+ .model-list-row {
687
+ display: grid;
688
+ grid-template-columns: minmax(0, 1fr) auto auto auto;
689
+ gap: 4px;
690
+ align-items: center;
691
+ min-height: 44px;
692
+ padding: 6px 8px 6px 12px;
693
+ border: 1px solid var(--line);
694
+ border-radius: var(--radius-md);
695
+ background: var(--panel-strong);
696
+ }
697
+
698
+ .model-list-value {
699
+ min-width: 0;
700
+ overflow-wrap: anywhere;
701
+ color: var(--text-strong);
702
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
703
+ font-size: 13px;
704
+ }
705
+
706
+ .model-list-action {
707
+ min-height: 32px;
708
+ padding: 4px 8px;
709
+ }
710
+
711
+ .model-list-editor button:disabled {
712
+ cursor: not-allowed;
713
+ opacity: 0.45;
714
+ }
715
+
716
+ .model-list-empty {
717
+ padding: 8px 2px;
718
+ color: var(--muted);
719
+ font-size: 13px;
720
+ }
721
+
722
+ .field input:focus,
723
+ .field select:focus,
724
+ .field textarea:focus {
725
+ border-color: var(--accent);
726
+ background: var(--input-focus);
727
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
728
+ outline: none;
729
+ }
730
+
731
+ /* Checkbox specific layout styling */
732
+ .field input[type="checkbox"] {
733
+ align-self: flex-start;
734
+ width: 20px;
735
+ height: 20px;
736
+ accent-color: var(--accent);
737
+ cursor: pointer;
738
+ margin: 4px 0;
739
+ }
740
+
741
+ .field textarea {
742
+ min-height: 100px;
743
+ resize: vertical;
744
+ line-height: 1.5;
745
+ }
746
+
747
+ .field input:disabled,
748
+ .field select:disabled,
749
+ .field textarea:disabled {
750
+ background: rgba(255, 255, 255, 0.02);
751
+ border-color: var(--line);
752
+ color: var(--muted);
753
+ cursor: not-allowed;
754
+ }
755
+
756
+ .field-description {
757
+ color: var(--muted);
758
+ font-size: 12px;
759
+ line-height: 1.4;
760
+ margin-top: 2px;
761
+ }
762
+
763
+ /* Show/Hide Advanced fields */
764
+ .field.advanced-field {
765
+ display: none;
766
+ }
767
+
768
+ .settings-section.show-advanced .advanced-field {
769
+ display: flex;
770
+ }
771
+
772
+ .advanced-toggle {
773
+ margin-top: 20px;
774
+ font-size: 12px;
775
+ border: 1px solid var(--line-strong);
776
+ }
777
+
778
+ /* Fixed Bottom Action Bar */
779
+ .action-bar {
780
+ position: fixed;
781
+ right: 0;
782
+ bottom: 0;
783
+ left: 260px;
784
+ z-index: 100;
785
+ display: grid;
786
+ grid-template-columns: minmax(0, 1.2fr) minmax(200px, 1fr) auto;
787
+ gap: 20px;
788
+ align-items: center;
789
+ min-height: 80px;
790
+ border-top: 1px solid var(--line);
791
+ background: rgba(9, 10, 15, 0.82);
792
+ padding: 16px 40px;
793
+ backdrop-filter: blur(20px);
794
+ -webkit-backdrop-filter: blur(20px);
795
+ box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.3);
796
+ }
797
+
798
+ .action-meta {
799
+ display: flex;
800
+ flex-direction: column;
801
+ gap: 4px;
802
+ min-width: 0;
803
+ }
804
+
805
+ .action-meta strong {
806
+ font-size: 14px;
807
+ font-weight: 700;
808
+ color: var(--text-strong);
809
+ white-space: nowrap;
810
+ overflow: hidden;
811
+ text-overflow: ellipsis;
812
+ }
813
+
814
+ .action-meta span {
815
+ color: var(--muted);
816
+ font-size: 11px;
817
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
818
+ white-space: nowrap;
819
+ overflow: hidden;
820
+ text-overflow: ellipsis;
821
+ }
822
+
823
+ .message-area {
824
+ min-width: 0;
825
+ color: var(--muted);
826
+ font-size: 13px;
827
+ font-weight: 500;
828
+ line-height: 1.4;
829
+ }
830
+
831
+ .message-area.error {
832
+ color: var(--error);
833
+ font-weight: 600;
834
+ }
835
+
836
+ .message-area.ok {
837
+ color: var(--ok);
838
+ font-weight: 600;
839
+ }
840
+
841
+ .message-area.warn {
842
+ color: var(--warn);
843
+ font-weight: 600;
844
+ }
845
+
846
+ .action-buttons {
847
+ display: flex;
848
+ gap: 12px;
849
+ }
850
+
851
+ .action-buttons button {
852
+ min-width: 100px;
853
+ }
854
+
855
+ /* Tablet Layout Optimization */
856
+ @media (max-width: 900px) {
857
+ .app-shell {
858
+ display: flex;
859
+ flex-direction: column;
860
+ }
861
+
862
+ .sidebar {
863
+ position: relative;
864
+ height: auto;
865
+ border-right: 0;
866
+ border-bottom: 1px solid var(--line);
867
+ padding: 20px;
868
+ gap: 20px;
869
+ }
870
+
871
+ .section-nav {
872
+ grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
873
+ }
874
+
875
+ .main {
876
+ padding: 24px 20px;
877
+ padding-bottom: calc(24px + var(--action-bar-height, 0px));
878
+ }
879
+
880
+ .action-bar {
881
+ left: 0;
882
+ grid-template-columns: 1fr;
883
+ gap: 12px;
884
+ padding: 16px 20px;
885
+ min-height: auto;
886
+ background: rgba(9, 10, 15, 0.95);
887
+ }
888
+
889
+ .action-meta {
890
+ flex-direction: row;
891
+ justify-content: space-between;
892
+ align-items: center;
893
+ }
894
+
895
+ .action-meta span {
896
+ text-align: right;
897
+ }
898
+
899
+ .action-buttons {
900
+ width: 100%;
901
+ }
902
+
903
+ .action-buttons button {
904
+ flex: 1;
905
+ min-height: 44px; /* Better touch target on mobile */
906
+ }
907
+ }
908
+
909
+ /* Mobile Layout Optimization */
910
+ @media (max-width: 600px) {
911
+ .brand {
912
+ justify-content: center;
913
+ text-align: center;
914
+ flex-direction: column;
915
+ }
916
+
917
+ .brand-mark {
918
+ width: 48px;
919
+ height: 48px;
920
+ }
921
+
922
+ .section-nav {
923
+ grid-template-columns: 1fr;
924
+ }
925
+
926
+ .topbar {
927
+ text-align: center;
928
+ }
929
+
930
+ .topbar h2 {
931
+ font-size: 24px;
932
+ }
933
+
934
+ .provider-grid {
935
+ grid-template-columns: 1fr;
936
+ }
937
+
938
+ .field-grid {
939
+ grid-template-columns: 1fr;
940
+ }
941
+
942
+ .model-list-add {
943
+ grid-template-columns: 1fr;
944
+ }
945
+
946
+ .model-list-row {
947
+ grid-template-columns: 1fr repeat(3, auto);
948
+ }
949
+
950
+ .action-meta {
951
+ flex-direction: column;
952
+ align-items: stretch;
953
+ gap: 2px;
954
+ }
955
+
956
+ .action-meta span {
957
+ text-align: left;
958
+ }
959
+ }
960
+ .field-error {
961
+ color: var(--danger, #ef4444);
962
+ font-size: 13px;
963
+ }
964
+
965
+ .field [aria-invalid="true"] {
966
+ border-color: var(--danger, #ef4444);
967
+ }
968
+
969
+ #messageArea {
970
+ white-space: pre-line;
971
+ }
972
+
973
+ .page-heading { display: flex; align-items: center; gap: 12px; }
974
+ .startup-message { font-size: 13px; color: var(--muted); }
975
+ .startup-message.error { color: var(--error); }
976
+ button.startup-busy, .startup-spinner { display: inline-flex; align-items: center; gap: 8px; }
977
+ .startup-spinner[hidden] { display: none; }
978
+ @media (prefers-reduced-motion: reduce) {
979
+ button.startup-busy::before, .startup-spinner::before { animation: none; }
980
+ }