superqode 0.1.9__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.9/src/superqode.egg-info → superqode-0.1.10}/PKG-INFO +1 -1
  2. {superqode-0.1.9 → superqode-0.1.10}/pyproject.toml +1 -1
  3. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/__init__.py +1 -1
  4. superqode-0.1.10/src/superqode/auth/__init__.py +264 -0
  5. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/acp.py +109 -109
  6. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/auth.py +134 -12
  7. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/execution/resolver.py +40 -2
  8. {superqode-0.1.9 → superqode-0.1.10/src/superqode.egg-info}/PKG-INFO +1 -1
  9. {superqode-0.1.9 → superqode-0.1.10}/src/superqode.egg-info/SOURCES.txt +2 -0
  10. superqode-0.1.10/tests/test_auth.py +181 -0
  11. {superqode-0.1.9 → superqode-0.1.10}/LICENSE +0 -0
  12. {superqode-0.1.9 → superqode-0.1.10}/README.md +0 -0
  13. {superqode-0.1.9 → superqode-0.1.10}/setup.cfg +0 -0
  14. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/acp/__init__.py +0 -0
  15. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/acp/client.py +0 -0
  16. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/acp/permission_screen.py +0 -0
  17. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/acp/types.py +0 -0
  18. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/acp_discovery.py +0 -0
  19. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent/__init__.py +0 -0
  20. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent/edit_strategies.py +0 -0
  21. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent/loop.py +0 -0
  22. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent/qe_report_templates.py +0 -0
  23. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent/system_prompts.py +0 -0
  24. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent_output.py +0 -0
  25. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agent_stream.py +0 -0
  26. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/__init__.py +0 -0
  27. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/acp_registry.py +0 -0
  28. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/client.py +0 -0
  29. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/ampcode.com.toml +0 -0
  30. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/augmentcode.com.toml +0 -0
  31. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/cagent.dev.toml +0 -0
  32. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/claude.com.toml +0 -0
  33. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/codeassistant.dev.toml +0 -0
  34. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/codex.openai.com.toml +0 -0
  35. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/fastagent.ai.toml +0 -0
  36. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/geminicli.com.toml +0 -0
  37. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/goose.block.xyz.toml +0 -0
  38. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/junie.jetbrains.com.toml +0 -0
  39. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/kimi.moonshot.cn.toml +0 -0
  40. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/llmlingagent.dev.toml +0 -0
  41. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/molt.bot.toml +0 -0
  42. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/opencode.ai.toml +0 -0
  43. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/stakpak.dev.toml +0 -0
  44. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/data/vtcode.dev.toml +0 -0
  45. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/discovery.py +0 -0
  46. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/messaging.py +0 -0
  47. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/persona.py +0 -0
  48. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/registry.py +0 -0
  49. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/schema.py +0 -0
  50. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/agents/unified.py +0 -0
  51. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/__init__.py +0 -0
  52. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/constants.py +0 -0
  53. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/css.py +0 -0
  54. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/models.py +0 -0
  55. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/suggester.py +0 -0
  56. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app/widgets.py +0 -0
  57. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app_enhanced.py +0 -0
  58. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/app_main.py +0 -0
  59. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/approval.py +0 -0
  60. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/atomic.py +0 -0
  61. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/__init__.py +0 -0
  62. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/agents.py +0 -0
  63. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/config.py +0 -0
  64. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/init.py +0 -0
  65. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/providers.py +0 -0
  66. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/qe.py +0 -0
  67. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/roles.py +0 -0
  68. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/serve.py +0 -0
  69. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/suggestions.py +0 -0
  70. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/commands/superqe.py +0 -0
  71. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/config/__init__.py +0 -0
  72. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/config/loader.py +0 -0
  73. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/config/schema.py +0 -0
  74. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/core/__init__.py +0 -0
  75. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/core/roles.py +0 -0
  76. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/danger.py +0 -0
  77. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/data/superqode-template.yaml +0 -0
  78. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/design_system.py +0 -0
  79. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/dialogs/__init__.py +0 -0
  80. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/dialogs/base.py +0 -0
  81. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/dialogs/model.py +0 -0
  82. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/dialogs/provider.py +0 -0
  83. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/diff_view.py +0 -0
  84. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/enterprise.py +0 -0
  85. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/evaluation/__init__.py +0 -0
  86. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/evaluation/adapters.py +0 -0
  87. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/evaluation/behaviors.py +0 -0
  88. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/evaluation/engine.py +0 -0
  89. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/evaluation/scenarios.py +0 -0
  90. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/execution/__init__.py +0 -0
  91. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/execution/linter.py +0 -0
  92. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/execution/modes.py +0 -0
  93. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/execution/runner.py +0 -0
  94. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/file_explorer.py +0 -0
  95. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/file_viewer.py +0 -0
  96. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/flash.py +0 -0
  97. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/guidance/__init__.py +0 -0
  98. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/guidance/config.py +0 -0
  99. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/guidance/prompts.py +0 -0
  100. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/harness/__init__.py +0 -0
  101. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/harness/accelerator.py +0 -0
  102. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/harness/config.py +0 -0
  103. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/harness/validator.py +0 -0
  104. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/history.py +0 -0
  105. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/integrations/superopt_runner.py +0 -0
  106. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/__init__.py +0 -0
  107. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/adapters.py +0 -0
  108. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/formatter.py +0 -0
  109. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/integration.py +0 -0
  110. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/sinks.py +0 -0
  111. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/logging/unified_log.py +0 -0
  112. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/lsp/__init__.py +0 -0
  113. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/lsp/client.py +0 -0
  114. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/main.py +0 -0
  115. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/__init__.py +0 -0
  116. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/auth_storage.py +0 -0
  117. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/client.py +0 -0
  118. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/config.py +0 -0
  119. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/integration.py +0 -0
  120. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/oauth.py +0 -0
  121. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/oauth_callback.py +0 -0
  122. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/mcp/types.py +0 -0
  123. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/memory/__init__.py +0 -0
  124. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/memory/feedback.py +0 -0
  125. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/memory/store.py +0 -0
  126. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/notifications.py +0 -0
  127. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/optimization/__init__.py +0 -0
  128. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/optimization/config.py +0 -0
  129. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/permissions/__init__.py +0 -0
  130. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/permissions/rules.py +0 -0
  131. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/plan.py +0 -0
  132. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/__init__.py +0 -0
  133. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/gateway/__init__.py +0 -0
  134. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/gateway/base.py +0 -0
  135. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/gateway/litellm_gateway.py +0 -0
  136. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/gateway/openresponses_gateway.py +0 -0
  137. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/health.py +0 -0
  138. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/__init__.py +0 -0
  139. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/downloader.py +0 -0
  140. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/endpoints.py +0 -0
  141. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/hub.py +0 -0
  142. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/inference.py +0 -0
  143. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/huggingface/transformers_runner.py +0 -0
  144. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/__init__.py +0 -0
  145. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/base.py +0 -0
  146. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/discovery.py +0 -0
  147. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/lmstudio.py +0 -0
  148. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/mlx.py +0 -0
  149. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/ollama.py +0 -0
  150. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/sglang.py +0 -0
  151. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/tgi.py +0 -0
  152. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/tool_support.py +0 -0
  153. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/local/vllm.py +0 -0
  154. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/manager.py +0 -0
  155. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/models.py +0 -0
  156. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/models_dev.py +0 -0
  157. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/__init__.py +0 -0
  158. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/__init__.py +0 -0
  159. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/messages.py +0 -0
  160. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/converters/tools.py +0 -0
  161. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/schema/__init__.py +0 -0
  162. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/schema/models.py +0 -0
  163. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/streaming/__init__.py +0 -0
  164. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/streaming/parser.py +0 -0
  165. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/__init__.py +0 -0
  166. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/apply_patch.py +0 -0
  167. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/code_interpreter.py +0 -0
  168. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/file_search.py +0 -0
  169. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/openresponses/tools/mcp_adapter.py +0 -0
  170. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/registry.py +0 -0
  171. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/providers/usage.py +0 -0
  172. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/pure_mode.py +0 -0
  173. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/qr/__init__.py +0 -0
  174. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/qr/dashboard.py +0 -0
  175. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/qr/generator.py +0 -0
  176. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/qr/templates.py +0 -0
  177. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/safety/__init__.py +0 -0
  178. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/safety/sandbox.py +0 -0
  179. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/safety/warnings.py +0 -0
  180. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/server/__init__.py +0 -0
  181. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/server/lsp_server.py +0 -0
  182. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/server/web.py +0 -0
  183. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/session/__init__.py +0 -0
  184. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/session/persistence.py +0 -0
  185. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/session/sharing.py +0 -0
  186. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/session.py +0 -0
  187. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/sidebar.py +0 -0
  188. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/stream_view.py +0 -0
  189. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/styles/__init__.py +0 -0
  190. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/__init__.py +0 -0
  191. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/acp_runner.py +0 -0
  192. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/constitution/__init__.py +0 -0
  193. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/constitution/evaluator.py +0 -0
  194. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/constitution/loader.py +0 -0
  195. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/constitution/schema.py +0 -0
  196. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/events.py +0 -0
  197. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/__init__.py +0 -0
  198. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/base.py +0 -0
  199. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/e2e.py +0 -0
  200. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/executor.py +0 -0
  201. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/javascript.py +0 -0
  202. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/python.py +0 -0
  203. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/frameworks/registry.py +0 -0
  204. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/__init__.py +0 -0
  205. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/core_tools.py +0 -0
  206. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/registry.py +0 -0
  207. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/mcp_tools/testing_tools.py +0 -0
  208. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/noise.py +0 -0
  209. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/orchestrator.py +0 -0
  210. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/roles.py +0 -0
  211. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/session.py +0 -0
  212. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/skills/__init__.py +0 -0
  213. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/skills/base.py +0 -0
  214. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/skills/core_skills.py +0 -0
  215. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/skills/registry.py +0 -0
  216. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe/verifier.py +0 -0
  217. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/superqe_cli.py +0 -0
  218. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tool_call.py +0 -0
  219. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/__init__.py +0 -0
  220. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/agent_tools.py +0 -0
  221. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/base.py +0 -0
  222. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/batch_tool.py +0 -0
  223. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/diagnostics.py +0 -0
  224. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/edit_tools.py +0 -0
  225. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/enhanced_base.py +0 -0
  226. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/file_tools.py +0 -0
  227. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/file_tracking.py +0 -0
  228. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/lsp_tools.py +0 -0
  229. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/network_tools.py +0 -0
  230. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/permissions.py +0 -0
  231. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/question_tool.py +0 -0
  232. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/search_tools.py +0 -0
  233. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/shell_tools.py +0 -0
  234. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/todo_tools.py +0 -0
  235. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/validation.py +0 -0
  236. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tools/web_tools.py +0 -0
  237. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui.py +0 -0
  238. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui_integration.py +0 -0
  239. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui_widgets/__init__.py +0 -0
  240. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/__init__.py +0 -0
  241. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/progress.py +0 -0
  242. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/tui_widgets/widgets/tool_display.py +0 -0
  243. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/undo_manager.py +0 -0
  244. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/utils/__init__.py +0 -0
  245. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/utils/error_handling.py +0 -0
  246. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/utils/fuzzy.py +0 -0
  247. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/__init__.py +0 -0
  248. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/agent_collab.py +0 -0
  249. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/agent_store.py +0 -0
  250. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/agent_switcher.py +0 -0
  251. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/animation_manager.py +0 -0
  252. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/code_context.py +0 -0
  253. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/command_palette.py +0 -0
  254. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/connection_status.py +0 -0
  255. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/conversation_history.py +0 -0
  256. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/diff_indicator.py +0 -0
  257. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/enhanced_status_bar.py +0 -0
  258. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/enhanced_toast.py +0 -0
  259. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/file_browser.py +0 -0
  260. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/file_reference.py +0 -0
  261. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/issue_timeline.py +0 -0
  262. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/leader_key.py +0 -0
  263. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/mode_switcher.py +0 -0
  264. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/model_picker.py +0 -0
  265. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/permission_preview.py +0 -0
  266. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/prompt.py +0 -0
  267. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/provider_connect.py +0 -0
  268. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/pty_shell.py +0 -0
  269. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/qe_dashboard.py +0 -0
  270. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/resizable_sidebar.py +0 -0
  271. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/response_changes.py +0 -0
  272. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/response_display.py +0 -0
  273. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/rich_tool_display.py +0 -0
  274. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/sidebar_panels.py +0 -0
  275. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/slash_complete.py +0 -0
  276. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/split_view.py +0 -0
  277. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/status_bar.py +0 -0
  278. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/superqode_display.py +0 -0
  279. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/thinking_display.py +0 -0
  280. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/throbber.py +0 -0
  281. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/toast.py +0 -0
  282. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/widgets/unified_output.py +0 -0
  283. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/__init__.py +0 -0
  284. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/artifacts.py +0 -0
  285. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/coordinator.py +0 -0
  286. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/diff_tracker.py +0 -0
  287. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/git_guard.py +0 -0
  288. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/git_snapshot.py +0 -0
  289. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/manager.py +0 -0
  290. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/snapshot.py +0 -0
  291. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/watcher.py +0 -0
  292. {superqode-0.1.9 → superqode-0.1.10}/src/superqode/workspace/worktree.py +0 -0
  293. {superqode-0.1.9 → superqode-0.1.10}/src/superqode.egg-info/dependency_links.txt +0 -0
  294. {superqode-0.1.9 → superqode-0.1.10}/src/superqode.egg-info/entry_points.txt +0 -0
  295. {superqode-0.1.9 → superqode-0.1.10}/src/superqode.egg-info/requires.txt +0 -0
  296. {superqode-0.1.9 → superqode-0.1.10}/src/superqode.egg-info/top_level.txt +0 -0
  297. {superqode-0.1.9 → superqode-0.1.10}/tests/test_acp_client.py +0 -0
  298. {superqode-0.1.9 → superqode-0.1.10}/tests/test_cli_commands.py +0 -0
  299. {superqode-0.1.9 → superqode-0.1.10}/tests/test_linter_runner.py +0 -0
  300. {superqode-0.1.9 → superqode-0.1.10}/tests/test_login_api.py +0 -0
  301. {superqode-0.1.9 → superqode-0.1.10}/tests/test_mcp.py +0 -0
  302. {superqode-0.1.9 → superqode-0.1.10}/tests/test_mcp_integration.py +0 -0
  303. {superqode-0.1.9 → superqode-0.1.10}/tests/test_mcp_live.py +0 -0
  304. {superqode-0.1.9 → superqode-0.1.10}/tests/test_orchestrator.py +0 -0
  305. {superqode-0.1.9 → superqode-0.1.10}/tests/test_oss_integration.py +0 -0
  306. {superqode-0.1.9 → superqode-0.1.10}/tests/test_simple_login.py +0 -0
  307. {superqode-0.1.9 → superqode-0.1.10}/tests/test_tools.py +0 -0
  308. {superqode-0.1.9 → 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.9
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.9"
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,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)
@@ -780,136 +780,136 @@ def install_agent(agent_identifier: str) -> int:
780
780
  )
