astra-cli-agent 0.1.2__tar.gz → 0.1.4__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 (148) hide show
  1. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/.env.example +7 -0
  2. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/HANDOFF.md +298 -135
  3. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/PKG-INFO +59 -3
  4. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/README.md +58 -2
  5. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/pyproject.toml +1 -1
  6. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/git_agent.py +6 -2
  7. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/chat.py +4 -0
  8. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/setup.py +86 -0
  9. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/single.py +7 -1
  10. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/litellm_client.py +7 -0
  11. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/git/backend.py +3 -2
  12. astra_cli_agent-0.1.4/src/astra/tools/git/github_backend.py +305 -0
  13. astra_cli_agent-0.1.4/src/astra/tools/git/tools.py +121 -0
  14. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_git_backend.py +42 -0
  15. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_git_tools.py +22 -1
  16. astra_cli_agent-0.1.4/tests/unit/test_github_backend.py +212 -0
  17. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_setup.py +112 -1
  18. astra_cli_agent-0.1.2/src/astra/tools/git/tools.py +0 -55
  19. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/.github/workflows/ci.yml +0 -0
  20. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/.github/workflows/release.yml +0 -0
  21. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/.gitignore +0 -0
  22. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/LICENSE +0 -0
  23. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/docs/ARCHITECTURE.md +0 -0
  24. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/__init__.py +0 -0
  25. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/__init__.py +0 -0
  26. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/base.py +0 -0
  27. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/coder_agent.py +0 -0
  28. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/debug_agent.py +0 -0
  29. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/docker_agent.py +0 -0
  30. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/documentation_agent.py +0 -0
  31. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/file_agent.py +0 -0
  32. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/kubernetes_agent.py +0 -0
  33. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/mcp_agent.py +0 -0
  34. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/memory_agent.py +0 -0
  35. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/planner_agent.py +0 -0
  36. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/research_agent.py +0 -0
  37. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/retrieve_agent.py +0 -0
  38. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/agents/reviewer_agent.py +0 -0
  39. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/__init__.py +0 -0
  40. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/app.py +0 -0
  41. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/ingest.py +0 -0
  42. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/mcp.py +0 -0
  43. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/memory.py +0 -0
  44. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/cli/rendering.py +0 -0
  45. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/config/__init__.py +0 -0
  46. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/config/defaults.yaml +0 -0
  47. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/config/profiles/.gitkeep +0 -0
  48. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/__init__.py +0 -0
  49. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/confirm.py +0 -0
  50. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/events.py +0 -0
  51. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/exceptions.py +0 -0
  52. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/graph.py +0 -0
  53. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/json_stream.py +0 -0
  54. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/onboarding.py +0 -0
  55. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/settings.py +0 -0
  56. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/core/state.py +0 -0
  57. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/__init__.py +0 -0
  58. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/cost.py +0 -0
  59. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/ollama_client.py +0 -0
  60. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/provider.py +0 -0
  61. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/llm/router.py +0 -0
  62. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/__init__.py +0 -0
  63. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/chunking.py +0 -0
  64. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/embeddings.py +0 -0
  65. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/models.py +0 -0
  66. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/retriever.py +0 -0
  67. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/store.py +0 -0
  68. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/memory/vector_store.py +0 -0
  69. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/models/__init__.py +0 -0
  70. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/models/tool_result.py +0 -0
  71. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/prompts/.gitkeep +0 -0
  72. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/__init__.py +0 -0
  73. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/code/__init__.py +0 -0
  74. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/code/backend.py +0 -0
  75. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/code/tools.py +0 -0
  76. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/docker/__init__.py +0 -0
  77. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/docker/backend.py +0 -0
  78. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/docker/tools.py +0 -0
  79. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/filesystem/__init__.py +0 -0
  80. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/filesystem/backend.py +0 -0
  81. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/filesystem/tools.py +0 -0
  82. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/git/__init__.py +0 -0
  83. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/kubernetes/__init__.py +0 -0
  84. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/kubernetes/backend.py +0 -0
  85. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/kubernetes/tools.py +0 -0
  86. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/mcp/__init__.py +0 -0
  87. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/mcp/backend.py +0 -0
  88. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/mcp/client.py +0 -0
  89. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/mcp/discovery.py +0 -0
  90. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/registry.py +0 -0
  91. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/shell/__init__.py +0 -0
  92. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/shell/backend.py +0 -0
  93. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/shell/tools.py +0 -0
  94. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/web/__init__.py +0 -0
  95. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/web/backend.py +0 -0
  96. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/tools/web/tools.py +0 -0
  97. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/utils/__init__.py +0 -0
  98. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/src/astra/utils/logging.py +0 -0
  99. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/e2e/.gitkeep +0 -0
  100. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/e2e/test_e2e_live_groq.py +0 -0
  101. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/fixtures/mcp_fixture_server.py +0 -0
  102. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/.gitkeep +0 -0
  103. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/_helpers.py +0 -0
  104. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/conftest.py +0 -0
  105. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/test_cli_ask.py +0 -0
  106. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/test_cli_confirm_gate.py +0 -0
  107. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/test_cli_ingest_and_retrieval.py +0 -0
  108. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/test_cli_mcp.py +0 -0
  109. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/integration/test_cli_run_pipeline.py +0 -0
  110. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/.gitkeep +0 -0
  111. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/conftest.py +0 -0
  112. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_agents.py +0 -0
  113. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_chat.py +0 -0
  114. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_chunking.py +0 -0
  115. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_cli.py +0 -0
  116. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_code_backend.py +0 -0
  117. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_code_tools.py +0 -0
  118. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_docker_agent.py +0 -0
  119. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_docker_backend.py +0 -0
  120. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_docker_tools.py +0 -0
  121. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_file_agent.py +0 -0
  122. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_filesystem_backend.py +0 -0
  123. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_filesystem_tools.py +0 -0
  124. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_git_agent.py +0 -0
  125. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_graph.py +0 -0
  126. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_json_stream.py +0 -0
  127. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_kubernetes_agent.py +0 -0
  128. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_kubernetes_backend.py +0 -0
  129. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_kubernetes_tools.py +0 -0
  130. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_llm_adapters.py +0 -0
  131. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_llm_cost.py +0 -0
  132. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_llm_router.py +0 -0
  133. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_llm_router_streaming.py +0 -0
  134. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_mcp_agent.py +0 -0
  135. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_mcp_backend.py +0 -0
  136. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_mcp_client.py +0 -0
  137. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_mcp_discovery.py +0 -0
  138. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_mcp_http_transport.py +0 -0
  139. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_memory_agent.py +0 -0
  140. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_memory_store.py +0 -0
  141. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_onboarding.py +0 -0
  142. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_rag_e2e.py +0 -0
  143. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_research_agent.py +0 -0
  144. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_shell_backend.py +0 -0
  145. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_shell_tools.py +0 -0
  146. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_vector_store.py +0 -0
  147. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_web_backend.py +0 -0
  148. {astra_cli_agent-0.1.2 → astra_cli_agent-0.1.4}/tests/unit/test_web_tools.py +0 -0
