shotgun-sh 0.1.0.dev7__tar.gz → 0.1.0.dev9__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.
Potentially problematic release.
This version of shotgun-sh might be problematic. Click here for more details.
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/.gitignore +3 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/PKG-INFO +150 -1
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/README.md +146 -0
- shotgun_sh-0.1.0.dev9/hatch_build.py +84 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/pyproject.toml +15 -4
- shotgun_sh-0.1.0.dev9/src/shotgun/__init__.py +5 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/config/manager.py +34 -7
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/config/models.py +2 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/build_constants.py +20 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/config.py +14 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/plan.py +11 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/research.py +11 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/tasks.py +11 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/cli/update.py +152 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/main.py +148 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/posthog_telemetry.py +156 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/sentry_telemetry.py +85 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/telemetry.py +86 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/tui/app.py +84 -0
- shotgun_sh-0.1.0.dev9/src/shotgun/utils/update_checker.py +375 -0
- shotgun_sh-0.1.0.dev7/src/shotgun/__init__.py +0 -3
- shotgun_sh-0.1.0.dev7/src/shotgun/main.py +0 -78
- shotgun_sh-0.1.0.dev7/src/shotgun/telemetry.py +0 -44
- shotgun_sh-0.1.0.dev7/src/shotgun/tui/app.py +0 -49
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/LICENSE +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/agent_manager.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/common.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/config/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/config/provider.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/history/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/history/history_processors.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/plan.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/research.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tasks.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/codebase_shell.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/directory_lister.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/file_read.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/query_graph.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/codebase/retrieve_code.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/file_management.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/user_interaction.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/web_search/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/web_search/anthropic.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/web_search/gemini.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/web_search/openai.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/agents/tools/web_search/utils.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/codebase/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/codebase/commands.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/codebase/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/cli/utils.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/change_detector.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/code_retrieval.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/ingestor.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/language_config.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/manager.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/nl_query.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/core/parser_loader.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/codebase/service.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/logging_config.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/partials/codebase_understanding.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/partials/interactive_mode.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/plan.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/research.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/state/system_state.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/agents/tasks.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/cypher_query_patterns.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/cypher_system.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/enhanced_query_context.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/partials/cypher_rules.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/partials/graph_schema.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/codebase/partials/temporal_context.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/history/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/history/summarization.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/loader.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/prompts/user/research.j2 +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/py.typed +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/sdk/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/sdk/codebase.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/sdk/exceptions.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/sdk/models.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/sdk/services.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/components/prompt_input.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/components/spinner.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/components/splash.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/components/vertical_tail.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/screens/chat.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/screens/chat.tcss +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/screens/provider_config.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/screens/splash.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/tui/styles.tcss +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/utils/__init__.py +0 -0
- {shotgun_sh-0.1.0.dev7 → shotgun_sh-0.1.0.dev9}/src/shotgun/utils/file_system_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shotgun-sh
|
|
3
|
-
Version: 0.1.0.
|
|
3
|
+
Version: 0.1.0.dev9
|
|
4
4
|
Summary: AI-powered research, planning, and task management CLI tool
|
|
5
5
|
Project-URL: Homepage, https://shotgun.sh/
|
|
6
6
|
Project-URL: Repository, https://github.com/shotgun-sh/shotgun
|
|
@@ -29,8 +29,11 @@ Requires-Dist: jinja2>=3.1.0
|
|
|
29
29
|
Requires-Dist: kuzu>=0.7.0
|
|
30
30
|
Requires-Dist: logfire[pydantic-ai]>=2.0.0
|
|
31
31
|
Requires-Dist: openai>=1.0.0
|
|
32
|
+
Requires-Dist: packaging>=23.0
|
|
33
|
+
Requires-Dist: posthog>=3.0.0
|
|
32
34
|
Requires-Dist: pydantic-ai>=0.0.14
|
|
33
35
|
Requires-Dist: rich>=13.0.0
|
|
36
|
+
Requires-Dist: sentry-sdk[pure-eval]>=2.0.0
|
|
34
37
|
Requires-Dist: textual-dev>=1.7.0
|
|
35
38
|
Requires-Dist: textual>=6.1.0
|
|
36
39
|
Requires-Dist: tree-sitter-go>=0.23.0
|
|
@@ -131,6 +134,44 @@ uv run shotgun plan "Build a web application"
|
|
|
131
134
|
uv run shotgun tasks "Create a machine learning model"
|
|
132
135
|
```
|
|
133
136
|
|
|
137
|
+
## Auto-Updates
|
|
138
|
+
|
|
139
|
+
Shotgun automatically checks for updates to keep you on the latest version.
|
|
140
|
+
|
|
141
|
+
### How it works
|
|
142
|
+
|
|
143
|
+
- Checks for updates on startup (runs in background, non-blocking)
|
|
144
|
+
- Caches results for 24 hours to minimize API calls
|
|
145
|
+
- Shows notification after command execution if an update is available
|
|
146
|
+
- Never auto-updates development versions
|
|
147
|
+
|
|
148
|
+
### Update Commands
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Check for available updates
|
|
152
|
+
shotgun update --check
|
|
153
|
+
|
|
154
|
+
# Install available updates
|
|
155
|
+
shotgun update
|
|
156
|
+
|
|
157
|
+
# Force update (even for dev versions with confirmation)
|
|
158
|
+
shotgun update --force
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Disable Update Checks
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Disable for a single command
|
|
165
|
+
shotgun --no-update-check research "topic"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Installation Methods
|
|
169
|
+
|
|
170
|
+
The update command automatically detects and uses the appropriate method:
|
|
171
|
+
- **pipx**: `pipx upgrade shotgun-sh`
|
|
172
|
+
- **pip**: `pip install --upgrade shotgun-sh`
|
|
173
|
+
- **venv**: Updates within the virtual environment
|
|
174
|
+
|
|
134
175
|
## Development Setup
|
|
135
176
|
|
|
136
177
|
### Requirements
|
|
@@ -312,6 +353,114 @@ GitHub Actions automatically:
|
|
|
312
353
|
- Validates code with ruff, ruff-format, and mypy
|
|
313
354
|
- Ensures all checks pass before merge
|
|
314
355
|
|
|
356
|
+
## Observability & Telemetry
|
|
357
|
+
|
|
358
|
+
Shotgun includes built-in observability with Sentry for error tracking and Logfire for logging and tracing. Both services track users anonymously using a UUID generated on first run.
|
|
359
|
+
|
|
360
|
+
### Anonymous User Tracking
|
|
361
|
+
|
|
362
|
+
Each user gets a unique anonymous ID stored in their config:
|
|
363
|
+
```bash
|
|
364
|
+
# Get your anonymous user ID
|
|
365
|
+
shotgun config get-user-id
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
This ID is automatically included in:
|
|
369
|
+
- **Sentry**: Error reports and exceptions
|
|
370
|
+
- **Logfire**: All logs, traces, and spans
|
|
371
|
+
|
|
372
|
+
### Logfire Queries
|
|
373
|
+
|
|
374
|
+
Logfire uses SQL for querying logs. Here are helpful queries for debugging and analysis:
|
|
375
|
+
|
|
376
|
+
#### Find all logs for a specific user
|
|
377
|
+
```sql
|
|
378
|
+
SELECT * FROM records
|
|
379
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
380
|
+
ORDER BY timestamp DESC;
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### Track user actions
|
|
384
|
+
```sql
|
|
385
|
+
SELECT
|
|
386
|
+
timestamp,
|
|
387
|
+
span_name,
|
|
388
|
+
message,
|
|
389
|
+
attributes
|
|
390
|
+
FROM records
|
|
391
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
392
|
+
AND span_name LIKE '%research%'
|
|
393
|
+
ORDER BY timestamp DESC;
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
#### Find slow operations for a user
|
|
397
|
+
```sql
|
|
398
|
+
SELECT
|
|
399
|
+
span_name,
|
|
400
|
+
duration_ms,
|
|
401
|
+
attributes
|
|
402
|
+
FROM records
|
|
403
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
404
|
+
AND duration_ms > 1000
|
|
405
|
+
ORDER BY duration_ms DESC;
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### Find errors for a user
|
|
409
|
+
```sql
|
|
410
|
+
SELECT * FROM records
|
|
411
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
412
|
+
AND level = 'error'
|
|
413
|
+
ORDER BY timestamp DESC;
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### Analyze user's AI provider usage
|
|
417
|
+
```sql
|
|
418
|
+
SELECT
|
|
419
|
+
attributes->>'provider' as provider,
|
|
420
|
+
COUNT(*) as usage_count,
|
|
421
|
+
AVG(duration_ms) as avg_duration
|
|
422
|
+
FROM records
|
|
423
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
424
|
+
AND attributes->>'provider' IS NOT NULL
|
|
425
|
+
GROUP BY provider;
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
#### Track feature usage by user
|
|
429
|
+
```sql
|
|
430
|
+
SELECT
|
|
431
|
+
span_name,
|
|
432
|
+
COUNT(*) as usage_count
|
|
433
|
+
FROM records
|
|
434
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
435
|
+
AND span_name IN ('research', 'plan', 'tasks')
|
|
436
|
+
GROUP BY span_name
|
|
437
|
+
ORDER BY usage_count DESC;
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Setting Up Observability (Optional)
|
|
441
|
+
|
|
442
|
+
For local development with Logfire:
|
|
443
|
+
```bash
|
|
444
|
+
# Set environment variables
|
|
445
|
+
export LOGFIRE_ENABLED=true
|
|
446
|
+
export LOGFIRE_TOKEN=your-logfire-token
|
|
447
|
+
|
|
448
|
+
# Run shotgun - will now send logs to Logfire
|
|
449
|
+
shotgun research "topic"
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
For Sentry (automatically configured in production builds):
|
|
453
|
+
```bash
|
|
454
|
+
# Set for local development
|
|
455
|
+
export SENTRY_DSN=your-sentry-dsn
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Privacy
|
|
459
|
+
|
|
460
|
+
- **No PII collected**: Only anonymous UUIDs are used for identification
|
|
461
|
+
- **Opt-in for development**: Telemetry requires explicit environment variables
|
|
462
|
+
- **Automatic in production**: Production builds include telemetry for error tracking
|
|
463
|
+
|
|
315
464
|
## Support
|
|
316
465
|
|
|
317
466
|
Join our discord https://discord.gg/5RmY6J2N7s
|
|
@@ -81,6 +81,44 @@ uv run shotgun plan "Build a web application"
|
|
|
81
81
|
uv run shotgun tasks "Create a machine learning model"
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
## Auto-Updates
|
|
85
|
+
|
|
86
|
+
Shotgun automatically checks for updates to keep you on the latest version.
|
|
87
|
+
|
|
88
|
+
### How it works
|
|
89
|
+
|
|
90
|
+
- Checks for updates on startup (runs in background, non-blocking)
|
|
91
|
+
- Caches results for 24 hours to minimize API calls
|
|
92
|
+
- Shows notification after command execution if an update is available
|
|
93
|
+
- Never auto-updates development versions
|
|
94
|
+
|
|
95
|
+
### Update Commands
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Check for available updates
|
|
99
|
+
shotgun update --check
|
|
100
|
+
|
|
101
|
+
# Install available updates
|
|
102
|
+
shotgun update
|
|
103
|
+
|
|
104
|
+
# Force update (even for dev versions with confirmation)
|
|
105
|
+
shotgun update --force
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Disable Update Checks
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Disable for a single command
|
|
112
|
+
shotgun --no-update-check research "topic"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Installation Methods
|
|
116
|
+
|
|
117
|
+
The update command automatically detects and uses the appropriate method:
|
|
118
|
+
- **pipx**: `pipx upgrade shotgun-sh`
|
|
119
|
+
- **pip**: `pip install --upgrade shotgun-sh`
|
|
120
|
+
- **venv**: Updates within the virtual environment
|
|
121
|
+
|
|
84
122
|
## Development Setup
|
|
85
123
|
|
|
86
124
|
### Requirements
|
|
@@ -262,6 +300,114 @@ GitHub Actions automatically:
|
|
|
262
300
|
- Validates code with ruff, ruff-format, and mypy
|
|
263
301
|
- Ensures all checks pass before merge
|
|
264
302
|
|
|
303
|
+
## Observability & Telemetry
|
|
304
|
+
|
|
305
|
+
Shotgun includes built-in observability with Sentry for error tracking and Logfire for logging and tracing. Both services track users anonymously using a UUID generated on first run.
|
|
306
|
+
|
|
307
|
+
### Anonymous User Tracking
|
|
308
|
+
|
|
309
|
+
Each user gets a unique anonymous ID stored in their config:
|
|
310
|
+
```bash
|
|
311
|
+
# Get your anonymous user ID
|
|
312
|
+
shotgun config get-user-id
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
This ID is automatically included in:
|
|
316
|
+
- **Sentry**: Error reports and exceptions
|
|
317
|
+
- **Logfire**: All logs, traces, and spans
|
|
318
|
+
|
|
319
|
+
### Logfire Queries
|
|
320
|
+
|
|
321
|
+
Logfire uses SQL for querying logs. Here are helpful queries for debugging and analysis:
|
|
322
|
+
|
|
323
|
+
#### Find all logs for a specific user
|
|
324
|
+
```sql
|
|
325
|
+
SELECT * FROM records
|
|
326
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
327
|
+
ORDER BY timestamp DESC;
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
#### Track user actions
|
|
331
|
+
```sql
|
|
332
|
+
SELECT
|
|
333
|
+
timestamp,
|
|
334
|
+
span_name,
|
|
335
|
+
message,
|
|
336
|
+
attributes
|
|
337
|
+
FROM records
|
|
338
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
339
|
+
AND span_name LIKE '%research%'
|
|
340
|
+
ORDER BY timestamp DESC;
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
#### Find slow operations for a user
|
|
344
|
+
```sql
|
|
345
|
+
SELECT
|
|
346
|
+
span_name,
|
|
347
|
+
duration_ms,
|
|
348
|
+
attributes
|
|
349
|
+
FROM records
|
|
350
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
351
|
+
AND duration_ms > 1000
|
|
352
|
+
ORDER BY duration_ms DESC;
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Find errors for a user
|
|
356
|
+
```sql
|
|
357
|
+
SELECT * FROM records
|
|
358
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
359
|
+
AND level = 'error'
|
|
360
|
+
ORDER BY timestamp DESC;
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Analyze user's AI provider usage
|
|
364
|
+
```sql
|
|
365
|
+
SELECT
|
|
366
|
+
attributes->>'provider' as provider,
|
|
367
|
+
COUNT(*) as usage_count,
|
|
368
|
+
AVG(duration_ms) as avg_duration
|
|
369
|
+
FROM records
|
|
370
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
371
|
+
AND attributes->>'provider' IS NOT NULL
|
|
372
|
+
GROUP BY provider;
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### Track feature usage by user
|
|
376
|
+
```sql
|
|
377
|
+
SELECT
|
|
378
|
+
span_name,
|
|
379
|
+
COUNT(*) as usage_count
|
|
380
|
+
FROM records
|
|
381
|
+
WHERE attributes->>'user_id' = 'your-user-id-here'
|
|
382
|
+
AND span_name IN ('research', 'plan', 'tasks')
|
|
383
|
+
GROUP BY span_name
|
|
384
|
+
ORDER BY usage_count DESC;
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Setting Up Observability (Optional)
|
|
388
|
+
|
|
389
|
+
For local development with Logfire:
|
|
390
|
+
```bash
|
|
391
|
+
# Set environment variables
|
|
392
|
+
export LOGFIRE_ENABLED=true
|
|
393
|
+
export LOGFIRE_TOKEN=your-logfire-token
|
|
394
|
+
|
|
395
|
+
# Run shotgun - will now send logs to Logfire
|
|
396
|
+
shotgun research "topic"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
For Sentry (automatically configured in production builds):
|
|
400
|
+
```bash
|
|
401
|
+
# Set for local development
|
|
402
|
+
export SENTRY_DSN=your-sentry-dsn
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Privacy
|
|
406
|
+
|
|
407
|
+
- **No PII collected**: Only anonymous UUIDs are used for identification
|
|
408
|
+
- **Opt-in for development**: Telemetry requires explicit environment variables
|
|
409
|
+
- **Automatic in production**: Production builds include telemetry for error tracking
|
|
410
|
+
|
|
265
411
|
## Support
|
|
266
412
|
|
|
267
413
|
Join our discord https://discord.gg/5RmY6J2N7s
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Hatchling build hook for generating build constants."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CustomBuildHook(BuildHookInterface): # type: ignore[type-arg]
|
|
10
|
+
"""Custom build hook to generate build constants from environment variables."""
|
|
11
|
+
|
|
12
|
+
def initialize(self, version, build_data): # type: ignore[no-untyped-def]
|
|
13
|
+
"""Generate build constants file from environment variables.
|
|
14
|
+
|
|
15
|
+
This runs immediately before each build.
|
|
16
|
+
"""
|
|
17
|
+
# Check if this is a development build based on version
|
|
18
|
+
is_dev_build = any(
|
|
19
|
+
marker in str(version)
|
|
20
|
+
for marker in ["dev", "rc", "alpha", "beta", "a", "b"]
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Only generate constants if SENTRY_DSN is provided (production builds)
|
|
24
|
+
sentry_dsn = os.environ.get("SENTRY_DSN", "")
|
|
25
|
+
|
|
26
|
+
# Get PostHog configuration from environment
|
|
27
|
+
posthog_api_key = os.environ.get("POSTHOG_API_KEY", "")
|
|
28
|
+
posthog_project_id = os.environ.get("POSTHOG_PROJECT_ID", "")
|
|
29
|
+
|
|
30
|
+
# Get Logfire configuration (only for dev builds)
|
|
31
|
+
logfire_enabled = ""
|
|
32
|
+
logfire_token = ""
|
|
33
|
+
if is_dev_build:
|
|
34
|
+
logfire_enabled = os.environ.get("LOGFIRE_ENABLED", "")
|
|
35
|
+
logfire_token = os.environ.get("LOGFIRE_TOKEN", "")
|
|
36
|
+
|
|
37
|
+
# Generate Python configuration file with build-time constants
|
|
38
|
+
constants_content = f'''"""Build-time constants generated during packaging.
|
|
39
|
+
|
|
40
|
+
This file is auto-generated during the build process.
|
|
41
|
+
DO NOT EDIT MANUALLY.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
# Sentry DSN embedded at build time (empty string if not provided)
|
|
45
|
+
SENTRY_DSN = {repr(sentry_dsn)}
|
|
46
|
+
|
|
47
|
+
# PostHog configuration embedded at build time (empty strings if not provided)
|
|
48
|
+
POSTHOG_API_KEY = {repr(posthog_api_key)}
|
|
49
|
+
POSTHOG_PROJECT_ID = {repr(posthog_project_id)}
|
|
50
|
+
|
|
51
|
+
# Logfire configuration embedded at build time (only for dev builds)
|
|
52
|
+
LOGFIRE_ENABLED = {repr(logfire_enabled)}
|
|
53
|
+
LOGFIRE_TOKEN = {repr(logfire_token)}
|
|
54
|
+
|
|
55
|
+
# Build metadata
|
|
56
|
+
BUILD_TIME_ENV = "production" if SENTRY_DSN else "development"
|
|
57
|
+
IS_DEV_BUILD = {repr(is_dev_build)}
|
|
58
|
+
'''
|
|
59
|
+
|
|
60
|
+
# Write to build_constants.py in the source directory
|
|
61
|
+
output_path = Path(self.root) / "src" / "shotgun" / "build_constants.py"
|
|
62
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
63
|
+
|
|
64
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
65
|
+
f.write(constants_content)
|
|
66
|
+
|
|
67
|
+
# Log the build hook execution
|
|
68
|
+
features = []
|
|
69
|
+
if sentry_dsn:
|
|
70
|
+
features.append("Sentry")
|
|
71
|
+
if posthog_api_key:
|
|
72
|
+
features.append("PostHog")
|
|
73
|
+
if logfire_enabled and logfire_token:
|
|
74
|
+
features.append("Logfire")
|
|
75
|
+
|
|
76
|
+
if features:
|
|
77
|
+
build_type = "development" if is_dev_build else "production"
|
|
78
|
+
print(
|
|
79
|
+
f"✅ Generated build_constants.py with {', '.join(features)} ({build_type} build)"
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
print(
|
|
83
|
+
"⚠️ Generated build_constants.py without analytics keys (development build)"
|
|
84
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "shotgun-sh"
|
|
3
|
-
version = "0.1.0.
|
|
3
|
+
version = "0.1.0.dev9"
|
|
4
4
|
description = "AI-powered research, planning, and task management CLI tool"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "MIT" }
|
|
@@ -29,6 +29,8 @@ dependencies = [
|
|
|
29
29
|
"httpx>=0.27.0",
|
|
30
30
|
"jinja2>=3.1.0",
|
|
31
31
|
"logfire[pydantic-ai]>=2.0.0",
|
|
32
|
+
"sentry-sdk[pure_eval]>=2.0.0",
|
|
33
|
+
"posthog>=3.0.0",
|
|
32
34
|
"textual>=6.1.0",
|
|
33
35
|
"textual-dev>=1.7.0",
|
|
34
36
|
"kuzu>=0.7.0",
|
|
@@ -42,6 +44,7 @@ dependencies = [
|
|
|
42
44
|
"openai>=1.0.0",
|
|
43
45
|
"anthropic>=0.39.0",
|
|
44
46
|
"google-generativeai>=0.8.0",
|
|
47
|
+
"packaging>=23.0",
|
|
45
48
|
]
|
|
46
49
|
|
|
47
50
|
[project.urls]
|
|
@@ -60,7 +63,6 @@ dev = [
|
|
|
60
63
|
|
|
61
64
|
[project.scripts]
|
|
62
65
|
shotgun = "shotgun.main:app"
|
|
63
|
-
tui = "shotgun.tui.app:run"
|
|
64
66
|
|
|
65
67
|
[build-system]
|
|
66
68
|
requires = ["hatchling"]
|
|
@@ -77,9 +79,18 @@ include = [
|
|
|
77
79
|
"/pyproject.toml"
|
|
78
80
|
]
|
|
79
81
|
|
|
82
|
+
[tool.hatch.build.hooks.custom]
|
|
83
|
+
# Custom build hook configuration
|
|
84
|
+
|
|
85
|
+
[tool.hatch.build]
|
|
86
|
+
artifacts = [
|
|
87
|
+
"src/shotgun/build_constants.py"
|
|
88
|
+
]
|
|
89
|
+
|
|
80
90
|
[tool.ruff]
|
|
81
91
|
line-length = 88
|
|
82
92
|
target-version = "py310"
|
|
93
|
+
exclude = ["src/shotgun/build_constants.py"]
|
|
83
94
|
|
|
84
95
|
[tool.ruff.lint]
|
|
85
96
|
select = ["E", "W", "F", "I", "N", "UP", "B", "S", "C4", "PIE", "T20"]
|
|
@@ -93,8 +104,8 @@ python_version = "3.10"
|
|
|
93
104
|
strict = true
|
|
94
105
|
warn_return_any = true
|
|
95
106
|
warn_unused_configs = true
|
|
96
|
-
#
|
|
97
|
-
|
|
107
|
+
# Exclude build hooks and generated files
|
|
108
|
+
exclude = ["hatch_build.py", "src/shotgun/build_constants.py"]
|
|
98
109
|
plugins = ["pydantic.mypy"]
|
|
99
110
|
|
|
100
111
|
# Configure test-specific settings
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Configuration manager for Shotgun CLI."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import uuid
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Any
|
|
6
7
|
|
|
@@ -41,9 +42,11 @@ class ConfigManager:
|
|
|
41
42
|
|
|
42
43
|
if not self.config_path.exists():
|
|
43
44
|
logger.info(
|
|
44
|
-
"Configuration file not found,
|
|
45
|
+
"Configuration file not found, creating new config with user_id: %s",
|
|
46
|
+
self.config_path,
|
|
45
47
|
)
|
|
46
|
-
|
|
48
|
+
# Create new config with generated user_id
|
|
49
|
+
self._config = self.initialize()
|
|
47
50
|
return self._config
|
|
48
51
|
|
|
49
52
|
try:
|
|
@@ -61,8 +64,8 @@ class ConfigManager:
|
|
|
61
64
|
logger.error(
|
|
62
65
|
"Failed to load configuration from %s: %s", self.config_path, e
|
|
63
66
|
)
|
|
64
|
-
logger.info("
|
|
65
|
-
self._config =
|
|
67
|
+
logger.info("Creating new configuration with generated user_id")
|
|
68
|
+
self._config = self.initialize()
|
|
66
69
|
return self._config
|
|
67
70
|
|
|
68
71
|
def save(self, config: ShotgunConfig | None = None) -> None:
|
|
@@ -72,7 +75,14 @@ class ConfigManager:
|
|
|
72
75
|
config: Configuration to save. If None, saves current loaded config
|
|
73
76
|
"""
|
|
74
77
|
if config is None:
|
|
75
|
-
|
|
78
|
+
if self._config:
|
|
79
|
+
config = self._config
|
|
80
|
+
else:
|
|
81
|
+
# Create a new config with generated user_id
|
|
82
|
+
config = ShotgunConfig(
|
|
83
|
+
user_id=str(uuid.uuid4()),
|
|
84
|
+
config_version=1,
|
|
85
|
+
)
|
|
76
86
|
|
|
77
87
|
# Ensure directory exists
|
|
78
88
|
self.config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -150,9 +160,17 @@ class ConfigManager:
|
|
|
150
160
|
Returns:
|
|
151
161
|
Default ShotgunConfig
|
|
152
162
|
"""
|
|
153
|
-
|
|
163
|
+
# Generate unique user ID for new config
|
|
164
|
+
config = ShotgunConfig(
|
|
165
|
+
user_id=str(uuid.uuid4()),
|
|
166
|
+
config_version=1,
|
|
167
|
+
)
|
|
154
168
|
self.save(config)
|
|
155
|
-
logger.info(
|
|
169
|
+
logger.info(
|
|
170
|
+
"Configuration initialized at %s with user_id: %s",
|
|
171
|
+
self.config_path,
|
|
172
|
+
config.user_id,
|
|
173
|
+
)
|
|
156
174
|
return config
|
|
157
175
|
|
|
158
176
|
def _convert_secrets_to_secretstr(self, data: dict[str, Any]) -> None:
|
|
@@ -209,6 +227,15 @@ class ConfigManager:
|
|
|
209
227
|
|
|
210
228
|
return bool(value.strip())
|
|
211
229
|
|
|
230
|
+
def get_user_id(self) -> str:
|
|
231
|
+
"""Get the user ID from configuration.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
The unique user ID string
|
|
235
|
+
"""
|
|
236
|
+
config = self.load()
|
|
237
|
+
return config.user_id
|
|
238
|
+
|
|
212
239
|
|
|
213
240
|
def get_config_manager() -> ConfigManager:
|
|
214
241
|
"""Get the global ConfigManager instance."""
|
|
@@ -123,3 +123,5 @@ class ShotgunConfig(BaseModel):
|
|
|
123
123
|
default_provider: ProviderType = Field(
|
|
124
124
|
default=ProviderType.OPENAI, description="Default AI provider to use"
|
|
125
125
|
)
|
|
126
|
+
user_id: str = Field(description="Unique anonymous user identifier")
|
|
127
|
+
config_version: int = Field(default=1, description="Configuration schema version")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Build-time constants generated during packaging.
|
|
2
|
+
|
|
3
|
+
This file is auto-generated during the build process.
|
|
4
|
+
DO NOT EDIT MANUALLY.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Sentry DSN embedded at build time (empty string if not provided)
|
|
8
|
+
SENTRY_DSN = 'https://2818a6d165c64eccc94cfd51ce05d6aa@o4506813296738304.ingest.us.sentry.io/4510045952409600'
|
|
9
|
+
|
|
10
|
+
# PostHog configuration embedded at build time (empty strings if not provided)
|
|
11
|
+
POSTHOG_API_KEY = ''
|
|
12
|
+
POSTHOG_PROJECT_ID = '191396'
|
|
13
|
+
|
|
14
|
+
# Logfire configuration embedded at build time (only for dev builds)
|
|
15
|
+
LOGFIRE_ENABLED = 'true'
|
|
16
|
+
LOGFIRE_TOKEN = 'pylf_v1_us_KZ5NM1pP3NwgJkbBJt6Ftdzk8mMhmrXcGJHQQgDJ1LfK'
|
|
17
|
+
|
|
18
|
+
# Build metadata
|
|
19
|
+
BUILD_TIME_ENV = "production" if SENTRY_DSN else "development"
|
|
20
|
+
IS_DEV_BUILD = True
|
|
@@ -259,3 +259,17 @@ def _mask_value(value: str) -> str:
|
|
|
259
259
|
if len(value) <= 8:
|
|
260
260
|
return "••••••••"
|
|
261
261
|
return f"{value[:4]}{'•' * (len(value) - 8)}{value[-4:]}"
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@app.command()
|
|
265
|
+
def get_user_id() -> None:
|
|
266
|
+
"""Get the anonymous user ID from configuration."""
|
|
267
|
+
config_manager = get_config_manager()
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
user_id = config_manager.get_user_id()
|
|
271
|
+
console.print(f"[green]User ID:[/green] {user_id}")
|
|
272
|
+
except Exception as e:
|
|
273
|
+
logger.error(f"Error getting user ID: {e}")
|
|
274
|
+
console.print(f"❌ Failed to get user ID: {str(e)}", style="red")
|
|
275
|
+
raise typer.Exit(1) from e
|
|
@@ -38,6 +38,17 @@ def plan(
|
|
|
38
38
|
logger.info("📋 Planning Goal: %s", goal)
|
|
39
39
|
|
|
40
40
|
try:
|
|
41
|
+
# Track plan command usage
|
|
42
|
+
from shotgun.posthog_telemetry import track_event
|
|
43
|
+
|
|
44
|
+
track_event(
|
|
45
|
+
"plan_command",
|
|
46
|
+
{
|
|
47
|
+
"non_interactive": non_interactive,
|
|
48
|
+
"provider": provider.value if provider else "default",
|
|
49
|
+
},
|
|
50
|
+
)
|
|
51
|
+
|
|
41
52
|
# Create agent dependencies
|
|
42
53
|
agent_runtime_options = AgentRuntimeOptions(
|
|
43
54
|
interactive_mode=not non_interactive
|
|
@@ -58,6 +58,17 @@ async def async_research(
|
|
|
58
58
|
provider: ProviderType | None = None,
|
|
59
59
|
) -> None:
|
|
60
60
|
"""Async wrapper for research process."""
|
|
61
|
+
# Track research command usage
|
|
62
|
+
from shotgun.posthog_telemetry import track_event
|
|
63
|
+
|
|
64
|
+
track_event(
|
|
65
|
+
"research_command",
|
|
66
|
+
{
|
|
67
|
+
"non_interactive": non_interactive,
|
|
68
|
+
"provider": provider.value if provider else "default",
|
|
69
|
+
},
|
|
70
|
+
)
|
|
71
|
+
|
|
61
72
|
# Create agent dependencies
|
|
62
73
|
agent_runtime_options = AgentRuntimeOptions(interactive_mode=not non_interactive)
|
|
63
74
|
|
|
@@ -44,6 +44,17 @@ def tasks(
|
|
|
44
44
|
logger.info("📋 Task Creation Instruction: %s", instruction)
|
|
45
45
|
|
|
46
46
|
try:
|
|
47
|
+
# Track tasks command usage
|
|
48
|
+
from shotgun.posthog_telemetry import track_event
|
|
49
|
+
|
|
50
|
+
track_event(
|
|
51
|
+
"tasks_command",
|
|
52
|
+
{
|
|
53
|
+
"non_interactive": non_interactive,
|
|
54
|
+
"provider": provider.value if provider else "default",
|
|
55
|
+
},
|
|
56
|
+
)
|
|
57
|
+
|
|
47
58
|
# Create agent dependencies
|
|
48
59
|
agent_runtime_options = AgentRuntimeOptions(
|
|
49
60
|
interactive_mode=not non_interactive
|