evomeme 0.1.7 → 0.1.9

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evomeme",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "evomemeplugin_client - local stdio MCP server. Install: npx -y evomeme@latest install --ide cursor. Init: npx -y evomeme@latest init.",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: evomeme-canvas
3
+ description: 在生成或编辑任何游戏素材前,必须确保当前工作区的 evomeme素材画布在用户可见,并把画布链接告知用户。当任务涉及生图、图片编辑、抠图、图层分离、视频生成或其他 evomeme素材工具时使用。
4
+ ---
5
+
6
+ # evomeme素材画布
7
+
8
+ 在调用任何素材生成或编辑工具前,先完成本技能的画布启动流程。画布必须对应当前任务的工作区。
9
+
10
+ ## 启动前检查
11
+
12
+ 只根据当前对话记录判断一个画布服务是否可复用,不得仅凭端口已占用或 `/api/health` 响应正常推断服务属于当前工作区。
13
+
14
+ - 当前对话中明确记录了由本次对话为同一工作区启动的前台画布终端和地址时,访问 `<画布地址>/api/health`;响应正常则复用,地址未知、健康检查失败或终端已关闭则重新启动。
15
+ - 当前对话中不存在画布启动记录时,即使发现已有 evomeme画布服务也不得复用。该服务可能属于其他工作区;先关闭已有服务,再按照下方流程为当前工作区启动新的前台服务。
16
+ - 当前对话记录中的画布属于其他工作区时,同样先关闭该服务,再为当前工作区重新启动。
17
+
18
+ 关闭已有服务时只关闭能够确认是 evomeme画布的进程,不得终止身份不明的端口占用进程。
19
+
20
+ ## 前台启动
21
+
22
+ 1. 在当前工作区根目录打开一个用户可见的独立交互式终端或命令框。
23
+ 2. 在该终端以前台方式执行且只执行:
24
+
25
+ ```text
26
+ npx -y evomeme@latest canvas
27
+ ```
28
+
29
+ 3. 保持这个终端打开。命令必须持续占用该终端,用户必须能够在其中按 `Ctrl+C`,或直接关闭终端窗口来停止服务。
30
+ 4. 等待终端输出“素材画布已启动”和“画布地址”。启动失败时,先处理或向用户说明错误,不得继续调用素材生成工具。
31
+
32
+ 不得将命令作为隐藏、分离或后台进程运行。不得使用 `&`、`nohup`、`start /B`、`Start-Job`、隐藏窗口、服务管理器或其他后台启动方式,也不要添加 `--no-open`。如果当前执行环境不能提供用户可见且可自行中断的终端,请让用户在可见终端中执行上述命令;确认启动输出或健康检查通过后再继续。
33
+
34
+ 画布终端保持前台运行不妨碍使用另一个终端或其他工具继续工作;不要为了继续生成而关闭画布终端。
35
+
36
+ ## 告知并引导用户
37
+
38
+ 取得终端实际输出的地址后,在调用第一个素材工具前立即向用户发送可点击链接,并说明:
39
+
40
+ - 保持画布终端打开;在终端中`Ctrl+C` 或关闭该终端会停止服务。
41
+ - 在画布中可以实时查看当前工作区的素材、生成任务状态和生成结果。
42
+ - 用户可以直接在画布中选择参考图、生成图片或继续编辑;AI 也会继续使用当前工作区的素材工具,结果会同步显示在画布中。
43
+
44
+ 使用实际地址,不要猜测端口。可以采用下面的简短表达:
45
+
46
+ ```markdown
47
+ 素材画布已启动:[打开 evomeme素材画布](<实际地址>)。请保持运行画布的命令行窗口打开;你可以在画布中监控任务,也可以直接选择参考图并使用生图或编辑功能。在命令行中按 Ctrl+C 或关闭该命令行即可停止服务。
48
+ ```
49
+
50
+ ## 生成期间
51
+
52
+ 确认画布可用并告知用户后,继续执行已经获得授权的素材任务,无需仅为打开画布再次请求确认。后续生成只能复用当前对话明确记录的同一工作区健康画布;如果服务中途停止,在下一次素材工具调用前重新完成启动流程。
@@ -0,0 +1,7 @@
1
+ interface:
2
+ display_name: "evomemeCanvas"
3
+ short_description: "在素材生成前启动并引导使用 evomeme素材画布"
4
+ default_prompt: "使用 $evomeme-canvas 启动当前工作区的素材画布,并在画布运行后继续生成素材。"
5
+
6
+ policy:
7
+ allow_implicit_invocation: true
@@ -57,15 +57,82 @@ evomeme平台只支持竖屏手机游戏。开发的游戏必须适配竖屏 UI
57
57
  - `src/`:存放主要开发代码。