@@ -9,6 +9,13 @@ GROQ_API_KEY=
9
9
  # Local Ollama server (optional last-resort fallback)
10
10
  OLLAMA_HOST=http://localhost:11434
11
11
 
12
+ # Optional GitHub API access (the git agent's github_* tools: create/delete repos, issues,
13
+ # pull requests, and authenticated push/pull against private repos). Generate a fine-grained
14
+ # personal access token at https://github.com/settings/tokens with repo scope. Leaving
15
+ # GITHUB_TOKEN unset simply disables these tools; local git operations (status/diff/commit/
16
+ # push to a public or already-authenticated remote/etc.) work without it.
17
+ GITHUB_TOKEN=
18
+
12
19
  # Optional general web search (the research agent's `web_search_general` tool). Uses SerpApi
13
20
  # (https://serpapi.com) to run a real Google search. Leaving SERPAPI_KEY unset simply disables
14
21
  # `web_search_general`; the GitHub/StackOverflow/fetch tools work without it.
@@ -6,9 +6,14 @@ The living architecture doc is [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) —
6
6
  too for the full target design. This file is the "where are we right now" companion.
7
7
 
8
8
  Last updated: 2026-07-11, end of Phase 18 + a post-18 hardening pass (see §7) that closed
9
- six of the "known simplifications" from §3, plus a post-18 addendum (see §5) that verified
10
- CI is actually live on GitHub, resolved a PyPI naming collision (renamed to
11
- `astra-cli-agent`), and added first-run `astra setup` provider onboarding.
9
+ six of the "known simplifications" from §3, a post-18 addendum (see §9) that verified CI is
10
+ actually live on GitHub, resolved a PyPI naming collision (renamed to `astra-cli-agent`),
11
+ and added first-run `astra setup` provider onboarding, and a public-release pass (see §10)
12
+ that actually published `astra-cli-agent` to PyPI (v0.1.0–v0.1.2), stood up a public
13
+ README-only GitHub repo, and gave the CLI a real ASCII-logo presence. **The project is
14
+ fully shipped and installable** (`pip install astra-cli-agent`) — everything left open is
15
+ either a nice-to-have (LangSmith tracing needs a working key) or infra the user owns
16
+ (kubernetes cluster for a handful of skipped tests).
12
17
 
13
18
  ---
14
19
 
@@ -1388,138 +1393,9 @@ running on every future `pytest -q`, whereas the manual checks in Phases 3–16
1388
1393
  ~~17. Full test pass — integration + e2e tests (`tests/integration/`, `tests/e2e/`).~~ —
1389
1394
  **done, see Phase 17 above.**
1390
1395
  ~~18. Packaging/CI/CD — GitHub Actions (`.github/workflows/`), PyPI trusted-publishing release
