openfeel 1.0.0
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/LICENSE +21 -0
- package/README.en.md +140 -0
- package/README.md +17 -0
- package/README.zh-CN.md +140 -0
- package/bin/openfeel.js +13 -0
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +119 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/repl.d.ts +10 -0
- package/dist/cli/repl.d.ts.map +1 -0
- package/dist/cli/repl.js +74 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/commands/archive.d.ts +7 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +38 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/config.d.ts +15 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +208 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/flow.d.ts +24 -0
- package/dist/commands/flow.d.ts.map +1 -0
- package/dist/commands/flow.js +1024 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +62 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/instructions.d.ts +7 -0
- package/dist/commands/instructions.d.ts.map +1 -0
- package/dist/commands/instructions.js +36 -0
- package/dist/commands/instructions.js.map +1 -0
- package/dist/commands/knowledge.d.ts +7 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +174 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/lint.d.ts +12 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +192 -0
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/plan.d.ts +7 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +73 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/project.d.ts +7 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +189 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/roadmap.d.ts +7 -0
- package/dist/commands/roadmap.d.ts.map +1 -0
- package/dist/commands/roadmap.js +26 -0
- package/dist/commands/roadmap.js.map +1 -0
- package/dist/commands/stage.d.ts +17 -0
- package/dist/commands/stage.d.ts.map +1 -0
- package/dist/commands/stage.js +291 -0
- package/dist/commands/stage.js.map +1 -0
- package/dist/commands/update.d.ts +8 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +87 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/view.d.ts +7 -0
- package/dist/commands/view.d.ts.map +1 -0
- package/dist/commands/view.js +77 -0
- package/dist/commands/view.js.map +1 -0
- package/dist/core/archive/merge.d.ts +20 -0
- package/dist/core/archive/merge.d.ts.map +1 -0
- package/dist/core/archive/merge.js +118 -0
- package/dist/core/archive/merge.js.map +1 -0
- package/dist/core/artifact-graph/graph.d.ts +62 -0
- package/dist/core/artifact-graph/graph.d.ts.map +1 -0
- package/dist/core/artifact-graph/graph.js +184 -0
- package/dist/core/artifact-graph/graph.js.map +1 -0
- package/dist/core/artifact-graph/index.d.ts +10 -0
- package/dist/core/artifact-graph/index.d.ts.map +1 -0
- package/dist/core/artifact-graph/index.js +8 -0
- package/dist/core/artifact-graph/index.js.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +35 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.js +358 -0
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -0
- package/dist/core/artifact-graph/resolver.d.ts +10 -0
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -0
- package/dist/core/artifact-graph/resolver.js +32 -0
- package/dist/core/artifact-graph/resolver.js.map +1 -0
- package/dist/core/artifact-graph/state.d.ts +9 -0
- package/dist/core/artifact-graph/state.d.ts.map +1 -0
- package/dist/core/artifact-graph/state.js +24 -0
- package/dist/core/artifact-graph/state.js.map +1 -0
- package/dist/core/artifact-graph/types.d.ts +22 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -0
- package/dist/core/artifact-graph/types.js +2 -0
- package/dist/core/artifact-graph/types.js.map +1 -0
- package/dist/core/config.d.ts +256 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +393 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/flow-manager.d.ts +492 -0
- package/dist/core/flow-manager.d.ts.map +1 -0
- package/dist/core/flow-manager.js +2379 -0
- package/dist/core/flow-manager.js.map +1 -0
- package/dist/core/i18n-data/en.d.ts +26 -0
- package/dist/core/i18n-data/en.d.ts.map +1 -0
- package/dist/core/i18n-data/en.js +492 -0
- package/dist/core/i18n-data/en.js.map +1 -0
- package/dist/core/i18n-data/types.d.ts +18 -0
- package/dist/core/i18n-data/types.d.ts.map +1 -0
- package/dist/core/i18n-data/types.js +8 -0
- package/dist/core/i18n-data/types.js.map +1 -0
- package/dist/core/i18n-data/zh-CN.d.ts +28 -0
- package/dist/core/i18n-data/zh-CN.d.ts.map +1 -0
- package/dist/core/i18n-data/zh-CN.js +524 -0
- package/dist/core/i18n-data/zh-CN.js.map +1 -0
- package/dist/core/i18n.d.ts +40 -0
- package/dist/core/i18n.d.ts.map +1 -0
- package/dist/core/i18n.js +135 -0
- package/dist/core/i18n.js.map +1 -0
- package/dist/core/init.d.ts +22 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +292 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/metrics.d.ts +60 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +137 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/pipeline-schema.d.ts +78 -0
- package/dist/core/pipeline-schema.d.ts.map +1 -0
- package/dist/core/pipeline-schema.js +57 -0
- package/dist/core/pipeline-schema.js.map +1 -0
- package/dist/core/plan/roadmap.d.ts +17 -0
- package/dist/core/plan/roadmap.d.ts.map +1 -0
- package/dist/core/plan/roadmap.js +71 -0
- package/dist/core/plan/roadmap.js.map +1 -0
- package/dist/core/plan/scheme.d.ts +34 -0
- package/dist/core/plan/scheme.d.ts.map +1 -0
- package/dist/core/plan/scheme.js +262 -0
- package/dist/core/plan/scheme.js.map +1 -0
- package/dist/core/plan/stage.d.ts +20 -0
- package/dist/core/plan/stage.d.ts.map +1 -0
- package/dist/core/plan/stage.js +120 -0
- package/dist/core/plan/stage.js.map +1 -0
- package/dist/core/public-logger.d.ts +84 -0
- package/dist/core/public-logger.d.ts.map +1 -0
- package/dist/core/public-logger.js +344 -0
- package/dist/core/public-logger.js.map +1 -0
- package/dist/core/schema.d.ts +70 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +61 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/template-loader.d.ts +22 -0
- package/dist/core/template-loader.d.ts.map +1 -0
- package/dist/core/template-loader.js +2848 -0
- package/dist/core/template-loader.js.map +1 -0
- package/dist/core/templates.d.ts +18 -0
- package/dist/core/templates.d.ts.map +1 -0
- package/dist/core/templates.js +50 -0
- package/dist/core/templates.js.map +1 -0
- package/dist/core/update.d.ts +40 -0
- package/dist/core/update.d.ts.map +1 -0
- package/dist/core/update.js +1569 -0
- package/dist/core/update.js.map +1 -0
- package/dist/core/view/entry.d.ts +37 -0
- package/dist/core/view/entry.d.ts.map +1 -0
- package/dist/core/view/entry.js +108 -0
- package/dist/core/view/entry.js.map +1 -0
- package/dist/core/workspace/identity.d.ts +60 -0
- package/dist/core/workspace/identity.d.ts.map +1 -0
- package/dist/core/workspace/identity.js +169 -0
- package/dist/core/workspace/identity.js.map +1 -0
- package/dist/core/workspace/knowledge.d.ts +55 -0
- package/dist/core/workspace/knowledge.d.ts.map +1 -0
- package/dist/core/workspace/knowledge.js +230 -0
- package/dist/core/workspace/knowledge.js.map +1 -0
- package/dist/core/workspace/structure.d.ts +9 -0
- package/dist/core/workspace/structure.d.ts.map +1 -0
- package/dist/core/workspace/structure.js +59 -0
- package/dist/core/workspace/structure.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/kb-dedup.d.ts +46 -0
- package/dist/utils/kb-dedup.d.ts.map +1 -0
- package/dist/utils/kb-dedup.js +169 -0
- package/dist/utils/kb-dedup.js.map +1 -0
- package/dist/utils/path.d.ts +22 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +37 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +61 -0
- package/schemas/spec-driven/schema.yaml +50 -0
- package/schemas/spec-driven/templates/design.md +43 -0
- package/schemas/spec-driven/templates/plan.md +46 -0
- package/schemas/spec-driven/templates/proposal.md +35 -0
- package/schemas/spec-driven/templates/tasks.md +39 -0
- package/scripts/patch-inquirer.js +70 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { ArtifactGraph } from './graph.js';
|
|
2
|
+
import { detectCompletedArtifacts } from './state.js';
|
|
3
|
+
import { readConfig } from '../config.js';
|
|
4
|
+
import { FlowManager } from '../flow-manager.js';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
// ─── XML 工具函数 ────────────────────────────────────────────────
|
|
9
|
+
/** XML 特殊字符转义映射 */
|
|
10
|
+
const XML_ESCAPE_MAP = {
|
|
11
|
+
'&': '&',
|
|
12
|
+
'<': '<',
|
|
13
|
+
'>': '>',
|
|
14
|
+
'"': '"',
|
|
15
|
+
"'": ''',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* 对 XML 文本内容中的特殊字符进行转义
|
|
19
|
+
* 防止指令文本中含 XML 保留字符导致格式破坏
|
|
20
|
+
*/
|
|
21
|
+
function xmlEscape(text) {
|
|
22
|
+
return text.replace(/[&<>"']/g, (ch) => XML_ESCAPE_MAP[ch] ?? ch);
|
|
23
|
+
}
|
|
24
|
+
/** 默认三条规则约束,后续可从 schema.yaml 的 rules 字段扩展 */
|
|
25
|
+
const DEFAULT_RULES = [
|
|
26
|
+
'遵循 TypeScript 编码规范',
|
|
27
|
+
'产物生成到 generates 字段指定的路径',
|
|
28
|
+
'完成所有 hard 依赖后再开始当前 artifact',
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* 判断 artifact.template 是否为文件路径
|
|
32
|
+
* 文件路径特征:以 . 或 / 开头、以 .md/.yaml/.json/.xml 结尾、不以 ( 开头
|
|
33
|
+
*/
|
|
34
|
+
function isFilePath(template) {
|
|
35
|
+
if (template.startsWith('(')) {
|
|
36
|
+
return false; // "(无模板)" 等回退文本
|
|
37
|
+
}
|
|
38
|
+
if (template.startsWith('.') || template.startsWith('/')) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (/\.(md|yaml|yml|json|xml)$/.test(template)) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/** 从文件加载模板内容,失败时返回 null */
|
|
47
|
+
function loadTemplateFile(templatePath, projectPath) {
|
|
48
|
+
const fullPath = resolve(projectPath, templatePath);
|
|
49
|
+
try {
|
|
50
|
+
if (!existsSync(fullPath)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
return readFileSync(fullPath, 'utf-8');
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ─── 子块生成 ────────────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* 生成 <project_context> 块
|
|
62
|
+
* 包含技术栈、工作区状态、项目名和 config.yaml 关键配置
|
|
63
|
+
*/
|
|
64
|
+
function generateProjectContext(config) {
|
|
65
|
+
const techStack = config.meta?.tech_stack ?? 'TypeScript';
|
|
66
|
+
const workspace = '.openfeel/ 工作区已初始化';
|
|
67
|
+
const project = config.meta?.project ?? 'OpenFeel';
|
|
68
|
+
// 提取关键配置项摘要
|
|
69
|
+
const configParts = [];
|
|
70
|
+
if (config.execution_mode) {
|
|
71
|
+
configParts.push(`执行模式: ${config.execution_mode}`);
|
|
72
|
+
}
|
|
73
|
+
if (config.auto_advance) {
|
|
74
|
+
configParts.push(`自动推进: ${config.auto_advance}`);
|
|
75
|
+
}
|
|
76
|
+
if (config.test_enabled !== undefined) {
|
|
77
|
+
configParts.push(`测试启用: ${config.test_enabled}`);
|
|
78
|
+
}
|
|
79
|
+
if (config.merge_mode) {
|
|
80
|
+
configParts.push(`合并模式: ${config.merge_mode}`);
|
|
81
|
+
}
|
|
82
|
+
const configSummary = configParts.length > 0
|
|
83
|
+
? xmlEscape(configParts.join('; '))
|
|
84
|
+
: '无特殊配置';
|
|
85
|
+
return [
|
|
86
|
+
` <project_context>`,
|
|
87
|
+
` <tech_stack>${techStack}</tech_stack>`,
|
|
88
|
+
` <workspace>${workspace}</workspace>`,
|
|
89
|
+
` <project>${project}</project>`,
|
|
90
|
+
` <config>${configSummary}</config>`,
|
|
91
|
+
` </project_context>`,
|
|
92
|
+
].join('\n');
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 生成 <rules> 块
|
|
96
|
+
* 包含默认规则和 Schema 级别的规则(如存在)
|
|
97
|
+
*/
|
|
98
|
+
function generateRulesBlock(schema) {
|
|
99
|
+
// 合并默认规则与 Schema 规则(type inference: Schema 类型暂未定义 rules 字段)
|
|
100
|
+
const rules = [...DEFAULT_RULES];
|
|
101
|
+
const schemaRules = schema.rules;
|
|
102
|
+
if (Array.isArray(schemaRules)) {
|
|
103
|
+
for (const r of schemaRules) {
|
|
104
|
+
if (typeof r === 'string') {
|
|
105
|
+
rules.push(r);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const ruleLines = rules.map((r) => ` <rule>${xmlEscape(r)}</rule>`);
|
|
110
|
+
return [' <rules>', ...ruleLines, ' </rules>'].join('\n');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 生成 <dependencies> 块
|
|
114
|
+
* 遍历当前 artifact 的所有 hard 依赖,标注其完成状态(done/pending)
|
|
115
|
+
*/
|
|
116
|
+
function generateDependenciesBlock(artifact, schema, completed) {
|
|
117
|
+
// 收集 target artifact 的所有 hard 依赖 ID
|
|
118
|
+
const hardDepIds = collectHardDepIds(artifact);
|
|
119
|
+
if (hardDepIds.length === 0) {
|
|
120
|
+
return ' <dependencies></dependencies>';
|
|
121
|
+
}
|
|
122
|
+
const depLines = [];
|
|
123
|
+
for (const depId of hardDepIds) {
|
|
124
|
+
const depArtifact = schema.artifacts.find((a) => a.id === depId);
|
|
125
|
+
const status = completed.has(depId) ? 'done' : 'pending';
|
|
126
|
+
const path = depArtifact ? xmlEscape(depArtifact.generates) : '(未知)';
|
|
127
|
+
const desc = depArtifact?.description
|
|
128
|
+
? xmlEscape(depArtifact.description)
|
|
129
|
+
: '(无描述)';
|
|
130
|
+
depLines.push(` <dependency id="${xmlEscape(depId)}" status="${status}">`, ` <path>${path}</path>`, ` <description>${desc}</description>`, ` </dependency>`);
|
|
131
|
+
}
|
|
132
|
+
return [' <dependencies>', ...depLines, ' </dependencies>'].join('\n');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 生成 <unlocks> 描述
|
|
136
|
+
* 通过 ArtifactGraph 找出哪些 artifact 依赖当前 artifact
|
|
137
|
+
*/
|
|
138
|
+
function generateUnlocks(artifactId, graph, schema) {
|
|
139
|
+
// 通过 getBlocked 找出所有被阻塞的 artifact,筛选缺少当前 artifactId 的
|
|
140
|
+
const empty = new Set();
|
|
141
|
+
const blocked = graph.getBlocked(empty);
|
|
142
|
+
const unlockedByCurrent = [];
|
|
143
|
+
for (const info of blocked.blocked) {
|
|
144
|
+
if (info.missingDeps.includes(artifactId)) {
|
|
145
|
+
unlockedByCurrent.push(info.artifactId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 跳过当前 artifact 自身
|
|
149
|
+
const others = unlockedByCurrent.filter((id) => id !== artifactId);
|
|
150
|
+
if (others.length === 0) {
|
|
151
|
+
return ' <unlocks>完成此 artifact 后暂无直接解锁的下游 artifact</unlocks>';
|
|
152
|
+
}
|
|
153
|
+
// 获取下游 artifact 描述
|
|
154
|
+
const descList = others.map((id) => {
|
|
155
|
+
const a = schema.artifacts.find((art) => art.id === id);
|
|
156
|
+
return a?.description ? `${id}(${a.description})` : id;
|
|
157
|
+
});
|
|
158
|
+
return ` <unlocks>${xmlEscape(`Completing this artifact enables: ${descList.join(', ')}`)}</unlocks>`;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 收集 artifact 的所有 hard 依赖 ID(复用 ArtifactGraph 内部逻辑)
|
|
162
|
+
*/
|
|
163
|
+
function collectHardDepIds(artifact) {
|
|
164
|
+
const hardDeps = [];
|
|
165
|
+
// dependsOn 简写:全部视为 hard
|
|
166
|
+
if (artifact.dependsOn) {
|
|
167
|
+
hardDeps.push(...artifact.dependsOn);
|
|
168
|
+
}
|
|
169
|
+
// requires 数组:按 type 过滤
|
|
170
|
+
if (artifact.requires) {
|
|
171
|
+
for (const dep of artifact.requires) {
|
|
172
|
+
if (dep.type !== 'soft') {
|
|
173
|
+
hardDeps.push(dep.artifact);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [...new Set(hardDeps)];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* 为 instruction 字段为空时自动生成分步指导
|
|
181
|
+
*/
|
|
182
|
+
function generateFallbackInstruction(artifact) {
|
|
183
|
+
const name = artifact.description ?? artifact.id;
|
|
184
|
+
const output = artifact.generates;
|
|
185
|
+
return [
|
|
186
|
+
`1. 理解 ${name} 的需求和目标`,
|
|
187
|
+
`2. 检查前置依赖产物是否已就绪`,
|
|
188
|
+
`3. 根据规范编写代码或文档`,
|
|
189
|
+
`4. 将产物输出到 ${output}`,
|
|
190
|
+
`5. 验证产物完整性和正确性`,
|
|
191
|
+
].join('\n');
|
|
192
|
+
}
|
|
193
|
+
// ─── 公开 API ────────────────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* 为指定 artifact 生成 XML 格式的结构化指令
|
|
196
|
+
*
|
|
197
|
+
* @param schema - 工作流 Schema
|
|
198
|
+
* @param changeName - 变更名称
|
|
199
|
+
* @param artifactId - 目标 artifact ID
|
|
200
|
+
* @param projectPath - 项目根路径
|
|
201
|
+
* @param completed - 可选的已完成 artifact ID 集合(用于测试/缓存),不传则自动扫描文件系统
|
|
202
|
+
* @returns XML 格式的指令文本
|
|
203
|
+
* @throws 找不到 artifact 或 Schema 校验失败时抛出异常
|
|
204
|
+
*/
|
|
205
|
+
export async function generateInstructions(schema, changeName, artifactId, projectPath, completed) {
|
|
206
|
+
// 1. 校验 artifact 存在
|
|
207
|
+
const artifact = schema.artifacts.find((a) => a.id === artifactId);
|
|
208
|
+
if (!artifact) {
|
|
209
|
+
throw new Error(`Schema "${schema.name}" 中找不到 artifact "${artifactId}"`);
|
|
210
|
+
}
|
|
211
|
+
// 2. 检测已完成的 artifact(文件系统扫描)
|
|
212
|
+
const actualCompleted = completed ?? await detectCompletedArtifacts(schema, projectPath);
|
|
213
|
+
// 3. 读取项目配置
|
|
214
|
+
const config = readConfig(projectPath);
|
|
215
|
+
// 4. 验证 flow.json 存在(项目已初始化)
|
|
216
|
+
const flowPath = resolve(projectPath, '.openfeel', 'flow.json');
|
|
217
|
+
if (!existsSync(flowPath)) {
|
|
218
|
+
// flow.json 不存在时仅警告,不阻断指令生成
|
|
219
|
+
// FlowManager 会在构造函数中记录数据未加载
|
|
220
|
+
}
|
|
221
|
+
// 初始化 FlowManager(验证流水线初始化状态)
|
|
222
|
+
const flowManager = new FlowManager(projectPath);
|
|
223
|
+
const flowInitialized = flowManager.isLoaded();
|
|
224
|
+
// 5. 构建依赖图
|
|
225
|
+
const graph = new ArtifactGraph(schema);
|
|
226
|
+
// 6. 构建任务描述
|
|
227
|
+
const taskDesc = artifact.instruction ?? artifact.description ?? '请完成此 artifact';
|
|
228
|
+
// 7. 构建各 XML 块
|
|
229
|
+
const projectCtx = generateProjectContext(config);
|
|
230
|
+
const rulesBlock = generateRulesBlock(schema);
|
|
231
|
+
const depsBlock = generateDependenciesBlock(artifact, schema, actualCompleted);
|
|
232
|
+
const output = xmlEscape(artifact.generates);
|
|
233
|
+
const instruction = artifact.instruction
|
|
234
|
+
? xmlEscape(artifact.instruction)
|
|
235
|
+
: xmlEscape(generateFallbackInstruction(artifact));
|
|
236
|
+
const template = (() => {
|
|
237
|
+
if (artifact.template) {
|
|
238
|
+
// 若 template 是文件路径,尝试从文件加载
|
|
239
|
+
if (isFilePath(artifact.template)) {
|
|
240
|
+
const fileContent = loadTemplateFile(artifact.template, projectPath);
|
|
241
|
+
if (fileContent !== null) {
|
|
242
|
+
return xmlEscape(fileContent);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return xmlEscape(artifact.template);
|
|
246
|
+
}
|
|
247
|
+
return '(无模板)';
|
|
248
|
+
})();
|
|
249
|
+
const unlocks = generateUnlocks(artifactId, graph, schema);
|
|
250
|
+
// 8. 拼接完整 XML
|
|
251
|
+
const lines = [
|
|
252
|
+
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
253
|
+
`<artifact id="${xmlEscape(artifactId)}" change="${xmlEscape(changeName)}" schema="${xmlEscape(schema.name)}">`,
|
|
254
|
+
` <task>${xmlEscape(taskDesc)}</task>`,
|
|
255
|
+
projectCtx,
|
|
256
|
+
rulesBlock,
|
|
257
|
+
depsBlock,
|
|
258
|
+
` <output>${output}</output>`,
|
|
259
|
+
` <instruction>${instruction}</instruction>`,
|
|
260
|
+
` <template>${template}</template>`,
|
|
261
|
+
unlocks,
|
|
262
|
+
`</artifact>`,
|
|
263
|
+
];
|
|
264
|
+
return lines.join('\n') + '\n';
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 为指定 artifact 生成 JSON 格式的结构化指令
|
|
268
|
+
* 返回与 XML 标签对应的 JS 对象
|
|
269
|
+
*
|
|
270
|
+
* @param schema - 工作流 Schema
|
|
271
|
+
* @param changeName - 变更名称
|
|
272
|
+
* @param artifactId - 目标 artifact ID
|
|
273
|
+
* @param projectPath - 项目根路径
|
|
274
|
+
* @param completed - 可选的已完成 artifact ID 集合
|
|
275
|
+
* @returns JSON 对象
|
|
276
|
+
*/
|
|
277
|
+
export async function generateInstructionsJson(schema, changeName, artifactId, projectPath, completed) {
|
|
278
|
+
const artifact = schema.artifacts.find((a) => a.id === artifactId);
|
|
279
|
+
if (!artifact) {
|
|
280
|
+
throw new Error(`Schema "${schema.name}" 中找不到 artifact "${artifactId}"`);
|
|
281
|
+
}
|
|
282
|
+
const actualCompleted = completed ?? await detectCompletedArtifacts(schema, projectPath);
|
|
283
|
+
const config = readConfig(projectPath);
|
|
284
|
+
const graph = new ArtifactGraph(schema);
|
|
285
|
+
// 依赖列表
|
|
286
|
+
const hardDepIds = collectHardDepIds(artifact);
|
|
287
|
+
const dependencies = hardDepIds.map((depId) => {
|
|
288
|
+
const depArtifact = schema.artifacts.find((a) => a.id === depId);
|
|
289
|
+
return {
|
|
290
|
+
id: depId,
|
|
291
|
+
status: actualCompleted.has(depId) ? 'done' : 'pending',
|
|
292
|
+
path: depArtifact?.generates ?? '(未知)',
|
|
293
|
+
description: depArtifact?.description ?? '(无描述)',
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
// 解锁的下游 artifact
|
|
297
|
+
const empty = new Set();
|
|
298
|
+
const blocked = graph.getBlocked(empty);
|
|
299
|
+
const unlockedByCurrent = [];
|
|
300
|
+
for (const info of blocked.blocked) {
|
|
301
|
+
if (info.missingDeps.includes(artifactId)) {
|
|
302
|
+
unlockedByCurrent.push(info.artifactId);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const others = unlockedByCurrent.filter((id) => id !== artifactId);
|
|
306
|
+
const unlocks = others.map((id) => {
|
|
307
|
+
const a = schema.artifacts.find((art) => art.id === id);
|
|
308
|
+
return { id, description: a?.description ?? null };
|
|
309
|
+
});
|
|
310
|
+
// 规则列表
|
|
311
|
+
const rules = [...DEFAULT_RULES];
|
|
312
|
+
const schemaRules = schema.rules;
|
|
313
|
+
if (Array.isArray(schemaRules)) {
|
|
314
|
+
for (const r of schemaRules) {
|
|
315
|
+
if (typeof r === 'string') {
|
|
316
|
+
rules.push(r);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
artifact: {
|
|
322
|
+
id: artifactId,
|
|
323
|
+
change: changeName,
|
|
324
|
+
schema: schema.name,
|
|
325
|
+
},
|
|
326
|
+
task: artifact.instruction ?? artifact.description ?? '请完成此 artifact',
|
|
327
|
+
project_context: {
|
|
328
|
+
tech_stack: config.meta?.tech_stack ?? 'TypeScript',
|
|
329
|
+
workspace: '.openfeel/ 工作区已初始化',
|
|
330
|
+
project: config.meta?.project ?? 'OpenFeel',
|
|
331
|
+
config: {
|
|
332
|
+
execution_mode: config.execution_mode ?? null,
|
|
333
|
+
auto_advance: config.auto_advance ?? null,
|
|
334
|
+
test_enabled: config.test_enabled ?? null,
|
|
335
|
+
merge_mode: config.merge_mode ?? null,
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
rules,
|
|
339
|
+
dependencies,
|
|
340
|
+
output: artifact.generates,
|
|
341
|
+
instruction: artifact.instruction ?? generateFallbackInstruction(artifact),
|
|
342
|
+
template: (() => {
|
|
343
|
+
if (artifact.template) {
|
|
344
|
+
// 若 template 是文件路径,尝试从文件加载
|
|
345
|
+
if (isFilePath(artifact.template)) {
|
|
346
|
+
const fileContent = loadTemplateFile(artifact.template, projectPath);
|
|
347
|
+
if (fileContent !== null) {
|
|
348
|
+
return fileContent;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return artifact.template;
|
|
352
|
+
}
|
|
353
|
+
return null;
|
|
354
|
+
})(),
|
|
355
|
+
unlocks,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=instruction-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction-loader.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/instruction-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Schema } from '../schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* 按优先级查找并加载工作流 Schema
|
|
4
|
+
* @param name Schema 名称(对应 schemas/{name}/ 目录)
|
|
5
|
+
* @param projectPath 项目根路径
|
|
6
|
+
* @returns 验证后的 Schema 对象
|
|
7
|
+
* @throws 所有路径均未找到时抛出异常
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveSchema(name: string, projectPath: string): Promise<Schema>;
|
|
10
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAOA,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema 多层解析器 — 按优先级查找并加载 Schema 文件
|
|
3
|
+
* 查找顺序:项目本地 > 用户家目录 > 包内置
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import { loadSchema } from '../schema.js';
|
|
9
|
+
/**
|
|
10
|
+
* 按优先级查找并加载工作流 Schema
|
|
11
|
+
* @param name Schema 名称(对应 schemas/{name}/ 目录)
|
|
12
|
+
* @param projectPath 项目根路径
|
|
13
|
+
* @returns 验证后的 Schema 对象
|
|
14
|
+
* @throws 所有路径均未找到时抛出异常
|
|
15
|
+
*/
|
|
16
|
+
export async function resolveSchema(name, projectPath) {
|
|
17
|
+
const paths = [
|
|
18
|
+
// 1. 项目本地 .openfeel/schemas/{name}/schema.yaml
|
|
19
|
+
path.join(projectPath, '.openfeel', 'schemas', name, 'schema.yaml'),
|
|
20
|
+
// 2. 用户家目录 ~/.openfeel/schemas/{name}/schema.yaml
|
|
21
|
+
path.join(os.homedir(), '.openfeel', 'schemas', name, 'schema.yaml'),
|
|
22
|
+
// 3. 包内置 node_modules/openfeel/schemas/{name}/schema.yaml
|
|
23
|
+
path.join(projectPath, 'node_modules', 'openfeel', 'schemas', name, 'schema.yaml'),
|
|
24
|
+
];
|
|
25
|
+
for (const p of paths) {
|
|
26
|
+
if (existsSync(p)) {
|
|
27
|
+
return loadSchema(p);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`找不到 Schema "${name}": 已搜索路径 ${paths.join(', ')}`);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,UAAU,EAAe,MAAM,cAAc,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,WAAmB;IAEnB,MAAM,KAAK,GAAG;QACZ,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC;QACnE,kDAAkD;QAClD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC;QACpE,0DAA0D;QAC1D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC;KACnF,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,eAAe,IAAI,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Schema } from '../schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* 扫描文件系统,检查每个 artifact 的 generates 产物是否存在
|
|
4
|
+
* @param schema 工作流 Schema
|
|
5
|
+
* @param basePath 项目根路径(glob 搜索的基准目录)
|
|
6
|
+
* @returns 产物已存在的 artifact ID 集合
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectCompletedArtifacts(schema: Schema, basePath: string): Promise<Set<string>>;
|
|
9
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/state.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAatB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 文件系统状态检测 — 扫描产物文件判断 artifact 是否已完成
|
|
3
|
+
* 使用 fast-glob 支持 glob 模式匹配
|
|
4
|
+
*/
|
|
5
|
+
import fg from 'fast-glob';
|
|
6
|
+
/**
|
|
7
|
+
* 扫描文件系统,检查每个 artifact 的 generates 产物是否存在
|
|
8
|
+
* @param schema 工作流 Schema
|
|
9
|
+
* @param basePath 项目根路径(glob 搜索的基准目录)
|
|
10
|
+
* @returns 产物已存在的 artifact ID 集合
|
|
11
|
+
*/
|
|
12
|
+
export async function detectCompletedArtifacts(schema, basePath) {
|
|
13
|
+
const completed = new Set();
|
|
14
|
+
for (const artifact of schema.artifacts) {
|
|
15
|
+
const pattern = artifact.generates;
|
|
16
|
+
// 使用 fast-glob 匹配产物文件
|
|
17
|
+
const files = await fg(pattern, { cwd: basePath, onlyFiles: true });
|
|
18
|
+
if (files.length > 0) {
|
|
19
|
+
completed.add(artifact.id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return completed;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,WAAW,CAAC;AAG3B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAc,EACd,QAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC;QACnC,sBAAsB;QACtB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArtifactGraph 相关类型定义
|
|
3
|
+
* 从 ../schema.js 重导出核心类型,并定义图运算相关的状态类型
|
|
4
|
+
*/
|
|
5
|
+
export type { Schema, Artifact, Dependency } from '../schema.js';
|
|
6
|
+
/** 构建顺序:按拓扑排序的 artifact ID 列表 */
|
|
7
|
+
export type BuildOrder = string[];
|
|
8
|
+
/** 单个被阻塞的 artifact 信息 */
|
|
9
|
+
export interface BlockedInfo {
|
|
10
|
+
artifactId: string;
|
|
11
|
+
missingDeps: string[];
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
14
|
+
/** 整体阻塞状态 */
|
|
15
|
+
export interface BlockedArtifacts {
|
|
16
|
+
blocked: BlockedInfo[];
|
|
17
|
+
ready: string[];
|
|
18
|
+
completed: string[];
|
|
19
|
+
total: number;
|
|
20
|
+
done: number;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE,iCAAiC;AACjC,MAAM,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC;AAElC,yBAAyB;AACzB,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,aAAa;AACb,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":""}
|