44 Build a self-contained beautiCode Windows installer.
55
66. DESCRIPTION
7- Builds TypeScript, stages only runtime files, downloads and verifies the
8- official Node.js Windows x64 runtime, then compiles an Inno Setup installer.
7+ Builds TypeScript, stages both host adapters, downloads and verifies the
8+ official Node.js Windows x64 runtime, installs the integrity-pinned DSH into
9+ a private bundle, then compiles an Inno Setup installer.
910#>
1011[CmdletBinding ()]
1112param (
1213 [ValidatePattern (" ^\d+\.\d+\.\d+$" )]
1314 [string ]$NodeVersion = " 24.18.0" ,
14- [string ]$InnoCompiler = " "
15+ [string ]$InnoCompiler = " " ,
16+ [string ]$DshRuntimeCache = " "
1517)
1618
1719$ErrorActionPreference = " Stop"
@@ -20,6 +22,11 @@ $ArtifactsRoot = Join-Path $RepoRoot "artifacts\windows"
2022$StageRoot = Join-Path $ArtifactsRoot " stage"
2123$CacheRoot = Join-Path $ArtifactsRoot " cache"
2224$OutputRoot = Join-Path $ArtifactsRoot " installer"
25+ $DshCacheRoot = if ($DshRuntimeCache ) {
26+ [IO.Path ]::GetFullPath($DshRuntimeCache )
27+ } else {
28+ Join-Path $CacheRoot " dsh-runtime"
29+ }
2330$InstallerScript = Join-Path $RepoRoot " installer\windows\beauticode.iss"
2431$PinnedNodeVersion = " 24.18.0"
2532$PinnedNodeArchiveSha256 = " 0ae68406b42d7725661da979b1403ec9926da205c6770827f33aac9d8f26e821"
@@ -36,6 +43,17 @@ function Assert-WorkspaceChild([string]$Path) {
3643 }
3744}
3845
46+ function Get-Sha256Hex ([string ]$Path ) {
47+ $stream = [System.IO.File ]::OpenRead($Path )
48+ $sha256 = [System.Security.Cryptography.SHA256 ]::Create()
49+ try {
50+ return ([System.BitConverter ]::ToString($sha256.ComputeHash ($stream ))).Replace(" -" , " " ).ToLowerInvariant()
51+ } finally {
52+ $sha256.Dispose ()
53+ $stream.Dispose ()
54+ }
55+ }
56+
3957function Reset-Directory ([string ]$Path ) {
4058 Assert-WorkspaceChild $Path
4159 if (Test-Path - LiteralPath $Path ) {
@@ -144,6 +162,12 @@ if (-not (Test-Path -LiteralPath $InstallerScript -PathType Leaf)) {
144162
145163$package = Get-Content - Raw - LiteralPath (Join-Path $RepoRoot " package.json" ) |
146164 ConvertFrom-Json
165+ $compatibility = Get-Content - Raw - LiteralPath (
166+ Join-Path $RepoRoot " integrations\deepseek-harness\compatibility.json"
167+ ) | ConvertFrom-Json
168+ if ($compatibility.schema -ne " beauticode.dsh-compatibility/v1" ) {
169+ throw " DSH compatibility manifest is invalid."
170+ }
147171$appVersion = [string ]$package.version
148172if ($appVersion -notmatch " ^\d+\.\d+\.\d+$" ) {
149173 throw (" Installer requires a numeric three-part package version: {0}" -f $appVersion )
@@ -177,7 +201,7 @@ if (-not $checksumLine) {
177201 throw (" Official checksum was not found for {0}" -f $nodeArchiveName )
178202}
179203$expectedHash = ($checksumLine -split " \s+" )[0 ].ToLowerInvariant()
180- $actualHash = ( Get-FileHash - Algorithm SHA256 - LiteralPath $nodeArchive ).Hash.ToLowerInvariant()
204+ $actualHash = Get-Sha256Hex $nodeArchive
181205if ($actualHash -ne $expectedHash ) {
182206 throw (" Node.js archive checksum mismatch: expected {0}, got {1}" -f $expectedHash , $actualHash )
183207}
@@ -196,9 +220,12 @@ foreach ($relativeDir in @(
196220 " scripts" ,
197221 " packages\core" ,
198222 " packages\adapter-codex" ,
223+ " packages\adapter-dsh" ,
224+ " integrations\deepseek-harness" ,
199225 " node_modules\@beauticode\core" ,
200226 " runtime" ,
201- " licenses\node"
227+ " licenses\node" ,
228+ " licenses\dsh"
202229 )) {
203230 New-Item - ItemType Directory - Path (Join-Path $StageRoot $relativeDir ) - Force | Out-Null
204231}
@@ -208,9 +235,16 @@ foreach ($relativeFile in @(
208235 " apps\tray\start-tray.ps1" ,
209236 " assets\beauticode-icon-borderless.png" ,
210237 " scripts\codex-launch.ps1" ,
238+ " scripts\start-beauticode.ps1" ,
211239 " scripts\start-beauticode-engine.ps1" ,
240+ " scripts\start-beauticode-dsh.ps1" ,
241+ " scripts\install-dsh-runtime.ps1" ,
212242 " packages\core\package.json" ,
213243 " packages\adapter-codex\package.json" ,
244+ " packages\adapter-dsh\package.json" ,
245+ " integrations\deepseek-harness\index.mjs" ,
246+ " integrations\deepseek-harness\client.js" ,
247+ " integrations\deepseek-harness\compatibility.json" ,
214248 " LICENSE" ,
215249 " NOTICE.md" ,
216250 " THIRD_PARTY_NOTICES.md"
@@ -229,6 +263,9 @@ Copy-RuntimeDirectory `
229263Copy-RuntimeDirectory `
230264 (Join-Path $RepoRoot " packages\adapter-codex\dist" ) `
231265 (Join-Path $StageRoot " packages\adapter-codex\dist" )
266+ Copy-RuntimeDirectory `
267+ (Join-Path $RepoRoot " packages\adapter-dsh\dist" ) `
268+ (Join-Path $StageRoot " packages\adapter-dsh\dist" )
232269Copy-Item - LiteralPath (Join-Path $RepoRoot " packages\core\package.json" ) `
233270 - Destination (Join-Path $StageRoot " node_modules\@beauticode\core\package.json" ) - Force
234271Copy-RuntimeDirectory `
@@ -240,6 +277,18 @@ Copy-Item -LiteralPath (Join-Path $nodeDistribution "node.exe") `
240277Copy-Item - LiteralPath (Join-Path $nodeDistribution " LICENSE" ) `
241278 - Destination (Join-Path $StageRoot " licenses\node\LICENSE" ) - Force
242279
280+ & (Join-Path $RepoRoot " scripts\install-dsh-runtime.ps1" ) `
281+ - InstallRoot $DshCacheRoot `
282+ - CompatibilityFile (Join-Path $RepoRoot " integrations\deepseek-harness\compatibility.json" ) `
283+ - NodeCommand (Join-Path $StageRoot " runtime\node.exe" ) `
284+ - NpmCommand ((Get-Command npm.cmd - ErrorAction Stop).Source)
285+ Copy-RuntimeDirectory $DshCacheRoot (Join-Path $StageRoot " runtime\dsh" )
286+ $dshLicense = Join-Path $StageRoot " runtime\dsh\versions\$ ( $compatibility.supportedVersion ) \node_modules\@deepseek-ai\dsh\LICENSE"
287+ if (-not (Test-Path - LiteralPath $dshLicense - PathType Leaf)) {
288+ throw " Staged DSH license is missing."
289+ }
290+ Copy-Item - LiteralPath $dshLicense - Destination (Join-Path $StageRoot " licenses\dsh\LICENSE" ) - Force
291+
243292New-InstallerIcon `
244293 (Join-Path $RepoRoot " assets\beauticode-icon-borderless.png" ) `
245294 (Join-Path $StageRoot " beauticode.ico" )
@@ -250,6 +299,8 @@ $manifest = [ordered]@{
250299 schema = " beauticode.release/v1"
251300 appVersion = $appVersion
252301 nodeVersion = $NodeVersion
302+ dshVersion = [string ]$compatibility.supportedVersion
303+ dshBridgeProtocol = [int ]$compatibility.bridgeProtocol
253304 platform = " win-x64"
254305 commit = $commit
255306 dirty = ($trackedChanges.Count -gt 0 )
@@ -271,6 +322,19 @@ $adapterProbe = & $stagedNode --input-type=module -e `
271322if ($LASTEXITCODE -ne 0 -or $adapterProbe -ne " function" ) {
272323 throw (" Staged adapter import failed: {0}" -f $adapterProbe )
273324}
325+ $dshAdapterUrl = ([System.Uri ](Join-Path $StageRoot " packages\adapter-dsh\dist\index.js" )).AbsoluteUri
326+ $dshAdapterProbe = & $stagedNode -- input- type= module - e `
327+ " const m=await import(process.argv[1]); console.log(typeof m.DshSession);" `
328+ $dshAdapterUrl
329+ if ($LASTEXITCODE -ne 0 -or $dshAdapterProbe -ne " function" ) {
330+ throw (" Staged DSH adapter import failed: {0}" -f $dshAdapterProbe )
331+ }
332+ $dshManifest = Get-Content - Raw - LiteralPath (Join-Path $StageRoot " runtime\dsh\current.json" ) | ConvertFrom-Json
333+ $dshCli = Join-Path (Join-Path $StageRoot " runtime\dsh" ) ([string ]$dshManifest.cli )
334+ $stagedDshVersion = (& $stagedNode $dshCli -- version).Trim()
335+ if ($LASTEXITCODE -ne 0 -or $stagedDshVersion -ne [string ]$compatibility.supportedVersion ) {
336+ throw (" Staged DSH version mismatch: expected {0}, got {1}" -f $compatibility.supportedVersion , $stagedDshVersion )
337+ }
274338
275339$iscc = Resolve-InnoCompiler $InnoCompiler
276340& $iscc `
@@ -289,8 +353,8 @@ if (-not $installer) {
289353 throw " Inno Setup completed without producing an installer."
290354}
291355
292- $installerHash = Get-FileHash - Algorithm SHA256 - LiteralPath $installer.FullName
356+ $installerHash = Get-Sha256Hex $installer.FullName
293357Write-Host " "
294358Write-Host " Windows installer created:"
295359Write-Host (" {0}" -f $installer.FullName )
296- Write-Host (" SHA256 {0}" -f $installerHash.Hash )
360+ Write-Host (" SHA256 {0}" -f $installerHash.ToUpperInvariant () )
0 commit comments