cross-platform-python
Skill3 starsChanged 4 months agoMITView on GitHub
Rules for Python host code (templates/*.py, root launchers, tests) so every change runs identically on Windows, Ubuntu, and macOS the first time — host detection, path flavor, subprocess discipline, UTF-8, process replacement, and platform-portable test expectations.
In this repository7 other files it gives its agents.
- AGENTS.mdAGENTS.md
- llms.txtllms.txt
- atomic-ipc-filesSkill
- cross-platform-shellSkill
- editor-main-threadSkill
- release-ci-guardrailsSkill
- safe-process-managementSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
Never branch on sys.platform == "darwin" as an implicit "POSIX else Windows" split.
- Very specific: line 27
Every helper spawn (tasklist, taskkill, PowerShell, ps, lsof, wslpath, git, open, refresh helpers) must pass:
- Very specific: line 38
Call server_core.reconfigure_stdio_utf8() first in every Python entrypoint.
- Very specific: line 48
Use server_core.write_json (temp + os.replace) for anything the editor or another process polls.
- Distinctive: line 61
Never compare full path strings (cross-platform-shell skill rule 9).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Cross-Platform Python Guidelines
The Python host runs on macOS daily and on Windows/Linux only when a colleague or CI executes it. Every rule below was earned from a real Windows failure that macOS could not reproduce (2026-07 deep review: docs/archive/reports/2026-07-10_windows_platform_deep_review.md). Load this skill before writing or editing any Python in templates/, the root *.py launchers, or tests.
1. Host Detection Goes Through server_core
server_core.is_windows_like_host()for user-facing flavor decisions (rendered commands, launcher names, quoting). It is env-based and covers native cmd/PowerShell, MSYS/Git Bash, and Cygwin —os.namealone does not.server_host_platform.host_platform_kind()for adapter routing (process listing, liveness).- Never branch on
sys.platform == "darwin"as an implicit "POSIX else Windows" split; Linux must land in the POSIX branch deliberately.
2. Path Flavor Is Part of the Contract
- Shell-facing strings:
server_core.quoted_shell_path()/render_launcher_cli()— native form + quotes on Windows-like hosts,as_posix()elsewhere. Never embed barestr(path)in a command template (see cross-platform-shell skill rule 8). - The launcher token is the exception:
launcher_command_prefix()always renders the absolute launcher path with forward slashes, because bash treats a command word as a path only when it contains/, while cmd accepts it quoted. Route every rendered command (and the bridge-enable recipe viabridge_enable_recovery_command()) through it; never format a launcher-less verb. - Preserve
PurePathflavor in helpers: wrapping an incomingPureWindowsPathinPath(...)on a POSIX host silently rewrites separators. - Durable values read later by native Windows tools must be host-native; values read by Git Bash must be POSIX (cross-platform-shell skill rule 7).
3. Subprocess Discipline (enforced by AST sweep)
Every helper spawn (tasklist, taskkill, PowerShell, ps, lsof, wslpath, git, open, refresh helpers) must pass:
timeout=— a hung probe otherwise blocks the MCP server forever with zero diagnostics;- explicit
subprocess.TimeoutExpiredhandling — it is not anOSError; anexcept OSErrorguard silently lets the timeout escape and crash the caller (this bug shipped in the PowerShell process-listing path); encoding="utf-8", errors="replace"— never locale/ANSI decode (cp1251/cp866 hosts corrupt output);**server_core.hidden_window_subprocess_kwargs()when the spawn can run on a Windows host — GUI-hosted servers must not flash console windows.
The only legitimate no-timeout spawns are children that ARE the workload (delegated server run, batch self-invocations). tests/test_subprocess_timeout_contract.py sweeps every subprocess.run call via AST and holds the explicit allowlist — extend the allowlist consciously; never drop timeout= silently.
4. UTF-8 End to End
- Call
server_core.reconfigure_stdio_utf8()first in every Python entrypoint; Windows pipes default to the ANSI codepage and a Cyrillic project path kills stdio mid-decode otherwise. - Launchers default
PYTHONUTF8=1; keep protocol JSONensure_ascii=True. - File reads accept BOM/UTF-16 where the writer may be PowerShell (
server_core.read_json).
5. os.execv Is POSIX-Only Behavior
On Windows os.execv spawns a new process and kills the parent — an MCP client watching the parent sees its server die. On os.name == "nt" use subprocess.run and propagate the exit code (exec_python_script, refresh exec_run are the reference shape).
6. Files Other Processes Poll Are Published Atomically
Use server_core.write_json (temp + os.replace) for anything the editor or another process polls. Never ad-hoc open(...).write for polled files. Full co-design rules: atomic-ipc-files skill.
7. POSIX-Only Tools Need a Windows Answer
lsof, ps, open have no Windows presence. Any feature built on them needs a Windows counterpart (tasklist, CIM listing, Hub secondaryInstallPath.json discovery) or a documented safe degradation — silent [] on Windows turns a safety check into a no-op.
8. Platform-Portable Test Expectations
Windows CI failures from this repo's history were mostly test-pinning bugs, not product bugs. When writing tests:
- Pin the flavor when asserting rendered commands:
mock.patch.object(server_core, "is_windows_like_host", return_value=False)— otherwise the Windows leg correctly renders.cmd+ native paths and the assert breaks. - Derive path expectations from the platform: expect
str(Path("/x/y")), not a hard-coded"/x/y". - Case-insensitive usage asserts: the wrapper prints
Usage:, argparse printsusage:— compare on.lower(). - Never compare full path strings (cross-platform-shell skill rule 9).
- Patch through the facade, call through the facade:
server_editor_hostre-syncs owner modules per call; patches applied via the facade leak into owner modules until the next facade call, so direct owner-module calls in later tests see stale mocks (tests/test_subprocess_timeout_contract.pyTaskkillContractTest documents the shape). - New cross-module name in a star-import module: verify it resolves in the defining module (
hasattrprobe) AND add a test that executes the new call path — a latentNameErroron an untested branch passed a 340-test suite here once (render_launcher_cliin the lifecycle module).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