781
781
  return 1
782
782
 
783
- # Pre-flight checks
784
- _console.print(f"[bold cyan]🚀 Installing {agent['name']}[/bold cyan]")
785
- _console.print(f"[dim]{agent.get('description', '')}[/dim]")
786
- _console.print()
783
+ # Pre-flight checks
784
+ _console.print(f"[bold cyan]🚀 Installing {agent['name']}[/bold cyan]")
785
+ _console.print(f"[dim]{agent.get('description', '')}[/dim]")
786
+ _console.print()
787
787
 
788
- # Check system dependencies
789
- deps = check_system_dependencies()
790
- missing_deps = [dep for dep, available in deps.items() if not available]
788
+ # Check system dependencies
789
+ deps = check_system_dependencies()
790
+ missing_deps = [dep for dep, available in deps.items() if not available]
791
+
792
+ if missing_deps:
793
+ _console.print("[yellow]⚠️ Missing system dependencies detected:[/yellow]")
794
+ for dep in missing_deps:
795
+ _console.print(f" [red]• {dep}[/red]")
796
+
797
+ # Try to auto-install critical dependencies
798
+ critical_deps = ["uv"] # Add more as needed
799
+ for dep in critical_deps:
800
+ if dep in missing_deps:
801
+ if not install_system_dependency(dep):
802
+ _console.print(
803
+ f"[red]Cannot proceed without {dep}. Please install it manually.[/red]"
804
+ )
805
+ return 1
806
+
807
+ _console.print()
808
+
809
+ # Get the install command for current OS
810
+ install_command = get_os_command(actions, "install")
811
+ if not install_command:
812
+ _console.print("[red]No installation command found for this agent on your OS.[/red]")
813
+ return 1
791
814
 
