zixulu 1.80.7 → 1.80.8

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/dist/index.js CHANGED
@@ -4788,26 +4788,22 @@ async function sortPackageJson() {
4788
4788
  });
4789
4789
  consola.success("排序 package.json 中的依赖成功");
4790
4790
  }
4791
- const AgentRulesSyncTarget = {
4792
- agentsMd: "AGENTS.md",
4793
- cursor: "Cursor",
4794
- antiGravity: "AntiGravity"
4795
- };
4796
- const syncAgentRules_source = join(".cursor-rules");
4797
- const cursorRulesTarget = join(".cursor", "rules");
4798
- const antiGravityRulesTarget = join(".agent", "rules");
4791
+ const syncAgentRules_source = join(".agent-rules");
4792
+ const agentsMdTarget = "AGENTS.md";
4799
4793
  const orders = [
4800
- "base.mdc",
4801
- "react.mdc",
4802
- "api.mdc",
4803
- "next.mdc"
4794
+ "base.md",
4795
+ "style.md",
4796
+ "react.md",
4797
+ "api.md",
4798
+ "next.md"
4804
4799
  ];
4805
- function getDefaultSyncTargets() {
4806
- const targets = [];
4807
- if (existsSync("AGENTS.md")) targets.push(AgentRulesSyncTarget.agentsMd);
4808
- if (existsSync(".cursor")) targets.push(AgentRulesSyncTarget.cursor);
4809
- if (existsSync(".agent")) targets.push(AgentRulesSyncTarget.antiGravity);
4810
- return targets;
4800
+ async function pathExists(path) {
4801
+ try {
4802
+ await access(path);
4803
+ return true;
4804
+ } catch {
4805
+ return false;
4806
+ }
4811
4807
  }
4812
4808
  function sortAgentRuleFiles(files) {
4813
4809
  return files.toSorted((a, b)=>{
@@ -4819,72 +4815,70 @@ function sortAgentRuleFiles(files) {
4819
4815
  return aIndex - bIndex;
4820
4816
  });
4821
4817
  }
4822
- function transformCursorRuleToAntiGravityRule(source) {
4823
- return source.replace(/^---\nalwaysApply: (true|false)\n---/, (match, p1)=>`---
4824
- trigger: ${"true" === p1 ? "always_on" : "model_decision"}
4825
- glob:
4826
- description:
4827
- ---`);
4818
+ function normalizeMarkdownHeading(heading) {
4819
+ return heading.replace(/\s+#+$/, "").trim().toLocaleLowerCase();
4828
4820
  }
4829
- function transformCursorRuleToAgentsRule(source) {
4830
- return source.replace(/^---\nalwaysApply: (true|false)\n---/, "").replace(/^(#+ )/gm, "#$1");
4821
+ function getMarkdownHeadings(content, level) {
4822
+ const hashes = "#".repeat(level);
4823
+ const regexp = new RegExp(`^${hashes}(?!#)\\s+(.+?)\\s*$`, "gm");
4824
+ return Array.from(content.matchAll(regexp), ([, heading])=>heading.replace(/\s+#+$/, "").trim());
4831
4825
  }
4832
- async function getCursorRuleFileStatusMap(files) {
4833
- const map = {};
4834
- if (!existsSync(cursorRulesTarget)) return Object.fromEntries(files.map((file)=>[
4835
- file,
4836
- "new"
4837
- ]));
4838
- const targetDir = await readdir(cursorRulesTarget);
4839
- for (const file of files){
4840
- if (!targetDir.includes(file)) {
4841
- map[file] = "new";
4842
- continue;
4843
- }
4844
- const sourceContent = await readFile(join(syncAgentRules_source, file), "utf-8");
4845
- const targetContent = await readFile(join(cursorRulesTarget, file), "utf-8");
4846
- if (sourceContent !== targetContent) map[file] = "modified";
4826
+ function getMarkdownFirstHeading(content) {
4827
+ return getMarkdownHeadings(content, 1)[0] ?? "";
4828
+ }
4829
+ function transformMarkdownRuleToAgentsRule(source) {
4830
+ return source.replace(/^(#+ )/gm, "#$1").replace(/\n+$/, "");
4831
+ }
4832
+ async function getMarkdownRuleFilenames() {
4833
+ const entries = await readdir(syncAgentRules_source, {
4834
+ withFileTypes: true
4835
+ });
4836
+ return sortAgentRuleFiles(entries.filter((entry)=>entry.isFile()).map((entry)=>entry.name).filter((filename)=>filename.toLowerCase().endsWith(".md")));
4837
+ }
4838
+ async function readAgentRuleFiles(files) {
4839
+ const rules = [];
4840
+ for (const filename of files){
4841
+ const content = await readFile(join(syncAgentRules_source, filename), "utf-8");
4842
+ const title = getMarkdownFirstHeading(content) || filename;
4843
+ rules.push({
4844
+ filename,
4845
+ title,
4846
+ content
4847
+ });
4847
4848
  }
4848
- return map;
4849
+ return rules;
4850
+ }
4851
+ async function readOriginalAgentsMd() {
4852
+ if (!await pathExists(agentsMdTarget)) return;
4853
+ return await readFile(agentsMdTarget, "utf-8");
4849
4854
  }
4850
- async function syncCursorRules(files) {
4851
- const map = await getCursorRuleFileStatusMap(files);
4852
- const changedFiles = Object.keys(map);
4853
- if (0 === changedFiles.length) return;
4854
- const { files: selectedFiles } = await inquirer_0.prompt({
4855
+ function getDefaultAgentRuleFiles(params) {
4856
+ const { rules, originalContent } = params;
4857
+ if (!originalContent) return rules.map((rule)=>rule.filename);
4858
+ const originalSecondHeadings = new Set(getMarkdownHeadings(originalContent, 2).map(normalizeMarkdownHeading));
4859
+ return rules.filter((rule)=>originalSecondHeadings.has(normalizeMarkdownHeading(rule.title))).map((rule)=>rule.filename);
4860
+ }
4861
+ async function selectAgentRuleFiles(params) {
4862
+ const { rules, defaultFiles } = params;
4863
+ const { files } = await inquirer_0.prompt({
4855
4864
  type: "checkbox",
4856
4865
  name: "files",
4857
- message: "请选择要添加的 Cursor 规则文件",
4858
- choices: Object.entries(map).map(([key, value])=>({
4859
- name: `${key} (${value})`,
4860
- value: key
4866
+ message: "请选择要同步到 AGENTS.md 的规则",
4867
+ choices: rules.map((rule)=>({
4868
+ name: `${rule.title} (${rule.filename})`,
4869
+ value: rule.filename
4861
4870
  })),
4862
- default: changedFiles
4871
+ default: defaultFiles
4863
4872
  });
4864
- await mkdir(cursorRulesTarget, {
4865
- recursive: true
4866
- });
4867
- for (const file of selectedFiles)await copyFile(join(syncAgentRules_source, file), join(cursorRulesTarget, file));
4873
+ return files;
4868
4874
  }
4869
- async function syncAntiGravityRules(files) {
4870
- await mkdir(antiGravityRulesTarget, {
4871
- recursive: true
4872
- });
4873
- for (const file of files){
4874
- const sourceContent = await readFile(join(syncAgentRules_source, file), "utf-8");
4875
- const content = transformCursorRuleToAntiGravityRule(sourceContent);
4876
- await writeFile(join(antiGravityRulesTarget, file.replace(/\.mdc$/, ".md")), content);
4877
- }
4878
- }
4879
- async function syncAgentsMdRules(files) {
4880
- let agentsRule = "# Agent Rules";
4881
- for (const file of files){
4882
- const sourceContent = await readFile(join(syncAgentRules_source, file), "utf-8");
4883
- const content = transformCursorRuleToAgentsRule(sourceContent);
4884
- agentsRule = `${agentsRule}${content}`.replace(/\n+$/, "");
4885
- }
4886
- agentsRule = `${agentsRule}\n`;
4887
- await writeFile("AGENTS.md", agentsRule);
4875
+ async function syncAgentsMdRules(rules) {
4876
+ const sections = rules.map((rule)=>transformMarkdownRuleToAgentsRule(rule.content)).filter(Boolean);
4877
+ const agentsRule = `${[
4878
+ "# Agent Rules",
4879
+ ...sections
4880
+ ].join("\n\n").replace(/\n+$/, "")}\n`;
4881
+ await writeFile(agentsMdTarget, agentsRule);
4888
4882
  }
4889
4883
  async function asyncAgentRules() {
4890
4884
  try {
@@ -4893,33 +4887,33 @@ async function asyncAgentRules() {
4893
4887
  await writePackageJson({
4894
4888
  data: packageJson
4895
4889
  });
4896
- } catch (error) {}
4897
- await spawnAsync("npx gitpick 1adybug/cursor-rule/tree/main/.cursor/rules .cursor-rules");
4890
+ } catch {}
4891
+ await rm(syncAgentRules_source, {
4892
+ recursive: true,
4893
+ force: true
4894
+ });
4898
4895
  try {
4899
- const sourceDir = sortAgentRuleFiles(await readdir(syncAgentRules_source));
4900
- const defaultTargets = getDefaultSyncTargets();
4901
- const { targets } = await inquirer_0.prompt({
4902
- type: "checkbox",
4903
- name: "targets",
4904
- message: "请选择要同步的 Agent 规则",
4905
- choices: Object.values(AgentRulesSyncTarget),
4906
- default: defaultTargets
4896
+ await spawnAsync(`npx gitpick 1adybug/cursor-rule ${syncAgentRules_source}`);
4897
+ const sourceDir = await getMarkdownRuleFilenames();
4898
+ if (0 === sourceDir.length) throw new Error("未找到 Agent 规则文件");
4899
+ const rules = await readAgentRuleFiles(sourceDir);
4900
+ const originalAgentsMd = await readOriginalAgentsMd();
4901
+ const defaultFiles = getDefaultAgentRuleFiles({
4902
+ rules,
4903
+ originalContent: originalAgentsMd
4907
4904
  });
4908
- if (0 === targets.length) throw new Error("未选择同步目标");
4909
- if (targets.includes(AgentRulesSyncTarget.cursor)) await syncCursorRules(sourceDir);
4910
- if (targets.includes(AgentRulesSyncTarget.antiGravity)) await syncAntiGravityRules(sourceDir);
4911
- if (targets.includes(AgentRulesSyncTarget.agentsMd)) await syncAgentsMdRules(sourceDir);
4912
- await rm(syncAgentRules_source, {
4913
- recursive: true,
4914
- force: true
4905
+ const selectedFiles = await selectAgentRuleFiles({
4906
+ rules,
4907
+ defaultFiles
4915
4908
  });
4909
+ if (0 === selectedFiles.length) throw new Error("未选择 Agent 规则");
4910
+ await syncAgentsMdRules(rules.filter((rule)=>selectedFiles.includes(rule.filename)));
4916
4911
  return getCommitMessage("feature", "同步 Agent 规则");
4917
- } catch (error) {
4912
+ } finally{
4918
4913
  await rm(syncAgentRules_source, {
4919
4914
  recursive: true,
4920
4915
  force: true
4921
4916
  });
4922
- throw error;
4923
4917
  }
4924
4918
  }
4925
4919
  const EditorExtensionCommandMap = {
@@ -4928,7 +4922,7 @@ const EditorExtensionCommandMap = {
4928
4922
  Antigravity: "antigravity"
4929
4923
  };
4930
4924
  const editorExtensionCommandCache = new Map();
4931
- async function pathExists({ path }) {
4925
+ async function getEditorExtensions_pathExists({ path }) {
4932
4926
  try {
4933
4927
  await access(path);
4934
4928
  return true;
@@ -4994,7 +4988,7 @@ async function getEditorExtensionCommand({ editor }) {
4994
4988
  for (const candidate of getEditorWindowsCliCandidates({
4995
4989
  editor
4996
4990
  })){
4997
- if (!await pathExists({
4991
+ if (!await getEditorExtensions_pathExists({
4998
4992
  path: candidate
4999
4993
  })) continue;
5000
4994
  const command = quoteShellCommand({