{"id":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","shortId":"4aenwe","kind":"skill","title":"pyapp","tagline":"Auto-activate for pyapp build config. Build air-gapped, multi-architecture standalone Python executables using PyApp and uv. Use when: bundling Python runtimes for network-isolated environments, patching PyApp defaults, or compiling single-binary assets. Not for PyInstaller, cx_F","description":"# PyApp Standalone Binaries\n\nEnable building self-contained, air-gapped, multi-architecture standalone executables for any Python application using **PyApp** and **uv**.\n\n---\n\n## Overview\n\nStandard `pyapp` installation bootstraps the environment on first run, which usually requires internet access. For **air-gapped** or **network-isolated** environments, you must embed the entire Python distribution and its dependencies ahead of time.\n\nThis skill documents the **Bundle-Patch-Compile** workflow:\n\n1. **Bundle**: Download a standalone Python build, install dependencies into its `site-packages`, and repackage.\n2. **Patch**: Modify the PyApp source code to enforce custom install locations or isolation defaults.\n3. **Compile**: Compile the patched PyApp binary with the bundled distribution embedded.\n\n---\n\n## Architecture & Philosophy\n\n### The Packaged Distribution\n\nInstead of installing at runtime, we build a **hybrid distribution**:\n\n* A basic standalone Python distribution (e.g., from `python-build-standalone`).\n* Pre-populated `site-packages` via `uv pip install --target`.\n* This avoids running any package managers on first execution.\n\n---\n\n<workflow>\n\n## Configuration\n\n### 1. Standard Settings\n\nIn your `pyproject.toml`, configure the Hatch target or custom builder to use specific variables.\n\n<example>\n\n```toml\n[tool.hatch.build.targets.binary]\nscripts = [\"myapp\"]\npyapp-version = \"v0.29.0\"\n\n[tool.hatch.build.targets.binary.env]\nPYAPP_DISTRIBUTION_EMBED = \"1\"\nPYAPP_FULL_ISOLATION = \"1\"\nPYAPP_ALLOW_UPDATES = \"1\"\n```\n\n</example>\n\n---\n\n## Step-by-Step Workflow\n\n### Phase 1: Bundling (Prep the Runtime)\n\nTo enable fully offline operations, follow these steps using an automation script (see `scripts/bundler.py`):\n\n1. **Download Standalone Python**: Acquire a compatible `install_only_stripped` version for the Target Rust arch (e.g., `x86_64-unknown-linux-gnu`).\n2. **Install Deps Off-Target**: Use `uv pip install` with specific cross-compilation flags:\n    * `--target <extracted_python_site_packages>`\n    * `--python-platform <uv_supported_platform>`\n    * `--upgrade`\n3. **Repackage**: Compress the resulting layout back into a `.tar.gz`.\n\n### Phase 2: PyApp Patching (Enforce Paths)\n\nBy default, PyApp stores user data in standard local data folders. If you require strict isolation (e.g., `~/.myapp`), you can **patch the PyApp source code** just before `cargo build`:\n\n<example>\n\n```python\n# Conceptual example of patching src/app.rs\nimport re\ncontent = app_rs.read_text()\npattern = re.compile(r\"platform_dirs\\(\\)\\s*\\.data_local_dir\\(\\)...\")\nreplacement = \"std::path::PathBuf::from(\\\"~/.myapp\\\")\"\napp_rs.write_text(pattern.sub(replacement, content))\n```\n\n</example>\n\n### Phase 3: Compiling\n\nTo maintain maximum glibc backward-compatibility (e.g., supporting RHEL 7+ / manylinux2014 baseline):\n\n* Use **Zig** as the linker trigger: `cargo zigbuild --release --target <target>.2.17`\n\n</workflow>\n\n---\n\n## CI/CD Integration\n\nEnsure your GitHub Action includes:\n\n1. An upstream build step creating target-agnostic `.whl` files.\n2. A cross-target build matrix (`x86_64-linux-gnu`, `aarch64-linux-gnu`, `aarch64-apple-darwin`, etc.).\n3. Zig setup steps for robust glibc pin targeting.\n\n> [!TIP]\n> Always test inside a non-networked container:\n> `docker run --network none -v $(pwd):/app ubuntu:20.04 /app/myapp-binary --help`\n\n---\n\n## Provided Resources\n\n* **Bundler Template**: `scripts/bundler.py` (in this skill directory)\n* **CI Matrix Action Example**: `examples/release-action.yml` (in this skill directory)\n\n## Shared Styleguide Baseline\n\n* Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n* [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n* [Python](https://github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)\n* [Docker](https://github.com/cofin/flow/blob/main/templates/styleguides/tools/docker.md)\n* Keep this skill focused on tool-specific workflows, edge cases, and integration details.\n\n<guardrails>\n## Guardrails\n\n* **Use non-root user in production images** -- When containerizing the resulting binary, ensure it runs as a non-privileged user to minimize security risks.\n* **Prefer multi-stage Docker builds** -- Separate the build environment (with Cargo and Zig) from the final runtime image to keep the production artifact small.\n* **Target specific glibc versions with Zig** -- Use `cargo zigbuild --target <arch>.2.17` to ensure compatibility with older Linux distributions (e.g., RHEL 7+).\n* **Embed all dependencies for air-gapped use** -- Set `PYAPP_DISTRIBUTION_EMBED = \"1\"` to ensure the binary is fully self-contained and does not require internet access on first run.\n* **Validate binary size** -- Monitor the size of the embedded distribution; strip unnecessary symbols and files (e.g., `.pyc`, `__pycache__`, tests) to keep the executable manageable.\n</guardrails>\n\n<validation>\n## Validation Checkpoint\n\n* [ ] Binary runs successfully in a network-isolated (`--network none`) environment\n* [ ] glibc compatibility is verified using `ldd --version` on the target platform\n* [ ] No root privileges are required to execute the binary\n* [ ] All required Python dependencies are included in the embedded `site-packages`\n* [ ] Binary size is within the expected range for the bundled distribution\n* [ ] Custom install paths (if patched) are correctly respected by the application\n</validation>","tags":["pyapp","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-pyapp","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/pyapp","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (5,457 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-24T07:03:19.236Z","embedding":null,"createdAt":"2026-04-23T13:04:00.810Z","updatedAt":"2026-04-24T07:03:19.236Z","lastSeenAt":"2026-04-24T07:03:19.236Z","tsv":"'/.myapp':347,384 '/app':480 '/app/myapp-binary':483 '/cofin/flow/blob/main/templates/styleguides/general.md)':523 '/cofin/flow/blob/main/templates/styleguides/languages/python.md)':527 '/cofin/flow/blob/main/templates/styleguides/tools/docker.md)':531 '1':117,207,236,240,244,251,270,424,631 '2':133,293,325,435 '2.17':416,608 '20.04':482 '3':148,314,391,456 '64':288,443 '7':403,618 'aarch64':448,452 'aarch64-apple-darwin':451 'aarch64-linux-gnu':447 'access':85,646 'acquir':274 'action':422,496 'activ':4 'agnost':432 'ahead':105 'air':11,56,88,624 'air-gap':10,55,87,623 'allow':242 'alway':466 'app_rs.read':368 'app_rs.write':385 'appl':453 'applic':66,740 'arch':285 'architectur':15,60,160 'artifact':596 'asset':41 'auto':3 'auto-activ':2 'autom':266 'avoid':198 'back':320 'backward':398 'backward-compat':397 'baselin':405,505 'basic':176 'binari':40,49,154,559,635,651,676,706,719 'bootstrap':75 'build':7,9,51,123,171,184,358,427,440,578,581 'builder':219 'bundl':25,113,118,157,252,728 'bundle-patch-compil':112 'bundler':487 'cargo':357,412,584,605 'case':542 'checkpoint':675 'ci':494 'ci/cd':417 'code':139,354 'compat':276,399,611,688 'compil':37,115,149,150,307,392 'compress':316 'conceptu':360 'config':8 'configur':206,213 'contain':54,473,640 'container':556 'content':367,389 'correct':736 'creat':429 'cross':306,438 'cross-compil':305 'cross-target':437 'custom':142,218,730 'cx':45 'darwin':454 'data':335,339,376 'default':35,147,331 'dep':295 'depend':104,125,621,710 'detail':545 'dir':374,378 'directori':493,502 'distribut':101,158,164,174,179,234,615,629,659,729 'docker':474,528,577 'document':110 'download':119,271 'duplic':515 'e.g':180,286,346,400,616,665 'edg':541 'emb':97,235,619,630 'embed':159,658,715 'enabl':50,257 'enforc':141,328 'ensur':419,560,610,633 'entir':99 'environ':32,77,94,582,686 'etc':455 'exampl':361,497 'examples/release-action.yml':498 'execut':18,62,205,672,704 'expect':724 'f':46 'file':434,664 'final':589 'first':79,204,648 'flag':308 'focus':535 'folder':340 'follow':261 'full':238 'fulli':258,637 'gap':12,57,89,625 'general':519 'generic':510 'github':421 'github.com':522,526,530 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':521 'github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)':525 'github.com/cofin/flow/blob/main/templates/styleguides/tools/docker.md)':529 'glibc':396,462,600,687 'gnu':292,446,450 'guardrail':546 'hatch':215 'help':484 'hybrid':173 'imag':554,591 'import':365 'includ':423,712 'insid':468 'instal':74,124,143,167,195,277,294,302,731 'instead':165 'integr':418,544 'internet':84,645 'isol':31,93,146,239,345,683 'keep':532,593,670 'language/framework':511 'layout':319 'ldd':692 'linker':410 'linux':291,445,449,614 'linux-gnu':444 'local':338,377 'locat':144 'maintain':394 'manag':202,673 'manylinux2014':404 'matrix':441,495 'maximum':395 'minim':570 'modifi':135 'monitor':653 'multi':14,59,575 'multi-architectur':13,58 'multi-stag':574 'must':96 'myapp':227 'network':30,92,472,476,682,684 'network-isol':29,91,681 'non':471,549,566 'non-network':470 'non-privileg':565 'non-root':548 'none':477,685 'off-target':296 'offlin':259 'older':613 'oper':260 'overview':71 'packag':130,163,191,201,718 'patch':33,114,134,152,327,350,363,734 'path':329,381,732 'pathbuf':382 'pattern':370 'pattern.sub':387 'phase':250,324,390 'philosophi':161 'pin':463 'pip':194,301 'platform':312,373,697 'popul':188 'pre':187 'pre-popul':186 'prefer':573 'prep':253 'principl':520 'privileg':567,700 'product':553,595 'provid':485 'pwd':479 'pyapp':1,6,20,34,47,68,73,137,153,229,233,237,241,326,332,352,628 'pyapp-vers':228 'pyc':666 'pycach':667 'pyinstal':44 'pyproject.toml':212 'python':17,26,65,100,122,178,183,273,311,359,524,709 'python-build-standalon':182 'python-platform':310 'r':372 'rang':725 're':366 're.compile':371 'reduc':514 'releas':414 'repackag':132,315 'replac':379,388 'requir':83,343,644,702,708 'resourc':486 'respect':737 'result':318,558 'rhel':402,617 'risk':572 'robust':461 'root':550,699 'rule':512 'run':80,199,475,562,649,677 'runtim':27,169,255,590 'rust':284 'script':226,267 'scripts/bundler.py':269,489 'secur':571 'see':268 'self':53,639 'self-contain':52,638 'separ':579 'set':209,627 'setup':458 'share':503,507 'singl':39 'single-binari':38 'site':129,190,717 'site-packag':128,189,716 'size':652,655,720 'skill':109,492,501,518,534 'skill-pyapp' 'small':597 'sourc':138,353 'source-cofin' 'specif':222,304,539,599 'src/app.rs':364 'stage':576 'standalon':16,48,61,121,177,185,272 'standard':72,208,337 'std':380 'step':246,248,263,428,459 'step-by-step':245 'store':333 'strict':344 'strip':279,660 'styleguid':504,508 'success':678 'support':401 'symbol':662 'tar.gz':323 'target':196,216,283,298,309,415,431,439,464,598,607,696 'target-agnost':430 'templat':488 'test':467,668 'text':369,386 'time':107 'tip':465 'toml':224 'tool':538 'tool-specif':537 'tool.hatch.build.targets.binary':225 'tool.hatch.build.targets.binary.env':232 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'trigger':411 'ubuntu':481 'unknown':290 'unknown-linux-gnu':289 'unnecessari':661 'updat':243 'upgrad':313 'upstream':426 'use':19,23,67,221,264,299,406,506,547,604,626,691 'user':334,551,568 'usual':82 'uv':22,70,193,300 'v':478 'v0.29.0':231 'valid':650,674 'variabl':223 'verifi':690 'version':230,280,601,693 'via':192 'whl':433 'within':722 'workflow':116,249,540 'x86':287,442 'zig':407,457,586,603 'zigbuild':413,606","prices":[{"id":"87267abf-8806-4aef-bbde-227f36883427","listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:00.810Z"}],"sources":[{"listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","source":"github","sourceId":"cofin/flow/pyapp","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/pyapp","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:00.810Z","lastSeenAt":"2026-04-24T07:03:19.236Z"}],"details":{"listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"pyapp","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-19T23:22:27Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"75ef93d47d84560767cb202dd95c4b547ddb7384","skill_md_path":"skills/pyapp/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/pyapp"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"pyapp","description":"Auto-activate for pyapp build config. Build air-gapped, multi-architecture standalone Python executables using PyApp and uv. Use when: bundling Python runtimes for network-isolated environments, patching PyApp defaults, or compiling single-binary assets. Not for PyInstaller, cx_Freeze, or other Python packaging tools."},"skills_sh_url":"https://skills.sh/cofin/flow/pyapp"},"updatedAt":"2026-04-24T07:03:19.236Z"}}