@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
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 远程仓库扫描
3
+ *
4
+ * 扫描 rules/ agents/ skills/ 目录下的 MD 文件和 mcp.json,
5
+ * 从 YAML frontmatter 中读取元数据
6
+ */
7
+ import { readdir, readFile, stat } from 'node:fs/promises';
8
+ import { existsSync } from 'node:fs';
9
+ import path from 'node:path';
10
+ import matter from 'gray-matter';
11
+ import { SyncItemType } from './types.js';
12
+ // ─── Constants ──────
13
+ const DIR_TYPE_MAP = {
14
+ rules: SyncItemType.Rule,
15
+ agents: SyncItemType.Agent,
16
+ };
17
+ // ─── Public ──────
18
+ /** 扫描缓存目录,返回所有可用条目(MD 文件 + MCP servers) */
19
+ export async function scanRemoteEntries(cachePath) {
20
+ const entries = [];
21
+ for (const [dir, type] of Object.entries(DIR_TYPE_MAP)) {
22
+ const dirPath = path.join(cachePath, dir);
23
+ if (!existsSync(dirPath))
24
+ continue;
25
+ const files = (await readdir(dirPath)).filter((f) => f.endsWith('.md'));
26
+ for (const file of files) {
27
+ const raw = await readFile(path.join(dirPath, file), 'utf-8');
28
+ const { data } = matter(raw);
29
+ const id = path.basename(file, '.md');
30
+ entries.push({
31
+ type,
32
+ id,
33
+ name: data.name || id,
34
+ description: data.description || '',
35
+ appliesTo: Array.isArray(data.appliesTo) ? data.appliesTo : [],
36
+ sourcePath: `${dir}/${file}`,
37
+ });
38
+ }
39
+ }
40
+ // MCP servers
41
+ const mcpServers = await readMcpJson(cachePath);
42
+ for (const [id, config] of Object.entries(mcpServers)) {
43
+ const metadata = (config['x-metadata'] ?? {});
44
+ entries.push({
45
+ type: SyncItemType.McpServer,
46
+ id,
47
+ name: metadata.name ?? id,
48
+ description: metadata.description ?? '',
49
+ sourcePath: 'mcp.json',
50
+ });
51
+ }
52
+ // Skills 目录
53
+ entries.push(...(await scanSkillDirs(cachePath)));
54
+ return entries;
55
+ }
56
+ /** 根据选中 ID 列表加载内容,返回可写入的 SyncItem */
57
+ export async function loadSelectedItems(cachePath, entries, selectedIds, config) {
58
+ const subagentIds = new Set(config?.subagents ?? []);
59
+ const items = [];
60
+ let mcpServers;
61
+ for (const entry of entries) {
62
+ if (!selectedIds.has(entry.id))
63
+ continue;
64
+ if (entry.type === SyncItemType.McpServer) {
65
+ mcpServers ??= await readMcpJson(cachePath);
66
+ const serverConfig = mcpServers[entry.id];
67
+ if (!serverConfig)
68
+ continue;
69
+ const { 'x-metadata': _, ...cleanConfig } = serverConfig;
70
+ items.push({ type: SyncItemType.McpServer, id: entry.id, name: entry.name, content: '', serverConfig: cleanConfig });
71
+ continue;
72
+ }
73
+ if (entry.type === SyncItemType.Skill) {
74
+ items.push({ type: SyncItemType.Skill, id: entry.id, name: entry.name, sourcePath: path.join(cachePath, entry.sourcePath) });
75
+ continue;
76
+ }
77
+ const raw = await readFile(path.join(cachePath, entry.sourcePath), 'utf-8');
78
+ const { content } = matter(raw);
79
+ const type = entry.type === SyncItemType.Agent && subagentIds.has(entry.id) ? SyncItemType.Subagent : entry.type;
80
+ items.push({ type, id: entry.id, name: entry.name, content: content.trim() });
81
+ }
82
+ return items;
83
+ }
84
+ // ─── Helpers ──────
85
+ async function scanSkillDirs(cachePath) {
86
+ const skillsDir = path.join(cachePath, 'skills');
87
+ if (!existsSync(skillsDir))
88
+ return [];
89
+ const entries = [];
90
+ const children = await readdir(skillsDir);
91
+ for (const name of children) {
92
+ const childPath = path.join(skillsDir, name);
93
+ const childStat = await stat(childPath);
94
+ if (!childStat.isDirectory())
95
+ continue;
96
+ const skillMd = path.join(childPath, 'SKILL.md');
97
+ if (!existsSync(skillMd))
98
+ continue;
99
+ const raw = await readFile(skillMd, 'utf-8');
100
+ const { data } = matter(raw);
101
+ entries.push({
102
+ type: SyncItemType.Skill,
103
+ id: name,
104
+ name: data.name || name,
105
+ description: data.description || '',
106
+ sourcePath: `skills/${name}`,
107
+ });
108
+ }
109
+ return entries;
110
+ }
111
+ async function readMcpJson(cachePath) {
112
+ const mcpJsonPath = path.join(cachePath, 'mcp.json');
113
+ if (!existsSync(mcpJsonPath))
114
+ return {};
115
+ const raw = await readFile(mcpJsonPath, 'utf-8');
116
+ const parsed = JSON.parse(raw);
117
+ return parsed.mcpServers ?? {};
118
+ }
119
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 同步引擎
3
+ *
4
+ * 基于 TargetConfig 注册表驱动,将选中的 rules/agents/skills
5
+ * 写入各 IDE 目标目录。支持标记段落合并、冲突检测
6
+ */
7
+ import type { PluginContext } from '@xfe-repo/cli-core';
8
+ import type { AiConfig, InjectionRegistry, SyncItem } from './types.js';
9
+ export interface SyncResult {
10
+ written: number;
11
+ skipped: number;
12
+ fileHashes: Record<string, string>;
13
+ injectedHashes: Record<string, string>;
14
+ }
15
+ /**
16
+ * 执行完整同步流程: 按 target 生成输出 → 去重合并 → 冲突检测 → 写入 → .gitignore
17
+ *
18
+ * injections 为可选的动态注入注册表,sync 时自动合并到输出文件,
19
+ * 注入段落用标记包裹,hash 对比前自动剔除
20
+ */
21
+ export declare function syncRules(ctx: PluginContext, config: AiConfig, items: SyncItem[], injections?: InjectionRegistry): Promise<SyncResult>;
22
+ /**
23
+ * 检查同步状态:git 最新 && target 文件与上次同步哈希一致
24
+ */
25
+ export declare function checkSyncStatus(ctx: PluginContext, config: AiConfig): Promise<boolean>;
26
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGvD,OAAO,KAAK,EAAE,QAAQ,EAAqB,iBAAiB,EAAc,QAAQ,EAAE,MAAM,YAAY,CAAA;AAWtG,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACvC;AAID;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,QAAQ,EAChB,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,CAAC,EAAE,iBAAiB,GAC7B,OAAO,CAAC,UAAU,CAAC,CA0CrB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B5F"}
package/dist/sync.js ADDED
@@ -0,0 +1,172 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 同步引擎
3
+ *
4
+ * 基于 TargetConfig 注册表驱动,将选中的 rules/agents/skills
5
+ * 写入各 IDE 目标目录。支持标记段落合并、冲突检测
6
+ */
7
+ import { existsSync, readFileSync as fsReadFileSync } from 'node:fs';
8
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
9
+ import path from 'node:path';
10
+ import { SyncItemType } from './types.js';
11
+ import { getTarget, OutputStrategy, formatOutputFile } from './targets.js';
12
+ import { mergeMarkedSections } from './merge.js';
13
+ import { getCachePath, hasCachedRepo } from './repo-cache.js';
14
+ import { updateGitignore } from './gitignore.js';
15
+ import { stripInjectedSections, computeHash, appendInjectionsToOutputFiles } from './injection.js';
16
+ // ─── Public ──────
17
+ /**
18
+ * 执行完整同步流程: 按 target 生成输出 → 去重合并 → 冲突检测 → 写入 → .gitignore
19
+ *
20
+ * injections 为可选的动态注入注册表,sync 时自动合并到输出文件,
21
+ * 注入段落用标记包裹,hash 对比前自动剔除
22
+ */
23
+ export async function syncRules(ctx, config, items, injections) {
24
+ const { targets } = config;
25
+ const outputFiles = generateAllOutputFiles(ctx, targets, items);
26
+ const storeState = (ctx.store.getState()['ai-rules'] ?? {});
27
+ const lastHashes = storeState.lastSyncHash ?? {};
28
+ const injectedIndividualFiles = appendInjectionsToOutputFiles(outputFiles, targets, injections);
29
+ let written = 0;
30
+ let skipped = 0;
31
+ const fileHashes = {};
32
+ const injectedHashes = {};
33
+ for (const file of outputFiles) {
34
+ const absPath = path.join(ctx.projectRoot, file.relativePath);
35
+ const remoteHash = computeHash(stripInjectedSections(file.content));
36
+ const shouldWrite = await resolveConflict(ctx, absPath, file.relativePath, lastHashes);
37
+ if (!shouldWrite) {
38
+ skipped++;
39
+ fileHashes[file.relativePath] = lastHashes[file.relativePath] ?? remoteHash;
40
+ continue;
41
+ }
42
+ await mkdir(path.dirname(absPath), { recursive: true });
43
+ await writeFile(absPath, file.content, 'utf-8');
44
+ fileHashes[file.relativePath] = remoteHash;
45
+ written++;
46
+ }
47
+ for (const file of injectedIndividualFiles) {
48
+ const absPath = path.join(ctx.projectRoot, file.relativePath);
49
+ await mkdir(path.dirname(absPath), { recursive: true });
50
+ await writeFile(absPath, file.content, 'utf-8');
51
+ injectedHashes[file.relativePath] = computeHash(file.content);
52
+ written++;
53
+ }
54
+ await updateGitignore(ctx.projectRoot, collectGitignoreEntries(targets));
55
+ return { written, skipped, fileHashes, injectedHashes };
56
+ }
57
+ /**
58
+ * 检查同步状态:git 最新 && target 文件与上次同步哈希一致
59
+ */
60
+ export async function checkSyncStatus(ctx, config) {
61
+ const storeState = (ctx.store.getState()['ai-rules'] ?? {});
62
+ if (!storeState.lastSyncTime)
63
+ return false;
64
+ if (!hasCachedRepo(config.source))
65
+ return false;
66
+ const git = ctx.inject('git');
67
+ const cachePath = getCachePath(config.source);
68
+ await git.pull(ctx, { cwd: cachePath });
69
+ if ((await git.latestHash({ cwd: cachePath })) !== storeState.lastRemoteHash)
70
+ return false;
71
+ const lastHashes = storeState.lastSyncHash ?? {};
72
+ for (const [relativePath, expectedHash] of Object.entries(lastHashes)) {
73
+ const absPath = path.join(ctx.projectRoot, relativePath);
74
+ if (!existsSync(absPath))
75
+ return false;
76
+ const content = await readFile(absPath, 'utf-8');
77
+ if (computeHash(stripInjectedSections(content)) !== expectedHash)
78
+ return false;
79
+ }
80
+ return true;
81
+ }
82
+ // ─── 输出文件生成 ──────
83
+ function generateAllOutputFiles(ctx, targetIds, items) {
84
+ const fileMap = new Map();
85
+ const markedSectionMap = new Map();
86
+ const agents = items.filter((i) => i.type === SyncItemType.Agent);
87
+ const rules = items.filter((i) => i.type === SyncItemType.Rule);
88
+ const subagents = items.filter((i) => i.type === SyncItemType.Subagent);
89
+ const skills = items.filter((i) => i.type === SyncItemType.Skill);
90
+ for (const targetId of targetIds) {
91
+ const target = getTarget(targetId);
92
+ if (!target)
93
+ continue;
94
+ generateSlotOutputs(target.agent, agents, fileMap, markedSectionMap);
95
+ generateSlotOutputs(target.rules, rules, fileMap, markedSectionMap);
96
+ generateSlotOutputs(target.subagents, subagents, fileMap, markedSectionMap);
97
+ generateSlotOutputs(target.skills, skills, fileMap, markedSectionMap);
98
+ }
99
+ resolveMarkedSections(ctx.projectRoot, markedSectionMap, fileMap);
100
+ return [...fileMap.values()];
101
+ }
102
+ function generateSlotOutputs(slot, items, fileMap, markedSectionMap) {
103
+ if (items.length === 0)
104
+ return;
105
+ switch (slot.strategy) {
106
+ case OutputStrategy.MergeFile: {
107
+ const content = items.map((r) => `# ${r.name}\n\n${r.content}`).join('\n\n---\n\n');
108
+ const existing = fileMap.get(slot.pathTemplate);
109
+ if (existing) {
110
+ existing.content = existing.content.trimEnd() + '\n\n---\n\n' + content + '\n';
111
+ }
112
+ else {
113
+ fileMap.set(slot.pathTemplate, {
114
+ relativePath: slot.pathTemplate,
115
+ content: '<!-- Auto-generated by xfe rules sync — do not edit manually -->\n\n' + content + '\n',
116
+ });
117
+ }
118
+ break;
119
+ }
120
+ case OutputStrategy.IndividualFile: {
121
+ for (const item of items) {
122
+ const filePath = slot.pathTemplate.replace('{id}', item.id);
123
+ fileMap.set(filePath, { relativePath: filePath, content: formatOutputFile(filePath, item) });
124
+ }
125
+ break;
126
+ }
127
+ case OutputStrategy.MarkedSection: {
128
+ const existing = markedSectionMap.get(slot.pathTemplate) ?? [];
129
+ const existingIds = new Set(existing.map((i) => i.id));
130
+ markedSectionMap.set(slot.pathTemplate, [...existing, ...items.filter((i) => !existingIds.has(i.id))]);
131
+ break;
132
+ }
133
+ }
134
+ }
135
+ function resolveMarkedSections(projectRoot, markedSectionMap, fileMap) {
136
+ for (const [filePath, items] of markedSectionMap) {
137
+ const absPath = path.join(projectRoot, filePath);
138
+ const existingContent = existsSync(absPath) ? fsReadFileSync(absPath, 'utf-8') : '';
139
+ fileMap.set(filePath, { relativePath: filePath, content: mergeMarkedSections(existingContent, items) });
140
+ }
141
+ }
142
+ // ─── .gitignore 条目收集 ──────
143
+ function collectGitignoreEntries(targetIds) {
144
+ const entries = new Set();
145
+ for (const id of targetIds) {
146
+ const target = getTarget(id);
147
+ if (!target)
148
+ continue;
149
+ target.gitignoreEntries.forEach((e) => entries.add(e));
150
+ }
151
+ return [...entries];
152
+ }
153
+ // ─── 冲突检测 ──────
154
+ async function resolveConflict(ctx, absPath, relativePath, lastHashes) {
155
+ if (!existsSync(absPath))
156
+ return true;
157
+ const localHash = computeHash(stripInjectedSections(await readFile(absPath, 'utf-8')));
158
+ const knownHash = lastHashes[relativePath];
159
+ if (knownHash && localHash === knownHash)
160
+ return true;
161
+ const { conflictAction } = await ctx.prompt.ask({
162
+ type: 'list',
163
+ name: 'conflictAction',
164
+ message: `文件 ${relativePath} 已被本地修改,如何处理?`,
165
+ choices: [
166
+ { name: '覆盖(使用远程版本)', value: 'overwrite' },
167
+ { name: '跳过(保留本地版本)', value: 'skip' },
168
+ ],
169
+ });
170
+ return conflictAction === 'overwrite';
171
+ }
172
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - Target 注册表
3
+ *
4
+ * 内置 IDE target 配置:输出路径、命名规则
5
+ * 路径模板中包含 {id} 的为独立文件,否则为合并文件
6
+ */
7
+ import { SyncItemType, SyncTarget } from './types.js';
8
+ import type { SyncEntry } from './types.js';
9
+ export interface TargetConfig {
10
+ id: SyncTarget;
11
+ name: string;
12
+ agent: string;
13
+ rules: string;
14
+ subagents: string;
15
+ skills: string;
16
+ mcp?: string;
17
+ mcpRootKey?: string;
18
+ gitignoreEntries: string[];
19
+ }
20
+ export declare function getTarget(id: string): TargetConfig | undefined;
21
+ export declare function getTargetChoices(): Array<{
22
+ name: string;
23
+ value: string;
24
+ }>;
25
+ export declare function isIndividualSlot(pathTemplate: string): boolean;
26
+ export declare function resolvePathTemplate(target: TargetConfig, itemType: SyncItemType): string;
27
+ export declare function formatOutputFile(filePath: string, item: SyncEntry): string;
28
+ //# sourceMappingURL=targets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAI3C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,UAAU,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B;AAsDD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE9D;AAED,wBAAgB,gBAAgB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAE9D;AAUD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAExF;AAeD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAM1E"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - Target 注册表
3
+ *
4
+ * 内置 IDE target 配置:输出路径、命名规则
5
+ * 路径模板中包含 {id} 的为独立文件,否则为合并文件
6
+ */
7
+ import { SyncItemType, SyncTarget } from './types.js';
8
+ // ─── Target 注册表 ──────
9
+ const TARGET_REGISTRY = {
10
+ [SyncTarget.Copilot]: {
11
+ id: SyncTarget.Copilot,
12
+ name: 'GitHub Copilot',
13
+ agent: 'AGENTS.md',
14
+ rules: 'AGENTS.md',
15
+ subagents: '.github/agents/{id}.md',
16
+ skills: '.github/skills/{id}/SKILL.md',
17
+ mcp: '.vscode/mcp.json',
18
+ mcpRootKey: 'servers',
19
+ gitignoreEntries: ['AGENTS.md', '.github/', '.vscode/'],
20
+ },
21
+ [SyncTarget.Cursor]: {
22
+ id: SyncTarget.Cursor,
23
+ name: 'Cursor',
24
+ agent: 'AGENTS.md',
25
+ rules: 'AGENTS.md',
26
+ subagents: '.cursor/agents/{id}.md',
27
+ skills: '.cursor/skills/{id}/SKILL.md',
28
+ mcp: '.cursor/mcp.json',
29
+ mcpRootKey: 'mcpServers',
30
+ gitignoreEntries: ['AGENTS.md', '.cursor/'],
31
+ },
32
+ [SyncTarget.ClaudeCode]: {
33
+ id: SyncTarget.ClaudeCode,
34
+ name: 'Claude Code',
35
+ agent: 'CLAUDE.md',
36
+ rules: 'CLAUDE.md',
37
+ subagents: '.claude/agents/{id}.md',
38
+ skills: '.claude/skills/{id}/SKILL.md',
39
+ mcp: '.claude/mcp.json',
40
+ mcpRootKey: 'mcpServers',
41
+ gitignoreEntries: ['CLAUDE.md', '.claude/'],
42
+ },
43
+ [SyncTarget.Codex]: {
44
+ id: SyncTarget.Codex,
45
+ name: 'OpenAI Codex',
46
+ agent: 'AGENTS.md',
47
+ rules: 'AGENTS.md',
48
+ subagents: '.codex/agents/{id}.md',
49
+ skills: '.codex/skills/{id}/SKILL.md',
50
+ gitignoreEntries: ['AGENTS.md', '.codex/'],
51
+ },
52
+ };
53
+ // ─── Public ──────
54
+ export function getTarget(id) {
55
+ return TARGET_REGISTRY[id];
56
+ }
57
+ export function getTargetChoices() {
58
+ return Object.values(TARGET_REGISTRY).map((t) => ({ name: t.name, value: t.id }));
59
+ }
60
+ export function isIndividualSlot(pathTemplate) {
61
+ return pathTemplate.includes('{id}');
62
+ }
63
+ const PATH_TEMPLATE_KEY = {
64
+ [SyncItemType.Agent]: 'agent',
65
+ [SyncItemType.Rule]: 'rules',
66
+ [SyncItemType.Subagent]: 'subagents',
67
+ [SyncItemType.Skill]: 'skills',
68
+ [SyncItemType.McpServer]: 'mcp',
69
+ };
70
+ export function resolvePathTemplate(target, itemType) {
71
+ return target[PATH_TEMPLATE_KEY[itemType]] ?? '';
72
+ }
73
+ // ─── 文件格式化 ──────
74
+ const FORMATTER_MAP = {
75
+ '.mdc': (item) => {
76
+ const alwaysApply = item.type === SyncItemType.Rule;
77
+ return ['---', `description: ${item.name}`, `alwaysApply: ${alwaysApply}`, '---', '', item.content, ''].join('\n');
78
+ },
79
+ '.instructions.md': (item) => {
80
+ return ['---', `applyTo: "**"`, '---', '', item.content, ''].join('\n');
81
+ },
82
+ };
83
+ export function formatOutputFile(filePath, item) {
84
+ for (const [ext, formatter] of Object.entries(FORMATTER_MAP)) {
85
+ if (filePath.endsWith(ext))
86
+ return formatter(item);
87
+ }
88
+ return item.content + '\n';
89
+ }
90
+ //# sourceMappingURL=targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"targets.js","sourceRoot":"","sources":["../src/targets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 类型定义
3
+ *
4
+ * AI 声明式配置 schema、管道中间产物、同步状态等核心类型
5
+ */
6
+ import type { PluginContext } from '@xfe-repo/cli-core';
7
+ import { z } from 'zod';
8
+ export declare const aiConfigSchema: z.ZodObject<{
9
+ source: z.ZodString;
10
+ branch: z.ZodDefault<z.ZodString>;
11
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
12
+ agent: z.ZodOptional<z.ZodString>;
13
+ subagents: z.ZodDefault<z.ZodArray<z.ZodString>>;
14
+ rules: z.ZodDefault<z.ZodArray<z.ZodString>>;
15
+ mcpServers: z.ZodDefault<z.ZodArray<z.ZodString>>;
16
+ targets: z.ZodDefault<z.ZodArray<z.ZodString>>;
17
+ }, z.core.$strip>;
18
+ export type AiConfig = z.infer<typeof aiConfigSchema>;
19
+ export declare enum SyncTarget {
20
+ Copilot = "copilot",
21
+ Codex = "codex",
22
+ Cursor = "cursor",
23
+ ClaudeCode = "claude-code"
24
+ }
25
+ export declare const rulesTargetsParameters: z.ZodObject<{
26
+ targets: z.ZodOptional<z.ZodArray<z.ZodEnum<typeof SyncTarget>>>;
27
+ }, z.core.$strip>;
28
+ export declare const rulesAddParameters: z.ZodObject<{
29
+ selectedIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ primaryAgent: z.ZodOptional<z.ZodString>;
31
+ sync: z.ZodOptional<z.ZodBoolean>;
32
+ }, z.core.$strip>;
33
+ export declare const rulesSyncParameters: z.ZodObject<{
34
+ conflictAction: z.ZodOptional<z.ZodEnum<{
35
+ overwrite: "overwrite";
36
+ skip: "skip";
37
+ }>>;
38
+ }, z.core.$strip>;
39
+ export type RulesTargetsParameters = z.infer<typeof rulesTargetsParameters>;
40
+ export type RulesAddParameters = z.infer<typeof rulesAddParameters>;
41
+ export type RulesSyncParameters = z.infer<typeof rulesSyncParameters>;
42
+ export declare enum SyncItemType {
43
+ Rule = "rule",
44
+ Agent = "agent",
45
+ Subagent = "subagent",
46
+ Skill = "skill",
47
+ McpServer = "mcp-server"
48
+ }
49
+ /** 统一的同步条目:扫描阶段为元数据,加载后补充 content */
50
+ export interface SyncEntry {
51
+ type: SyncItemType;
52
+ id: string;
53
+ name: string;
54
+ description?: string;
55
+ appliesTo?: string[];
56
+ /** 相对于缓存根目录的文件路径(扫描阶段填充) */
57
+ sourcePath?: string;
58
+ /** 文件内容(加载后填充) */
59
+ content?: string;
60
+ /** MCP server 原始配置对象(仅 McpServer 类型使用) */
61
+ serverConfig?: Record<string, unknown>;
62
+ }
63
+ export type FileFormat = 'markdown' | 'mcp-json';
64
+ /** 计划写入的 skill 目录 */
65
+ export interface SkillDirPlan {
66
+ id: string;
67
+ sourceDir: string;
68
+ targetDir: string;
69
+ source: 'sync' | 'injection';
70
+ }
71
+ /** 计划写入的文件 */
72
+ export interface PlannedFile {
73
+ relativePath: string;
74
+ content: string;
75
+ action: 'write' | 'skip' | 'conflict';
76
+ /** 区分远端同步项 vs 动态注入项,hash 分开追踪 */
77
+ source: 'sync' | 'injection';
78
+ format: FileFormat;
79
+ }
80
+ /** 同步计划 */
81
+ export interface SyncPlan {
82
+ files: PlannedFile[];
83
+ skillDirs: SkillDirPlan[];
84
+ gitignoreEntries: string[];
85
+ }
86
+ /** 同步执行结果 */
87
+ export interface SyncResult {
88
+ written: number;
89
+ skipped: number;
90
+ fileHashes: Record<string, string>;
91
+ injectedHashes: Record<string, string>;
92
+ skillDirPaths: string[];
93
+ }
94
+ export type InjectionRegistry = Map<string, SyncEntry[]>;
95
+ export interface ApplyResult {
96
+ written: number;
97
+ removed: number;
98
+ }
99
+ export interface AiRulesCapability {
100
+ injectRules(source: string, items: SyncEntry[]): void;
101
+ removeInjectedRules(source: string): void;
102
+ applyInjections(ctx: PluginContext): Promise<ApplyResult>;
103
+ }
104
+ export interface AiRulesStoreState {
105
+ lastSyncHash: Record<string, string>;
106
+ lastRemoteHash: string;
107
+ lastSyncTime: number;
108
+ synced?: boolean;
109
+ lastInjectedHash?: Record<string, string>;
110
+ lastSkillDirs?: string[];
111
+ }
112
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @xfe-repo/cli-plugin-ai-rules - 类型定义
3
+ *
4
+ * AI 声明式配置 schema、管道中间产物、同步状态等核心类型
5
+ */
6
+ import { z } from 'zod';
7
+ // ─── AI 配置 Schema(xfe.json 中的 ai 字段) ──────
8
+ export const aiConfigSchema = z.object({
9
+ source: z.string(),
10
+ branch: z.string().default('main'),
11
+ skills: z.array(z.string()).default([]),
12
+ agent: z.string().optional(),
13
+ subagents: z.array(z.string()).default([]),
14
+ rules: z.array(z.string()).default([]),
15
+ mcpServers: z.array(z.string()).default([]),
16
+ targets: z.array(z.string()).default([]),
17
+ });
18
+ // ─── 同步目标 ──────
19
+ export var SyncTarget;
20
+ (function (SyncTarget) {
21
+ SyncTarget["Copilot"] = "copilot";
22
+ SyncTarget["Codex"] = "codex";
23
+ SyncTarget["Cursor"] = "cursor";
24
+ SyncTarget["ClaudeCode"] = "claude-code";
25
+ })(SyncTarget || (SyncTarget = {}));
26
+ const syncTargetSchema = z.enum(SyncTarget);
27
+ export const rulesTargetsParameters = z.object({
28
+ targets: z.array(syncTargetSchema).optional().describe('需要同步注入的 IDE 目标 ID,可选值: copilot、codex、cursor、claude-code'),
29
+ });
30
+ export const rulesAddParameters = z.object({
31
+ selectedIds: z
32
+ .array(z.string())
33
+ .optional()
34
+ .describe('需要写入 aiRules 的远程条目 ID 列表,可混合 agent、rule、skill;MCP 调用时应直接传入'),
35
+ primaryAgent: z.string().optional().describe('当 selectedIds 中包含多个 agent 时,指定主 Agent ID;其余 agent 会写入 subagents'),
36
+ sync: z.boolean().optional().describe('写入配置后立即执行同步'),
37
+ });
38
+ export const rulesSyncParameters = z.object({
39
+ conflictAction: z
40
+ .enum(['overwrite', 'skip'])
41
+ .optional()
42
+ .describe('当目标文件已存在且与上次同步结果不一致时的处理策略:overwrite 覆盖本地,skip 保留本地'),
43
+ });
44
+ // ─── 同步条目 ──────
45
+ export var SyncItemType;
46
+ (function (SyncItemType) {
47
+ SyncItemType["Rule"] = "rule";
48
+ SyncItemType["Agent"] = "agent";
49
+ SyncItemType["Subagent"] = "subagent";
50
+ SyncItemType["Skill"] = "skill";
51
+ SyncItemType["McpServer"] = "mcp-server";
52
+ })(SyncItemType || (SyncItemType = {}));
53
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,6CAA6C;AAE7C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACzC,CAAC,CAAA;AAIF,kBAAkB;AAElB,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,6BAAe,CAAA;IACf,+BAAiB,CAAA;IACjB,wCAA0B,CAAA;AAC5B,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB;AAED,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;AAE3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;CAClH,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE,CAAC;SACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,4DAA4D,CAAC;IACzE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC;IAC/G,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC;CACrD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,cAAc,EAAE,CAAC;SACd,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;SAC3B,QAAQ,EAAE;SACV,QAAQ,CAAC,oDAAoD,CAAC;CAClE,CAAC,CAAA;AAMF,kBAAkB;AAElB,MAAM,CAAN,IAAY,YAMX;AAND,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,+BAAe,CAAA;IACf,qCAAqB,CAAA;IACrB,+BAAe,CAAA;IACf,wCAAwB,CAAA;AAC1B,CAAC,EANW,YAAY,KAAZ,YAAY,QAMvB"}