Merge branch 'codex/memind-long-image-playwright'
This commit is contained in:
+28
-2
@@ -6,10 +6,12 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const PUBLISH_SKILL_NAME = 'static-page-publish';
|
||||
export const DOCX_SKILL_NAME = 'docx-generate';
|
||||
export const LONG_IMAGE_SKILL_NAME = 'long-image-download';
|
||||
export const PUBLISH_ROOT_DIR = 'MindSpace';
|
||||
export const PUBLIC_ZONE_DIR = 'public';
|
||||
export const PUBLISH_SKILL_DIR = path.join(__dirname, 'skills', PUBLISH_SKILL_NAME);
|
||||
export const DOCX_SKILL_DIR = path.join(__dirname, 'skills', DOCX_SKILL_NAME);
|
||||
export const LONG_IMAGE_SKILL_DIR = path.join(__dirname, 'skills', LONG_IMAGE_SKILL_NAME);
|
||||
export const WORKSPACE_HINTS_FILENAME = '.tkmindhints';
|
||||
export const LEGACY_WORKSPACE_HINTS_FILENAME = '.goosehints';
|
||||
|
||||
@@ -141,7 +143,7 @@ description: 在专属 MindSpace 目录生成可公开访问的静态 HTML 报
|
||||
|
||||
1. **唯一可写目录**:\`${publishDir}\`
|
||||
2. **禁止**使用绝对路径(如 \`/Users/...\`、\`../\` 跳出目录)
|
||||
3. **允许**在本目录内使用 \`write_file\`、\`edit_file\`、\`read_file\`、\`list_dir\`、\`generate_docx\`;**禁止**访问此目录外的路径(含 \`../\`、其它用户目录、项目根目录;系统会在 OS 层拦截越界访问)
|
||||
3. **允许**在本目录内使用 \`write_file\`、\`edit_file\`、\`read_file\`、\`list_dir\`、\`generate_docx\`、\`generate_long_image\`;**禁止**访问此目录外的路径(含 \`../\`、其它用户目录、项目根目录;系统会在 OS 层拦截越界访问)
|
||||
4. **禁止**子 Agent、扩展管理、修改工作区外文件
|
||||
5. 页面默认写入 \`public/\` 分区,使用相对路径如 \`public/report.html\`、\`public/assets/chart.png\`
|
||||
6. 生成 HTML 后,向用户提供可访问链接,格式:
|
||||
@@ -156,7 +158,8 @@ description: 在专属 MindSpace 目录生成可公开访问的静态 HTML 报
|
||||
4. 页面内资源使用**相对路径**(\`assets/foo.png\`),不要用磁盘绝对路径
|
||||
5. 保存 HTML 后,服务端会**立即**生成同名预览图 \`<文件名>.thumbnail.svg\`(Agent 交互阶段即生效,无需等用户保存到「我的空间」)
|
||||
6. 下载按钮的相对链接目标(如 \`public/report.docx\`)必须通过 \`generate_docx\` 落盘,且 basename 与 HTML 一致
|
||||
7. 完成后按「回复格式」返回可点击链接
|
||||
7. 若用户要求长图下载,必须先 \`load_skill\` → \`long-image-download\`,调用 \`generate_long_image\` 生成并确认 \`public/<页面名>.long.png\` 已存在
|
||||
8. 完成后按「回复格式」返回可点击链接
|
||||
|
||||
## 伴生下载文件(必须)
|
||||
|
||||
@@ -186,6 +189,7 @@ description: 在专属 MindSpace 目录生成可公开访问的静态 HTML 报
|
||||
- 标题用页面真实主题(不要用「点击这里」「链接」)
|
||||
- 可同时给出本地相对路径(如 \`public/pilates-618.html\`)与公网链接
|
||||
- 说明:静态文件保存即生效,**无需重启**
|
||||
- 若生成了长图,同时给 \`[长图预览](.../public/pilates-618.long.png)\` 和 \`[下载长图](.../public/pilates-618.html?download=long-image)\`
|
||||
|
||||
## 信息流预览图(必须)
|
||||
|
||||
@@ -241,6 +245,7 @@ description: 在专属 MindSpace 目录生成可公开访问的静态 HTML 报
|
||||
- shell 仅用于本目录内整理文件/简单脚本;不要 \`rm -rf\` 越界路径、不要安装系统级依赖
|
||||
- **禁止**在 HTML 中用 \`data:...;base64,...\` 内嵌 Word/PDF;二进制文件单独落盘后用相对路径链接(见 \`docx-generate\` 技能)
|
||||
- 用户要求 Word / docx 下载时,禁止跳过 \`docx-generate\` 直接在 HTML 中伪造下载链接
|
||||
- 用户要求长图下载时,禁止跳过 \`long-image-download\` 或把 \`.thumbnail.svg\` 当成长图
|
||||
|
||||
## 示例
|
||||
|
||||
@@ -282,6 +287,13 @@ ${renderBrandingBlock(addressName)}
|
||||
- 若用户要求页面里可下载 Word / docx:必须先 \`load_skill\` → \`docx-generate\`
|
||||
- 先生成并确认 \`public/*.docx\` 已存在,再写 \`public/*.html\`
|
||||
- HTML 中只能用同目录相对路径链接该文档,禁止只写下载按钮却没有先把 \`.docx\` 落盘
|
||||
|
||||
## 长图下载
|
||||
|
||||
- 若用户要求长图下载:必须先 \`load_skill\` → \`long-image-download\`
|
||||
- 调用 \`generate_long_image\` 生成 \`public/<页面名>.long.png\`
|
||||
- 先确认 \`public/*.long.png\` 已存在,再回复 \`[长图预览](...long.png)\` 和 \`[下载长图](...html?download=long-image)\`
|
||||
- \`.thumbnail.svg\` 只是信息流封面,不能当成长图
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -322,11 +334,13 @@ export function buildSandboxSessionConstraints({ baseConstraints, developerTools
|
||||
'- 你有 write_file/edit_file 工具:**必须由你**写入 `public/xxx.html`(或工作区根目录 `.html`)',
|
||||
'- 开始前执行 load_skill → `static-page-publish`,按技能说明写入 mindspace-cover 元数据',
|
||||
'- 如果用户要求 Word / docx 下载:先 `load_skill` → `docx-generate`,生成并确认 `public/*.docx` 已存在,再写 HTML 用相对路径链接',
|
||||
'- 如果用户要求长图下载:先 `load_skill` → `long-image-download`,调用 `generate_long_image` 生成并确认 `public/*.long.png` 已存在,再回复长图预览与下载链接',
|
||||
'- **禁止**用 shell / cat / heredoc / echo / cp 写入 HTML;shell 在容器内执行,文件不会出现在公网 MindSpace 路径',
|
||||
'- 用 `apps__create_app` 设计页面时,最后仍要按 `static-page-publish` skill 把内容 write_file 落到 `public/`,才有公网链接',
|
||||
'- **禁止**让用户手动保存到 public 或说无法生成页面(除非 write_file 调用失败)',
|
||||
'- 完成后回复 `[页面标题](公网URL)` 可点击链接;写入 `public/` 时 URL 必须含 `/public/` 路径段;按本会话给出的公网前缀模板拼接真实地址',
|
||||
'- 下载附件:Word 用 `generate_docx` 写入 `public/*.docx`,相对链接文件必须已在 `public/` 落盘,basename 与 HTML 一致',
|
||||
'- 长图附件:用 `generate_long_image` 写入 `public/*.long.png`,不要把 `.thumbnail.svg` 当成长图',
|
||||
);
|
||||
return lines.join('\n');
|
||||
}
|
||||
@@ -346,6 +360,7 @@ export function buildPublishConstraints({ slug, username, publicBaseUrl, publish
|
||||
'- **路径规则**:只用相对路径;禁止 `../`;工作区外的路径会被系统拒绝(OS 层强制,非软约束)',
|
||||
'- **生成页面(必须亲自完成)**:先 `load_skill` → `static-page-publish`,再用 `write_file`/`edit_file` 写入 `public/页面.html`',
|
||||
'- **Word 下载页(必须亲自完成)**:若用户要求 Word / docx 下载,必须先 `load_skill` → `docx-generate`,生成并确认 `public/*.docx` 已存在,再在 HTML 中用相对路径链接',
|
||||
'- **长图下载(必须亲自完成)**:若用户要求长图下载,必须先 `load_skill` → `long-image-download`,调用 `generate_long_image` 生成并确认 `public/*.long.png` 已存在',
|
||||
'- **用户可见回复**:不要向用户复述 load_skill、技能更新、页脚标记、mindspace-cover 等内部实现;完成后直接给出页面链接或结果',
|
||||
'- **禁止**用 shell 写入 HTML;**禁止**让用户「手动保存到 public 目录」或说「我无法生成页面」——除非 write_file 已失败并报告错误',
|
||||
'- 完成后给出 Markdown 可点击公网链接 `[标题](URL)`;写入 `public/页面.html` 时 URL 为 `.../MindSpace/<用户ID>/public/页面.html`',
|
||||
@@ -354,6 +369,7 @@ export function buildPublishConstraints({ slug, username, publicBaseUrl, publish
|
||||
'- **禁止**让用户「手动保存到 public 目录」或说「我无法生成页面」——除非 write_file 已失败并报告错误',
|
||||
'- 完成后给出 Markdown 可点击公网链接 `[标题](URL)`;写入 `public/页面.html` 时 URL 为 `.../MindSpace/<用户ID>/public/页面.html`,按模板拼真实地址',
|
||||
'- 下载链接(如 `report.docx`)必须与 HTML 同目录且文件名一致;Word 必须用 sandbox-fs `generate_docx` 生成,不要用 `computercontroller` / shell 作为交付依据',
|
||||
'- 长图链接:生成 `report.long.png` 后给 `[长图预览](.../report.long.png)`,下载用 `[下载长图](.../report.html?download=long-image)`',
|
||||
`- 发布技能:\`${PUBLISH_SKILL_NAME}\`(生成页面前应 load_skill)`,
|
||||
].join('\n');
|
||||
}
|
||||
@@ -378,8 +394,18 @@ export function ensureDocxSkillInstalled(publishDir) {
|
||||
return path.join(skillRoot, 'SKILL.md');
|
||||
}
|
||||
|
||||
export function ensureLongImageSkillInstalled(publishDir) {
|
||||
if (!fs.existsSync(LONG_IMAGE_SKILL_DIR)) return null;
|
||||
const skillRoot = path.join(publishDir, '.agents', 'skills', LONG_IMAGE_SKILL_NAME);
|
||||
fs.rmSync(skillRoot, { recursive: true, force: true });
|
||||
fs.mkdirSync(path.dirname(skillRoot), { recursive: true });
|
||||
fs.cpSync(LONG_IMAGE_SKILL_DIR, skillRoot, { recursive: true });
|
||||
return path.join(skillRoot, 'SKILL.md');
|
||||
}
|
||||
|
||||
export function ensurePublishSkillInstalled(publishDir, context) {
|
||||
ensureDocxSkillInstalled(publishDir);
|
||||
ensureLongImageSkillInstalled(publishDir);
|
||||
const skillRoot = path.join(publishDir, '.agents', 'skills', PUBLISH_SKILL_NAME);
|
||||
fs.mkdirSync(skillRoot, { recursive: true });
|
||||
const skillPath = path.join(skillRoot, 'SKILL.md');
|
||||
|
||||
Reference in New Issue
Block a user