zixulu 1.80.1 → 1.80.2
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 +117 -92
- package/dist/index.js.map +1 -1
- package/dist/src/utils/getEditorExtensions.d.ts +6 -15
- package/dist/src/utils/syncVscode.d.ts +10 -5
- package/package.json +1 -1
- package/src/utils/downloadVscodeExts.ts +2 -5
- package/src/utils/getEditorExtensions.ts +6 -45
- package/src/utils/syncVscode.ts +128 -78
package/dist/index.js
CHANGED
|
@@ -4865,23 +4865,10 @@ description:
|
|
|
4865
4865
|
throw error;
|
|
4866
4866
|
}
|
|
4867
4867
|
}
|
|
4868
|
-
const
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
win32Command: "code.cmd",
|
|
4873
|
-
win32Path: join(getEditorExtensions_userDir, "AppData/Local/Programs/Microsoft VS Code/bin/code.cmd")
|
|
4874
|
-
},
|
|
4875
|
-
Cursor: {
|
|
4876
|
-
command: "cursor",
|
|
4877
|
-
win32Command: "cursor.cmd",
|
|
4878
|
-
win32Path: join(getEditorExtensions_userDir, "AppData/Local/Programs/cursor/resources/app/bin/cursor.cmd")
|
|
4879
|
-
},
|
|
4880
|
-
Antigravity: {
|
|
4881
|
-
command: "antigravity",
|
|
4882
|
-
win32Command: "antigravity.cmd",
|
|
4883
|
-
win32Path: join(getEditorExtensions_userDir, "AppData/Local/Programs/Antigravity/bin/antigravity.cmd")
|
|
4884
|
-
}
|
|
4868
|
+
const EditorExtensionCommandMap = {
|
|
4869
|
+
Code: "code",
|
|
4870
|
+
Cursor: "cursor",
|
|
4871
|
+
Antigravity: "antigravity"
|
|
4885
4872
|
};
|
|
4886
4873
|
async function canGetEditorExtensions({ editor }) {
|
|
4887
4874
|
const command = getEditorExtensionCommand({
|
|
@@ -4895,11 +4882,7 @@ async function canGetEditorExtensions({ editor }) {
|
|
|
4895
4882
|
}
|
|
4896
4883
|
}
|
|
4897
4884
|
function getEditorExtensionCommand({ editor }) {
|
|
4898
|
-
|
|
4899
|
-
if ("win32" !== process.platform) return item.command;
|
|
4900
|
-
if (item.win32Path && existsSync(item.win32Path)) return `"${item.win32Path}"`;
|
|
4901
|
-
if (item.win32Command) return item.win32Command;
|
|
4902
|
-
return item.command;
|
|
4885
|
+
return EditorExtensionCommandMap[editor];
|
|
4903
4886
|
}
|
|
4904
4887
|
async function getEditorExtensions({ source }) {
|
|
4905
4888
|
let data = [];
|
|
@@ -5258,13 +5241,10 @@ async function getVscodeExtInfo(ext) {
|
|
|
5258
5241
|
const reg = /^(.+?)\.(.+?)$/;
|
|
5259
5242
|
const [, author, name] = ext.match(reg);
|
|
5260
5243
|
let version;
|
|
5261
|
-
const codeCommand = getEditorExtensionCommand({
|
|
5262
|
-
editor: "Code"
|
|
5263
|
-
});
|
|
5264
5244
|
if ("ms-ceintl.vscode-language-pack-zh-hans" === ext) {
|
|
5265
5245
|
const reg2 = /"Versions":(\[\{".+?\])/;
|
|
5266
5246
|
const versions = JSON.parse(html.match(reg2)[1]);
|
|
5267
|
-
const output = await execAsync(
|
|
5247
|
+
const output = await execAsync("code --version");
|
|
5268
5248
|
const codeVersions = output.split("\n")[0].split(".").map(Number);
|
|
5269
5249
|
const item = versions.find(({ version })=>version.split(".").map(Number).every((item, index)=>index >= 2 || item <= codeVersions[index])) ?? versions[0];
|
|
5270
5250
|
version = item.version;
|
|
@@ -5287,10 +5267,7 @@ async function downloadVscodeExts(dir) {
|
|
|
5287
5267
|
recursive: true
|
|
5288
5268
|
});
|
|
5289
5269
|
consola.start("正在获取 VS Code 扩展列表");
|
|
5290
|
-
const
|
|
5291
|
-
editor: "Code"
|
|
5292
|
-
});
|
|
5293
|
-
const extList = await execAsync(`${codeCommand} --list-extensions`);
|
|
5270
|
+
const extList = await execAsync("code --list-extensions");
|
|
5294
5271
|
const exts = await Promise.all(extList.split(/[\n\r]/).filter(Boolean).filter((item)=>!item.startsWith("anysphere.")).map((ext)=>getVscodeExtInfo(ext)));
|
|
5295
5272
|
const setting = await readZixuluSetting();
|
|
5296
5273
|
const vscodeDownloadHistory = setting?.vscodeDownloadHistory;
|
|
@@ -5308,37 +5285,127 @@ async function downloadVscodeExts(dir) {
|
|
|
5308
5285
|
await writeZixuluSetting(setting);
|
|
5309
5286
|
await Promise.all(exts.filter((ext)=>exts2.exts.includes(ext.id)).map((ext)=>retry(()=>download_download(ext.url, dir, `${ext.id}-${ext.version}.vsix`), 4)));
|
|
5310
5287
|
}
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5288
|
+
const VscodeSyncOption = {
|
|
5289
|
+
配置: "SETTING",
|
|
5290
|
+
插件: "EXTENSION",
|
|
5291
|
+
软件: "SOFTWARE",
|
|
5292
|
+
PowerShell: "POWERSHELL"
|
|
5293
|
+
};
|
|
5294
|
+
function createSyncVscodeScript(options) {
|
|
5295
|
+
const needUserDir = options.includes(VscodeSyncOption.配置) || options.includes(VscodeSyncOption.PowerShell);
|
|
5296
|
+
return `// @ts-check
|
|
5297
|
+
|
|
5298
|
+
import { spawn } from "node:child_process"
|
|
5299
|
+
import { access, copyFile, mkdir, readdir, rm } from "node:fs/promises"
|
|
5300
|
+
import { homedir } from "node:os"
|
|
5301
|
+
import { delimiter, join } from "node:path"
|
|
5302
|
+
|
|
5303
|
+
/**
|
|
5304
|
+
* @param {string} path
|
|
5305
|
+
*/
|
|
5306
|
+
async function pathExists(path) {
|
|
5307
|
+
try {
|
|
5308
|
+
await access(path)
|
|
5309
|
+
return true
|
|
5310
|
+
} catch {
|
|
5311
|
+
return false
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
|
|
5315
|
+
// Windows 上优先查找真实的 code.cmd,避免 shell 拼命令时的路径问题
|
|
5316
|
+
async function resolveCodeCli() {
|
|
5317
|
+
if (process.platform !== "win32") return "code"
|
|
5318
|
+
|
|
5319
|
+
const candidates = new Set()
|
|
5320
|
+
const localAppData = process.env.LOCALAPPDATA ?? join(homedir(), "AppData", "Local")
|
|
5321
|
+
const programFiles = process.env.ProgramFiles ?? "C:/Program Files"
|
|
5322
|
+
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:/Program Files (x86)"
|
|
5323
|
+
|
|
5324
|
+
candidates.add(join(localAppData, "Programs", "Microsoft VS Code", "bin", "code.cmd"))
|
|
5325
|
+
candidates.add(join(programFiles, "Microsoft VS Code", "bin", "code.cmd"))
|
|
5326
|
+
candidates.add(join(programFilesX86, "Microsoft VS Code", "bin", "code.cmd"))
|
|
5327
|
+
|
|
5328
|
+
const pathDirs = process.env.PATH?.split(delimiter).filter(Boolean) ?? []
|
|
5329
|
+
for (const dir of pathDirs) {
|
|
5330
|
+
candidates.add(join(dir, "code.cmd"))
|
|
5331
|
+
candidates.add(join(dir, "code.exe"))
|
|
5332
|
+
candidates.add(join(dir, "code"))
|
|
5333
|
+
}
|
|
5334
|
+
|
|
5335
|
+
for (const candidate of candidates) {
|
|
5336
|
+
if (await pathExists(candidate)) return candidate
|
|
5337
|
+
}
|
|
5338
|
+
|
|
5339
|
+
throw new Error("未找到 VS Code 命令行工具,请先安装 VS Code,并确认安装时勾选了“添加到 PATH”")
|
|
5340
|
+
}
|
|
5341
|
+
|
|
5342
|
+
/**
|
|
5343
|
+
* @param {string} command
|
|
5344
|
+
* @param {string[]} args
|
|
5345
|
+
*/
|
|
5346
|
+
function spawnAsync(command, args) {
|
|
5347
|
+
return new Promise((resolve, reject) => {
|
|
5348
|
+
const child = spawn(command, args, { stdio: "inherit" })
|
|
5349
|
+
child.on("error", reject)
|
|
5350
|
+
child.on("exit", code => {
|
|
5351
|
+
if (code !== 0) return reject(new Error(\`Command failed with code \${code}: \${command} \${args.join(" ")}\`))
|
|
5352
|
+
resolve(0)
|
|
5353
|
+
})
|
|
5354
|
+
})
|
|
5355
|
+
}
|
|
5356
|
+
|
|
5357
|
+
async function main() {
|
|
5358
|
+
const workspaceDir = process.cwd()
|
|
5359
|
+
${needUserDir ? ` const userDir = homedir()
|
|
5360
|
+
` : ""}${options.includes(VscodeSyncOption.插件) ? ` const extensionsDir = join(workspaceDir, "extensions")
|
|
5361
|
+
const codeCli = await resolveCodeCli()
|
|
5362
|
+
const dir = await readdir(extensionsDir)
|
|
5363
|
+
for (const ext of dir) {
|
|
5364
|
+
await spawnAsync(codeCli, ["--install-extension", join(extensionsDir, ext)])
|
|
5365
|
+
}
|
|
5366
|
+
` : ""}${options.includes(VscodeSyncOption.配置) ? ` const codeUserDir = join(userDir, "AppData", "Roaming", "Code", "User")
|
|
5367
|
+
await mkdir(codeUserDir, { recursive: true })
|
|
5368
|
+
const setting = join(codeUserDir, "settings.json")
|
|
5369
|
+
await rm(setting, { force: true })
|
|
5370
|
+
await copyFile(join(workspaceDir, "settings.json"), setting)
|
|
5371
|
+
const snippetTarget = join(codeUserDir, "snippets")
|
|
5372
|
+
await mkdir(snippetTarget, { recursive: true })
|
|
5373
|
+
const dir2 = await readdir(join(workspaceDir, "snippets"))
|
|
5374
|
+
for (const file of dir2) {
|
|
5375
|
+
await rm(join(snippetTarget, file), { force: true })
|
|
5376
|
+
await copyFile(join(workspaceDir, "snippets", file), join(snippetTarget, file))
|
|
5377
|
+
}` : ""}${options.includes(VscodeSyncOption.PowerShell) ? `
|
|
5378
|
+
const profileDir = join(userDir, "Documents", "PowerShell")
|
|
5379
|
+
await mkdir(profileDir, { recursive: true })
|
|
5380
|
+
const profile = join(profileDir, "Microsoft.PowerShell_profile.ps1")
|
|
5381
|
+
await copyFile(join(workspaceDir, "Microsoft.PowerShell_profile.ps1"), profile)` : ""}
|
|
5382
|
+
}
|
|
5383
|
+
|
|
5384
|
+
main()
|
|
5385
|
+
`;
|
|
5386
|
+
}
|
|
5318
5387
|
async function syncVscode() {
|
|
5319
|
-
const codeCommand = getEditorExtensionCommand({
|
|
5320
|
-
editor: "Code"
|
|
5321
|
-
});
|
|
5322
5388
|
const options = (await inquirer_0.prompt({
|
|
5323
5389
|
type: "checkbox",
|
|
5324
5390
|
name: "options",
|
|
5325
5391
|
message: "请选择要同步的内容",
|
|
5326
|
-
choices: getEnumEntries(
|
|
5392
|
+
choices: getEnumEntries(VscodeSyncOption).map(([name, value])=>({
|
|
5327
5393
|
name,
|
|
5328
5394
|
value
|
|
5329
5395
|
})),
|
|
5330
|
-
default: getEnumValues(
|
|
5396
|
+
default: getEnumValues(VscodeSyncOption)
|
|
5331
5397
|
})).options;
|
|
5332
5398
|
if (0 === options.length) return;
|
|
5333
5399
|
const userDir = homedir();
|
|
5334
|
-
const
|
|
5335
|
-
const
|
|
5400
|
+
const codeUserDir = join(userDir, "AppData", "Roaming", "Code", "User");
|
|
5401
|
+
const snippetSource = join(codeUserDir, "snippets");
|
|
5402
|
+
const setting = (await readFile(join(codeUserDir, "settings.json"), "utf-8")).replace(/}[ \n\r]*$/, ` "chat.disableAIFeatures": true,\n}`);
|
|
5336
5403
|
const dir = `vscode-${dayjs().format("YYYYMMDDHHmmss")}`;
|
|
5337
5404
|
try {
|
|
5338
5405
|
await mkdir(dir, {
|
|
5339
5406
|
recursive: true
|
|
5340
5407
|
});
|
|
5341
|
-
if (options.includes(
|
|
5408
|
+
if (options.includes(VscodeSyncOption.配置)) {
|
|
5342
5409
|
const snippetTarget = join(dir, "snippets");
|
|
5343
5410
|
await mkdir(snippetTarget, {
|
|
5344
5411
|
recursive: true
|
|
@@ -5349,62 +5416,20 @@ async function syncVscode() {
|
|
|
5349
5416
|
for (const file of files)await copyFile(join(snippetSource, file), join(snippetTarget, file));
|
|
5350
5417
|
consola.success("下载最新 VSCode 配置完成");
|
|
5351
5418
|
}
|
|
5352
|
-
if (options.includes(
|
|
5419
|
+
if (options.includes(VscodeSyncOption.插件)) {
|
|
5353
5420
|
await downloadVscodeExts(join(dir, "extensions"));
|
|
5354
5421
|
consola.success("下载最新 VSCode 插件完成");
|
|
5355
5422
|
}
|
|
5356
|
-
if (options.includes(
|
|
5357
|
-
const script =
|
|
5358
|
-
|
|
5359
|
-
import { spawn } from "node:child_process"
|
|
5360
|
-
import { readdir, copyFile, rm } from "node:fs/promises"
|
|
5361
|
-
import { homedir } from "node:os"
|
|
5362
|
-
import { join } from "node:path"
|
|
5363
|
-
|
|
5364
|
-
const codeCommand = ${JSON.stringify(codeCommand)}
|
|
5365
|
-
|
|
5366
|
-
/**
|
|
5367
|
-
* @param {string} command
|
|
5368
|
-
*/
|
|
5369
|
-
function spawnAsync(command) {
|
|
5370
|
-
return new Promise((resolve, reject) => {
|
|
5371
|
-
const child = spawn(command, { shell: true, stdio: "inherit" })
|
|
5372
|
-
child.on("exit", code => {
|
|
5373
|
-
if (code !== 0) return reject(new Error(\`Command failed with code \${code}\`))
|
|
5374
|
-
resolve(0)
|
|
5375
|
-
})
|
|
5376
|
-
})
|
|
5377
|
-
}
|
|
5378
|
-
|
|
5379
|
-
async function main() {
|
|
5380
|
-
${options.includes("EXTENSION") ? ` const dir = await readdir("./extensions")
|
|
5381
|
-
for (const ext of dir) {
|
|
5382
|
-
await spawnAsync(\`\${codeCommand} --install-extension "./extensions/\${ext}"\`)
|
|
5383
|
-
}
|
|
5384
|
-
` : ""}${options.includes("SETTING") ? ` const userDir = homedir()
|
|
5385
|
-
const setting = join(userDir, "AppData/Roaming/Code/User/settings.json")
|
|
5386
|
-
await rm(setting, { force: true })
|
|
5387
|
-
await copyFile("./settings.json", setting)
|
|
5388
|
-
const snippetTarget = join(userDir, "AppData/Roaming/Code/User/snippets")
|
|
5389
|
-
const dir2 = await readdir("./snippets")
|
|
5390
|
-
for (const file of dir2) {
|
|
5391
|
-
await rm(join(snippetTarget, file), { force: true })
|
|
5392
|
-
await copyFile(join("./snippets", file), join(snippetTarget, file))
|
|
5393
|
-
}` : ""}${options.includes("POWERSHELL") ? `
|
|
5394
|
-
${options.includes("SETTING") ? "" : `const userDir = homedir()
|
|
5395
|
-
`}const profile = join(userDir, "Documents/PowerShell/Microsoft.PowerShell_profile.ps1")
|
|
5396
|
-
await copyFile("./Microsoft.PowerShell_profile.ps1", profile)` : ""}
|
|
5397
|
-
}
|
|
5398
|
-
|
|
5399
|
-
main()`;
|
|
5423
|
+
if (options.includes(VscodeSyncOption.配置) || options.includes(VscodeSyncOption.插件) || options.includes(VscodeSyncOption.PowerShell)) {
|
|
5424
|
+
const script = createSyncVscodeScript(options);
|
|
5400
5425
|
await writeFile(join(dir, "syncVscode.mjs"), script, "utf-8");
|
|
5401
5426
|
}
|
|
5402
|
-
if (options.includes(
|
|
5427
|
+
if (options.includes(VscodeSyncOption.软件)) {
|
|
5403
5428
|
consola.start("开始下载最新 VSCode");
|
|
5404
5429
|
await download_download("https://code.visualstudio.com/sha/download?build=stable&os=win32-x64", dir);
|
|
5405
5430
|
consola.success("下载最新 VSCode 完成");
|
|
5406
5431
|
}
|
|
5407
|
-
if (options.includes(
|
|
5432
|
+
if (options.includes(VscodeSyncOption.PowerShell)) {
|
|
5408
5433
|
consola.start("开始同步 PowerShell 配置");
|
|
5409
5434
|
const userDir = homedir();
|
|
5410
5435
|
const profile = join(userDir, "Documents/PowerShell/Microsoft.PowerShell_profile.ps1");
|