baucli 1.0.74__tar.gz → 1.0.76__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 (49) hide show
  1. {baucli-1.0.74 → baucli-1.0.76}/PKG-INFO +1 -1
  2. {baucli-1.0.74 → baucli-1.0.76}/baucli/__init__.py +1 -1
  3. {baucli-1.0.74 → baucli-1.0.76}/baucli/cli.py +156 -19
  4. baucli-1.0.76/baucli/skills.py +1053 -0
  5. {baucli-1.0.74 → baucli-1.0.76}/baucli/sync.py +16 -8
  6. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/PKG-INFO +1 -1
  7. {baucli-1.0.74 → baucli-1.0.76}/setup.py +1 -1
  8. baucli-1.0.74/baucli/skills.py +0 -264
  9. {baucli-1.0.74 → baucli-1.0.76}/MANIFEST.in +0 -0
  10. {baucli-1.0.74 → baucli-1.0.76}/README.md +0 -0
  11. {baucli-1.0.74 → baucli-1.0.76}/baucli/apex_rebuild.py +0 -0
  12. {baucli-1.0.74 → baucli-1.0.76}/baucli/apexlang.py +0 -0
  13. {baucli-1.0.74 → baucli-1.0.76}/baucli/api.py +0 -0
  14. {baucli-1.0.74 → baucli-1.0.76}/baucli/canon.py +0 -0
  15. {baucli-1.0.74 → baucli-1.0.76}/baucli/config.py +0 -0
  16. {baucli-1.0.74 → baucli-1.0.76}/baucli/db/__init__.py +0 -0
  17. {baucli-1.0.74 → baucli-1.0.76}/baucli/db/mssql.py +0 -0
  18. {baucli-1.0.74 → baucli-1.0.76}/baucli/db/mysql.py +0 -0
  19. {baucli-1.0.74 → baucli-1.0.76}/baucli/db/oracle.py +0 -0
  20. {baucli-1.0.74 → baucli-1.0.76}/baucli/db/postgresql.py +0 -0
  21. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm.py +0 -0
  22. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/mssql/crm_data_mssql.sql +0 -0
  23. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/mssql/crm_demo_mssql.sql +0 -0
  24. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/mysql/crm_data_mysql.sql +0 -0
  25. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/mysql/crm_demo_mysql.sql +0 -0
  26. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/oracle/crm_demo_oracle.sql +0 -0
  27. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/postgresql/crm_data_postgresql.sql +0 -0
  28. {baucli-1.0.74 → baucli-1.0.76}/baucli/democrm_sql/postgresql/crm_demo_postgresql.sql +0 -0
  29. {baucli-1.0.74 → baucli-1.0.76}/baucli/diffenvs.py +0 -0
  30. {baucli-1.0.74 → baucli-1.0.76}/baucli/docmig.py +0 -0
  31. {baucli-1.0.74 → baucli-1.0.76}/baucli/git.py +0 -0
  32. {baucli-1.0.74 → baucli-1.0.76}/baucli/legacy/__init__.py +0 -0
  33. {baucli-1.0.74 → baucli-1.0.76}/baucli/legacy/delphi.py +0 -0
  34. {baucli-1.0.74 → baucli-1.0.76}/baucli/legacy/magic.py +0 -0
  35. {baucli-1.0.74 → baucli-1.0.76}/baucli/mcp_server.py +0 -0
  36. {baucli-1.0.74 → baucli-1.0.76}/baucli/project.py +0 -0
  37. {baucli-1.0.74 → baucli-1.0.76}/baucli/rag_embed.py +0 -0
  38. {baucli-1.0.74 → baucli-1.0.76}/baucli/sample_scan.py +0 -0
  39. {baucli-1.0.74 → baucli-1.0.76}/baucli/scope_scan.py +0 -0
  40. {baucli-1.0.74 → baucli-1.0.76}/baucli/screenshot.py +0 -0
  41. {baucli-1.0.74 → baucli-1.0.76}/baucli/seed_check.py +0 -0
  42. {baucli-1.0.74 → baucli-1.0.76}/baucli/stress.py +0 -0
  43. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/SOURCES.txt +0 -0
  44. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/dependency_links.txt +0 -0
  45. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/entry_points.txt +0 -0
  46. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/requires.txt +0 -0
  47. {baucli-1.0.74 → baucli-1.0.76}/baucli.egg-info/top_level.txt +0 -0
  48. {baucli-1.0.74 → baucli-1.0.76}/setup.cfg +0 -0
  49. {baucli-1.0.74 → baucli-1.0.76}/tests/test_canon_multiengine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: baucli
3
- Version: 1.0.74
3
+ Version: 1.0.76
4
4
  Summary: Extracts verified business-logic and schema context from Oracle, PostgreSQL, MySQL and SQL Server
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.74"
6
+ __version__ = "1.0.76"
7
7
  __product__ = "BAUCLI"
