{"adoption": {"forks": 417, "observed_at": "2026-08-28T04:06:13.462551+00:00", "stars": 2099}, "canonical_url": "https://ross.abutalabs.com/products/app-host", "card": {"archived": false, "artifact_type": "application", "description": "应用内网发布 | iOS OTA (Over-the-Air) | APP publish website like fir.im  | 适用于企业 iOS & Android 内网发布测试使用，方便管理和分发 APP 包", "domain": ["mobile-development", "developer-tools", "self-hosted"], "enriched": true, "function": ["file-upload", "web-framework", "self-hosted", "developer-tools"], "health_score": 20, "homepage": null, "language": "Ruby", "license": "MIT", "license_family": "permissive", "maturity": "maintenance", "member_repos": ["pluosi/app-host"], "name": "pluosi/app-host", "platform": ["self-hosted", "cross-platform"], "pushed_at": "2023-01-19T11:16:18+00:00", "repo": "pluosi/app-host", "stars": 2099, "tags": ["ios-ota", "app-distribution", "android-apk", "fir-im-alternative", "ruby-on-rails", "intranet", "mobile-app-hosting", "ad-hoc-distribution", "automation", "docker", "web-server"], "topics": [], "urls": [], "use_cases": ["distribute iOS and Android test builds to internal teams", "self-hosted alternative to fir.im for enterprise app distribution", "install iOS ad-hoc apps over-the-air inside a private network", "manage app release channels like production, sandbox, and jailbreak builds", "upload APK and IPA packages via API or web form", "parse package metadata such as iOS build type, UDIDs, and Android signing certificates", "manage user accounts and permissions for app distribution"], "what_it_is": "AppHost is a self-hosted web application for managing and distributing iOS and Android app packages within an intranet, similar to fir.im. It supports package uploads via API or web forms, channel management (e.g., iOS production, sandbox, Android builds), package metadata parsing, and iOS OTA installation over HTTPS.", "when_to_avoid": ["you need public app store distribution or consumer-facing app publishing", "you cannot configure HTTPS, since iOS IPA installation requires it", "you need XML-based APK icon parsing or other unsupported features", "you want a actively developed project with frequent updates"], "when_to_choose": ["you need to distribute internal iOS/Android builds without exposing them to public services", "your company requires on-premises hosting for confidentiality", "you want an open-source fir.im alternative you can customize", "you need iOS OTA installation within an intranet with HTTPS"]}, "data_as_of": "2026-08-30T08:39:29.467469+00:00", "members": [{"path": "/products/app-host", "repo": "pluosi/app-host", "role": "main", "score": 32}], "provenance": {"archived": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "artifact_type": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "description": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "domain": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "enriched": {"inputs": [], "kind": "computed", "method": "enrichment_status"}, "function": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "health_score": {"inputs": ["days_since_push", "days_since_release", "archived"], "kind": "computed", "method": "health_v1"}, "homepage": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "language": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "license": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "license_family": {"inputs": ["license"], "kind": "computed", "method": "license_family"}, "maturity": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "member_repos": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "name": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "platform": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "pushed_at": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "repo": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "stars": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "tags": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "topics": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "urls": {"kind": "observed", "observed_at": "2026-08-28T04:06:13.462551+00:00", "source": "github"}, "use_cases": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "what_it_is": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "when_to_avoid": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}, "when_to_choose": {"confidence": null, "enriched_at": "2026-08-30T02:54:25.783259+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "9b24546a4e7c0a73724315ac0cfc586684b81b082471fc12dd1d83fcb827c361", "fetched_at": "2026-08-28T04:06:13.462551+00:00", "kind": "readme", "missing": false, "url": "https://github.com/pluosi/app-host"}], "taxonomy_version": 1}}, "score": {"components": {"activity": 0, "longevity": 100, "rhythm": 35}, "computed_at": "2026-09-03T02:20:16.233290+00:00", "flags": ["no_releases"], "formula": "round(0.45*activity + 0.35*rhythm + 0.20*longevity); archived -> min(score, 10)", "inputs": {"age_days": 3175, "days_push": 1322, "days_rel": null, "gap_med": null, "n_releases_24m": 0}, "score": 32, "version": 2}, "staleness": {"enrichment_outdated": false, "low_confidence": false, "scrape_days": 9, "stale_scrape": false}}