sqlsaber 0.10.0__tar.gz → 0.47.1__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.
- sqlsaber-0.47.1/.github/workflows/claude-code-review.yml +77 -0
- sqlsaber-0.47.1/.github/workflows/claude.yml +64 -0
- sqlsaber-0.47.1/.github/workflows/deploy-docs.yml +34 -0
- sqlsaber-0.47.1/.github/workflows/test.yml +33 -0
- sqlsaber-0.47.1/AGENTS.md +39 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/CLAUDE.md +6 -4
- sqlsaber-0.47.1/PKG-INFO +149 -0
- sqlsaber-0.47.1/README.md +125 -0
- sqlsaber-0.47.1/docs/.gitignore +24 -0
- sqlsaber-0.47.1/docs/.vscode/extensions.json +4 -0
- sqlsaber-0.47.1/docs/.vscode/launch.json +11 -0
- sqlsaber-0.47.1/docs/CLAUDE.md +40 -0
- sqlsaber-0.47.1/docs/astro.config.mjs +68 -0
- sqlsaber-0.47.1/docs/package-lock.json +7106 -0
- sqlsaber-0.47.1/docs/package.json +22 -0
- sqlsaber-0.47.1/docs/public/CNAME +1 -0
- sqlsaber-0.47.1/docs/public/favicon.svg +5 -0
- sqlsaber-0.47.1/docs/src/assets/sqlsaber.gif +0 -0
- sqlsaber-0.47.1/docs/src/content/docs/changelog.md +641 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/authentication.mdx +124 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/database-setup.mdx +199 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/getting-started.mdx +119 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/memory.mdx +127 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/models.mdx +79 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/queries.mdx +225 -0
- sqlsaber-0.47.1/docs/src/content/docs/guides/threads.md +69 -0
- sqlsaber-0.47.1/docs/src/content/docs/index.mdx +125 -0
- sqlsaber-0.47.1/docs/src/content/docs/installation.mdx +54 -0
- sqlsaber-0.47.1/docs/src/content/docs/reference/commands.md +469 -0
- sqlsaber-0.47.1/docs/src/content.config.ts +7 -0
- sqlsaber-0.47.1/docs/src/styles/global.css +243 -0
- sqlsaber-0.47.1/docs/tsconfig.json +5 -0
- sqlsaber-0.47.1/legislators.db +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/pyproject.toml +11 -10
- sqlsaber-0.47.1/sqlsaber.gif +0 -0
- sqlsaber-0.47.1/src/sqlsaber/__init__.py +5 -0
- sqlsaber-0.47.1/src/sqlsaber/agents/__init__.py +7 -0
- sqlsaber-0.47.1/src/sqlsaber/agents/base.py +63 -0
- sqlsaber-0.47.1/src/sqlsaber/agents/provider_factory.py +194 -0
- sqlsaber-0.47.1/src/sqlsaber/agents/pydantic_ai_agent.py +176 -0
- sqlsaber-0.47.1/src/sqlsaber/api.py +223 -0
- sqlsaber-0.47.1/src/sqlsaber/application/__init__.py +1 -0
- sqlsaber-0.47.1/src/sqlsaber/application/auth_setup.py +133 -0
- sqlsaber-0.47.1/src/sqlsaber/application/db_setup.py +258 -0
- sqlsaber-0.47.1/src/sqlsaber/application/model_selection.py +98 -0
- sqlsaber-0.47.1/src/sqlsaber/application/prompts.py +115 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/auth.py +150 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/buffered_streaming.py +166 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/commands.py +294 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/cli/completers.py +2 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/database.py +530 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/display.py +589 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/html_export.py +865 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/interactive.py +319 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/cli/memory.py +50 -25
- sqlsaber-0.47.1/src/sqlsaber/cli/models.py +288 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/onboarding.py +320 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/slash_commands.py +89 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/streaming.py +165 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/theme.py +154 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/threads.py +406 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/update_check.py +149 -0
- sqlsaber-0.47.1/src/sqlsaber/cli/usage.py +67 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/config/api_keys.py +41 -19
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/config/auth.py +16 -6
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/config/database.py +17 -2
- sqlsaber-0.47.1/src/sqlsaber/config/logging.py +195 -0
- sqlsaber-0.47.1/src/sqlsaber/config/providers.py +105 -0
- sqlsaber-0.47.1/src/sqlsaber/config/settings.py +192 -0
- sqlsaber-0.47.1/src/sqlsaber/database/__init__.py +74 -0
- sqlsaber-0.47.1/src/sqlsaber/database/base.py +207 -0
- sqlsaber-0.47.1/src/sqlsaber/database/csv.py +156 -0
- sqlsaber-0.47.1/src/sqlsaber/database/csvs.py +91 -0
- sqlsaber-0.47.1/src/sqlsaber/database/duckdb.py +382 -0
- sqlsaber-0.47.1/src/sqlsaber/database/mysql.py +395 -0
- sqlsaber-0.47.1/src/sqlsaber/database/postgresql.py +399 -0
- sqlsaber-0.47.1/src/sqlsaber/database/resolver.py +166 -0
- sqlsaber-0.47.1/src/sqlsaber/database/schema.py +173 -0
- sqlsaber-0.47.1/src/sqlsaber/database/sqlite.py +297 -0
- sqlsaber-0.47.1/src/sqlsaber/prompts/claude.py +52 -0
- sqlsaber-0.47.1/src/sqlsaber/prompts/dangerous_mode.py +13 -0
- sqlsaber-0.47.1/src/sqlsaber/prompts/memory.py +4 -0
- sqlsaber-0.47.1/src/sqlsaber/prompts/openai.py +40 -0
- sqlsaber-0.47.1/src/sqlsaber/theme/__init__.py +5 -0
- sqlsaber-0.47.1/src/sqlsaber/theme/manager.py +224 -0
- sqlsaber-0.47.1/src/sqlsaber/threads/__init__.py +5 -0
- sqlsaber-0.47.1/src/sqlsaber/threads/manager.py +87 -0
- sqlsaber-0.47.1/src/sqlsaber/threads/storage.py +317 -0
- sqlsaber-0.47.1/src/sqlsaber/tools/__init__.py +18 -0
- sqlsaber-0.47.1/src/sqlsaber/tools/base.py +30 -0
- sqlsaber-0.47.1/src/sqlsaber/tools/registry.py +85 -0
- sqlsaber-0.47.1/src/sqlsaber/tools/sql_guard.py +365 -0
- sqlsaber-0.47.1/src/sqlsaber/tools/sql_tools.py +219 -0
- sqlsaber-0.47.1/tests/test_agents/test_provider_factory.py +134 -0
- sqlsaber-0.47.1/tests/test_agents/test_pydantic_ai_agent.py +82 -0
- sqlsaber-0.47.1/tests/test_api/test_database.py +34 -0
- sqlsaber-0.47.1/tests/test_api/test_memory.py +78 -0
- sqlsaber-0.47.1/tests/test_application/test_auth_setup.py +74 -0
- sqlsaber-0.47.1/tests/test_cli/test_auth_reset.py +64 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/tests/test_cli/test_commands.py +24 -22
- sqlsaber-0.47.1/tests/test_cli/test_slash_commands.py +87 -0
- sqlsaber-0.47.1/tests/test_cli/test_threads.py +456 -0
- sqlsaber-0.47.1/tests/test_config/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/tests/test_config/test_database.py +28 -1
- sqlsaber-0.47.1/tests/test_config/test_providers.py +40 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/tests/test_config/test_settings.py +12 -8
- sqlsaber-0.47.1/tests/test_database/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/tests/test_database/test_connection.py +10 -1
- sqlsaber-0.47.1/tests/test_database/test_csv_connection.py +40 -0
- sqlsaber-0.47.1/tests/test_database/test_csv_module.py +357 -0
- sqlsaber-0.47.1/tests/test_database/test_csvs_connection.py +66 -0
- sqlsaber-0.47.1/tests/test_database/test_duckdb_module.py +452 -0
- sqlsaber-0.47.1/tests/test_database/test_mysql_module.py +49 -0
- sqlsaber-0.47.1/tests/test_database/test_postgresql_module.py +129 -0
- sqlsaber-0.47.1/tests/test_database/test_schema.py +110 -0
- sqlsaber-0.47.1/tests/test_database/test_schema_display.py +355 -0
- sqlsaber-0.47.1/tests/test_database/test_sqlite_module.py +307 -0
- sqlsaber-0.47.1/tests/test_database/test_timeout.py +105 -0
- sqlsaber-0.47.1/tests/test_database_resolver.py +183 -0
- sqlsaber-0.47.1/tests/test_theme/test_manager.py +36 -0
- sqlsaber-0.47.1/tests/test_tools/__init__.py +1 -0
- sqlsaber-0.47.1/tests/test_tools/test_base.py +33 -0
- sqlsaber-0.47.1/tests/test_tools/test_registry.py +156 -0
- sqlsaber-0.47.1/tests/test_tools/test_sql_guard.py +779 -0
- sqlsaber-0.47.1/tests/test_tools/test_sql_tools.py +260 -0
- sqlsaber-0.47.1/tests/threads/test_threads_manager.py +184 -0
- sqlsaber-0.47.1/tests/threads/test_threads_storage.py +89 -0
- sqlsaber-0.47.1/uv.lock +3172 -0
- sqlsaber-0.10.0/AGENT.md +0 -24
- sqlsaber-0.10.0/CHANGELOG.md +0 -179
- sqlsaber-0.10.0/PKG-INFO +0 -253
- sqlsaber-0.10.0/README.md +0 -232
- sqlsaber-0.10.0/src/sqlsaber/__init__.py +0 -3
- sqlsaber-0.10.0/src/sqlsaber/agents/__init__.py +0 -9
- sqlsaber-0.10.0/src/sqlsaber/agents/anthropic.py +0 -551
- sqlsaber-0.10.0/src/sqlsaber/agents/base.py +0 -286
- sqlsaber-0.10.0/src/sqlsaber/agents/mcp.py +0 -21
- sqlsaber-0.10.0/src/sqlsaber/agents/streaming.py +0 -16
- sqlsaber-0.10.0/src/sqlsaber/cli/auth.py +0 -141
- sqlsaber-0.10.0/src/sqlsaber/cli/commands.py +0 -186
- sqlsaber-0.10.0/src/sqlsaber/cli/database.py +0 -387
- sqlsaber-0.10.0/src/sqlsaber/cli/display.py +0 -267
- sqlsaber-0.10.0/src/sqlsaber/cli/interactive.py +0 -191
- sqlsaber-0.10.0/src/sqlsaber/cli/models.py +0 -230
- sqlsaber-0.10.0/src/sqlsaber/cli/streaming.py +0 -100
- sqlsaber-0.10.0/src/sqlsaber/clients/__init__.py +0 -6
- sqlsaber-0.10.0/src/sqlsaber/clients/anthropic.py +0 -285
- sqlsaber-0.10.0/src/sqlsaber/clients/base.py +0 -31
- sqlsaber-0.10.0/src/sqlsaber/clients/exceptions.py +0 -117
- sqlsaber-0.10.0/src/sqlsaber/clients/models.py +0 -282
- sqlsaber-0.10.0/src/sqlsaber/clients/streaming.py +0 -257
- sqlsaber-0.10.0/src/sqlsaber/config/oauth_flow.py +0 -274
- sqlsaber-0.10.0/src/sqlsaber/config/oauth_tokens.py +0 -175
- sqlsaber-0.10.0/src/sqlsaber/config/settings.py +0 -130
- sqlsaber-0.10.0/src/sqlsaber/database/__init__.py +0 -9
- sqlsaber-0.10.0/src/sqlsaber/database/connection.py +0 -415
- sqlsaber-0.10.0/src/sqlsaber/database/schema.py +0 -719
- sqlsaber-0.10.0/src/sqlsaber/mcp/__init__.py +0 -5
- sqlsaber-0.10.0/src/sqlsaber/mcp/mcp.py +0 -137
- sqlsaber-0.10.0/src/sqlsaber/models/__init__.py +0 -13
- sqlsaber-0.10.0/src/sqlsaber/models/events.py +0 -28
- sqlsaber-0.10.0/src/sqlsaber/models/types.py +0 -40
- sqlsaber-0.10.0/tests/test_agents/test_anthropic_oauth.py +0 -78
- sqlsaber-0.10.0/tests/test_clients/test_anthropic_client.py +0 -91
- sqlsaber-0.10.0/tests/test_clients/test_streaming.py +0 -282
- sqlsaber-0.10.0/tests/test_config/test_oauth.py +0 -179
- sqlsaber-0.10.0/uv.lock +0 -1073
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/.github/workflows/publish.yml +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/.gitignore +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/.python-version +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/LICENSE +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/pytest.ini +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/sqlsaber.svg +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/__main__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/cli/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/config/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/memory/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/memory/manager.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/src/sqlsaber/memory/storage.py +0 -0
- {sqlsaber-0.10.0/tests → sqlsaber-0.47.1/src/sqlsaber/prompts}/__init__.py +0 -0
- {sqlsaber-0.10.0/tests/test_cli → sqlsaber-0.47.1/tests}/__init__.py +0 -0
- {sqlsaber-0.10.0 → sqlsaber-0.47.1}/tests/conftest.py +0 -0
- {sqlsaber-0.10.0/tests/test_config → sqlsaber-0.47.1/tests/test_api}/__init__.py +0 -0
- {sqlsaber-0.10.0/tests/test_database → sqlsaber-0.47.1/tests/test_cli}/__init__.py +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
name: Claude Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
# Optional: Only run on specific file changes
|
|
7
|
+
# paths:
|
|
8
|
+
# - "src/**/*.ts"
|
|
9
|
+
# - "src/**/*.tsx"
|
|
10
|
+
# - "src/**/*.js"
|
|
11
|
+
# - "src/**/*.jsx"
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude-review:
|
|
15
|
+
# Optional: Filter by PR author
|
|
16
|
+
# if: |
|
|
17
|
+
# github.event.pull_request.user.login == 'external-contributor' ||
|
|
18
|
+
# github.event.pull_request.user.login == 'new-developer' ||
|
|
19
|
+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
|
20
|
+
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: read
|
|
25
|
+
issues: read
|
|
26
|
+
id-token: write
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout repository
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
with:
|
|
32
|
+
fetch-depth: 1
|
|
33
|
+
|
|
34
|
+
- name: Run Claude Code Review
|
|
35
|
+
id: claude-review
|
|
36
|
+
uses: anthropics/claude-code-action@beta
|
|
37
|
+
with:
|
|
38
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
39
|
+
|
|
40
|
+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
|
|
41
|
+
# model: "claude-opus-4-20250514"
|
|
42
|
+
|
|
43
|
+
# Direct prompt for automated review (no @claude mention needed)
|
|
44
|
+
direct_prompt: |
|
|
45
|
+
Please review this pull request and provide feedback on:
|
|
46
|
+
- Code quality and best practices
|
|
47
|
+
- Potential bugs or issues
|
|
48
|
+
- Performance considerations
|
|
49
|
+
- Security concerns
|
|
50
|
+
- Test coverage
|
|
51
|
+
|
|
52
|
+
Be constructive and helpful in your feedback.
|
|
53
|
+
|
|
54
|
+
# Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
|
|
55
|
+
# use_sticky_comment: true
|
|
56
|
+
|
|
57
|
+
# Optional: Customize review based on file types
|
|
58
|
+
# direct_prompt: |
|
|
59
|
+
# Review this PR focusing on:
|
|
60
|
+
# - For TypeScript files: Type safety and proper interface usage
|
|
61
|
+
# - For API endpoints: Security, input validation, and error handling
|
|
62
|
+
# - For React components: Performance, accessibility, and best practices
|
|
63
|
+
# - For tests: Coverage, edge cases, and test quality
|
|
64
|
+
|
|
65
|
+
# Optional: Different prompts for different authors
|
|
66
|
+
# direct_prompt: |
|
|
67
|
+
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
|
|
68
|
+
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
|
|
69
|
+
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
|
|
70
|
+
|
|
71
|
+
# Optional: Add specific tools for running tests or linting
|
|
72
|
+
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
|
|
73
|
+
|
|
74
|
+
# Optional: Skip review for certain conditions
|
|
75
|
+
if: |
|
|
76
|
+
!contains(github.event.pull_request.title, '[skip-review]') &&
|
|
77
|
+
!contains(github.event.pull_request.title, '[WIP]')
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Claude Code
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
issues:
|
|
9
|
+
types: [opened, assigned]
|
|
10
|
+
pull_request_review:
|
|
11
|
+
types: [submitted]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude:
|
|
15
|
+
if: |
|
|
16
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
17
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
18
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
19
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
pull-requests: read
|
|
24
|
+
issues: read
|
|
25
|
+
id-token: write
|
|
26
|
+
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout repository
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 1
|
|
32
|
+
|
|
33
|
+
- name: Run Claude Code
|
|
34
|
+
id: claude
|
|
35
|
+
uses: anthropics/claude-code-action@beta
|
|
36
|
+
with:
|
|
37
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
|
+
|
|
39
|
+
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
|
+
additional_permissions: |
|
|
41
|
+
actions: read
|
|
42
|
+
|
|
43
|
+
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
|
|
44
|
+
# model: "claude-opus-4-20250514"
|
|
45
|
+
|
|
46
|
+
# Optional: Customize the trigger phrase (default: @claude)
|
|
47
|
+
# trigger_phrase: "/claude"
|
|
48
|
+
|
|
49
|
+
# Optional: Trigger when specific user is assigned to an issue
|
|
50
|
+
# assignee_trigger: "claude-bot"
|
|
51
|
+
|
|
52
|
+
# Optional: Allow Claude to run specific commands
|
|
53
|
+
# allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
|
|
54
|
+
|
|
55
|
+
# Optional: Add custom instructions for Claude to customize its behavior for your project
|
|
56
|
+
# custom_instructions: |
|
|
57
|
+
# Follow our coding standards
|
|
58
|
+
# Ensure all new code has tests
|
|
59
|
+
# Use TypeScript for new files
|
|
60
|
+
|
|
61
|
+
# Optional: Custom environment variables for Claude
|
|
62
|
+
# claude_env: |
|
|
63
|
+
# NODE_ENV: test
|
|
64
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Deploy docs to GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
# Allow this job to clone the repo and create a page deployment
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout your repository using git
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
- name: Install, build, and upload your site
|
|
21
|
+
uses: withastro/action@v3
|
|
22
|
+
with:
|
|
23
|
+
path: docs/
|
|
24
|
+
|
|
25
|
+
deploy:
|
|
26
|
+
needs: build
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
environment:
|
|
29
|
+
name: github-pages
|
|
30
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
31
|
+
steps:
|
|
32
|
+
- name: Deploy to GitHub Pages
|
|
33
|
+
id: deployment
|
|
34
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
# Cancel active CI runs for a PR before starting another run
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow}}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: uv sync --locked --all-extras --dev
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: uv run python -m pytest
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
- Source: `src/sqlsaber/`
|
|
5
|
+
- `cli/`: CLI entry (`saber`, `sqlsaber`), REPL, prompts.
|
|
6
|
+
- `agents/`: agent implementations (pydantic‑ai).
|
|
7
|
+
- `tools/`: SQL, introspection, registry.
|
|
8
|
+
- `database/`: connection, resolver, schema utilities.
|
|
9
|
+
- `memory/`, `conversation/`: state and persistence.
|
|
10
|
+
- `config/`: settings, API keys, DB configs.
|
|
11
|
+
- Tests: `tests/` mirror modules (`test_cli/`, `test_tools/`, …).
|
|
12
|
+
- Docs & assets: `docs/`, `sqlsaber.gif`, `sqlsaber.svg`.
|
|
13
|
+
|
|
14
|
+
## Build, Test, and Development Commands
|
|
15
|
+
- Install (editable): `uv sync`
|
|
16
|
+
- Lint: `uv run ruff check .`
|
|
17
|
+
- Type check (all): `uvx ty check src/`
|
|
18
|
+
- Type check (targeted): `uvx ty check <file>`
|
|
19
|
+
- Format: `uv run ruff format .`
|
|
20
|
+
- Tests (all): `uv run pytest -q`
|
|
21
|
+
- Tests (targeted): `uv run pytest tests/test_tools -q`
|
|
22
|
+
- Run CLI (dev): `uv run saber` or `uv run python -m sqlsaber`
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Note: Prefer `uv run ruff ...` over `uvx ruff ...` to avoid hitting user-level uv caches that may be restricted in sandboxed environments.
|
|
26
|
+
|
|
27
|
+
## Coding Style & Naming Conventions
|
|
28
|
+
- Python 3.12+, 4‑space indent, strictly use modern (3.12+) type hints approach.
|
|
29
|
+
- Type check must pass without errors always.
|
|
30
|
+
- Ruff is the linter/formatter; code must be clean and formatted.
|
|
31
|
+
- Naming: modules/files `snake_case.py`; classes `PascalCase`; functions/vars `snake_case`; constants `UPPER_SNAKE`.
|
|
32
|
+
- Keep public CLI surfaces in `cli/`; factor reusable logic into modules under `sqlsaber/`.
|
|
33
|
+
|
|
34
|
+
## Testing Guidelines
|
|
35
|
+
- Framework: `pytest` with `pytest-asyncio`.
|
|
36
|
+
- Place tests under `tests/`, name files `test_*.py` and mirror package layout.
|
|
37
|
+
- Include tests for new behavior and bug fixes; prefer async tests for async code.
|
|
38
|
+
- Use fixtures from `tests/conftest.py` where possible.
|
|
39
|
+
- Tests must pass without errors always.
|
|
@@ -3,20 +3,22 @@
|
|
|
3
3
|
- **Run Python**: `uv run python`
|
|
4
4
|
- **Run tests**: `uv run python -m pytest`
|
|
5
5
|
- **Run single test**: `uv run python -m pytest tests/test_path/test_file.py::test_function`
|
|
6
|
+
- **Type check (all)**: `uvx ty check src/`
|
|
7
|
+
- **Type check (targeted)**: `uvx ty check <file>`
|
|
6
8
|
- **Lint**: `uv run ruff check --fix`
|
|
7
9
|
- **Format**: `uv run ruff format`
|
|
8
10
|
|
|
9
11
|
## Architecture
|
|
10
12
|
|
|
11
13
|
- **CLI App**: Agentic SQL assistant for natural language to SQL
|
|
12
|
-
- **Core modules**: `agents/` (AI logic), `cli/` (commands), `
|
|
14
|
+
- **Core modules**: `agents/` (AI logic), `cli/` (commands), `database/` (connections)
|
|
13
15
|
- **Database support**: PostgreSQL, SQLite, MySQL via asyncpg/aiosqlite/aiomysql
|
|
14
|
-
- **MCP integration**: Exposes tools via `sqlsaber-mcp` for Claude Code and other MCP clients
|
|
15
16
|
|
|
16
17
|
## Code Style
|
|
17
18
|
|
|
18
19
|
- **Imports**: stdlib → 3rd party → local, use relative imports within modules
|
|
19
20
|
- **Naming**: snake_case functions/vars, PascalCase classes, UPPER_SNAKE constants, `_private` methods
|
|
20
|
-
- **Types**: Always use modern type hints (3.12+), async functions for I/O
|
|
21
|
-
-
|
|
21
|
+
- **Types**: Always use ONLY modern type hints (3.12+), async functions for I/O
|
|
22
|
+
- Type check must pass without errors always
|
|
23
|
+
- **Errors**: Use try/finally for cleanup
|
|
22
24
|
- **Docstrings**: Triple-quoted with Args/Returns sections
|
sqlsaber-0.47.1/PKG-INFO
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlsaber
|
|
3
|
+
Version: 0.47.1
|
|
4
|
+
Summary: SQLsaber - Open-source agentic SQL assistant
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: aiomysql>=0.2.0
|
|
8
|
+
Requires-Dist: aiosqlite>=0.21.0
|
|
9
|
+
Requires-Dist: asyncpg>=0.30.0
|
|
10
|
+
Requires-Dist: cyclopts>=3.22.1
|
|
11
|
+
Requires-Dist: duckdb>=0.9.2
|
|
12
|
+
Requires-Dist: httpx>=0.28.1
|
|
13
|
+
Requires-Dist: keyring>=25.6.0
|
|
14
|
+
Requires-Dist: keyrings-cryptfile; sys_platform == 'linux'
|
|
15
|
+
Requires-Dist: platformdirs>=4.0.0
|
|
16
|
+
Requires-Dist: prompt-toolkit>3.0.51
|
|
17
|
+
Requires-Dist: pydantic-ai
|
|
18
|
+
Requires-Dist: questionary>=2.1.0
|
|
19
|
+
Requires-Dist: rich>=13.7.0
|
|
20
|
+
Requires-Dist: sqlglot[rs]>=27.20.0
|
|
21
|
+
Requires-Dist: structlog>=25.4.0
|
|
22
|
+
Requires-Dist: tabulate>=0.9.0
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# SQLsaber
|
|
26
|
+
|
|
27
|
+
> SQLsaber is an open-source agentic SQL assistant. Think Claude Code but for SQL.
|
|
28
|
+
|
|
29
|
+
**Ask questions about your data in plain English. SQLsaber writes SQL queries, executes them, and explains the results.**
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
SQLsaber reads your schema, writes SQL, executes it, and explains the results—all from a single natural language prompt.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
$ saber "How many orders were placed last month?"
|
|
37
|
+
|
|
38
|
+
# SQLsaber will:
|
|
39
|
+
# 1. Discover relevant tables (orders, order_items, etc.)
|
|
40
|
+
# 2. Analyze their schema
|
|
41
|
+
# 3. Generate and run SQL
|
|
42
|
+
# 4. Return results with explanation
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Why SQLsaber?
|
|
46
|
+
|
|
47
|
+
- **No context switching** — Stay in your terminal, ask questions, get answers
|
|
48
|
+
- **Schema-aware** — Automatically introspects your database; no manual setup
|
|
49
|
+
- **Safe by default** — Read-only queries; won't modify your data
|
|
50
|
+
- **Works with your stack** — PostgreSQL, MySQL, SQLite, DuckDB, and CSV files
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Recommended
|
|
56
|
+
uv tool install sqlsaber
|
|
57
|
+
|
|
58
|
+
# Or with pipx
|
|
59
|
+
pipx install sqlsaber
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then run:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
saber
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
On first launch, SQLsaber walks you through connecting a database and setting up authentication.
|
|
69
|
+
|
|
70
|
+
## Quick Examples
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Interactive mode
|
|
74
|
+
saber
|
|
75
|
+
|
|
76
|
+
# Single query
|
|
77
|
+
saber "show me users who signed up this week"
|
|
78
|
+
|
|
79
|
+
# Pipe from stdin
|
|
80
|
+
echo "top 10 customers by revenue" | saber
|
|
81
|
+
|
|
82
|
+
# Use a specific database
|
|
83
|
+
saber -d mydb "count active subscriptions"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Features
|
|
87
|
+
|
|
88
|
+
| Feature | Description |
|
|
89
|
+
|---------|-------------|
|
|
90
|
+
| **Schema introspection** | Discovers tables, columns, and relationships automatically |
|
|
91
|
+
| **Conversation memory** | Add context like "dates are stored as Unix timestamps" |
|
|
92
|
+
| **Thread history** | Resume past conversations with `saber threads resume` |
|
|
93
|
+
| **Extended thinking** | Enable `--thinking` for complex analytical queries |
|
|
94
|
+
| **Multiple AI providers** | Anthropic, OpenAI, Google, Groq (Claude Sonnet 4 by default) |
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
### Add a database
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
saber db add mydb
|
|
102
|
+
# Prompts for connection details
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Or pass a connection string directly:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
saber -d "postgresql://user:pass@localhost:5432/mydb" "count users"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Change AI model
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
saber models set
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Add memory (context for your database)
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
saber memory add "customer_id in orders table references users.id"
|
|
121
|
+
saber memory add "all timestamps are UTC"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## How It Works
|
|
125
|
+
|
|
126
|
+
1. **Discovery** — Lists tables and identifies relevant ones based on your question
|
|
127
|
+
2. **Schema analysis** — Introspects only the tables needed
|
|
128
|
+
3. **Query generation** — Writes SQL tailored to your database dialect
|
|
129
|
+
4. **Execution** — Runs read-only queries with safety checks
|
|
130
|
+
5. **Results** — Formats output with explanations
|
|
131
|
+
|
|
132
|
+
## Documentation
|
|
133
|
+
|
|
134
|
+
Full docs at [sqlsaber.com](https://sqlsaber.com):
|
|
135
|
+
|
|
136
|
+
- [Installation](https://sqlsaber.com/installation/)
|
|
137
|
+
- [Getting Started](https://sqlsaber.com/guides/getting-started/)
|
|
138
|
+
- [Database Setup](https://sqlsaber.com/guides/database-setup/)
|
|
139
|
+
- [Command Reference](https://sqlsaber.com/reference/commands/)
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
Contributions welcome! Please open an issue first to discuss changes.
|
|
144
|
+
|
|
145
|
+
If you find SQLsaber useful, a ⭐ on GitHub helps others discover it.
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
Apache-2.0 — see [LICENSE](./LICENSE)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# SQLsaber
|
|
2
|
+
|
|
3
|
+
> SQLsaber is an open-source agentic SQL assistant. Think Claude Code but for SQL.
|
|
4
|
+
|
|
5
|
+
**Ask questions about your data in plain English. SQLsaber writes SQL queries, executes them, and explains the results.**
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
SQLsaber reads your schema, writes SQL, executes it, and explains the results—all from a single natural language prompt.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
$ saber "How many orders were placed last month?"
|
|
13
|
+
|
|
14
|
+
# SQLsaber will:
|
|
15
|
+
# 1. Discover relevant tables (orders, order_items, etc.)
|
|
16
|
+
# 2. Analyze their schema
|
|
17
|
+
# 3. Generate and run SQL
|
|
18
|
+
# 4. Return results with explanation
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Why SQLsaber?
|
|
22
|
+
|
|
23
|
+
- **No context switching** — Stay in your terminal, ask questions, get answers
|
|
24
|
+
- **Schema-aware** — Automatically introspects your database; no manual setup
|
|
25
|
+
- **Safe by default** — Read-only queries; won't modify your data
|
|
26
|
+
- **Works with your stack** — PostgreSQL, MySQL, SQLite, DuckDB, and CSV files
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Recommended
|
|
32
|
+
uv tool install sqlsaber
|
|
33
|
+
|
|
34
|
+
# Or with pipx
|
|
35
|
+
pipx install sqlsaber
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then run:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
saber
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
On first launch, SQLsaber walks you through connecting a database and setting up authentication.
|
|
45
|
+
|
|
46
|
+
## Quick Examples
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Interactive mode
|
|
50
|
+
saber
|
|
51
|
+
|
|
52
|
+
# Single query
|
|
53
|
+
saber "show me users who signed up this week"
|
|
54
|
+
|
|
55
|
+
# Pipe from stdin
|
|
56
|
+
echo "top 10 customers by revenue" | saber
|
|
57
|
+
|
|
58
|
+
# Use a specific database
|
|
59
|
+
saber -d mydb "count active subscriptions"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Features
|
|
63
|
+
|
|
64
|
+
| Feature | Description |
|
|
65
|
+
|---------|-------------|
|
|
66
|
+
| **Schema introspection** | Discovers tables, columns, and relationships automatically |
|
|
67
|
+
| **Conversation memory** | Add context like "dates are stored as Unix timestamps" |
|
|
68
|
+
| **Thread history** | Resume past conversations with `saber threads resume` |
|
|
69
|
+
| **Extended thinking** | Enable `--thinking` for complex analytical queries |
|
|
70
|
+
| **Multiple AI providers** | Anthropic, OpenAI, Google, Groq (Claude Sonnet 4 by default) |
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
### Add a database
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
saber db add mydb
|
|
78
|
+
# Prompts for connection details
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Or pass a connection string directly:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
saber -d "postgresql://user:pass@localhost:5432/mydb" "count users"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Change AI model
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
saber models set
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Add memory (context for your database)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
saber memory add "customer_id in orders table references users.id"
|
|
97
|
+
saber memory add "all timestamps are UTC"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## How It Works
|
|
101
|
+
|
|
102
|
+
1. **Discovery** — Lists tables and identifies relevant ones based on your question
|
|
103
|
+
2. **Schema analysis** — Introspects only the tables needed
|
|
104
|
+
3. **Query generation** — Writes SQL tailored to your database dialect
|
|
105
|
+
4. **Execution** — Runs read-only queries with safety checks
|
|
106
|
+
5. **Results** — Formats output with explanations
|
|
107
|
+
|
|
108
|
+
## Documentation
|
|
109
|
+
|
|
110
|
+
Full docs at [sqlsaber.com](https://sqlsaber.com):
|
|
111
|
+
|
|
112
|
+
- [Installation](https://sqlsaber.com/installation/)
|
|
113
|
+
- [Getting Started](https://sqlsaber.com/guides/getting-started/)
|
|
114
|
+
- [Database Setup](https://sqlsaber.com/guides/database-setup/)
|
|
115
|
+
- [Command Reference](https://sqlsaber.com/reference/commands/)
|
|
116
|
+
|
|
117
|
+
## Contributing
|
|
118
|
+
|
|
119
|
+
Contributions welcome! Please open an issue first to discuss changes.
|
|
120
|
+
|
|
121
|
+
If you find SQLsaber useful, a ⭐ on GitHub helps others discover it.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
Apache-2.0 — see [LICENSE](./LICENSE)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# build output
|
|
2
|
+
dist/
|
|
3
|
+
# generated types
|
|
4
|
+
.astro/
|
|
5
|
+
|
|
6
|
+
# dependencies
|
|
7
|
+
node_modules/
|
|
8
|
+
|
|
9
|
+
# logs
|
|
10
|
+
npm-debug.log*
|
|
11
|
+
yarn-debug.log*
|
|
12
|
+
yarn-error.log*
|
|
13
|
+
pnpm-debug.log*
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# environment variables
|
|
17
|
+
.env
|
|
18
|
+
.env.production
|
|
19
|
+
|
|
20
|
+
# macOS-specific files
|
|
21
|
+
.DS_Store
|
|
22
|
+
|
|
23
|
+
# jetbrains setting folder
|
|
24
|
+
.idea/
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
- **Development server**: `npm run dev` or `npm start`
|
|
8
|
+
- **Build documentation**: `npm run build`
|
|
9
|
+
- **Preview built site**: `npm run preview`
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
13
|
+
- **Documentation Site**: Built with Astro and Starlight for SQLsaber project documentation
|
|
14
|
+
- **Framework**: Astro 5.x with Starlight integration for documentation structure
|
|
15
|
+
- **Styling**: TailwindCSS 4.x with Starlight-specific Tailwind integration
|
|
16
|
+
- **Content**: MDX files in `src/content/docs/` for documentation pages
|
|
17
|
+
- **Assets**: Static images and SVGs in `src/assets/` and `public/`
|
|
18
|
+
|
|
19
|
+
## Project Context
|
|
20
|
+
|
|
21
|
+
This is the documentation website (`/docs`) for SQLsaber, an open-source agentic SQL assistant. The main SQLsaber Python project is in the parent directory with its own development workflow using uv/Python.
|
|
22
|
+
|
|
23
|
+
Key documentation areas:
|
|
24
|
+
- Landing page: `src/content/docs/index.mdx` (splash template with hero section)
|
|
25
|
+
- Guides: `src/content/docs/guides/` (tutorial content)
|
|
26
|
+
- Reference: `src/content/docs/reference/` (API and technical reference)
|
|
27
|
+
|
|
28
|
+
## Configuration Files
|
|
29
|
+
|
|
30
|
+
- `astro.config.mjs`: Main Astro configuration with Starlight integration
|
|
31
|
+
- `package.json`: Node.js dependencies and scripts
|
|
32
|
+
- `tsconfig.json`: TypeScript configuration for the Astro project
|
|
33
|
+
- Site URL configured for https://sqlsaber.com
|
|
34
|
+
|
|
35
|
+
## Content Structure
|
|
36
|
+
|
|
37
|
+
- Starlight sidebar automatically generates from `src/content/docs/` structure
|
|
38
|
+
- Use `.mdx` extension for components in markdown
|
|
39
|
+
- Use components available via `@astrojs/starlight/components`
|
|
40
|
+
- Asciinema integration for terminal recordings/demos
|