superqode 0.1.8__tar.gz → 0.1.10__tar.gz

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 (308) hide show
  1. {superqode-0.1.8/src/superqode.egg-info → superqode-0.1.10}/PKG-INFO +1 -1
  2. {superqode-0.1.8 → superqode-0.1.10}/pyproject.toml +1 -1
  3. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/__init__.py +1 -1
  4. superqode-0.1.10/src/superqode/agents/data/ampcode.com.toml +69 -0
  5. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/registry.py +13 -0
  6. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app_main.py +12 -3
  7. superqode-0.1.10/src/superqode/auth/__init__.py +264 -0
  8. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/acp.py +109 -109
  9. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/auth.py +134 -12
  10. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/execution/resolver.py +40 -2
  11. {superqode-0.1.8 → superqode-0.1.10/src/superqode.egg-info}/PKG-INFO +1 -1
  12. {superqode-0.1.8 → superqode-0.1.10}/src/superqode.egg-info/SOURCES.txt +3 -0
  13. superqode-0.1.10/tests/test_auth.py +181 -0
  14. {superqode-0.1.8 → superqode-0.1.10}/LICENSE +0 -0
  15. {superqode-0.1.8 → superqode-0.1.10}/README.md +0 -0
  16. {superqode-0.1.8 → superqode-0.1.10}/setup.cfg +0 -0
  17. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/acp/__init__.py +0 -0
  18. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/acp/client.py +0 -0
  19. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/acp/permission_screen.py +0 -0
  20. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/acp/types.py +0 -0
  21. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/acp_discovery.py +0 -0
  22. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent/__init__.py +0 -0
  23. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent/edit_strategies.py +0 -0
  24. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent/loop.py +0 -0
  25. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent/qe_report_templates.py +0 -0
  26. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent/system_prompts.py +0 -0
  27. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent_output.py +0 -0
  28. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agent_stream.py +0 -0
  29. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/__init__.py +0 -0
  30. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/acp_registry.py +0 -0
  31. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/client.py +0 -0
  32. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/augmentcode.com.toml +0 -0
  33. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/cagent.dev.toml +0 -0
  34. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/claude.com.toml +0 -0
  35. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/codeassistant.dev.toml +0 -0
  36. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/codex.openai.com.toml +0 -0
  37. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/fastagent.ai.toml +0 -0
  38. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/geminicli.com.toml +0 -0
  39. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/goose.block.xyz.toml +0 -0
  40. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/junie.jetbrains.com.toml +0 -0
  41. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/kimi.moonshot.cn.toml +0 -0
  42. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/llmlingagent.dev.toml +0 -0
  43. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/molt.bot.toml +0 -0
  44. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/opencode.ai.toml +0 -0
  45. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/stakpak.dev.toml +0 -0
  46. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/data/vtcode.dev.toml +0 -0
  47. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/discovery.py +0 -0
  48. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/messaging.py +0 -0
  49. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/persona.py +0 -0
  50. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/schema.py +0 -0
  51. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/agents/unified.py +0 -0
  52. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/__init__.py +0 -0
  53. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/constants.py +0 -0
  54. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/css.py +0 -0
  55. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/models.py +0 -0
  56. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/suggester.py +0 -0
  57. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app/widgets.py +0 -0
  58. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/app_enhanced.py +0 -0
  59. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/approval.py +0 -0
  60. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/atomic.py +0 -0
  61. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/__init__.py +0 -0
  62. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/agents.py +0 -0
  63. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/config.py +0 -0
  64. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/init.py +0 -0
  65. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/providers.py +0 -0
  66. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/qe.py +0 -0
  67. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/roles.py +0 -0
  68. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/serve.py +0 -0
  69. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/suggestions.py +0 -0
  70. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/commands/superqe.py +0 -0
  71. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/config/__init__.py +0 -0
  72. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/config/loader.py +0 -0
  73. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/config/schema.py +0 -0
  74. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/core/__init__.py +0 -0
  75. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/core/roles.py +0 -0
  76. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/danger.py +0 -0
  77. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/data/superqode-template.yaml +0 -0
  78. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/design_system.py +0 -0
  79. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/dialogs/__init__.py +0 -0
  80. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/dialogs/base.py +0 -0
  81. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/dialogs/model.py +0 -0
  82. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/dialogs/provider.py +0 -0
  83. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/diff_view.py +0 -0
  84. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/enterprise.py +0 -0
  85. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/evaluation/__init__.py +0 -0
  86. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/evaluation/adapters.py +0 -0
  87. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/evaluation/behaviors.py +0 -0
  88. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/evaluation/engine.py +0 -0
  89. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/evaluation/scenarios.py +0 -0
  90. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/execution/__init__.py +0 -0
  91. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/execution/linter.py +0 -0
  92. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/execution/modes.py +0 -0
  93. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/execution/runner.py +0 -0
  94. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/file_explorer.py +0 -0
  95. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/file_viewer.py +0 -0
  96. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/flash.py +0 -0
  97. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/guidance/__init__.py +0 -0
  98. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/guidance/config.py +0 -0
  99. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/guidance/prompts.py +0 -0
  100. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/harness/__init__.py +0 -0
  101. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/harness/accelerator.py +0 -0
  102. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/harness/config.py +0 -0
  103. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/harness/validator.py +0 -0
  104. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/history.py +0 -0
  105. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/integrations/superopt_runner.py +0 -0
  106. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/__init__.py +0 -0
  107. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/adapters.py +0 -0
  108. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/formatter.py +0 -0
  109. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/integration.py +0 -0
  110. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/sinks.py +0 -0
  111. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/logging/unified_log.py +0 -0
  112. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/lsp/__init__.py +0 -0
  113. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/lsp/client.py +0 -0
  114. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/main.py +0 -0
  115. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/__init__.py +0 -0
  116. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/auth_storage.py +0 -0
  117. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/client.py +0 -0
  118. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/config.py +0 -0
  119. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/integration.py +0 -0
  120. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/oauth.py +0 -0
  121. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/oauth_callback.py +0 -0
  122. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/mcp/types.py +0 -0
  123. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/memory/__init__.py +0 -0
  124. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/memory/feedback.py +0 -0
  125. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/memory/store.py +0 -0
  126. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/notifications.py +0 -0
  127. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/optimization/__init__.py +0 -0
  128. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/optimization/config.py +0 -0
  129. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/permissions/__init__.py +0 -0
  130. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/permissions/rules.py +0 -0
  131. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/plan.py +0 -0
  132. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/__init__.py +0 -0
  133. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/gateway/__init__.py +0 -0
  134. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/gateway/base.py +0 -0
  135. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/gateway/litellm_gateway.py +0 -0
  136. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/gateway/openresponses_gateway.py +0 -0
  137. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/health.py +0 -0
  138. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/__init__.py +0 -0
  139. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/downloader.py +0 -0
  140. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/endpoints.py +0 -0
  141. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/hub.py +0 -0
  142. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/inference.py +0 -0
  143. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/huggingface/transformers_runner.py +0 -0
  144. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/__init__.py +0 -0
  145. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/base.py +0 -0
  146. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/discovery.py +0 -0
  147. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/lmstudio.py +0 -0
  148. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/mlx.py +0 -0
  149. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/ollama.py +0 -0
  150. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/sglang.py +0 -0
  151. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/tgi.py +0 -0
  152. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/tool_support.py +0 -0
  153. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/local/vllm.py +0 -0
  154. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/manager.py +0 -0
  155. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/models.py +0 -0
  156. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/models_dev.py +0 -0
  157. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/__init__.py +0 -0
  158. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/__init__.py +0 -0
  159. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/messages.py +0 -0
  160. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/tools.py +0 -0
  161. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/schema/__init__.py +0 -0
  162. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/schema/models.py +0 -0
  163. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/streaming/__init__.py +0 -0
  164. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/streaming/parser.py +0 -0
  165. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/__init__.py +0 -0
  166. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/apply_patch.py +0 -0
  167. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/code_interpreter.py +0 -0
  168. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/file_search.py +0 -0
  169. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/mcp_adapter.py +0 -0
  170. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/registry.py +0 -0
  171. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/providers/usage.py +0 -0
  172. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/pure_mode.py +0 -0
  173. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/qr/__init__.py +0 -0
  174. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/qr/dashboard.py +0 -0
  175. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/qr/generator.py +0 -0
  176. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/qr/templates.py +0 -0
  177. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/safety/__init__.py +0 -0
  178. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/safety/sandbox.py +0 -0
  179. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/safety/warnings.py +0 -0
  180. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/server/__init__.py +0 -0
  181. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/server/lsp_server.py +0 -0
  182. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/server/web.py +0 -0
  183. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/session/__init__.py +0 -0
  184. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/session/persistence.py +0 -0
  185. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/session/sharing.py +0 -0
  186. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/session.py +0 -0
  187. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/sidebar.py +0 -0
  188. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/stream_view.py +0 -0
  189. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/styles/__init__.py +0 -0
  190. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/__init__.py +0 -0
  191. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/acp_runner.py +0 -0
  192. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/constitution/__init__.py +0 -0
  193. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/constitution/evaluator.py +0 -0
  194. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/constitution/loader.py +0 -0
  195. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/constitution/schema.py +0 -0
  196. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/events.py +0 -0
  197. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/__init__.py +0 -0
  198. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/base.py +0 -0
  199. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/e2e.py +0 -0
  200. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/executor.py +0 -0
  201. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/javascript.py +0 -0
  202. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/python.py +0 -0
  203. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/frameworks/registry.py +0 -0
  204. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/__init__.py +0 -0
  205. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/core_tools.py +0 -0
  206. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/registry.py +0 -0
  207. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/testing_tools.py +0 -0
  208. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/noise.py +0 -0
  209. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/orchestrator.py +0 -0
  210. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/roles.py +0 -0
  211. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/session.py +0 -0
  212. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/skills/__init__.py +0 -0
  213. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/skills/base.py +0 -0
  214. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/skills/core_skills.py +0 -0
  215. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/skills/registry.py +0 -0
  216. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe/verifier.py +0 -0
  217. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/superqe_cli.py +0 -0
  218. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tool_call.py +0 -0
  219. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/__init__.py +0 -0
  220. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/agent_tools.py +0 -0
  221. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/base.py +0 -0
  222. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/batch_tool.py +0 -0
  223. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/diagnostics.py +0 -0
  224. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/edit_tools.py +0 -0
  225. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/enhanced_base.py +0 -0
  226. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/file_tools.py +0 -0
  227. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/file_tracking.py +0 -0
  228. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/lsp_tools.py +0 -0
  229. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/network_tools.py +0 -0
  230. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/permissions.py +0 -0
  231. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/question_tool.py +0 -0
  232. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/search_tools.py +0 -0
  233. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/shell_tools.py +0 -0
  234. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/todo_tools.py +0 -0
  235. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/validation.py +0 -0
  236. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tools/web_tools.py +0 -0
  237. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui.py +0 -0
  238. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui_integration.py +0 -0
  239. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui_widgets/__init__.py +0 -0
  240. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/__init__.py +0 -0
  241. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/progress.py +0 -0
  242. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/tool_display.py +0 -0
  243. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/undo_manager.py +0 -0
  244. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/utils/__init__.py +0 -0
  245. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/utils/error_handling.py +0 -0
  246. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/utils/fuzzy.py +0 -0
  247. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/__init__.py +0 -0
  248. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/agent_collab.py +0 -0
  249. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/agent_store.py +0 -0
  250. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/agent_switcher.py +0 -0
  251. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/animation_manager.py +0 -0
  252. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/code_context.py +0 -0
  253. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/command_palette.py +0 -0
  254. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/connection_status.py +0 -0
  255. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/conversation_history.py +0 -0
  256. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/diff_indicator.py +0 -0
  257. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/enhanced_status_bar.py +0 -0
  258. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/enhanced_toast.py +0 -0
  259. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/file_browser.py +0 -0
  260. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/file_reference.py +0 -0
  261. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/issue_timeline.py +0 -0
  262. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/leader_key.py +0 -0
  263. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/mode_switcher.py +0 -0
  264. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/model_picker.py +0 -0
  265. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/permission_preview.py +0 -0
  266. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/prompt.py +0 -0
  267. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/provider_connect.py +0 -0
  268. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/pty_shell.py +0 -0
  269. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/qe_dashboard.py +0 -0
  270. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/resizable_sidebar.py +0 -0
  271. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/response_changes.py +0 -0
  272. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/response_display.py +0 -0
  273. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/rich_tool_display.py +0 -0
  274. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/sidebar_panels.py +0 -0
  275. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/slash_complete.py +0 -0
  276. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/split_view.py +0 -0
  277. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/status_bar.py +0 -0
  278. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/superqode_display.py +0 -0
  279. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/thinking_display.py +0 -0
  280. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/throbber.py +0 -0
  281. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/toast.py +0 -0
  282. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/widgets/unified_output.py +0 -0
  283. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/__init__.py +0 -0
  284. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/artifacts.py +0 -0
  285. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/coordinator.py +0 -0
  286. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/diff_tracker.py +0 -0
  287. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/git_guard.py +0 -0
  288. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/git_snapshot.py +0 -0
  289. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/manager.py +0 -0
  290. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/snapshot.py +0 -0
  291. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/watcher.py +0 -0
  292. {superqode-0.1.8 → superqode-0.1.10}/src/superqode/workspace/worktree.py +0 -0
  293. {superqode-0.1.8 → superqode-0.1.10}/src/superqode.egg-info/dependency_links.txt +0 -0
  294. {superqode-0.1.8 → superqode-0.1.10}/src/superqode.egg-info/entry_points.txt +0 -0
  295. {superqode-0.1.8 → superqode-0.1.10}/src/superqode.egg-info/requires.txt +0 -0
  296. {superqode-0.1.8 → superqode-0.1.10}/src/superqode.egg-info/top_level.txt +0 -0
  297. {superqode-0.1.8 → superqode-0.1.10}/tests/test_acp_client.py +0 -0
  298. {superqode-0.1.8 → superqode-0.1.10}/tests/test_cli_commands.py +0 -0
  299. {superqode-0.1.8 → superqode-0.1.10}/tests/test_linter_runner.py +0 -0
  300. {superqode-0.1.8 → superqode-0.1.10}/tests/test_login_api.py +0 -0
  301. {superqode-0.1.8 → superqode-0.1.10}/tests/test_mcp.py +0 -0
  302. {superqode-0.1.8 → superqode-0.1.10}/tests/test_mcp_integration.py +0 -0
  303. {superqode-0.1.8 → superqode-0.1.10}/tests/test_mcp_live.py +0 -0
  304. {superqode-0.1.8 → superqode-0.1.10}/tests/test_orchestrator.py +0 -0
  305. {superqode-0.1.8 → superqode-0.1.10}/tests/test_oss_integration.py +0 -0
  306. {superqode-0.1.8 → superqode-0.1.10}/tests/test_simple_login.py +0 -0
  307. {superqode-0.1.8 → superqode-0.1.10}/tests/test_tools.py +0 -0
  308. {superqode-0.1.8 → superqode-0.1.10}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superqode
