baucli 1.0.4__tar.gz → 1.0.6__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.
- {baucli-1.0.4 → baucli-1.0.6}/PKG-INFO +1 -1
- {baucli-1.0.4 → baucli-1.0.6}/baucli/__init__.py +1 -1
- {baucli-1.0.4 → baucli-1.0.6}/baucli/api.py +22 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/cli.py +52 -4
- {baucli-1.0.4 → baucli-1.0.6}/baucli/mcp_server.py +31 -1
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/PKG-INFO +1 -1
- {baucli-1.0.4 → baucli-1.0.6}/setup.py +1 -1
- {baucli-1.0.4 → baucli-1.0.6}/README.md +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/apex_rebuild.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/apexlang.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/config.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/db/__init__.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/db/mssql.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/db/mysql.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/db/oracle.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/db/postgresql.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/docmig.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/git.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/legacy/__init__.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/legacy/delphi.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/project.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/rag_embed.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/sample_scan.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/scope_scan.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/screenshot.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/seed_check.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/stress.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli/sync.py +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/SOURCES.txt +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/dependency_links.txt +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/entry_points.txt +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/requires.txt +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/top_level.txt +0 -0
- {baucli-1.0.4 → baucli-1.0.6}/setup.cfg +0 -0
|
@@ -169,6 +169,28 @@ class BauApi:
|
|
|
169
169
|
return self._request("GET", "verify/column",
|
|
170
170
|
params={"schema": schema, "table": table, "column": column})
|
|
171
171
|
|
|
172
|
+
# ── AI Edit Safety (F2) — rotina grande demais p/ a IA editar inteira ─
|
|
173
|
+
def large_routines(self, schema: str, scope: str = None, language: str = None) -> dict:
|
|
174
|
+
"""GET /docpl/large-routines — rotinas PL/SQL CAUTION/UNSAFE do escopo
|
|
175
|
+
(grandes demais p/ reescrever inteiras). Cada uma: name/type/safety/
|
|
176
|
+
est_tokens/risk_score/refactor/note + guidance única. scope = CODE de um
|
|
177
|
+
Scope Set (recorte do projeto); vazio = schema inteiro."""
|
|
178
|
+
params = {"schema": schema}
|
|
179
|
+
if scope:
|
|
180
|
+
params["scope"] = scope
|
|
181
|
+
if language:
|
|
182
|
+
params["lang"] = language
|
|
183
|
+
return self._request("GET", "docpl/large-routines", params=params)
|
|
184
|
+
|
|
185
|
+
def edit_safety(self, schema: str, object: str, language: str = None) -> dict:
|
|
186
|
+
"""GET /docpl/edit-safety — banda de edição-por-IA de UM objeto PL/SQL:
|
|
187
|
+
safety (SAFE/CAUTION/UNSAFE), est_tokens, risk_score, refactor, note,
|
|
188
|
+
guidance. exists:false se não achar."""
|
|
189
|
+
params = {"schema": schema, "object": object}
|
|
190
|
+
if language:
|
|
191
|
+
params["lang"] = language
|
|
192
|
+
return self._request("GET", "docpl/edit-safety", params=params)
|
|
193
|
+
|
|
172
194
|
def agent_columns(self, schema: str, table: str) -> dict:
|
|
173
195
|
"""GET /columns — compact list of every column of a table (name/type/
|
|
174
196
|
nullable/pk/fk/uk/domain/label/default)."""
|
|
@@ -87,11 +87,21 @@ def show_db_panel(title: str, db_name: str = None, db_config: dict = None,
|
|
|
87
87
|
if uuid != "—":
|
|
88
88
|
lines.append(f" BAU UUID: {uuid}")
|
|
89
89
|
else:
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
_lic = cfg.get("license_key")
|
|
91
|
+
if _lic and str(_lic).strip().upper() not in ("NONE", "-", "—"):
|
|
92
|
+
lines.append(f" License: [cyan]{_lic}[/cyan]")
|
|
92
93
|
lines.append(f" Server: {cfg.get('api_url', '—')}")
|
|
93
94
|
lines.append(f" Tenant: {cfg.get('tenant_code', '—')}")
|
|
94
|
-
|
|
95
|
+
# Idioma efetivo: [project].language do bau.toml vence o config do home.
|
|
96
|
+
_lang = cfg.get("language")
|
|
97
|
+
try:
|
|
98
|
+
from baucli.project import find_project as _fp
|
|
99
|
+
_pj = _fp()
|
|
100
|
+
if _pj and _pj.language:
|
|
101
|
+
_lang = _pj.language
|
|
102
|
+
except Exception:
|
|
103
|
+
pass
|
|
104
|
+
lines.append(f" Language: [cyan]{_lang or 'en_US (default)'}[/cyan]")
|
|
95
105
|
|
|
96
106
|
if extra_lines:
|
|
97
107
|
lines.append("")
|
|
@@ -1484,6 +1494,14 @@ def context(db_name: str, schema: str, output: str, language: str,
|
|
|
1484
1494
|
# the IDE reads; empty string when the schema has no golden entities.
|
|
1485
1495
|
golden_md = _render_golden_md(golden_data, locale)
|
|
1486
1496
|
|
|
1497
|
+
# ⚠ Rotinas grandes (AI Edit Safety F2) — avisa a IDE-AI mesmo sem MCP.
|
|
1498
|
+
_large_md = ""
|
|
1499
|
+
try:
|
|
1500
|
+
_lr = api.large_routines(schema, scope=scope_code, language=short_lang)
|
|
1501
|
+
_large_md = _large_routines_md(_lr, locale)
|
|
1502
|
+
except BauApiError:
|
|
1503
|
+
_large_md = ""
|
|
1504
|
+
|
|
1487
1505
|
if not tree:
|
|
1488
1506
|
base_path = output or (_proj.context_file if _proj else None) or cfg.get("context_output", "CLAUDE.md")
|
|
1489
1507
|
out_path = _localized_filename(base_path, locale, is_primary)
|
|
@@ -1492,6 +1510,8 @@ def context(db_name: str, schema: str, output: str, language: str,
|
|
|
1492
1510
|
single = content
|
|
1493
1511
|
if golden_md:
|
|
1494
1512
|
single = content.rstrip() + "\n\n---\n\n" + golden_md
|
|
1513
|
+
if _large_md:
|
|
1514
|
+
single = single.rstrip() + "\n\n" + _large_md
|
|
1495
1515
|
out_file.write_text(single, encoding="utf-8")
|
|
1496
1516
|
size = out_file.stat().st_size
|
|
1497
1517
|
written.append(f"{out_path} ({size:,} bytes, {locale})")
|
|
@@ -1537,7 +1557,8 @@ def context(db_name: str, schema: str, output: str, language: str,
|
|
|
1537
1557
|
"Do not edit by hand — re-run to refresh. -->\n\n"
|
|
1538
1558
|
)
|
|
1539
1559
|
schema_md = (generated_marker + parts["preamble"]
|
|
1540
|
-
+ "\n".join(index_lines) + "\n" + parts["footer"]
|
|
1560
|
+
+ "\n".join(index_lines) + "\n" + parts["footer"]
|
|
1561
|
+
+ (("\n\n" + _large_md) if _large_md else ""))
|
|
1541
1562
|
(tree_base / "_SCHEMA.md").write_text(schema_md, encoding="utf-8")
|
|
1542
1563
|
golden_files = 0
|
|
1543
1564
|
if golden_md:
|
|
@@ -1576,6 +1597,33 @@ def context(db_name: str, schema: str, output: str, language: str,
|
|
|
1576
1597
|
console.print(f" • {w}")
|
|
1577
1598
|
|
|
1578
1599
|
|
|
1600
|
+
def _large_routines_md(data: dict, locale: str = "en_US") -> str:
|
|
1601
|
+
"""Seção '⚠ Rotinas grandes' (AI Edit Safety F2) em markdown. '' se nenhuma."""
|
|
1602
|
+
if not isinstance(data, dict):
|
|
1603
|
+
return ""
|
|
1604
|
+
routines = data.get("routines") or []
|
|
1605
|
+
if not routines:
|
|
1606
|
+
return ""
|
|
1607
|
+
pt = (locale or "").lower().startswith("pt")
|
|
1608
|
+
head = ("## ⚠ Rotinas grandes — manuseie com cuidado" if pt
|
|
1609
|
+
else "## ⚠ Large routines — handle with care")
|
|
1610
|
+
intro = ("Estas rotinas PL/SQL são grandes demais para reescrever inteiras com IA. "
|
|
1611
|
+
"Edite **por subprograma** e valide antes de aplicar:" if pt
|
|
1612
|
+
else "These PL/SQL routines are too large to rewrite whole with AI. "
|
|
1613
|
+
"Edit **per subprogram** and verify before applying:")
|
|
1614
|
+
lines = ["", head, "", intro, ""]
|
|
1615
|
+
for r in routines:
|
|
1616
|
+
est = r.get("est_tokens") or 0
|
|
1617
|
+
tok = f"~{round(est / 1000)}k tokens" if est else "?"
|
|
1618
|
+
note = f": {r.get('note')}" if r.get("note") else ""
|
|
1619
|
+
lines.append(f"- `{r.get('owner')}.{r.get('name')}` "
|
|
1620
|
+
f"({r.get('type')}, {tok}, **{r.get('safety')}**){note}")
|
|
1621
|
+
g = data.get("guidance")
|
|
1622
|
+
if g:
|
|
1623
|
+
lines += ["", g]
|
|
1624
|
+
return "\n".join(lines)
|
|
1625
|
+
|
|
1626
|
+
|
|
1579
1627
|
# Markers that envelope the auto-generated block. Edits OUTSIDE the markers
|
|
1580
1628
|
# are preserved across regenerations; edits inside are overwritten. A
|
|
1581
1629
|
# user-authored CLAUDE.md without any markers is left untouched.
|
|
@@ -214,7 +214,23 @@ def build_server():
|
|
|
214
214
|
confidence, in_project. Use para não inventar tabela/objeto."""
|
|
215
215
|
try:
|
|
216
216
|
s = ctx().schema(schema)
|
|
217
|
-
|
|
217
|
+
obj = object_name.strip().upper()
|
|
218
|
+
res = ctx().api.verify_object(s, obj)
|
|
219
|
+
# Enriquecer objetos PL/SQL com a banda de edição-por-IA (F2).
|
|
220
|
+
try:
|
|
221
|
+
t = (res.get("type") or "").upper()
|
|
222
|
+
if any(k in t for k in ("PACKAGE", "PROCEDURE", "FUNCTION", "TRIGGER", "TYPE")):
|
|
223
|
+
es = ctx().api.edit_safety(s, obj)
|
|
224
|
+
if isinstance(es, dict) and es.get("safety"):
|
|
225
|
+
res["ai_edit_safety"] = es.get("safety")
|
|
226
|
+
res["est_tokens"] = es.get("est_tokens")
|
|
227
|
+
res["risk_score"] = es.get("risk_score")
|
|
228
|
+
res["refactor"] = es.get("refactor")
|
|
229
|
+
if es.get("guidance"):
|
|
230
|
+
res["edit_guidance"] = es.get("guidance")
|
|
231
|
+
except BauApiError:
|
|
232
|
+
pass
|
|
233
|
+
return res
|
|
218
234
|
except (BauApiError, ValueError) as e:
|
|
219
235
|
return _err(e)
|
|
220
236
|
|
|
@@ -458,6 +474,20 @@ def build_server():
|
|
|
458
474
|
except (BauApiError, ValueError) as e:
|
|
459
475
|
return _err(e)
|
|
460
476
|
|
|
477
|
+
@mcp.tool()
|
|
478
|
+
def bau_large_routines(schema: str = "", scope: str = "") -> dict:
|
|
479
|
+
"""Rotinas PL/SQL grandes demais p/ a IA editar INTEIRAS (CAUTION/UNSAFE).
|
|
480
|
+
CONSULTE ANTES de planejar editar um package/rotina grande: devolve
|
|
481
|
+
name/type/safety/est_tokens/risk_score/refactor/note + uma guidance única
|
|
482
|
+
(edite POR SUBPROGRAMA, valide com bau_verify_*). scope = CODE de um Scope
|
|
483
|
+
Set (recorte do projeto); vazio usa o scope do bau.toml ou o schema inteiro."""
|
|
484
|
+
try:
|
|
485
|
+
s = ctx().schema(schema)
|
|
486
|
+
sc = scope.strip() or (ctx().project.scope if ctx().project else None)
|
|
487
|
+
return ctx().api.large_routines(s, scope=sc, language=ctx().language(""))
|
|
488
|
+
except (BauApiError, ValueError) as e:
|
|
489
|
+
return _err(e)
|
|
490
|
+
|
|
461
491
|
# ---- análise -----------------------------------------------------
|
|
462
492
|
|
|
463
493
|
@mcp.tool()
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="baucli",
|
|
5
|
-
version="1.0.
|
|
5
|
+
version="1.0.6",
|
|
6
6
|
description="BAUCLI — AI-powered database documentation CLI for BAU",
|
|
7
7
|
long_description=open("README.md").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
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
|