Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .chocolatey/codeshellmanager.nuspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>codeshellmanager</id>
<version>__VERSION__</version>
<packageSourceUrl>https://github.com/umage-ai/CodeShellManager/tree/main/.chocolatey</packageSourceUrl>
<owners>umage.ai</owners>
<title>CodeShellManager</title>
<authors>umage.ai</authors>
<projectUrl>https://umage.ai/products/code-shell-manager/</projectUrl>
<iconUrl>https://raw.githubusercontent.com/umage-ai/CodeShellManager/main/src/CodeShellManager/Assets/app.ico</iconUrl>
<copyright>Copyright (c) 2025 umage.ai</copyright>
<licenseUrl>https://github.com/umage-ai/CodeShellManager/blob/main/LICENSE</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/umage-ai/CodeShellManager</projectSourceUrl>
<docsUrl>https://github.com/umage-ai/CodeShellManager#readme</docsUrl>
<bugTrackerUrl>https://github.com/umage-ai/CodeShellManager/issues</bugTrackerUrl>
<tags>codeshellmanager terminal claude claude-code wpf conpty xterm ai coding-agent admin</tags>
<summary>Multi-terminal host for Claude Code and other CLI coding agents on Windows.</summary>
<description><![CDATA[
**CodeShellManager** is a Windows desktop app for running multiple AI coding agents side-by-side — Claude Code, Codex, GitHub Copilot, or any CLI tool — in a tabbed and grid-layout terminal host. Built with WPF, xterm.js, and Windows ConPTY for full pseudo-terminal fidelity.

## Features

* Multi-terminal grid — up to 18 sessions simultaneously in configurable layouts
* Sleep & wake — park sessions without losing them
* Full-text search across every session, ever (SQLite FTS5)
* Per-project notepad, alert detection, git status, session rename, auto-resume
* SSH remote sessions, session history, configurable launch commands
* Tray icon with balloon notifications

## Requirements

* Windows 10 (1903+) or Windows 11
* [Microsoft Edge WebView2 Runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) (pre-installed on Windows 11)
]]></description>
<releaseNotes>https://github.com/umage-ai/CodeShellManager/releases/tag/v__VERSION__</releaseNotes>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
23 changes: 23 additions & 0 deletions .chocolatey/tools/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -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.
34 changes: 34 additions & 0 deletions .chocolatey/tools/VERIFICATION.txt
Original file line number Diff line number Diff line change
@@ -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-<version>-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
23 changes: 23 additions & 0 deletions .chocolatey/tools/chocolateyinstall.ps1
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions .chocolatey/tools/chocolateyuninstall.ps1
Original file line number Diff line number Diff line change
@@ -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)" }
}
112 changes: 112 additions & 0 deletions .github/workflows/chocolatey.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ The tag value overrides the csproj `<Version>` 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
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Build](https://github.com/umage-ai/CodeShellManager/actions/workflows/build.yml/badge.svg)](https://github.com/umage-ai/CodeShellManager/actions/workflows/build.yml)
[![Latest Release](https://img.shields.io/github/v/release/umage-ai/CodeShellManager?label=download&cacheSeconds=3600)](https://github.com/umage-ai/CodeShellManager/releases/latest)
[![winget](https://img.shields.io/winget/v/UmageAI.CodeShellManager?label=winget)](https://winstall.app/apps/UmageAI.CodeShellManager)
[![Chocolatey](https://img.shields.io/chocolatey/v/codeshellmanager?label=chocolatey)](https://community.chocolatey.org/packages/codeshellmanager)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

> **🌐 [umage.ai/products/code-shell-manager](https://umage.ai/products/code-shell-manager/)** — product page, screenshots, and latest news
Expand Down Expand Up @@ -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)
Expand Down
Loading