3
- Version: 0.1.8
3
+ Version: 0.1.10
4
4
  Summary: SuperQode: Super Quality Engineering for Agentic Coding Teams
5
5
  Author-email: Shashi Jagtap <info@super-agentic.ai>
6
6
  Maintainer-email: Shashi Jagtap <info@super-agentic.ai>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "superqode"
3
- version = "0.1.8"
3
+ version = "0.1.10"
4
4
  description = "SuperQode: Super Quality Engineering for Agentic Coding Teams"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -30,4 +30,4 @@ __all__ = [
30
30
  "sidebar",
31
31
  ]
32
32
 
33
- __version__ = "0.1.8"
33
+ __version__ = "0.1.10"
@@ -0,0 +1,69 @@
1
+ # Schema defined in agent_schema.py
2
+ # https://ampcode.com
3
+
4
+ identity = "ampcode.com"
5
+ name = "Amp"
6
+ short_name = "amp"
7
+ url = "https://ampcode.com"
8
+ protocol = "acp"
9
+ author_name = "Ampcode"
10
+ author_url = "https://ampcode.com"
11
+ publisher_name = "Superagentic AI"
12
+ publisher_url = "https://super-agentic.ai"
13
+ type = "coding"
14
+ description = "AI coding agent by Ampcode. Works in any codebase with full ACP support via acp-amp adapter."
15
+ tags = ["ampcode", "amp", "coding", "acp"]
16
+ run_command."*" = "acp-amp"
17
+
18
+ help = '''
19
+ # Amp
20
+
21
+ AI coding agent by Ampcode. Works in any codebase with full ACP support.
22
+
23
+ - Multi-turn conversations with thread continuity
24
+ - Full tool execution with permission modes
25
+ - MCP server integration
26
+ - Image support
27
+
28
+ ## Installation
29
+
30
+ Install Amp CLI and the ACP adapter:
31
+
32
+ ```bash
33
+ # Install Amp CLI
34
+ curl -fsSL https://ampcode.com/install.sh | bash
35
+ amp login
36
+
37
+ # Install ACP adapter (Python - recommended)
38
+ uv tool install acp-amp
39
+
40
+ # Alternative: Node.js
41
+ npm install -g @superagenticai/acp-amp
42
+ ```
43
+
44
+ **Requirements:**
45
+ - Amp CLI authenticated (`amp login`)
46
+ - Python 3.10+ with uv (for Python version)
47
+ - Or Node.js 18+ (for Node.js version)
48
+
49
+ ---
50
+
51
+ **For latest install instructions**: https://superagenticai.github.io/acp-amp/
52
+ **ACP Adapter**: https://github.com/SuperagenticAI/acp-amp
53
+ '''
54
+
55
+ welcome = '''
56
+ Welcome to Amp! 🚀
57
+
58
+ I'm Amp, an AI coding agent by Ampcode. I can help you with:
59
+ - Code analysis and refactoring
60
+ - Bug fixing and debugging
61
+ - Writing new features
62
+ - Code review and optimization
63
+
64
+ Just tell me what you'd like to work on!
65
+ '''
66
+
67
+ [actions."*".install]
68
+ command = "uv tool install acp-amp"
69
+ description = "Install Amp ACP adapter (see https://superagenticai.github.io/acp-amp/ for latest)"
@@ -247,6 +247,19 @@ AGENTS: Dict[str, AgentDef] = {
247
247
  connection_type="stdio",
248
248
  command="llmling-agent --acp",
249
249
  ),