792
- if missing_deps:
793
- _console.print("[yellow]⚠️ Missing system dependencies detected:[/yellow]")
794
- for dep in missing_deps:
795
- _console.print(f" [red]• {dep}[/red]")
815
+ # Check for bootstrap_uv flag
816
+ needs_uv_bootstrap = False
817
+ for os_actions in actions.values():
818
+ if isinstance(os_actions, dict) and os_actions.get("bootstrap_uv", False):
819
+ needs_uv_bootstrap = True
820
+ break
796
821
 
797
- # Try to auto-install critical dependencies
798
- critical_deps = ["uv"] # Add more as needed
799
- for dep in critical_deps:
800
- if dep in missing_deps:
801
- if not install_system_dependency(dep):
802
- _console.print(
803
- f"[red]Cannot proceed without {dep}. Please install it manually.[/red]"
804
- )
805
- return 1
822
+ # Bootstrap UV if needed
823
+ if needs_uv_bootstrap and not deps.get("uv", False):
824
+ _console.print("[cyan]Bootstrapping UV package manager...[/cyan]")
825
+ if not install_system_dependency("uv"):
826
+ _console.print("[red]UV bootstrap failed. Cannot proceed.[/red]")
827
+ return 1
806
828
 
829
+ _console.print(f"[green]Installing {agent['name']}...[/green]")
830
+ _console.print(f"[dim]Command: {install_command}[/dim]")
807
831
  _console.print()
