1#!/usr/bin/env python3
2"""Check downloaded wrappers without calling the model or changing client settings."""
3import json
4import os
5import pty
6import select
7import time
8from pathlib import Path
9import subprocess
10import sys
11import tempfile
12
13source = Path(sys.argv[1]).resolve()
14with tempfile.TemporaryDirectory(prefix="snow-wrapper-test-") as temporary:
15 root = Path(temporary)
16 for name in ("codex", "claude"):
17 binary = root / name
18 binary.write_text('''#!/usr/bin/env python3
19import json, os, pathlib, sys
20catalog = next((a.split("=",1)[1].strip('"') for a in sys.argv if a.startswith("model_catalog_json=")), None)
21print(json.dumps({"args":sys.argv[1:],"env":{k:v for k,v in os.environ.items() if k.startswith(("SNOW", "ANTHROPIC", "CLAUDE", "API_", "ENABLE_CLAUDE"))},"catalog":json.loads(pathlib.Path(catalog).read_text()) if catalog else None}))
22''')
23 binary.chmod(0o755)
24 env = dict(os.environ, PATH=str(root) + os.pathsep + os.environ["PATH"], XDG_CONFIG_HOME=str(root / "config"))
25 env.pop("SNOWGLOBE_AI_KEY", None)
26 env.pop("SNOWGLOBE_AI_URL", None)
27 for name in ("snow-codex", "snow-claude"):
28 wrapper = source / name
29 subprocess.run(["bash", "-n", wrapper], check=True)
30 failed = subprocess.run(["bash", wrapper], env=env, stdin=subprocess.DEVNULL, capture_output=True)
31 assert failed.returncode == 1 and b"SNOWGLOBE_AI_KEY" in failed.stderr
32 key = root / "config/snowglobe-ai/api-key"
33 key.parent.mkdir(parents=True, exist_ok=True)
34 master, slave = pty.openpty()
35 process = subprocess.Popen(["bash", wrapper, "--help"], env=env, stdin=slave, stdout=subprocess.PIPE, stderr=slave)
36 os.close(slave)
37 prompt = b""
38 deadline = time.monotonic() + 10
39 try:
40 while b"Snow Globe API key:" not in prompt:
41 assert time.monotonic() < deadline, "first-run key prompt did not appear"
42 if select.select([master], [], [], 1)[0]:
43 prompt += os.read(master, 4096)
44 os.write(master, b"wrapper-canary\n")
45 output, _ = process.communicate(timeout=10)
46 assert process.returncode == 0 and json.loads(output)["env"]["SNOWGLOBE_AI_KEY"] == "wrapper-canary"
47 assert key.read_text() == "wrapper-canary\n" and key.stat().st_mode & 0o777 == 0o600
48 finally:
49 if process.poll() is None: process.kill()
50 os.close(master)
51 data = json.loads(subprocess.check_output(["bash", wrapper, "--help", "argument with spaces"], env={**env, "ANTHROPIC_AUTH_TOKEN":"old-auth", "CLAUDE_CODE_OAUTH_TOKEN":"old-login"}))
52 assert data["args"][-2:] == ["--help", "argument with spaces"]
53 assert "wrapper-canary" not in " ".join(data["args"])
54 assert data["env"]["SNOWGLOBE_AI_KEY"] == "wrapper-canary"
55 assert key.stat().st_mode & 0o777 == 0o600
56 if name == "snow-codex":
57 assert data["args"][:2] == ["--no-daemon", "--approve-for-me"]
58 assert data["catalog"]["models"][0]["context_window"] == 131072
59 assert not list(key.parent.glob("catalog.*")), "temporary catalog leaked"
60 else:
61 assert data["args"][:2] == ["--permission-mode", "auto"]
62 assert "ANTHROPIC_AUTH_TOKEN" not in data["env"] and "CLAUDE_CODE_OAUTH_TOKEN" not in data["env"]
63 assert data["env"]["CLAUDE_CODE_AUTO_MODE_SERVER"] == "0"
64 assert data["env"]["API_TIMEOUT_MS"] == "28800000"
65 credentials = Path(data["env"]["CLAUDE_SECURESTORAGE_CONFIG_DIR"])
66 assert credentials.stat().st_mode & 0o777 == 0o700
67 key.unlink()
68 print("Both downloaded wrappers preserve arguments, enable auto approval, isolate credentials, and clean up.")