pythia-plsql 0.4.0__tar.gz → 0.4.1__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.
- {pythia_plsql-0.4.0/scripts/pythia_plsql.egg-info → pythia_plsql-0.4.1}/PKG-INFO +1 -1
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/pyproject.toml +1 -1
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia.py +24 -8
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1/scripts/pythia_plsql.egg-info}/PKG-INFO +1 -1
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-apply/SKILL.md +15 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/tests/test_phase3.py +26 -29
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/LICENSE +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/README.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/compile-errors.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/dependencies.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/impact.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/invalid-objects.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/name-occupants.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/object-source.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/plscope-enabled.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/plscope-statements.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/plscope-usages.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/session-privileges.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/similar-candidates.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/queries/source.sql +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/SOURCES.txt +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/dependency_links.txt +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/entry_points.txt +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/requires.txt +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/top_level.txt +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/setup.cfg +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-explore/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-explore/reference/data-dictionary.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-impact/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-review/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-review/reference/antipatterns.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-setup/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-skill-author/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-write/SKILL.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-write/reference/patterns.md +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/tests/test_install.py +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/tests/test_phase1.py +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/tests/test_phase2.py +0 -0
- {pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/tests/test_phase5.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythia-plsql
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: PL/SQL development for AI agents on Oracle Database - expert data-dictionary queries, impact analysis, and a snapshot-verified write path with honest rollback.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/thaildhe172591/pythia
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pythia-plsql"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.1"
|
|
8
8
|
description = "PL/SQL development for AI agents on Oracle Database - expert data-dictionary queries, impact analysis, and a snapshot-verified write path with honest rollback."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -1337,6 +1337,11 @@ def run_apply(conn, schema, ns, file_text, origin=None):
|
|
|
1337
1337
|
print(f" {paint_diff_line(ln, en)}")
|
|
1338
1338
|
print(paint(f"\n Snapshot saved: {journal_root(ns.project_root) / entry}",
|
|
1339
1339
|
"dim", en))
|
|
1340
|
+
if not confirmed:
|
|
1341
|
+
print(paint(" Rollback file for the current database version — "
|
|
1342
|
+
"use it if this is\n run by hand instead: "
|
|
1343
|
+
f"{journal_root(ns.project_root) / entry / 'restore.sql'}",
|
|
1344
|
+
"dim", en))
|
|
1340
1345
|
if not confirmed:
|
|
1341
1346
|
print(f"\n To apply:\n "
|
|
1342
1347
|
+ paint(f"{invocation()} apply {ns.file} --confirm {token}",
|
|
@@ -1536,18 +1541,29 @@ def cmd_journal(conn, schema, ns):
|
|
|
1536
1541
|
if ns.action == "prune":
|
|
1537
1542
|
import shutil
|
|
1538
1543
|
removed = 0
|
|
1539
|
-
|
|
1540
|
-
|
|
1544
|
+
# A preview wrote nothing to the database, but its restore.sql holds
|
|
1545
|
+
# the version that was live at the time — the only rollback there is
|
|
1546
|
+
# for a change the developer then ran by hand. So drop a preview only
|
|
1547
|
+
# when its rollback is byte-identical to one a newer entry already
|
|
1548
|
+
# keeps: redundant captures go, unique ones never do.
|
|
1549
|
+
kept = {}
|
|
1550
|
+
for eid in list_journal_entries(root): # newest first
|
|
1551
|
+
e = read_journal_entry(root, eid)
|
|
1552
|
+
meta, obj = e["meta"], str(e["meta"].get("object", ""))
|
|
1541
1553
|
if meta.get("applied") or meta.get("snapshot"):
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1554
|
+
kept.setdefault(obj, set()).add(e["restore"])
|
|
1555
|
+
continue
|
|
1556
|
+
if e["restore"] in kept.get(obj, set()):
|
|
1557
|
+
shutil.rmtree(journal_root(root) / eid)
|
|
1558
|
+
removed += 1
|
|
1559
|
+
else:
|
|
1560
|
+
kept.setdefault(obj, set()).add(e["restore"])
|
|
1546
1561
|
if ns.json:
|
|
1547
1562
|
print(json.dumps({"pruned": removed}))
|
|
1548
1563
|
else:
|
|
1549
|
-
print(f"-- pruned {removed}
|
|
1550
|
-
"
|
|
1564
|
+
print(f"-- pruned {removed} redundant previews; applied entries, "
|
|
1565
|
+
"snapshots, and any preview holding a rollback nothing "
|
|
1566
|
+
"else has are all kept")
|
|
1551
1567
|
return
|
|
1552
1568
|
if not ns.id:
|
|
1553
1569
|
sys.exit(f"Usage: {invocation()} journal "
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythia-plsql
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: PL/SQL development for AI agents on Oracle Database - expert data-dictionary queries, impact analysis, and a snapshot-verified write path with honest rollback.
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/thaildhe172591/pythia
|
|
@@ -31,6 +31,21 @@ Three moves are FORBIDDEN for agents, and the CLI enforces the first two
|
|
|
31
31
|
your turn; the token is only used after the developer's approval
|
|
32
32
|
arrives as a NEW message.
|
|
33
33
|
|
|
34
|
+
## When the change will NOT go through apply
|
|
35
|
+
|
|
36
|
+
Sometimes the developer runs the file themselves — a DBA executes it, a
|
|
37
|
+
release process owns it, or policy denies the group. The preview still ran,
|
|
38
|
+
so a rollback file for the version currently live already exists. Hand it
|
|
39
|
+
over in the same message as the .sql file, by path:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
.pythia/journal/<entry>/restore.sql
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Never let a change leave your hands for manual execution without naming
|
|
46
|
+
that file. `pythia history <OBJECT>` lists every captured version if an
|
|
47
|
+
older one is wanted.
|
|
48
|
+
|
|
34
49
|
## The Workflow
|
|
35
50
|
|
|
36
51
|
**Before step 1:** if this conversation has not yet seen a standalone impact
|
|
@@ -540,25 +540,42 @@ def test_privilege_warning_speaks_proxy():
|
|
|
540
540
|
FakeConn(direct), "APP", "APP")
|
|
541
541
|
|
|
542
542
|
|
|
543
|
-
def
|
|
543
|
+
def test_prune_drops_only_redundant_previews():
|
|
544
|
+
"""A preview wrote nothing, but its restore.sql is the live version at
|
|
545
|
+
that moment — the only rollback for a change run by hand. Prune may drop
|
|
546
|
+
it only when a newer entry already keeps the identical rollback."""
|
|
544
547
|
import argparse
|
|
548
|
+
import contextlib
|
|
545
549
|
import datetime
|
|
550
|
+
import io
|
|
546
551
|
with tempfile.TemporaryDirectory() as td:
|
|
547
|
-
base = datetime.datetime(2026, 8,
|
|
548
|
-
|
|
552
|
+
base = datetime.datetime(2026, 8, 27, 9, 0, 0)
|
|
553
|
+
# two previews of the same object, same live version -> one is spare
|
|
554
|
+
pythia.write_journal_entry(td, "PROCEDURE", "P_A", "old", "new1",
|
|
549
555
|
{"applied": False}, now=base)
|
|
550
|
-
|
|
551
|
-
td, "PROCEDURE", "
|
|
556
|
+
keep_dup = pythia.write_journal_entry(
|
|
557
|
+
td, "PROCEDURE", "P_A", "old", "new2", {"applied": False},
|
|
552
558
|
now=base.replace(minute=1))
|
|
559
|
+
# a preview of another object, unique rollback -> must survive
|
|
560
|
+
lone = pythia.write_journal_entry(
|
|
561
|
+
td, "PROCEDURE", "P_B", "only_copy", "x", {"applied": False},
|
|
562
|
+
now=base.replace(minute=2))
|
|
563
|
+
applied = pythia.write_journal_entry(
|
|
564
|
+
td, "PROCEDURE", "P_C", "a", "b", {"applied": True},
|
|
565
|
+
now=base.replace(minute=3))
|
|
566
|
+
snap = pythia.write_journal_entry(
|
|
567
|
+
td, "PROCEDURE", "P_D", "a", "a",
|
|
568
|
+
{"snapshot": True, "applied": False}, now=base.replace(minute=4))
|
|
553
569
|
ns = argparse.Namespace(action="prune", project_root=td, json=False,
|
|
554
570
|
id=None)
|
|
555
|
-
import contextlib
|
|
556
|
-
import io
|
|
557
571
|
buf = io.StringIO()
|
|
558
572
|
with contextlib.redirect_stdout(buf):
|
|
559
573
|
pythia.cmd_journal(None, None, ns)
|
|
560
|
-
|
|
561
|
-
assert
|
|
574
|
+
left = pythia.list_journal_entries(td)
|
|
575
|
+
assert "pruned 1" in buf.getvalue(), buf.getvalue()
|
|
576
|
+
assert applied in left and snap in left # never touched
|
|
577
|
+
assert lone in left # unique rollback survives
|
|
578
|
+
assert keep_dup in left # newest of the pair kept
|
|
562
579
|
|
|
563
580
|
|
|
564
581
|
def test_agent_user_alter_form_and_warning_prediction():
|
|
@@ -742,26 +759,6 @@ def test_auto_snapshot_reports_drift_and_keeps_the_old_rollback():
|
|
|
742
759
|
assert len(pythia.list_journal_entries(td)) == 2
|
|
743
760
|
|
|
744
761
|
|
|
745
|
-
def test_prune_never_eats_a_snapshot():
|
|
746
|
-
import argparse
|
|
747
|
-
import contextlib
|
|
748
|
-
import io
|
|
749
|
-
import datetime
|
|
750
|
-
with tempfile.TemporaryDirectory() as td:
|
|
751
|
-
base = datetime.datetime(2026, 8, 27, 9, 0, 0)
|
|
752
|
-
pythia.write_journal_entry(td, "PROCEDURE", "P_A", "a", "b",
|
|
753
|
-
{"applied": False}, now=base)
|
|
754
|
-
snap = pythia.write_journal_entry(
|
|
755
|
-
td, "PROCEDURE", "P_B", "a", "a", {"snapshot": True,
|
|
756
|
-
"applied": False},
|
|
757
|
-
now=base.replace(minute=1))
|
|
758
|
-
ns = argparse.Namespace(action="prune", project_root=td, json=False,
|
|
759
|
-
id=None)
|
|
760
|
-
with contextlib.redirect_stdout(io.StringIO()):
|
|
761
|
-
pythia.cmd_journal(None, None, ns)
|
|
762
|
-
assert pythia.list_journal_entries(td) == [snap]
|
|
763
|
-
|
|
764
|
-
|
|
765
762
|
def main():
|
|
766
763
|
failed = 0
|
|
767
764
|
for name, fn in sorted(globals().items()):
|
|
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
|
{pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/scripts/pythia_plsql.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythia_plsql-0.4.0 → pythia_plsql-0.4.1}/skills/pythia-explore/reference/data-dictionary.md
RENAMED
|
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
|