808
832
 
809
- # Get the install command for current OS
810
- install_command = get_os_command(actions, "install")
811
- if not install_command:
812
- _console.print("[red]No installation command found for this agent on your OS.[/red]")
813
- return 1
814
-
815
- # Check for bootstrap_uv flag
816
- needs_uv_bootstrap = False
817
- for os_actions in actions.values():
818
- if isinstance(os_actions, dict) and os_actions.get("bootstrap_uv", False):
819
- needs_uv_bootstrap = True
820
- break
821
-
822
- # Bootstrap UV if needed
823
- if needs_uv_bootstrap and not deps.get("uv", False):
824
- _console.print("[cyan]Bootstrapping UV package manager...[/cyan]")
825
- if not install_system_dependency("uv"):
826
- _console.print("[red]UV bootstrap failed. Cannot proceed.[/red]")
827
- return 1
828
-
829
- _console.print(f"[green]Installing {agent['name']}...[/green]")
830
- _console.print(f"[dim]Command: {install_command}[/dim]")
831
- _console.print()
833
+ # Run the installation command with progress feedback
834
+ try:
835
+ # Use a more interactive approach for long-running installs
836
+ process = subprocess.Popen(
837
+ install_command,
838
+ shell=True,
839
+ stdout=subprocess.PIPE,
840
+ stderr=subprocess.PIPE,
841
+ text=True,
842
+ bufsize=1,
843
+ universal_newlines=True,
844
+ )
832
845
 
