buildai-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- buildai_cli-0.1.0/.gitignore +78 -0
- buildai_cli-0.1.0/AGENTS.md +1 -0
- buildai_cli-0.1.0/CLAUDE.md +96 -0
- buildai_cli-0.1.0/PKG-INFO +21 -0
- buildai_cli-0.1.0/cli/__init__.py +1 -0
- buildai_cli-0.1.0/cli/_has_core.py +29 -0
- buildai_cli-0.1.0/cli/commands/__init__.py +1 -0
- buildai_cli-0.1.0/cli/commands/auth_lite.py +79 -0
- buildai_cli-0.1.0/cli/commands/auth_ops.py +432 -0
- buildai_cli-0.1.0/cli/commands/clips.py +78 -0
- buildai_cli-0.1.0/cli/commands/collections.py +57 -0
- buildai_cli-0.1.0/cli/commands/database.py +2040 -0
- buildai_cli-0.1.0/cli/commands/embed.py +638 -0
- buildai_cli-0.1.0/cli/commands/external.py +276 -0
- buildai_cli-0.1.0/cli/commands/ingest.py +480 -0
- buildai_cli-0.1.0/cli/commands/jobs.py +134 -0
- buildai_cli-0.1.0/cli/commands/keys.py +68 -0
- buildai_cli-0.1.0/cli/commands/medoid.py +341 -0
- buildai_cli-0.1.0/cli/commands/migrate.py +295 -0
- buildai_cli-0.1.0/cli/commands/operations.py +48 -0
- buildai_cli-0.1.0/cli/commands/partners.py +48 -0
- buildai_cli-0.1.0/cli/commands/permissions.py +174 -0
- buildai_cli-0.1.0/cli/commands/projection.py +242 -0
- buildai_cli-0.1.0/cli/commands/query.py +213 -0
- buildai_cli-0.1.0/cli/commands/schema.py +420 -0
- buildai_cli-0.1.0/cli/commands/stats.py +44 -0
- buildai_cli-0.1.0/cli/commands/sync/__init__.py +104 -0
- buildai_cli-0.1.0/cli/commands/sync/apply.py +363 -0
- buildai_cli-0.1.0/cli/commands/sync/data.py +437 -0
- buildai_cli-0.1.0/cli/commands/sync/ddl.py +327 -0
- buildai_cli-0.1.0/cli/commands/sync/diff.py +386 -0
- buildai_cli-0.1.0/cli/commands/sync/models.py +216 -0
- buildai_cli-0.1.0/cli/commands/sync/queries.py +356 -0
- buildai_cli-0.1.0/cli/config.py +67 -0
- buildai_cli-0.1.0/cli/console.py +84 -0
- buildai_cli-0.1.0/cli/context.py +216 -0
- buildai_cli-0.1.0/cli/guard.py +26 -0
- buildai_cli-0.1.0/cli/main.py +279 -0
- buildai_cli-0.1.0/cli/nl_query/__init__.py +5 -0
- buildai_cli-0.1.0/cli/nl_query/dataset_tools.py +191 -0
- buildai_cli-0.1.0/cli/ops_init.py +147 -0
- buildai_cli-0.1.0/cli/output.py +117 -0
- buildai_cli-0.1.0/cli/sdk_client.py +28 -0
- buildai_cli-0.1.0/pyproject.toml +41 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Worktrees
|
|
2
|
+
.worktrees/
|
|
3
|
+
|
|
4
|
+
# Ralph status files
|
|
5
|
+
.ralph-status
|
|
6
|
+
|
|
7
|
+
# Python
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*$py.class
|
|
11
|
+
*.so
|
|
12
|
+
.Python
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
ENV/
|
|
16
|
+
.eggs/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
dist/
|
|
19
|
+
build/
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
|
|
23
|
+
# Node
|
|
24
|
+
node_modules/
|
|
25
|
+
.next/
|
|
26
|
+
out/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_productivity_inference/
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# OS
|
|
39
|
+
.DS_Store
|
|
40
|
+
Thumbs.db
|
|
41
|
+
|
|
42
|
+
# Environment
|
|
43
|
+
.env
|
|
44
|
+
.env.*
|
|
45
|
+
!.env.op
|
|
46
|
+
.env.local
|
|
47
|
+
.env.*.local
|
|
48
|
+
.env-archive/
|
|
49
|
+
.vercel
|
|
50
|
+
|
|
51
|
+
# Benchmark results (large files)
|
|
52
|
+
backend/benchmark-results/
|
|
53
|
+
|
|
54
|
+
# Large binary feature files
|
|
55
|
+
*.npy
|
|
56
|
+
|
|
57
|
+
# V-JEPA2 frame features (39GB+)
|
|
58
|
+
backend/results/vjepa2_frame_features/
|
|
59
|
+
|
|
60
|
+
dashboard-legacy/
|
|
61
|
+
.mcp.json
|
|
62
|
+
|
|
63
|
+
# Reference materials
|
|
64
|
+
reference/
|
|
65
|
+
sd-to-storage/
|
|
66
|
+
.dmux/
|
|
67
|
+
.hypothesis/
|
|
68
|
+
|
|
69
|
+
# Local data cache (frames, manifests, labels)
|
|
70
|
+
.cache/
|
|
71
|
+
|
|
72
|
+
# Generated data artifacts & reports
|
|
73
|
+
scripts/dead_assets.json
|
|
74
|
+
scripts/dead_assets.ids.txt
|
|
75
|
+
scripts/sample_preview.html
|
|
76
|
+
scripts/sample_dataset_report.html
|
|
77
|
+
outputs/
|
|
78
|
+
reference_mobile.png
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CLAUDE.md
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# apps/buildai-cli/
|
|
2
|
+
|
|
3
|
+
Typer CLI with two planes, distributable as a standalone package:
|
|
4
|
+
- **Data plane**: SDK-backed commands (clips, jobs, collections, partners, operations, keys, stats). Requires `BUILDAI_API_KEY`. Works with just `pip install buildai-cli`.
|
|
5
|
+
- **Ops plane**: DAL-direct commands (database, schema, auth CRUD, permissions, ingest, projection, medoid, external). Requires DB access. Install with `pip install 'buildai-cli[ops]'`.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
- `cli/_has_core.py` — detects if `buildai-core` is installed
|
|
10
|
+
- `cli/ops_init.py` — lazy DB/auth/observability setup (called by ops commands, NOT at startup)
|
|
11
|
+
- `cli/main.py` — lightweight callback, conditional ops registration, stubs when core absent
|
|
12
|
+
- `cli/commands/auth_lite.py` — login + status (no core deps)
|
|
13
|
+
- `cli/commands/auth_ops.py` — API key CRUD (ops-plane, requires core)
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
1. Always run from repo root (`uv run buildai`), never from inside the app directory.
|
|
18
|
+
2. Default profile is read-only. Mutations require `--profile admin --write`.
|
|
19
|
+
3. Missing `--write` on mutating commands now errors (not silent no-op).
|
|
20
|
+
4. All DB access goes through `core/data/` DAL with a `CLIContext`. No raw SQL in commands.
|
|
21
|
+
5. The `query` command only permits SELECT/WITH/EXPLAIN — it blocks mutations at parse time (via sqlparse AST).
|
|
22
|
+
6. Data-plane commands go through the SDK — they need an API key, not DB credentials.
|
|
23
|
+
7. **No `infra` imports at module level** in main.py or data-plane modules.
|
|
24
|
+
|
|
25
|
+
## Data Plane (SDK-backed)
|
|
26
|
+
|
|
27
|
+
These commands wrap `buildai` SDK resources. Set `BUILDAI_API_KEY` or `buildai auth login <key>`.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv run buildai clips list --factory <id> --limit 5
|
|
31
|
+
uv run buildai jobs list --status running
|
|
32
|
+
uv run buildai jobs retry <id> --write
|
|
33
|
+
uv run buildai collections list
|
|
34
|
+
uv run buildai stats overview
|
|
35
|
+
uv run buildai partners list # internal mode
|
|
36
|
+
uv run buildai operations hours # internal mode
|
|
37
|
+
uv run buildai keys list # internal mode
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Ops Plane (DAL-direct)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv run buildai --profile readonly database status
|
|
44
|
+
uv run buildai --profile readonly schema tables
|
|
45
|
+
uv run buildai auth status
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Output
|
|
49
|
+
|
|
50
|
+
- TTY detected: table format (Rich tables)
|
|
51
|
+
- Piped: JSON format (machine-readable)
|
|
52
|
+
- Override: `--format json|table|csv|jsonl`
|
|
53
|
+
- Status/errors go to stderr, data to stdout
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Workspace (all commands — ops + data plane)
|
|
59
|
+
uv pip install -e "apps/buildai-cli[ops]" -e core -e services -e apps/buildai-sdk
|
|
60
|
+
|
|
61
|
+
# Standalone data-plane only
|
|
62
|
+
pip install buildai-cli # or: uv tool install -e ./apps/buildai-cli
|
|
63
|
+
|
|
64
|
+
# Global install
|
|
65
|
+
uv tool install -e ./apps/buildai-cli
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Run
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
uv run buildai --profile readonly <command>
|
|
72
|
+
uv run buildai --profile admin --write <command>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Things That Will Bite You
|
|
76
|
+
|
|
77
|
+
- `uv run buildai` fails with `ModuleNotFoundError` after pulling — reinstall with: `uv pip install -e "apps/buildai-cli[ops]" -e core -e services -e apps/buildai-sdk`
|
|
78
|
+
- `--env production` requires valid production DB credentials.
|
|
79
|
+
- New data-plane command groups: register in `cli/main.py` in the data-plane section.
|
|
80
|
+
- New ops-plane command groups: register in `cli/main.py` via `_register_ops_typer()` inside `if has_core():`, and add to `_OPS_GROUPS` in the else branch.
|
|
81
|
+
- Data-plane commands fail without `BUILDAI_API_KEY` — use `buildai auth login` to configure.
|
|
82
|
+
- `--dry-run` is available on all mutating data-plane commands.
|
|
83
|
+
- Shell completion: `uv run buildai --install-completion`
|
|
84
|
+
- Auth ops commands (create-key, list-keys, show-key, revoke-key) call `init_ops_context()` themselves — they're registered onto the auth_lite app, not via `_register_ops_typer`.
|
|
85
|
+
|
|
86
|
+
## Closing the Loop
|
|
87
|
+
|
|
88
|
+
When adding a command group: register it in `cli/main.py`. Data-plane = always imported. Ops-plane = behind `has_core()` guard.
|
|
89
|
+
|
|
90
|
+
## See Also
|
|
91
|
+
|
|
92
|
+
| Topic | File |
|
|
93
|
+
|-------|------|
|
|
94
|
+
| DAL patterns, profiles, Context | `core/CLAUDE.md` |
|
|
95
|
+
| SDK resources | `apps/buildai-sdk/CLAUDE.md` |
|
|
96
|
+
| Common failure modes | `docs/gotchas.md` |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: buildai-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Build AI CLI (Typer)
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: buildai-sdk
|
|
7
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
8
|
+
Requires-Dist: rich>=13.0.0
|
|
9
|
+
Requires-Dist: typer>=0.12.0
|
|
10
|
+
Provides-Extra: ops
|
|
11
|
+
Requires-Dist: anthropic>=0.73.0; extra == 'ops'
|
|
12
|
+
Requires-Dist: anyio>=4.0.0; extra == 'ops'
|
|
13
|
+
Requires-Dist: buildai-core; extra == 'ops'
|
|
14
|
+
Requires-Dist: buildai-services; extra == 'ops'
|
|
15
|
+
Requires-Dist: claude-agent-sdk>=0.1.6; extra == 'ops'
|
|
16
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'ops'
|
|
17
|
+
Requires-Dist: matplotlib>=3.10.7; extra == 'ops'
|
|
18
|
+
Requires-Dist: questionary>=2.0.1; extra == 'ops'
|
|
19
|
+
Requires-Dist: sqlparse>=0.4.4; extra == 'ops'
|
|
20
|
+
Requires-Dist: textual-plotext>=1.0.1; extra == 'ops'
|
|
21
|
+
Requires-Dist: textual>=6.6.0; extra == 'ops'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""BuildAI Backend CLI."""
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Detect whether buildai-core is available."""
|
|
2
|
+
|
|
3
|
+
_cached: bool | None = None
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def has_core() -> bool:
|
|
7
|
+
global _cached
|
|
8
|
+
if _cached is None:
|
|
9
|
+
try:
|
|
10
|
+
import infra # noqa: F401
|
|
11
|
+
|
|
12
|
+
_cached = True
|
|
13
|
+
except ImportError:
|
|
14
|
+
_cached = False
|
|
15
|
+
return _cached
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def require_core(command_name: str) -> None:
|
|
19
|
+
if not has_core():
|
|
20
|
+
import typer
|
|
21
|
+
|
|
22
|
+
from cli.console import error
|
|
23
|
+
|
|
24
|
+
error(
|
|
25
|
+
f"'{command_name}' requires ops-plane deps.\n"
|
|
26
|
+
f" Install with: pip install 'buildai-cli[ops]'\n"
|
|
27
|
+
f" Or workspace: uv pip install -e 'apps/buildai-cli[ops]' -e core"
|
|
28
|
+
)
|
|
29
|
+
raise typer.Exit(1)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI commands — use direct imports, not this barrel."""
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Lightweight auth commands — no core/infra deps."""
|
|
2
|
+
|
|
3
|
+
from typing_extensions import Annotated
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from cli.config import resolve_cli_api_key, save_cli_config
|
|
8
|
+
from cli.console import console, success
|
|
9
|
+
|
|
10
|
+
app = typer.Typer(
|
|
11
|
+
name="auth",
|
|
12
|
+
help="Authentication and API key management",
|
|
13
|
+
no_args_is_help=True,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@app.command("login")
|
|
18
|
+
def login(
|
|
19
|
+
api_key: Annotated[str, typer.Argument(help="API key to store locally")],
|
|
20
|
+
profile: Annotated[
|
|
21
|
+
str | None,
|
|
22
|
+
typer.Option(
|
|
23
|
+
"--profile",
|
|
24
|
+
"-p",
|
|
25
|
+
help="Default CLI profile (e.g., readonly, mcp, svc_embedder)",
|
|
26
|
+
),
|
|
27
|
+
] = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
"""Store an API key and optional profile in ~/.buildai/config.toml."""
|
|
30
|
+
save_cli_config(api_key=api_key, profile=profile)
|
|
31
|
+
success("Saved CLI credentials to ~/.buildai/config.toml")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@app.command("status")
|
|
35
|
+
def auth_status(ctx: typer.Context) -> None:
|
|
36
|
+
"""Show current authentication state — gcloud account, API key, profile."""
|
|
37
|
+
import subprocess
|
|
38
|
+
|
|
39
|
+
cli_profile = (ctx.obj or {}).get("cli_profile", "readonly")
|
|
40
|
+
|
|
41
|
+
# gcloud active account
|
|
42
|
+
try:
|
|
43
|
+
result = subprocess.run(
|
|
44
|
+
[
|
|
45
|
+
"gcloud",
|
|
46
|
+
"auth",
|
|
47
|
+
"list",
|
|
48
|
+
"--filter=status=ACTIVE",
|
|
49
|
+
"--format=value(account)",
|
|
50
|
+
],
|
|
51
|
+
capture_output=True,
|
|
52
|
+
text=True,
|
|
53
|
+
timeout=5,
|
|
54
|
+
)
|
|
55
|
+
gcloud_account = result.stdout.strip() or "not authenticated"
|
|
56
|
+
except Exception:
|
|
57
|
+
gcloud_account = "gcloud not available"
|
|
58
|
+
|
|
59
|
+
console.print(f" gcloud account : [cyan]{gcloud_account}[/cyan]")
|
|
60
|
+
console.print(f" profile : {cli_profile}")
|
|
61
|
+
|
|
62
|
+
# DB environment (only if core available)
|
|
63
|
+
from cli._has_core import has_core
|
|
64
|
+
|
|
65
|
+
if has_core() and ctx.obj and ctx.obj.get("_ops_ready"):
|
|
66
|
+
settings = ctx.obj.get("settings")
|
|
67
|
+
if settings:
|
|
68
|
+
env_color = "yellow" if settings.is_production else "green"
|
|
69
|
+
console.print(f" DB environment : [{env_color}]{settings.app_env.value}[/]")
|
|
70
|
+
else:
|
|
71
|
+
console.print(" DB environment : [dim]n/a (ops-plane not loaded)[/dim]")
|
|
72
|
+
|
|
73
|
+
# API key status
|
|
74
|
+
api_key = resolve_cli_api_key()
|
|
75
|
+
if api_key:
|
|
76
|
+
prefix = api_key[:12] + "..."
|
|
77
|
+
console.print(f" API key : [green]{prefix}[/green]")
|
|
78
|
+
else:
|
|
79
|
+
console.print(" API key : [dim]not configured (set BUILDAI_API_KEY)[/dim]")
|