- 重构版主提示词(14 parts,面向 ClassHelper 灵动岛重构) - ClassIsland 全量规格提示词(20 parts,含分卷与逐章版本) - 投喂指南、分卷、逐节文件 - 调研记录、一致性基线、生成与质检脚本
22 KiB
ClassHelper 技术栈调研笔记(Part 02/12/13 支撑)
本文件是队友
stack的静态分析记录,供 Lead 汇总审校时核对"我读了什么、为什么这样映射、还剩什么不确定"。 全程只使用 read/grep/glob 与纯文本统计命令;未执行任何构建、安装、运行、截图、冒烟或 UI 命令;未修改repos/下任何文件。
1. 已读文件清单
1.1 ClassHelper(repos/ClassHelper-master)
| 文件 | 用途 |
|---|---|
package.json |
根版本单一来源、pnpm@11.8.0、Node >=20.19.0、全部脚本(build/dev/typecheck/lint/dist/version) |
pnpm-workspace.yaml |
workspace 定义、allowBuilds 白名单、verifyDepsBeforeRun |
tsconfig.base.json |
目标 ES2023、NodeNext、strict、verbatimModuleSyntax、declaration |
packages/desktop-client/package.json |
Electron 44.3、Vue 3.5.42、Element Plus 2.14.5、Pinia 4.0.3、Vue Router 5.3.1、Vite 8.3、TS 5.9.3、electron-builder 26.15.3、esbuild 0.28.2 |
packages/desktop-client/electron-builder.yml |
appId/productName、electronLanguages: [zh-CN]、files/asar/npmRebuild、win nsis+portable、artifactName |
packages/desktop-client/vite.config.mts |
双入口(index/island)、base:'./'、outDir dist/renderer、5174 strictPort |
packages/desktop-client/island.html / index.html |
透明底、CSP 全指令、preload 挂载点 |
packages/desktop-client/scripts/build-main.mjs |
esbuild CJS 主进程/preload/岛 preload、产物路径、更新助手编译 |
packages/desktop-client/scripts/dev.mjs |
Vite 就绪探测 → Electron 启动、VITE_DEV_SERVER_URL |
packages/desktop-client/src/main/index.ts |
单实例、启动时序、设置窗口参数、导航白名单、开机自启、托盘、退出清理 |
src/main/config.ts |
config.json 路径、PersistedConfig 全字段与默认值、归一化、safeStorage、120ms 合并写、flushConfigSync、deviceKey |
src/main/island.ts(前 1140 行) |
岛窗口全参数、固定包围盒、命中/穿透、失焦宽限、触摸模式、CLOSE_ANIMATION_MS=360、各状态超时表、通知队列与动作 |
src/main/ipc.ts |
IPC handler 注册、配置白名单剔除、appInfo、自启、日志目录、DevTools、client status |
src/main/channels.ts |
通道名叶子模块(零 import)与原因 |
src/main/tray.ts |
托盘菜单与图标兜底 |
src/main/logger.ts |
main.log、1MB 轮转、懒解析、格式与堆栈写入 |
src/main/crash-guard.ts |
崩溃自愈三条路径、10 分钟 3 次限流、空闲重启、冒烟豁免 |
src/main/auto-update.ts |
更新策略、文件名校验、下载/校验/差分、空闲 5 分钟、安装助手、结果文件 |
src/main/island.ts(1141+ 行片段经 grep) |
recoverWindow、命中轮询、alive 心跳相关字段 |
src/preload/index.ts |
window.desktop 全量白名单、订阅可取消、纯数据约束 |
src/preload/island.ts |
window.island 全量白名单(状态/外观/尺寸/命中/触摸/心跳) |
src/types/desktop.d.ts |
桥接契约、DesktopStoredConfig 全字段、IslandState、冒烟钩子 |
src/island/main.ts |
岛入口零 UI 库、二次注入动效令牌 |
src/island/spring.ts |
WinIsland 弹簧参数、换向限速、零过冲钳制 |
src/island/squircle.ts |
连续圆角(p=4.2、14 段/角)、展开半径 |
src/renderer/composables/motion.ts |
令牌注入、reduced-motion、hover 能力、count-up、stagger、主题揭示 |
src/renderer/main.ts |
应用窗口挂载顺序、冒烟动态 import |
src/renderer/router/index.ts |
hash 路由、守卫、路由表结构 |
src/renderer/cache/db.ts |
IndexedDB 缓存层(classhelper-cache、object store 列表、容错) |
packages/shared/package.json / src/index.ts / src/motion.ts / src/island-layout.ts / src/constants.ts(255-364 行)/ src/types.ts(ScheduleDto、IslandNotification、IslandState 片段) |
共享类型、动效令牌、岛方案 schema 与 normalize、外观默认值/范围、尺寸增量、ClassIsland 度量常量 |
packages/ui/package.json / src/tokens.css / src/index.ts 文件清单 |
共享 UI 消费方式、基础令牌与深色覆盖 |
docs/dev/architecture.md |
目录职责、数据流、更新助手链路、工程边界 |
docs/dev/motion.md |
动效令牌表、CSS linear() 弹簧、四条硬约束、主题两条纪律 |
docs/dev/winisland-design-tokens.md |
经典岛几何、自定义行度量、禁用 setBackgroundMaterial、阴影常驻 |
docs/dev/release.md |
版本单一来源、构建与验证顺序、产物命名 |
docs/get-started/requirements.md |
客户端内存/磁盘/触摸屏/平台要求(250–350MB、仅 Windows) |
AGENTS.md(自动注入) |
preload 白名单、CSP、离线缓存隔离、岛方案字段、验证纪律、发布纪律 |
1.2 ClassIsland(repos/ClassIsland)
| 文件 | 用途 |
|---|---|
ClassIsland/Program.cs |
命令行参数全集、Global\ClassIsland.Lock 单实例、URI 二次启动转发、Sentry、进程优先级 |
ClassIsland.Launcher/Program.cs |
多版本目录枚举(app*、.current、.destroy、.partial)、Linux 执行权限 |
ClassIsland/Services/SettingsService.cs |
Settings.json 加载/保存、版本迁移门、设置叠层(Add/RemoveSettingsOverlay)、属性变更即保存 |
ClassIsland/Models/Settings.cs |
211 个默认值字段(grep private .* _\w+ = 全量提取) |
ClassIsland.Shared/Helpers/ConfigureFileHelper.cs |
.bak 备份/回退、原子写、MergeDictionary、CopyObject、反序列化选项 |
ClassIsland.Shared/Models/ConfigError.cs |
配置错误记录模型(只读声明) |
ClassIsland/Services/ProfileService.cs |
档案路径、管理端拉取、临时层清理、信任档案、切换保存 |
ClassIsland.Shared/Models/Profile/Profile.cs |
档案根字段、默认群、编辑科目、临时层、预定课表 |
.../Profile/TimeLayout.cs / TimeLayoutItem.cs / ClassPlan.cs / ClassInfo.cs / TimeRule.cs / Subject.cs / ClassPlanGroup.cs / OrderedSchedule.cs |
课表数据模型全字段、默认值、[JsonIgnore]、GUID 空回退、有效时间点算法 |
ClassIsland/Services/ComponentsService.cs |
组件布局路径/默认布局 GUID/迁移/保存时机 |
ClassIsland.Core/Models/Components/{ComponentProfile,MainWindowLineSettings,ComponentSettings,ComponentGroup}.cs |
组件布局全字段与默认值 |
ClassIsland/Models/ComponentSettings/*.cs(9 个) |
组件专属设置模型清单 |
ClassIsland/Services/AutomationService.cs |
自动化目录、Workflow[] 顶层、切换保存、信任档案门槛、时间点行动、触发/恢复语义 |
ClassIsland.Core/Models/Automation/{Workflow,TriggerSettings,ActionMenuTreeNode}.cs、ClassIsland.Shared/Models/Automation/{ActionSet,ActionItem}.cs |
自动化数据结构与 Actions 序列化名 |
ClassIsland.Core/Models/Ruleset/{Ruleset,Rule,RuleGroup,StringMatchingSettings}.cs |
规则集结构与默认值(Or/And、IsReversed、IsEnabled) |
ClassIsland/Services/Automation/{Triggers,Actions}/*.cs(grep TriggerInfo/ActionInfo) |
12 个触发器 ID、7 个动作 ID |
ClassIsland/Services/PluginService.cs |
.cipx 安装/解压/.disabled/.uninstall、清单解析、API 版本门槛、依赖拓扑、插件配置目录、审计 |
ClassIsland.Core/Abstractions/PluginBase.cs / Services/IPluginService.cs / Models/Plugin/{PluginManifest,PluginInfo,PluginIndex,PluginIndexItem,PluginDependency,PluginRepoManifest}.cs / Enums/PluginLoadStatus.cs |
插件模型、市场索引、加载状态 |
ClassIsland/Services/PluginMarketService.cs |
回退镜像、索引刷新 7 天、默认索引 URL |
ClassIsland.PluginSdk/ClassIsland.PluginSdk.targets / generate-md5.ps1 |
插件打包成 .cipx、checksums.md 的 MD5 注释 |
ClassIsland/Services/IpcService.cs、ClassIsland.Shared.IPC/{IpcClient,IpcRoutedNotifyIds}.cs、Abstractions/Services/IPublic*.cs、README.md |
命名管道 IPC、公开服务契约、事件通知 ID |
ClassIsland.Core/CommonDirectories.cs / Services/GlobalStorageService.cs |
路径划分、机器级全局存储 |
ClassIsland/Services/FileFolderService.cs |
需创建目录全集、备份内容与命名、自动备份策略 |
ClassIsland/Services/XamlThemeService.cs(grep) |
主题路径、EnabledThemes.json、主题包缓存 |
ClassIsland/Services/AppUpdating/UpdateService.cs(1-150、380-500、630-880 行) |
更新通道/状态枚举、部署锁、文件图签名、差分、.partial/.current/.destroy、压缩包校验 |
ClassIsland/Models/AppUpdating/DeploymentLock.cs、Models/{UpdateChannel,UpdateSource}.cs、ClassIsland.Shared/Enums/{UpdateStatus,UpdateWorkingStatus}.cs |
更新模型与状态 |
ClassIsland.Shared/Models/Notification/{NotificationSettings,NotificationPriority,NotificationRequest}.cs、ClassIsland.Core/Models/Notification/NotificationRequest.cs |
提醒设置/优先级/播放会话字段 |
ClassIsland.Core/Converters/ColorHexJsonConverter.cs、ClassIsland.Shared/JsonConverters/GuidEmptyFallbackConverter.cs |
颜色与空 GUID 的 JSON 兼容规则 |
ClassIsland.Core/Models/XamlTheme/ThemeManifest.cs |
主题清单字段与默认值 |
examples/example.json |
真实档案 JSON 形态(PascalCase、StartSecond 旧字段、AttachedObjects、TimeType 注释) |
AGENTS.md(自动注入) |
仓库形状、SDK 版本、构建与验证纪律、Avalonia 开发规则 |
1.3 团队上下文
analysis/00-brief.md(总简报、纪律、术语、分工)analysis/40-baseline.md(Lead 核对的 canonical 数值)parts/01-overview.md(总纲:三进程模型、ClassHelper 栈、P0/P1/P2 模块)- 共享任务
task-1(认领/完成状态)
2. ClassIsland → ClassHelper 映射决策(含理由)
2.1 已定决策(写入 parts)
| 决策 | 选择 | 理由 / 证据 |
|---|---|---|
| 工程形态 | pnpm monorepo:shared + ui + desktop-client |
复用 ClassHelper 已验证结构(pnpm-workspace.yaml:1-2、desktop-client/package.json) |
| 包管理/运行时 | pnpm 11.8.0、Node ≥20.19 | 根 package.json:6-9;allowBuilds 必须显式声明,否则 install 失败 |
| 桌面壳 | Electron 44.3 + electron-builder 26.15 | 唯一被团队指定且与 ClassHelper 对齐 |
| 进程模型 | 主进程 / 应用窗口渲染 / 岛渲染 / 插件 utilityProcess / 更新助手 | 保留 ClassHelper 三进程 + 新增隔离进程(ClassIsland 的插件 PluginLoadContext 在 Electron 下的等价物是进程隔离) |
| 数据形态 | 本地 JSON 文件(ClassIsland 兼容 PascalCase 档案 + camelCase 运行配置) | ClassIsland 是单机应用;ClassHelper 的 IndexedDB 缓存是"服务端离线缓存",本应用无服务端,故只保留 JSON 文件 + 可选内存缓存 |
| 数据根目录 | app.getPath('userData') |
Electron 正确做法;ClassIsland 的 AppRootFolderPath 在便携/安装两种形态下语义不同,用 userData 统一 |
| 主界面窗口 | 岛窗口 = ClassIsland MainWindow;设置窗口 = 新增 | 团队总纲第 1.6 节要求三进程分离;岛必须透明置顶,设置窗口是普通窗口 |
| 岛形变 | SpringValue 帧积分 + squircle 连续圆角 |
ClassHelper 已验证(spring.ts、squircle.ts),且 ClassIsland 的 WrapPanel 尺寸动画可平滑映射 |
| 主题 | CSS 变量 + html.dark + 主题包目录 |
ClassIsland 是 XAML 资源字典;Vue 下唯一可行且可热切换的等价物 |
| 插件包 | .cipx = zip + manifest.yml(camelCase)+ ESM 入口 |
保留 ClassIsland 生态语义(清单字段/依赖/API 版本/.disabled/.uninstall),把 DLL 入口换成 main.mjs |
| 插件市场 | 多源索引 JSON + 镜像回退 + MD5(兼容)+ SHA-256(安全) | 对齐 PluginIndex/PluginMarketService,并补足 ClassIsland 只校验 MD5 的弱点 |
| 更新 | 自研:清单 + SHA-256 + 独立安装助手 + 三档安装时机 | ClassIsland 是 FileMap 分组件部署 + Launcher 多版本;Electron 下以 NSIS 安装目录 + 助手替换 + 回滚副本等价实现(标注【推断】) |
| 单实例 | requestSingleInstanceLock + second-instance |
对齐 ClassIsland Mutex 语义,且 Electron 原生支持 |
| 外部进程集成 | 默认关闭本地 HTTP;插件通过宿主 API | ClassIsland 有命名管道 IPC 公开服务;Electron 不暴露等价物,改为按需可选的 localhost HTTP |
| 崩溃自愈 | 崩溃重建 + 无响应 10s 重建 + 内存 1.5GB 看门狗 + 10 分钟 3 次限流 | 直接对齐 crash-guard.ts 与 MemoryWatchDogService.cs |
| 日志 | 自研 logger.ts(main.log + 1MB 轮转) |
与 ClassHelper 完全一致;不引入 electron-log 以减少不可控行为 |
| 自动备份 | backups/Auto_*.zip,7 天/16 份 |
对齐 FileFolderService.cs:83-113 |
| 安全 | CSP + contextBridge 白名单 + sandbox + 导航白名单 + 凭据门禁 + 插件权限 | 与 ClassHelper AGENTS.md 完全一致;插件权限是在 ClassIsland(全信任 DLL)之上的主动增强【推断】 |
2.2 有意偏离 ClassIsland 的地方(必须在提示词中说明)
- 插件权限模型:ClassIsland 插件是进程内 DLL,天然全信任;本实现必须默认拒绝、按
permissions放行。属安全增强,不是功能缺失。 - 热更新/热重载:ClassIsland 有 HotAvalonia(开发期);本实现只在开发期用 Vite HMR,生产不得热替换插件。
- 管理端(集控):ClassIsland 有
ManagementService(管理服务器下发设置/档案);本任务明确不要求后端,P2 可选。提示词中应写"默认不实现,预留接口"。 - Sentry:ClassIsland 默认开启匿名崩溃上报;本实现默认提示可关闭,且不得上报课表/个人信息。
- 多平台:ClassIsland 支持 Windows/Linux/macOS;本实现主目标 Windows(触摸屏/希沃),macOS/Linux 尽力支持但不得阻塞 Windows 验收。
2.3 与其他 part 的边界
- Part 03(设计 tokens):
tokens.css数值我引用了基础令牌,但完整色板/字号阶梯归 Part 03;我未在 02 中重定义。 - Part 04/05(主界面/组件):岛窗口参数、组件行度量、组件布局 schema 的"存储字段"归我(13.5),"视觉与交互"归 04/05,已在 13.5 注明"视觉见第 5 部分"。
- Part 06/07/08(课表/提醒/自动化):数据 schema 我给出字段级清单,业务语义(触发时机、队列行为)归 06/07/08;我在 13.4/13.6/13.7 只规定"存什么、默认值、兼容规则"。
- Part 09(主题):主题目录与
EnabledThemes.json、ThemeManifest字段归我(13.8),CSS 变量清单与壁纸取色算法归 09。 - Part 10/11(设置/其他窗口):设置页字段默认值我给了 13.3 全表,页面分组与控件归 10。
- Part 14(动画总表):我只引用 spring/squircle/动效令牌的数值,未展开逐动画时间表。
- Part 16/18(验收/禁止):我给出的验收标准是"本部分自查",与总验收不冲突。
3. 未决问题 / 缺口(交给 Lead 决策或后续 part 补齐)
- 更新安装目录策略:ClassIsland 用 Launcher 枚举
app-<版本>目录实现"多版本 + 回滚";Electron + NSIS 下我建议"固定安装目录 + 助手替换 + 回滚副本",但是否允许 side-by-side 多版本目录需要 Lead 确认(影响 02/12 的更新章节与 17 里程碑)。 - 插件清单字段名:ClassIsland 的
manifest.yml用camelCase(YamlDotNetCamelCaseNamingConvention)。我按 camelCase 写;若团队希望与"PascalCase 档案"统一,需要在 Part 12 全局替换(会影响导入 ClassIsland 插件包)。 - 插件设置页渲染方式:我规定"声明式 schema,不允许任意 HTML"(安全),但 ClassIsland 插件可提供任意 Avalonia 控件;若要求 1:1 还原插件 UI 能力,需要引入受限的 iframe/webview 方案(会带来安全与样式隔离成本)——建议按声明式实现并在 Part 12 注明"这是有意限制"。
- 外部进程 IPC:ClassIsland 公开
IPublicLessonsService/IPublicProfileService给外部程序(命名管道)。我建议默认关闭 localhost HTTP;若产品需要"第三方读取当前课程",需要 Lead 决定是否实现并规定端口/鉴权。 AttachedObjects(附加设置)兼容:ClassIsland 1.7 档案在TimeLayoutItem下有AttachedObjects(提醒/天气/附加信息附加设置)。我在 13.4.3 规定"导入保留、新代码不写",但 Part 06/07 如果要支持"每个时间点的课级提醒设置",需要把该字段升级为一等公民。Settings.json双写问题:我规定config.json(camelCase)为主、Settings.json(PascalCase)仅导入导出时出现;若团队希望"用户可以直接编辑 ClassIsland 风格的 Settings.json",需要改成以 PascalCase 为主(牵动 02/10/13)。- 通知历史是否落盘:ClassIsland 没有持久化通知历史;我按"通知中心"需求(Part 07/11)推断了
notification-history.json与 500 条上限,需 Part 07 确认。 - 多显示器与 DPI:
windowDockingMonitorIndex、followCursorDisplay、scale的 DPI 换算规则我未展开(属 Part 04);Part 04 需要给出"逻辑像素 vs 物理像素"的统一口径,避免 02 的窗口参数与 04 的定位算法冲突。 isIslandSeperated拼写:ClassIsland 源码确实是IsIslandSeperated(少一个 a,Settings.cs:1852)。为导入兼容必须保留该拼写;Part 04/10 若写正确拼写会造成字段不匹配。- 触摸模式与窗口形状:
setShape只在 Windows 生效;macOS/Linux 需要不同的命中策略(ClassHelper 也没覆盖)。提示词中应写明"非 Windows 平台降级为整窗接收鼠标"。 - 更新签名:ClassIsland 的更新清单有签名(
DetachedSignatureProcessor);我要求"必须签名",但密钥管理(公钥内置、轮换策略)需要 Lead 在 Part 17/18 里给一句总纪律。 - 插件/主题市场的默认源:我引用了 ClassIsland 的官方索引 URL 作为示例;本实现是否内置该源(涉及外网与合规)需要 Lead 决定,建议默认"仅用户手动添加源"。
3.1 最终裁决(Lead 已确定,已并入 parts 并覆盖上述 1–12 条)
- 更新安装:固定安装目录 + 独立更新助手替换 +
updates/rollback/<旧版本>/回滚副本,不做 side-by-side 多版本。 - 插件清单:统一 camelCase 写出,兼容读取 PascalCase 旧清单并归一化。
- 插件设置页:只能声明式 schema,禁止任意 HTML/iframe/DOM 访问(安全红线)。
- 外部读取课程:可选本地只读 HTTP API(仅 127.0.0.1、随机端口、默认关闭、一次性 token),不恢复命名管道。
AttachedObjects升级为一等公民attachedObjects(Profile/ClassPlan/ClassInfo/TimeLayout/TimeLayoutItem/Subject),接收AttachedObjects原拼写。- 数据文件:
config.json为主 +Settings.json只读导入/导出兼容层(不双向双写),保留IsIslandSeperated。 - 通知历史:默认 500 条、可调 100–5000、滚动删除、写入节流(≥5 条或 ≥5s)。
- 坐标:全部使用 DIP(CSS px),窗口 bounds 也按 DIP;仅截图验收用
devicePixelRatio。 - 非 Windows 无
setShape:降级为整窗setIgnoreMouseEvents(true,{forward:true})+ 岛可见区内命中。 - 更新清单:SHA-256 必校验 + 可选 Ed25519(
keyId、公钥轮换);默认只接受 https,镜像需显式开启并提示风险。 - 插件/主题市场:默认不内置在线官方索引,仅离线示例索引;用户手动添加并二次确认后才联网。
- 其余按原写法。
AttachedObjects不是 1.7 遗留:AttachableSettingsObject.cs:15定义、2.xAttachedSettingsControlPresenter.axaml.cs:241,361仍读写;已补 4 个已知 Guid 与设置对象类型(课程显示/上课提醒/放学提醒/天气提醒)。- 已补天气数据 schema 一节(
WeatherInfo/WeatherAlert/ForecastDaily/ForecastHourly/Minutely/AqiInfo/WeatherQueryResult+ 缓存/来源/刷新/预警清洗 + 5 个规则 ID),与 07 对齐。 - Excel 导入导出定为 P1 必须实现(xlsx 重建),ReoGrid/WPF 仅参考;已写导入/导出/8MB 上限/导入前备份/worker 执行要求。
新增研读文件(为裁决 13/14/15):ClassIsland.Shared/AttachableSettingsObject.cs、ClassIsland.Core/Controls/AttachedSettingsControlPresenter.axaml.cs(241-253)、ClassIsland.Core/Models/AttachedSettings/LessonControlAttachedSettings.cs、ClassIsland/Models/AttachedSettings/{ClassNotification,WeatherNotification,AfterSchoolNotification,Test}AttachedSettings.cs、ClassIsland/Controls/AttachedSettingsControls/*.axaml.cs(Guid 与 Usage 目标)、ClassIsland.Core/Enums/AttachedSettingsTargets.cs、ClassIsland.Core/Models/Weather/*.cs(WeatherInfo/WeatherAlert/CurrentWeather/ForecastDaily/ForecastHourly/Minutely/MinutelyPrecipitation/AqiInfo/ValueUnitPair/WindInfo/RangedValue/StatusValueBase/WeatherQueryResult)、ClassIsland/Services/WeatherService.cs(来源/刷新/过滤)、ClassIsland/Views/ExcelImportWindow.xaml.cs、ExcelExportWindow.xaml.cs(ReoGrid 参考)、Settings.cs:113,2122-2130(ExpIsExcelImportEnabled 默认 false)。
4. 静态分析纪律声明
- 全程只读:
read读文本、grep/glob找文件、Select-String/Get-Content做纯文本统计、[regex]统计中文字符数。 - 未执行
dotnet build/run、pnpm install/dev/build、electron、npm、截图、冒烟或任何会弹窗/占用屏幕的命令。 - 未修改
repos/ClassIsland与repos/ClassHelper-master下任何文件;只写入了parts/02-tech-stack.md、parts/12-plugins-ipc.md、parts/13-data-storage.md、analysis/classhelper-stack.md。 - 证据标注口径:
repos/...:行号;无法从源码直接确认的工程设计一律标【推断】。