playlist-admin 2.15.68 → 2.15.69

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 (2) hide show
  1. package/cli/index.js +107 -4
  2. package/package.json +1 -1
package/cli/index.js CHANGED
@@ -11,10 +11,16 @@ import { fileURLToPath } from 'node:url';
11
11
 
12
12
  const HELP = `playlist-admin CLI
13
13
 
14
- Runs the same engine as the GUI app (shared Dart code). Requires a built
15
- release: flutter build windows --release
14
+ Runs the same engine as the GUI app (shared Dart code).
16
15
 
17
16
  Usage:
17
+ playlist-admin -v | --version | version Show CLI + GUI 版本,並檢查有沒有新版
18
+ playlist-admin -h | --help | help 顯示這份說明
19
+ playlist-admin update| upgrade 更新 CLI(npm)並提示 GUI 更新方式
20
+ playlist-admin where 顯示根目錄 / exe / 資料夾位置
21
+ playlist-admin doctor [--fast] [--verbose] [--no-stt]
22
+ 音訊庫健康檢查(覆蓋率/損毀/品質/語言/額度)
23
+
18
24
  playlist-admin pipeline [--step N] Run full pipeline (or from step N)
19
25
  playlist-admin podcast Run podcast pipeline
20
26
  playlist-admin status Show status
@@ -32,8 +38,6 @@ Usage:
32
38
  playlist-admin skill list List bundled opencode skills
33
39
  playlist-admin skill install [name] [--dir X] Install skill(s) to opencode (~/.config/opencode/skills)
34
40
  playlist-admin skill path [name] Print installed path of a skill
35
- playlist-admin doctor [--fast] [--verbose] [--no-stt]
36
- 音訊庫健康檢查(覆蓋率/損毀/品質/語言/額度)
37
41
  `;
38
42
 
39
43
  function projectRoot() {
@@ -280,12 +284,86 @@ function runSkill(args) {
280
284
  process.exit(1);
281
285
  }
282
286
 
287
+ /// npm 包自身的版本(package.json)。CI 由 git tag 填入。
288
+ function packageVersion() {
289
+ try {
290
+ const pkg = path.join(packageRoot() || '', 'package.json');
291
+ return JSON.parse(fs.readFileSync(pkg, 'utf8')).version || '?';
292
+ } catch {
293
+ return '?';
294
+ }
295
+ }
296
+
297
+ /// GUI 引擎(playlist-admin.exe)的版本。
298
+ /// exe 的 Windows VersionInfo 沒被 CI 改(仍是 pubspec 的 3.0.0-beta.1),
299
+ /// 所以直接問引擎自己——它知道 build 時注入的 APP_VERSION。
300
+ function guiVersion(exe) {
301
+ if (!exe || !fs.existsSync(exe)) return null;
302
+ const r = spawnSync(exe, [], {
303
+ env: { ...process.env, PA_CLI_ARGS: '["version"]' },
304
+ encoding: 'utf8',
305
+ windowsHide: true,
306
+ timeout: 30000,
307
+ });
308
+ const out = (r.stdout || '').trim();
309
+ const m = out.match(/Engine\s+(\S+)/);
310
+ if (m) return m[1];
311
+ // 引擎起不來就退回修改時間,至少讓使用者看得出新舊
312
+ try {
313
+ const mt = fs.statSync(exe).mtime.toISOString().slice(0, 16).replace('T', ' ');
314
+ return `(exe 最後修改 ${mt})`;
315
+ } catch {
316
+ return null;
317
+ }
318
+ }
319
+
320
+ function cmdVersion() {
321
+ const cli = packageVersion();
322
+ const root = installedRoot() || projectRoot();
323
+ const exe = exePath(root);
324
+ const gv = guiVersion(exe);
325
+ console.log(`CLI ${cli}`);
326
+ console.log(gv ? `GUI ${gv} (${exe})` : 'GUI (找不到安裝中的 GUI)');
327
+ if (gv && !gv.startsWith('(') && gv !== cli) {
328
+ console.log('⚠️ CLI 與 GUI 版本不一致 → 先更新 GUI 再用 CLI');
329
+ }
330
+ const latest = runQuiet('npm', ['view', 'playlist-admin', 'version']);
331
+ if (latest && latest !== cli) {
332
+ console.log(`最新 ${latest} → npm i -g playlist-admin@latest`);
333
+ }
334
+ }
335
+
336
+ function runQuiet(cmd, cmdArgs) {
337
+ try {
338
+ const r = spawnSync(cmd, cmdArgs, { encoding: 'utf8', windowsHide: true });
339
+ return (r.stdout || '').trim().split('\n').pop();
340
+ } catch {
341
+ return null;
342
+ }
343
+ }
344
+
283
345
  async function main() {
284
346
  const args = process.argv.slice(2);
285
347
  if (args.length === 0) {
286
348
  console.log(HELP);
287
349
  return;
288
350
  }
351
+ // 標準旗標
352
+ if (args[0] === '-h' || args[0] === '--help' || args[0] === 'help') {
353
+ console.log(HELP);
354
+ return;
355
+ }
356
+ if (args[0] === '-v' || args[0] === '--version' || args[0] === 'version') {
357
+ cmdVersion();
358
+ return;
359
+ }
360
+ if (args[0] === '--doctor') {
361
+ args[0] = 'doctor';
362
+ }
363
+ if (args[0] === 'update' || args[0] === 'upgrade') {
364
+ cmdUpdate();
365
+ return;
366
+ }
289
367
  if (args[0] === 'rag') {
290
368
  runRag(args.slice(1));
291
369
  return;
@@ -298,6 +376,13 @@ async function main() {
298
376
  runSkill(args.slice(1));
299
377
  return;
300
378
  }
379
+ if (args[0] === 'where' || args[0] === 'doctor-env') {
380
+ const root = installedRoot() || projectRoot();
381
+ console.log(`根目錄: ${root || '(找不到)'}`);
382
+ console.log(`exe : ${exePath(root) || '(找不到)'}`);
383
+ console.log(`資料 : ${path.join(root || '?', 'data')}`);
384
+ return;
385
+ }
301
386
 
302
387
  const root = projectRoot();
303
388
  if (!root) {
@@ -314,6 +399,24 @@ async function main() {
314
399
  forward(exe, args);
315
400
  }
316
401
 
402
+ /// 更新 CLI 與 GUI。
403
+ function cmdUpdate() {
404
+ console.log('更新 CLI (npm)...');
405
+ const r = spawnSync('npm', ['install', '-g', 'playlist-admin@latest'], {
406
+ stdio: 'inherit',
407
+ windowsHide: true,
408
+ });
409
+ if (r.status !== 0) {
410
+ console.error('npm 更新失敗,試試用系統管理員權限重跑');
411
+ process.exit(1);
412
+ }
413
+ console.log('');
414
+ console.log('更新 GUI...');
415
+ console.log('GUI 是獨立安裝檔,請下載最新的 Setup 執行檔:');
416
+ console.log(' https://github.com/thumb2086/playlist-admin/releases/latest');
417
+ console.log('(或直接在 app 設定頁按「檢查更新」)');
418
+ }
419
+
317
420
  main().catch((e) => {
318
421
  console.error(e);
319
422
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playlist-admin",
3
- "version": "2.15.68",
3
+ "version": "2.15.69",
4
4
  "description": "playlist-admin CLI - pipeline, podcast, music + podcast RAG + study RAG (PDF 試題/課本)",
5
5
  "type": "module",
6
6
  "bin": {