pythia-plsql 0.14.0__tar.gz → 0.14.2__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.14.0/scripts/pythia_plsql.egg-info → pythia_plsql-0.14.2}/PKG-INFO +1 -1
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/pyproject.toml +1 -1
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia.py +47 -55
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2/scripts/pythia_plsql.egg-info}/PKG-INFO +1 -1
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-apply/SKILL.md +1 -1
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_mcp.py +20 -33
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/LICENSE +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/README.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/compile-errors.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/current-schema.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/dependencies.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/impact.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/invalid-objects.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/name-occupants.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/object-names.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/object-source.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/plscope-enabled.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/plscope-statements.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/plscope-usages.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/session-privileges.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/similar-candidates.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/queries/source.sql +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia_plsql.egg-info/SOURCES.txt +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia_plsql.egg-info/dependency_links.txt +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia_plsql.egg-info/entry_points.txt +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia_plsql.egg-info/requires.txt +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/scripts/pythia_plsql.egg-info/top_level.txt +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/setup.cfg +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-comment/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-conventions/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-explore/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-explore/reference/data-dictionary.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-impact/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-review/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-review/reference/antipatterns.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-setup/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-skill-author/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-spec/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-write/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/pythia-write/reference/patterns.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/skills/using-pythia/SKILL.md +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_install.py +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_phase1.py +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_phase2.py +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_phase3.py +0 -0
- {pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/tests/test_phase5.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythia-plsql
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.2
|
|
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.14.
|
|
7
|
+
version = "0.14.2"
|
|
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" }
|
|
@@ -2286,8 +2286,11 @@ def run_apply(conn, schema, ns, file_text, origin=None):
|
|
|
2286
2286
|
"dim", en))
|
|
2287
2287
|
if not confirmed:
|
|
2288
2288
|
print("\n To apply — the developer approves, then the agent confirms:")
|
|
2289
|
-
print(" in chat:
|
|
2289
|
+
print(" in chat (Claude): the agent asks (AskUserQuestion) with the text of "
|
|
2290
2290
|
+ paint(f"{invocation()} approve --card {token}", "cyan", en))
|
|
2291
|
+
print(" on Codex: the agent calls the "
|
|
2292
|
+
+ paint("pythia_approve", "cyan", en)
|
|
2293
|
+
+ f" MCP tool with token {token}")
|
|
2291
2294
|
print(" or in a terminal: "
|
|
2292
2295
|
+ paint(f"{invocation()} approve {token}", "cyan", en))
|
|
2293
2296
|
print(" then the agent: "
|
|
@@ -2826,15 +2829,20 @@ def agents_md_block():
|
|
|
2826
2829
|
"""The pythia section for AGENTS.md — Codex's always-loaded instruction
|
|
2827
2830
|
file. Body is BRIEF_GUIDE verbatim (the same constant `guide --brief`
|
|
2828
2831
|
prints and the Claude SessionStart hook runs, so the two cannot drift),
|
|
2829
|
-
plus the
|
|
2832
|
+
plus the lines Codex needs that Claude gets from its hook: where the
|
|
2830
2833
|
approval door is, since Codex has no chat-mint. Marker-wrapped so a re-run
|
|
2831
2834
|
replaces it in place and the developer's own text is untouched."""
|
|
2832
2835
|
return (f"{AGENTS_BEGIN}\n"
|
|
2833
2836
|
"## pythia — developing PL/SQL on Oracle\n\n"
|
|
2834
2837
|
f"{BRIEF_GUIDE.rstrip()}\n\n"
|
|
2835
|
-
"
|
|
2836
|
-
"
|
|
2837
|
-
"
|
|
2838
|
+
"APPROVAL ON CODEX: your approval door is the `pythia_approve` MCP "
|
|
2839
|
+
"tool, not AskUserQuestion (Codex has none). After `pythia apply "
|
|
2840
|
+
"<file>` prints a token, call the `pythia_approve` tool with that "
|
|
2841
|
+
"token — the developer answers a select prompt, and on Approve the "
|
|
2842
|
+
"grant is minted. Then YOU run `pythia apply <file> --confirm "
|
|
2843
|
+
"<token>` yourself; do not stop at the preview or hand the "
|
|
2844
|
+
"developer a command to type. If the tool is not available "
|
|
2845
|
+
"(older Codex), relay `pythia approve <token>` for their terminal.\n"
|
|
2838
2846
|
f"{AGENTS_END}")
|
|
2839
2847
|
|
|
2840
2848
|
|
|
@@ -3484,9 +3492,11 @@ def mcp_approve_decision(root, token, elicit):
|
|
|
3484
3492
|
prune_expired_grants(root)
|
|
3485
3493
|
mint_grant(root, token, meta.get("connection") or "",
|
|
3486
3494
|
revalidate=fingerprint_text(meta.get("row_set")), approver="mcp")
|
|
3487
|
-
return _mcp_text(f"Approved — grant minted for {token}
|
|
3488
|
-
f"
|
|
3489
|
-
|
|
3495
|
+
return _mcp_text(f"Approved — grant minted for {token} (single use, "
|
|
3496
|
+
f"{GRANT_TTL_MINUTES} min). Now run apply --confirm on the "
|
|
3497
|
+
"file you previewed YOURSELF — do not hand the developer a "
|
|
3498
|
+
f"command to type: {invocation()} apply <file> --confirm "
|
|
3499
|
+
f"{token}")
|
|
3490
3500
|
|
|
3491
3501
|
|
|
3492
3502
|
def mcp_serve(reader, writer, root):
|
|
@@ -3558,33 +3568,30 @@ def cmd_mcp(conn, schema, ns):
|
|
|
3558
3568
|
# table header inside a string/comment is not worth a parser here.
|
|
3559
3569
|
CODEX_MCP_BEGIN = "# pythia:begin (managed by `pythia install`)"
|
|
3560
3570
|
CODEX_MCP_END = "# pythia:end"
|
|
3571
|
+
# Only the server roster — nothing else. An earlier attempt also wrote an
|
|
3572
|
+
# [approval_policy.granular] table, but that table requires several fields
|
|
3573
|
+
# (sandbox_approval, rules, ...) and an incomplete one broke Codex v0.154 at
|
|
3574
|
+
# config-load time. Elicitations surface under the default interactive
|
|
3575
|
+
# approval policy without any of that, and the developer's approval policy is
|
|
3576
|
+
# theirs, not ours to set.
|
|
3561
3577
|
CODEX_MCP_BLOCK = (f"{CODEX_MCP_BEGIN}\n"
|
|
3562
3578
|
"[mcp_servers.pythia]\n"
|
|
3563
3579
|
'command = "python"\n'
|
|
3564
|
-
'args = ["-m", "pythia", "mcp"]\n
|
|
3565
|
-
"[approval_policy.granular]\n"
|
|
3566
|
-
"mcp_elicitations = true\n"
|
|
3580
|
+
'args = ["-m", "pythia", "mcp"]\n'
|
|
3567
3581
|
f"{CODEX_MCP_END}")
|
|
3568
|
-
# requirements.toml is a separate admin-enforced file; forbidding these two is
|
|
3569
|
-
# what closes the danger-full-access elicitation auto-approve hole.
|
|
3570
|
-
CODEX_REQUIREMENTS = (f"{CODEX_MCP_BEGIN}\n"
|
|
3571
|
-
"# pythia needs elicitations to reach a human, so the two\n"
|
|
3572
|
-
"# modes that would auto-answer or skip them are disallowed.\n"
|
|
3573
|
-
'allowed_approval_policies = ["untrusted", "on-request", "on-failure"]\n'
|
|
3574
|
-
'allowed_sandbox_modes = ["read-only", "workspace-write"]\n'
|
|
3575
|
-
f"{CODEX_MCP_END}")
|
|
3576
3582
|
|
|
3577
3583
|
|
|
3578
3584
|
def merge_codex_mcp_config(path):
|
|
3579
|
-
"""Append the MCP
|
|
3580
|
-
(path, action): 'created' | 'appended' | 'present' | 'conflict'.
|
|
3581
|
-
(writes nothing) if
|
|
3585
|
+
"""Append the MCP server registration to <project>/.codex/config.toml.
|
|
3586
|
+
Returns (path, action): 'created' | 'appended' | 'present' | 'conflict'.
|
|
3587
|
+
Refuses (writes nothing) if [mcp_servers.pythia] already exists without our
|
|
3588
|
+
marker — the stdlib cannot safely merge TOML, so a collision is reported,
|
|
3589
|
+
never overwritten."""
|
|
3582
3590
|
path = pathlib.Path(path)
|
|
3583
3591
|
old = path.read_text(encoding="utf-8") if path.is_file() else None
|
|
3584
3592
|
if old is not None and CODEX_MCP_BEGIN in old:
|
|
3585
3593
|
return path, "present"
|
|
3586
|
-
if old is not None and
|
|
3587
|
-
or "[approval_policy.granular]" in old):
|
|
3594
|
+
if old is not None and "[mcp_servers.pythia]" in old:
|
|
3588
3595
|
return path, "conflict"
|
|
3589
3596
|
if old is None:
|
|
3590
3597
|
new, action = CODEX_MCP_BLOCK + "\n", "created"
|
|
@@ -3596,21 +3603,6 @@ def merge_codex_mcp_config(path):
|
|
|
3596
3603
|
return path, action
|
|
3597
3604
|
|
|
3598
3605
|
|
|
3599
|
-
def merge_codex_requirements(path):
|
|
3600
|
-
"""Write <project>/.codex/requirements.toml forbidding danger-full-access
|
|
3601
|
-
and never-approval. Returns (path, action): 'created' | 'present' |
|
|
3602
|
-
'conflict'. An existing file without our marker is left untouched."""
|
|
3603
|
-
path = pathlib.Path(path)
|
|
3604
|
-
old = path.read_text(encoding="utf-8") if path.is_file() else None
|
|
3605
|
-
if old is not None and CODEX_MCP_BEGIN in old:
|
|
3606
|
-
return path, "present"
|
|
3607
|
-
if old is not None:
|
|
3608
|
-
return path, "conflict"
|
|
3609
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
3610
|
-
path.write_text(CODEX_REQUIREMENTS + "\n", encoding="utf-8")
|
|
3611
|
-
return path, "created"
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
3606
|
def install_claude_hooks(base_dir, events=None):
|
|
3615
3607
|
"""Merge the two hooks and the deny rule into <base>/.claude/settings.json
|
|
3616
3608
|
— the project's, or the home directory's for -g. The file is Claude
|
|
@@ -3693,28 +3685,28 @@ def report_codex_hooks(project_root, ns):
|
|
|
3693
3685
|
|
|
3694
3686
|
|
|
3695
3687
|
def report_codex_mcp(project_root, ns):
|
|
3696
|
-
"""Project scope: register the write-free MCP approver in Codex's config
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3688
|
+
"""Project scope: register the write-free MCP approver in Codex's config.
|
|
3689
|
+
--no-hooks skips it, as with the other Codex wiring. Needs Codex >= v0.120
|
|
3690
|
+
for elicitation; older Codex ignores the server and the console approve
|
|
3691
|
+
path still works."""
|
|
3700
3692
|
if getattr(ns, "no_hooks", False):
|
|
3701
3693
|
return
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
req_path, req = merge_codex_requirements(base / "requirements.toml")
|
|
3694
|
+
cfg_path, cfg = merge_codex_mcp_config(pathlib.Path(project_root)
|
|
3695
|
+
/ ".codex" / "config.toml")
|
|
3705
3696
|
if cfg in ("created", "appended"):
|
|
3706
3697
|
print(f"\nRegistered the pythia MCP approver in {cfg_path} "
|
|
3707
3698
|
"(Codex >= v0.120; run /mcp to trust it).")
|
|
3708
3699
|
elif cfg == "conflict":
|
|
3709
|
-
print(f"\n! {cfg_path} already defines [mcp_servers.pythia]
|
|
3710
|
-
"
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3700
|
+
print(f"\n! {cfg_path} already defines [mcp_servers.pythia]; add this "
|
|
3701
|
+
"yourself:\n" + CODEX_MCP_BLOCK)
|
|
3702
|
+
else:
|
|
3703
|
+
print(f"\npythia MCP approver already registered in {cfg_path}.")
|
|
3704
|
+
# The one bypass of the elicitation is Codex auto-approving it under the
|
|
3705
|
+
# danger-full-access sandbox. pythia does not write requirements.toml to
|
|
3706
|
+
# forbid that — it is enterprise-managed config, and the schema is
|
|
3707
|
+
# version-fragile — so it warns instead.
|
|
3708
|
+
print("Do not run Codex under `danger-full-access` with pythia: that "
|
|
3709
|
+
"sandbox auto-approves elicitations, bypassing your Approve.")
|
|
3718
3710
|
|
|
3719
3711
|
|
|
3720
3712
|
def cmd_install(conn, schema, ns):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythia-plsql
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.2
|
|
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
|
|
@@ -60,7 +60,7 @@ confirms a number you already knew.
|
|
|
60
60
|
in the option descriptions; the hook does not read those. Header `pythia`;
|
|
61
61
|
options exactly `Approve` / `Reject`, no "(Recommended)"; up to four tokens
|
|
62
62
|
per call. Anything but `Approve` is not approval: stop and ask what should
|
|
63
|
-
change. File changed → step 1.
|
|
63
|
+
change. File changed → step 1. On Codex: call the `pythia_approve` MCP tool with the token — its select prompt is your door — then run `--confirm` yourself. No tool/hook? Relay `pythia approve <token>` for the terminal.
|
|
64
64
|
4. **Apply** by running the exact `then the agent:` line pythia printed. Two
|
|
65
65
|
refusals are normal here, and neither is a malfunction:
|
|
66
66
|
- *"no developer approval is on file"* — the answer was not `Approve`, or
|
|
@@ -79,7 +79,11 @@ def test_mint_only_on_accept_with_approve():
|
|
|
79
79
|
|
|
80
80
|
res = pythia.mcp_approve_decision(td, token, elicit)
|
|
81
81
|
assert res["isError"] is False
|
|
82
|
-
|
|
82
|
+
text = res["content"][0]["text"]
|
|
83
|
+
assert token in text
|
|
84
|
+
# the message tells the AGENT to continue itself, not the developer to
|
|
85
|
+
# type a command — 0.14.1 fix
|
|
86
|
+
assert "yourself" in text.lower()
|
|
83
87
|
assert "PKG_ORDER" in seen["message"] # the card was shown
|
|
84
88
|
assert seen["schema"]["properties"]["decision"]["enum"] == ["Approve", "Reject"]
|
|
85
89
|
g = pythia.read_grant(td, token)
|
|
@@ -200,7 +204,10 @@ def test_merge_codex_mcp_config_appends_once_when_clean():
|
|
|
200
204
|
body = path.read_text(encoding="utf-8")
|
|
201
205
|
assert "[mcp_servers.pythia]" in body
|
|
202
206
|
assert 'args = ["-m", "pythia", "mcp"]' in body
|
|
203
|
-
|
|
207
|
+
# 0.14.1: we do NOT touch approval_policy — an incomplete granular table
|
|
208
|
+
# broke Codex v0.154 config loading, and elicitations work under the
|
|
209
|
+
# default interactive policy anyway.
|
|
210
|
+
assert "approval_policy" not in body
|
|
204
211
|
assert pythia.merge_codex_mcp_config(path)[1] == "present" # idempotent
|
|
205
212
|
|
|
206
213
|
|
|
@@ -216,43 +223,20 @@ def test_merge_codex_mcp_config_preserves_other_content():
|
|
|
216
223
|
assert "[mcp_servers.pythia]" in body
|
|
217
224
|
|
|
218
225
|
|
|
219
|
-
def
|
|
226
|
+
def test_merge_codex_mcp_config_refuses_on_server_collision():
|
|
220
227
|
with tempfile.TemporaryDirectory() as td:
|
|
221
228
|
path = pathlib.Path(td) / ".codex" / "config.toml"
|
|
222
229
|
path.parent.mkdir(parents=True)
|
|
223
|
-
original =
|
|
230
|
+
original = '[mcp_servers.pythia]\ncommand = "other"\n'
|
|
224
231
|
path.write_text(original, encoding="utf-8")
|
|
225
232
|
p, action = pythia.merge_codex_mcp_config(path)
|
|
226
233
|
assert action == "conflict"
|
|
227
234
|
assert path.read_text(encoding="utf-8") == original # untouched
|
|
228
235
|
|
|
229
236
|
|
|
230
|
-
def test_merge_codex_requirements_creates_and_is_idempotent():
|
|
231
|
-
with tempfile.TemporaryDirectory() as td:
|
|
232
|
-
path = pathlib.Path(td) / ".codex" / "requirements.toml"
|
|
233
|
-
p, action = pythia.merge_codex_requirements(path)
|
|
234
|
-
assert action == "created"
|
|
235
|
-
body = path.read_text(encoding="utf-8")
|
|
236
|
-
assert "allowed_approval_policies" in body and "allowed_sandbox_modes" in body
|
|
237
|
-
assert "danger-full-access" not in body # the forbidden mode is absent
|
|
238
|
-
assert '"never"' not in body # the forbidden policy is absent
|
|
239
|
-
assert pythia.merge_codex_requirements(path)[1] == "present"
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def test_merge_codex_requirements_refuses_an_existing_file():
|
|
243
|
-
with tempfile.TemporaryDirectory() as td:
|
|
244
|
-
path = pathlib.Path(td) / ".codex" / "requirements.toml"
|
|
245
|
-
path.parent.mkdir(parents=True)
|
|
246
|
-
original = "# org policy\nallowed_sandbox_modes = []\n"
|
|
247
|
-
path.write_text(original, encoding="utf-8")
|
|
248
|
-
p, action = pythia.merge_codex_requirements(path)
|
|
249
|
-
assert action == "conflict"
|
|
250
|
-
assert path.read_text(encoding="utf-8") == original # untouched
|
|
251
|
-
|
|
252
|
-
|
|
253
237
|
# --- Task 5: wire the MCP install into cmd_install (project scope) ----------
|
|
254
238
|
|
|
255
|
-
def
|
|
239
|
+
def test_cmd_install_registers_the_mcp_server_and_warns_off_danger():
|
|
256
240
|
import argparse
|
|
257
241
|
import contextlib
|
|
258
242
|
old = os.environ.get("PATH")
|
|
@@ -261,13 +245,16 @@ def test_cmd_install_registers_the_mcp_server_and_pins_the_sandbox():
|
|
|
261
245
|
with tempfile.TemporaryDirectory() as td:
|
|
262
246
|
ns = argparse.Namespace(project_root=td, glob=False, source=None,
|
|
263
247
|
color=False, json=False, no_hooks=False)
|
|
264
|
-
|
|
248
|
+
buf = io.StringIO()
|
|
249
|
+
with contextlib.redirect_stdout(buf):
|
|
265
250
|
pythia.cmd_install(None, None, ns)
|
|
266
251
|
cfg = pathlib.Path(td) / ".codex" / "config.toml"
|
|
267
|
-
|
|
268
|
-
assert "[mcp_servers.pythia]" in
|
|
269
|
-
assert "
|
|
270
|
-
|
|
252
|
+
body = cfg.read_text(encoding="utf-8")
|
|
253
|
+
assert "[mcp_servers.pythia]" in body
|
|
254
|
+
assert "approval_policy" not in body # 0.14.1: never touched
|
|
255
|
+
# requirements.toml is no longer written; the pin became a warning
|
|
256
|
+
assert not (pathlib.Path(td) / ".codex" / "requirements.toml").exists()
|
|
257
|
+
assert "danger-full-access" in buf.getvalue() # the warning
|
|
271
258
|
finally:
|
|
272
259
|
if old is not None:
|
|
273
260
|
os.environ["PATH"] = old
|
|
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
|
{pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/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
|
|
File without changes
|
|
File without changes
|
{pythia_plsql-0.14.0 → pythia_plsql-0.14.2}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|