@istuen/pt 0.1.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.md +219 -0
- package/dist/agent/api-bridge.d.ts +8 -0
- package/dist/agent/api-bridge.js +83 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/index.js +3 -0
- package/dist/agent/pi-adapter.d.ts +35 -0
- package/dist/agent/pi-adapter.js +251 -0
- package/dist/agent/registry.d.ts +4 -0
- package/dist/agent/registry.js +40 -0
- package/dist/asset-health.d.ts +50 -0
- package/dist/asset-health.js +267 -0
- package/dist/asset-pack/loader.d.ts +47 -0
- package/dist/asset-pack/loader.js +121 -0
- package/dist/asset-pack/manifest.d.ts +23 -0
- package/dist/asset-pack/manifest.js +96 -0
- package/dist/asset-pack/md-file-pack.d.ts +41 -0
- package/dist/asset-pack/md-file-pack.js +153 -0
- package/dist/asset-pack/validate.d.ts +55 -0
- package/dist/asset-pack/validate.js +131 -0
- package/dist/builtin/assets/blueprints/dev-knowledge.blueprint.yaml +13 -0
- package/dist/builtin/assets/domains/agent-info.md +15 -0
- package/dist/builtin/assets/domains/authoring.md +201 -0
- package/dist/builtin/assets/domains/pack-repair.md +47 -0
- package/dist/builtin/assets/domains/project-analysis.md +52 -0
- package/dist/builtin/assets/domains/usage.md +81 -0
- package/dist/builtin/assets/domains/user-info.md +15 -0
- package/dist/builtin/assets/profiles/guide.profile.md +28 -0
- package/dist/commands.d.ts +69 -0
- package/dist/commands.js +344 -0
- package/dist/compile/agent-context.d.ts +48 -0
- package/dist/compile/agent-context.js +423 -0
- package/dist/compile/index.d.ts +1 -0
- package/dist/compile/index.js +5 -0
- package/dist/compile/resolve-use.d.ts +36 -0
- package/dist/compile/resolve-use.js +171 -0
- package/dist/compile/type-guards.d.ts +29 -0
- package/dist/compile/type-guards.js +107 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.js +133 -0
- package/dist/constants.d.ts +52 -0
- package/dist/constants.js +81 -0
- package/dist/diagnostics.d.ts +14 -0
- package/dist/diagnostics.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +838 -0
- package/dist/injection-status.d.ts +45 -0
- package/dist/injection-status.js +134 -0
- package/dist/log.d.ts +64 -0
- package/dist/log.js +139 -0
- package/dist/manual-session.d.ts +24 -0
- package/dist/manual-session.js +152 -0
- package/dist/manual-track.d.ts +35 -0
- package/dist/manual-track.js +107 -0
- package/dist/parse/blueprint.d.ts +5 -0
- package/dist/parse/blueprint.js +59 -0
- package/dist/parse/domain-renderers.d.ts +8 -0
- package/dist/parse/domain-renderers.js +115 -0
- package/dist/parse/domain.d.ts +7 -0
- package/dist/parse/domain.js +69 -0
- package/dist/parse/index.d.ts +9 -0
- package/dist/parse/index.js +223 -0
- package/dist/parse/profile.d.ts +18 -0
- package/dist/parse/profile.js +117 -0
- package/dist/parse/ref-resolver.d.ts +63 -0
- package/dist/parse/ref-resolver.js +174 -0
- package/dist/parse/shared.d.ts +76 -0
- package/dist/parse/shared.js +273 -0
- package/dist/profile-persist.d.ts +22 -0
- package/dist/profile-persist.js +53 -0
- package/dist/render/cache.d.ts +15 -0
- package/dist/render/cache.js +135 -0
- package/dist/render/index.d.ts +3 -0
- package/dist/render/index.js +14 -0
- package/dist/render/session-inject.d.ts +5 -0
- package/dist/render/session-inject.js +24 -0
- package/dist/render/turn-inject.d.ts +36 -0
- package/dist/render/turn-inject.js +248 -0
- package/dist/schema.d.ts +448 -0
- package/dist/schema.js +45 -0
- package/dist/session.d.ts +82 -0
- package/dist/session.js +102 -0
- package/dist/slog.d.ts +3 -0
- package/dist/slog.js +27 -0
- package/dist/transpile.d.ts +34 -0
- package/dist/transpile.js +220 -0
- package/dist/verify/file-hash.d.ts +2 -0
- package/dist/verify/file-hash.js +30 -0
- package/dist/verify/fs-content-match.d.ts +2 -0
- package/dist/verify/fs-content-match.js +26 -0
- package/dist/verify/fs-exists.d.ts +2 -0
- package/dist/verify/fs-exists.js +13 -0
- package/dist/verify/fs-not-exists.d.ts +2 -0
- package/dist/verify/fs-not-exists.js +13 -0
- package/dist/verify/git-status-clean.d.ts +2 -0
- package/dist/verify/git-status-clean.js +19 -0
- package/dist/verify/index.d.ts +7 -0
- package/dist/verify/index.js +46 -0
- package/dist/verify/lint-check.d.ts +2 -0
- package/dist/verify/lint-check.js +17 -0
- package/dist/verify/read-stderr.d.ts +5 -0
- package/dist/verify/read-stderr.js +20 -0
- package/dist/verify/ref-check.d.ts +13 -0
- package/dist/verify/ref-check.js +88 -0
- package/dist/verify/test-pass.d.ts +2 -0
- package/dist/verify/test-pass.js +17 -0
- package/dist/verify/ts-compiles.d.ts +2 -0
- package/dist/verify/ts-compiles.js +17 -0
- package/package.json +62 -0
- package/src/agent/api-bridge.ts +105 -0
- package/src/agent/index.ts +4 -0
- package/src/agent/pi-adapter.ts +326 -0
- package/src/agent/registry.ts +44 -0
- package/src/asset-health.ts +327 -0
- package/src/asset-pack/loader.ts +141 -0
- package/src/asset-pack/manifest.ts +118 -0
- package/src/asset-pack/md-file-pack.ts +202 -0
- package/src/asset-pack/validate.ts +186 -0
- package/src/builtin/assets/blueprints/dev-knowledge.blueprint.yaml +13 -0
- package/src/builtin/assets/domains/agent-info.md +15 -0
- package/src/builtin/assets/domains/authoring.md +201 -0
- package/src/builtin/assets/domains/pack-repair.md +47 -0
- package/src/builtin/assets/domains/project-analysis.md +52 -0
- package/src/builtin/assets/domains/usage.md +81 -0
- package/src/builtin/assets/domains/user-info.md +15 -0
- package/src/builtin/assets/profiles/guide.profile.md +28 -0
- package/src/commands.ts +405 -0
- package/src/compile/agent-context.ts +487 -0
- package/src/compile/index.ts +5 -0
- package/src/compile/resolve-use.ts +208 -0
- package/src/compile/type-guards.ts +132 -0
- package/src/config.ts +154 -0
- package/src/constants.ts +104 -0
- package/src/diagnostics.ts +36 -0
- package/src/index.ts +1028 -0
- package/src/injection-status.ts +155 -0
- package/src/log.ts +173 -0
- package/src/manual-session.ts +190 -0
- package/src/manual-track.ts +127 -0
- package/src/parse/blueprint.ts +82 -0
- package/src/parse/domain-renderers.ts +120 -0
- package/src/parse/domain.ts +78 -0
- package/src/parse/index.ts +266 -0
- package/src/parse/profile.ts +139 -0
- package/src/parse/ref-resolver.ts +198 -0
- package/src/parse/shared.ts +331 -0
- package/src/profile-persist.ts +60 -0
- package/src/render/cache.ts +150 -0
- package/src/render/index.ts +14 -0
- package/src/render/session-inject.ts +26 -0
- package/src/render/turn-inject.ts +278 -0
- package/src/schema.ts +542 -0
- package/src/session.ts +190 -0
- package/src/slog.ts +32 -0
- package/src/transpile.ts +302 -0
- package/src/verify/file-hash.ts +29 -0
- package/src/verify/fs-content-match.ts +28 -0
- package/src/verify/fs-exists.ts +14 -0
- package/src/verify/fs-not-exists.ts +17 -0
- package/src/verify/git-status-clean.ts +23 -0
- package/src/verify/index.ts +57 -0
- package/src/verify/lint-check.ts +21 -0
- package/src/verify/read-stderr.ts +24 -0
- package/src/verify/ref-check.ts +118 -0
- package/src/verify/test-pass.ts +18 -0
- package/src/verify/ts-compiles.ts +21 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
// src/render/turn-inject.ts — FlowTemplate + 参数 → Turn Inject
|
|
2
|
+
//
|
|
3
|
+
// Phase 9.5:v9 后端通用化。
|
|
4
|
+
// - renderTurnInject(ctx, blueprint, domains, args) 修复死代码——实现 /manual:xxx 触发
|
|
5
|
+
// - findFlowInBlueprint(blueprint, domains, tplName) — 替代 v8 findFlowInBundle
|
|
6
|
+
//
|
|
7
|
+
// /manual:<domain-name> 触发:从 Blueprint 的 turn 聚合组引用的 Domain 里查 Manual 段
|
|
8
|
+
// /<flow-name> <args> 触发:展开 Domain 的 FlowTemplate(v8 逻辑保留)
|
|
9
|
+
//
|
|
10
|
+
// Phase term-P4.3:renderContextMessage → renderTurnInject;inject 语义值 context_message → turn(Agent-agnostic 语义值)。
|
|
11
|
+
// bindFlowTemplate / findFlowInBlueprint 函数名不改——它们是 FlowTemplate 操作,非注入位置概念。
|
|
12
|
+
//
|
|
13
|
+
// Tech Debt T6: 全用 type guard 收窄,不用 as 断言(pt-quality #1)
|
|
14
|
+
// Tech Debt T2: 用 constants 模块名常量(pt-quality #5)
|
|
15
|
+
import { MOD_CHECKLISTS, MOD_FLOWS, MOD_RULES } from "../constants.js";
|
|
16
|
+
import { isChecklistArray, isFlowTemplateArray, isRuleArray } from "../compile/type-guards.js";
|
|
17
|
+
/**
|
|
18
|
+
* 给定 AgentContext + Blueprint + Domains + args(形如 "/manual:pt-quality" 或 "/risk-check 客户A 5000"),
|
|
19
|
+
* 展开目标 Domain 的 Manual 段内容或 FlowTemplate。
|
|
20
|
+
*
|
|
21
|
+
* v9 触发:
|
|
22
|
+
* - /manual:<domain-name>:注入该 Domain 的 Manual 段内容(term→Rule checklist / workflow→FlowTemplate 列表)
|
|
23
|
+
* - /<flow-name> <args>:展开 workflow-Domain 的 FlowTemplate(v8 逻辑保留)
|
|
24
|
+
*
|
|
25
|
+
* Phase term-P4.3:AgentAdapter 内部把 Turn Inject 注入到 Agent 的 turn 级(Pi: input 事件 transform)。
|
|
26
|
+
*
|
|
27
|
+
* v13.x(issue pt-turn-inject-not-profile-scoped):加 profile 参数——
|
|
28
|
+
* - domain 维度:调用方(adapter)应已用 filterDomainsByProfile 过滤 domains,renderTurnInject
|
|
29
|
+
* 不再二次过滤(信任传入的 domains scope)
|
|
30
|
+
* - modules 维度(阶段 2):从 blueprint 的 inject=turn 聚合组 + profile 同名 ProfileGroup.modules 算
|
|
31
|
+
* 白名单,/manual:<domain> 只渲染白名单内的段,/<flow-name> 只在白名单含 Flows 段时查找。
|
|
32
|
+
* profile 为 null 或无 turn 聚合组 → 白名单 null = 不限制(向后兼容)。
|
|
33
|
+
*/
|
|
34
|
+
export function renderTurnInject(_ctx, blueprint, domains, profile, args) {
|
|
35
|
+
const m = args.trim().match(/^\/(\S+)\s*(.*)$/);
|
|
36
|
+
if (!m)
|
|
37
|
+
return null;
|
|
38
|
+
const [, name, rest] = m;
|
|
39
|
+
// 阶段 2:算 turn 聚合组的 modules 白名单(Profile "参考手册"聚合组的 ### Modules)
|
|
40
|
+
const mods = turnGroupModules(blueprint, profile);
|
|
41
|
+
// /manual:<domain-name> 触发(v9 新增)—— name 可能是 "manual:pt-quality"
|
|
42
|
+
// Phase term-P9.2:Domain 不再有单一 Manual 段,而是 Rules/Flows/Checklists 三选一。
|
|
43
|
+
// 顺序遍历找第一个非空段,返回对应渲染。
|
|
44
|
+
// v13.x:受 mods 白名单限制——只渲染白名单内的段。
|
|
45
|
+
if (name.startsWith("manual:")) {
|
|
46
|
+
const domainName = name.slice("manual:".length).trim();
|
|
47
|
+
const d = domains.find((x) => x.name === domainName);
|
|
48
|
+
if (!d)
|
|
49
|
+
return null;
|
|
50
|
+
return renderDomainManual(d, mods);
|
|
51
|
+
}
|
|
52
|
+
// /manual <domain-name> 触发——空格分隔形式
|
|
53
|
+
if (name === "manual") {
|
|
54
|
+
const domainName = rest.trim();
|
|
55
|
+
const d = domains.find((x) => x.name === domainName);
|
|
56
|
+
if (!d)
|
|
57
|
+
return null;
|
|
58
|
+
return renderDomainManual(d, mods);
|
|
59
|
+
}
|
|
60
|
+
// /<flow-name> <args> 触发(v8 逻辑保留)
|
|
61
|
+
// v13.x:findFlowInBlueprint 内部按 mods 白名单判断是否允许查找 Flows 段。
|
|
62
|
+
const tpl = findFlowInBlueprint(blueprint, domains, name, profile);
|
|
63
|
+
if (!tpl)
|
|
64
|
+
return null;
|
|
65
|
+
return bindFlowTemplate(tpl, rest);
|
|
66
|
+
}
|
|
67
|
+
// ==================== turn 聚合组 modules 白名单辅助(v13.x issue pt-turn-inject-not-profile-scoped) ====================
|
|
68
|
+
/** 找 turn 聚合组的 modules 白名单(Profile 同名 ProfileGroup 的 ### Modules)。
|
|
69
|
+
* 返 null = 不限制(profile 为 null / 无 turn 聚合组 / ProfileGroup 未填 modules——向后兼容)。
|
|
70
|
+
* 这是阶段 2 的核心:让 Profile "参考手册"### Modules 的段选择真正影响 turn 触发渲染范围。 */
|
|
71
|
+
function turnGroupModules(blueprint, profile) {
|
|
72
|
+
if (!profile)
|
|
73
|
+
return null;
|
|
74
|
+
const turnGroupName = blueprint.groups.find((g) => g.inject === "turn")?.name;
|
|
75
|
+
if (!turnGroupName)
|
|
76
|
+
return null;
|
|
77
|
+
const pg = profile.groups.find((g) => g.name === turnGroupName);
|
|
78
|
+
if (!pg || pg.modules.length === 0)
|
|
79
|
+
return null;
|
|
80
|
+
return pg.modules;
|
|
81
|
+
}
|
|
82
|
+
/** 检查 mods 白名单是否包含某段名。null = 不限制(含)。 */
|
|
83
|
+
function modsAllowsSection(mods, section) {
|
|
84
|
+
if (!mods)
|
|
85
|
+
return true;
|
|
86
|
+
return mods.some((m) => m.section === section);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 渲染 Domain 的"手册"段内容(Phase term-P9.2:从 Manual 拆三段)。
|
|
90
|
+
* - Rules → Rule checklist("## 规范清单")
|
|
91
|
+
* - Flows → FlowTemplate 列表("## 可用手册")
|
|
92
|
+
* - Checklists → Checklist 列表("## 验收清单")
|
|
93
|
+
* 优先级:Flows > Rules > Checklists(workhorse 最常被查)
|
|
94
|
+
* v13.x:受 mods 白名单限制——只渲染 modsAllowsSection 通过的段。
|
|
95
|
+
* 返回 null 表示该 Domain 没有任何手册段(或所有段都被白名单排除)。 */
|
|
96
|
+
function renderDomainManual(d, mods) {
|
|
97
|
+
if (modsAllowsSection(mods, MOD_FLOWS)) {
|
|
98
|
+
const flows = d.modules[MOD_FLOWS];
|
|
99
|
+
if (isFlowTemplateArray(flows)) {
|
|
100
|
+
const lines = [];
|
|
101
|
+
for (const t of flows) {
|
|
102
|
+
const hint = t.argumentHint ? ` ${t.argumentHint}` : "";
|
|
103
|
+
lines.push(`- ${t.name}${hint}: ${t.intent}`);
|
|
104
|
+
}
|
|
105
|
+
if (lines.length > 0) {
|
|
106
|
+
return `# /manual:${d.name}\n\n## 可用手册\n\n${lines.join("\n")}`.trimEnd();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (modsAllowsSection(mods, MOD_RULES)) {
|
|
111
|
+
const rules = d.modules[MOD_RULES];
|
|
112
|
+
if (isRuleArray(rules)) {
|
|
113
|
+
const lines = [];
|
|
114
|
+
for (const r of rules) {
|
|
115
|
+
if (r.type === "invariant") {
|
|
116
|
+
if (r.check)
|
|
117
|
+
lines.push(`- ${r.name}: ${r.check}`);
|
|
118
|
+
else
|
|
119
|
+
lines.push(`- ${r.name}`);
|
|
120
|
+
}
|
|
121
|
+
else if (r.type === "ban" && r.items && r.items.length > 0) {
|
|
122
|
+
if (r.check)
|
|
123
|
+
lines.push(`- ${r.name}: ${r.check} (${r.items.join(" / ")})`);
|
|
124
|
+
else
|
|
125
|
+
lines.push(`- ${r.name}: ${r.items.join(" / ")}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (lines.length > 0) {
|
|
129
|
+
return `# /manual:${d.name}\n\n## 规范清单\n\n${lines.join("\n")}`.trimEnd();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (modsAllowsSection(mods, MOD_CHECKLISTS)) {
|
|
134
|
+
const checklists = d.modules[MOD_CHECKLISTS];
|
|
135
|
+
if (isChecklistArray(checklists)) {
|
|
136
|
+
const sections = [];
|
|
137
|
+
for (const cl of checklists) {
|
|
138
|
+
sections.push(`### ${cl.name}\n${cl.items.map((i) => `- ${i}`).join("\n")}`);
|
|
139
|
+
}
|
|
140
|
+
if (sections.length > 0) {
|
|
141
|
+
return `# /manual:${d.name}\n\n## 验收清单\n\n${sections.join("\n\n")}`.trimEnd();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 把 FlowTemplate 模板 + 用户参数 展开为完整手册 markdown。
|
|
149
|
+
* 错误 / 缺失变量 → 留为字面量(不抛异常)。
|
|
150
|
+
*/
|
|
151
|
+
export function bindFlowTemplate(tpl, args) {
|
|
152
|
+
const tokens = args.trim() ? args.trim().split(/\s+/) : [];
|
|
153
|
+
const varSpecs = parseVarSpecs(tpl._vars, tpl.argumentHint);
|
|
154
|
+
const bound = new Map();
|
|
155
|
+
for (let i = 0; i < varSpecs.length; i++) {
|
|
156
|
+
const spec = varSpecs[i];
|
|
157
|
+
const token = tokens[i];
|
|
158
|
+
if (token !== undefined) {
|
|
159
|
+
bound.set(spec.name, token);
|
|
160
|
+
}
|
|
161
|
+
else if (spec.default !== undefined) {
|
|
162
|
+
bound.set(spec.name, spec.default);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const lines = [];
|
|
166
|
+
lines.push(`# ${tpl.name}`);
|
|
167
|
+
lines.push("");
|
|
168
|
+
if (tpl.argumentHint) {
|
|
169
|
+
lines.push(`_参数:${tpl.argumentHint}_`);
|
|
170
|
+
lines.push("");
|
|
171
|
+
}
|
|
172
|
+
lines.push(`## 前提(Intent)`);
|
|
173
|
+
lines.push(replaceVars(tpl.intent, bound));
|
|
174
|
+
lines.push("");
|
|
175
|
+
lines.push(`## 步骤`);
|
|
176
|
+
tpl.steps.forEach((s, i) => {
|
|
177
|
+
lines.push(`${i + 1}. ${replaceVars(s.desc, bound)}`);
|
|
178
|
+
if (s.observe && s.observe.length > 0) {
|
|
179
|
+
lines.push(` - 验证参照:${s.observe.join(", ")}`);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return lines.join("\n");
|
|
183
|
+
}
|
|
184
|
+
// ==================== 内部辅助 ====================
|
|
185
|
+
function parseVarSpecs(_vars, hint) {
|
|
186
|
+
if (_vars && _vars.length > 0) {
|
|
187
|
+
return _vars.map(parseVarSpecName);
|
|
188
|
+
}
|
|
189
|
+
if (hint) {
|
|
190
|
+
const matches = [...hint.matchAll(/<([^>]+)>/g)];
|
|
191
|
+
return matches.map((m) => parseVarSpecName(m[1]));
|
|
192
|
+
}
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
function parseVarSpecName(raw) {
|
|
196
|
+
const trimmed = raw.trim();
|
|
197
|
+
const idx = trimmed.indexOf("|");
|
|
198
|
+
if (idx < 0)
|
|
199
|
+
return { name: trimmed };
|
|
200
|
+
const name = trimmed.slice(0, idx).trim();
|
|
201
|
+
const defaultPart = trimmed.slice(idx + 1).trim();
|
|
202
|
+
const defaultMatch = defaultPart.match(/^default\s*:\s*(.*)$/);
|
|
203
|
+
if (defaultMatch)
|
|
204
|
+
return { name, default: defaultMatch[1].trim() };
|
|
205
|
+
return { name, default: defaultPart };
|
|
206
|
+
}
|
|
207
|
+
function replaceVars(text, bound) {
|
|
208
|
+
return text.replace(/\{\{([^}]+)\}\}/g, (match, inner) => {
|
|
209
|
+
const spec = parseVarSpecName(inner);
|
|
210
|
+
const v = bound.get(spec.name);
|
|
211
|
+
if (v !== undefined)
|
|
212
|
+
return v;
|
|
213
|
+
if (spec.default !== undefined)
|
|
214
|
+
return spec.default;
|
|
215
|
+
return match;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/** 在 Blueprint 聚合组(inject=turn)的引用域中按名查找 FlowTemplate(跨 Domain)。
|
|
219
|
+
* v13.x(issue pt-turn-inject-not-profile-scoped):加 profile 参数——内部算 mods 白名单,
|
|
220
|
+
* 白名单不含 Flows 段时返 undefined(Profile "参考手册"### Modules 未声明 Flows 则 /<flow-name> 触发失效)。
|
|
221
|
+
* Phase term-P4.3 + term-final:inject 语义值 turn(原 context_message → turn → 现聚合组 inject=turn)。 */
|
|
222
|
+
export function findFlowInBlueprint(blueprint,
|
|
223
|
+
// Phase term-P9.3:type 字段删除——Domain 不再有 type 维度,按 H2 段名(这里是 ## Flows)识别 FlowTemplate
|
|
224
|
+
domains, tplName, profile = null) {
|
|
225
|
+
// 验证 Blueprint 里有 inject=turn 的聚合组(间接确认 input 事件该由本实例覆盖接管)
|
|
226
|
+
const hasTurnGroup = blueprint.groups.some((g) => g.inject === "turn");
|
|
227
|
+
if (!hasTurnGroup)
|
|
228
|
+
return undefined;
|
|
229
|
+
// v13.x:mods 白名单不含 Flows 段则不查找——配置即行为
|
|
230
|
+
const mods = turnGroupModules(blueprint, profile);
|
|
231
|
+
if (!modsAllowsSection(mods, MOD_FLOWS))
|
|
232
|
+
return undefined;
|
|
233
|
+
for (const d of domains) {
|
|
234
|
+
// Phase term-P9.2:FlowTemplate 在 ## Flows 段(不分 type)。
|
|
235
|
+
const flows = d.modules[MOD_FLOWS];
|
|
236
|
+
if (!isFlowTemplateArray(flows))
|
|
237
|
+
continue;
|
|
238
|
+
const hit = flows.find((t) => t.name === tplName);
|
|
239
|
+
if (hit) {
|
|
240
|
+
const bt = { ...hit };
|
|
241
|
+
// P2.1:v9 BoundableTemplate = FlowTemplate & { _vars? },vars 字段 spread 不会产生
|
|
242
|
+
// 原双重 cast (bt as unknown as { vars?: unknown }).vars 永远 undefined(dead code)。
|
|
243
|
+
// 若未来需从 args 传 vars 进来,应在调用方 bindFlowTemplate 处理,不在此处 cast 补救。
|
|
244
|
+
return bt;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|