@66rpg/lumimaker 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: lumimaker-play-sdk
3
+ description: 幻光社区播放页游戏宿主 SDK(window.CgMakerSdk)接入指引。在游戏内实现用户登录、展示昵称头像、查询游玩/购买权限(章节锁)、安全返回社区或进入全屏时使用。平台自动注入 SDK 脚本,严禁手动引入或打包 SDK 文件。
4
+ ---
5
+
6
+ # 游戏宿主 SDK(CgMakerSdk)
7
+
8
+ 游戏发布后,将在幻光社区的**播放页**(宿主环境)内通过 iframe 运行。宿主环境会在全局自动注入 `window.CgMakerSdk` 对象,为游戏提供登录验证、用户信息读取、游戏购买/游玩权限查询、安全跳转以及全屏播放等能力。
9
+
10
+ > **核心原则**:
11
+ > 1. **严禁在工程中引入 SDK 文件**:平台在发布时会自动将 SDK 注入游戏 HTML。**切勿**下载 `lumimaker-game.js`、**切勿**拷进 `dist/` 或源码、**切勿**手动编写 `<script src="...lumimaker-game.js">`。
12
+ > 2. **SDK 不负责画面渲染**:游戏的画布、UI 与核心玩法逻辑完全由您自己的代码绘制。
13
+ > 3. **本地开发无宿主**:本地使用 `npm run dev` 预览时无宿主环境,`ready()` 握手超时属于正常现象,无需进行 mock。
14
+
15
+ ---
16
+
17
+ ## 1. 适用场景
18
+
19
+ - **用户信息与登录**:需要在游戏内唤起社区登录、展示玩家昵称/头像,或保存玩家专属云端进度。
20
+ - **权限与章节锁**:根据用户是否已购买或是否拥有游玩权限,控制后续关卡锁或自制试玩结束提示。
21
+ - **页面导航与全屏**:在游戏界面提供“返回社区首页”、“查看作者主页”、“返回上一页”或“切换全屏”按钮。
22
+ - **环境疑问解答**:确认 SDK 是否需要 npm 安装、文件存放位置等疑问(无需安装,平台运行时注入)。
23
+
24
+ ---
25
+
26
+ ## 2. 快速接入示例
27
+
28
+ 在游戏代码中,仅通过 `window.CgMakerSdk` 与宿主进行通信。**切勿使用原生 `postMessage`,切勿尝试读取或操作 token**。
29
+
30
+ ```js
31
+ // 初始化并连接宿主播放页
32
+ async function initPlaySdk() {
33
+ const sdk = window.CgMakerSdk
34
+ if (!sdk) {
35
+ // 本地开发预览,或当前页面未运行在社区播放页中
36
+ return null
37
+ }
38
+
39
+ // 1. 与宿主建立握手(约 5 秒超时,超时不会抛出异常,而是返回 ready: false)
40
+ const { ready, context, error } = await sdk.ready()
41
+ if (!ready) {
42
+ console.debug('未连接到宿主环境(本地预览时此情况属正常现象):', error)
43
+ return null
44
+ }
45
+
46
+ // 2. 检查并按需请求登录(如未登录,引导用户唤起社区登录弹窗)
47
+ if (!sdk.isLoggedIn()) {
48
+ try {
49
+ await sdk.requireLogin()
50
+ } catch (err) {
51
+ if (err && err.code === 'LOGIN_CANCELLED') {
52
+ // 用户主动关闭了登录弹窗,游戏可继续以访客模式运行
53
+ console.log('用户取消了登录')
54
+ return null
55
+ }
56
+ throw err
57
+ }
58
+ }
59
+
60
+ // 3. 查询当前游戏在社区的发布信息与权限
61
+ const gameInfo = await sdk.queryGame()
62
+ // 可根据 gameInfo.can_play / gameInfo.purchased 控制游戏内的章节锁等自制 UI
63
+ // 注意:切勿使用 gameInfo.play_url 强行进行页面重定向
64
+
65
+ // 4. 监听环境与登录态变化(如用户在外部切换语言或完成登录)
66
+ const unbind = sdk.onChange((nextContext) => {
67
+ // 收到环境变化,在此处刷新游戏内的个人信息或文案
68
+ })
69
+
70
+ return { sdk, context, gameInfo, unbind }
71
+ }
72
+
73
+ // 页面加载完成后调用
74
+ initPlaySdk().then((host) => {
75
+ if (!host) return
76
+
77
+ // 示例:按钮点击事件绑定
78
+ // document.getElementById('btn-home').onclick = () => host.sdk.navigateHome()
79
+ // document.getElementById('btn-author').onclick = () => host.sdk.navigateAuthorPage()
80
+ // document.getElementById('btn-back').onclick = () => host.sdk.navigateBack()
81
+ // document.getElementById('btn-fullscreen').onclick = () => host.sdk.requestFullscreen()
82
+
83
+ // 页面卸载或组件销毁时,解除监听
84
+ // window.addEventListener('unload', () => host.unbind())
85
+ })
86
+ ```
87
+
88
+ ---
89
+
90
+ ## 3. TypeScript 类型声明(可选)
91
+
92
+ 若使用 TypeScript 开发,可将以下全局声明加入项目声明文件(如 `src/env.d.ts`):
93
+
94
+ ```ts
95
+ export {}
96
+
97
+ declare global {
98
+ interface Window {
99
+ CgMakerSdk?: {
100
+ version: string
101
+ ready(): Promise<{ ready: boolean; context: CgMakerContext | null; error?: string }>
102
+ isReady(): boolean
103
+ getError(): string | null
104
+ getContext(): CgMakerContext | null
105
+ onChange(fn: (context: CgMakerContext) => void): () => void
106
+ isLoggedIn(): boolean
107
+ requireLogin(): Promise<void>
108
+ queryGame(): Promise<CgMakerGameInfo>
109
+ queryUser(): Promise<CgMakerUserInfo>
110
+ navigateHome(): void
111
+ navigateAuthorPage(): void
112
+ navigateBack(): void
113
+ requestFullscreen(): Promise<void>
114
+ exitFullscreen(): Promise<void>
115
+ }
116
+ }
117
+
118
+ interface CgMakerContext {
119
+ gameId: string
120
+ lang: string
121
+ user: CgMakerUserInfo | null
122
+ variant: 1 | 2 | 3 // 1 正式版 · 2 试玩版 · 3 衍生版
123
+ }
124
+
125
+ interface CgMakerUserInfo {
126
+ username: string
127
+ nickname: string
128
+ avatar: string
129
+ }
130
+
131
+ interface CgMakerGameInfo {
132
+ game_id: string
133
+ owner: string
134
+ name: string
135
+ summary: string
136
+ cover_url: string
137
+ variant: number
138
+ can_play: boolean
139
+ purchased: boolean
140
+ play_url: string
141
+ }
142
+ }
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 4. 核心规范与操作红线
148
+
149
+ 1. **宿主注入与源码纯净**:
150
+ - **绝对不要**将 `lumimaker-game.js` 文件放入工程或产物目录中。
151
+ - **绝对不要**在 HTML 中手动写 `<script src="...lumimaker-game.js">`,发版时系统会自动安全注入。
152
+ 2. **安全通信边界**:
153
+ - 严禁自行调用 `window.parent.postMessage`,严禁尝试向父级页面读取、打印或篡改鉴权 token。
154
+ - 严禁在游戏内自行实现社区账号登录、签发 token、创建订单或支付逻辑,所有交互均通过 SDK 提供的标准方法交由宿主承接。
155
+ 3. **页面导航红线**:
156
+ - 严禁使用 `window.top.location` 进行整页重定向。
157
+ - 页面返回与跳转必须且仅能调用 `navigateHome()`、`navigateAuthorPage()`、`navigateBack()` 等无参方法,切勿向方法中传递自定义 URL。
158
+ - 切勿使用 `queryGame()` 返回的 `play_url` 进行跳转。
159
+ 4. **权限与购买体验**:
160
+ - 正式版游戏未获游玩授权时,宿主播放页会自动覆盖平台购买界面,根本不会加载游戏 iframe。
161
+ - 游戏内只需根据 `can_play` / `purchased` 处理“已经进入游戏后”的章节锁或提示,**切勿在游戏内自制并复刻社区的购买结算弹窗**。
162
+ 5. **本地开发调试预期**:
163
+ - 本地 `npm run dev` 阶段不存在宿主环境,`sdk.ready()` 握手超时为正常情况,请做好判空保护,**不要在本地伪造假登录或假用户数据**。
164
+ - 游戏内的图片、音效、字体等资源依然遵循工程本地化原则,严禁使用 SDK 请求未经打包的在线 CDN 资源。
165
+
166
+ ---
167
+
168
+ ## 5. API 完整参考
169
+
170
+ 详细的方法签名、字段解释与错误码对照表,请查阅 [API 接口规范细则](references/api.md)。
@@ -0,0 +1,100 @@
1
+ # CgMakerSdk 接口规范细则
2
+
3
+ 全局挂载对象为 `window.CgMakerSdk`。当游戏发布到平台并在社区播放页(iframe)中运行时,平台宿主会自动将此对象注入到全局环境中。
4
+
5
+ ---
6
+
7
+ ## 1. 生命周期与上下文
8
+
9
+ ### 1.1 核心方法
10
+
11
+ | 方法 / 属性 | 返回类型 | 功能与使用说明 |
12
+ |---|---|---|
13
+ | `version` | string | 当前 SDK 脚本的版本号字符串(如 `"0.1.0"`)。 |
14
+ | `ready()` | `Promise<{ ready: boolean; context: CgMakerContext \| null; error?: string }>` | 与宿主播放页握手建立连接。<br>• 握手超时时间约为 5 秒。<br>• **超时不会抛出异常**,而是返回 `ready: false`,并在 `error` 字段中说明“等待主站数据超时”(本地预览时属正常表现)。 |
15
+ | `isReady()` | boolean | 检查当前是否已成功完成握手并获取到环境上下文。 |
16
+ | `getError()` | string \| null | 获取最近一次握手失败的具体错误信息。 |
17
+ | `getContext()` | CgMakerContext \| null | 直接获取当前环境上下文对象(未握手成功时返回 `null`)。上下文内不包含敏感 token。 |
18
+ | `onChange(fn)` | `() => void` | 监听环境上下文或用户登录态的变化(如外部切换了语言或登录状态改变)。<br>• 参数 `fn` 接收最新的 `context` 对象。<br>• **必须保存并调用该方法的返回值以取消事件监听**,避免组件销毁后造成内存泄漏。 |
19
+ | `isLoggedIn()` | boolean | 快捷检查当前是否已有用户登录态。 |
20
+ | `getGameId()` | string \| null | 快捷获取当前游戏的唯一标识 ID。 |
21
+ | `getUser()` | CgMakerUserInfo \| null | 快捷获取当前已登录用户的基本信息。 |
22
+
23
+ ### 1.2 环境上下文对象 (`CgMakerContext`)
24
+
25
+ 调用 `getContext()` 或握手成功后返回的上下文结构如下:
26
+
27
+ | 字段 | 类型 | 说明 |
28
+ |---|---|---|
29
+ | `gameId` | string | 当前作品在平台上的全局游戏 ID。 |
30
+ | `lang` | string | 播放页当前的语言代码(如 `"zh"`、`"en"` 等)。 |
31
+ | `user` | object \| null | 当前登录的用户信息对象(未登录时为 `null`),包含 `username`、`nickname`、`avatar`。 |
32
+ | `variant` | number | 当前作品的版本形态:`1` 正式版 · `2` 试玩版(demo) · `3` 衍生版。 |
33
+ | `parentOrigin` | string | 仅供 SDK 内部验证跨域消息来源的安全字段,游戏业务逻辑切勿依赖此字段。 |
34
+
35
+ ---
36
+
37
+ ## 2. 账号与登录认证
38
+
39
+ | 方法 | 返回类型 | 功能与使用说明 |
40
+ |---|---|---|
41
+ | `requireLogin()` | `Promise<void>` | 要求用户进行登录。<br>• 若当前已处于登录状态,Promise 将立即以成功状态 resolve。<br>• 若当前未登录,宿主将弹出社区官方登录窗口。<br>• 若用户主动关闭或取消登录窗口,Promise 将以带有错误码 `LOGIN_CANCELLED` 的异常 reject。 |
42
+
43
+ > **提示**:未登录时,试玩版(demo)通常仍允许玩家离线体验基础内容;但此时调用 `queryGame()` 或 `queryUser()` 均会抛出 `NOT_LOGGED_IN` 错误。
44
+
45
+ ---
46
+
47
+ ## 3. 游戏与用户信息查询
48
+
49
+ 调用查询接口前,必须已处于登录状态,否则接口将返回错误码 `NOT_LOGGED_IN`。**严禁在游戏内自行携带 Cookie 请求社区后端接口**。
50
+
51
+ | 方法 | 返回类型 | 功能与使用说明 |
52
+ |---|---|---|
53
+ | `queryGame()` | `Promise<CgMakerGameInfo>` | 查询当前游戏作品在平台的发布信息、价格及游玩授权状态。 |
54
+ | `queryUser()` | `Promise<CgMakerUserInfo>` | 查询当前已登录用户的详细个人资料(包含 `username`、`nickname`、`avatar`)。 |
55
+
56
+ ### `queryGame()` 返回常用字段一览
57
+
58
+ | 字段名称 | 数据类型 | 说明与业务指引 |
59
+ |---|---|---|
60
+ | `game_id` | string | 作品 ID。 |
61
+ | `name` | string | 作品在平台显示的名称。 |
62
+ | `owner` | string | 作品作者的平台用户名。 |
63
+ | `summary` | string | 作品简介摘要。 |
64
+ | `cover_url` | string | 封面图地址。 |
65
+ | `variant` | number | 作品形态:`1` 正式版 · `2` 试玩版。 |
66
+ | `parent_game_id`| string \| null | 若为试玩版,对应关联的正式版游戏 ID。 |
67
+ | `price_flower` | number | 作品标价(鲜花数)。 |
68
+ | `price_cny` | number | 作品人民币售价(分)。 |
69
+ | `status` | number | 作品状态:`1` 正常启用 · `2` 已禁用。 |
70
+ | `purchased` | boolean | 当前登录用户是否已购买该可售作品(未购买时为 `false`)。 |
71
+ | `can_play` | boolean | 当前用户当前是否具备游玩权限。游戏可用此字段控制后续章节锁。 |
72
+ | `play_url` | string | 播放链接。**严禁使用此 URL 自行进行页面重定向**。 |
73
+
74
+ ---
75
+
76
+ ## 4. 页面导航与全屏控制
77
+
78
+ 为保证运行沙箱安全,页面跳转与全屏控制**只允许调用以下无参方法**。严禁直接操作 `window.top.location`,切勿向这些方法中传入自定义 URL。
79
+
80
+ | 方法 | 返回类型 | 功能与说明 |
81
+ |---|---|---|
82
+ | `navigateHome()` | void | 触发播放器外壳返回幻光社区首页。 |
83
+ | `navigateAuthorPage()`| void | 触发播放器外壳打开该作品作者的社区个人主页。 |
84
+ | `navigateBack()` | void | 触发返回上一级页面(若外壳无上一页历史,默认返回作品社区帖子)。 |
85
+ | `requestFullscreen()`| `Promise<void>` | 请求将**播放器整体外壳**切换至全屏状态(全屏由外壳容器承接,游戏无需自改样式)。 |
86
+ | `exitFullscreen()` | `Promise<void>` | 请求退出播放器外壳的全屏状态。 |
87
+
88
+ ---
89
+
90
+ ## 5. 错误码与异常处理
91
+
92
+ 当 SDK 方法调用失败时,抛出的错误对象(`CgMakerError`)通常包含 `code` 属性。常见错误码对照如下:
93
+
94
+ | 错误代码 (`code`) | 触发场景 | 推荐处理方案 |
95
+ |---|---|---|
96
+ | `NOT_LOGGED_IN` | 当前用户未登录,或调用 `queryGame` / `queryUser` 时鉴权未通过。 | 引导调用 `requireLogin()` 完成登录,或在游戏内提示访客限制。 |
97
+ | `LOGIN_CANCELLED` | 唤起登录窗口后,用户主动点击关闭或取消。 | 视为非致命取消操作,允许玩家继续游玩未锁定关卡或保留在当前界面。 |
98
+ | `TIMEOUT` | 跨窗口握手通信超时或请求宿主桥接超时(注:`ready()` 超时仅返回 `ready: false`,不抛出本错误)。 | 检查运行环境是否处于沙箱异常状态,做好容错兜底。 |
99
+ | `FULLSCREEN_DENIED`| 浏览器安全策略拦截全屏请求(例如未在真实用户点击手势内调用)。 | 确保仅在按钮的 `click` 等显式手势回调中调用 `requestFullscreen()`。 |
100
+ | `FAILED` | 其他未知系统级或通信层错误。 | 记录调试日志,对用户展示通用重试提示。 |
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: lumimaker-template-spec
3
+ description: 幻光 lumimaker 模板工程规范。用户准备发布模板、做模板、询问工程是否符合模板规范,或调整模板目录、scripts 脚本、package.json 字段与 dist 产物时使用。不符合时对照模板规范协议调整适配。
4
+ ---
5
+
6
+ # 模板规范指引
7
+
8
+ 本技能用于验证当前工程是否符合幻光平台模板规范,并在不合规时引导进行标准化调整。
9
+
10
+ 所有硬性规则与格式要求均以 [模板规范协议](references/protocol.md) 为唯一事实来源。本技能仅提供操作流程与排查指引。
11
+
12
+ ---
13
+
14
+ ## 协作分工
15
+
16
+ - **规范校验与结构调整**:使用本技能(`lumimaker-template-spec`)。
17
+ - **账号登录与发布操作**:使用同套工具提供的 `lumimaker`。
18
+ - **模板特定玩法逻辑**:查阅工程根目录下模板自带的 `skill/SKILL.md`(若有)。
19
+
20
+ ---
21
+
22
+ ## 操作步骤
23
+
24
+ ### 1. 运行规范校验
25
+
26
+ 在模板工程根目录下执行:
27
+
28
+ ```bash
29
+ npx lumimaker validate-template
30
+ ```
31
+
32
+ - **校验通过**:工程结构合规,可继续执行后续发布。
33
+ - **校验未通过**:控制台将提示不合规的具体路径与原因,按下方步骤调整。
34
+
35
+ ### 2. 对照协议调整适配
36
+
37
+ 若校验未通过,根据控制台指出的不合规项,直接查阅 [模板规范协议](references/protocol.md) 的对应章节进行针对性修复:
38
+
39
+ - 涉及文件或目录缺失:对照协议第 1 节(目录结构)补齐必要项。
40
+ - 涉及配置或脚本问题:对照协议第 2 节(package.json)核对字段格式与脚本要求。
41
+ - 涉及构建输出问题:对照协议第 3 节(构建产物)检查产物目录与入口。
42
+
43
+ > **原则**:仅针对报错项和协议明确约定的内容做修改;协议未约定的文件和配置保持原样,切勿随意变动。
44
+
45
+ ### 3. 复验直至通过
46
+
47
+ 完成调整后,重新执行校验:
48
+
49
+ ```bash
50
+ npx lumimaker validate-template
51
+ ```
52
+
53
+ 校验通过后,即可按照 `lumimaker` 技能指引进行模板发布。
@@ -0,0 +1,113 @@
1
+ # 幻光 lumimaker 模板规范协议
2
+
3
+ | 项 | 内容 |
4
+ |---|---|
5
+ | 协议版本 | 1.0 |
6
+ | 最新更新 | 2026-09-22 |
7
+ | 修订日期 | 2026-09-22 |
8
+
9
+ 本协议约定幻光平台模板工程的基础结构、`package.json` 配置与构建产物要求。未在本文中列出的目录、文件与配置字段,均不属于本协议的约定范围。
10
+
11
+ **约束用词定义**:
12
+ - **必须**:模板工程必须满足的硬性要求,未满足则视为不合规。
13
+ - **可选**:模板工程可自行决定是否提供;若提供,须符合本协议规定的格式。
14
+ - **建议**:推荐的最佳实践做法,不作为合规与否的判断条件。
15
+
16
+ ---
17
+
18
+ ## 1. 目录结构
19
+
20
+ 模板工程根目录即为项目的源码根目录。
21
+
22
+ ### 1.1 结构全景
23
+
24
+ ```text
25
+ .
26
+ ├── package.json # 必须:工程配置与脚本清单
27
+ ├── README.md # 必须:模板使用说明(供人阅读)
28
+ ├── AGENTS.md # 必须:AI 协同指南(说明工程结构与修改建议)
29
+ ├── src/ # 必须:模板源代码目录
30
+ ├── assets/ # 可选:模板资源目录(包含游戏数据、图片、音频等;若有资源放入此目录,也可没有任何资源,纯 index.html)
31
+ └── skill/ # 可选:模板自带的玩法技能目录
32
+ └── SKILL.md # 可选:供 AI 阅读的玩法说明
33
+ ```
34
+
35
+ ### 1.2 目录与文件说明
36
+
37
+ | 路径 | 属性 | 作用与要求 |
38
+ |---|---|---|
39
+ | `package.json` | **必须** | 模板工程的包清单,声明平台展示名、英文标识、版本号、数据包版本与必要脚本。详见第 2 节。 |
40
+ | `README.md` | **必须** | 供创作者阅读的工程说明与使用指引。 |
41
+ | `AGENTS.md` | **必须** | 供 AI 助手阅读的协同指南,须明确说明工程组织方式与推荐的修改位置(若包含 `assets/` 须说明其子目录划分)。 |
42
+ | `src/` | **必须** | 模板的完整源代码目录,不限制编程语言或开发框架(如 React、Vue、Pixi、原生 Canvas 均可)。 |
43
+ | `assets/` | **可选** | 模板的资源目录(包含游戏数据、图片、音频、样式等)。若模板包含静态资源,统一存放于此;也可以没有任何资源文件或不创建此目录,工程最终可仅依赖纯 `index.html` 运行。 |
44
+ | `skill/SKILL.md` | **可选** | 本模板特定的玩法技能说明文件,指导 AI 助手如何协助创作者调整游戏规则。若无独立玩法技能可不提供。 |
45
+
46
+ ---
47
+
48
+ ## 2. package.json
49
+
50
+ `package.json` 文件必须位于工程根目录,且内容为合法的 JSON 对象。
51
+
52
+ ### 2.1 基础配置字段
53
+
54
+ 所有字段集中约定如下:
55
+
56
+ | 字段 | 属性 | 数据类型 | 格式与要求 | 示例 |
57
+ |---|---|---|---|---|
58
+ | `name` | **必须** | string | 平台展示名称,供人阅读,支持中文;去掉首尾空格后长度至少为 1;不能包含字符 `/` 或 `@`。 | `"趣味问答"`、`"quiz-react"` |
59
+ | `slug` | **必须** | string | 模板英文短名,在平台中唯一标识本模板;格式须匹配 `^[a-z0-9][a-z0-9-]{0,62}$`。详见下方细则。 | `"quiz-react"` |
60
+ | `version` | **必须** | string | 模板版本号;格式须匹配 `^(?=.{1,16}$)[a-z0-9]+(?:[.-][a-z0-9]+)*$`。详见下方细则。 | `"0.1.0"`、`"1.0.0-a"` |
61
+ | `data_ver` | **必须** | string 或 number | 配套数据包版本;非空字符串或有限数字。详见下方细则。 | `"1"` 或 `1` |
62
+ | `description` | **可选** | string | 模板简介说明。若省略,默认取值视为空字符串 `""`;若填写,允许为空字符串。 | `"基于 React 的题库答题游戏模板"` |
63
+
64
+ #### 字段格式细则
65
+
66
+ - **`slug`(英文短名)**
67
+ - 正则表达式:`^[a-z0-9][a-z0-9-]{0,62}$`
68
+ - 长度限制:1 至 63 个字符。
69
+ - 字符范围:仅允许小写英文字母(`a-z`)、数字(`0-9`)和连字符(`-`)。
70
+ - 起始字符:必须以小写字母或数字开头(首字符不能是连字符 `-`)。
71
+
72
+ - **`version`(模板版本号)**
73
+ - 正则表达式:`^(?=.{1,16}$)[a-z0-9]+(?:[.-][a-z0-9]+)*$`
74
+ - 长度限制:1 至 16 个字符。
75
+ - 字符范围:仅允许小写英文字母(`a-z`)、数字(`0-9`)、英文点号(`.`)和连字符(`-`)。
76
+ - 边界要求:必须以小写字母或数字开头,且以小写字母或数字结尾。
77
+ - 连续符号限制:点号与连字符不能相邻或连续出现(例如禁止 `..`、`--`、`.-`、`-.`)。
78
+ - 合法示例:`0.1.0`、`1.0.0-a`、`1.0.0-rc1`。
79
+
80
+ - **`data_ver`(数据包版本)**
81
+ - 当类型为字符串(string)时:去除首尾空白字符后,长度至少为 1。示例:`"1"`。
82
+ - 当类型为数字(number)时:必须为合法的有限数值。示例:`1`。
83
+
84
+ ### 2.2 必须脚本命令 (`scripts`)
85
+
86
+ `package.json` 中的 `scripts` 字段必须为对象,且必须包含以下 5 个指定脚本。每个脚本对应的值必须为字符串,且去除首尾空白后不可为空。脚本的具体执行命令由模板自身的技术栈决定。
87
+
88
+ | 脚本名称 | 属性 | 作用与要求 |
89
+ |---|---|---|
90
+ | `dev` | **必须** | 启动正式内容的本地开发服务。 |
91
+ | `dev:demo` | **必须** | 启动试玩内容的本地开发服务。若模板未制作独立的试玩内容,命令可与 `dev` 保持完全一致。 |
92
+ | `build` | **必须** | 构建正式版产物到根目录 `dist/`。详见第 3 节。 |
93
+ | `build:demo` | **必须** | 构建试玩版产物到根目录 `dist/`。若模板未制作独立的试玩内容,命令可与 `build` 保持完全一致。 |
94
+ | `validate` | **必须** | 执行模板自身的数据检查。若模板包含独立的试玩数据,此单条脚本须同时覆盖正式数据与试玩数据的校验。 |
95
+
96
+ ---
97
+
98
+ ## 3. 构建产物 (dist/)
99
+
100
+ 构建产物用于静态托管与作品发布,统一约定如下:
101
+
102
+ 1. **产物目录**:`scripts.build` 与 `scripts.build:demo` 的输出目录必须是工程根目录下的 `dist/`,两者共用该目录。
103
+ 2. **入口文件**:`dist/` 根目录下**必须**产出 `index.html` 入口文件。可以仅产出纯 `index.html`,无需任何其他静态资源文件。
104
+ 3. **静态资源(建议)**:若构建产物包含 JavaScript、CSS、图片等静态资源,建议放置于与 `index.html` 同级的 `dist/assets/` 目录下。
105
+ 4. **其他产物**:除 `dist/index.html` 外,产物目录内的其他文件组织形式本协议不作强制限制。
106
+
107
+ ---
108
+
109
+ ## 修订记录
110
+
111
+ | 文档版本 | 修订日期 | 变更说明 |
112
+ |---|---|---|
113
+ | 1.0 | 2026-09-22 | 初始版本。明确工程目录结构、`package.json` 配置字段与脚本规范,以及 `dist/` 构建产物约定(assets 为可选,支持纯 index.html)。 |
@@ -0,0 +1,14 @@
1
+ {
2
+ "projectSkillDirs": [
3
+ ".agents/skills",
4
+ ".cursor/skills",
5
+ ".claude/skills",
6
+ ".codex/skills",
7
+ ".opencode/skills",
8
+ ".codebuddy/skills",
9
+ ".workbuddy/skills",
10
+ ".trae/skills",
11
+ ".kimi/skills",
12
+ ".qwen/skills"
13
+ ]
14
+ }