250
+ "amp": AgentDef(
251
+ id="amp",
252
+ name="Amp",
253
+ protocol=AgentProtocol.ACP,
254
+ status=AgentStatus.SUPPORTED,
255
+ description="AI coding agent by Ampcode with full ACP support",
256
+ auth_info="Managed via amp login",
257
+ setup_command="uv tool install acp-amp",
258
+ docs_url="https://ampcode.com",
259
+ capabilities=["File editing", "Shell commands", "MCP tools", "Multi-turn"],
260
+ connection_type="stdio",
261
+ command="acp-amp",
262
+ ),
250
263
  }
251
264
 
252
265
 
@@ -4660,7 +4660,7 @@ team:
4660
4660
  else:
4661
4661
  # Handle all other ACP-compatible agents generically
4662
4662
  # This covers: junie, goose, kimi, stakpak, vtcode, auggie,
4663
- # code-assistant, cagent, fast-agent, llmling-agent
4663
+ # code-assistant, cagent, fast-agent, llmling-agent, amp
4664
4664
  acp_agents = {
4665
4665
  "junie",
4666
4666
  "goose",
@@ -4672,6 +4672,7 @@ team:
4672
4672
  "cagent",
4673
4673
  "fast-agent",
4674
4674
  "llmling-agent",
4675
+ "amp",
4675
4676
  }
