{"id":50119170,"url":"https://github.com/depthbomb/kit","last_synced_at":"2026-05-23T18:01:00.037Z","repository":{"id":359740108,"uuid":"1247305742","full_name":"depthbomb/Kit","owner":"depthbomb","description":"A Windows bootstrapper and release tooling set for self-updating desktop apps.","archived":false,"fork":false,"pushed_at":"2026-05-23T07:15:05.000Z","size":1064,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-23T09:20:11.422Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/depthbomb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T06:23:05.000Z","updated_at":"2026-05-23T07:15:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/depthbomb/Kit","commit_stats":null,"previous_names":["depthbomb/kit"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/depthbomb/Kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depthbomb%2FKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depthbomb%2FKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depthbomb%2FKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depthbomb%2FKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/depthbomb","download_url":"https://codeload.github.com/depthbomb/Kit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depthbomb%2FKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33406444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-23T18:00:32.459Z","updated_at":"2026-05-23T18:01:00.028Z","avatar_url":"https://github.com/depthbomb.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kit\n\nA Windows bootstrapper and release tooling set for self-updating desktop apps.\n\nIt consists of:\n\n- `Kit.Updater`: a .NET Framework 4.8 WinForms bootstrapper that reads a stamped configuration payload from its own executable, checks for updates, installs app payloads, and launches the app.\n- `Kit.Cli`: a CLI used to stamp the updater binary and generate release artifacts during packaging or CI/CD.\n\n## What The Project Currently Supports\n\n- Stamping a blank updater executable with app metadata and embedded branding assets\n- Checking for updates from either GitHub Releases or a hosted JSON manifest\n- Optional, required, and minimum-version-required update policies\n- Fresh install when no local `app-*` folder exists and `allowFreshInstall` is enabled\n- ZIP extraction built in, with optional `.7z` support when `bin\\7za.exe` is shipped next to the updater\n- SHA-256 verification of downloaded payloads\n- Optional post-install command execution\n- Optional NTFS compression of extracted files\n- Optional installation of required .NET runtimes\n- Optional installation of Windows App Runtime\n- Updater-refresh releases via an external installer plus `release-manifest.json`\n\n## CLI Commands\n\nThe CLI exposes four commands:\n\n```text\nkit stamp --input \u003cblank-bootstrapper.exe\u003e --config \u003cstamp-config.json\u003e [--output \u003cstamped-bootstrapper.exe\u003e]\nkit inspect --input \u003cstamped-bootstrapper.exe\u003e\nkit manifest --version \u003crelease-version\u003e --updater \u003cstamped-updater.exe\u003e --package \u003capp-package.zip\u003e --installer \u003cupdater-refresh-installer.exe\u003e [--output \u003coutput-directory\u003e] [--updater-update-required \u003ctrue|false\u003e]\nkit release --app-dir \u003capp-dir-path\u003e --config \u003cstamp-config.json\u003e --updater \u003cblank-updater.exe\u003e [--version \u003crelease-version\u003e] [--output-dir \u003coutput-dir-path\u003e] [--package-name \u003capp-package.zip\u003e] [--updater-update-required \u003ctrue|false\u003e] [--installer-command \u003ccommand\u003e] [--installer-args \u003cargs\u003e] [--installer-path \u003cinstaller-path\u003e]\n```\n\n### `stamp`\n\nWrites the stamped updater executable. If `--output` is omitted, the input file is overwritten.\n\n```powershell\n.\\kit.exe stamp `\n  --input .\\Kit.Updater\\bin\\Release\\net48\\Kit.Updater.exe `\n  --config .\\stamp-config.sample.json `\n  --output .\\out\\MyApp-Updater.exe\n```\n\n### `inspect`\n\nReads the stamped updater payload and prints the embedded configuration as formatted JSON.\n\n```powershell\n.\\kit.exe inspect `\n  --input .\\out\\MyApp-Updater.exe\n```\n\n### `manifest`\n\nBuilds `release-manifest.json` in the target output directory. The manifest always contains the application package. The installer package is only valid when `--updater-update-required true`.\n\n```powershell\n.\\kit.exe manifest `\n  --version 1.1.0 `\n  --updater .\\out\\MyApp-Updater.exe `\n  --package .\\artifacts\\MyApp-1.1.0.zip `\n  --installer .\\artifacts\\MyApp-1.1.0-setup.exe `\n  --output .\\artifacts `\n  --updater-update-required false\n```\n\n### `release`\n\nRuns the end-to-end release flow:\n\n1. Reads the stamp config.\n2. Auto-detects the app version from `launchExecutable` unless `--version` is supplied.\n3. Zips `--app-dir`.\n4. Stamps the updater in place.\n5. Optionally runs an installer build command.\n6. Writes `release-manifest.json`.\n\nExample:\n\n```powershell\n.\\kit.exe release `\n  --app-dir .\\publish\\MyApp `\n  --config .\\stamp-config.sample.json `\n  --updater .\\Kit.Updater\\bin\\Release\\net48\\Kit.Updater.exe `\n  --output-dir .\\artifacts `\n  --package-name MyApp.zip `\n  --installer-command \"iscc.exe\" `\n  --installer-args \".\\installer.iss /DAppVersion={Version} /DOutputDir={OutputDir}\" `\n  --installer-path \"{OutputDir}\\MyApp-Setup.exe\"\n```\n\n## Stamp Configuration\n\nUse **stamp-config.sample.json** as the reference template.\n\nCurrent top-level fields:\n\n- `applicationName` required\n- `initialVersion` required\n- `launchExecutable` required\n- `launchArguments` optional\n- `bannerImagePath` optional\n- `windowIconPath` optional, must point to an `.ico`\n- `requiresAppRuntime` optional\n- `appearance` optional\n- `text` optional\n- `installation` optional\n- `updatePolicy` optional\n- `requiredRuntimes` optional\n- `updateSource` required\n\nExample:\n\n```json\n{\n  \"applicationName\": \"My App\",\n  \"initialVersion\": \"1.0.0\",\n  \"launchExecutable\": \"MyApp.exe\",\n  \"launchArguments\": \"\",\n  \"bannerImagePath\": \"assets/banner.png\",\n  \"windowIconPath\": \"assets/app.ico\",\n  \"requiresAppRuntime\": false,\n  \"appearance\": {\n    \"useDarkMode\": true,\n    \"useDarkTitleBar\": true,\n    \"backgroundColor\": \"#202020\",\n    \"foregroundColor\": \"#f5f5f5\",\n    \"secondaryTextColor\": \"#d2d2d2\",\n    \"bannerBackgroundColor\": \"#161616\"\n  },\n  \"text\": {\n    \"windowTitle\": \"{ApplicationName} Launcher\",\n    \"title\": \"{ApplicationName}\"\n  },\n  \"installation\": {\n    \"requireIntegrityVerification\": true,\n    \"processName\": \"MyApp\",\n    \"keepLastVersions\": 3,\n    \"extractionLayout\": \"auto\",\n    \"postInstallCommand\": \"postinstall.cmd\",\n    \"postInstallArguments\": \"\\\"{AppDirectory}\\\" {Version}\",\n    \"allowFreshInstall\": true,\n    \"compressFiles\": true\n  },\n  \"updatePolicy\": {\n    \"mode\": \"optional\",\n    \"minimumVersion\": \"\"\n  },\n  \"requiredRuntimes\": [\n    {\n      \"name\": \"Microsoft.WindowsDesktop.App\",\n      \"version\": \"6.0.0\",\n      \"type\": \"windowsdesktop-runtime\"\n    }\n  ],\n  \"updateSource\": {\n    \"type\": \"github\",\n    \"repository\": \"owner/repo\",\n    \"includePrerelease\": false\n  }\n}\n```\n\n### `installation.extractionLayout`\n\nSupported values:\n\n- `auto`\n- `direct`\n- `strip-single-root-directory`\n\n`auto` tries the archive root first and otherwise falls back to a single top-level directory when one exists.\n\n### `installation.compressFiles`\n\nWhen omitted, `compressFiles` defaults to `true`.\n\nCompression is applied when the updater installs files from a downloaded package, including fresh installs and normal update installs.\n\n### `updatePolicy.mode`\n\nSupported values:\n\n- `optional`\n- `required`\n- `minimum-version-required`\n\nWhen `minimum-version-required` is used, `minimumVersion` must be a valid version string.\n\n### `updateSource`\n\nSupported source types:\n\n- `github`\n- `json`\n\nFor `github`, configure:\n\n- `repository`: `owner/repo`\n- `includePrerelease`: optional\n\nFor `json`, configure:\n\n- `url`: absolute manifest URL\n\n## Release Manifest\n\nThe updater expects a manifest named `release-manifest.json`.\n\nCurrent manifest shape:\n\n```json\n{\n  \"applicationName\": \"My App\",\n  \"version\": \"1.1.0\",\n  \"updaterUpdateRequired\": false,\n  \"download\": {\n    \"kind\": \"application\",\n    \"fileName\": \"MyApp-1.1.0.zip\",\n    \"sha256\": \"...\"\n  },\n  \"applicationPackage\": {\n    \"kind\": \"application\",\n    \"fileName\": \"MyApp-1.1.0.zip\",\n    \"sha256\": \"...\"\n  },\n  \"updaterPackage\": {\n    \"kind\": \"installer\",\n    \"fileName\": \"MyApp-1.1.0-setup.exe\",\n    \"sha256\": \"...\"\n  }\n}\n```\n\nBehavior:\n\n- If `updaterUpdateRequired` is `false`, `download` points at the normal app package.\n- If `updaterUpdateRequired` is `true`, `download` points at the updater-refresh installer.\n- After an updater-refresh install, the stamped `updaterVersion` prevents the updater from looping back into the same installer release and allows it to fall back to the app package from the same manifest.\n\nFor GitHub sources, the updater reads the latest eligible release, looks for a `release-manifest.json` asset, then resolves the referenced package asset by file name.\n\nFor JSON sources, relative `fileName` values are resolved relative to the manifest URL.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepthbomb%2Fkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdepthbomb%2Fkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepthbomb%2Fkit/lists"}