833
- # Run the installation command with progress feedback
834
- try:
835
- # Use a more interactive approach for long-running installs
836
- process = subprocess.Popen(
837
- install_command,
838
- shell=True,
839
- stdout=subprocess.PIPE,
840
- stderr=subprocess.PIPE,
841
- text=True,
842
- bufsize=1,
843
- universal_newlines=True,
844
- )
846
+ # Show progress
847
+ _console.print("[cyan]Installation in progress...[/cyan]")
845
848
 
846
- # Show progress
847
- _console.print("[cyan]Installation in progress...[/cyan]")
849
+ # Wait for completion
850
+ stdout, stderr = process.communicate()
848
851
 
849
- # Wait for completion
850
- stdout, stderr = process.communicate()
852
+ if process.returncode == 0:
853
+ _console.print("[green]✓ Installation completed successfully![/green]")
851
854
 
852
- if process.returncode == 0:
853
- _console.print("[green]✓ Installation completed successfully![/green]")
855
+ # Verify installation
856
+ if check_agent_installed(agent):
857
+ _console.print(f"[green]✓ Agent '{agent['short_name']}' is ready to use![/green]")
858
+ _console.print(f"[dim]Try: superqode agents connect {agent['short_name']}[/dim]")
859
+ else:
860
+ _console.print("[yellow]⚠️ Agent installed but verification failed[/yellow]")
861
+ _console.print(
862
+ "[dim]You may need to restart your shell or check the installation manually[/dim]"
863
+ )
854
864
 
855
- # Verify installation
856
- if check_agent_installed(agent):
857
- _console.print(f"[green]✓ Agent '{agent['short_name']}' is ready to use![/green]")
858
- _console.print(f"[dim]Try: superqode agents connect {agent['short_name']}[/dim]")
865
+ return 0
859
866
  else:
860
- _console.print("[yellow]⚠️ Agent installed but verification failed[/yellow]")
861
- _console.print(
862
- f"[dim]You may need to restart your shell or check the installation manually[/dim]"
863
- )
867
+ _console.print(f"[red] Installation failed (exit code {process.returncode})[/red]")
864
868
 