58
58
  - `index.html`:作为游戏工程的网页入口。
59
59
 
60
- #### 代码依赖与发布路径
61
-
62
- - 项目内代码依赖必须使用相对路径,源码模块之间使用 `./` 或 `../` 引用;禁止写入本机绝对路径、工作区绝对路径、`file://` 地址或只能由开发服务器解析的源码 URL。
63
- - 构建工具必须使用相对发布基路径;Vite 项目设置 `base: "./"`,其他构建工具使用等价配置。运行时资源与配置使用 `./` 开头的相对 URL,例如 `fetch("./config.json")`,禁止假设游戏部署在域名根路径。
64
- - `dist/` 必须是可以独立部署的完整运行目录。`dist/index.html`、构建后的 JavaScript、CSS 和配置只能依赖 `dist/` 内文件或可公开访问的 `http://` / `https://` 资源。
65
- - 严禁 `dist/` 中任何运行时代码或页面回指 `src/`、`public/`、项目根目录、工作区文件、`localhost`、Vite 开发服务器或其他仅在开发环境存在的路径;禁止从 `dist/` 动态导入 `.ts`、`.tsx` 或其他未构建源码。
66
- - `dist/`内禁止存在任何二进制文件,包括图片、视频、音频、模型等。
67
- - 禁止通过复制源码到 `dist/` 来规避构建。源码依赖必须在生产构建时完成解析、打包或复制为真正的发布资源。
68
- - 发布前必须以 `dist/` 为静态服务根目录启动预览,并在该地址验证启动、资源加载和完整核心流程。开发服务器可以用于开发,但不能作为发布可用性的验收证据。
60
+ #### 代码依赖与发布路径
61
+
62
+ **强制交付门槛:** 只有生产构建命令(通常为 `npm run build`)以退出码 `0` 完成,生成真实且非空的 `dist/`,其中存在 `dist/index.html` 和全部被引用的本地文件,并通过本节的构建后路径检查,游戏任务才算完成。仅修改源码、开发服务器可运行、截图正常或推测“应该可以构建”,均不能作为交付结果。任一条件不满足时,必须继续修复、重新构建并重新检查。
63
+
64
+ 最终 `dist/` 可能被部署到任意 URL 子路径,不保证位于域名根目录。所有本地运行时引用都必须相对于当前文档或构建产物:
65
+
66
+ - 项目内代码依赖使用 `./` 或 `../`;禁止写入本机绝对路径、工作区绝对路径、`file://` 地址或只能由开发服务器解析的源码 URL。
67
+ - HTML 的本地 `src`、`href`、`poster`、`srcset`,CSS 的本地 `url(...)`,以及 JavaScript 的 `fetch()`、动态 `import()`、Worker、音频和其他本地资源地址,必须使用 `./...` 或等价相对路径。
68
+ - 严禁任何以单个 `/` 开头的本地根绝对路径,例如 `/assets/...`、`/asset/...`、`/config.json`、`/src/...`。应分别写为 `./assets/...`、`./asset/...`、`./config.json`、`./src/...`。
69
+ - 禁止通过 `location.origin`、`new URL(path, location.origin)` 或其他字符串拼接方式重新构造根绝对本地地址。
70
+ - 可公开访问的 `http://`、`https://` 远程 URL 不受本地相对路径规则限制。
71
+ - 修改现有项目时保留与任务无关的架构,但只要最终 `dist/` 仍包含根绝对本地引用,就必须做最小修复,不能交付。
72
+
73
+ ##### Vite 基址(强制)
74
+
75
+ 新建 Vite 项目必须创建 Vite 配置并显式设置 `base: './'`,不得依赖 Vite 默认值 `/`。React 项目示例:
76
+
77
+ ```js
78
+ import { defineConfig } from 'vite';
79
+ import react from '@vitejs/plugin-react';
80
+
81
+ export default defineConfig({
82
+ plugins: [react()],
83
+ base: './',
84
+ });
85
+ ```
86
+
87
+ 其他构建工具必须设置等价的相对发布基路径。
88
+
89
+ ##### 新建 React + Vite 项目的完整 `index.html`(强制)
90
+
91
+ 新建 React + Vite 项目必须使用以下源码入口格式。JavaScript 项目使用 `./src/main.jsx`;TypeScript 项目只将其替换为 `./src/main.tsx`。入口禁止写成 `/src/main.jsx` 或 `/src/main.tsx`。
92
+
93
+ ```html
94
+ <!doctype html>
95
+ <html lang="zh-CN">
96
+ <head>
97
+ <meta charset="UTF-8" />
98
+ <meta
99
+ name="viewport"
100
+ content="width=device-width,initial-scale=1,viewport-fit=cover,user-scalable=no"
101
+ />
102
+ <meta name="theme-color" content="#000000" />
103
+ <title>游戏名称</title>
104
+ </head>
105
+ <body>
106
+ <div id="root"></div>
107
+ <script type="module" src="./src/main.jsx"></script>
108
+ </body>
109
+ </html>
110
+ ```
111
+
112
+ CSS 应从入口模块通过 `import './style.css'` 等相对路径导入,不要在源码 `index.html` 中预写或猜测带哈希的构建文件名。Vite 构建后的 `dist/index.html` 必须使用相对构建资源路径,例如:
113
+
114
+ ```html
115
+ <script type="module" crossorigin src="./assets/index-HASH.js"></script>
116
+ <link rel="stylesheet" crossorigin href="./assets/index-HASH.css">
117
+ ```
118
+
119
+ `HASH` 代表 Vite 实际生成的哈希,不能硬编码。
120
+
121
+ ##### `dist/` 完整性和路径检查(阻断交付)
122
+
123
+ 每次生产构建完成后、宣布成功前,必须直接检查 `dist/index.html` 以及它引用的 JavaScript、CSS 和其他文本产物:
124
+
125
+ 1. 确认构建命令退出码为 `0`。
126
+ 2. 确认 `dist/` 真实存在且非空,并确认 `dist/index.html` 存在。
127
+ 3. 解析或逐一核对 `dist/index.html` 中的本地引用,确认每个目标文件真实存在于 `dist/` 内。
128
+ 4. 扫描 `dist/index.html`、构建后的 JavaScript 和 CSS,不得出现指向本地资源的 `src="/`、`src='/`、`href="/`、`href='/`、`poster="/`、`poster='/`、`url(/`、`fetch('/`、`fetch("/`、`import('/`、`import("/`、`new Worker('/`、`new Worker("/` 或等价根绝对形式。
129
+ 5. 明确检查并禁止 `/assets/...`、`/asset/...`、`/config.json`、`/src/...`;它们必须改为 `./assets/...`、`./asset/...`、`./config.json`、`./src/...` 或其他正确的相对路径。
130
+ 6. 检查 `dist/` 中不存在对 `src/`、`public/`、项目根目录、工作区文件、`localhost`、Vite 开发服务器、`.ts`、`.tsx` 或其他未构建源码的运行时依赖。
131
+ 7. 发现任何违规引用、缺失文件或不完整产物时,构建即判定无效;修复后必须重新执行生产构建,并从第 1 步重新检查。不能因为构建命令曾经退出码为 `0` 就跳过复查。
132
+
133
+ `dist/` 必须是可以独立部署的完整运行目录。`dist/index.html`、构建后的 JavaScript、CSS 和配置只能依赖 `dist/` 内文件或公开远程 URL。`dist/` 内禁止存在图片、视频、音频、字体、模型等二进制文件;这些素材必须通过公开 URL 接入。禁止通过复制源码到 `dist/` 规避构建,源码依赖必须在生产构建中正确解析和打包。
134
+
135
+ 发布前还必须以 `dist/` 为静态服务根目录启动预览,并在该地址验证启动、资源加载和完整核心流程。开发服务器可以用于开发,但不能作为发布验收证据。
69
136
 
