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.
Files changed (34) hide show
  1. {baucli-1.0.4 → baucli-1.0.6}/PKG-INFO +1 -1
  2. {baucli-1.0.4 → baucli-1.0.6}/baucli/__init__.py +1 -1
  3. {baucli-1.0.4 → baucli-1.0.6}/baucli/api.py +22 -0
  4. {baucli-1.0.4 → baucli-1.0.6}/baucli/cli.py +52 -4
  5. {baucli-1.0.4 → baucli-1.0.6}/baucli/mcp_server.py +31 -1
  6. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/PKG-INFO +1 -1
  7. {baucli-1.0.4 → baucli-1.0.6}/setup.py +1 -1
  8. {baucli-1.0.4 → baucli-1.0.6}/README.md +0 -0
  9. {baucli-1.0.4 → baucli-1.0.6}/baucli/apex_rebuild.py +0 -0
  10. {baucli-1.0.4 → baucli-1.0.6}/baucli/apexlang.py +0 -0
  11. {baucli-1.0.4 → baucli-1.0.6}/baucli/config.py +0 -0
  12. {baucli-1.0.4 → baucli-1.0.6}/baucli/db/__init__.py +0 -0
  13. {baucli-1.0.4 → baucli-1.0.6}/baucli/db/mssql.py +0 -0
  14. {baucli-1.0.4 → baucli-1.0.6}/baucli/db/mysql.py +0 -0
  15. {baucli-1.0.4 → baucli-1.0.6}/baucli/db/oracle.py +0 -0
  16. {baucli-1.0.4 → baucli-1.0.6}/baucli/db/postgresql.py +0 -0
  17. {baucli-1.0.4 → baucli-1.0.6}/baucli/docmig.py +0 -0
  18. {baucli-1.0.4 → baucli-1.0.6}/baucli/git.py +0 -0
  19. {baucli-1.0.4 → baucli-1.0.6}/baucli/legacy/__init__.py +0 -0
  20. {baucli-1.0.4 → baucli-1.0.6}/baucli/legacy/delphi.py +0 -0
  21. {baucli-1.0.4 → baucli-1.0.6}/baucli/project.py +0 -0
  22. {baucli-1.0.4 → baucli-1.0.6}/baucli/rag_embed.py +0 -0
  23. {baucli-1.0.4 → baucli-1.0.6}/baucli/sample_scan.py +0 -0
  24. {baucli-1.0.4 → baucli-1.0.6}/baucli/scope_scan.py +0 -0
  25. {baucli-1.0.4 → baucli-1.0.6}/baucli/screenshot.py +0 -0
  26. {baucli-1.0.4 → baucli-1.0.6}/baucli/seed_check.py +0 -0
  27. {baucli-1.0.4 → baucli-1.0.6}/baucli/stress.py +0 -0
  28. {baucli-1.0.4 → baucli-1.0.6}/baucli/sync.py +0 -0
  29. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/SOURCES.txt +0 -0
  30. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/dependency_links.txt +0 -0
  31. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/entry_points.txt +0 -0
  32. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/requires.txt +0 -0
  33. {baucli-1.0.4 → baucli-1.0.6}/baucli.egg-info/top_level.txt +0 -0
  34. {baucli-1.0.4 → baucli-1.0.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: baucli
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: BAUCLI — AI-powered database documentation CLI for BAU
5
5
  Home-page: https://www.begcloud.com
6
6
  Author: BEG Support
@@ -3,6 +3,6 @@
3
3
  import warnings
4
4
  warnings.filterwarnings("ignore", message="urllib3 v2 only supports OpenSSL")
5
5
 
6
- __version__ = "1.0.4"
6
+ __version__ = "1.0.6"
7
7
  __product__ = "BAUCLI"
8
8
  __author__ = "BEG Support"
@@ -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
- if cfg.get("license_key"):
91
- lines.append(f" License: [cyan]{cfg['license_key']}[/cyan]")
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
- lines.append(f" Language: [cyan]{cfg.get('language') or 'en_US (default)'}[/cyan]")
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
- return ctx().api.verify_object(s, object_name.strip().upper())
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()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: baucli
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: BAUCLI — AI-powered database documentation CLI for BAU
5
5
  Home-page: https://www.begcloud.com
6
6
  Author: BEG Support
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="baucli",
5
- version="1.0.4",
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