865
- return 0
866
- else:
867
- _console.print(f"[red]✗ Installation failed (exit code {process.returncode})[/red]")
869
+ # Enhanced error analysis
870
+ error_msg = stderr.lower() if stderr else ""
868
871
 
869
- # Enhanced error analysis
870
- error_msg = stderr.lower() if stderr else ""
872
+ if "eacces" in error_msg or "permission denied" in error_msg:
873
+ _console.print("[yellow]💡 Permission Error:[/yellow]")
874
+ _console.print(" This command requires administrator privileges.")
875
+ _console.print(f" Try: [bold]sudo {install_command}[/bold]")
876
+ _console.print(
877
+ " Or use a Node version manager like nvm/fnm for user-space installation"
878
+ )
879
+ elif "command not found" in error_msg or "npm: command not found" in error_msg:
880
+ _console.print("[yellow]💡 Missing npm:[/yellow]")
881
+ _console.print(" Node.js/npm is not installed. Install from:")
882
+ _console.print(" https://nodejs.org/ or use your system package manager")
883
+ elif "uv: command not found" in error_msg:
884
+ _console.print("[yellow]💡 Missing UV:[/yellow]")
885
+ _console.print(" UV package manager is not installed. Install with:")
886
+ _console.print(" curl -LsSf https://astral.sh/uv/install.sh | sh")
887
+ elif "certificate" in error_msg or "ssl" in error_msg:
888
+ _console.print("[yellow]💡 SSL/Certificate Error:[/yellow]")
889
+ _console.print(" There may be network or certificate issues.")
890
+ _console.print(" Try updating your system's CA certificates.")
891
+ else:
892
+ # Show the actual error output
893
+ if stdout.strip():
894
+ _console.print("[dim]Output:[/dim]")
895
+ _console.print(stdout.strip())
896
+ if stderr.strip():
897
+ _console.print("[dim]Error:[/dim]")
898
+ _console.print(stderr.strip())
871
899
 
872
- if "eacces" in error_msg or "permission denied" in error_msg:
873
- _console.print("[yellow]💡 Permission Error:[/yellow]")
874
- _console.print(" This command requires administrator privileges.")
875
- _console.print(f" Try: [bold]sudo {install_command}[/bold]")
876
900
  _console.print(
877
- " Or use a Node version manager like nvm/fnm for user-space installation"
901
+ f"\n[dim]💡 Alternative: Try installing manually with: {install_command}[/dim]"
878
902
  )
879
- elif "command not found" in error_msg or "npm: command not found" in error_msg:
880
- _console.print("[yellow]💡 Missing npm:[/yellow]")
881
- _console.print(" Node.js/npm is not installed. Install from:")
882
- _console.print(" https://nodejs.org/ or use your system package manager")
883
- elif "uv: command not found" in error_msg:
884
- _console.print("[yellow]💡 Missing UV:[/yellow]")
885
- _console.print(" UV package manager is not installed. Install with:")
886
- _console.print(" curl -LsSf https://astral.sh/uv/install.sh | sh")
887
- elif "certificate" in error_msg or "ssl" in error_msg:
888
- _console.print("[yellow]💡 SSL/Certificate Error:[/yellow]")
889
- _console.print(" There may be network or certificate issues.")
890
- _console.print(" Try updating your system's CA certificates.")
891
- else:
892
- # Show the actual error output
893
- if stdout.strip():
894
- _console.print("[dim]Output:[/dim]")
895
- _console.print(stdout.strip())
896
- if stderr.strip():
897
- _console.print("[dim]Error:[/dim]")
898
- _console.print(stderr.strip())
903
+ return 1
899
904
 
905
+ except FileNotFoundError:
900
906
  _console.print(
901
- f"\n[dim]💡 Alternative: Try installing manually with: {install_command}[/dim]"
907
+ "[red]Command not found. Please ensure required dependencies are installed.[/red]"
902
908
  )
903
909
  return 1
904
-
905
- except FileNotFoundError:
906
- _console.print(
907
- f"[red]Command not found. Please ensure required dependencies are installed.[/red]"
908
- )
909
- return 1
910
- except Exception as e:
911
- _console.print(f"[red]Installation error: {e}[/red]")
912
- return 1
910
+ except Exception as e:
911
+ _console.print(f"[red]Installation error: {e}[/red]")
912
+ return 1
913
913
 
914
914
  try:
915
915
  return asyncio.run(install_agent_async())