diff --git a/.chocolatey/codeshellmanager.nuspec b/.chocolatey/codeshellmanager.nuspec
new file mode 100644
index 0000000..dba8321
--- /dev/null
+++ b/.chocolatey/codeshellmanager.nuspec
@@ -0,0 +1,42 @@
+
+
+
+ codeshellmanager
+ __VERSION__
+ https://github.com/umage-ai/CodeShellManager/tree/main/.chocolatey
+ umage.ai
+ CodeShellManager
+ umage.ai
+ https://umage.ai/products/code-shell-manager/
+ https://raw.githubusercontent.com/umage-ai/CodeShellManager/main/src/CodeShellManager/Assets/app.ico
+ Copyright (c) 2025 umage.ai
+ https://github.com/umage-ai/CodeShellManager/blob/main/LICENSE
+ false
+ https://github.com/umage-ai/CodeShellManager
+ https://github.com/umage-ai/CodeShellManager#readme
+ https://github.com/umage-ai/CodeShellManager/issues
+ codeshellmanager terminal claude claude-code wpf conpty xterm ai coding-agent admin
+ Multi-terminal host for Claude Code and other CLI coding agents on Windows.
+
+ https://github.com/umage-ai/CodeShellManager/releases/tag/v__VERSION__
+
+
+
+
+
diff --git a/.chocolatey/tools/LICENSE.txt b/.chocolatey/tools/LICENSE.txt
new file mode 100644
index 0000000..33ded07
--- /dev/null
+++ b/.chocolatey/tools/LICENSE.txt
@@ -0,0 +1,23 @@
+From: https://github.com/umage-ai/CodeShellManager/blob/main/LICENSE
+
+MIT License
+
+Copyright (c) 2025 umage.ai
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/.chocolatey/tools/VERIFICATION.txt b/.chocolatey/tools/VERIFICATION.txt
new file mode 100644
index 0000000..4e2a034
--- /dev/null
+++ b/.chocolatey/tools/VERIFICATION.txt
@@ -0,0 +1,34 @@
+VERIFICATION
+
+Verification is intended to assist Chocolatey moderators and end-users in
+verifying that this package's contents are authentic.
+
+This Chocolatey package downloads the official signed MSI installer from the
+matching CodeShellManager GitHub Release:
+
+ https://github.com/umage-ai/CodeShellManager/releases
+
+The MSI is built and signed by GitHub Actions from the source in
+https://github.com/umage-ai/CodeShellManager (see .github/workflows/build.yml)
+using Azure Trusted Signing — publisher: umage.ai.
+
+To verify the package independently:
+
+1. Note the embedded download URL and SHA256 checksum in
+ tools\chocolateyinstall.ps1 (variables $url64 and $checksum64).
+
+2. Download the same MSI directly from the GitHub Release page above.
+
+3. On Windows, compute the SHA256 of the downloaded file:
+
+ Get-FileHash -Algorithm SHA256 .\CodeShellManager--Setup.msi
+
+ The output should match the $checksum64 value in chocolateyinstall.ps1.
+
+4. Optionally inspect the Authenticode signature on the MSI — it should be
+ issued to "umage.ai" via Microsoft's Azure Trusted Signing service.
+
+The bundled LICENSE.txt is a verbatim copy of the project license, also
+available at:
+
+ https://github.com/umage-ai/CodeShellManager/blob/main/LICENSE
diff --git a/.chocolatey/tools/chocolateyinstall.ps1 b/.chocolatey/tools/chocolateyinstall.ps1
new file mode 100644
index 0000000..f89ccdd
--- /dev/null
+++ b/.chocolatey/tools/chocolateyinstall.ps1
@@ -0,0 +1,23 @@
+$ErrorActionPreference = 'Stop'
+
+$packageName = 'codeshellmanager'
+$toolsDir = "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)"
+
+# These placeholders are replaced by .github/workflows/chocolatey.yml at pack time
+# with the version-pinned MSI URL and its SHA256 from the GitHub Release.
+$url64 = '__URL64__'
+$checksum64 = '__CHECKSUM64__'
+
+$packageArgs = @{
+ packageName = $packageName
+ unzipLocation = $toolsDir
+ fileType = 'msi'
+ url64bit = $url64
+ softwareName = 'CodeShellManager*'
+ checksum64 = $checksum64
+ checksumType64 = 'sha256'
+ silentArgs = '/qn /norestart /l*v "$($env:TEMP)\$($packageName).$($env:chocolateyPackageVersion).MsiInstall.log"'
+ validExitCodes = @(0, 3010, 1641)
+}
+
+Install-ChocolateyPackage @packageArgs
diff --git a/.chocolatey/tools/chocolateyuninstall.ps1 b/.chocolatey/tools/chocolateyuninstall.ps1
new file mode 100644
index 0000000..4b9d1cc
--- /dev/null
+++ b/.chocolatey/tools/chocolateyuninstall.ps1
@@ -0,0 +1,28 @@
+$ErrorActionPreference = 'Stop'
+
+$packageName = 'codeshellmanager'
+$softwareName = 'CodeShellManager*'
+
+# Discover the install record (MSI product code) registered for the
+# installed CodeShellManager and uninstall via msiexec.
+$key = Get-UninstallRegistryKey -SoftwareName $softwareName
+
+if ($key.Count -eq 1) {
+ $packageArgs = @{
+ packageName = $packageName
+ fileType = 'msi'
+ silentArgs = "$($key.PSChildName) /qn /norestart"
+ validExitCodes = @(0, 3010, 1605, 1614, 1641)
+ file = ''
+ }
+ Uninstall-ChocolateyPackage @packageArgs
+}
+elseif ($key.Count -eq 0) {
+ Write-Warning "$packageName has already been uninstalled by other means."
+}
+elseif ($key.Count -gt 1) {
+ Write-Warning "$($key.Count) matches found!"
+ Write-Warning "To prevent accidental data loss, no programs will be uninstalled."
+ Write-Warning "Please alert package maintainer the following keys were matched:"
+ $key | ForEach-Object { Write-Warning "- $($_.DisplayName)" }
+}
diff --git a/.github/workflows/chocolatey.yml b/.github/workflows/chocolatey.yml
new file mode 100644
index 0000000..41ad678
--- /dev/null
+++ b/.github/workflows/chocolatey.yml
@@ -0,0 +1,112 @@
+name: Publish to Chocolatey
+
+# Packs and pushes a Chocolatey package wrapping the signed MSI from a GitHub Release
+# to community.chocolatey.org.
+# - `release` event fires automatically when CI / Release publishes the GitHub Release.
+# - `workflow_dispatch` lets us re-publish a past version (used for the first
+# submission once this workflow exists on main).
+#
+# Requires repo secret CHOCO_API_KEY (from https://community.chocolatey.org/account)
+# scoped to push for package id `codeshellmanager`.
+
+on:
+ release:
+ types: [released]
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: 'Release tag to publish (e.g. v0.5.0)'
+ required: true
+ type: string
+
+permissions:
+ contents: read
+
+jobs:
+ publish:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: Resolve tag and version
+ id: ver
+ shell: pwsh
+ run: |
+ $tag = '${{ inputs.tag }}'
+ if (-not $tag) { $tag = '${{ github.event.release.tag_name }}' }
+ if (-not $tag) { Write-Error 'No release tag resolved.'; exit 1 }
+ $version = $tag.TrimStart('v')
+ "tag=$tag" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+ "version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+ Write-Host "Publishing tag=$tag version=$version"
+
+ - name: Download signed MSI from GitHub Release
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: |
+ $tag = '${{ steps.ver.outputs.tag }}'
+ $version = '${{ steps.ver.outputs.version }}'
+ $msiName = "CodeShellManager-$version-Setup.msi"
+ New-Item -ItemType Directory -Force -Path artifact | Out-Null
+ gh release download $tag --repo umage-ai/CodeShellManager --pattern $msiName --dir artifact
+ if (-not (Test-Path "artifact\$msiName")) {
+ Write-Error "MSI $msiName not found in release $tag."
+ exit 1
+ }
+ Write-Host "Downloaded artifact\$msiName"
+
+ - name: Template version, URL, and checksum into package
+ shell: pwsh
+ run: |
+ $version = '${{ steps.ver.outputs.version }}'
+ $msiName = "CodeShellManager-$version-Setup.msi"
+ $url64 = "https://github.com/umage-ai/CodeShellManager/releases/download/v$version/$msiName"
+ $sha256 = (Get-FileHash "artifact\$msiName" -Algorithm SHA256).Hash.ToLowerInvariant()
+ Write-Host "URL: $url64"
+ Write-Host "SHA256: $sha256"
+
+ $installPs1 = '.chocolatey/tools/chocolateyinstall.ps1'
+ (Get-Content $installPs1 -Raw).
+ Replace('__URL64__', $url64).
+ Replace('__CHECKSUM64__', $sha256) |
+ Set-Content -Path $installPs1 -NoNewline
+
+ $nuspec = '.chocolatey/codeshellmanager.nuspec'
+ (Get-Content $nuspec -Raw).
+ Replace('__VERSION__', $version) |
+ Set-Content -Path $nuspec -NoNewline
+
+ Write-Host '--- chocolateyinstall.ps1 ---'
+ Get-Content $installPs1
+ Write-Host '--- codeshellmanager.nuspec ---'
+ Get-Content $nuspec
+
+ - name: choco pack
+ shell: pwsh
+ run: |
+ choco pack .chocolatey/codeshellmanager.nuspec --out artifact
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+ Get-ChildItem artifact\*.nupkg
+
+ - name: choco push
+ shell: pwsh
+ env:
+ CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
+ run: |
+ $version = '${{ steps.ver.outputs.version }}'
+ $nupkg = "artifact/codeshellmanager.$version.nupkg"
+ if (-not (Test-Path $nupkg)) {
+ Write-Error "Expected nupkg not found: $nupkg"
+ exit 1
+ }
+ choco push $nupkg --source https://push.chocolatey.org/ --api-key $env:CHOCO_API_KEY
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+
+ - name: Upload built nupkg as workflow artifact
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: codeshellmanager-chocolatey-${{ steps.ver.outputs.version }}
+ path: artifact/*.nupkg
+ if-no-files-found: warn
diff --git a/CLAUDE.md b/CLAUDE.md
index c53798b..f4b6f42 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -263,6 +263,8 @@ The tag value overrides the csproj `` at publish time (`-p:Version=` fl
A second workflow, `.github/workflows/winget.yml`, fires on the `release: released` event and submits the signed MSI to microsoft/winget-pkgs as `UmageAI.CodeShellManager` via [vedantmgoyal9/winget-releaser](https://github.com/vedantmgoyal9/winget-releaser). It needs the repo secret `WINGET_TOKEN` (classic PAT, `public_repo` scope). The same workflow is `workflow_dispatch`-able with a `tag` input to backfill or retry a release.
+A third workflow, `.github/workflows/chocolatey.yml`, also fires on `release: released` and publishes the signed MSI to community.chocolatey.org as `codeshellmanager`. It downloads the MSI from the GitHub Release, computes its SHA256, substitutes `__URL64__` / `__CHECKSUM64__` placeholders in `.chocolatey/tools/chocolateyinstall.ps1`, then runs `choco pack` and `choco push`. Needs the repo secret `CHOCO_API_KEY` (API key from a chocolatey.org account with push rights on the `codeshellmanager` id). Also `workflow_dispatch`-able with a `tag` input. The `.chocolatey/` folder holds the package skeleton (`codeshellmanager.nuspec`, `tools/chocolateyinstall.ps1`, `tools/chocolateyuninstall.ps1`, `tools/LICENSE.txt`, `tools/VERIFICATION.txt`); never commit a resolved URL or checksum into the install script — those placeholders are only substituted by the workflow at pack time.
+
## Known Conventions
- All WPF color literals use Catppuccin Mocha hex values — do not introduce system colors
diff --git a/README.md b/README.md
index 861b01c..ef1eb53 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[](https://github.com/umage-ai/CodeShellManager/actions/workflows/build.yml)
[](https://github.com/umage-ai/CodeShellManager/releases/latest)
[](https://winstall.app/apps/UmageAI.CodeShellManager)
+[](https://community.chocolatey.org/packages/codeshellmanager)
[](LICENSE)
> **🌐 [umage.ai/products/code-shell-manager](https://umage.ai/products/code-shell-manager/)** — product page, screenshots, and latest news
@@ -49,6 +50,14 @@ winget install UmageAI.CodeShellManager
Future updates pick up automatically with `winget upgrade UmageAI.CodeShellManager` (or `winget upgrade --all`).
+### Chocolatey
+
+```powershell
+choco install codeshellmanager
+```
+
+Upgrade with `choco upgrade codeshellmanager` (or `choco upgrade all`).
+
### Download from Releases
1. Go to [**Releases**](https://github.com/umage-ai/CodeShellManager/releases/latest)