1391
- automation.~~ — **code-complete, see Phase 18 above. Not yet proven against real GitHub/PyPI
1392
- infrastructure no remote pushed yet, no trusted publisher registered on PyPI yet.**
1393
-
1394
- ---
1395
-
1396
- ## 5. Post-Phase-18 addendum (2026-07-11): CI verified live, PyPI rename, first-run onboarding
1397
-
1398
- This session found Phase 18's "known gap" note (§4 above, "CI never run on real GitHub
1399
- infrastructure") was **stale** — a remote had since been added and pushed outside of a
1400
- tracked phase. Checked directly: `git remote -v` shows `origin` →
1401
- `github.com/Subharjun/astra-cli` (private), `git log` shows two commits already pushed to
1402
- `main`, and `gh run list` shows both pushes triggered a real `CI` workflow run on GitHub's
1403
- infrastructure — both green. **Nothing left to do for CI itself.** Whoever picks this up
1404
- next should open PRs against `main` going forward rather than pushing directly, now that
1405
- CI is live and would actually gate them.
1406
-
1407
- **PyPI blocker found and resolved**: `astra-cli` (the name Phase 18 assumed would be
1408
- registered) is already taken on PyPI by an unrelated project (a different "Astra agent
1409
- framework" CLI, owned by a different PyPI user). Confirmed via `curl
1410
- https://pypi.org/pypi/astra-cli/json` returning a real, different project's metadata, not
1411
- a 404. **Renamed the PyPI distribution name to `astra-cli-agent`** (confirmed available via
1412
- a 404 check first) in `pyproject.toml`'s `[project].name` — **the installed console command
1413
- stays `astra`** (`[project.scripts]` unchanged), so this is a packaging-metadata-only
1414
- rename, not a UX change. `docs/ARCHITECTURE.md`'s install-target line and `README.md`
1415
- updated to match; `.github/workflows/release.yml` needed no changes since it reads the name
1416
- from `pyproject.toml` rather than hardcoding it. **Still needs a human**: registering
1417
- `astra-cli-agent` on PyPI, adding the trusted-publisher entry (repo + `release.yml` +
1418
- `pypi` environment name), and creating the `pypi` GitHub Environment — none of that is
1419
- executable from inside a coding session. Step-by-step instructions for that are now in
1420
- README.md's "Releasing (maintainers)" section.
1421
-
1422
- **New: `astra setup` — first-run provider onboarding**, the same "prompt for what's needed
1423
- before doing anything else" pattern other terminal AI CLIs use, since Astra previously just
1424
- failed with a raw `AllProvidersFailedError` if no `.env` had been hand-edited yet.
1425
- - `core/onboarding.py`: `configured_providers()` (which of `GROQ_API_KEY`/
1426
- `ANTHROPIC_API_KEY`/`OPENAI_API_KEY` are non-empty in the environment) and
1427
- `is_provider_configured()`. Ollama needs no key, so a completed wizard run always writes
1428
- an `ASTRA_SETUP_COMPLETE=true` marker to `~/.astra/.env` regardless of which provider was
1429
- chosen — otherwise an Ollama-only setup would trigger onboarding forever.
1430
- - `cli/setup.py`: `astra setup` — an interactive loop over Groq/Anthropic/OpenAI/Ollama.
1431
- For a cloud provider, the key is tested with one real, cheap completion call
1432
- (`temperature=0, max_tokens=5`, "reply with exactly: ok") **before** being saved, using
1433
- the same `LiteLLMClient`/`OllamaClient` adapters the real router uses — not a separate
1434
- validation path that could drift from what actually works. A failed test doesn't silently
1435
- discard the key; the user is asked whether to save it anyway (e.g. a transient network
1436
- blip). `_write_env_vars()` updates `~/.astra/.env` in place, preserving unrelated lines
1437
- and replacing an existing key rather than duplicating it, and applies the same values to
1438
- `os.environ` immediately so the rest of that process sees them with no restart needed.
1439
- Loops until the user declines "configure another provider" (recommended, since
1440
- `FallbackRouter` only has something to fall back to if more than one is configured).
1441
- - `ensure_provider_or_prompt()` is called at the top of `ask`, `run` (i.e. `astra
1442
- "<prompt>"`), and `chat` — the three commands that actually make an LLM call — before
1443
- they touch the graph/router at all. If nothing is configured, it offers to run the wizard
1444
- right there (`typer.confirm`, default yes); declining prints how to run `astra setup`
1445
- later and exits cleanly (code 1) instead of a raw provider-chain stack trace. `hello`
1446
- deliberately does **not** force this (it's meant to stay a side-effect-free sanity check)
1447
- — it now just reports provider status passively (`LLM provider configured: groq` or a
1448
- yellow "run astra setup" nudge).
1449
- - `"setup"` added to `cli/app.py`'s `_KNOWN_COMMANDS` (same manual-upkeep gotcha flagged in
1450
- §3 — every new top-level command needs an entry here or `resolve_argv` mis-rewrites it).
1451
-
1452
- Tests: `tests/unit/test_onboarding.py` (5, pure env-var logic), `tests/unit/test_setup.py`
1453
- (12, `monkeypatch`-injected fake `LiteLLMClient`/`OllamaClient` + a `typer.prompt`/
1454
- `typer.confirm` fake-queue harness + a `tmp_path`-redirected `USER_CONFIG_DIR` — covering
1455
- the env-file write/preserve/replace behavior, a working-key save, a bad-key decline, a
1456
- bad-key "save anyway", Ollama configuration, an empty-key skip, the full wizard's
1457
- save-marker-after-one-provider path, and all three `ensure_provider_or_prompt` branches),
1458
- plus one new case in `tests/unit/test_cli.py` (`setup` recognized by `resolve_argv`). Full
1459
- suite: 289 passed + 36 skipped (unchanged kubernetes-cluster skip count), `ruff check .` and
1460
- `mypy src` (strict) both clean.
1461
-
1462
- **Verified live** (real Groq calls, two disposable `$HOME` sandboxes, never touching the
1463
- real `~/.astra`): direct call to `_test_cloud_provider("groq", ...)` with the real key from
1464
- this repo's `.env` → genuine `'ok'` response, proving the wizard's key-test path itself
1465
- works against the real API, not just mocked tests. Full interactive wizard end-to-end via a
1466
- piped-stdin `astra setup` run against a real Groq key in a fresh sandbox `$HOME` → real
1467
- `✓ got a real response from groq/llama-3.3-70b-versatile: 'ok'`, key + completion marker
1468
- written to that sandbox's `~/.astra/.env`. Separately, `astra ask "hello"` in a **different**
1469
- fresh sandbox `$HOME` with zero providers configured → the auto-prompt fired
1470
- ("No LLM provider is configured yet... Run the setup wizard now?"), walked through the full
1471
- wizard with a deliberately invalid key, correctly reported the real Groq `invalid_api_key`
1472
- error, saved it anyway on user confirmation, then proceeded to actually attempt the real
1473
- request — which failed for the expected reason (bad key) with the real
1474
- `AllProvidersFailedError` chain, proving `ensure_provider_or_prompt()` actually gates the
1475
- call rather than just running cosmetically. `astra hello` confirmed to report
1476
- `LLM provider configured: groq` correctly in this repo's own already-configured environment
1477
- without prompting (passive path).
1478
-
1479
- **Caught by real CI, not by local testing**: pushing the onboarding change broke 8 of the
1480
- 10 `tests/integration/` tests on GitHub's runner (green locally beforehand) —
1481
- `ensure_provider_or_prompt()` only checks provider API-key env vars, so it didn't know
1482
- `patch_router()` (the integration suite's helper for swapping in a `FakeRouter`) had
1483
- already made the pipeline fully working; it blocked on a real `typer.confirm` prompt with
1484
- no piped stdin and aborted. Invisible locally because this repo's own `.env` (real Groq
1485
- key, gitignored) always made `is_provider_configured()` true regardless of the bug —
1486
- GitHub's runner has no such file, by design (§4 item 15/CI notes: no `GROQ_API_KEY` secret
1487
- configured, deliberately, so CI never spends real API money). Fixed by having
1488
- `tests/integration/_helpers.py`'s `patch_router()` also `monkeypatch.setenv("GROQ_API_KEY",
1489
- "test-fake-key")` — it's already simulating a working provider, so the gate should see one
1490
- too. Reverified **the actual failure mode**, not just the fix, by temporarily moving this
1491
- repo's real `.env` aside and re-running `tests/integration/` in a fresh `$HOME`: all 10
1492
- failed the same way pre-fix, all 10 passed post-fix — then pushed again and confirmed the
1493
- real GitHub Actions run went green. This is exactly the kind of gap `tests/integration/`
1494
- (Phase 17) exists to catch and mostly did — except a gate that behaves differently based on
1495
- ambient env state needs either a credential-free CI runner (which this repo already has) or
1496
- a local repro with the same env, and this session's first local check used the wrong one.
1497
-
1498
- ⚠️ **Unrelated pre-existing issue noticed, not fixed (out of scope for this session)**:
1499
- during the bad-key live test above, the fallback chain's `anthropic` attempt failed with
1500
- `litellm.UnsupportedParamsError: claude-sonnet-5 does not support temperature=0.2. Only
1501
- temperature=1 is supported.` — `defaults.yaml`'s `llm.temperature: 0.2` default is
1502
- incompatible with the `claude-sonnet-5` model name in the same file's fallback chain.
1503
- Whoever next touches `llm/router.py` or `config/defaults.yaml` should either drop
1504
- `temperature` for Anthropic calls or pin a different default model — flagging here so it
1505
- isn't mistaken for something this session broke.
1506
-
1507
- All 18 phases from the architecture doc's phase list are now built. What's left:
1508
- 1. ~~**Prove `ci.yml` actually runs**~~ — **closed in §8**: a GitHub remote now exists
1509
- (`https://github.com/Subharjun/astra-cli`, private), pushed, and the push-triggered `ci.yml`
1510
- run went fully green on real GitHub-hosted infrastructure (checkout → Python 3.12 → `uv`
1511
- install → ruff → mypy → pytest, 3m32s). See §8 for the run details.
1512
- 2. **Prove `release.yml` actually publishes**: register `astra-cli` as a PyPI project, add a
1513
- trusted publisher entry pointing at this repo (see Phase 18's section above for the exact
1514
- fields needed), create the `pypi` GitHub Environment, then cut a real `v0.1.0` GitHub Release
1515
- and confirm the package actually lands on PyPI.
1516
- 3. **Live-verify Phase 15's LangSmith tracing** if a working `lsv2_...` key turns up — both keys
1517
- tried in that session were rejected with `403 Forbidden`, so this is still only code-complete,
1518
- not confirmed working end-to-end.
1519
-
1520
- Neither remaining item blocks calling the project "done" in the sense the original 18-phase plan
1521
- meant — they're external-account-setup steps (PyPI trusted-publisher registration, a valid
1522
- LangSmith key) that fall outside what a coding session alone can complete.
1396
+ automation.~~ — **fully proven, not just code-complete see §8 (CI verified live on real
1397
+ GitHub infrastructure) and §9/§10 (PyPI package actually published and installable as
1398
+ `astra-cli-agent`, real GitHub Releases cut for v0.1.0/v0.1.1/v0.1.2).**
1523
1399
 
