Files
Genarrative/apps/ai-game-creator-shell/scripts/read-installed-node-license.ps1
T
kdletters 8a8d94c14a
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 16s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 18s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 16s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 12s
Project CI / AI game creator shell Rust crates (pull_request) Failing after 16s
Project CI / Backend tests (pull_request) Failing after 21s
Project CI / Native shell tests (pull_request) Failing after 20s
Project CI / Frontend tests (pull_request) Failing after 8s
Project CI / AI game creator shell web tests (pull_request) Failing after 17s
Project CI / Repository checks (pull_request) Failing after 17s
AGC 七项交付效率优化并升级捆绑 Codex 到 0.155.1
- 自动环境预检接入首页与 Direct 后端:新建 Web 游戏在生成前完成 Node/npm、真实构建与双端浏览器检查
- 新增宿主权威执行账本与交付合同:冻结核验项、绑定当前输入证据、封口后拒绝新副作用并产出宿主报告
- 原生 shell、内置浏览器/托管命令与第三方 MCP 共用执行许可和累计执行时间预算,按执行批次与墙钟分别约束
- 新增固定种子 runner 物理基线、真实双端输入与公平窗口负例,可复用且不冒充完整关卡
- 新增请求与工具分段计时、有界并行批读和首轮上下文预取,未知耗时不补零
- 移除 SDK 全局串行的 apply_patch/update_plan 注册,改由宿主 agc_apply_patch/agc_update_plan 提供等价能力,独立工具可并发
- 付费提交与本地写入绑定原回合租约:封口、取消或耗尽后零新增提交,已受理操作保留 GET 对账
- 捆绑 Codex 由 0.147.0 升级到 0.155.1,固定版本收敛到 build_support/codex_bundle.rs,vendor 解析源码按 rust-v0.155.1 重取并更新 UPSTREAM 证据
- 适配 0.155 统一 exec(exec_command/write_stdin),生产夹具新增会话用例,宿主 Job 与期限约束保持有效
- 同步更新 AGC 主规范、Skill 与提示词、共享记忆和发行载荷校验
2026-09-21 00:59:41 +08:00

96 lines
5.5 KiB
PowerShell

# 只读取 Windows Installer 已登记的同版本 Node.js 缓存;不执行安装、不访问网络。
$ErrorActionPreference = 'Stop'
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
$expectedVersion = $env:AGC_STAGING_NODE_VERSION
if ($expectedVersion -notmatch '^\d+\.\d+\.\d+$') { throw 'Invalid Node version' }
# WinVerifyTrust 强制仅使用本地证书缓存,禁止吊销/证书 URL 网络检索。
Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;
public static class AgcOfflineSignature {
[StructLayout(LayoutKind.Sequential)]
struct FileInfo { public uint Size; public IntPtr Path; public IntPtr File; public IntPtr Subject; }
[StructLayout(LayoutKind.Sequential)]
struct TrustData {
public uint Size; public IntPtr Policy; public IntPtr Sip; public uint Ui;
public uint Revocation; public uint Choice; public IntPtr File;
public uint StateAction; public IntPtr State; public IntPtr Url;
public uint Flags; public uint Context;
}
[DllImport("wintrust.dll", ExactSpelling=true, PreserveSig=true)]
static extern int WinVerifyTrust(IntPtr window, ref Guid action, ref TrustData data);
public static bool Verify(string path) {
IntPtr name = Marshal.StringToCoTaskMemUni(path);
IntPtr file = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileInfo)));
try {
var info = new FileInfo { Size=(uint)Marshal.SizeOf(typeof(FileInfo)), Path=name };
Marshal.StructureToPtr(info, file, false);
var data = new TrustData { Size=(uint)Marshal.SizeOf(typeof(TrustData)), Ui=2, Choice=1, File=file, Flags=0x1000|0x10 };
var action = new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
return WinVerifyTrust(new IntPtr(-1), ref action, ref data) == 0;
} finally { Marshal.FreeHGlobal(file); Marshal.FreeCoTaskMem(name); }
}
}
'@
function Read-Property($database, [string]$name) {
$view = $database.OpenView("SELECT ``Value`` FROM ``Property`` WHERE ``Property`` = '$name'")
try {
[void]$view.Execute()
$record = $view.Fetch()
if ($null -ne $record) { return $record.StringData(1) }
return ''
} finally { [void]$view.Close() }
}
$installer = New-Object -ComObject WindowsInstaller.Installer
$cacheRoot = [System.IO.Path]::GetFullPath((Join-Path ([Environment]::GetFolderPath('Windows')) 'Installer'))
$registrations = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
$products = Get-ItemProperty $registrations -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName -eq 'Node.js' -and $_.DisplayVersion -eq $expectedVersion -and $_.PSChildName -match '^\{[0-9A-Fa-f-]{36}\}$' } |
Select-Object -ExpandProperty PSChildName -Unique
foreach ($product in $products) {
try {
if ($installer.ProductInfo($product, 'ProductName') -ne 'Node.js') { continue }
if ($installer.ProductInfo($product, 'VersionString') -ne $expectedVersion) { continue }
$package = [System.IO.Path]::GetFullPath($installer.ProductInfo($product, 'LocalPackage'))
if (-not [string]::Equals([System.IO.Path]::GetDirectoryName($package), $cacheRoot, [StringComparison]::OrdinalIgnoreCase)) { continue }
if ([System.IO.Path]::GetExtension($package) -ne '.msi') { continue }
$entry = Get-Item -LiteralPath $package -Force
$cache = Get-Item -LiteralPath $cacheRoot -Force
if (($entry.Attributes -band [IO.FileAttributes]::ReparsePoint) -or ($cache.Attributes -band [IO.FileAttributes]::ReparsePoint)) { continue }
if (-not [AgcOfflineSignature]::Verify($package)) { continue }
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new([System.Security.Cryptography.X509Certificates.X509Certificate]::CreateFromSignedFile($package))
if ($certificate.Subject -notmatch '(^|,\s*)O=OpenJS Foundation(,|$)') { continue }
$database = $installer.OpenDatabase($package, 0)
if ((Read-Property $database 'ProductName') -ne 'Node.js') { continue }
if ((Read-Property $database 'ProductVersion') -ne $expectedVersion) { continue }
if ((Read-Property $database 'ProductCode') -ne $product) { continue }
$manufacturer = Read-Property $database 'Manufacturer'
if ($manufacturer -notin @('Node.js Foundation', 'OpenJS Foundation')) { continue }
$view = $database.OpenView('SELECT `Text` FROM `Control` WHERE `Dialog_` = ''LicenseAgreementDlg'' AND `Control` = ''LicenseText''')
try {
[void]$view.Execute()
$record = $view.Fetch()
if ($null -eq $record) { continue }
$content = $record.StringData(1)
} finally { [void]$view.Close() }
if (-not $content.StartsWith('{\rtf') -or $content.Length -gt 1048576) { continue }
if (-not $content.Contains('Node.js') -or -not $content.Contains('Permission is hereby granted')) { continue }
[pscustomobject]@{
productName = 'Node.js'; version = $expectedVersion; manufacturer = $manufacturer
signatureVerified = $true; signer = 'OpenJS Foundation'; format = 'rtf'; content = $content
} | ConvertTo-Json -Compress
exit 0
} catch {
# 单个损坏/无权限缓存不能绕过验证;继续查找其它已登记候选。
continue
}
}
throw 'No matching trusted installed Node.js license'