elva-cli 0.4.0__tar.gz → 1.0.0__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 (149) hide show
  1. elva_cli-1.0.0/CHANGELOG.md +40 -0
  2. elva_cli-1.0.0/PKG-INFO +764 -0
  3. elva_cli-1.0.0/README.md +733 -0
  4. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/_version.py +2 -2
  5. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/auth/__init__.py +2 -0
  6. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/auth/session.py +110 -17
  7. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/commands/auth.py +14 -0
  8. elva_cli-1.0.0/src/elva_cli/commands/collection.py +165 -0
  9. elva_cli-1.0.0/src/elva_cli/commands/config.py +65 -0
  10. elva_cli-1.0.0/src/elva_cli/commands/import_.py +223 -0
  11. elva_cli-1.0.0/src/elva_cli/commands/mcp.py +319 -0
  12. elva_cli-1.0.0/src/elva_cli/commands/workspace.py +75 -0
  13. elva_cli-1.0.0/src/elva_cli/core/api/collections.py +82 -0
  14. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/api/http.py +96 -17
  15. elva_cli-1.0.0/src/elva_cli/core/api/identity.py +21 -0
  16. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/api/targets.py +40 -27
  17. elva_cli-1.0.0/src/elva_cli/core/collections.py +331 -0
  18. elva_cli-1.0.0/src/elva_cli/core/openapi_ops.py +147 -0
  19. elva_cli-1.0.0/src/elva_cli/core/services/auth.py +400 -0
  20. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/auth_result.py +5 -0
  21. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/config.py +52 -0
  22. elva_cli-1.0.0/src/elva_cli/core/services/import_postman.py +742 -0
  23. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/import_spec.py +144 -116
  24. elva_cli-1.0.0/src/elva_cli/core/services/mcp.py +137 -0
  25. elva_cli-1.0.0/src/elva_cli/core/services/mcp_common.py +54 -0
  26. elva_cli-1.0.0/src/elva_cli/core/services/mcp_create.py +291 -0
  27. elva_cli-1.0.0/src/elva_cli/core/services/mcp_create_result.py +37 -0
  28. elva_cli-1.0.0/src/elva_cli/core/services/mcp_logs.py +338 -0
  29. elva_cli-1.0.0/src/elva_cli/core/services/mcp_logs_result.py +31 -0
  30. elva_cli-1.0.0/src/elva_cli/core/services/mcp_publish.py +73 -0
  31. elva_cli-1.0.0/src/elva_cli/core/services/mcp_result.py +36 -0
  32. elva_cli-1.0.0/src/elva_cli/core/services/postman_result.py +54 -0
  33. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/whoami.py +11 -19
  34. elva_cli-1.0.0/src/elva_cli/core/services/workspace_list.py +99 -0
  35. elva_cli-1.0.0/src/elva_cli/core/services/workspace_list_result.py +20 -0
  36. elva_cli-1.0.0/src/elva_cli/core/services/workspace_switch.py +121 -0
  37. elva_cli-1.0.0/src/elva_cli/core/services/workspace_switch_result.py +11 -0
  38. elva_cli-1.0.0/src/elva_cli/core/spec/fetch.py +80 -0
  39. elva_cli-1.0.0/src/elva_cli/core/spec/normalize.py +58 -0
  40. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/errors.py +16 -0
  41. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/registry.py +4 -1
  42. elva_cli-1.0.0/src/elva_cli/safe_text.py +31 -0
  43. elva_cli-1.0.0/src/elva_cli/settings/writer.py +178 -0
  44. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/console.py +8 -0
  45. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/output.py +30 -2
  46. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/prompts.py +39 -2
  47. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/__init__.py +6 -0
  48. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/auth.py +11 -1
  49. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/base.py +17 -0
  50. elva_cli-1.0.0/src/elva_cli/ui/renderables/collection.py +113 -0
  51. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/config.py +17 -1
  52. elva_cli-1.0.0/src/elva_cli/ui/renderables/mcp.py +47 -0
  53. elva_cli-1.0.0/src/elva_cli/ui/renderables/mcp_create.py +65 -0
  54. elva_cli-1.0.0/src/elva_cli/ui/renderables/mcp_logs.py +40 -0
  55. elva_cli-1.0.0/src/elva_cli/ui/renderables/postman.py +83 -0
  56. elva_cli-1.0.0/src/elva_cli/ui/renderables/workspace.py +60 -0
  57. elva_cli-1.0.0/src/elva_cli/ui/secrets.py +45 -0
  58. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/conftest.py +1 -1
  59. elva_cli-1.0.0/tests/cli/test_auth_register_command.py +18 -0
  60. elva_cli-1.0.0/tests/cli/test_collection_command.py +83 -0
  61. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_config_command.py +2 -1
  62. elva_cli-1.0.0/tests/cli/test_config_write.py +213 -0
  63. elva_cli-1.0.0/tests/cli/test_import_postman_command.py +128 -0
  64. elva_cli-1.0.0/tests/cli/test_mcp_command.py +46 -0
  65. elva_cli-1.0.0/tests/cli/test_mcp_create_command.py +77 -0
  66. elva_cli-1.0.0/tests/cli/test_mcp_logs_command.py +52 -0
  67. elva_cli-1.0.0/tests/cli/test_mcp_publish_command.py +34 -0
  68. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_never_blocks.py +13 -2
  69. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_output_streams.py +2 -1
  70. elva_cli-1.0.0/tests/cli/test_workspace_switch_command.py +62 -0
  71. elva_cli-1.0.0/tests/unit/test_collection_endpoints.py +233 -0
  72. elva_cli-1.0.0/tests/unit/test_collection_endpoints_flow.py +231 -0
  73. elva_cli-1.0.0/tests/unit/test_collection_show.py +152 -0
  74. elva_cli-1.0.0/tests/unit/test_collections_flow.py +360 -0
  75. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_http.py +126 -0
  76. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_import_flow.py +384 -28
  77. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_login_flow.py +21 -4
  78. elva_cli-1.0.0/tests/unit/test_mcp_create_flow.py +484 -0
  79. elva_cli-1.0.0/tests/unit/test_mcp_create_operations.py +46 -0
  80. elva_cli-1.0.0/tests/unit/test_mcp_flow.py +219 -0
  81. elva_cli-1.0.0/tests/unit/test_mcp_logs_flow.py +425 -0
  82. elva_cli-1.0.0/tests/unit/test_mcp_publish_flow.py +176 -0
  83. elva_cli-1.0.0/tests/unit/test_openapi_ops.py +200 -0
  84. elva_cli-1.0.0/tests/unit/test_postman_flow.py +1256 -0
  85. elva_cli-1.0.0/tests/unit/test_refresh_client.py +273 -0
  86. elva_cli-1.0.0/tests/unit/test_register_flow.py +245 -0
  87. elva_cli-1.0.0/tests/unit/test_safe_output.py +127 -0
  88. elva_cli-1.0.0/tests/unit/test_secret_input.py +135 -0
  89. elva_cli-1.0.0/tests/unit/test_secrets.py +47 -0
  90. elva_cli-1.0.0/tests/unit/test_settings_writer.py +178 -0
  91. elva_cli-1.0.0/tests/unit/test_spec_fetch.py +174 -0
  92. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_targets.py +12 -4
  93. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_whoami_flow.py +11 -11
  94. elva_cli-1.0.0/tests/unit/test_workspace_list.py +149 -0
  95. elva_cli-1.0.0/tests/unit/test_workspace_render.py +94 -0
  96. elva_cli-1.0.0/tests/unit/test_workspace_switch.py +166 -0
  97. elva_cli-0.4.0/PKG-INFO +0 -292
  98. elva_cli-0.4.0/README.md +0 -261
  99. elva_cli-0.4.0/src/elva_cli/commands/config.py +0 -25
  100. elva_cli-0.4.0/src/elva_cli/commands/import_.py +0 -94
  101. elva_cli-0.4.0/src/elva_cli/core/services/auth.py +0 -197
  102. {elva_cli-0.4.0 → elva_cli-1.0.0}/.gitignore +0 -0
  103. {elva_cli-0.4.0 → elva_cli-1.0.0}/pyproject.toml +0 -0
  104. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/__init__.py +0 -0
  105. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/__main__.py +0 -0
  106. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/auth/models.py +0 -0
  107. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/auth/store.py +0 -0
  108. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/commands/__init__.py +0 -0
  109. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/commands/whoami.py +0 -0
  110. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/context.py +0 -0
  111. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/__init__.py +0 -0
  112. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/api/__init__.py +0 -0
  113. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/__init__.py +0 -0
  114. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/import_result.py +0 -0
  115. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/services/whoami_result.py +0 -0
  116. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/spec/__init__.py +0 -0
  117. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/core/spec/detect.py +0 -0
  118. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/logging.py +0 -0
  119. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/main.py +0 -0
  120. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/settings/__init__.py +0 -0
  121. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/settings/loader.py +0 -0
  122. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/settings/models.py +0 -0
  123. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/settings/paths.py +0 -0
  124. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/telemetry.py +0 -0
  125. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/__init__.py +0 -0
  126. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/import_spec.py +0 -0
  127. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/renderables/whoami.py +0 -0
  128. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/theme.py +0 -0
  129. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/ui/views/__init__.py +0 -0
  130. {elva_cli-0.4.0 → elva_cli-1.0.0}/src/elva_cli/update.py +0 -0
  131. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_auth_logout_command.py +0 -0
  132. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_cli_exit_codes.py +0 -0
  133. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_import_command.py +0 -0
  134. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_lazy_imports.py +0 -0
  135. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/cli/test_whoami_command.py +0 -0
  136. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_boundary.py +0 -0
  137. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_context.py +0 -0
  138. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_credentials.py +0 -0
  139. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_error_boundary.py +0 -0
  140. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_errors.py +0 -0
  141. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_exit_codes.py +0 -0
  142. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_interactivity.py +0 -0
  143. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_logout_flow.py +0 -0
  144. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_output.py +0 -0
  145. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_prompts.py +0 -0
  146. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_session.py +0 -0
  147. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_settings_loader.py +0 -0
  148. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_spec_detect.py +0 -0
  149. {elva_cli-0.4.0 → elva_cli-1.0.0}/tests/unit/test_token_store.py +0 -0
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ### Added
6
+ - **Identify as a first-class refresh client (ELVA-200).** Every request now
7
+ sends `X-Elva-Client: cli` and a `User-Agent: elva-cli/<version>`. The refresh
8
+ and CLI-login exchanges carry the marker so the backend routes them on the
9
+ body-token path and, once its compatibility flag is turned off, does not
10
+ reject the CLI as an unmarked client.
11
+ - **Refresh-and-retry on 401.** An idempotent request (GET/HEAD) that returns
12
+ 401 on a token that looked valid now forces one refresh and retries once.
13
+ Non-idempotent requests (the spec upload) are never auto-replayed.
14
+ - **Backoff on transient refresh failures.** A refresh that hits 429/5xx or a
15
+ network error is retried with backoff (1s/2s/4s) before surfacing as a
16
+ transient `ApiError` (exit 5); it never forces a re-login.
17
+
18
+ ### Changed
19
+ - Refresh continues to happen proactively ~60s before the access token expires
20
+ and to persist the rotated token atomically (temp file + rename, 0600) before
21
+ the response is used — unchanged, but now covered by explicit tests.
22
+ - **`elva import spec --url` now fetches through Elva and uploads like a file.**
23
+ The URL is fetched via Elva's `fetch-file` proxy (the same path the web app
24
+ uses, so a spec host only Elva can reach still works), a JSON spec is stored
25
+ as YAML to match a web-app import instead of one minified line, and `--name`
26
+ now defaults from the fetched spec's `info.title`. `--dry-run --url` reports
27
+ the real title/version/endpoint count/size, and a spec URL that 404s or times
28
+ out is now a usage error (exit 2) rather than a late server rejection. Local
29
+ `.json` files are converted to YAML on import for the same consistency.
30
+
31
+ ### Compatibility
32
+ This version works with **both** the flagged and the unflagged backend:
33
+ - While the backend keeps `AUTH_ALLOW_BODY_REFRESH_TOKEN` on, unmarked body
34
+ refreshes still work, so **older CLI versions keep working** too.
35
+ - Once the backend turns that flag off (this CLI version being the minimum
36
+ supported), the server rejects unmarked and legacy ("family-less") refresh
37
+ tokens with `401 REFRESH_TOKEN_LEGACY`. This CLI maps that to
38
+ *"Your session has expired. Run `elva auth login` to sign in again."*
39
+ (exit code 3). **Older CLI versions stop working at that point** and users
40
+ must upgrade and re-login once.