delimit-cli 3.15.14 → 4.0.1
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.
- package/CHANGELOG.md +1 -1
- package/gateway/ai/license_core.py +2 -1
- package/gateway/ai/notify.py +12 -12
- package/gateway/ai/server.py +49 -332
- package/gateway/ai/swarm.py +2 -2
- package/gateway/core/contract_ledger.py +1 -1
- package/gateway/core/dependency_graph.py +1 -1
- package/gateway/core/dependency_manifest.py +1 -1
- package/gateway/core/event_backbone.py +2 -2
- package/gateway/core/event_schema.py +1 -1
- package/gateway/core/impact_analyzer.py +1 -1
- package/package.json +4 -1
- package/scripts/crosspost_devto.py +0 -304
- package/scripts/security-check.sh +0 -66
- package/scripts/weekly-tweet.py +0 -191
package/CHANGELOG.md
CHANGED
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
- GitHub Action smoke test workflow
|
|
118
118
|
|
|
119
119
|
### Fixed
|
|
120
|
-
- Gemini deliberation HTTP 400 (ADC credentials +
|
|
120
|
+
- Gemini deliberation HTTP 400 (ADC credentials + GCP project)
|
|
121
121
|
- Deliberation timeout: parallelized round 1 (46% faster)
|
|
122
122
|
- Sensor dedup: titles include repo/issue to prevent duplicates
|
|
123
123
|
- Test-mode guard prevents ledger pollution from tests
|
|
@@ -5,6 +5,7 @@ This module is distributed as a native binary (.so/.pyd), not readable Python.
|
|
|
5
5
|
"""
|
|
6
6
|
import hashlib
|
|
7
7
|
import json
|
|
8
|
+
import os
|
|
8
9
|
import time
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
@@ -166,7 +167,7 @@ def activate(key: str) -> dict:
|
|
|
166
167
|
def _revalidate(data: dict) -> dict:
|
|
167
168
|
"""Re-validate against Lemon Squeezy."""
|
|
168
169
|
key = data.get("key", "")
|
|
169
|
-
if not key or key.startswith("
|
|
170
|
+
if not key or key.startswith(os.environ.get("DELIMIT_INTERNAL_KEY_PREFIX", "")):
|
|
170
171
|
return {"valid": True}
|
|
171
172
|
try:
|
|
172
173
|
import urllib.request
|
package/gateway/ai/notify.py
CHANGED
|
@@ -34,10 +34,10 @@ HISTORY_FILE = Path.home() / ".delimit" / "notifications.jsonl"
|
|
|
34
34
|
INBOX_ROUTING_FILE = Path.home() / ".delimit" / "inbox_routing.jsonl"
|
|
35
35
|
|
|
36
36
|
# ── Inbound email configuration ──────────────────────────────────────
|
|
37
|
-
IMAP_HOST =
|
|
38
|
-
IMAP_PORT = 993
|
|
39
|
-
IMAP_USER =
|
|
40
|
-
FORWARD_TO =
|
|
37
|
+
IMAP_HOST = os.environ.get("DELIMIT_IMAP_HOST", "")
|
|
38
|
+
IMAP_PORT = int(os.environ.get("DELIMIT_IMAP_PORT", "993"))
|
|
39
|
+
IMAP_USER = os.environ.get("DELIMIT_IMAP_USER", "")
|
|
40
|
+
FORWARD_TO = os.environ.get("DELIMIT_FORWARD_TO", "")
|
|
41
41
|
|
|
42
42
|
# Domains/senders whose emails require owner action
|
|
43
43
|
OWNER_ACTION_DOMAINS = {
|
|
@@ -60,9 +60,9 @@ OWNER_ACTION_DOMAINS = {
|
|
|
60
60
|
"digitalocean.com",
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
OWNER_ACTION_SENDERS =
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
OWNER_ACTION_SENDERS = set(
|
|
64
|
+
filter(None, [os.environ.get("DELIMIT_OWNER_EMAIL", "")])
|
|
65
|
+
)
|
|
66
66
|
|
|
67
67
|
# Subject patterns that indicate owner-action (compiled once)
|
|
68
68
|
import re as _re
|
|
@@ -192,7 +192,7 @@ def _load_smtp_account(from_account: str) -> Optional[Dict[str, str]]:
|
|
|
192
192
|
"""Load SMTP credentials from smtp-all.json for a given account.
|
|
193
193
|
|
|
194
194
|
Args:
|
|
195
|
-
from_account: Email address key in smtp-all.json (e.g. '
|
|
195
|
+
from_account: Email address key in smtp-all.json (e.g. 'notifications@example.com').
|
|
196
196
|
|
|
197
197
|
Returns:
|
|
198
198
|
Dict with host, port, user, pass keys, or None if not found.
|
|
@@ -228,7 +228,7 @@ def send_email(
|
|
|
228
228
|
body: Email body text (preferred). Falls back to 'message' for
|
|
229
229
|
backward compatibility.
|
|
230
230
|
from_account: Sender account key in ~/.delimit/secrets/smtp-all.json
|
|
231
|
-
(e.g. '
|
|
231
|
+
(e.g. 'notifications@example.com', 'admin@example.com'). If provided, SMTP
|
|
232
232
|
credentials are loaded from that file instead of env vars.
|
|
233
233
|
message: Email body text (legacy parameter, use 'body' instead).
|
|
234
234
|
event_type: Event category for filtering/logging.
|
|
@@ -258,7 +258,7 @@ def send_email(
|
|
|
258
258
|
smtp_pass = os.environ.get("DELIMIT_SMTP_PASS", "")
|
|
259
259
|
smtp_from = os.environ.get("DELIMIT_SMTP_FROM", "")
|
|
260
260
|
|
|
261
|
-
smtp_to = to or os.environ.get("DELIMIT_SMTP_TO", "
|
|
261
|
+
smtp_to = to or os.environ.get("DELIMIT_SMTP_TO", "")
|
|
262
262
|
|
|
263
263
|
if not all([smtp_host, smtp_from, smtp_to]):
|
|
264
264
|
record = {
|
|
@@ -744,7 +744,7 @@ def _forward_email(original_msg: email.message.Message, smtp_pass: str) -> bool:
|
|
|
744
744
|
body = "\n".join(body_parts) if body_parts else "(no text content)"
|
|
745
745
|
|
|
746
746
|
fwd_text = (
|
|
747
|
-
f"--- Forwarded from
|
|
747
|
+
f"--- Forwarded from notifications@example.com ---\n"
|
|
748
748
|
f"From: {from_header}\n"
|
|
749
749
|
f"Subject: {subject}\n"
|
|
750
750
|
f"Date: {original_msg.get('Date', 'unknown')}\n"
|
|
@@ -776,7 +776,7 @@ def poll_inbox(
|
|
|
776
776
|
"""Poll the IMAP inbox, classify emails, and optionally forward owner-action items.
|
|
777
777
|
|
|
778
778
|
Args:
|
|
779
|
-
smtp_pass: SMTP/IMAP password for
|
|
779
|
+
smtp_pass: SMTP/IMAP password for notifications@example.com.
|
|
780
780
|
limit: Max number of recent messages to check.
|
|
781
781
|
process: If True, forward owner-action emails and mark as read.
|
|
782
782
|
If False, just report classification (dry run).
|