1524
1400
  ---
1525
1401
 
@@ -1750,3 +1626,290 @@ credential-blocked live search test now passes for real instead of skipping), `r
1750
1626
 
1751
1627
  **Verified live**: `gh run list` / `gh run watch` against the real run — every step (`Ruff`,
1752
1628
  `Mypy`, `Pytest`) shows a genuine ✓ from the GitHub-hosted runner.
1629
+
1630
+ ---
1631
+
1632
+ ## 9. Post-Phase-18 addendum (2026-07-11): CI verified live, PyPI rename, first-run onboarding
1633
+
1634
+ This session found Phase 18's "known gap" note (§4 above, "CI never run on real GitHub
1635
+ infrastructure") was **stale** — a remote had since been added and pushed outside of a
1636
+ tracked phase. Checked directly: `git remote -v` shows `origin` →
1637
+ `github.com/Subharjun/astra-cli` (private), `git log` shows two commits already pushed to
1638
+ `main`, and `gh run list` shows both pushes triggered a real `CI` workflow run on GitHub's
1639
+ infrastructure — both green. **Nothing left to do for CI itself.** Whoever picks this up
1640
+ next should open PRs against `main` going forward rather than pushing directly, now that
1641
+ CI is live and would actually gate them.
1642
+
1643
+ **PyPI blocker found and resolved**: `astra-cli` (the name Phase 18 assumed would be
1644
+ registered) is already taken on PyPI by an unrelated project (a different "Astra agent
1645
+ framework" CLI, owned by a different PyPI user). Confirmed via `curl
1646
+ https://pypi.org/pypi/astra-cli/json` returning a real, different project's metadata, not
1647
+ a 404. **Renamed the PyPI distribution name to `astra-cli-agent`** (confirmed available via
1648
+ a 404 check first) in `pyproject.toml`'s `[project].name` — **the installed console command
1649
+ stays `astra`** (`[project.scripts]` unchanged), so this is a packaging-metadata-only
1650
+ rename, not a UX change. `docs/ARCHITECTURE.md`'s install-target line and `README.md`
1651
+ updated to match; `.github/workflows/release.yml` needed no changes since it reads the name
1652
+ from `pyproject.toml` rather than hardcoding it. **Still needs a human**: registering
1653
+ `astra-cli-agent` on PyPI, adding the trusted-publisher entry (repo + `release.yml` +
1654
+ `pypi` environment name), and creating the `pypi` GitHub Environment — none of that is
1655
+ executable from inside a coding session. Step-by-step instructions for that are now in
1656
+ README.md's "Releasing (maintainers)" section.
1657
+
1658
+ **New: `astra setup` — first-run provider onboarding**, the same "prompt for what's needed
1659
+ before doing anything else" pattern other terminal AI CLIs use, since Astra previously just
1660
+ failed with a raw `AllProvidersFailedError` if no `.env` had been hand-edited yet.
1661
+ - `core/onboarding.py`: `configured_providers()` (which of `GROQ_API_KEY`/
1662
+ `ANTHROPIC_API_KEY`/`OPENAI_API_KEY` are non-empty in the environment) and
1663
+ `is_provider_configured()`. Ollama needs no key, so a completed wizard run always writes
1664
+ an `ASTRA_SETUP_COMPLETE=true` marker to `~/.astra/.env` regardless of which provider was
1665
+ chosen — otherwise an Ollama-only setup would trigger onboarding forever.
1666
+ - `cli/setup.py`: `astra setup` — an interactive loop over Groq/Anthropic/OpenAI/Ollama.
1667
+ For a cloud provider, the key is tested with one real, cheap completion call
1668
+ (`temperature=0, max_tokens=5`, "reply with exactly: ok") **before** being saved, using
1669
+ the same `LiteLLMClient`/`OllamaClient` adapters the real router uses — not a separate
1670
+ validation path that could drift from what actually works. A failed test doesn't silently
1671
+ discard the key; the user is asked whether to save it anyway (e.g. a transient network
1672
+ blip). `_write_env_vars()` updates `~/.astra/.env` in place, preserving unrelated lines
1673
+ and replacing an existing key rather than duplicating it, and applies the same values to
1674
+ `os.environ` immediately so the rest of that process sees them with no restart needed.
1675
+ Loops until the user declines "configure another provider" (recommended, since
1676
+ `FallbackRouter` only has something to fall back to if more than one is configured).
1677
+ - `ensure_provider_or_prompt()` is called at the top of `ask`, `run` (i.e. `astra
1678
+ "<prompt>"`), and `chat` — the three commands that actually make an LLM call — before
1679
+ they touch the graph/router at all. If nothing is configured, it offers to run the wizard
1680
+ right there (`typer.confirm`, default yes); declining prints how to run `astra setup`
1681
+ later and exits cleanly (code 1) instead of a raw provider-chain stack trace. `hello`
1682
+ deliberately does **not** force this (it's meant to stay a side-effect-free sanity check)
1683
+ — it now just reports provider status passively (`LLM provider configured: groq` or a
1684
+ yellow "run astra setup" nudge).
1685
+ - `"setup"` added to `cli/app.py`'s `_KNOWN_COMMANDS` (same manual-upkeep gotcha flagged in
1686
+ §3 — every new top-level command needs an entry here or `resolve_argv` mis-rewrites it).
1687
+
1688
+ Tests: `tests/unit/test_onboarding.py` (5, pure env-var logic), `tests/unit/test_setup.py`
1689
+ (12, `monkeypatch`-injected fake `LiteLLMClient`/`OllamaClient` + a `typer.prompt`/
1690
+ `typer.confirm` fake-queue harness + a `tmp_path`-redirected `USER_CONFIG_DIR` — covering
1691
+ the env-file write/preserve/replace behavior, a working-key save, a bad-key decline, a
1692
+ bad-key "save anyway", Ollama configuration, an empty-key skip, the full wizard's
1693
+ save-marker-after-one-provider path, and all three `ensure_provider_or_prompt` branches),
1694
+ plus one new case in `tests/unit/test_cli.py` (`setup` recognized by `resolve_argv`). Full
1695
+ suite: 289 passed + 36 skipped (unchanged kubernetes-cluster skip count), `ruff check .` and
1696
+ `mypy src` (strict) both clean.
1697
+
1698
+ **Verified live** (real Groq calls, two disposable `$HOME` sandboxes, never touching the
1699
+ real `~/.astra`): direct call to `_test_cloud_provider("groq", ...)` with the real key from
1700
+ this repo's `.env` → genuine `'ok'` response, proving the wizard's key-test path itself
1701
+ works against the real API, not just mocked tests. Full interactive wizard end-to-end via a
1702
+ piped-stdin `astra setup` run against a real Groq key in a fresh sandbox `$HOME` → real
1703
+ `✓ got a real response from groq/llama-3.3-70b-versatile: 'ok'`, key + completion marker
1704
+ written to that sandbox's `~/.astra/.env`. Separately, `astra ask "hello"` in a **different**
1705
+ fresh sandbox `$HOME` with zero providers configured → the auto-prompt fired
1706
+ ("No LLM provider is configured yet... Run the setup wizard now?"), walked through the full
1707
+ wizard with a deliberately invalid key, correctly reported the real Groq `invalid_api_key`
1708
+ error, saved it anyway on user confirmation, then proceeded to actually attempt the real
1709
+ request — which failed for the expected reason (bad key) with the real
1710
+ `AllProvidersFailedError` chain, proving `ensure_provider_or_prompt()` actually gates the
1711
+ call rather than just running cosmetically. `astra hello` confirmed to report
1712
+ `LLM provider configured: groq` correctly in this repo's own already-configured environment
1713
+ without prompting (passive path).
1714
+
1715
+ **Caught by real CI, not by local testing**: pushing the onboarding change broke 8 of the
1716
+ 10 `tests/integration/` tests on GitHub's runner (green locally beforehand) —
1717
+ `ensure_provider_or_prompt()` only checks provider API-key env vars, so it didn't know
1718
+ `patch_router()` (the integration suite's helper for swapping in a `FakeRouter`) had
1719
+ already made the pipeline fully working; it blocked on a real `typer.confirm` prompt with
1720
+ no piped stdin and aborted. Invisible locally because this repo's own `.env` (real Groq
1721
+ key, gitignored) always made `is_provider_configured()` true regardless of the bug —
1722
+ GitHub's runner has no such file, by design (§4 item 15/CI notes: no `GROQ_API_KEY` secret
1723
+ configured, deliberately, so CI never spends real API money). Fixed by having
1724
+ `tests/integration/_helpers.py`'s `patch_router()` also `monkeypatch.setenv("GROQ_API_KEY",
1725
+ "test-fake-key")` — it's already simulating a working provider, so the gate should see one
1726
+ too. Reverified **the actual failure mode**, not just the fix, by temporarily moving this
1727
+ repo's real `.env` aside and re-running `tests/integration/` in a fresh `$HOME`: all 10
1728
+ failed the same way pre-fix, all 10 passed post-fix — then pushed again and confirmed the
1729
+ real GitHub Actions run went green. This is exactly the kind of gap `tests/integration/`
1730
+ (Phase 17) exists to catch and mostly did — except a gate that behaves differently based on
1731
+ ambient env state needs either a credential-free CI runner (which this repo already has) or
1732
+ a local repro with the same env, and this session's first local check used the wrong one.
1733
+
1734
+ ⚠️ **Unrelated pre-existing issue noticed, not fixed (out of scope for this session)**:
1735
+ during the bad-key live test above, the fallback chain's `anthropic` attempt failed with
1736
+ `litellm.UnsupportedParamsError: claude-sonnet-5 does not support temperature=0.2. Only
1737
+ temperature=1 is supported.` — `defaults.yaml`'s `llm.temperature: 0.2` default is
1738
+ incompatible with the `claude-sonnet-5` model name in the same file's fallback chain.
1739
+ Whoever next touches `llm/router.py` or `config/defaults.yaml` should either drop
1740
+ `temperature` for Anthropic calls or pin a different default model — flagging here so it
1741
+ isn't mistaken for something this session broke.
1742
+
1743
+ All 18 phases from the architecture doc's phase list are now built. What's left:
1744
+ 1. ~~**Prove `ci.yml` actually runs**~~ — **closed in §8**: a GitHub remote now exists
1745
+ (`https://github.com/Subharjun/astra-cli`, private), pushed, and the push-triggered `ci.yml`
1746
+ run went fully green on real GitHub-hosted infrastructure (checkout → Python 3.12 → `uv`
1747
+ install → ruff → mypy → pytest, 3m32s). See §8 for the run details.
1748
+ 2. ~~**Prove `release.yml` actually publishes**~~ — **closed in §10**: the user registered
1749
+ `astra-cli-agent` (not `astra-cli` — see the PyPI-blocker paragraph above) as a PyPI pending
1750
+ publisher and created the `pypi` GitHub Environment; `v0.1.0` was tagged and released, and
1751
+ the package landed on PyPI for real, confirmed via a fresh-venv `pip install`. See §10.
1752
+ 3. **Live-verify Phase 15's LangSmith tracing** if a working `lsv2_...` key turns up — both keys
1753
+ tried in that session were rejected with `403 Forbidden`, so this is still only code-complete,
1754
+ not confirmed working end-to-end. **Still open** as of §10.
1755
+
1756
+ Neither remaining item blocks calling the project "done" in the sense the original 18-phase plan
1757
+ meant — they're external-account-setup steps (PyPI trusted-publisher registration, a valid
1758
+ LangSmith key) that fall outside what a coding session alone can complete.
1759
+
1760
+ ---
1761
+
1762
+ ## 10. Public release (2026-07-11): PyPI v0.1.0–v0.1.2 shipped, public README repo, big banner
1763
+
1764
+ Continuation of §9 in the same calling session. §9 left two things pending on the user: register
1765
+ `astra-cli-agent` as a PyPI pending publisher, and create the `pypi` GitHub Environment. Both
1766
+ confirmed done — `gh api repos/Subharjun/astra-cli/environments` showed a real `pypi` environment
1767
+ (created `2026-07-11T11:57:25Z`, no protection rules).
1768
+
1769
+ ### v0.1.0: first real PyPI publish
1770
+
1771
+ - Tagged `v0.1.0`, pushed the tag, `gh release create v0.1.0 --generate-notes` — publishing that
1772
+ Release fired `release.yml` for real. Green on the first try (`build` → sdist+wheel →
1773
+ `publish` via PyPI trusted-publishing/OIDC, no token anywhere in the repo).
1774
+ - **Verified live, not just "the workflow said success"**: fresh `python3 -m venv` +
1775
+ `pip install astra-cli-agent` from the real public index, `astra version` → `astra 0.1.0`,
1776
+ `astra hello`, `astra --help` all worked, including the onboarding nudge
1777
+ ("No LLM provider configured yet. Run astra setup to get started.") firing correctly for a
1778
+ genuinely fresh install.
1779
+ - Downloaded the actual published wheel from `files.pythonhosted.org` and grepped its contents
1780
+ for `.env`/secret/key patterns — zero matches, confirming no credentials ship in the package
1781
+ (the user asked directly whether this was possible; answered from direct inspection, not
1782
+ inference).
1783
+
1784
+ ### Public-repo privacy discussion, and what actually got built
1785
+
1786
+ The user wants the source private but still wants a public, installable package. Clarified for
1787
+ the record: the private GitHub repo (`Subharjun/astra-cli`) staying private does **not** make the
1788
+ PyPI package private — PyPI is a public index, and the wheel/sdist contain full `.py` source
1789
+ regardless of GitHub visibility, since Python isn't compiled/obfuscated. There is no "private
1790
+ PyPI project with public `pip install`" without a separate private index (Gemfury/Cloudsmith/
1791
+ self-hosted devpi) or installing straight from the private GitHub repo via `pip install
1792
+ git+https://...`. Presented these options; **user chose to publish to PyPI anyway** (source
1793
+ downloadable via `pip download`/wheel inspection is an accepted tradeoff) but wanted the
1794
+ **GitHub side to show a separate public repo containing only usage instructions, not source**.
1795
+
1796
+ - Created `Subharjun/astra-cli-agent` as a new public GitHub repo (separate from the private
1797
+ `Subharjun/astra-cli`, which stays the real working repo and stays private).
1798
+ - **First attempt was wrong and had to be corrected**: initially pushed the *entire* private
1799
+ repo's history (all source, all commits, the `v0.1.0` tag) to the new public repo — a
1800
+ misreading of "public repo" as "public mirror." User corrected explicitly: *"no no public repo
1801
+ just readme.md file no other just instructions."*
1802
+ - **Fix**: deleted the `v0.1.0` tag from the public repo. Attempted `gh repo delete` to start
1803
+ clean, but `gh`'s token lacks the `delete_repo` scope, and granting it requires an interactive
1804
+ browser OAuth step this non-interactive session can't complete (`gh auth refresh -h github.com
1805
+ -s delete_repo` needs a device-code confirmation in a browser). Instead, sanitized the existing
1806
+ repo: built a fresh orphan git history (`git init` in a scratch dir, one commit containing only
1807
+ `README.md`) and `git push --force` to replace `main` entirely. Verified after the fact via the
1808
+ GitHub API: `main` has exactly 1 commit, `contents/` lists only `README.md`, zero other
1809
+ branches, zero tags. ⚠️ **Known residual caveat, disclosed to the user**: force-replacing history
1810
+ makes the old source-containing commit unreachable from any ref (so it won't appear anywhere in
1811
+ GitHub's UI/history), but without the `delete_repo`+recreate path there's no hard guarantee
1812
+ GitHub has garbage-collected the underlying git objects yet — a direct-SHA lookup could
1813
+ theoretically still resolve for some window. Full delete+recreate remains the only airtight fix,
1814
+ and needs the user (or a session with `delete_repo` scope granted interactively) to do it.
1815
+ - The public repo's `README.md` is a trimmed variant of the main README: badges (PyPI version +
1816
+ Python version only — no CI badge, since no workflow lives in this repo; no license badge/file,
1817
+ since "no other files" was explicit), the same feature table, install/quickstart/config/MCP
1818
+ sections, no "Contributing/development" section (there's no source here to clone/build).
1819
+
1820
+ ### README beautification + LICENSE + pyproject metadata (private repo)
1821
+
1822
+ - `README.md` (private repo) rewritten: leads with badges (PyPI version, Python version, CI
1823
+ status, MIT license), a feature table per agent domain (git/filesystem/shell/docker/k8s/web/
1824
+ debug/docs/MCP), a proper quickstart walking through `astra setup` → example commands → the
1825
+ confirmation-gate behavior, an MCP-server config example, and a "Contributing/development"
1826
+ section — replacing the old stub that just said "early scaffold" and listed two commands.
1827
+ - Added `LICENSE` (MIT) — `pyproject.toml` had declared `license = { text = "MIT" }` since Phase 2
1828
+ but no `LICENSE` file had ever actually been created; added now that the project has real public
1829
+ surface area.
1830
+ - Added `[project.urls]` (`Homepage`, `Issues`) to `pyproject.toml`, pointing at the new public
1831
+ `astra-cli-agent` GitHub repo — no `Repository` key, since that repo is README-only and calling
1832
+ it "the repository" would be misleading about where the source actually lives.
1833
+ - **Real build-breaking bug caught by CI, not locally**: the first `[project.urls]` edit placed
1834
+ the table header *before* the existing `dependencies = [...]` list inside `[project]` — in TOML,
1835
+ a table header ends the previous table, so `dependencies` silently became a key under
1836
+ `[project.urls]` instead of `[project]`. `hatchling` rejected this outright at build time
1837
+ (`TypeError: URL 'dependencies' of field 'project.urls' must be a string`), breaking `pip
1838
+ install`/`uv pip install -e .` entirely. Invisible locally because the dev venv already had the
1839
+ package installed from before the bad edit — first surfaced when CI ran `uv pip install --system
1840
+ -e ".[dev]"` from scratch on the newly-created public-repo push and failed at the install step.
1841
+ Fixed by moving `[project.urls]` after `[project.optional-dependencies]`; reverified with a real
1842
+ `uv pip install -e ".[dev]"` from scratch plus the full test suite before pushing again.
1843
+
1844
+ ### Big ASCII banner (user-requested: "make it appear big... typer or rich")
1845
+
1846
+ User feedback: the CLI's presence "doesn't feel like Claude" and asked for something bigger, using
1847
+ Typer or Rich. `print_banner()` previously wrapped the word "Astra" in a one-line-tall bordered
1848
+ `Panel` — replaced with a real figlet wordmark:
1849
+
1850
+ - New runtime dependency `pyfiglet` (pure Python, zero transitive deps) — lazy-imported inside
1851
+ `print_banner()`, same "pay for it only where it's used" convention `litellm`/
1852
+ `sentence-transformers`/`mcp` already follow, since only three interactive commands need it.
1853
+ - `cli/rendering.py`: `print_banner()` now renders `pyfiglet.figlet_format("ASTRA", font="slant")`
1854
+ as a Rich `Text`, coloring each line with a fixed cyan→violet gradient (`_BANNER_GRADIENT`,
1855
+ 5 hex stops, purely cosmetic — no meaning attached to the specific colors), followed by the
1856
+ "your terminal AI developer assistant" tagline in dim italic.
1857
+ - Wired into `hello` and `setup` (already had the old banner) and **newly into `cli/chat.py`'s
1858
+ `run_chat()`** startup, which previously printed only a plain one-line `"Astra chat"` label with
1859
+ no banner at all.
1860
+ - Deliberately **not** added to `ask`/`run` (`astra "<prompt>"`) — those are also used
1861
+ non-interactively/scripted/piped, and a multi-line ASCII banner on every scripted invocation
1862
+ would be noise, not polish.
1863
+
1864
+ ### Shipped as v0.1.1 — then a real bug found in production, fixed as v0.1.2
1865
+
1866
+ - Bumped `pyproject.toml` to `0.1.1`, tagged, released — `release.yml` published it for real.
1867
+ - **Live-verified in a fresh venv, and this is what caught the bug**: `astra hello` showed the new
1868
+ banner correctly, but `astra version` printed `astra 0.1.0` — one version behind what was just
1869
+ explicitly installed (`pip install astra-cli-agent==0.1.1`).
1870
+ - **Root cause**: `src/astra/__init__.py`'s `__version__` was a hardcoded string literal,
1871
+ completely disconnected from `pyproject.toml`'s `version` field — nothing had ever wired them
1872
+ together, all the way back to Phase 2. It happened to read `"0.1.0"` and nobody had bumped it
1873
+ during any of the version changes this session, since local dev testing via `pip install -e .`
1874
+ never surfaces the mismatch the way a real "install a specific released version and check what
1875
+ it reports" test does.
1876
+ - **Fixed properly, not just patched for this one instance**: `__version__` now resolves via
1877
+ `importlib.metadata.version("astra-cli-agent")` at import time (falls back to a hardcoded
1878
+ constant only if run from a source checkout with no installed distribution metadata at all,
1879
+ which shouldn't happen via any normal install path). This makes future drift structurally
1880
+ impossible for anyone who installs the package normally — `astra version` will always match
1881
+ whatever's actually installed.
1882
+ - Bumped to `0.1.2`, tagged, released, published. **Live-verified again** in a completely fresh
1883
+ venv (`pip install astra-cli-agent==0.1.2`): `astra version` → `astra 0.1.2` correctly, banner
1884
+ renders correctly. This is the version currently live and correct on PyPI.
1885
+
1886
+ ### Verification discipline held throughout
1887
+
1888
+ Every step in this section (banner change, LICENSE/README/pyproject edits, the TOML bug fix, the
1889
+ `__version__` fix) went through the same loop before being pushed: local `ruff check .` + `mypy
1890
+ src` (strict) + `pytest -q` all green (**289 passed, 36 skipped**, unchanged kubernetes-cluster
1891
+ skip count throughout), push, wait for real GitHub Actions CI to go green, *then* proceed — never
1892
+ assumed a fix worked from local state alone once a real CI failure had already been observed once
1893
+ this session (the `[project.urls]` TOML bug). Every PyPI publish was confirmed with a genuinely
1894
+ fresh `python3 -m venv` + `pip install` from the real index, not just "the release workflow
1895
+ reported success."
1896
+
1897
+ ### Housekeeping: this document's own section numbering
1898
+
1899
+ This session found a pre-existing numbering collision in this very file: an earlier addendum had
1900
+ been inserted as "## 5. Post-Phase-18 addendum," directly colliding with an already-existing,
1901
+ differently-scoped "## 5. Environment state" section further down (itself part of an older
1902
+ 5→6→7→8 sequence: Environment state, Working agreements, the post-18 hardening pass, and the
1903
+ web-search/GitHub-push section). Fixed by relocating that addendum to become **§9** (after §8,
1904
+ where it chronologically belongs — it discovered/confirmed work §8 had already done), and this
1905
+ section is **§10**. `§1`–`§8`'s existing numbers and every cross-reference to them elsewhere in
1906
+ this document were left untouched to avoid a much larger, riskier rewrite across ~1700 lines;
1907
+ only the previously-misnumbered/misplaced section was moved and renumbered.
1908
+
1909
+ **Final state as of this section**: all 18 phases built (§2), all known simplifications tracked
1910
+ (§3) with six closed in §7 and more in §9/§10, CI proven live on real GitHub infrastructure (§8),
1911
+ `astra-cli-agent` actually published and installable from PyPI at `v0.1.2` (this section),
1912
+ first-run provider onboarding shipped (§9), and a real ASCII-logo presence shipped (this
1913
+ section). Remaining open items are genuinely external: a working LangSmith key (§9 item 3) and,
1914
+ per §5's environment notes, a local kubernetes cluster to un-skip a handful of tests — neither
1915
+ blocks calling this project done and publicly usable.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astra-cli-agent
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Astra — a terminal AI assistant that understands natural language and drives your dev tools.
5
5
  Project-URL: Homepage, https://github.com/Subharjun/astra-cli-agent
6
6
  Project-URL: Issues, https://github.com/Subharjun/astra-cli-agent/issues
@@ -63,7 +63,7 @@ wrapping a shell call.
63
63
 
64
64
  | Domain | Agent | Capabilities |
65
65
  |---|---|---|
66
- | Git | `GitAgent` | status, diff, log, blame, branch, commit (auto-generates messages), push, merge, checkout, stash |
66
+ | Git | `GitAgent` | status, diff, log, blame, branch, commit (auto-generates messages), push, merge, checkout, stash, plus GitHub API: create/delete repos, issues, pull requests (needs `GITHUB_TOKEN`) |
67
67
  | Filesystem & code | `FileAgent` | read/write/move/delete files, lint & format (`ruff`), run tests (`pytest`), symbol search |
68
68
  | Shell | `FileAgent` | runs arbitrary commands behind a hard denylist + confirmation gate |
69
69
  | Docker | `DockerAgent` | ps, images, build, run, logs, exec, inspect, rm/rmi, prune |
@@ -73,6 +73,27 @@ wrapping a shell call.
73
73
  | Documentation | `DocumentationAgent` | writes docstrings, README sections, usage guides |
74
74
  | MCP | `MCPAgent` | connects to any configured MCP server (stdio, HTTP, or SSE) and discovers/calls its tools |
75
75
 
76
+ **Example prompts by domain** — every one of these routes automatically, no flags needed
77
+ beyond `--yes` for anything risky:
78
+
79
+ | Domain | Example prompt |
80
+ |---|---|
81
+ | Git | `astra "what's the git status here, and diff the uncommitted changes"` |
82
+ | Git | `astra "commit my staged changes with a good message" --yes` |
83
+ | Git | `astra "list the open issues on this github repo"` (needs `GITHUB_TOKEN`) |
84
+ | Filesystem & code | `astra "create a file called notes.md with a todo list"` |
85
+ | Filesystem & code | `astra "run the linter and the test suite on this project"` |
86
+ | Shell | `astra "run df -h and tell me how much disk space is free" --yes` |
87
+ | Docker | `astra "list all running docker containers"` |
88
+ | Docker | `astra "build a docker image from the Dockerfile in this directory" --yes` |
89
+ | Kubernetes | `astra "list the pods in the default namespace"` |
90
+ | Kubernetes | `astra "scale the api deployment to 3 replicas" --yes` |
91
+ | Web research | `astra "search stack overflow for how to fix a detached HEAD in git"` |
92
+ | Web research | `astra "find github repos for a python rate limiter library"` |
93
+ | Debugging | `astra "here's a stack trace, find the root cause and propose a fix: <paste>"` |
94
+ | Documentation | `astra "write a README section documenting the config file format"` |
95
+ | MCP | `astra "list the tools available from my configured MCP servers"` |
96
+
76
97
  Also included:
77
98
 
78
99
  - **Safety by default** — risky operations (`git push`, file delete, shell, container/exec
@@ -88,7 +109,9 @@ Also included:
88
109
  - **Cost/token tracking** — `astra memory costs` shows a real per-provider/per-model
89
110
  breakdown and daily spend trend, no external service required.
90
111
  - **First-run onboarding** — `astra setup` walks you through picking a provider and tests
91
- your key with a real request before saving it.
112
+ your key with a real request before saving it. Optionally continues into GitHub API
113
+ (`GITHUB_TOKEN`) and general web search (`SERPAPI_KEY`) setup, same real-tested-before-saved
114
+ flow.
92
115
 
93
116
  See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full design and
94
117
  [HANDOFF.md](HANDOFF.md) for exactly what's built, what's tested, and what's left.
@@ -131,6 +154,11 @@ is the fastest way to try Astra.
131
154
  If you skip this step, the first command that actually needs an LLM (`ask`, a bare prompt,
132
155
  or `chat`) will offer to run the wizard for you automatically.
133
156
 
157
+ The wizard then offers an optional second stage for feature-unlocking keys — a GitHub
158
+ personal access token (`GITHUB_TOKEN`, for the `github_*` tools) and a SerpApi key
159
+ (`SERPAPI_KEY`, for general web search) — same real-request-before-saving flow, skippable,
160
+ default no. Run `astra setup` again any time to add these later.
161
+
134
162
  Then just talk to it — **from inside whatever project directory you want it to act on**,
135
163
  since every tool call is scoped to your current working directory:
136
164
 
@@ -185,6 +213,34 @@ mcp:
185
213
 
186
214
  `astra mcp tools` lists everything discovered from your configured servers.
187
215
 
216
+ ## All commands
217
+
218
+ Beyond natural-language prompts, every subcommand below is a direct, non-LLM entrypoint:
219
+
220
+ ```bash
221
+ astra hello # install/config/provider sanity check
222
+ astra version # print the installed version
223
+ astra setup # interactive onboarding wizard (LLM provider + optional integrations)
224
+ astra ask "<prompt>" # one-shot LLM call, bypasses the agent pipeline
225
+ astra chat # interactive REPL with streaming + history
226
+ astra ingest [path] # index a codebase for retrieval (defaults to .)
227
+
228
+ astra memory history [-n N] # recent conversation history
229
+ astra memory clear # wipe conversation history
230
+ astra memory costs # per-provider/per-model cost & token breakdown
231
+ astra memory projects # list ingested (RAG-indexed) projects
232
+ astra memory search "<query>" # test retrieval directly against an ingested project
233
+ astra memory prefs set <k> <v> # store a preference
234
+ astra memory prefs get <k> # read a preference
235
+ astra memory prefs list # list all preferences
236
+
237
+ astra mcp servers # list configured MCP servers
238
+ astra mcp tools # list tools discovered from configured MCP servers
239
+ ```
240
+
241
+ Any bare prompt (`astra "..."`) or `astra run "<prompt>"` triggers the full
242
+ router→planner→execute→reviewer→memory pipeline described above.
243
+
188
244
  ## Contributing / development
189
245
 
190
246
  ```bash