feat: update Makelore modules and conversations
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
export const projectTemplateIds = ['standard-development', 'game-development'] as const;
|
||||
export type ProjectTemplateId = (typeof projectTemplateIds)[number];
|
||||
export const YOUTH_PLAIN_LANGUAGE_SKILL_ID = 'youth-plain-language';
|
||||
export const PRODUCT_OVERVIEW_FILENAME = 'PRODUCT_OVERVIEW.md';
|
||||
export const LEGACY_PROMOTION_PLAN_FILENAME = 'PROMOTION_PLAN.md';
|
||||
|
||||
@@ -23,11 +20,14 @@ export type ProjectAgentConfig = {
|
||||
skillIds: string[];
|
||||
responsibility: ProjectAgentResponsibility;
|
||||
prompt: string;
|
||||
archivedAt?: string | null;
|
||||
pinned?: boolean;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
};
|
||||
|
||||
export type ProjectConfig = {
|
||||
schemaVersion: 1;
|
||||
templateId: ProjectTemplateId;
|
||||
initialized: boolean;
|
||||
superpowersEnabled: boolean;
|
||||
defaultModel: string | null;
|
||||
@@ -37,281 +37,19 @@ export type ProjectConfig = {
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type ProjectTemplateDefinition = {
|
||||
id: ProjectTemplateId;
|
||||
title: string;
|
||||
description: string;
|
||||
agents: ProjectAgentConfig[];
|
||||
};
|
||||
|
||||
const responsibility = (
|
||||
mission: string,
|
||||
owns: string[],
|
||||
boundaries: string[],
|
||||
collaborators: string[],
|
||||
principles: string[],
|
||||
): ProjectAgentResponsibility => ({ mission, owns, boundaries, collaborators, principles });
|
||||
|
||||
const agent = (
|
||||
id: string,
|
||||
roleName: string,
|
||||
skillIds: string[],
|
||||
value: ProjectAgentResponsibility,
|
||||
): ProjectAgentConfig => ({
|
||||
id,
|
||||
avatarId: ({
|
||||
'product-planning': 'avatar-01',
|
||||
'design-experience': 'avatar-03',
|
||||
development: 'avatar-10',
|
||||
'release-maintenance': 'avatar-12',
|
||||
'game-design': 'avatar-06',
|
||||
'game-art': 'avatar-08',
|
||||
'game-development': 'avatar-11',
|
||||
'game-test-release': 'avatar-14',
|
||||
'game-promotion': 'avatar-16',
|
||||
} as Record<string, string>)[id] ?? 'avatar-01',
|
||||
roleName,
|
||||
name: '',
|
||||
builtIn: true,
|
||||
enabled: true,
|
||||
model: null,
|
||||
skillIds: [...new Set([YOUTH_PLAIN_LANGUAGE_SKILL_ID, ...skillIds])],
|
||||
responsibility: value,
|
||||
prompt: buildResponsibilityPrompt(roleName, value),
|
||||
});
|
||||
|
||||
export function buildResponsibilityPrompt(roleName: string, value: ProjectAgentResponsibility): string {
|
||||
return [
|
||||
`你在项目中的职能是「${roleName}」。`,
|
||||
'',
|
||||
'## 核心职责',
|
||||
value.mission,
|
||||
'',
|
||||
'## 负责内容',
|
||||
...value.owns.map((item) => `- ${item}`),
|
||||
'',
|
||||
'## 职能边界',
|
||||
...value.boundaries.map((item) => `- ${item}`),
|
||||
'',
|
||||
'## 协作关系',
|
||||
...value.collaborators.map((item) => `- ${item}`),
|
||||
'',
|
||||
'## 工作原则',
|
||||
...value.principles.map((item) => `- ${item}`),
|
||||
'- 面向学生、家长或老师输出内容时,必须使用 `youth-plain-language`,用简体中文、短句和少术语的方式说明结论与下一步。',
|
||||
'',
|
||||
'## 项目空间协作',
|
||||
'- 项目目录是所有 Agent 共享的长期上下文。开始工作前,先读取与当前任务相关的已有项目文件和未提交改动。',
|
||||
'- 聊天里的口头总结不能代替项目产物。完成工作时,必须把结论、状态、假设和验证结果写入你负责的文件,给后续 Agent 留下可读取的推进痕迹。',
|
||||
'- 缺少上游产物时不要把它当作阶段门禁。先检查项目事实;能安全推进时记录假设并留下草案,只有缺失决定会实质改变结果时才询问用户。',
|
||||
'- 不依赖自动派发或跨会话消息。需要其他 Agent 继续时,在项目文件中写清当前状态、未决问题和建议下一步。',
|
||||
'',
|
||||
'## 版本与共享任务',
|
||||
'- 每次工作开始前读取根目录 `VERSION.md` 和 `TASKS.md`。`VERSION.md` 是当前项目版本的唯一权威索引;`TASKS.md` 是所有 Agent 共同维护的当前版本任务中枢。',
|
||||
'- 你可以新增或更新与自己工作有关的任务、Owner、状态、验收、证据、阻塞、来源和下一步。专业事实仍写入角色负责的文档,`TASKS.md` 只保存摘要与链接。',
|
||||
'- 更新角色 Markdown 文档时,使其包含并同步 `Project Version`、`Document Revision`、`Last Updated By`。项目版本来自 `VERSION.md`;每次实质修改文档时增加该文档的修订号。',
|
||||
'- 根目录文档只表示当前有效版本,不在同一文件持续堆叠完整历史。已归档版本位于 `docs/versions/<version>/`;归档文件原则上只读,历史修正使用明确勘误。',
|
||||
'- 如果当前工作需要新版本但你不是版本负责人,在 `TASKS.md` 记录升版建议、理由、建议级别和影响文档,不自行修改 `VERSION.md`。用户直接指定版本时遵循用户决定。',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
export function buildInitialProductOverviewDocument(): string {
|
||||
return `# 产品运营介绍
|
||||
|
||||
Project Version: v0.1.0
|
||||
Document Revision: 1
|
||||
Last Updated By: game-promotion
|
||||
|
||||
> 这是游戏项目唯一的产品运营介绍资料。它把真实的产品事实、用户价值、游戏讲解、对外表达、展示素材和证据状态整理成可持续复用的内容;聊天总结不能代替本文件。
|
||||
|
||||
## 1. 产品摘要
|
||||
|
||||
- 产品名称:
|
||||
- 产品类型:
|
||||
- 一句话介绍:
|
||||
- 当前产品状态:Concept / Prototype / Build / Ship
|
||||
- 当前版本:
|
||||
- 当前体验入口:
|
||||
|
||||
## 2. 目标用户与使用场景
|
||||
|
||||
| 用户/角色 | 使用场景 | 期待获得的价值 | 证据状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| TODO | TODO | TODO | 待补证据 |
|
||||
|
||||
## 3. 核心体验与玩法说明
|
||||
|
||||
- 玩家是谁,想完成什么:
|
||||
- 玩家如何开始和操作:
|
||||
- 一次完整体验如何经过“开始 → 行动 → 反馈 → 结果 → 重开或继续”:
|
||||
- 最值得展示的体验瞬间:
|
||||
- 当前已验证的玩法能力:
|
||||
- 尚未完成或暂不能承诺的玩法:
|
||||
|
||||
## 4. 用户价值与差异化
|
||||
|
||||
| 用户价值/差异点 | 用户能感受到的好处 | 对应产品事实或试玩证据 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| TODO | TODO | TODO | 待验证 |
|
||||
|
||||
## 5. 对外介绍与运营表达
|
||||
|
||||
### 30 秒介绍
|
||||
|
||||
- TODO
|
||||
|
||||
### 三句话介绍
|
||||
|
||||
- TODO
|
||||
|
||||
### 短文案
|
||||
|
||||
- TODO
|
||||
|
||||
### 讲给家长、老师或合作方
|
||||
|
||||
- TODO
|
||||
|
||||
### 行动引导
|
||||
|
||||
- 适合引导用户做什么:
|
||||
- 体验入口或发布链接:
|
||||
- 试玩前需要知道什么:
|
||||
|
||||
> 每个对外说法都要能回到项目文件、真实 Demo、截图、录屏或发布证据;没有证据时明确写“待补证据”。
|
||||
|
||||
## 6. 展示素材与运营信息
|
||||
|
||||
| 素材/信息 | 要证明或展示的产品事实 | 来源/路径 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| 截图或录屏 | TODO | TODO | 待准备 |
|
||||
|
||||
### 当前运营状态
|
||||
|
||||
- 当前可对外介绍的版本:
|
||||
- 当前可用的体验链接:
|
||||
- 已完成的展示准备:
|
||||
- 仍需补齐的展示信息:
|
||||
|
||||
## 7. 证据与真实性边界
|
||||
|
||||
- 已验证事实:
|
||||
- 尚未验证的说法:
|
||||
- 已知限制:
|
||||
- 需要向用户确认的产品表达:
|
||||
- 不得写成事实的愿景或候选能力:
|
||||
|
||||
## 8. 协作交接
|
||||
|
||||
- 给游戏策划:需要确认的玩家价值和核心卖点:
|
||||
- 给游戏素材:需要准备的截图、录屏或视觉资产:
|
||||
- 给游戏开发:需要补充的可讲解功能或体验证据:
|
||||
- 给测试发布:需要确认的试玩结果、版本、链接和发布状态:
|
||||
|
||||
> 本文件是产品运营介绍,不是投放排期、预算表或项目任务计划。任务状态写入 TASKS.md;需要页面、广告或发布动作时,再交给对应伙伴协作。
|
||||
`;
|
||||
}
|
||||
|
||||
export const projectTemplates: ProjectTemplateDefinition[] = [
|
||||
{
|
||||
id: 'standard-development',
|
||||
title: '普通开发项目',
|
||||
description: '从需求、体验、实现到发布,由四位项目 Agent 协作完成。',
|
||||
agents: [
|
||||
agent('product-planning', '产品规划', [], responsibility(
|
||||
'澄清目标、用户、范围、验收标准和工作优先级。',
|
||||
['REQUIREMENTS.md', 'PROJECT_PLAN.md'],
|
||||
['不直接实现产品代码', '不替代设计体验 Agent 决定视觉细节'],
|
||||
['design-experience:交接已确认的用户流程', 'development:交接范围与验收标准', 'release-maintenance:同步发布目标'],
|
||||
['你是普通开发项目的版本负责人;评估其他 Agent 的升版建议,并在新版本工作开始前创建范围', '初始版本为 v0.1.0;修复/小优化使用 PATCH,新增用户可感知能力使用 MINOR,正式发布或不兼容核心变化使用 MAJOR', '关闭版本前确认任务均为 Done、Deferred 或明确 Blocked,创建增量归档与 VERSION_SUMMARY.md,并把未完成任务带来源迁移到下一版本', '先确认高影响决策', '保持范围可验证', '发现跨职责任务时主动建议协作'],
|
||||
)),
|
||||
agent('design-experience', '设计体验', [], responsibility(
|
||||
'定义信息架构、交互、视觉规范、状态和可访问性要求。',
|
||||
['DESIGN.md', 'docs/design/', 'design/'],
|
||||
['不修改业务后端', '不擅自扩大产品范围'],
|
||||
['product-planning:确认用户与范围', 'development:提供可实现规范', 'release-maintenance:确认发布体验'],
|
||||
['设计必须覆盖空、错、载入状态', '优先复用项目设计系统', '交付应可被工程验证'],
|
||||
)),
|
||||
agent('development', '开发实现', [], responsibility(
|
||||
'按照已确认需求与设计完成代码、自动化测试和技术说明。',
|
||||
['src/', 'app/', 'packages/', 'tests/', 'README.md'],
|
||||
['不擅自改变产品目标', '不伪造测试或运行证据'],
|
||||
['product-planning:反馈范围风险', 'design-experience:澄清交互细节', 'release-maintenance:交接构建与风险'],
|
||||
['保持改动可回滚', '先读项目规范', '完成声明必须有测试或运行证据'],
|
||||
)),
|
||||
agent('release-maintenance', '发布维护', ['deploy-publish-check'], responsibility(
|
||||
'负责构建、Works Square 发布检查、部署说明、回滚方案和维护风险。',
|
||||
['Dockerfile', 'docker-compose.yml', 'niancode.yml', 'works-publish.json', 'works-deploy-check.json', '部署报告.md', 'RELEASE.md', 'CHANGELOG.md', 'deploy/', '.github/workflows/'],
|
||||
['不改写未确认的产品需求', '不以构建成功代替功能验收', '静态安全检查或真实执行失败时不允许云端提交', '不把缺少 Docker/浏览器证据伪造成通过;明确写 SKIPPED 或 BLOCKED + execution: unavailable,交给 Works Square 云端复核'],
|
||||
['development:接收可发布构建', 'product-planning:确认发布范围', 'design-experience:检查关键体验'],
|
||||
['发布步骤可复现', '逐项执行 Works Square ZIP/Compose/Docker/sandbox 检查', '输出 PASS、SKIPPED 或 BLOCKED 机器报告;环境不可用时保留 execution: unavailable', '云端部署由 Main 读取交接文件并自动提交,Agent 不接触令牌', '明确区分已提交远端、远端构建中和已公开', '明确剩余风险', '保留回滚路径'],
|
||||
)),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'game-development',
|
||||
title: '游戏开发项目',
|
||||
description: '遵循 nianxxgame 范式,由策划、美术、开发、测试发布和运营宣传协作完成可玩且可推广的游戏;新建项目会预置素材生成与审核工作区。',
|
||||
agents: [
|
||||
agent('game-design', '游戏策划', ['nianxxgame-skill'], responsibility(
|
||||
'定义玩家体验、核心循环、规则、范围与可验证的设计风险;开始工作前读取 TECH_STACK.md,同时明确 2D/3D 渲染选择和玩家可感知的技术约束。当出现素材缺口时,把视觉意图、玩家用途和验收语境交给 game-art。',
|
||||
['GDD.md'],
|
||||
['不直接承担正式代码实现', '不在缺少试玩证据时宣称玩法成立', '不直接运行 game-assets 或请求 Meowa'],
|
||||
['game-art:交接玩家幻想与反馈目标', 'game-development:交接系统规则与验收条件', 'game-test-release:定义试玩问题'],
|
||||
['你是游戏开发项目的版本负责人;评估其他 Agent 的升版建议,并在新版本工作开始前创建范围', '初始版本为 v0.1.0;修复/素材替换/小优化使用 PATCH,新增玩家可感知玩法或内容使用 MINOR,正式发布或不兼容核心变化使用 MAJOR', '关闭版本前确认任务均为 Done、Deferred 或明确 Blocked,创建增量归档与 VERSION_SUMMARY.md,并把未完成任务带来源迁移到下一版本', '开始时读取现有 GDD、代码、素材计划、测试报告和用户资料,避免覆盖已验证事实', '保持 GDD 渐进且可测试', '每次策划工作都更新 GDD.md,明确已确认内容、假设、风险和给素材/开发伙伴的上下文', '一次聚焦一个高风险问题', '用玩家语言描述结果'],
|
||||
)),
|
||||
agent('game-art', '游戏素材', ['nianxxgame-skill', 'game-assets'], responsibility(
|
||||
'优先从 Works Square 素材 API 搜索、筛选和组织游戏素材;开始工作前读取 TECH_STACK.md,缺口明确且授权条件可接受时,通过项目内固定版 Meowa game-assets Skill 生成 2D 素材,核对并记录授权,同时制定可落地的 2D/3D 游戏美术规范。它是游戏模板中唯一直接调用 game-assets 的 Agent;3D 模型改走项目、用户或许可证明确的外部来源。',
|
||||
['ASSET_PLAN.md', 'ART_GUIDE.md', 'assets/', 'public/assets/', 'assets/generated/meowa/', 'assets/models/', 'public/models/'],
|
||||
['不擅自改变玩法规则', '不使用来源或授权不明的素材', '不负责正式玩法代码', '不得把仅可浏览或来源不明的素材当作开源素材', '不得把 Meowa 生成物标成 CC0 或默认商业可用', '不得读取、暴露或写入 Meowa API Key'],
|
||||
['game-design:对齐玩家幻想', 'game-development:交付素材键名、规格与接入说明', 'game-test-release:处理可读性问题'],
|
||||
['新建游戏项目会预置 GDD.md、ASSET_PLAN.md、ART_GUIDE.md、assets/generated/meowa/、assets/review-previews/ 和 public/assets/;先读取这些共享产物,不覆盖用户后续改动', '开始时读取 GDD.md、现有 ASSET_PLAN.md、ART_GUIDE.md、TASKS.md、代码和素材目录,只为当前设计准备资源', '优先请求 `https://square.nianxx.cn/api/assets`,根据当前素材需求自行使用 q、category、tag、source、limit、offset 等适用参数;limit 由你按任务规模决定,可从 12 开始,结果不足时使用 offset 继续分页。接口不可用、返回错误或没有合适结果时,再依次搜索 Kenney、OpenGameArt、itch.io 的明确 CC0/CC-BY 素材和其他可信开源站点;接口失败不代表不存在可用素材', '当现有素材仍有明确缺口时,先运行项目内 `game-assets` Skill 的 `skill-doc` 和 `config-status`,再从 `template-info` 读取真实模版;确认配置可用后,只通过 Makelore 本地适配器生成,不直接请求 Meowa,不运行 npx skills add 或远程 bootstrap', '生成物必须写入 `assets/generated/meowa/<run>/`,保留任务响应、最终响应、下载文件和 `generation.meta.json`;元数据记录 provider、Skill 版本、模版、提示词、任务 ID、生成时间、条款链接和授权状态', '开始前读取 `.niancode/asset-review.json`(如果存在),绝不再次提交其中已舍弃或已纳入开发的素材', '每次素材工作都更新 ASSET_PLAN.md 与必要的 ART_GUIDE.md,记录候选/选用状态、来源、作者、许可证、项目内路径、缺口、假设和接入说明', 'ASSET_PLAN.md 必须同时保留一个顶层为 {"assets":[...]} 的 fenced JSON 资产清单,每项使用稳定 id;Markdown 表格只能作为展示说明,不能替代机器记录', '图片/音频/动画/素材包候选必须先保存项目内可预览证据:至少确认每项的相对 localPath、previewPath、coverPath 或非空 manifestPaths 实际存在;没有可预览证据时先下载/整理预览或继续搜索,不得提交空预览的审核批次', '候选准备好且需要用户判断时,在回复末尾输出新的 `<!-- niancode:game-asset-review {"invocationId":"唯一批次 id","candidateIds":["候选 id"]} -->` 标记;禁止只问用户选哪个方案或让用户回复文件名来代替审核标记;审核台先收集全部卡片决定,用户全部选完后通过一次确认提交一条汇总消息,不要把决定拆成逐卡聊天;每次唤起都由你填充新的候选列表,不自动追加旧批次', '用户舍弃的素材不得再次提交;用户未处理的素材也不自动带入下一次,只有你明确判断仍有价值时才重新提交', '如果当前相关任务仍有待审核内容,可以再次输出新的审核标记;与素材无关的任务不要打断用户', '统一尺寸、色彩、命名和导出规范'],
|
||||
)),
|
||||
agent('game-development', '游戏开发', ['nianxxgame-skill'], responsibility(
|
||||
'实现一个可玩的玩家可见结果,按 TECH_STACK.md 选择并固定 2D Phaser 或 3D Three.js 路径,接入项目中可用且授权清楚的素材,并保持游戏持续可运行;素材缺口交由 game-art 处理,自己只接入已经审核通过的项目内素材。',
|
||||
['src/', 'public/', 'package.json', 'TECH_STACK.md', 'TASKS.md'],
|
||||
['不擅自改写 GDD 中已确认的核心设计', '不使用授权不明的素材', '不伪造浏览器试玩结果', '不直接运行 game-assets 或绕过素材审核'],
|
||||
['game-design:澄清规则与调参目标', 'game-art:确认素材规范', 'game-test-release:交付构建与已知风险'],
|
||||
['开始时读取 GDD.md、TECH_STACK.md、ASSET_PLAN.md、ART_GUIDE.md、TASKS.md、`.niancode/asset-review.json`、测试/发布记录和现有代码;缺失内容按项目事实记录假设,不把缺文件当作开工门禁', '只接入 `.niancode/asset-review.json` 中明确 approved 的素材;candidate、pending、discarded 和 replace-requested 素材不得进入正式开发', '没有已批准的真实素材时可以使用可逆的安全占位,并把缺口写回 TASKS.md,不得把候选素材当成已确认素材', '根据 TECH_STACK.md 固定 2D Phaser 3.90.0 或 3D Three.js + TypeScript;不得把 3D 需求静默降级为 2D,也不得静默迁移已有 2D 项目', '每次开发工作都更新代码与 TASKS.md,记录完成内容、真实验证、剩余风险和后续伙伴可执行的下一步', '一次只维护一个当前可玩结果', '必须在真实浏览器验证'],
|
||||
)),
|
||||
agent('game-test-release', '测试发布', ['nianxxgame-skill', 'deploy-publish-check'], responsibility(
|
||||
'在真实浏览器试玩核心循环,验证缺陷、构建和 Works Square 发布准备;按 TECH_STACK.md 检查 2D 或 3D 路径,检查已审核素材的项目内路径、元数据、可读性和运行结果,并把素材问题回交 game-art。',
|
||||
['TEST_REPORT.md', 'RELEASE.md', 'works-publish.json', 'works-deploy-check.json', '部署报告.md', 'Dockerfile', 'docker-compose.yml', 'niancode.yml'],
|
||||
['不把未观察行为标记为通过', '不擅自重写核心设计', '不以静态检查代替试玩', '不为缺失素材自行调用 game-assets 或生成替代品', '不把 Docker/浏览器不可用伪造成 PASS;标记 SKIPPED 或 BLOCKED + execution: unavailable 交给云端复核', '静态安全检查或真实执行失败时不允许云端提交'],
|
||||
['game-development:反馈可复现缺陷', 'game-design:反馈体验证据', 'game-art:反馈视觉与可读性问题'],
|
||||
['开始时读取 GDD.md、ASSET_PLAN.md、ART_GUIDE.md、TASKS.md、现有测试与代码,按项目当前事实确定验证范围', '验证开始到结果再到重开的完整循环', '执行 Works Square Compose/ZIP 安全检查、容器内 0.0.0.0:8080 监听、Docker build/up、动态端口、HTTP smoke、全新目录重复 smoke 和 sandbox iframe smoke', '游戏或画布项目额外执行桌面/移动 viewport 与 resize/全屏 smoke,记录逻辑分辨率、实际 canvas、最大等比预期和 resize_verified', '每次测试发布工作都更新 TEST_REPORT.md、RELEASE.md、works-publish.json、works-deploy-check.json 或部署报告中适用的产物,记录可复现步骤、证据、缺陷、风险和回滚方式', '记录浏览器与控制台证据;环境不可用时写 SKIPPED 或 BLOCKED + execution: unavailable,不伪造画布证据', '任何失败输出 BLOCKED;真实失败输出 BLOCKED,不继续云端提交;本机环境不可用时让 Main 的 cloud 模式接管远端复核', '发布步骤必须可复现和回滚'],
|
||||
)),
|
||||
agent('game-promotion', '运营宣传角色', ['nianxxgame-skill', 'marketing-launch-story'], responsibility(
|
||||
'把游戏真实可玩的内容整理成清楚、可信、可持续维护的产品运营介绍,让玩家、家长、老师或合作方理解产品价值、体验方式和当前状态。',
|
||||
[PRODUCT_OVERVIEW_FILENAME],
|
||||
['不直接修改游戏代码、玩法规则或正式视觉资产', '不把愿景、候选功能或未验证行为写成已经实现的能力', '不替代测试发布 Agent 的试玩、构建和发布验收', '不自行宣称游戏已上线、已有用户、已有销量或已经获得反馈', `不创建与 ${PRODUCT_OVERVIEW_FILENAME} 平行的宣发材料.md、SHOWCASE_PACKAGE.md 等宣传主文档`],
|
||||
['game-design:确认玩家幻想、核心循环、目标用户和价值承诺', 'game-art:确认可用视觉资产、截图和录屏方向', 'game-development:核对真实功能、操作方式和版本行为', 'game-test-release:核对试玩结果、构建版本、发布链接和证据状态'],
|
||||
['开始时读取 GDD.md、ASSET_PLAN.md、ART_GUIDE.md、TASKS.md、TEST_REPORT.md、RELEASE.md、works-publish.json、现有代码和 knowledge/ 中的相关资料', `每次工作都更新 ${PRODUCT_OVERVIEW_FILENAME},并同步与产品运营有关的任务、证据、风险和下一步到 TASKS.md`, '把产品价值翻译成用户能理解的收益,而不是只罗列技术实现', '分别整理产品事实、用户场景、对外介绍、游戏讲解、展示素材和证据边界,避免把不同用途的表达混在一起', '每个卖点和对外说法都标注对应的产品事实、试玩、截图、录屏或发布证据;没有证据就明确标记待补', '按“开始 → 行动 → 反馈 → 结果 → 重开或继续”讲清游戏,不编造不存在的玩法或链接', `默认只维护 ${PRODUCT_OVERVIEW_FILENAME};它是产品运营介绍,不是投放排期、预算表或项目任务计划`, '用户明确要求宣传页或 HTML 时才扩展到页面产物,并把页面需求交给合适的伙伴协作', '使用 marketing-launch-story 组织受众、定位、价值、文案、演示和运营信息,并使用 youth-plain-language 输出简体中文短句'],
|
||||
)),
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export function createProjectConfig(templateId: ProjectTemplateId, now = new Date().toISOString()): ProjectConfig {
|
||||
const template = projectTemplates.find((candidate) => candidate.id === templateId);
|
||||
if (!template) throw new Error(`Unknown project template: ${templateId}`);
|
||||
export function createProjectConfig(now = new Date().toISOString()): ProjectConfig {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
templateId,
|
||||
initialized: false,
|
||||
superpowersEnabled: getDefaultSuperpowersEnabled(templateId),
|
||||
superpowersEnabled: false,
|
||||
defaultModel: null,
|
||||
agents: structuredClone(template.agents),
|
||||
agents: [],
|
||||
knowledgeDirectory: 'knowledge',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
}
|
||||
|
||||
export function getDefaultSuperpowersEnabled(templateId: ProjectTemplateId): boolean {
|
||||
return templateId === 'standard-development';
|
||||
}
|
||||
|
||||
export function validateAgentNames(agents: ProjectAgentConfig[]): string[] {
|
||||
const errors: string[] = [];
|
||||
const names = new Set<string>();
|
||||
@@ -326,6 +64,18 @@ export function validateAgentNames(agents: ProjectAgentConfig[]): string[] {
|
||||
return errors;
|
||||
}
|
||||
|
||||
export function isProjectTemplateId(value: unknown): value is ProjectTemplateId {
|
||||
return typeof value === 'string' && projectTemplateIds.includes(value as ProjectTemplateId);
|
||||
export function validateAgentConfigs(agents: ProjectAgentConfig[]): string[] {
|
||||
const errors = validateAgentNames(agents);
|
||||
for (const agent of agents) {
|
||||
if (!/^avatar-(0[1-9]|1[0-6])$/.test(agent.avatarId)) {
|
||||
errors.push(`${agent.id}:avatar-required`);
|
||||
}
|
||||
if (!agent.model?.trim()) {
|
||||
errors.push(`${agent.id}:model-required`);
|
||||
}
|
||||
if (!agent.responsibility.mission.trim()) {
|
||||
errors.push(`${agent.id}:responsibility-required`);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user