Repository navigation
101 lines (89 loc) · 3.63 KB
/
Copy pathci.yml
File metadata and controls
101 lines (89 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
name: CI
on:
push:
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Secret scan
uses: gitleaks/gitleaks-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install lint tools
run: sudo DEBIAN_FRONTEND=noninteractive apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y shellcheck libxml2-utils
- name: Shellcheck
run: |
set -euo pipefail
shopt -s nullglob
scripts=(scripts/*.sh)
if ((${#scripts[@]})); then
shellcheck "${scripts[@]}"
else
echo "No scripts/*.sh present; skipping shellcheck"
fi
- name: Host MCP split
run: |
set -euo pipefail
python3 - <<'PY'
import json
from pathlib import Path
cursor = json.loads(Path("plugins/phonezero/mcp.json").read_text())
telnyx = cursor["mcpServers"]["telnyx"]
if telnyx.get("type") != "stdio" or "url" in telnyx:
raise SystemExit("Cursor mcp.json telnyx must stay stdio (no hosted URL)")
if "xai" not in cursor["mcpServers"]:
raise SystemExit("Cursor mcp.json must keep the xAI stdio server")
grok = json.loads(Path("plugins/phonezero-grok/.mcp.json").read_text())
gtel = grok["mcpServers"]["telnyx"]
if gtel.get("type") != "http" or gtel.get("url") != "https://api.telnyx.com/v2/mcp":
raise SystemExit("Grok .mcp.json telnyx must be hosted HTTP")
if grok["mcpServers"].get("xai", {}).get("type") != "stdio":
raise SystemExit("Grok .mcp.json must ship the xAI stdio server")
print("host MCP split ok")
PY
- name: xAI MCP self-test
run: |
set -euo pipefail
node plugins/phonezero/scripts/xai-mcp.mjs --self-test
node scripts/xai-mcp.mjs --self-test
node plugins/phonezero/scripts/launch-xai-mcp.mjs --resolve-only
- name: Prompt paste files
run: |
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
desc = Path("plugins/phonezero/prompts/end_call.md").read_text(encoding="utf-8").strip()
voice = Path("plugins/phonezero/prompts/voice-agent.md").read_text(encoding="utf-8")
if not desc:
raise SystemExit("end_call.md is empty")
if desc not in voice:
raise SystemExit("end_call.md must appear verbatim in voice-agent.md")
print("end_call description in sync")
PY
- name: TeXML well-formed
run: |
set -euo pipefail
shopt -s nullglob
xmls=(texml/*.xml plugins/phonezero/texml/*.xml)
if ((${#xmls[@]})); then
xmllint --noout "${xmls[@]}"
else
echo "No texml/*.xml present; skipping xmllint"
fi
# Generic E.164 plus separated US/NANP forms. Dates, semver, and $0.05
# do not match. Only scripts/privacy-phone-allowlist.txt is permitted.
# File-content emails must be GitHub noreply or RFC 2606 example.* .
# Commit authors must be a GitHub noreply (or cursoragent) identity.
- name: Privacy guards
env:
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
run: |
set -euo pipefail
git fetch --no-tags origin "${GITHUB_BASE_REF:-main}:refs/remotes/origin/${GITHUB_BASE_REF:-main}" || true
python3 scripts/privacy-check.py --self-test
python3 scripts/privacy-check.py