devin-qa-pack 0.2.0__tar.gz → 0.2.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.
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/PKG-INFO +2 -2
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/pyproject.toml +2 -2
- devin_qa_pack-0.2.1/src/devin_qa_pack/__init__.py +1 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/cli.py +7 -1
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/mcp_server.py +4 -1
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/session_end.py +4 -1
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/PKG-INFO +2 -2
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_cli.py +13 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_mcp.py +10 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_session_end.py +16 -0
- devin_qa_pack-0.2.0/src/devin_qa_pack/__init__.py +0 -1
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/README.md +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/setup.cfg +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/__init__.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/aider.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/base.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/claude_code.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/devin.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/adapters/mcp.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/claims.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/evidence/__init__.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/evidence/codex_cli.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/evidence/copilot_cli.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/evidence/devin_cli.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/evidence/vscode_chat.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/html_report.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/intent.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/paths.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/report.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack/verify.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/SOURCES.txt +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/dependency_links.txt +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/entry_points.txt +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/requires.txt +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/src/devin_qa_pack.egg-info/top_level.txt +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_adapters.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_claims.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_evidence.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_evidence_corpus.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_html_report.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_intent.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_offline_core.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_paths.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_precommit_hook.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_release_workflow.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_report.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_skill.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_smoke.py +0 -0
- {devin_qa_pack-0.2.0 → devin_qa_pack-0.2.1}/tests/test_verify.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devin-qa-pack
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: QA audit for
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: QA audit for agent sessions: verifies deliverable claims (tests, commits, files, pushes) against recorded tool-call ground truth across Devin CLI, Copilot CLI, Codex CLI and VS Code chat stores.
|
|
5
5
|
Author: Icaro0310
|
|
6
6
|
License: MIT
|
|
7
7
|
Requires-Python: >=3.10
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "devin-qa-pack"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "QA audit for
|
|
7
|
+
version = "0.2.1"
|
|
8
|
+
description = "QA audit for agent sessions: verifies deliverable claims (tests, commits, files, pushes) against recorded tool-call ground truth across Devin CLI, Copilot CLI, Codex CLI and VS Code chat stores."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.1"
|
|
@@ -26,6 +26,7 @@ from __future__ import annotations
|
|
|
26
26
|
|
|
27
27
|
import argparse
|
|
28
28
|
import json
|
|
29
|
+
import sqlite3
|
|
29
30
|
import sys
|
|
30
31
|
from pathlib import Path
|
|
31
32
|
|
|
@@ -242,7 +243,12 @@ def _open_store(db_arg: str | None):
|
|
|
242
243
|
return None, None
|
|
243
244
|
try:
|
|
244
245
|
return db, SessionsStore(db)
|
|
245
|
-
except (SchemaError, OSError) as exc:
|
|
246
|
+
except (SchemaError, OSError, sqlite3.Error) as exc:
|
|
247
|
+
# sqlite3.Error covers stores that exist but are not databases
|
|
248
|
+
# ("file is not a database") — SchemaError only fires once a real
|
|
249
|
+
# SQLite file fails schema detection, so a corrupt file used to
|
|
250
|
+
# escape as an unhandled DatabaseError (traceback, exit 1) while
|
|
251
|
+
# provider mode reported the same store as a warning + exit 2.
|
|
246
252
|
print(f"error: cannot open {db}: {exc}", file=sys.stderr)
|
|
247
253
|
return None, None
|
|
248
254
|
|
|
@@ -12,6 +12,7 @@ server or the ``mcp`` package. ``build_server()`` wraps it — needs the
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
import sqlite3
|
|
15
16
|
import sys
|
|
16
17
|
from pathlib import Path
|
|
17
18
|
|
|
@@ -140,7 +141,9 @@ def do_audit(
|
|
|
140
141
|
"detail": f"sessions.db not found: {db}"}
|
|
141
142
|
try:
|
|
142
143
|
store = SessionsStore(db)
|
|
143
|
-
except (SchemaError, OSError) as exc:
|
|
144
|
+
except (SchemaError, OSError, sqlite3.Error) as exc:
|
|
145
|
+
# sqlite3.Error: the file exists but is not a database — same
|
|
146
|
+
# controlled bad_store shape the CLI prints at exit 2.
|
|
144
147
|
return {"error": "bad_store", "detail": f"cannot open {db}: {exc}"}
|
|
145
148
|
with store:
|
|
146
149
|
if session_id:
|
|
@@ -27,6 +27,7 @@ from __future__ import annotations
|
|
|
27
27
|
import json
|
|
28
28
|
import os
|
|
29
29
|
import re
|
|
30
|
+
import sqlite3
|
|
30
31
|
import sys
|
|
31
32
|
from dataclasses import dataclass
|
|
32
33
|
from datetime import datetime, timezone
|
|
@@ -232,7 +233,9 @@ def run_session_end(
|
|
|
232
233
|
)
|
|
233
234
|
except Exception: # noqa: BLE001 - fail-soft; side field is optional
|
|
234
235
|
intent = None # fail-soft — side field is optional
|
|
235
|
-
except (SchemaError, OSError) as exc:
|
|
236
|
+
except (SchemaError, OSError, sqlite3.Error) as exc:
|
|
237
|
+
# sqlite3.Error: the file exists but is not a database —
|
|
238
|
+
# report it as an unreadable store, not an internal error.
|
|
236
239
|
reason = f"cannot open {db}: {exc}"
|
|
237
240
|
|
|
238
241
|
if audit is not None:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devin-qa-pack
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: QA audit for
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: QA audit for agent sessions: verifies deliverable claims (tests, commits, files, pushes) against recorded tool-call ground truth across Devin CLI, Copilot CLI, Codex CLI and VS Code chat stores.
|
|
5
5
|
Author: Icaro0310
|
|
6
6
|
License: MIT
|
|
7
7
|
Requires-Python: >=3.10
|
|
@@ -74,6 +74,19 @@ def test_missing_db_exits_two(tmp_path, capsys):
|
|
|
74
74
|
assert capsys.readouterr().err
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
def test_non_sqlite_db_exits_two_without_traceback(tmp_path, capsys):
|
|
78
|
+
"""A --sessions-db file that is not SQLite fails closed (exit 2 +
|
|
79
|
+
`error:` line), never an unhandled DatabaseError traceback — the
|
|
80
|
+
fast path must degrade exactly like provider mode."""
|
|
81
|
+
bad = tmp_path / "not-a-db.db"
|
|
82
|
+
bad.write_text("this is not sqlite at all", encoding="utf-8")
|
|
83
|
+
rc = main(["audit", "--sessions-db", str(bad), "--all"])
|
|
84
|
+
err = capsys.readouterr().err
|
|
85
|
+
assert rc == 2
|
|
86
|
+
assert "cannot open" in err
|
|
87
|
+
assert "Traceback" not in err
|
|
88
|
+
|
|
89
|
+
|
|
77
90
|
def test_unique_session_prefix_resolves(sessions_db, capsys):
|
|
78
91
|
rc = main(["audit", "--sessions-db", str(sessions_db),
|
|
79
92
|
"--session", "sess-veri"])
|
|
@@ -45,6 +45,16 @@ def test_do_audit_missing_db(tmp_path):
|
|
|
45
45
|
assert out["error"] == "no_store"
|
|
46
46
|
|
|
47
47
|
|
|
48
|
+
def test_do_audit_non_sqlite_db_is_bad_store(tmp_path):
|
|
49
|
+
"""A file that exists but is not SQLite reports the structured
|
|
50
|
+
bad_store error — not a raw DatabaseError from the boundary catch."""
|
|
51
|
+
bad = tmp_path / "not-a-db.db"
|
|
52
|
+
bad.write_text("this is not sqlite at all", encoding="utf-8")
|
|
53
|
+
out = do_audit(sessions_db=str(bad))
|
|
54
|
+
assert out["error"] == "bad_store"
|
|
55
|
+
assert "cannot open" in out["detail"]
|
|
56
|
+
|
|
57
|
+
|
|
48
58
|
def test_do_audit_conflicting_scope_is_error(sessions_db):
|
|
49
59
|
out = do_audit(
|
|
50
60
|
session_id="sess-verified", audit_all_sessions=True,
|
|
@@ -178,6 +178,22 @@ def test_missing_db_skips_softly(tmp_path, capsys):
|
|
|
178
178
|
assert "not found" in payload["reason"]
|
|
179
179
|
|
|
180
180
|
|
|
181
|
+
def test_non_sqlite_db_skips_with_cannot_open_reason(tmp_path, capsys):
|
|
182
|
+
"""A file that exists but is not SQLite is an unreadable store —
|
|
183
|
+
SKIPPED with a `cannot open` reason, not an `internal error`
|
|
184
|
+
DatabaseError falling through to the CLI's outer catch."""
|
|
185
|
+
bad = tmp_path / "not-a-db.db"
|
|
186
|
+
bad.write_text("this is not sqlite at all", encoding="utf-8")
|
|
187
|
+
out = tmp_path / "v.json"
|
|
188
|
+
rc = main(["session-end", "--sessions-db", str(bad),
|
|
189
|
+
"--session-id", "sess-x", "--out", str(out)])
|
|
190
|
+
assert rc == 0
|
|
191
|
+
payload = _read(out)
|
|
192
|
+
assert payload["verdict"] == SKIPPED
|
|
193
|
+
assert "cannot open" in payload["reason"]
|
|
194
|
+
assert "internal error" not in payload["reason"]
|
|
195
|
+
|
|
196
|
+
|
|
181
197
|
def test_empty_store_skips_softly(tmp_path, capsys):
|
|
182
198
|
db = create_sessions_db(tmp_path / "empty.db", n_sessions=0)
|
|
183
199
|
out = tmp_path / "v.json"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.0"
|
|
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
|
|
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
|