8
8
  __author__ = "BEG Support"
@@ -909,10 +909,12 @@ def _guard_db_tenant(cfg, db_name, acao="sincronizar"):
909
909
  @click.option("--days", type=int, default=None, help="Override: extract only objects modified in last N days")
910
910
  @click.option("--objects-only", is_flag=True, help="Sync only PL/SQL objects (skip tables)")
911
911
  @click.option("--tables-only", is_flag=True, help="Sync only tables (skip PL/SQL objects)")
912
- @click.option("--object", "object_name", default=None,
913
- help="Sync ONLY this PL/SQL object (case-insensitive exact match). Forces --objects-only and --full.")
914
- @click.option("--table", "table_name", default=None,
915
- help="Sync ONLY this table/view (case-insensitive exact match). Forces --tables-only and --full.")
912
+ @click.option("--object", "object_name", multiple=True,
913
+ help="Sync ONLY this PL/SQL object (case-insensitive exact match). "
914
+ "Repeatable, and combines with --table (union). Forces --full.")
915
+ @click.option("--table", "table_name", multiple=True,
916
+ help="Sync ONLY this table/view (case-insensitive exact match). "
917
+ "Repeatable, and combines with --object (union). Forces --full.")
916
918
  @click.option("--parallel/--no-parallel", default=None, help="Force parallel/sequential extraction (default: auto, server-defined threshold)")
