zixulu 1.80.2 → 1.80.4
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 +182 -63
- package/dist/index.js.map +1 -1
- package/dist/src/utils/syncAgentRules.d.ts +31 -0
- package/package.json +1 -1
- package/src/utils/addTailwind.ts +21 -21
- package/src/utils/checkTailwind.ts +9 -9
- package/src/utils/checkType.ts +9 -9
- package/src/utils/clearDockerLog.ts +8 -8
- package/src/utils/download7Zip.ts +14 -14
- package/src/utils/downloadAnydesk.ts +14 -14
- package/src/utils/downloadChrome.ts +14 -14
- package/src/utils/downloadFirefox.ts +14 -14
- package/src/utils/downloadGit.ts +14 -14
- package/src/utils/downloadHoneyview.ts +9 -9
- package/src/utils/downloadNodeJS.ts +14 -14
- package/src/utils/downloadPeazip.ts +14 -14
- package/src/utils/downloadPotPlayer.ts +14 -14
- package/src/utils/downloadPowerToys.ts +14 -14
- package/src/utils/downloadVscode.ts +14 -14
- package/src/utils/getDependcy.ts +16 -16
- package/src/utils/getPackageUpgradeVersion.ts +43 -43
- package/src/utils/getPackageVersionFromRange.ts +8 -8
- package/src/utils/getRelativePath.ts +11 -11
- package/src/utils/hasChangeNoCommit.ts +6 -6
- package/src/utils/isAsset.ts +26 -26
- package/src/utils/isShellProxy.ts +12 -12
- package/src/utils/isStableVersion.ts +3 -3
- package/src/utils/isUrl.ts +5 -5
- package/src/utils/next.ts +12 -12
- package/src/utils/replaceCommitAuthor.ts +57 -57
- package/src/utils/setBun.ts +10 -10
- package/src/utils/setEnv.ts +24 -24
- package/src/utils/sleep.ts +3 -3
- package/src/utils/sortPackageJson.ts +16 -16
- package/src/utils/sudoCommand.ts +17 -17
- package/src/utils/syncAgentRules.ts +143 -63
- package/src/utils/syncVscode.ts +67 -5
- package/src/utils/unique.ts +3 -3
- package/src/utils/vite.ts +15 -15
package/dist/index.js
CHANGED
|
@@ -4788,6 +4788,104 @@ 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");
|
|
4799
|
+
const orders = [
|
|
4800
|
+
"base.mdc",
|
|
4801
|
+
"react.mdc",
|
|
4802
|
+
"api.mdc",
|
|
4803
|
+
"next.mdc"
|
|
4804
|
+
];
|
|
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;
|
|
4811
|
+
}
|
|
4812
|
+
function sortAgentRuleFiles(files) {
|
|
4813
|
+
return files.toSorted((a, b)=>{
|
|
4814
|
+
const aIndex = orders.indexOf(a);
|
|
4815
|
+
const bIndex = orders.indexOf(b);
|
|
4816
|
+
if (-1 === aIndex && -1 === bIndex) return a.localeCompare(b);
|
|
4817
|
+
if (-1 === aIndex) return 1;
|
|
4818
|
+
if (-1 === bIndex) return -1;
|
|
4819
|
+
return aIndex - bIndex;
|
|
4820
|
+
});
|
|
4821
|
+
}
|
|
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
|
+
---`);
|
|
4828
|
+
}
|
|
4829
|
+
function transformCursorRuleToAgentsRule(source) {
|
|
4830
|
+
return source.replace(/^---\nalwaysApply: (true|false)\n---/, "").replace(/^(#+ )/gm, "#$1");
|
|
4831
|
+
}
|
|
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";
|
|
4847
|
+
}
|
|
4848
|
+
return map;
|
|
4849
|
+
}
|
|
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
|
+
type: "checkbox",
|
|
4856
|
+
name: "files",
|
|
4857
|
+
message: "请选择要添加的 Cursor 规则文件",
|
|
4858
|
+
choices: Object.entries(map).map(([key, value])=>({
|
|
4859
|
+
name: `${key} (${value})`,
|
|
4860
|
+
value: key
|
|
4861
|
+
})),
|
|
4862
|
+
default: changedFiles
|
|
4863
|
+
});
|
|
4864
|
+
await mkdir(cursorRulesTarget, {
|
|
4865
|
+
recursive: true
|
|
4866
|
+
});
|
|
4867
|
+
for (const file of selectedFiles)await copyFile(join(syncAgentRules_source, file), join(cursorRulesTarget, file));
|
|
4868
|
+
}
|
|
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);
|
|
4888
|
+
}
|
|
4791
4889
|
async function asyncAgentRules() {
|
|
4792
4890
|
try {
|
|
4793
4891
|
const packageJson = await readPackageJson();
|
|
@@ -4797,70 +4895,29 @@ async function asyncAgentRules() {
|
|
|
4797
4895
|
});
|
|
4798
4896
|
} catch (error) {}
|
|
4799
4897
|
await spawnAsync("npx gitpick 1adybug/cursor-rule/tree/main/.cursor/rules .cursor-rules");
|
|
4800
|
-
const source = join(".cursor-rules");
|
|
4801
|
-
const target = join(".cursor", "rules");
|
|
4802
|
-
let existed = existsSync(target);
|
|
4803
|
-
if (!existed) await mkdir(target, {
|
|
4804
|
-
recursive: true
|
|
4805
|
-
});
|
|
4806
4898
|
try {
|
|
4807
|
-
const sourceDir = await readdir(
|
|
4808
|
-
const
|
|
4809
|
-
const
|
|
4810
|
-
for (const file of sourceDir){
|
|
4811
|
-
if (!targetDir.includes(file)) {
|
|
4812
|
-
map[file] = "new";
|
|
4813
|
-
continue;
|
|
4814
|
-
}
|
|
4815
|
-
const sourceContent = await readFile(join(source, file), "utf-8");
|
|
4816
|
-
const targetContent = await readFile(join(target, file), "utf-8");
|
|
4817
|
-
if (sourceContent !== targetContent) map[file] = "modified";
|
|
4818
|
-
}
|
|
4819
|
-
if (0 === Object.keys(map).length) throw new Error("Cursor 规则已是最新");
|
|
4820
|
-
const { files } = await inquirer_0.prompt({
|
|
4899
|
+
const sourceDir = sortAgentRuleFiles(await readdir(syncAgentRules_source));
|
|
4900
|
+
const defaultTargets = getDefaultSyncTargets();
|
|
4901
|
+
const { targets } = await inquirer_0.prompt({
|
|
4821
4902
|
type: "checkbox",
|
|
4822
|
-
name: "
|
|
4823
|
-
message: "
|
|
4824
|
-
choices: Object.
|
|
4825
|
-
|
|
4826
|
-
value: key
|
|
4827
|
-
})),
|
|
4828
|
-
default: Object.keys(map)
|
|
4829
|
-
});
|
|
4830
|
-
for (const file of files)await copyFile(join(source, file), join(target, file));
|
|
4831
|
-
await rm(source, {
|
|
4832
|
-
recursive: true
|
|
4903
|
+
name: "targets",
|
|
4904
|
+
message: "请选择要同步的 Agent 规则",
|
|
4905
|
+
choices: Object.values(AgentRulesSyncTarget),
|
|
4906
|
+
default: defaultTargets
|
|
4833
4907
|
});
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
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
|
|
4837
4915
|
});
|
|
4838
|
-
const orders = [
|
|
4839
|
-
"base.mdc",
|
|
4840
|
-
"react.mdc",
|
|
4841
|
-
"api.mdc",
|
|
4842
|
-
"next.mdc"
|
|
4843
|
-
];
|
|
4844
|
-
dir.sort((a, b)=>orders.indexOf(a) - orders.indexOf(b));
|
|
4845
|
-
let agentsRule = "# Agent Rules";
|
|
4846
|
-
for (const file of dir){
|
|
4847
|
-
const source = await readFile(join(".cursor/rules", file), "utf-8");
|
|
4848
|
-
const content = source.replace(/^---\nalwaysApply: (true|false)\n---/, (match, p1)=>`---
|
|
4849
|
-
trigger: ${"true" === p1 ? "always_on" : "model_decision"}
|
|
4850
|
-
glob:
|
|
4851
|
-
description:
|
|
4852
|
-
---`);
|
|
4853
|
-
const content2 = source.replace(/^---\nalwaysApply: (true|false)\n---/, "").replace(/^(#+ )/gm, "#$1");
|
|
4854
|
-
agentsRule += content2;
|
|
4855
|
-
agentsRule = agentsRule.replace(/\n+$/, "");
|
|
4856
|
-
await writeFile(join(".agent/rules", file.replace(/\.mdc$/, ".md")), content);
|
|
4857
|
-
}
|
|
4858
|
-
agentsRule += "\n";
|
|
4859
|
-
await writeFile("AGENTS.md", agentsRule);
|
|
4860
4916
|
return getCommitMessage("feature", "同步 Agent 规则");
|
|
4861
4917
|
} catch (error) {
|
|
4862
|
-
await rm(
|
|
4863
|
-
recursive: true
|
|
4918
|
+
await rm(syncAgentRules_source, {
|
|
4919
|
+
recursive: true,
|
|
4920
|
+
force: true
|
|
4864
4921
|
});
|
|
4865
4922
|
throw error;
|
|
4866
4923
|
}
|
|
@@ -5312,7 +5369,7 @@ async function pathExists(path) {
|
|
|
5312
5369
|
}
|
|
5313
5370
|
}
|
|
5314
5371
|
|
|
5315
|
-
// Windows
|
|
5372
|
+
// Windows 上优先查找 code.cmd,避免直接调用 Code.exe 打开编辑器窗口
|
|
5316
5373
|
async function resolveCodeCli() {
|
|
5317
5374
|
if (process.platform !== "win32") return "code"
|
|
5318
5375
|
|
|
@@ -5328,7 +5385,6 @@ async function resolveCodeCli() {
|
|
|
5328
5385
|
const pathDirs = process.env.PATH?.split(delimiter).filter(Boolean) ?? []
|
|
5329
5386
|
for (const dir of pathDirs) {
|
|
5330
5387
|
candidates.add(join(dir, "code.cmd"))
|
|
5331
|
-
candidates.add(join(dir, "code.exe"))
|
|
5332
5388
|
candidates.add(join(dir, "code"))
|
|
5333
5389
|
}
|
|
5334
5390
|
|
|
@@ -5339,16 +5395,69 @@ async function resolveCodeCli() {
|
|
|
5339
5395
|
throw new Error("未找到 VS Code 命令行工具,请先安装 VS Code,并确认安装时勾选了“添加到 PATH”")
|
|
5340
5396
|
}
|
|
5341
5397
|
|
|
5398
|
+
/**
|
|
5399
|
+
* @param {string} value
|
|
5400
|
+
*/
|
|
5401
|
+
function quoteWindowsArg(value) {
|
|
5402
|
+
return "\\"" + value.replace(/"/g, "\\"\\"") + "\\""
|
|
5403
|
+
}
|
|
5404
|
+
|
|
5405
|
+
/**
|
|
5406
|
+
* @param {string[]} args
|
|
5407
|
+
* @param {string} output
|
|
5408
|
+
*/
|
|
5409
|
+
function isCliCommandSuccessful(args, output) {
|
|
5410
|
+
if (args.includes("--install-extension")) return output.includes("was successfully installed.") || output.includes("is already installed.")
|
|
5411
|
+
if (args.includes("--uninstall-extension")) return output.includes("was successfully uninstalled.") || output.includes("is not installed.")
|
|
5412
|
+
return false
|
|
5413
|
+
}
|
|
5414
|
+
|
|
5415
|
+
/**
|
|
5416
|
+
* @param {Buffer | string} data
|
|
5417
|
+
* @param {string[]} chunks
|
|
5418
|
+
* @param {NodeJS.WriteStream} stream
|
|
5419
|
+
*/
|
|
5420
|
+
function writeChildOutput(data, chunks, stream) {
|
|
5421
|
+
const text = data.toString()
|
|
5422
|
+
chunks.push(text)
|
|
5423
|
+
stream.write(text)
|
|
5424
|
+
}
|
|
5425
|
+
|
|
5342
5426
|
/**
|
|
5343
5427
|
* @param {string} command
|
|
5344
5428
|
* @param {string[]} args
|
|
5345
5429
|
*/
|
|
5346
5430
|
function spawnAsync(command, args) {
|
|
5347
5431
|
return new Promise((resolve, reject) => {
|
|
5348
|
-
|
|
5432
|
+
// Windows 不能直接 spawn .cmd 或 .bat 文件,需要交给 cmd.exe 执行
|
|
5433
|
+
const needCmdShell = process.platform === "win32" && /\\.(cmd|bat)$/i.test(command)
|
|
5434
|
+
const chunks = []
|
|
5435
|
+
const child = needCmdShell
|
|
5436
|
+
? spawn(
|
|
5437
|
+
process.env.ComSpec ?? "cmd.exe",
|
|
5438
|
+
["/d", "/s", "/c", "\\"" + quoteWindowsArg(command) + " " + args.map(quoteWindowsArg).join(" ") + "\\""],
|
|
5439
|
+
{
|
|
5440
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
5441
|
+
windowsVerbatimArguments: true,
|
|
5442
|
+
},
|
|
5443
|
+
)
|
|
5444
|
+
: spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] })
|
|
5445
|
+
|
|
5446
|
+
child.stdout?.on("data", data => writeChildOutput(data, chunks, process.stdout))
|
|
5447
|
+
child.stderr?.on("data", data => writeChildOutput(data, chunks, process.stderr))
|
|
5349
5448
|
child.on("error", reject)
|
|
5350
5449
|
child.on("exit", code => {
|
|
5351
|
-
|
|
5450
|
+
const output = chunks.join("")
|
|
5451
|
+
|
|
5452
|
+
if (code !== 0) {
|
|
5453
|
+
if (isCliCommandSuccessful(args, output)) {
|
|
5454
|
+
console.warn(\`VS Code 命令退出码为 \${code},但操作已完成,继续执行后续步骤\`)
|
|
5455
|
+
return resolve(0)
|
|
5456
|
+
}
|
|
5457
|
+
|
|
5458
|
+
return reject(new Error(\`Command failed with code \${code}: \${command} \${args.join(" ")}\`))
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5352
5461
|
resolve(0)
|
|
5353
5462
|
})
|
|
5354
5463
|
})
|
|
@@ -5360,8 +5469,18 @@ ${needUserDir ? ` const userDir = homedir()
|
|
|
5360
5469
|
` : ""}${options.includes(VscodeSyncOption.插件) ? ` const extensionsDir = join(workspaceDir, "extensions")
|
|
5361
5470
|
const codeCli = await resolveCodeCli()
|
|
5362
5471
|
const dir = await readdir(extensionsDir)
|
|
5472
|
+
const extensionErrors = []
|
|
5363
5473
|
for (const ext of dir) {
|
|
5364
|
-
|
|
5474
|
+
try {
|
|
5475
|
+
await spawnAsync(codeCli, ["--install-extension", join(extensionsDir, ext), "--force"])
|
|
5476
|
+
} catch (error) {
|
|
5477
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
5478
|
+
extensionErrors.push(\`\${ext}: \${message}\`)
|
|
5479
|
+
console.error(\`扩展同步失败:\${ext}\`)
|
|
5480
|
+
}
|
|
5481
|
+
}
|
|
5482
|
+
if (extensionErrors.length > 0) {
|
|
5483
|
+
throw new Error(\`以下扩展同步失败:\\n\${extensionErrors.join("\\n")}\`)
|
|
5365
5484
|
}
|
|
5366
5485
|
` : ""}${options.includes(VscodeSyncOption.配置) ? ` const codeUserDir = join(userDir, "AppData", "Roaming", "Code", "User")
|
|
5367
5486
|
await mkdir(codeUserDir, { recursive: true })
|