@xfe-repo/cli-plugin-ai-rules 2.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.
Files changed (89) hide show
  1. package/dist/block-utils.d.ts +11 -0
  2. package/dist/block-utils.d.ts.map +1 -0
  3. package/dist/block-utils.js +13 -0
  4. package/dist/block-utils.js.map +1 -0
  5. package/dist/formats/agent-md.d.ts +35 -0
  6. package/dist/formats/agent-md.d.ts.map +1 -0
  7. package/dist/formats/agent-md.js +241 -0
  8. package/dist/formats/agent-md.js.map +1 -0
  9. package/dist/formats/markdown.d.ts +35 -0
  10. package/dist/formats/markdown.d.ts.map +1 -0
  11. package/dist/formats/markdown.js +241 -0
  12. package/dist/formats/markdown.js.map +1 -0
  13. package/dist/formats/mcp-json.d.ts +25 -0
  14. package/dist/formats/mcp-json.d.ts.map +1 -0
  15. package/dist/formats/mcp-json.js +132 -0
  16. package/dist/formats/mcp-json.js.map +1 -0
  17. package/dist/formats/shared.d.ts +4 -0
  18. package/dist/formats/shared.d.ts.map +1 -0
  19. package/dist/formats/shared.js +24 -0
  20. package/dist/formats/shared.js.map +1 -0
  21. package/dist/formats/skill-dir.d.ts +17 -0
  22. package/dist/formats/skill-dir.d.ts.map +1 -0
  23. package/dist/formats/skill-dir.js +72 -0
  24. package/dist/formats/skill-dir.js.map +1 -0
  25. package/dist/gitignore.d.ts +12 -0
  26. package/dist/gitignore.d.ts.map +1 -0
  27. package/dist/gitignore.js +32 -0
  28. package/dist/gitignore.js.map +1 -0
  29. package/dist/index.d.ts +18 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +358 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/injection.d.ts +26 -0
  34. package/dist/injection.d.ts.map +1 -0
  35. package/dist/injection.js +169 -0
  36. package/dist/injection.js.map +1 -0
  37. package/dist/mcp-writer.d.ts +23 -0
  38. package/dist/mcp-writer.d.ts.map +1 -0
  39. package/dist/mcp-writer.js +131 -0
  40. package/dist/mcp-writer.js.map +1 -0
  41. package/dist/merge.d.ts +14 -0
  42. package/dist/merge.d.ts.map +1 -0
  43. package/dist/merge.js +35 -0
  44. package/dist/merge.js.map +1 -0
  45. package/dist/pipeline.d.ts +16 -0
  46. package/dist/pipeline.d.ts.map +1 -0
  47. package/dist/pipeline.js +165 -0
  48. package/dist/pipeline.js.map +1 -0
  49. package/dist/pipeline.new.d.ts +11 -0
  50. package/dist/pipeline.new.d.ts.map +1 -0
  51. package/dist/pipeline.new.js +11 -0
  52. package/dist/pipeline.new.js.map +1 -0
  53. package/dist/repo-cache.d.ts +24 -0
  54. package/dist/repo-cache.d.ts.map +1 -0
  55. package/dist/repo-cache.js +51 -0
  56. package/dist/repo-cache.js.map +1 -0
  57. package/dist/scanner.d.ts +12 -0
  58. package/dist/scanner.d.ts.map +1 -0
  59. package/dist/scanner.js +119 -0
  60. package/dist/scanner.js.map +1 -0
  61. package/dist/sync.d.ts +26 -0
  62. package/dist/sync.d.ts.map +1 -0
  63. package/dist/sync.js +172 -0
  64. package/dist/sync.js.map +1 -0
  65. package/dist/targets.d.ts +28 -0
  66. package/dist/targets.d.ts.map +1 -0
  67. package/dist/targets.js +90 -0
  68. package/dist/targets.js.map +1 -0
  69. package/dist/types.d.ts +112 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +53 -0
  72. package/dist/types.js.map +1 -0
  73. package/dist/writers/index.d.ts +15 -0
  74. package/dist/writers/index.d.ts.map +1 -0
  75. package/dist/writers/index.js +23 -0
  76. package/dist/writers/index.js.map +1 -0
  77. package/dist/writers/markdown-writer.d.ts +15 -0
  78. package/dist/writers/markdown-writer.d.ts.map +1 -0
  79. package/dist/writers/markdown-writer.js +249 -0
  80. package/dist/writers/markdown-writer.js.map +1 -0
  81. package/dist/writers/mcp-json-writer.d.ts +11 -0
  82. package/dist/writers/mcp-json-writer.d.ts.map +1 -0
  83. package/dist/writers/mcp-json-writer.js +185 -0
  84. package/dist/writers/mcp-json-writer.js.map +1 -0
  85. package/dist/writers/types.d.ts +29 -0
  86. package/dist/writers/types.d.ts.map +1 -0
  87. package/dist/writers/types.js +8 -0
  88. package/dist/writers/types.js.map +1 -0
  89. package/package.json +27 -0
