opencode-deepseek-chan 1.0.0 → 1.0.1

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/README.md CHANGED
@@ -4,7 +4,11 @@ Unofficial community theme: cyber-dark and glassmorphism visual theme inspired b
4
4
 
5
5
  非官方社区主题:受 DeepSeek-chan 启发的赛博暗黑玻璃拟态主题,适用于 OpenCode Desktop,附带交互式终端安装器,可安全地安装与恢复主题,无需手动修改代码。
6
6
 
7
- ![Version](https://img.shields.io/badge/version-1.0.0-4D6BFE)
7
+ **Windows only**: the installer patches the OpenCode Desktop installation under `%LOCALAPPDATA%`. macOS and Linux are not supported yet.
8
+
9
+ **仅支持 Windows**:安装器会修改 `%LOCALAPPDATA%` 下的 OpenCode Desktop 安装。暂不支持 macOS 和 Linux。
10
+
11
+ ![Version](https://img.shields.io/badge/version-1.0.1-4D6BFE)
8
12
  ![License](https://img.shields.io/badge/license-MIT-70C0FF)
9
13
  ![Platform](https://img.shields.io/badge/platform-Windows-0B1528)
10
14
  ![Node](https://img.shields.io/badge/node-%3E%3D18-4D6BFE)
package/bin/cli.js CHANGED
@@ -115,7 +115,7 @@ const obtainAssetFile = async (preset, localeStrings) => {
115
115
  return destinationPath;
116
116
  };
117
117
 
118
- const executeInstall = async (itemType, filePath, localeStrings) => {
118
+ const executeInstall = async (itemType, filePath, localeStrings, themeTitle) => {
119
119
  if (isOpenCodeRunning()) {
120
120
  console.log(`${colors.red}${localeStrings.opencodeRunning}${colors.reset}`);
121
121
  process.exit(1);
@@ -128,8 +128,24 @@ const executeInstall = async (itemType, filePath, localeStrings) => {
128
128
  }
129
129
 
130
130
  try {
131
- await installTheme(itemType, filePath);
132
- console.log(`${colors.green}${colors.bold}${localeStrings.installSuccess}${colors.reset}\n`);
131
+ const stepLabels = {
132
+ backup: localeStrings.stepBackup,
133
+ encode: localeStrings.stepEncode,
134
+ extract: localeStrings.stepExtract,
135
+ patch: localeStrings.stepPatch,
136
+ repack: localeStrings.stepRepack
137
+ };
138
+
139
+ const stepLog = (key, current, total) => {
140
+ const label = stepLabels[key] || key;
141
+ console.log(`${colors.cyan}${colors.bold}[${current}/${total}]${colors.reset} ${label}...`);
142
+ };
143
+
144
+ await installTheme(itemType, filePath, stepLog);
145
+ const successMessage = themeTitle
146
+ ? localeStrings.installSuccessNamed.replace("{theme}", themeTitle)
147
+ : localeStrings.installSuccess;
148
+ console.log(`${colors.green}${colors.bold}${successMessage}${colors.reset}\n`);
133
149
  } catch (error) {
134
150
  console.log(`${colors.red}${localeStrings.error}: ${error.message}${colors.reset}`);
135
151
  process.exit(1);
@@ -211,7 +227,7 @@ const runInteractiveMenu = async (localeStrings, currentLocale = "en", cliArgs =
211
227
  const title = localeStrings[chosenPreset.titleKey] || chosenPreset.id;
212
228
  console.log(`\n${colors.cyan}${title}${colors.reset}\n`);
213
229
  const assetPath = await obtainAssetFile(chosenPreset, localeStrings);
214
- await executeInstall(chosenPreset.type, assetPath, localeStrings);
230
+ await executeInstall(chosenPreset.type, assetPath, localeStrings, title);
215
231
  } else if (numericChoice === changeLangOptionNumber) {
216
232
  promptLanguageSelection(readlineInterface, localeStrings, cliArgs, async (selectedLanguage) => {
217
233
  readlineInterface.close();
@@ -280,7 +296,7 @@ const main = async () => {
280
296
  const title = localeStrings[chosenPreset.titleKey] || chosenPreset.id;
281
297
  console.log(`${colors.cyan}${title}${colors.reset}\n`);
282
298
  const assetPath = await obtainAssetFile(chosenPreset, localeStrings);
283
- await executeInstall(chosenPreset.type, assetPath, localeStrings);
299
+ await executeInstall(chosenPreset.type, assetPath, localeStrings, title);
284
300
  return;
285
301
  }
286
302
 
@@ -290,11 +306,13 @@ const main = async () => {
290
306
  const cleaned = cliArgs.install.trim().replace(/^["']|["']$/g, "");
291
307
  const extension = path.extname(cleaned).toLowerCase();
292
308
  const isVideo = [".mp4", ".webm", ".mkv"].includes(extension);
293
- await executeInstall(isVideo ? "video" : "image", cleaned, localeStrings);
309
+ const customTitle = path.basename(cleaned, path.extname(cleaned));
310
+ await executeInstall(isVideo ? "video" : "image", cleaned, localeStrings, customTitle);
294
311
  } else {
295
312
  const defaultPreset = presets[0];
313
+ const defaultTitle = localeStrings[defaultPreset.titleKey] || defaultPreset.id;
296
314
  const assetPath = await obtainAssetFile(defaultPreset, localeStrings);
297
- await executeInstall(defaultPreset.type, assetPath, localeStrings);
315
+ await executeInstall(defaultPreset.type, assetPath, localeStrings, defaultTitle);
298
316
  }
299
317
  return;
300
318
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "opencode-deepseek-chan",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Animated video backgrounds & cyber glassmorphism theme for OpenCode Desktop (DeepSeek-chan). 适用于 OpenCode Desktop 的 DeepSeek 赛博动态壁纸主题。",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
7
- "opencode-deepseek-chan": "./bin/cli.js"
7
+ "opencode-deepseek-chan": "bin/cli.js"
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node ./bin/cli.js",
package/src/engine.js CHANGED
@@ -231,7 +231,17 @@ button:hover {
231
231
  };
232
232
 
233
233
  const installTheme = async (itemType, filePath, logFunction) => {
234
- const log = logFunction || console.log;
234
+ const log = logFunction || (() => {});
235
+
236
+ const stepKeys =
237
+ itemType === "video"
238
+ ? ["backup", "extract", "patch", "repack"]
239
+ : ["backup", "encode", "extract", "patch", "repack"];
240
+ let stepIndex = 0;
241
+ const emitStep = (key) => {
242
+ stepIndex += 1;
243
+ log(key, stepIndex, stepKeys.length);
244
+ };
235
245
 
236
246
  if (isOpenCodeRunning()) {
237
247
  throw new Error("OPENCODE_RUNNING");
@@ -250,6 +260,7 @@ const installTheme = async (itemType, filePath, logFunction) => {
250
260
  throw new Error(`app.asar not found in ${resourcesDirectory}`);
251
261
  }
252
262
 
263
+ emitStep("backup");
253
264
  if (fs.existsSync(appAsarBackupPath)) {
254
265
  fs.copyFileSync(appAsarBackupPath, appAsarPath);
255
266
  } else {
@@ -263,6 +274,7 @@ const installTheme = async (itemType, filePath, logFunction) => {
263
274
  const isVideo = itemType === "video";
264
275
  let base64Url = "";
265
276
  if (!isVideo) {
277
+ emitStep("encode");
266
278
  base64Url = encodeImageToBase64(filePath);
267
279
  }
268
280
 
@@ -273,6 +285,7 @@ const installTheme = async (itemType, filePath, logFunction) => {
273
285
  `opencode_patch_${Date.now()}`
274
286
  );
275
287
 
288
+ emitStep("extract");
276
289
  asar.extractAll(appAsarPath, temporaryExtractionPath);
277
290
 
278
291
  const indexHtmlPath = path.join(
@@ -315,9 +328,11 @@ const installTheme = async (itemType, filePath, logFunction) => {
315
328
  }
316
329
 
317
330
  const styleBlock = `<style id="opencode-bg-correct-override">${themeCss}</style>\n</head>`;
331
+ emitStep("patch");
318
332
  indexHtmlContent = indexHtmlContent.replace("</head>", styleBlock);
319
333
  fs.writeFileSync(indexHtmlPath, indexHtmlContent, "utf8");
320
334
 
335
+ emitStep("repack");
321
336
  await asar.createPackage(temporaryExtractionPath, appAsarPath);
322
337
  fs.rmSync(temporaryExtractionPath, { recursive: true, force: true });
323
338
  };
package/src/i18n.js CHANGED
@@ -10,8 +10,14 @@ const locales = {
10
10
  exitOption: "Exit",
11
11
  downloading: "Downloading asset",
12
12
  downloadFallback: "Retrying using mirror accelerator...",
13
+ stepBackup: "Backing up original app.asar",
14
+ stepEncode: "Encoding image asset",
15
+ stepExtract: "Extracting app.asar",
16
+ stepPatch: "Patching renderer index.html",
17
+ stepRepack: "Repacking app.asar",
13
18
  opencodeRunning: "OpenCode Desktop is currently running. Please close it before proceeding.",
14
19
  installSuccess: "DeepSeek Cyber theme installed successfully.",
20
+ installSuccessNamed: "{theme} theme installed successfully.",
15
21
  restoreSuccess: "OpenCode Desktop restored to factory state.",
16
22
  pathNotFound: "OpenCode Desktop installation path not found.",
17
23
  error: "Error",
@@ -30,8 +36,14 @@ const locales = {
30
36
  exitOption: "退出",
31
37
  downloading: "正在下载背景资源",
32
38
  downloadFallback: "正在尝试使用国内镜像加速下载...",
39
+ stepBackup: "备份原始 app.asar",
40
+ stepEncode: "编码图片资源",
41
+ stepExtract: "解压 app.asar",
42
+ stepPatch: "修改渲染进程 index.html",
43
+ stepRepack: "重新打包 app.asar",
33
44
  opencodeRunning: "检测到 OpenCode Desktop 正在运行,请先关闭该程序再执行安装。",
34
45
  installSuccess: "DeepSeek 赛博主题安装成功!",
46
+ installSuccessNamed: "{theme} 主题安装成功!",
35
47
  restoreSuccess: "OpenCode Desktop 已成功恢复出厂默认状态。",
36
48
  pathNotFound: "未找到 OpenCode Desktop 安装路径。",
37
49
  error: "错误",
@@ -50,8 +62,14 @@ const locales = {
50
62
  exitOption: "Salir",
51
63
  downloading: "Descargando recurso",
52
64
  downloadFallback: "Reintentando mediante espejo acelerado...",
65
+ stepBackup: "Respaldando app.asar original",
66
+ stepEncode: "Codificando recurso de imagen",
67
+ stepExtract: "Extrayendo app.asar",
68
+ stepPatch: "Parcheando index.html del renderer",
69
+ stepRepack: "Reempaquetando app.asar",
53
70
  opencodeRunning: "OpenCode Desktop esta en ejecucion. Cierralo antes de continuar.",
54
71
  installSuccess: "Tema DeepSeek Cyber instalado con exito.",
72
+ installSuccessNamed: "Tema {theme} instalado con exito.",
55
73
  restoreSuccess: "OpenCode Desktop ha sido restaurado a su estado original.",
56
74
  pathNotFound: "No se detecto la ruta de OpenCode Desktop.",
57
75
  error: "Error",