Rebrand Pinscope to Periscope across product and codebase.

Rename the core package to periscopex, update UI/docs/Docker/deploy defaults to periscope.michelebigi.it, and keep legacy version/storage key aliases so existing projects keep working.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-13 20:02:04 +02:00
co-authored by Cursor
parent 556306bf4d
commit 8d2b85600f
177 changed files with 869 additions and 766 deletions
+90
View File
@@ -0,0 +1,90 @@
"""periscope-cad-bridge JSON (E2) for the KiCad action plugin."""
from __future__ import annotations
import json
from pathlib import Path
from backend.periscopex.models import CadIndexEntry, DesignGraph, Finding, ValidationReport
CAD_BRIDGE_VERSION = 1
_PCB_RULE_PREFIXES = ("PE-PLC", "PE-SI", "PE-LAY", "PE-3W", "PE-CLR")
def annotate_findings_cad(
findings: list[Finding],
cad_index: dict[str, CadIndexEntry] | None,
) -> None:
"""Fill cad_sheet/cad_uuid from the graph index when the finding omitted them."""
if not cad_index:
return
for f in findings:
entry = cad_index.get(f.designator)
if not entry:
continue
if not f.cad_uuid and entry.uuid:
f.cad_uuid = entry.uuid
if not f.cad_sheet and entry.sheet:
f.cad_sheet = entry.sheet
def _pin_numbers(designator: str, pins: list[str]) -> list[str]:
out: list[str] = []
prefix = designator + "."
for raw in pins:
s = str(raw).strip()
if not s:
continue
if s.upper().startswith(prefix.upper()):
s = s[len(prefix):]
out.append(s)
return out
def _target_kind(rule_id: str | None) -> str:
rid = rule_id or ""
if any(rid.startswith(p) for p in _PCB_RULE_PREFIXES):
return "pcb"
return "sch"
def build_cad_bridge(
report: ValidationReport,
project_id: str,
*,
url_base: str = "",
) -> dict:
"""E2 `periscope-cad-bridge` payload. Missing uuid/sheet stay empty strings."""
findings: list[dict] = []
for f in report.findings:
fid = f.finding_id or ""
url = ""
if url_base and fid:
sep = "&" if "?" in url_base else "?"
url = f"{url_base}{sep}finding={fid}"
findings.append({
"rule_id": f.rule_id or f.source or "review",
"ref": f.designator,
"pins": _pin_numbers(f.designator, f.pins or []),
"sheet": f.cad_sheet or "",
"uuid": f.cad_uuid or "",
"severity": (f.status or "WARNING").lower(),
"message": f.finding,
"url": url,
"finding_id": fid,
"net": f.net or "",
"target": _target_kind(f.rule_id),
})
return {
"version": CAD_BRIDGE_VERSION,
"project_id": project_id,
"findings": findings,
}
def write_cad_bridge(path: str | Path, payload: dict) -> None:
Path(path).write_text(json.dumps(payload, indent=2) + "\n")
def cad_index_from_graph(graph: DesignGraph) -> dict[str, CadIndexEntry]:
return dict(graph.cad_index or {})