70
137
  #### `/public/config.json` 规则
71
138
 
@@ -196,9 +263,13 @@ key 以 `_` 开头,用于内部配置、资源映射、版本号和调试开
196
263
  - [ ] `public/config.json` 以公开链接记录游戏使用的二进制素材。
197
264
  - [ ] 本地二进制文件路径已加入 `.evomemeignore`。
198
265
  - [ ] `.evomemeignore` 保持 `dist/` 在提交范围内。
199
- - [ ] `dist/` 来自完成资源链接替换后的最新生产构建。
200
- - [ ] 构建使用相对发布基路径;运行时配置和资源使用相对 URL,不依赖域名根路径。
201
- - [ ] `dist/` 可独立部署,且其中没有对 `src/`、`public/`、项目根目录、`localhost`、开发服务器或未构建源码的运行时依赖。
266
+ - [ ] `dist/` 来自完成资源链接替换后的最新生产构建。
267
+ - [ ] 生产构建命令以退出码 `0` 完成,`dist/` 非空并包含 `dist/index.html`。
268
+ - [ ] 新建 Vite 项目显式设置 `base: './'`;源码 `index.html` 使用 `./src/main.jsx` 或 `./src/main.tsx`。
269
+ - [ ] `dist/index.html` 中引用的每个本地文件均真实存在于 `dist/` 内。
270
+ - [ ] 已扫描 `dist/index.html` 及其引用的 JavaScript、CSS;不存在 `src="/`、`href="/`、`url(/`、`fetch('/`、`fetch("/`、`/assets/`、`/asset/`、`/config.json`、`/src/` 或等价根绝对本地引用。
271
+ - [ ] 构建使用相对发布基路径;运行时配置和资源使用 `./...` 或等价相对 URL,不依赖域名根路径,也不通过 `location.origin` 重建根路径。
272
+ - [ ] `dist/` 可独立部署,且其中没有对 `src/`、`public/`、项目根目录、`localhost`、开发服务器或未构建源码的运行时依赖。
202
273
  - [ ] 已以 `dist/` 为静态服务根目录完成预览,游戏能够启动、加载资源并跑通核心流程。