917
919
  @click.option("--batch-size", type=int, default=None,
918
920
  help="Objetos por POST ao /sync/batch (default 50). Use menor "
@@ -958,6 +960,7 @@ def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
958
960
  baucli sync --tables-only Only tables (skip PL/SQL objects)
959
961
  baucli sync --object PKG_X Sync just one PL/SQL object (FULL)
960
962
  baucli sync --table MEDICOS Sync just one table/view (FULL)
963
+ baucli sync --table T1 --object P1 --object P2 Uniao (repetivel, FULL)
961
964
  baucli sync --parallel Force parallel extraction
962
965
  baucli sync --no-parallel Force sequential extraction
963
966
  baucli sync --full -O Re-seed comments on undocumented rows
@@ -973,13 +976,18 @@ def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
973
976
  que quer (útil p/ enviar apenas a rotina que você concluiu). Use -y/--yes
974
977
  para pular a revisão (CI/pipe já pulam automaticamente).
975
978
  """
979
+ # --object/--table sao repetiveis e COMBINAVEIS (uniao): com os dois, o
980
+ # sync_filter continua 'all' e cada lado extrai com o SEU name_filter --
981
+ # mesmo mecanismo do --scope (o extractor aceita colecao = IN list).
982
+ # click multiple=True entrega tuplas; vazio vira None (sem filtro).
983
+ object_name = list(object_name) or None
984
+ table_name = list(table_name) or None
976
985
  if object_name and table_name:
977
- console.print("[red]--object and --table are mutually exclusive.[/red]")
978
- raise SystemExit(1)
979
- if object_name:
986
+ full = True
987
+ elif object_name:
980
988
  objects_only = True
981
989
  full = True
982
- if table_name:
990
+ elif table_name:
983
991
  tables_only = True
984
992
  full = True
985
993
  cfg = load_config()
@@ -1087,10 +1095,16 @@ def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
1087
1095
  if dry_run:
1088
1096
  mode_label += " [bold yellow](DRY-RUN)[/bold yellow]"
1089
1097
  filter_label = {"all": "Objects + Tables", "objects": "Objects only", "tables": "Tables only"}[sync_filter]
1090
- if object_name:
1091
- filter_label = f"Object only: [yellow]{object_name.upper()}[/yellow]"
1098
+ def _names_label(names):
1099
+ up = [str(x).upper() for x in names]
1100
+ return ", ".join(up) if len(up) <= 4 else f"{len(up)} nomes"
1101
+ if object_name and table_name:
1102
+ filter_label = (f"Union: objects [yellow]{_names_label(object_name)}[/yellow]"
1103
+ f" + tables [yellow]{_names_label(table_name)}[/yellow]")
1104
+ elif object_name:
1105
+ filter_label = f"Object only: [yellow]{_names_label(object_name)}[/yellow]"
1092
1106
  elif table_name:
1093
- filter_label = f"Table only: [yellow]{table_name.upper()}[/yellow]"
1107
+ filter_label = f"Table only: [yellow]{_names_label(table_name)}[/yellow]"
1094
1108
  if parallel is True:
1095
1109
  par_label = "[green]ON[/green]"
1096
1110
  elif parallel is False:
@@ -7916,19 +7930,29 @@ def project_show():
7916
7930
  help="Reescreve tambem o SKILL.md (por padrao so o resolved/ e "
7917
7931
  "atualizado, para nao apagar adaptacoes do time).")
7918
7932
  def project_skills(schema, force):
7919
- """Gera o skill de Claude Code para geracao de PL/SQL.
7933
+ """Gera os skills de Claude Code do BAU para este projeto.
7920
7934
 
7921
- Escreve .claude/skills/bau-plsql-header/ com o METODO (marcadores, ancora
7922
- do engine, o que nao fazer) + resolved/ com o DADO buscado do BAU: qual
7923
- template de cabecalho vale para este schema e por que.
7924
-
7925
- O template NAO e copiado para dentro do skill -- ele e escopado e editavel
7926
- pela UI; a copia desatualizaria em silencio. Re-rode apos mudar template.
7935
+ \b
7936
+ Skills gerados (METODO estavel + resolved/ regenerado do catalogo):
7937
+ bau-plsql-header marcadores e template de cabecalho do schema
7938
+ bau-edit-safety editar PL/SQL existente: bandas SAFE/CAUTION/UNSAFE,
7939
+ edicao por subprograma, regras de edicao e deploy
7940
+ bau-sql escrever SQL: biblioteca de consultas verificadas
7941
+ primeiro, FKs documentadas, dominios, golden e LOVs
7942
+ bau-doc-cycle operar o ciclo sync -> IA -> aprovacao -> deploy:
7943
+ acao por status, sync dirigido, trava de deploy
7944
+ bau-apex-forms padrao de paginas APEX (grid/ordem/botoes/refresh) +
7945
+ LOVs compartilhadas com slug de sharedComponent
7946
+
7947
+ O dado NAO e copiado para dentro do SKILL.md -- e escopado e muda com o
7948
+ catalogo; a copia desatualizaria em silencio. Re-rode apos sync/mudancas.
7927
7949
  """
7928
7950
  from datetime import datetime
7929
7951
 
7930
7952
  from baucli.project import find_project
7931
- from baucli.skills import write_skill
7953
+ from baucli.skills import (write_apex_forms_skill, write_doc_cycle_skill,
7954
+ write_edit_safety_skill, write_skill,
7955
+ write_sql_skill)
7932
7956
 
7933
7957
  proj = find_project()
7934
7958
  if not proj:
@@ -7974,6 +7998,119 @@ def project_skills(schema, force):
7974
7998
  console.print(" [dim]SKILL.md preservado (use --force para "
7975
7999
  "reescrever)[/dim]")
7976
8000
 
8001
+ # bau-edit-safety: rotinas grandes do schema (best-effort -- uma falha
8002
+ # aqui nao derruba o skill de header ja gerado acima).
8003
+ try:
8004
+ lr = api.large_routines(target, scope=(proj.scope or None),
8005
+ language=proj.language)
8006
+ if not isinstance(lr, dict) or lr.get("error"):
8007
+ raise RuntimeError((lr or {}).get("error") or "payload invalido")
8008
+ res2 = write_edit_safety_skill(
8009
+ proj.root, lr, target,
8010
+ datetime.now().strftime("%Y-%m-%d %H:%M"), force=force)
8011
+ console.print(f"[green]Skill gerado em[/green] "
8012
+ f"{res2['dir'].relative_to(proj.root)}")
8013
+ console.print(f" Rotinas CAUTION/UNSAFE no schema: "
8014
+ f"[cyan]{lr.get('count', 0)}[/cyan]")
8015
+ for p in res2["resolved_written"]:
8016
+ console.print(f" [green]escrito[/green] {p.relative_to(proj.root)}")
8017
+ if res2["skill_written"]:
8018
+ console.print(" [green]escrito[/green] "
8019
+ f"{(res2['dir'] / 'SKILL.md').relative_to(proj.root)}")
8020
+ else:
8021
+ console.print(" [dim]SKILL.md preservado (use --force para "
8022
+ "reescrever)[/dim]")
8023
+ except Exception as exc:
8024
+ console.print(f"[yellow]bau-edit-safety pulado: {exc} -- o skill de "
8025
+ f"header acima foi gerado normalmente.[/yellow]")
8026
+
8027
+ # bau-sql: biblioteca semantica + golden + LOVs. Cada payload e
8028
+ # best-effort individual -- o skill sai util mesmo parcial (empty-state
8029
+ # nas secoes cujo fetch falhou).
8030
+ def _try(fn, *args, **kw):
8031
+ try:
8032
+ r = fn(*args, **kw)
8033
+ return r if isinstance(r, dict) and not r.get("error") else {}
8034
+ except Exception:
8035
+ return {}
8036
+
8037
+ try:
8038
+ q_pl = _try(api.semantic_queries, target)
8039
+ g_pl = _try(api.golden, target)
8040
+ l_pl = _try(api.lovs, target)
8041
+ res3 = write_sql_skill(
8042
+ proj.root, q_pl, g_pl, l_pl, target,
8043
+ datetime.now().strftime("%Y-%m-%d %H:%M"), force=force)
8044
+ n_q = len(q_pl.get("queries") or [])
8045
+ n_g = (len(g_pl.get("tables") or []) + len(g_pl.get("objects") or [])
8046
+ + len(g_pl.get("flows") or []))
8047
+ n_l = len(l_pl.get("lovs") or [])
8048
+ console.print(f"[green]Skill gerado em[/green] "
8049
+ f"{res3['dir'].relative_to(proj.root)}")
8050
+ console.print(f" Consultas: [cyan]{n_q}[/cyan] · golden: "
8051
+ f"[cyan]{n_g}[/cyan] · LOVs: [cyan]{n_l}[/cyan]")
8052
+ for p in res3["resolved_written"]:
8053
+ console.print(f" [green]escrito[/green] {p.relative_to(proj.root)}")
8054
+ if res3["skill_written"]:
8055
+ console.print(" [green]escrito[/green] "
8056
+ f"{(res3['dir'] / 'SKILL.md').relative_to(proj.root)}")
8057
+ else:
8058
+ console.print(" [dim]SKILL.md preservado (use --force para "
8059
+ "reescrever)[/dim]")
8060
+ except Exception as exc:
8061
+ console.print(f"[yellow]bau-sql pulado: {exc}[/yellow]")
8062
+
8063
+ # bau-doc-cycle: retrato do ciclo (sync status + fila de deploy).
8064
+ try:
8065
+ ss_pl = _try(api.sync_status, target)
8066
+ if "text" in ss_pl and "recommendation" not in ss_pl:
8067
+ import json as _json
8068
+ try:
8069
+ ss_pl = _json.loads(ss_pl["text"])
8070
+ except Exception:
8071
+ ss_pl = {}
8072
+ dp_pl = _try(api.deploys_pending, schema=target)
8073
+ res4 = write_doc_cycle_skill(
8074
+ proj.root, ss_pl, dp_pl, target,
8075
+ datetime.now().strftime("%Y-%m-%d %H:%M"), force=force)
8076
+ console.print(f"[green]Skill gerado em[/green] "
8077
+ f"{res4['dir'].relative_to(proj.root)}")
8078
+ console.print(f" Sync: [cyan]{ss_pl.get('recommendation', '--')}"
8079
+ f"[/cyan] · deploys pendentes: "
8080
+ f"[cyan]{dp_pl.get('total') or len(dp_pl.get('deploys') or [])}[/cyan]")
8081
+ for p in res4["resolved_written"]:
8082
+ console.print(f" [green]escrito[/green] {p.relative_to(proj.root)}")
8083
+ if res4["skill_written"]:
8084
+ console.print(" [green]escrito[/green] "
8085
+ f"{(res4['dir'] / 'SKILL.md').relative_to(proj.root)}")
8086
+ else:
8087
+ console.print(" [dim]SKILL.md preservado (use --force para "
8088
+ "reescrever)[/dim]")
8089
+ except Exception as exc:
8090
+ console.print(f"[yellow]bau-doc-cycle pulado: {exc}[/yellow]")
8091
+
8092
+ # bau-apex-forms: metodo migrado do skill manual (preservado se o time ja
8093
+ # o editou) + LOVs compartilhadas com slug p/ sharedComponent.
8094
+ try:
8095
+ lf_pl = _try(api.lovs, target)
8096
+ res5 = write_apex_forms_skill(
8097
+ proj.root, lf_pl, target,
8098
+ datetime.now().strftime("%Y-%m-%d %H:%M"), force=force)
8099
+ console.print(f"[green]Skill gerado em[/green] "
8100
+ f"{res5['dir'].relative_to(proj.root)}")
8101
+ console.print(f" LOVs compartilhadas: "
8102
+ f"[cyan]{len(lf_pl.get('lovs') or [])}[/cyan]")
8103
+ for p in res5["resolved_written"]:
8104
+ console.print(f" [green]escrito[/green] {p.relative_to(proj.root)}")
8105
+ if res5["skill_written"]:
8106
+ console.print(" [green]escrito[/green] "
8107
+ f"{(res5['dir'] / 'SKILL.md').relative_to(proj.root)}")
8108
+ else:
8109
+ console.print(" [dim]SKILL.md preservado (use --force para "
8110
+ "reescrever)[/dim]")
8111
+ except Exception as exc:
8112
+ console.print(f"[yellow]bau-apex-forms pulado: {exc}[/yellow]")
8113
+
7977
8114
 
7978
8115
  @project_grp.command("github-init")
7979
8116
  @click.option("--name", default=None,