4676
4677
  if short_name in acp_agents:
4677
4678
  model_name = self.current_model if self.current_model else "auto"
@@ -4722,7 +4723,7 @@ team:
4722
4723
  self._current_file_context = "" # Clear after use
4723
4724
 
4724
4725
  # Route ACP-compatible agents to the JSON-RPC ACP client
4725
- # All 14 official ACP agents support the Agent Client Protocol
4726
+ # All 15 official ACP agents support the Agent Client Protocol
4726
4727
  acp_agents = (
4727
4728
  "opencode",
4728
4729
  "claude",
@@ -4738,6 +4739,7 @@ team:
4738
4739
  "cagent",
4739
4740
  "fast-agent",
4740
4741
  "llmling-agent",
4742
+ "amp",
4741
4743
  )
4742
4744
  if agent_type in acp_agents:
4743
4745
  self._run_acp_jsonrpc_client(
@@ -4979,7 +4981,7 @@ team:
4979
4981
  self._current_file_context = ""
4980
4982
 
4981
4983
  # Choose command and model display based on agent type
4982
- # All 14 official ACP agents are supported
4984
+ # All 15 official ACP agents are supported
4983
4985
  if agent_type == "gemini":
4984
4986
  command = "gemini --experimental-acp"
4985
4987
  model_display = f"gemini/{model}" if model and model != "auto" else "gemini/auto"
@@ -5058,6 +5060,10 @@ team:
5058
5060
  elif agent_type == "llmling-agent":
5059
5061
  command = "llmling-agent --acp"
5060
5062
  model_display = f"llmling-agent/{model}" if model else "llmling-agent/auto"
5063
+ elif agent_type == "amp":
5064
+ command = "acp-amp"
5065
+ model_display = f"amp/{model}" if model else "amp/auto"
5066
+ # Amp handles its own authentication via `amp login`
5061
5067
  else:
5062
5068
  self.call_from_thread(self._stop_thinking)
5063
5069
  self.call_from_thread(log.add_error, f"Unsupported ACP agent type: {agent_type}")
@@ -14862,6 +14868,9 @@ team:
14862
14868
  "stakpak": "📦", # Package
14863
14869
  "vtcode": "🎨", # Paint palette
14864
14870
  "openhands": "🤲", # Open hands
14871
+ "amp": "⚡", # Lightning (Amp)
14872
+ "ampcode": "⚡", # Lightning
14873
+ "ampcode.com": "⚡", # Lightning
14865
14874
  }
