chatsbom 0.2.6__tar.gz → 0.2.8__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.
- {chatsbom-0.2.6 → chatsbom-0.2.8}/PKG-INFO +1 -1
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/__main__.py +24 -1
- chatsbom-0.2.8/chatsbom/__version__.py +19 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/chat.py +50 -1
- {chatsbom-0.2.6 → chatsbom-0.2.8}/pyproject.toml +1 -1
- chatsbom-0.2.6/start.sh → chatsbom-0.2.8/test.sh +14 -1
- {chatsbom-0.2.6 → chatsbom-0.2.8}/uv.lock +1 -1
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.env.example +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.github/workflows/release.yaml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.github/workflows/weekly.yml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.gitignore +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.pre-commit-config.yaml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/.python-version +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/README.md +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/__init__.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/__init__.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/collect.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/convert.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/download.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/index.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/query.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/commands/status.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/__init__.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/clickhouse.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/client.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/config.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/repository.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/schema.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/core/validation.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/models/__init__.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/models/framework.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/chatsbom/models/language.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/config/users.d/admin.xml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/config/users.d/guest.xml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/docker-compose.yaml +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/figures/demo.gif +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/figures/use-cases/gin/01.png +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/figures/use-cases/gin/02.png +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/client_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/collect_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/convert_sbom_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/download_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/framework_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/index_test.py +0 -0
- {chatsbom-0.2.6 → chatsbom-0.2.8}/tests/language_test.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
|
|
3
|
+
from chatsbom.__version__ import __version__
|
|
3
4
|
from chatsbom.commands import chat
|
|
4
5
|
from chatsbom.commands import collect
|
|
5
6
|
from chatsbom.commands import convert
|
|
@@ -8,13 +9,35 @@ from chatsbom.commands import index
|
|
|
8
9
|
from chatsbom.commands import query
|
|
9
10
|
from chatsbom.commands import status
|
|
10
11
|
|
|
12
|
+
|
|
13
|
+
def version_callback(value: bool):
|
|
14
|
+
"""Print version and exit."""
|
|
15
|
+
if value:
|
|
16
|
+
typer.echo(f"ChatSBOM version {__version__}")
|
|
17
|
+
raise typer.Exit()
|
|
18
|
+
|
|
19
|
+
|
|
11
20
|
app = typer.Typer(
|
|
12
21
|
help='ChatSBOM - Talk to your Supply Chain. Chat with SBOMs.',
|
|
13
22
|
no_args_is_help=True,
|
|
14
23
|
add_completion=False,
|
|
15
24
|
)
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
|
|
27
|
+
@app.callback()
|
|
28
|
+
def main(
|
|
29
|
+
version: bool = typer.Option(
|
|
30
|
+
None,
|
|
31
|
+
'--version',
|
|
32
|
+
'-v',
|
|
33
|
+
help='Show version and exit',
|
|
34
|
+
callback=version_callback,
|
|
35
|
+
is_eager=True,
|
|
36
|
+
),
|
|
37
|
+
):
|
|
38
|
+
"""ChatSBOM - Talk to your Supply Chain. Chat with SBOMs."""
|
|
39
|
+
|
|
40
|
+
|
|
18
41
|
app.command(name='collect')(collect.main)
|
|
19
42
|
app.command(name='download')(download.main)
|
|
20
43
|
app.command(name='convert')(convert.main)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Version information for ChatSBOM."""
|
|
2
|
+
from importlib.metadata import PackageNotFoundError
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_version() -> str:
|
|
7
|
+
"""
|
|
8
|
+
Get version from installed package metadata.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
Version string (e.g., "0.2.6")
|
|
12
|
+
"""
|
|
13
|
+
try:
|
|
14
|
+
return version('chatsbom')
|
|
15
|
+
except PackageNotFoundError:
|
|
16
|
+
return '0.0.0-dev'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__version__ = get_version()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
from contextlib import suppress
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from dataclasses import field
|
|
7
8
|
from datetime import datetime
|
|
@@ -127,6 +128,12 @@ class ChatSBOMApp(App):
|
|
|
127
128
|
self._update_status()
|
|
128
129
|
|
|
129
130
|
async def on_mount(self) -> None:
|
|
131
|
+
"""Initialize the Claude Agent SDK client."""
|
|
132
|
+
import tempfile
|
|
133
|
+
stderr_file = tempfile.NamedTemporaryFile(
|
|
134
|
+
mode='w', delete=False, suffix='.log',
|
|
135
|
+
)
|
|
136
|
+
|
|
130
137
|
opts = ClaudeAgentOptions(
|
|
131
138
|
disallowed_tools=[
|
|
132
139
|
'Read', 'Write', 'Edit',
|
|
@@ -139,9 +146,24 @@ class ChatSBOMApp(App):
|
|
|
139
146
|
),
|
|
140
147
|
},
|
|
141
148
|
system_prompt=SYSTEM_PROMPT,
|
|
149
|
+
env={
|
|
150
|
+
k: v for k, v in [
|
|
151
|
+
('ANTHROPIC_BASE_URL', os.getenv('ANTHROPIC_BASE_URL')),
|
|
152
|
+
] if v
|
|
153
|
+
},
|
|
154
|
+
debug_stderr=stderr_file,
|
|
142
155
|
)
|
|
156
|
+
|
|
143
157
|
self.client = ClaudeSDKClient(options=opts)
|
|
144
|
-
|
|
158
|
+
try:
|
|
159
|
+
await self.client.__aenter__()
|
|
160
|
+
except Exception as e:
|
|
161
|
+
self._handle_init_error(e, stderr_file.name)
|
|
162
|
+
raise
|
|
163
|
+
finally:
|
|
164
|
+
stderr_file.close()
|
|
165
|
+
with suppress(OSError):
|
|
166
|
+
os.unlink(stderr_file.name)
|
|
145
167
|
|
|
146
168
|
log = self.query_one('#log', RichLog)
|
|
147
169
|
log.write('[bold green]ChatSBOM Agent[/] - Query examples:')
|
|
@@ -150,6 +172,33 @@ class ChatSBOMApp(App):
|
|
|
150
172
|
self.query_one('#loading').add_class('hidden')
|
|
151
173
|
self._update_status()
|
|
152
174
|
|
|
175
|
+
def _handle_init_error(self, error: Exception, stderr_path: str) -> None:
|
|
176
|
+
"""Display initialization error with context."""
|
|
177
|
+
from rich.console import Console
|
|
178
|
+
from rich.panel import Panel
|
|
179
|
+
from pathlib import Path
|
|
180
|
+
|
|
181
|
+
lines = [
|
|
182
|
+
f'[red]{error}[/red]',
|
|
183
|
+
f'[dim]{type(error).__name__}[/dim]',
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
if stderr := Path(stderr_path).read_text().strip():
|
|
187
|
+
lines += ['', '[yellow]stderr:[/yellow]', f'[dim]{stderr}[/dim]']
|
|
188
|
+
|
|
189
|
+
if os.geteuid() == 0:
|
|
190
|
+
lines += ['', '[yellow]⚠ Cannot use bypassPermissions as root. Run as non-root user.[/yellow]']
|
|
191
|
+
|
|
192
|
+
if url := os.getenv('ANTHROPIC_BASE_URL'):
|
|
193
|
+
lines += ['', f'[dim]API: {url}[/dim]']
|
|
194
|
+
|
|
195
|
+
Console().print(
|
|
196
|
+
Panel(
|
|
197
|
+
'\n'.join(lines),
|
|
198
|
+
title='[red]Init Failed[/red]', border_style='red',
|
|
199
|
+
),
|
|
200
|
+
)
|
|
201
|
+
|
|
153
202
|
async def on_unmount(self) -> None:
|
|
154
203
|
if self.client:
|
|
155
204
|
try:
|
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
# 1. Collect repository links from GitHub (e.g., top Go repos)
|
|
1
2
|
uv run python -m chatsbom collect --language go --min-stars 10000
|
|
3
|
+
|
|
4
|
+
# 2. Download dependency files
|
|
2
5
|
uv run python -m chatsbom download --language go
|
|
6
|
+
|
|
7
|
+
# 3. Convert to standard SBOM format
|
|
3
8
|
uv run python -m chatsbom convert --language go
|
|
9
|
+
|
|
10
|
+
# 4. Index SBOM data into database
|
|
4
11
|
uv run python -m chatsbom index --language go
|
|
5
|
-
|
|
12
|
+
|
|
13
|
+
# 5. Show database statistics
|
|
6
14
|
uv run python -m chatsbom status
|
|
15
|
+
|
|
16
|
+
# 6. Query dependencies
|
|
17
|
+
uv run python -m chatsbom query gin --language go
|
|
18
|
+
|
|
19
|
+
# 7. Launch AI chat interface
|
|
7
20
|
uv run python -m chatsbom chat
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|