203
274
  - [ ] 提交文件集合只包含 UTF-8 文本文件。
204
275
  - [ ] 发布过程遵循 `evomeme-cloud-fs`。
@@ -1,59 +0,0 @@
1
- /**
2
- * 将序列帧拼成单张透明底图:按「先左到右、再换行向下」填格。
3
- */
4
-
5
- function loadImage(url) {
6
- return new Promise((resolve, reject) => {
7
- const img = new Image()
8
- img.onload = () => resolve(img)
9
- img.onerror = () => reject(new Error(`无法加载帧图:${url}`))
10
- img.src = url
11
- })
12
- }
13
-
14
- /**
15
- * @param {string[]} frameUrls
16
- * @param {{ rows: number, cols: number }} grid
17
- * @returns {Promise<string>} PNG data URL
18
- */
19
- export async function packSequenceSheet(frameUrls, { rows, cols }) {
20
- const r = Math.round(Number(rows))
21
- const c = Math.round(Number(cols))
22
- if (!Number.isFinite(r) || !Number.isFinite(c) || r < 1 || c < 1) {
23
- throw new Error('行数与列数需为正整数')
24
- }
25
- const frames = Array.isArray(frameUrls) ? frameUrls.filter(Boolean) : []
26
- if (!frames.length) throw new Error('序列没有可拼接的帧')
27
- if (r * c < frames.length) {
28
- throw new Error(`格子不足:${r}×${c}=${r * c},但有 ${frames.length} 帧`)
29
- }
30
-
31
- const images = await Promise.all(frames.map((url) => loadImage(url)))
32
- const cellW = Math.max(...images.map((img) => img.naturalWidth || img.width || 0))
33
- const cellH = Math.max(...images.map((img) => img.naturalHeight || img.height || 0))
34
- if (!(cellW > 0 && cellH > 0)) throw new Error('无法读取帧尺寸')
35
-
36
- const canvas = document.createElement('canvas')
37
- canvas.width = cellW * c
38
- canvas.height = cellH * r
39
- const ctx = canvas.getContext('2d')
40
- if (!ctx) throw new Error('无法创建画布')
41
- ctx.clearRect(0, 0, canvas.width, canvas.height)
42
-
43
- for (let i = 0; i < images.length; i++) {
44
- // 先从左到右填满一行,再换到下一行
45
- const row = Math.floor(i / c)
46
- const col = i % c
47
- ctx.drawImage(images[i], col * cellW, row * cellH)
48
- }
49
-
50
- return canvas.toDataURL('image/png')
51
- }
52
-
53
- /** 根据帧数给出接近方形的默认行列(行优先填充)。 */
54
- export function suggestSheetGrid(frameCount) {
55
- const n = Math.max(1, Math.round(Number(frameCount) || 1))
56
- const cols = Math.max(1, Math.ceil(Math.sqrt(n)))
57
- const rows = Math.max(1, Math.ceil(n / cols))
58
- return { rows, cols }
59
- }