-
-
Notifications
You must be signed in to change notification settings - Fork 20
feat(commercial-v1-ga): sync working-tree changes for v1 GA #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f5b7605
d0cd06c
a337091
8fa946a
fa0fdd1
7c8c948
c08a73d
f7cc598
91c96c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,17 @@ | ||
| """Ensure the repo root is importable when running ``python -m pytest`` from anywhere.""" | ||
| import os | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| ROOT = Path(__file__).resolve().parent | ||
| if str(ROOT) not in sys.path: | ||
| sys.path.insert(0, str(ROOT)) | ||
|
|
||
| # The update reminder reaches out to the network to look up the newest release. Keep the | ||
| # offline test suite network-inert by default; tests that exercise the feature opt back in | ||
| # explicitly via monkeypatch (see tests/test_update_check.py). | ||
| os.environ.setdefault("ENGRAPHIS_UPDATE_CHECK", "0") | ||
|
|
||
| # The legacy scripts/test_*.py files are HTTP smoke tests (need a running server + | ||
| # httpx), not unit tests. Keep pytest focused on the tests/ suite. | ||
| collect_ignore_glob = ["scripts/*"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -202,6 +202,21 @@ def _provider_state(conn: sqlite3.Connection, provider_message_id: str) -> str: | |
| return "sent" | ||
|
|
||
|
|
||
| def _body_has_license_key(text_body: Optional[str]) -> bool: | ||
| """True when the body carries a signed license key (ENGR1.<sig>.<payload>). | ||
|
|
||
| Mirrors inspector/webhooks.py::_existing_license_delivery() extraction so a | ||
| purchase/renewal outbox row stays the recoverable source of truth until the | ||
| Polar fulfillment claim is finalized; only non-recoverable bodies are redacted | ||
| after a successful send. | ||
| """ | ||
| for entry in str(text_body or "").splitlines(): | ||
| candidate = entry.strip() | ||
| if candidate.startswith("ENGR1.") and candidate.count(".") == 2: | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def deliver_now(message_id: str, | ||
| deliverer: Callable[ | ||
| [str, str, str, Optional[str], str], tuple[str, str]]) -> bool: | ||
|
|
@@ -242,9 +257,16 @@ def deliver_now(message_id: str, | |
| provider_message_id = (provider_id or "")[:160] | ||
| conn.execute("BEGIN IMMEDIATE") | ||
| now = time.time() | ||
| # A purchased license key in the body is the crash-recovery source of | ||
| # truth for inspector/webhooks.py::_existing_license_delivery() until the | ||
| # Polar fulfillment claim is finalized; redacting a license row here would | ||
| # strand the webhook. Only clear bodies with no recoverable entitlement. | ||
| redact_sql = ( | ||
| "" if _body_has_license_key(message["text_body"]) | ||
| else ",text_body='',reply_to=NULL") | ||
| updated = conn.execute( | ||
| "UPDATE email_outbox SET status='sent',provider=?,provider_message_id=?," | ||
| "last_error='',sent_at=?,updated_at=? " | ||
| "last_error='',sent_at=?,updated_at=?" + redact_sql + " " | ||
| "WHERE id=? AND status='sending' AND attempts=?", | ||
|
Comment on lines
268
to
270
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Clearing Useful? React with 👍 / 👎. |
||
| (provider_name, provider_message_id, now, now, | ||
| message_id, int(message["attempts"]))) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -119,6 +119,7 @@ def _err(exc: Exception) -> str: | |
| "engraphis_verify_receipts", | ||
| "engraphis_export_receipts", | ||
| "engraphis_stats", | ||
| "engraphis_check_update", | ||
| }) | ||
| _ADMIN_TOOLS = frozenset({ | ||
| "engraphis_consolidate", | ||
|
|
@@ -990,6 +991,33 @@ def engraphis_stats( | |
| return _err(exc) | ||
|
|
||
|
|
||
| @mcp.tool( | ||
| name="engraphis_check_update", | ||
| annotations={"title": "Check for an Engraphis update", "readOnlyHint": True, | ||
| "destructiveHint": False, "idempotentHint": True, "openWorldHint": True}, | ||
| ) | ||
| def engraphis_check_update( | ||
| force: Annotated[bool, Field(description="Bypass the ~24h cache and re-check the " | ||
| "release source now.")] = False, | ||
| ) -> str: | ||
|
Comment on lines
+994
to
+1002
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This adds Useful? React with 👍 / 👎. |
||
| """Report whether a newer Engraphis release is available, so an agent can proactively | ||
| remind the user to upgrade. | ||
|
|
||
| Cached ~24h and fail-silent; honors ``ENGRAPHIS_UPDATE_CHECK=0`` (then ``enabled`` is | ||
| false). The default GitHub source is overridable via ``ENGRAPHIS_UPDATE_URL``. | ||
|
|
||
| Returns: | ||
| str: JSON ``{"enabled","current","latest","update_available","url","notice"}``. | ||
| """ | ||
| try: | ||
| from engraphis import update_check | ||
| snap = dict(update_check.check(force=True) if force else update_check.snapshot()) | ||
| snap["notice"] = update_check.notice_line(snap) or "" | ||
| return _ok(snap) | ||
| except Exception as exc: # noqa: BLE001 | ||
| return _err(exc) | ||
|
|
||
|
|
||
| @mcp.tool( | ||
| name="engraphis_ingest", | ||
| annotations={"title": "Ingest raw text (extract facts first)", "readOnlyHint": False, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For every normal
purchase_licenseemail,inspector/webhooks.py::_license_email_text()places the signed key on its own indented line, so this predicate is true and the successful-send update deliberately leavestext_bodyintact. There is no subsequent outbox cleanup or fulfillment-finalization path in this commit—_existing_license_delivery()only reads the body—so all successfully delivered customer license keys now remain as plaintext in the vendor ledger indefinitely, whereas they were previously redacted after delivery. Retain recovery material only through the webhook finalization window (or in a protected recovery record), then clear it.Useful? React with 👍 / 👎.