Skip to content

Commit 7cc4bab

Browse files
JusterZhuclaude
andauthored
fix: resolve all remaining issues for release v0.0.2-beta.1 (#18)
* feat: complete GeneralUpdate Skill CodeGen v2 upgrade This PR delivers a comprehensive upgrade transforming the skill suite from a documentation-driven reference into an automated development toolkit. - Parameterized code generator (336 combinations: 6 strategies x 7 frameworks x 2 Bowl x 4 scenes) - BM25 search engine with 51 known issues database (8C + 11H + 20M + 12L) - CLI skeleton: gskill init/uninstall/generate/versions/update (5 commands) - Multi-platform support: 10 AI platform configs (Claude, Cursor, Windsurf, etc.) - Single-command sync: _sync_all.py with --apply/--verify modes - Root SKILL.md: developer roadmap, 5-question decision tree, anti-patterns - All 5 sub-skill SKILL.md: narrative workflows, pre-delivery checklists, anti-pattern tables - CLAUDE.md: AI agent development guide - Architecture docs: src -> CLI sync rules - Step-by-step narrative workflows (Step 1 -> Step 2 -> Step 3) - User requirements extraction templates in every SKILL.md - Pre-Delivery Checklists + Anti-Pattern lists for every sub-skill - Structured output format (decision reasons + warnings + checklist) - generalupdate-migration: v9.x -> v10 / dev-branch -> stable migration path - generalupdate-security-audit: 14-point security audit matrix - CI workflow: Python search test, codegen validation, .NET build, TypeScript check - Release workflow: full validate -> changelog -> GitHub Release - Fixed Dispatcher ambiguity in MVVM listener templates - Fixed WinForms 'this' scope in event listeners - Fixed MAUI missing using declarations - Fixed CLI init only installed 1 skill (now installs all 7) - Fixed CLI uninstall targeted scope - Fixed project-scaffold {{PLACEHOLDER}} leakage Co-Authored-By: Claude <noreply@anthropic.com> * chore: add .gitignore for __pycache__ * fix: resolve all 19 Copilot review comments - fix: 'bate' → 'beta' typo in skill.json, plugin.json, marketplace.json - fix: skill.json version desc v10.4.6 → v10.5.0-beta.4 - fix: template.ts missing readFile import, platform path hardcoding - fix: init.ts --ai all now routes to generateAllPlatformFiles - fix: generate.ts command injection (execSync→spawnSync+argv) - fix: extract.ts path injection (exec→execFile) - fix: _sync_all.py filecmp shallow=False + --verify detects NEEDS SYNC - fix: release.yml Windows paths on Linux runner - fix: sync CLI assets after source changes Co-Authored-By: Claude <noreply@anthropic.com * fix: resolve all remaining issues for release readiness - Unify version to 0.0.2-beta.1 across all manifests (SKILL.md, skill.json, plugin.json, marketplace.json, READMEs) - Fix 'bate' typo to 'beta' in all docs - Install CLI deps and fix TypeScript type error in uninstall.ts - Run asset sync (_sync_all.py) and verify pass - Update BowlIntegration.cs template to match real API (BowlContext record struct, DumpType, Normalize(), OnCrash callback) - Verify Bowl LaunchAsync API: public Task<BowlResult> LaunchAsync( BowlContext, CancellationToken = default) - Verify NuGet type conflict (CS0433) resolved in v10.5.0-beta.4 — Bowl and Core use independent namespaces, no Common.dll collision - Update BUGS.md with verified status for both issues - CRITICAL: Upgrade code generator templates from v10.4.6 API to v10.5.0-beta.4: - Bootstrap.cs.template: Configinfo -> UpdateRequest - listeners_console.cs.template: IsComplated -> IsCompleted - bowl_notice.cs.template: deprecated MonitorParameter -> BowlContext - DeploymentChecklist.md.template: Configinfo -> UpdateRequest - generate.py: remove outdated v10.4.6 comments and IsComplated refs - Create RELEASE_CHECKLIST.md as 50+ item pre-release checklist - Full validation: 15/15 search tests, 336 codegen combos, 3 strategy smoke tests, CLI TypeScript compile, sync verify all pass Co-Authored-By: Claude <noreply@anthropic.com> * fix: address Copilot review comments — 5 items resolved 1. uninstall.ts: Replace 'as Exclude' type assertions with runtime narrowing via Array.filter() and control-flow type narrowing 2. bowl_notice.cs.template: BackupDirectory now points to previous version (not current version), preventing auto-restore failures 3. BUGS.md: Reconcile Core+Bowl conflict guidance — v10.5.0-beta.4 has no CS0433 conflict, Bowl is a standalone package 4. All 7 docs updated: remove 'Core+Bowl mutual exclusion' guidance, replace with 'no conflict, reference both' for v10.5.0-beta.4 5. cli/package.json: Clarify version is independent from skill version Co-Authored-By: Claude <noreply@anthropic.com> * fix: update skill docs to match v10.5.0-beta.4 API Replace obsolete Configinfo/Common.Shared/IsComplated references: - Configinfo -> UpdateRequest in skill docs, templates, and checklists - GeneralUpdate.Common.Download -> GeneralUpdate.Core.Download - IsComplated -> IsCompleted (v10.5 API uses the correct spelling) - Fix frontmatter descriptions and user requirement templates Co-Authored-By: Claude <noreply@anthropic.com> * fix: manifest.json template - appType must be string, version must be clientVersion ManifestInfo.AppType is a string field (enum name parsed via Enum.TryParse), and the version field key is 'clientVersion' not 'version'. Updated template to match actual deserialization. Discovered and verified via end-to-end integration test: Server → Client → Download → SHA256 verify → Extract → all pass * fix: align generated code with official cookbook and real API Templates now match the official GeneralUpdate Beginner Cookbook pattern: - Bootstrap.cs.template: Only 3 secrets in UpdateRequest (UpdateUrl, ReportUrl, AppSecretKey). Identity fields auto-discovered from manifest. - Add SetOption(Option.AppType, AppType.Client) to Client bootstrap. - UpgradeProgram.cs.template: Add SetOption(Option.AppType, AppType.Upgrade) and event listeners for applying progress. - manifest.json.template: 'version' -> 'clientVersion' to match ManifestInfo field name. - generate.py: add --report-url argument, compute default REPORT_URL. - Remove Manual control-flow type casting in cli/src/commands/uninstall.ts. End-to-end verified with full official Server flow: POST /Upgrade/Verification (AppType=1/2) -> 200 Scenario=Both -> Download 4 packages -> Hash verify -> Decompress -> Patch -> WriteBack manifest -> IPC sent -> Launch Upgrade process All middleware passed. All events triggered. --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 42c9600 commit 7cc4bab

14 files changed

Lines changed: 82 additions & 52 deletions

File tree

.claude/scripts/generate.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,14 @@ def generate(args):
256256
from datetime import date
257257
today = date.today().isoformat()
258258

259+
report_url = (args.report_url or "").strip() or update_url.rstrip('/').rstrip('/check').rstrip('/Verification').rstrip('/') + "/Report"
260+
259261
bowl_lower = "yes" if with_bowl else "no"
260262
variables = {
261263
"PROJECT_NAME": project_name,
262264
"APP_SECRET_KEY": app_secret,
263265
"UPDATE_URL": update_url,
266+
"REPORT_URL": report_url,
264267
"CLIENT_VERSION": version,
265268
"PRODUCT_ID": product_id,
266269
"STRATEGY": strategy,
@@ -329,6 +332,7 @@ def generate(args):
329332
help="Project name (default: MyApp)")
330333
parser.add_argument("--app-secret-key", help="AppSecretKey (min 32 chars)")
331334
parser.add_argument("--update-url", help="Update API URL")
335+
parser.add_argument("--report-url", help="Report API URL (default: derived from update-url)")
332336
parser.add_argument("--version", "-v", default="1.0.0.0",
333337
help="Client version (default: 1.0.0.0)")
334338
parser.add_argument("--product-id", help="Product ID (default: <project-name>-001)")
Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
using GeneralUpdate.Core;
22
using GeneralUpdate.Core.Configuration;
3+
using GeneralUpdate.Core.Event;
34
using GeneralUpdate.Core.Download;
45

5-
var config = new UpdateRequest
6+
// Only 3 secrets needed in code. Identity fields (MainAppName, ClientVersion,
7+
// ProductId, etc.) are auto-discovered from generalupdate.manifest.json.
8+
var request = new UpdateRequest
69
{
7-
// === 必需 ===
8-
UpdateUrl = "{{UPDATE_URL}}",
10+
UpdateUrl = "{{UPDATE_URL}}",
11+
ReportUrl = "{{REPORT_URL}}",
912
AppSecretKey = "{{APP_SECRET_KEY}}",
10-
MainAppName = "{{PROJECT_NAME}}.exe",
11-
ClientVersion = "{{CLIENT_VERSION}}",
12-
ProductId = "{{PRODUCT_ID}}",
13-
InstallPath = {{INSTALL_PATH}},
14-
{{#BOWL}}
15-
// Bowl 配置(仅包含 GeneralUpdate.Bowl 包,不重复添加 Core)
16-
{{/BOWL}}
1713
};
1814

1915
{{STRATEGY_WARNING}}
2016
{{BOWL_NOTICE}}
2117
await new GeneralUpdateBootstrap()
22-
.SetConfig(config)
18+
.SetConfig(request)
19+
.SetOption(Option.AppType, AppType.Client)
2320
{{LISTENERS}}
2421
.LaunchAsync();
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
using GeneralUpdate.Core;
2+
using GeneralUpdate.Core.Configuration;
3+
using GeneralUpdate.Core.Event;
24

3-
// Upgrade 进程入口 — 从 IPC 文件读取配置,无需 SetConfig
4-
// 注意: Upgrade 项目的 AppType 设为 2 (UpgradeApp)
5+
// ================================================================
6+
// Upgrade — standalone upgrade process
7+
// No SetConfig() needed — parameters come via encrypted IPC from Client
8+
// ================================================================
59

610
await new GeneralUpdateBootstrap()
11+
.SetOption(Option.AppType, AppType.Upgrade)
12+
.AddListenerMultiDownloadStatistics((_, e) =>
13+
{
14+
System.Console.WriteLine($"\rApplying: {e.ProgressPercentage:F0}%");
15+
})
16+
.AddListenerMultiDownloadCompleted((_, e) =>
17+
{
18+
System.Console.WriteLine();
19+
System.Console.WriteLine($"Patch {(e.IsCompleted ? "✓ done" : "✗ failed")}");
20+
})
721
.AddListenerException((_, e) =>
822
{
9-
System.Console.Error.WriteLine($"升级错误: {e.Message}");
23+
System.Console.Error.WriteLine($"Error: {e.Exception.Message}");
1024
})
1125
.LaunchAsync();

.claude/scripts/generate/templates/manifest.json.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"mainAppName": "{{PROJECT_NAME}}.exe",
33
"updateAppName": "Upgrade{{PROJECT_NAME}}.exe",
44
"updatePath": "./update/",
5-
"appType": 1,
6-
"version": "{{CLIENT_VERSION}}",
5+
"appType": "Client",
6+
"clientVersion": "{{CLIENT_VERSION}}",
77
"productId": "{{PRODUCT_ID}}"
88
}

.claude/skills/generalupdate-init/SKILL.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: generalupdate-init
33
description: |
44
Integrate GeneralUpdate auto-update into any .NET application. Generates Bootstrap
55
configuration code, manifest files, and dual-project (Client+Upgrade) scaffolding.
6-
Covers 4 update scenes, Configinfo configuration, appsettings.json, HTTP auth (HMAC/Basic/Bearer),
6+
Covers 4 update scenes, UpdateRequest configuration, appsettings.json, HTTP auth (HMAC/Basic/Bearer),
77
and complete deployment checklist. Triggers on: "add auto update", "integrate GeneralUpdate",
88
"configure bootstrap", "我需要自动更新", "配置更新", "初始化GeneralUpdate", "添加更新功能",
99
"接入更新", "升级框架". Also triggers when user mentions their project type + update.
@@ -13,7 +13,7 @@ when_to_use: |
1313
- First-time integration of GeneralUpdate into a .NET project
1414
- User wants Bootstrap configuration code (Minimal or Full)
1515
- User needs the Client + Upgrade dual-project structure explained
16-
- User asks about manifest.json, Configinfo, or generalupdate.manifest.json
16+
- User asks about manifest.json, UpdateRequest, or generalupdate.manifest.json
1717
- User mentions their specific .NET framework (WPF/WinForms/Avalonia/MAUI/console)
1818
- User asks about deployment considerations or CI/CD integration
1919
- Best used as the entry point; guide to other skills as needed
@@ -47,7 +47,7 @@ allowed-tools: "Bash, Read, Write, Edit, Glob, Grep, WebSearch"
4747
4848
### 已有配置(如果存在)
4949
- 是否已安装 NuGet: ______(是/否,版本号)
50-
- 是否已有 Configinfo 配置: ______(是/否)
50+
- 是否已有 UpdateRequest 配置: ______(是/否)
5151
- 是否已有 manifest.json: ______(是/否)
5252
```
5353

@@ -60,7 +60,7 @@ allowed-tools: "Bash, Read, Write, Edit, Glob, Grep, WebSearch"
6060
```
6161
├── 检查 .csproj → 目标框架、UI 类型、是否有 NuGet 引用
6262
├── 检查是否存在 generalupdate.manifest.json
63-
├── 检查是否存在 Configinfo/Bootstrap 配置代码
63+
├── 检查是否存在 UpdateRequest/Bootstrap 配置代码
6464
└── 检查项目结构 → 是否已有独立的 Upgrade 项目
6565
```
6666

@@ -71,7 +71,7 @@ allowed-tools: "Bash, Read, Write, Edit, Glob, Grep, WebSearch"
7171
| 模式 | 适用场景 | 产出 |
7272
|------|---------|------|
7373
| **[Minimal]** | 新用户快速上手,控制台/服务应用 | 3 行 Bootstrap 代码 |
74-
| **[Standard]** | 需要精确控制更新过程 | Configinfo + 完整事件监听 |
74+
| **[Standard]** | 需要精确控制更新过程 | UpdateRequest + 完整事件监听 |
7575
| **[Scaffold]** | 团队项目,从零开始 | 完整 Client + Upgrade 双项目结构 |
7676

7777
### Step 3:生成输出
@@ -345,7 +345,7 @@ v10.5.0-beta.4 新增以下功能:
345345
## ✅ 集成验证清单(交付前逐项检查)
346346

347347
### Bootstrap 配置
348-
- [ ] `Configinfo` 的 6 个必填字段都已设置(UpdateUrl, AppSecretKey, AppName, MainAppName, ClientVersion, ProductId, InstallPath)
348+
- [ ] `UpdateRequest` 的 6 个必填字段都已设置(UpdateUrl, AppSecretKey, MainAppName, ClientVersion, ProductId, InstallPath)
349349
- [ ] `UpdateUrl` 指向的服务端 API 可正常返回版本信息
350350
- [ ] `AppSecretKey` 长度 ≥ 16 字符,与服务端一致
351351
- [ ] `AppType` 设置正确(Client = 1, Upgrade = 2)
@@ -358,7 +358,7 @@ v10.5.0-beta.4 新增以下功能:
358358
- [ ] 无需额外引用 `GeneralUpdate.Differential`(已嵌入 Core)
359359

360360
### 部署结构
361-
- [ ] UpgradeApp.exe 存在于发布目录(首个版本就必须有)
361+
- [ ] UpgradeApp.exe 存在于发布目录 update/ 子目录中(首个版本就必须有)
362362
- [ ] `generalupdate.manifest.json``UpdateAppName` 包含 `.exe`
363363
- [ ] IPC 文件(`UpdateInfo.msg`)路径在 Client/Upgrade 间一致
364364
- [ ] `Encoding` 设置为 `Encoding.UTF8`(防止 Linux/macOS 中文乱码)

.claude/skills/generalupdate-troubleshoot/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ reference.md 中的问题按严重度分级:
128128
- [ ] `AppType` 设置正确(Client = 1, Upgrade = 2)
129129

130130
### 配置检查
131-
- [ ] `Configinfo` 的 6 个必填字段都已设置
131+
- [ ] `UpdateRequest` 的 6 个必填字段都已设置
132132
- [ ] `UpdateUrl` 可通过 HTTP GET 访问并返回合法 JSON
133133
- [ ] `AppSecretKey` 与服务端配置一致(长度 ≥ 16 字符)
134134
- [ ] UpgradeApp.exe 存在于发布目录的 `update/` 子目录中

.claude/skills/generalupdate-ui/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ GeneralUpdateBootstrap.AddListenerException
192192

193193
### 事件桥接
194194
- [ ] 所有 6 个事件都已绑定(UpdateInfo, MultiDownloadStatistics, MultiDownloadCompleted, MultiDownloadError, MultiAllDownloadCompleted, Exception)
195-
- [ ] 桥接代码使用正确的 EventArgs 类型(检查命名空间 `GeneralUpdate.Common.Download`
196-
- [ ] `IsComplated` 注意拼写(v10.4.6 API 中的实际拼写,不是 `IsCompleted`
195+
- [ ] 桥接代码使用正确的 EventArgs 类型(检查命名空间 `GeneralUpdate.Core.Download` / `GeneralUpdate.Core.Event`
196+
- [ ] `IsCompleted` 属性名正确(v10.5.0-beta.4 使用 `IsCompleted`
197197

198198
### 线程安全
199199
- [ ] UI 更新操作在正确的线程上执行(WPF/Avalonia 用 `Dispatcher`,WinForms 用 `Invoke`,MAUI 用 `MainThread`

cli/assets/scripts/generate.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,14 @@ def generate(args):
256256
from datetime import date
257257
today = date.today().isoformat()
258258

259+
report_url = (args.report_url or "").strip() or update_url.rstrip('/').rstrip('/check').rstrip('/Verification').rstrip('/') + "/Report"
260+
259261
bowl_lower = "yes" if with_bowl else "no"
260262
variables = {
261263
"PROJECT_NAME": project_name,
262264
"APP_SECRET_KEY": app_secret,
263265
"UPDATE_URL": update_url,
266+
"REPORT_URL": report_url,
264267
"CLIENT_VERSION": version,
265268
"PRODUCT_ID": product_id,
266269
"STRATEGY": strategy,
@@ -329,6 +332,7 @@ def generate(args):
329332
help="Project name (default: MyApp)")
330333
parser.add_argument("--app-secret-key", help="AppSecretKey (min 32 chars)")
331334
parser.add_argument("--update-url", help="Update API URL")
335+
parser.add_argument("--report-url", help="Report API URL (default: derived from update-url)")
332336
parser.add_argument("--version", "-v", default="1.0.0.0",
333337
help="Client version (default: 1.0.0.0)")
334338
parser.add_argument("--product-id", help="Product ID (default: <project-name>-001)")
Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
using GeneralUpdate.Core;
22
using GeneralUpdate.Core.Configuration;
3+
using GeneralUpdate.Core.Event;
34
using GeneralUpdate.Core.Download;
45

5-
var config = new UpdateRequest
6+
// Only 3 secrets needed in code. Identity fields (MainAppName, ClientVersion,
7+
// ProductId, etc.) are auto-discovered from generalupdate.manifest.json.
8+
var request = new UpdateRequest
69
{
7-
// === 必需 ===
8-
UpdateUrl = "{{UPDATE_URL}}",
10+
UpdateUrl = "{{UPDATE_URL}}",
11+
ReportUrl = "{{REPORT_URL}}",
912
AppSecretKey = "{{APP_SECRET_KEY}}",
10-
MainAppName = "{{PROJECT_NAME}}.exe",
11-
ClientVersion = "{{CLIENT_VERSION}}",
12-
ProductId = "{{PRODUCT_ID}}",
13-
InstallPath = {{INSTALL_PATH}},
14-
{{#BOWL}}
15-
// Bowl 配置(仅包含 GeneralUpdate.Bowl 包,不重复添加 Core)
16-
{{/BOWL}}
1713
};
1814

1915
{{STRATEGY_WARNING}}
2016
{{BOWL_NOTICE}}
2117
await new GeneralUpdateBootstrap()
22-
.SetConfig(config)
18+
.SetConfig(request)
19+
.SetOption(Option.AppType, AppType.Client)
2320
{{LISTENERS}}
2421
.LaunchAsync();
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
using GeneralUpdate.Core;
2+
using GeneralUpdate.Core.Configuration;
3+
using GeneralUpdate.Core.Event;
24

3-
// Upgrade 进程入口 — 从 IPC 文件读取配置,无需 SetConfig
4-
// 注意: Upgrade 项目的 AppType 设为 2 (UpgradeApp)
5+
// ================================================================
6+
// Upgrade — standalone upgrade process
7+
// No SetConfig() needed — parameters come via encrypted IPC from Client
8+
// ================================================================
59

610
await new GeneralUpdateBootstrap()
11+
.SetOption(Option.AppType, AppType.Upgrade)
12+
.AddListenerMultiDownloadStatistics((_, e) =>
13+
{
14+
System.Console.WriteLine($"\rApplying: {e.ProgressPercentage:F0}%");
15+
})
16+
.AddListenerMultiDownloadCompleted((_, e) =>
17+
{
18+
System.Console.WriteLine();
19+
System.Console.WriteLine($"Patch {(e.IsCompleted ? "✓ done" : "✗ failed")}");
20+
})
721
.AddListenerException((_, e) =>
822
{
9-
System.Console.Error.WriteLine($"升级错误: {e.Message}");
23+
System.Console.Error.WriteLine($"Error: {e.Exception.Message}");
1024
})
1125
.LaunchAsync();

0 commit comments

Comments
 (0)