14866
14875
 
14867
14876
  priority_order = {
@@ -0,0 +1,264 @@
1
+ """
2
+ Local Auth Storage for SuperQode.
3
+
4
+ Simple, minimal local storage for API keys. Inspired by opencode's approach.
5
+
6
+ Security:
7
+ - File permissions set to 0o600 (owner read/write only)
8
+ - Stored in ~/.superqode/auth.json
9
+ - Never logs or exposes key values
10
+
11
+ This is OPTIONAL - SuperQode still supports BYOK (env vars) as primary.
12
+ Local storage is for users who prefer file-based key management.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ import logging
19
+ import os
20
+ from dataclasses import dataclass
21
+ from datetime import datetime
22
+ from enum import Enum
23
+ from pathlib import Path
24
+ from typing import Any, Dict, Optional, Union
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ class AuthType(Enum):
30
+ """Type of authentication credential."""
31
+
32
+ API = "api" # Simple API key
33
+ OAUTH = "oauth" # OAuth with refresh token
34
+ WELLKNOWN = "wellknown" # Well-known auth (key + token pair)
35
+
36
+
37
+ @dataclass
38
+ class ApiAuth:
39
+ """Simple API key authentication."""
40
+
41
+ type: str = "api"
42
+ key: str = ""
43
+
44
+ def to_dict(self) -> Dict[str, Any]:
45
+ return {"type": self.type, "key": self.key}
46
+
47
+ @classmethod
48
+ def from_dict(cls, data: Dict[str, Any]) -> "ApiAuth":
49
+ return cls(type=data.get("type", "api"), key=data.get("key", ""))
50
+
51
+
52
+ @dataclass
53
+ class OAuthAuth:
54
+ """OAuth authentication with refresh token."""
55
+
56
+ type: str = "oauth"
57
+ refresh: str = ""
58
+ access: str = ""
59
+ expires: int = 0
60
+ account_id: Optional[str] = None
61
+ enterprise_url: Optional[str] = None
62
+
63
+ def to_dict(self) -> Dict[str, Any]:
64
+ result = {
65
+ "type": self.type,
66
+ "refresh": self.refresh,
67
+ "access": self.access,
68
+ "expires": self.expires,
69
+ }
70
+ if self.account_id:
71
+ result["account_id"] = self.account_id
72
+ if self.enterprise_url:
73
+ result["enterprise_url"] = self.enterprise_url
74
+ return result
75
+
76
+ @classmethod
77
+ def from_dict(cls, data: Dict[str, Any]) -> "OAuthAuth":
78
+ return cls(
79
+ type=data.get("type", "oauth"),
80
+ refresh=data.get("refresh", ""),
81
+ access=data.get("access", ""),
82
+ expires=data.get("expires", 0),
83
+ account_id=data.get("account_id"),
84
+ enterprise_url=data.get("enterprise_url"),
85
+ )
86
+
87
+ def is_expired(self) -> bool:
88
+ """Check if access token is expired."""
89
+ return self.expires > 0 and self.expires < int(datetime.now().timestamp())
90
+
91
+
92
+ @dataclass
93
+ class WellKnownAuth:
94
+ """Well-known authentication (key + token pair)."""
95
+
96
+ type: str = "wellknown"
97
+ key: str = ""
98
+ token: str = ""
99
+
100
+ def to_dict(self) -> Dict[str, Any]:
101
+ return {"type": self.type, "key": self.key, "token": self.token}
102
+
103
+ @classmethod
104
+ def from_dict(cls, data: Dict[str, Any]) -> "WellKnownAuth":
105
+ return cls(
106
+ type=data.get("type", "wellknown"),
107
+ key=data.get("key", ""),
108
+ token=data.get("token", ""),
109
+ )
110
+
111
+
112
+ AuthInfo = Union[ApiAuth, OAuthAuth, WellKnownAuth]
113
+
114
+
115
+ def parse_auth_info(data: Dict[str, Any]) -> Optional[AuthInfo]:
116
+ """Parse auth info from dict based on type."""
117
+ auth_type = data.get("type")
118
+ if auth_type == "api":
119
+ return ApiAuth.from_dict(data)
120
+ if auth_type == "oauth":
121
+ return OAuthAuth.from_dict(data)
122
+ if auth_type == "wellknown":
123
+ return WellKnownAuth.from_dict(data)
124
+ return None
125
+
126
+
127
+ class LocalAuthStorage:
128
+ """
129
+ Local storage for API keys and OAuth tokens.
130
+
131
+ Stores credentials in ~/.superqode/auth.json with restricted permissions.
132
+
133
+ Usage:
134
+ auth = LocalAuthStorage()
135
+
136
+ # Set API key
137
+ auth.set("anthropic", ApiAuth(key="sk-..."))
138
+
139
+ # Get credentials
140
+ creds = auth.get("anthropic")
141
+
142
+ # Remove
143
+ auth.remove("anthropic")
144
+
145
+ # List all
146
+ all_creds = auth.all()
147
+ """
148
+
149
+ DEFAULT_PATH = Path.home() / ".superqode" / "auth.json"
150
+
151
+ def __init__(self, filepath: Optional[Path] = None):
152
+ self.filepath = filepath or self.DEFAULT_PATH
153
+ self._ensure_dir()
154
+
155
+ def _ensure_dir(self) -> None:
156
+ """Ensure parent directory exists with proper permissions."""
157
+ parent = self.filepath.parent
158
+ if not parent.exists():
159
+ parent.mkdir(parents=True, mode=0o700)
160
+
161
+ def _read_file(self) -> Dict[str, Any]:
162
+ """Read auth file, return empty dict if not exists or invalid."""
163
+ if not self.filepath.exists():
164
+ return {}
165
+ try:
166
+ with open(self.filepath) as f:
167
+ return json.load(f)
168
+ except (json.JSONDecodeError, IOError):
169
+ return {}
170
+
171
+ def _write_file(self, data: Dict[str, Any]) -> None:
172
+ """Write auth file with secure permissions."""
173
+ # Write to temp file first, then rename (atomic)
174
+ temp_path = self.filepath.with_suffix(".tmp")
175
+ with open(temp_path, "w") as f:
176
+ json.dump(data, f, indent=2)
177
+
178
+ # Set permissions before moving
179
+ os.chmod(temp_path, 0o600)
180
+
181
+ # Atomic rename
182
+ temp_path.rename(self.filepath)
183
+
184
+ def get(self, provider_id: str) -> Optional[AuthInfo]:
185
+ """Get credentials for a provider."""
186
+ data = self._read_file()
187
+ if provider_id not in data:
188
+ return None
189
+ return parse_auth_info(data[provider_id])
190
+
191
+ def all(self) -> Dict[str, AuthInfo]:
192
+ """Get all stored credentials."""
193
+ data = self._read_file()
194
+ result: Dict[str, AuthInfo] = {}
195
+ for key, value in data.items():
196
+ if isinstance(value, dict):
197
+ parsed = parse_auth_info(value)
198
+ if parsed:
199
+ result[key] = parsed
200
+ return result
201
+
202
+ def set(self, provider_id: str, info: AuthInfo) -> None:
203
+ """Set credentials for a provider."""
204
+ data = self._read_file()
205
+ data[provider_id] = info.to_dict()
206
+ self._write_file(data)
207
+ logger.debug(f"Saved auth for {provider_id}")
208
+
209
+ def remove(self, provider_id: str) -> bool:
210
+ """Remove credentials for a provider. Returns True if removed."""
211
+ data = self._read_file()
212
+ if provider_id not in data:
213
+ return False
214
+ del data[provider_id]
215
+ self._write_file(data)
216
+ logger.debug(f"Removed auth for {provider_id}")
217
+ return True
218
+
219
+ def exists(self, provider_id: str) -> bool:
220
+ """Check if credentials exist for a provider."""
221
+ return provider_id in self._read_file()
222
+
223
+ def clear(self) -> None:
224
+ """Clear all stored credentials."""
225
+ self._write_file({})
226
+ logger.debug("Cleared all auth")
227
+
228
+
229
+ # Singleton instance
230
+ _storage: Optional[LocalAuthStorage] = None
231
+
232
+
233
+ def get_storage() -> LocalAuthStorage:
234
+ """Get the singleton auth storage instance."""
235
+ global _storage
236
+ if _storage is None:
237
+ _storage = LocalAuthStorage()
238
+ return _storage
239
+
240
+
241
+ # Convenience functions
242
+ def get(provider_id: str) -> Optional[AuthInfo]:
243
+ """Get credentials for a provider."""
244
+ return get_storage().get(provider_id)
245
+
246
+
247
+ def all() -> Dict[str, AuthInfo]:
248
+ """Get all stored credentials."""
249
+ return get_storage().all()
250
+
251
+
252
+ def set(provider_id: str, info: AuthInfo) -> None:
253
+ """Set credentials for a provider."""
254
+ get_storage().set(provider_id, info)
255
+
256
+
257
+ def remove(provider_id: str) -> bool:
258
+ """Remove credentials for a provider."""
259
+ return get_storage().remove(provider_id)
260
+
261
+
262
+ def exists(provider_id: str) -> bool:
263
+ """Check if credentials exist for a provider."""
264
+ return get_storage().exists(provider_id)