Files
jkooe 531991954c feat(T-3): 多端适配与工程质量 —— PlatformAdapter 三端实现/命令注入面清零/发现并发限流/CI 门禁
1. platform:三端完整实现。windows.ts / macos.ts / linux.ts 各自导出能力表与
   usb/share/discovery 实现,共用设施抽到 shared.ts(单向依赖,无循环)。
   Linux 是**显式降级实现类**(usb=null + 每条能力带中文 reason),不是 else 兜底。
2. usb.ts:退化为薄分派层,清掉 5 处 exec 拼串,改走 runner(参数数组 +
   shell:false);新增 listAttached();parseUsbPort / parseUsbipdList 纯函数,
   usb===null 时抛 UNSUPPORTED_ON_PLATFORM(不再把 ENOENT 抛给 UI)。
3. share.ts:薄分派 + 本机共享开关。Windows 接 scripts/setup-smb.ps1
   (ValidatePattern 白名单 + 绝对路径校验 + -EncryptData $true),
   macOS/Linux 明确 UNSUPPORTED_ON_PLATFORM + 引导文案,绝不静默成功。
4. discover.ts:候选 IP 剔除 .0/.255/网关/本机并按 /24 全局去重(单网卡 252);
   mapWithConcurrency 真实并发上限 64;mDNS 分派改由 capabilities().mdns 驱动,
   不再判断平台;解析器 parseDnsSd / parseAvahiBrowse 纯函数化。
5. 依赖预检:probeDependency 支持 ok/missing/outdated + hintUrl,最低主版本来自
   DEPENDENCY_MIN_MAJOR;core/logger.ts 补文件轮转与脱敏测试(4 类敏感输入)。
6. CI:.github/workflows/ci.yml —— typecheck → 双端测试 → 覆盖率门禁 →
   smoke → 残留进程检查;launcher 用 vitest.config.ts thresholds(全局 60%,
   核心 connect/discover/usb/agent/share/platform/* ≥70%),server 用 Node 22
   内置 --test-coverage-lines=60,低于阈值直接 fail。
7. UI:能力驱动显隐(USB/共享面板按 capabilities() 隐藏并显示原因),
   renderer 内无任何平台判断;IPC 错误边界抽成 core/ipc.ts 的 makeSafeHandler()
   以便 vitest 直测(§12.4 R4),main.ts 的 wrapIpc 退化为 3 行调用。

测试:launcher 245 例全绿(原 143 例非回归 + 102 新增),server 43 例全绿;
tsc --noEmit 0 错误;launcher 行覆盖 82.56%,server 75.31%(门禁 60%);
gitleaks pre-commit 通过。
2026-10-26 00:45:17 +08:00

50 lines
2.0 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Only in One - create an encrypted SMB share on Windows.
#
# 安全要点(G-21 / 安全红线第 2 条):
# · `ShareName` 走 **ValidatePattern 白名单**(与 launcher 的 `isShareName` 同一份定义:
# `^[A-Za-z0-9_$-]{1,64}$`),任何 `" ; rm -rf /` 之类载荷在**参数绑定阶段**就被拒绝,
# 根本进不到命令解析;
# · `Path` 必须是绝对路径且不含控制字符;
# · `New-SmbShare -EncryptData $true` 强制 SMB 加密(团队内网也要加密)。
#
# 调用方式(launcher 用参数数组调用,不经过 shell):
# powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass `
# -File scripts/setup-smb.ps1 -ShareName OnlyInOne -Path D:\Shared
[CmdletBinding()]
param(
[ValidatePattern('^[A-Za-z0-9_$-]{1,64}$')]
[string]$ShareName = 'OnlyInOne',
[string]$Path = 'D:\Shared'
)
$ErrorActionPreference = 'Stop'
# 路径校验:必须绝对路径,且不含控制字符
if ([string]::IsNullOrWhiteSpace($Path)) {
throw 'Path 不能为空'
}
if ($Path -notmatch '^[A-Za-z]:\\' -and $Path -notmatch '^\\\\') {
throw "Path 必须是绝对路径(如 D:\Shared 或 \\server\share),收到:$Path"
}
if ($Path -match '[\x00-\x1F]') {
throw 'Path 不得包含控制字符'
}
if (-not (Test-Path -LiteralPath $Path)) {
New-Item -ItemType Directory -Force -Path $Path | Out-Null
}
$user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$existing = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue
if ($null -ne $existing) {
Write-Host "SMB share '$ShareName' 已存在,跳过创建(如需重建请先 Remove-SmbShare -Name '$ShareName' -Force)"
}
else {
New-SmbShare -Name $ShareName -Path $Path -FullAccess $user -EncryptData $true | Out-Null
Write-Host "SMB share '$ShareName' -> $Path created (encrypted, FullAccess=$user)."
}
# 输出 smb:// 地址供 UI 复制(host 由 launcher 侧拼装)
Write-Host "smb://<this-host>/$ShareName"