package/dist/index.js ADDED
@@ -0,0 +1,358 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 插件入口
3
+ *
4
+ * 声明式 AI 配置同步:从 xfe.json 读取 ai 配置,
5
+ * 拉取远程仓库内容,按 target 注册表分发到项目 IDE 配置
6
+ */
7
+ import { aiConfigSchema, rulesAddParameters, rulesSyncParameters, rulesTargetsParameters } from './types.js';
8
+ import { SyncItemType } from './types.js';
9
+ import { planSync, detectConflicts, resolveConflicts, executePlan, checkSyncStatus, applyInjections as applyInjectionsToFiles, } from './pipeline.js';
10
+ import { scanRemoteEntries, loadSelectedItems } from './scanner.js';
11
+ import { fetchCachedRepo } from './repo-cache.js';
12
+ import { getTargetChoices } from './targets.js';
13
+ import { removeStaleSkillDirs } from './formats/skill-dir.js';
14
+ export { SyncItemType } from './types.js';
15
+ // ─── Store ──────
16
+ const AI_RULES_STORE_INITIAL = {
17
+ lastSyncHash: {},
18
+ lastRemoteHash: '',
19
+ lastSyncTime: 0,
20
+ };
21
+ // ─── 插件工厂 ──────
22
+ export function aiRulesPlugin() {
23
+ const injectionRegistry = new Map();
24
+ return {
25
+ name: 'ai-rules',
26
+ setup(_ctx, hooks) {
27
+ hooks.registerStore(AI_RULES_STORE_INITIAL);
28
+ const capability = {
29
+ injectRules(source, items) {
30
+ injectionRegistry.set(source, items);
31
+ },
32
+ removeInjectedRules(source) {
33
+ injectionRegistry.delete(source);
34
+ },
35
+ async applyInjections(ctx) {
36
+ const config = parseAiConfig(ctx);
37
+ if (!config)
38
+ return { written: 0, removed: 0 };
39
+ return applyInjectionsToFiles(ctx, config, injectionRegistry);
40
+ },
41
+ };
42
+ hooks.provide('ai-rules', capability);
43
+ hooks.registerView({
44
+ name: 'rules-status',
45
+ label: 'Rules',
46
+ icon: '◇',
47
+ slot: 'footer',
48
+ value: (state) => {
49
+ const s = state['ai-rules'];
50
+ if (!s?.lastSyncTime || s.synced === false)
51
+ return 'Rules Not Synced';
52
+ return 'Rules Synced';
53
+ },
54
+ color: 'cyan',
55
+ });
56
+ hooks.registerCommand({
57
+ name: 'rules:list',
58
+ simpleDescription: '查看本地 AI 规则配置',
59
+ description: '读取 xfe.json 中的 aiRules 配置,展示 targets、agent、subagents、rules、skills 以及最近同步时间;不会访问远程仓库。',
60
+ execute: executeListCommand,
61
+ });
62
+ hooks.registerCommand({
63
+ name: 'rules:sync',
64
+ simpleDescription: '同步 AI 规则到 IDE',
65
+ description: '根据 xfe.json 中的 aiRules 配置拉取远程内容并写入对应 IDE 配置文件。若预期存在本地改动,建议预先传入 conflictAction 指定 overwrite 或 skip。',
66
+ parameters: rulesSyncParameters,
67
+ execute: (ctx) => executeSyncCommand(ctx, injectionRegistry),
68
+ });
69
+ hooks.registerCommand({
70
+ name: 'rules:add',
71
+ simpleDescription: '选择远程 AI 条目并写入配置',
72
+ description: '从 aiRules.source 仓库扫描可用的 agent、rule、skill 条目,并把 selectedIds 写回 xfe.json。若 selectedIds 中包含多个 agent,可通过 primaryAgent 指定主 Agent,其余 agent 会写入 subagents。',
73
+ parameters: rulesAddParameters,
74
+ execute: (ctx) => executeAddCommand(ctx, injectionRegistry),
75
+ });
76
+ hooks.registerCommand({
77
+ name: 'rules:targets',
78
+ simpleDescription: '更新 AI 规则同步目标',
79
+ description: '更新 xfe.json 中的 aiRules.targets。targets 可选值为 copilot、codex、cursor、claude-code。',
80
+ parameters: rulesTargetsParameters,
81
+ execute: executeTargetsCommand,
82
+ });
83
+ hooks.onAppInit.tap('ai-rules', async (ctx) => {
84
+ const config = parseAiConfig(ctx);
85
+ if (!config)
86
+ return;
87
+ try {
88
+ const synced = await checkSyncStatus(ctx, config);
89
+ ctx.store.setPluginState('ai-rules', { synced });
90
+ if (!synced) {
91
+ ctx.toast.show('AI 规则未同步,运行 xfe rules sync 同步', 'info');
92
+ }
93
+ }
94
+ catch {
95
+ // 网络不可用时静默跳过
96
+ }
97
+ });
98
+ },
99
+ };
100
+ }
101
+ // ─── rules:list 命令 ──────
102
+ async function executeListCommand(ctx) {
103
+ const config = parseAiConfig(ctx);
104
+ if (!config)
105
+ return;
106
+ const hasItems = config.agent || config.subagents.length > 0 || config.rules.length > 0 || config.skills.length > 0 || config.mcpServers.length > 0;
107
+ if (!hasItems && config.targets.length === 0) {
108
+ ctx.logger.warn('暂无本地 AI 配置,请使用 xfe rules add 新增');
109
+ return;
110
+ }
111
+ const totalSelected = (config.agent ? 1 : 0) + config.subagents.length + config.rules.length + config.skills.length + config.mcpServers.length;
112
+ ctx.logger.log('');
113
+ ctx.logger.log(`本地 AI 配置 (已选 ${totalSelected} 项):`);
114
+ ctx.logger.log('─'.repeat(60));
115
+ if (config.targets.length > 0) {
116
+ ctx.logger.log(` Targets: ${config.targets.join(', ')}`);
117
+ }
118
+ const sections = [
119
+ ['Agent', config.agent ? [config.agent] : []],
120
+ ['Sub-Agent', config.subagents],
121
+ ['Rule', config.rules],
122
+ ['Skill', config.skills],
123
+ ['MCP Server', config.mcpServers],
124
+ ];
125
+ for (const [label, items] of sections) {
126
+ for (const id of items) {
127
+ ctx.logger.log(` ${label.padEnd(12)} ${id}`);
128
+ }
129
+ }
130
+ ctx.logger.log('');
131
+ ctx.logger.log(` Source: ${config.source}`);
132
+ ctx.logger.log(` Branch: ${config.branch}`);
133
+ const storeState = getAiRulesState(ctx);
134
+ if (storeState.lastSyncTime) {
135
+ ctx.logger.log(` 上次同步: ${new Date(storeState.lastSyncTime).toLocaleString()}`);
136
+ }
137
+ ctx.logger.log('');
138
+ }
139
+ // ─── rules:sync 命令 ──────
140
+ async function executeSyncCommand(ctx, injections) {
141
+ const config = parseAiConfig(ctx);
142
+ if (!config)
143
+ return;
144
+ if (config.targets.length === 0) {
145
+ ctx.logger.warn('未配置 aiRules.targets,请先运行 xfe rules targets 或在 xfe.json 中补充配置');
146
+ return;
147
+ }
148
+ const hasItems = config.agent || config.subagents.length > 0 || config.rules.length > 0 || config.skills.length > 0 || config.mcpServers.length > 0;
149
+ if (!hasItems && injections.size === 0) {
150
+ ctx.logger.warn('未配置任何 agent/subagents/rules/skills/mcpServers,请先运行 xfe rules add');
151
+ return;
152
+ }
153
+ const git = ctx.inject('git');
154
+ const spinner = ctx.spinner.create('正在同步 AI 规则...');
155
+ spinner.start();
156
+ try {
157
+ const cachePath = await fetchCachedRepo(ctx, git, config);
158
+ const entries = await scanRemoteEntries(cachePath);
159
+ const selectedIds = collectSelectedIds(config);
160
+ const selectedItems = await loadSelectedItems(cachePath, entries, selectedIds, config);
161
+ const totalCount = selectedItems.length + [...injections.values()].flat().length;
162
+ spinner.text = `正在注入 ${totalCount} 条规则到 ${config.targets.join(', ')}...`;
163
+ const storeState = getAiRulesState(ctx);
164
+ const plan = planSync(config, selectedItems, injections);
165
+ const detected = await detectConflicts(plan, ctx.projectRoot, storeState.lastSyncHash);
166
+ spinner.stop();
167
+ const resolved = await resolveConflicts(detected, ctx);
168
+ spinner.start();
169
+ const result = await executePlan(resolved, ctx.projectRoot);
170
+ const remoteHash = await git.latestHash({ cwd: cachePath });
171
+ await removeStaleSkillDirs(ctx.projectRoot, storeState.lastSkillDirs ?? [], result.skillDirPaths);
172
+ ctx.store.setPluginState('ai-rules', {
173
+ lastSyncHash: result.fileHashes,
174
+ lastRemoteHash: remoteHash,
175
+ lastSyncTime: Date.now(),
176
+ synced: true,
177
+ lastInjectedHash: result.injectedHashes,
178
+ lastSkillDirs: result.skillDirPaths,
179
+ });
180
+ spinner.succeed(`AI 规则同步完成: ${result.written} 个文件写入, ${result.skipped} 个跳过`);
181
+ }
182
+ catch (e) {
183
+ spinner.fail(`同步失败: ${e instanceof Error ? e.message : e}`);
184
+ }
185
+ }
186
+ // ─── rules:add 命令 ──────
187
+ async function executeAddCommand(ctx, injections) {
188
+ const config = parseAiConfig(ctx);
189
+ if (!config)
190
+ return;
191
+ const git = ctx.inject('git');
192
+ const spinner = ctx.spinner.create('正在获取远程规则列表...');
193
+ spinner.start();
194
+ try {
195
+ const cachePath = await fetchCachedRepo(ctx, git, config);
196
+ const entries = await scanRemoteEntries(cachePath);
197
+ spinner.stop();
198
+ const currentSelectedIds = collectSelectedIds(config);
199
+ const selectedIds = await promptItemSelection(ctx, entries, currentSelectedIds);
200
+ // 分类选中项
201
+ const selectedAgents = entries.filter((e) => e.type === SyncItemType.Agent && selectedIds.has(e.id));
202
+ let agentId;
203
+ if (selectedAgents.length === 1) {
204
+ agentId = selectedAgents[0].id;
205
+ }
206
+ else if (selectedAgents.length > 1) {
207
+ agentId = await promptMainAgentSelection(ctx, selectedAgents, config.agent);
208
+ }
209
+ const { rules, skills, mcpServers, subagents } = classifySelectedIds(entries, selectedIds, agentId);
210
+ ctx.store.setPluginState('xfe', {
211
+ aiRules: {
212
+ ...ctx.store.getState().xfe?.aiRules,
213
+ agent: agentId,
214
+ subagents,
215
+ rules,
216
+ skills,
217
+ mcpServers,
218
+ },
219
+ });
220
+ const parts = [
221
+ agentId && `agent: ${agentId}`,
222
+ subagents.length > 0 && `${subagents.length} subagents`,
223
+ rules.length > 0 && `${rules.length} rules`,
224
+ skills.length > 0 && `${skills.length} skills`,
225
+ mcpServers.length > 0 && `${mcpServers.length} mcp-servers`,
226
+ ].filter(Boolean);
227
+ ctx.logger.success(`已写入 xfe.json: ${parts.join(', ') || '无选择'}`);
228
+ if (parts.length === 0) {
229
+ ctx.logger.warn('未选择任何条目,配置已清空');
230
+ return;
231
+ }
232
+ const { sync } = await ctx.prompt.ask({
233
+ type: 'confirm',
234
+ name: 'sync',
235
+ message: '是否立即执行同步?',
236
+ default: true,
237
+ });
238
+ if (sync) {
239
+ await executeSyncCommand(ctx, injections);
240
+ }
241
+ else {
242
+ ctx.logger.log('运行 xfe rules sync 开始同步');
243
+ }
244
+ }
245
+ catch (e) {
246
+ spinner.fail(`获取列表失败: ${e instanceof Error ? e.message : e}`);
247
+ }
248
+ }
249
+ // ─── rules:targets 命令 ──────
250
+ async function executeTargetsCommand(ctx) {
251
+ const config = parseAiConfig(ctx);
252
+ if (!config)
253
+ return;
254
+ const choices = getTargetChoices();
255
+ const { targets = [] } = await ctx.prompt.ask({
256
+ type: 'search-checkbox',
257
+ name: 'targets',
258
+ message: '选择同步目标 IDE:',
259
+ choices,
260
+ default: config.targets,
261
+ });
262
+ ctx.store.setPluginState('xfe', {
263
+ aiRules: { ...ctx.store.getState().xfe?.aiRules, targets },
264
+ });
265
+ if (targets.length > 0) {
266
+ ctx.logger.success(`已更新 targets: ${targets.join(', ')}`);
267
+ }
268
+ else {
269
+ ctx.logger.warn('未选择任何 IDE 目标');
270
+ }
271
+ }
272
+ // ─── 交互提示 ──────
273
+ async function promptMainAgentSelection(ctx, selectedAgents, currentAgent) {
274
+ const choices = selectedAgents.map((entry) => {
275
+ const desc = entry.description ? ` — ${entry.description}` : '';
276
+ return { name: `${entry.id}${desc}`, value: entry.id };
277
+ });
278
+ const { primaryAgent } = await ctx.prompt.ask({
279
+ type: 'list',
280
+ name: 'primaryAgent',
281
+ message: '已选择多个 Agent,请指定主 Agent(输出到 AGENTS.md/CLAUDE.md):',
282
+ choices,
283
+ default: currentAgent || undefined,
284
+ });
285
+ return primaryAgent || undefined;
286
+ }
287
+ async function promptItemSelection(ctx, entries, currentIds) {
288
+ if (entries.length === 0)
289
+ return new Set();
290
+ const choices = entries.map((entry) => {
291
+ const desc = entry.description ? ` — ${entry.description}` : '';
292
+ const scope = entry.appliesTo?.length ? ` [${entry.appliesTo.join(', ')}]` : '';
293
+ return {
294
+ name: `[${entry.type}] ${entry.id}${desc}${scope}`,
295
+ value: entry.id,
296
+ short: entry.id,
297
+ };
298
+ });
299
+ const message = currentIds.size > 0 ? `选择 AI 规则 (当前已选 ${currentIds.size} 项):` : '选择 AI 规则:';
300
+ const { selectedIds = [] } = await ctx.prompt.ask({
301
+ type: 'search-checkbox',
302
+ name: 'selectedIds',
303
+ message,
304
+ choices,
305
+ default: [...currentIds],
306
+ });
307
+ return new Set(selectedIds);
308
+ }
309
+ // ─── Helpers ──────
310
+ function classifySelectedIds(entries, selectedIds, agentId) {
311
+ const rules = [];
312
+ const skills = [];
313
+ const mcpServers = [];
314
+ const subagents = [];
315
+ for (const entry of entries) {
316
+ if (!selectedIds.has(entry.id))
317
+ continue;
318
+ switch (entry.type) {
319
+ case SyncItemType.Rule:
320
+ rules.push(entry.id);
321
+ break;
322
+ case SyncItemType.Skill:
323
+ skills.push(entry.id);
324
+ break;
325
+ case SyncItemType.McpServer:
326
+ mcpServers.push(entry.id);
327
+ break;
328
+ case SyncItemType.Agent:
329
+ if (entry.id !== agentId)
330
+ subagents.push(entry.id);
331
+ break;
332
+ }
333
+ }
334
+ return { rules, skills, mcpServers, subagents };
335
+ }
336
+ function collectSelectedIds(config) {
337
+ const ids = [...config.subagents, ...config.rules, ...config.skills, ...config.mcpServers];
338
+ if (config.agent)
339
+ ids.push(config.agent);
340
+ return new Set(ids);
341
+ }
342
+ function getAiRulesState(ctx) {
343
+ return (ctx.store.getState()['ai-rules'] ?? AI_RULES_STORE_INITIAL);
344
+ }
345
+ function parseAiConfig(ctx) {
346
+ const aiConfig = ctx.store.getState().xfe?.aiRules;
347
+ if (!aiConfig) {
348
+ ctx.logger.warn('xfe.json 中未配置 aiRules 字段,请先添加 AI 规则配置');
349
+ return undefined;
350
+ }
351
+ const parseResult = aiConfigSchema.safeParse(aiConfig);
352
+ if (!parseResult.success) {
353
+ ctx.logger.error(`aiRules 配置格式错误: ${parseResult.error.message}`);
354
+ return undefined;
355
+ }
356
+ return parseResult.data;
357
+ }
358
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAE5G,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EACL,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,eAAe,IAAI,sBAAsB,GAC1C,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGzC,mBAAmB;AAEnB,MAAM,sBAAsB,GAAsB;IAChD,YAAY,EAAE,EAAE;IAChB,cAAc,EAAE,EAAE;IAClB,YAAY,EAAE,CAAC;CAChB,CAAA;AAQD,kBAAkB;AAElB,MAAM,UAAU,aAAa;IAC3B,MAAM,iBAAiB,GAAsB,IAAI,GAAG,EAAE,CAAA;IAEtD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,KAAK,CAAC,IAAI,EAAE,KAAK;YACf,KAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAA;YAE3C,MAAM,UAAU,GAAsB;gBACpC,WAAW,CAAC,MAAM,EAAE,KAAK;oBACvB,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;gBACtC,CAAC;gBAED,mBAAmB,CAAC,MAAM;oBACxB,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBAClC,CAAC;gBAED,KAAK,CAAC,eAAe,CAAC,GAAG;oBACvB,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;oBAEjC,IAAI,CAAC,MAAM;wBAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;oBAE9C,OAAO,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAA;gBAC/D,CAAC;aACF,CAAA;YAED,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;YAErC,KAAK,CAAC,YAAY,CAAC;gBACjB,IAAI,EAAE,cAAc;gBACpB,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,GAAG;gBACT,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;oBAE3B,IAAI,CAAC,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK;wBAAE,OAAO,kBAAkB,CAAA;oBAErE,OAAO,cAAc,CAAA;gBACvB,CAAC;gBACD,KAAK,EAAE,MAAM;aACd,CAAC,CAAA;YAEF,KAAK,CAAC,eAAe,CAAC;gBACpB,IAAI,EAAE,YAAY;gBAClB,iBAAiB,EAAE,cAAc;gBACjC,WAAW,EAAE,sFAAsF;gBACnG,OAAO,EAAE,kBAAkB;aAC5B,CAAC,CAAA;YAEF,KAAK,CAAC,eAAe,CAAC;gBACpB,IAAI,EAAE,YAAY;gBAClB,iBAAiB,EAAE,eAAe;gBAClC,WAAW,EACT,oGAAoG;gBACtG,UAAU,EAAE,mBAAmB;gBAC/B,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,CAAC;aAC7D,CAAC,CAAA;YAEF,KAAK,CAAC,eAAe,CAAC;gBACpB,IAAI,EAAE,WAAW;gBACjB,iBAAiB,EAAE,iBAAiB;gBACpC,WAAW,EACT,sJAAsJ;gBACxJ,UAAU,EAAE,kBAAkB;gBAC9B,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,CAAC;aAC5D,CAAC,CAAA;YAEF,KAAK,CAAC,eAAe,CAAC;gBACpB,IAAI,EAAE,eAAe;gBACrB,iBAAiB,EAAE,cAAc;gBACjC,WAAW,EAAE,+EAA+E;gBAC5F,UAAU,EAAE,sBAAsB;gBAClC,OAAO,EAAE,qBAAqB;aAC/B,CAAC,CAAA;YAEF,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;gBAEjC,IAAI,CAAC,MAAM;oBAAE,OAAM;gBAEnB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;oBAEjD,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;oBAEhD,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAA;oBACzD,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,aAAa;gBACf,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC;AAED,2BAA2B;AAE3B,KAAK,UAAU,kBAAkB,CAAC,GAAkB;IAClD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,QAAQ,GACZ,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAA;IAEpI,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;QAClD,OAAM;IACR,CAAC;IAED,MAAM,aAAa,GACjB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAA;IAE1H,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,aAAa,MAAM,CAAC,CAAA;IACnD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IAE9B,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED,MAAM,QAAQ,GAA8B;QAC1C,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC;QAC/B,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACxB,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC;KAClC,CAAA;IAED,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACtC,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;IACjD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;IAEjD,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;IAEvC,IAAI,UAAU,CAAC,YAAY,EAAE,CAAC;QAC5B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;IACpF,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACpB,CAAC;AAED,2BAA2B;AAE3B,KAAK,UAAU,kBAAkB,CAAC,GAAkB,EAAE,UAA6B;IACjF,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAA;QAC/E,OAAM;IACR,CAAC;IAED,MAAM,QAAQ,GACZ,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAA;IAEpI,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAA;QACnF,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAgB,KAAK,CAAC,CAAA;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IACnD,OAAO,CAAC,KAAK,EAAE,CAAA;IAEf,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACzD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;QAC9C,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAA;QACtF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAA;QAEhF,OAAO,CAAC,IAAI,GAAG,QAAQ,UAAU,SAAS,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAA;QAExE,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;QACxD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;QAEtF,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAEtD,OAAO,CAAC,KAAK,EAAE,CAAA;QAEf,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,CAAA;QAC3D,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA;QAE3D,MAAM,oBAAoB,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,aAAa,IAAI,EAAE,EAAE,MAAM,CAAC,aAAa,CAAC,CAAA;QAEjG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE;YACnC,YAAY,EAAE,MAAM,CAAC,UAAU;YAC/B,cAAc,EAAE,UAAU;YAC1B,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;YACxB,MAAM,EAAE,IAAI;YACZ,gBAAgB,EAAE,MAAM,CAAC,cAAc;YACvC,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CAAC,CAAA;QAEF,OAAO,CAAC,OAAO,CAAC,cAAc,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC,OAAO,MAAM,CAAC,CAAA;IAC9E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC7D,CAAC;AACH,CAAC;AAED,0BAA0B;AAE1B,KAAK,UAAU,iBAAiB,CAAC,GAAsC,EAAE,UAA6B;IACpG,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAgB,KAAK,CAAC,CAAA;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IACnD,OAAO,CAAC,KAAK,EAAE,CAAA;IAEf,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QACzD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAA;QAElD,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,MAAM,kBAAkB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACrD,MAAM,WAAW,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAA;QAE/E,QAAQ;QACR,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAEpG,IAAI,OAA2B,CAAA;QAE/B,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAChC,CAAC;aAAM,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QAC7E,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;QAEnG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE;YAC9B,OAAO,EAAE;gBACP,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO;gBACpC,KAAK,EAAE,OAAO;gBACd,SAAS;gBACT,KAAK;gBACL,MAAM;gBACN,UAAU;aACX;SACF,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG;YACZ,OAAO,IAAI,UAAU,OAAO,EAAE;YAC9B,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC,MAAM,YAAY;YACvD,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,QAAQ;YAC3C,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,SAAS;YAC9C,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC,MAAM,cAAc;SAC5D,CAAC,MAAM,CAAC,OAAO,CAAa,CAAA;QAE7B,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;QAEhE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YAChC,OAAM;QACR,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;YACpC,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,IAAI;SACd,CAAC,CAAA;QAEF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC3C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC/D,CAAC;AACH,CAAC;AAED,8BAA8B;AAE9B,KAAK,UAAU,qBAAqB,CAAC,GAAkB;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,CAAC,MAAM;QAAE,OAAM;IAEnB,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAA;IAElC,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;QAC5C,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,aAAa;QACtB,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE;QAC9B,OAAO,EAAE,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;KAC3D,CAAC,CAAA;IAEF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC1D,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IACjC,CAAC;AACH,CAAC;AAED,kBAAkB;AAElB,KAAK,UAAU,wBAAwB,CACrC,GAAkB,EAClB,cAA2B,EAC3B,YAAqB;IAErB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAE/D,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;QAC5C,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,kDAAkD;QAC3D,OAAO;QACP,OAAO,EAAE,YAAY,IAAI,SAAS;KACnC,CAAC,CAAA;IAEF,OAAO,YAAY,IAAI,SAAS,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,GAAkB,EAAE,OAAoB,EAAE,UAAuB;IAClG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAA;IAE1C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QAE/E,OAAO;YACL,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,GAAG,IAAI,GAAG,KAAK,EAAE;YAClD,KAAK,EAAE,KAAK,CAAC,EAAE;YACf,KAAK,EAAE,KAAK,CAAC,EAAE;SAChB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAA;IAE3F,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;QAChD,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,aAAa;QACnB,OAAO;QACP,OAAO;QACP,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC;KACzB,CAAC,CAAA;IAEF,OAAO,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;AAC7B,CAAC;AAED,qBAAqB;AAErB,SAAS,mBAAmB,CAC1B,OAAoB,EACpB,WAAwB,EACxB,OAAgB;IAEhB,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAA;IAE9B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,SAAQ;QAExC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,YAAY,CAAC,IAAI;gBACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAK;YACP,KAAK,YAAY,CAAC,KAAK;gBACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBACrB,MAAK;YACP,KAAK,YAAY,CAAC,SAAS;gBACzB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBACzB,MAAK;YACP,KAAK,YAAY,CAAC,KAAK;gBACrB,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO;oBAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAClD,MAAK;QACT,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;AACjD,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAgB;IAC1C,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAE1F,IAAI,MAAM,CAAC,KAAK;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAExC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;AACrB,CAAC;AAED,SAAS,eAAe,CAAC,GAAkB;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,IAAI,sBAAsB,CAAsB,CAAA;AAC1F,CAAC;AAED,SAAS,aAAa,CAAC,GAAkB;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAA;IAElD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAA;QACxD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAEtD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAChE,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,WAAW,CAAC,IAAI,CAAA;AACzB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 注入管理
3
+ *
4
+ * 动态注入段落的构建、追加、剥离、应用逻辑
5
+ * 从 sync.ts 拆分,作为独立关注点
6
+ */
7
+ import type { PluginContext } from '@xfe-repo/cli-core';
8
+ import type { AiConfig, ApplyResult, InjectionRegistry, OutputFile } from './types.js';
9
+ export declare function stripInjectedSections(content: string): string;
10
+ export declare function computeHash(content: string): string;
11
+ /**
12
+ * 为 MergeFile / MarkedSection 输出文件追加注入段落
13
+ *
14
+ * 返回注入产生的 IndividualFile 独立文件列表
15
+ */
16
+ export declare function appendInjectionsToOutputFiles(outputFiles: OutputFile[], targetIds: string[], injections?: InjectionRegistry): OutputFile[];
17
+ /**
18
+ * 将注入注册表中的内容立即写入已有的目标文件(不触发完整 sync 流程)
19
+ *
20
+ * - MergeFile / MarkedSection:读取已有文件 → 剔除旧注入段落 → 追加新注入 → 写回
21
+ * - IndividualFile:创建/覆盖注入项独立文件
22
+ * - 注入表为空时:移除合并文件中的注入段落 + 删除历史注入独立文件
23
+ */
24
+ export declare function applyInjections(ctx: PluginContext, config: AiConfig, injections: InjectionRegistry): Promise<ApplyResult>;
25
+ export declare function spliceMarkerBlock(content: string, beginMarker: string, endMarker: string, replacement?: string): string;
26
+ //# sourceMappingURL=injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.d.ts","sourceRoot":"","sources":["../src/injection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAqB,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAY,MAAM,YAAY,CAAA;AAYnH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,UAAU,EAAE,EACzB,SAAS,EAAE,MAAM,EAAE,EACnB,UAAU,CAAC,EAAE,iBAAiB,GAC7B,UAAU,EAAE,CAgBd;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA+D/H;AAgED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BvH"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 注入管理
3
+ *
4
+ * 动态注入段落的构建、追加、剥离、应用逻辑
5
+ * 从 sync.ts 拆分,作为独立关注点
6
+ */
7
+ import { createHash } from 'node:crypto';
8
+ import { existsSync } from 'node:fs';
9
+ import { readFile, writeFile, mkdir, unlink } from 'node:fs/promises';
10
+ import path from 'node:path';
11
+ import { getTarget, getTargetSlots, resolveSlotForItem, formatOutputFile, OutputStrategy } from './targets.js';
12
+ // ─── Constants ──────
13
+ const INJECTED_BEGIN = '<!-- xfe:injected:begin -->';
14
+ const INJECTED_END = '<!-- xfe:injected:end -->';
15
+ const INJECTED_SOURCE_BEGIN = (source) => `<!-- xfe:injected:${source}:begin -->`;
16
+ const INJECTED_SOURCE_END = (source) => `<!-- xfe:injected:${source}:end -->`;
17
+ // ─── Public ──────
18
+ export function stripInjectedSections(content) {
19
+ return spliceMarkerBlock(content, INJECTED_BEGIN, INJECTED_END);
20
+ }
21
+ export function computeHash(content) {
22
+ return createHash('sha256').update(content).digest('hex');
23
+ }
24
+ /**
25
+ * 为 MergeFile / MarkedSection 输出文件追加注入段落
26
+ *
27
+ * 返回注入产生的 IndividualFile 独立文件列表
28
+ */
29
+ export function appendInjectionsToOutputFiles(outputFiles, targetIds, injections) {
30
+ if (!injections || injections.size === 0)
31
+ return [];
32
+ const injectedBlock = buildInjectedBlock(injections);
33
+ if (!injectedBlock)
34
+ return [];
35
+ const mergeFilePaths = collectMergeFilePaths(targetIds);
36
+ for (const file of outputFiles) {
37
+ if (!mergeFilePaths.has(file.relativePath))
38
+ continue;
39
+ file.content = file.content.trimEnd() + '\n\n' + injectedBlock + '\n';
40
+ }
41
+ return generateInjectedIndividualFiles(targetIds, injections);
42
+ }
43
+ /**
44
+ * 将注入注册表中的内容立即写入已有的目标文件(不触发完整 sync 流程)
45
+ *
46
+ * - MergeFile / MarkedSection:读取已有文件 → 剔除旧注入段落 → 追加新注入 → 写回
47
+ * - IndividualFile:创建/覆盖注入项独立文件
48
+ * - 注入表为空时:移除合并文件中的注入段落 + 删除历史注入独立文件
49
+ */
50
+ export async function applyInjections(ctx, config, injections) {
51
+ const injectedBlock = buildInjectedBlock(injections);
52
+ const mergeFilePaths = collectMergeFilePaths(config.targets);
53
+ let written = 0;
54
+ let removed = 0;
55
+ for (const relativePath of mergeFilePaths) {
56
+ const absPath = path.join(ctx.projectRoot, relativePath);
57
+ if (!existsSync(absPath))
58
+ continue;
59
+ const content = await readFile(absPath, 'utf-8');
60
+ const stripped = stripInjectedSections(content);
61
+ if (injectedBlock) {
62
+ await writeFile(absPath, stripped.trimEnd() + '\n\n' + injectedBlock + '\n', 'utf-8');
63
+ written++;
64
+ }
65
+ else if (content !== stripped) {
66
+ await writeFile(absPath, stripped, 'utf-8');
67
+ removed++;
68
+ }
69
+ }
70
+ const individualFiles = generateInjectedIndividualFiles(config.targets, injections);
71
+ for (const file of individualFiles) {
72
+ const absPath = path.join(ctx.projectRoot, file.relativePath);
73
+ await mkdir(path.dirname(absPath), { recursive: true });
74
+ await writeFile(absPath, file.content, 'utf-8');
75
+ written++;
76
+ }
77
+ // 删除历史注入独立文件(不在当前注入列表中的旧文件)
78
+ const storeState = (ctx.store.getState()['ai-rules'] ?? {});
79
+ const prevInjectedPaths = new Set(Object.keys(storeState.lastInjectedHash ?? {}));
80
+ const currentInjectedPaths = new Set(individualFiles.map((f) => f.relativePath));
81
+ for (const staleRelPath of prevInjectedPaths) {
82
+ if (currentInjectedPaths.has(staleRelPath))
83
+ continue;
84
+ const absPath = path.join(ctx.projectRoot, staleRelPath);
85
+ if (!existsSync(absPath))
86
+ continue;
87
+ try {
88
+ await unlink(absPath);
89
+ removed++;
90
+ }
91
+ catch {
92
+ // 删除失败时静默跳过
93
+ }
94
+ }
95
+ const injectedHashes = {};
96
+ for (const file of individualFiles) {
97
+ injectedHashes[file.relativePath] = computeHash(file.content);
98
+ }
99
+ ctx.store.setPluginState('ai-rules', { ...storeState, lastInjectedHash: injectedHashes });
100
+ return { written, removed };
101
+ }
102
+ // ─── Helpers ──────
103
+ function buildInjectedBlock(injections) {
104
+ const sections = [];
105
+ for (const [source, items] of injections) {
106
+ if (items.length === 0)
107
+ continue;
108
+ const itemsContent = items.map((item) => `## ${item.name}\n\n${item.content}`).join('\n\n---\n\n');
109
+ sections.push([INJECTED_SOURCE_BEGIN(source), '', itemsContent, '', INJECTED_SOURCE_END(source)].join('\n'));
110
+ }
111
+ if (sections.length === 0)
112
+ return '';
113
+ return [INJECTED_BEGIN, '', ...sections, '', INJECTED_END].join('\n');
114
+ }
115
+ function collectMergeFilePaths(targetIds) {
116
+ const paths = new Set();
117
+ for (const targetId of targetIds) {
118
+ const target = getTarget(targetId);
119
+ if (!target)
120
+ continue;
121
+ for (const slot of getTargetSlots(target)) {
122
+ if (slot.strategy === OutputStrategy.MergeFile || slot.strategy === OutputStrategy.MarkedSection) {
123
+ paths.add(slot.pathTemplate);
124
+ }
125
+ }
126
+ }
127
+ return paths;
128
+ }
129
+ function generateInjectedIndividualFiles(targetIds, injections) {
130
+ const allItems = [...injections.values()].flat();
131
+ if (allItems.length === 0)
132
+ return [];
133
+ const files = [];
134
+ for (const targetId of targetIds) {
135
+ const target = getTarget(targetId);
136
+ if (!target)
137
+ continue;
138
+ for (const item of allItems) {
139
+ const slot = resolveSlotForItem(target, item);
140
+ if (slot.strategy !== OutputStrategy.IndividualFile)
141
+ continue;
142
+ const filePath = slot.pathTemplate.replace('{id}', item.id);
143
+ files.push({ relativePath: filePath, content: formatOutputFile(filePath, item) });
144
+ }
145
+ }
146
+ return files;
147
+ }
148
+ export function spliceMarkerBlock(content, beginMarker, endMarker, replacement) {
149
+ const beginIdx = content.indexOf(beginMarker);
150
+ const endIdx = content.indexOf(endMarker);
151
+ const found = beginIdx !== -1 && endIdx !== -1;
152
+ if (!found) {
153
+ if (replacement === undefined)
154
+ return content;
155
+ const sep = content.endsWith('\n') ? '\n' : '\n\n';
156
+ return content + sep + replacement + '\n';
157
+ }
158
+ const before = content.slice(0, beginIdx);
159
+ const after = content.slice(endIdx + endMarker.length);
160
+ if (replacement === undefined) {
161
+ const trimBefore = before.trimEnd();
162
+ const trimAfter = after.trimStart();
163
+ if (!trimAfter)
164
+ return trimBefore ? trimBefore + '\n' : '';
165
+ return trimBefore + '\n\n' + trimAfter;
166
+ }
167
+ return before + replacement + after;
168
+ }
169
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../src/injection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - MCP 配置写入
3
+ *
4
+ * 将 MCP 服务器配置写入各 IDE 的 MCP 配置文件
5
+ * 支持 VS Code (.vscode/mcp.json)、Cursor (.cursor/mcp.json)、Claude Code (.mcp.json)
6
+ *
7
+ * xfe 管理的 server key 使用 `xfe--` 前缀,与用户手动配置隔离
8
+ */
9
+ import type { PluginContext } from '@xfe-repo/cli-core';
10
+ import type { AiConfig, McpApplyResult, McpInjectionRegistry, McpServerEntry } from './types.js';
11
+ /**
12
+ * 将静态 + 动态 MCP 服务器配置写入各 IDE 的 MCP 配置文件
13
+ *
14
+ * - 静态条目:源仓库 mcp.json 中用户选中的 servers
15
+ * - 动态注入:其他插件通过 mcpInjections 注册的 servers(如 xfe-cli-mcp)
16
+ * - 保留用户手动添加的 servers(无 xfe-- 前缀的 key)
17
+ */
18
+ export declare function applyMcpConfigs(ctx: PluginContext, config: AiConfig, staticEntries: McpServerEntry[], mcpInjections: McpInjectionRegistry): Promise<McpApplyResult>;
19
+ /**
20
+ * 清理所有 IDE MCP 配置文件中 xfe 管理的条目
21
+ */
22
+ export declare function cleanMcpConfigs(ctx: PluginContext, config: AiConfig): Promise<McpApplyResult>;
23
+ //# sourceMappingURL=mcp-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-writer.d.ts","sourceRoot":"","sources":["../src/mcp-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAUhG;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,QAAQ,EAChB,aAAa,EAAE,cAAc,EAAE,EAC/B,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAYnG"}