bilisum 1.13.1 → 1.13.3

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 (125) hide show
  1. package/README.md +4 -4
  2. package/bin/bilisum.js +268 -63
  3. package/package.json +7 -2
  4. package/runtime/VERSION +1 -0
  5. package/runtime/apps/service/pyproject.toml +29 -0
  6. package/runtime/apps/service/src/video_sum_service/__init__.py +1 -0
  7. package/runtime/apps/service/src/video_sum_service/__main__.py +5 -0
  8. package/runtime/apps/service/src/video_sum_service/app.py +480 -0
  9. package/runtime/apps/service/src/video_sum_service/context.py +24 -0
  10. package/runtime/apps/service/src/video_sum_service/integrations.py +264 -0
  11. package/runtime/apps/service/src/video_sum_service/knowledge/__init__.py +5 -0
  12. package/runtime/apps/service/src/video_sum_service/knowledge/index_service.py +408 -0
  13. package/runtime/apps/service/src/video_sum_service/knowledge/local_llm.py +319 -0
  14. package/runtime/apps/service/src/video_sum_service/knowledge/rag_service.py +492 -0
  15. package/runtime/apps/service/src/video_sum_service/knowledge/tag_service.py +242 -0
  16. package/runtime/apps/service/src/video_sum_service/main.py +31 -0
  17. package/runtime/apps/service/src/video_sum_service/repository.py +942 -0
  18. package/runtime/apps/service/src/video_sum_service/routers/__init__.py +1 -0
  19. package/runtime/apps/service/src/video_sum_service/routers/knowledge.py +272 -0
  20. package/runtime/apps/service/src/video_sum_service/routers/system.py +280 -0
  21. package/runtime/apps/service/src/video_sum_service/routers/tasks.py +287 -0
  22. package/runtime/apps/service/src/video_sum_service/routers/videos.py +766 -0
  23. package/runtime/apps/service/src/video_sum_service/runtime_support.py +1007 -0
  24. package/runtime/apps/service/src/video_sum_service/schemas.py +418 -0
  25. package/runtime/apps/service/src/video_sum_service/settings_manager.py +130 -0
  26. package/runtime/apps/service/src/video_sum_service/task_artifacts.py +102 -0
  27. package/runtime/apps/service/src/video_sum_service/task_exports.py +108 -0
  28. package/runtime/apps/service/src/video_sum_service/transcribe_worker.py +9 -0
  29. package/runtime/apps/service/src/video_sum_service/video_assets.py +623 -0
  30. package/runtime/apps/service/src/video_sum_service/worker.py +381 -0
  31. package/runtime/apps/web/static/apple-touch-icon.png +0 -0
  32. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  33. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  34. package/runtime/apps/web/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  35. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  36. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  37. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  38. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  39. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  40. package/runtime/apps/web/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  41. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  42. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  43. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  44. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  45. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  46. package/runtime/apps/web/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  47. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  48. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  49. package/runtime/apps/web/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  50. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  51. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  52. package/runtime/apps/web/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  53. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  54. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  55. package/runtime/apps/web/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  56. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  57. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  58. package/runtime/apps/web/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  59. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  60. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  61. package/runtime/apps/web/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  62. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  63. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  64. package/runtime/apps/web/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  65. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  66. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  67. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  68. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  69. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  70. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  71. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  72. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  73. package/runtime/apps/web/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  74. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  75. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  76. package/runtime/apps/web/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  77. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  78. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  79. package/runtime/apps/web/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  80. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  81. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  82. package/runtime/apps/web/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  83. package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  84. package/runtime/apps/web/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  85. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  86. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  87. package/runtime/apps/web/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  88. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  89. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  90. package/runtime/apps/web/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  91. package/runtime/apps/web/static/assets/icons/icon-180.png +0 -0
  92. package/runtime/apps/web/static/assets/icons/icon-512.png +0 -0
  93. package/runtime/apps/web/static/assets/icons/icon.svg +17 -0
  94. package/runtime/apps/web/static/assets/index-Cj5PVjQg.js +388 -0
  95. package/runtime/apps/web/static/assets/index-DU2t4_7s.css +1 -0
  96. package/runtime/apps/web/static/favicon-32x32.png +0 -0
  97. package/runtime/apps/web/static/favicon.ico +0 -0
  98. package/runtime/apps/web/static/favicon.svg +17 -0
  99. package/runtime/apps/web/static/index.html +19 -0
  100. package/runtime/apps/web/static/js/api.js +123 -0
  101. package/runtime/apps/web/static/js/main.js +932 -0
  102. package/runtime/apps/web/static/js/state.js +28 -0
  103. package/runtime/apps/web/static/js/utils.js +81 -0
  104. package/runtime/apps/web/static/js/views/home.js +604 -0
  105. package/runtime/apps/web/static/js/views/settings.js +477 -0
  106. package/runtime/apps/web/static/styles.css +2206 -0
  107. package/runtime/packages/core/pyproject.toml +18 -0
  108. package/runtime/packages/core/src/video_sum_core/__init__.py +1 -0
  109. package/runtime/packages/core/src/video_sum_core/errors.py +22 -0
  110. package/runtime/packages/core/src/video_sum_core/markdown_exports.py +154 -0
  111. package/runtime/packages/core/src/video_sum_core/models/__init__.py +1 -0
  112. package/runtime/packages/core/src/video_sum_core/models/tasks.py +70 -0
  113. package/runtime/packages/core/src/video_sum_core/pipeline/__init__.py +1 -0
  114. package/runtime/packages/core/src/video_sum_core/pipeline/base.py +46 -0
  115. package/runtime/packages/core/src/video_sum_core/pipeline/real.py +3467 -0
  116. package/runtime/packages/core/src/video_sum_core/transcribe_subprocess.py +173 -0
  117. package/runtime/packages/core/src/video_sum_core/utils.py +127 -0
  118. package/runtime/packages/infra/pyproject.toml +16 -0
  119. package/runtime/packages/infra/src/video_sum_infra/__init__.py +1 -0
  120. package/runtime/packages/infra/src/video_sum_infra/app.py +39 -0
  121. package/runtime/packages/infra/src/video_sum_infra/config.py +393 -0
  122. package/runtime/packages/infra/src/video_sum_infra/db.py +34 -0
  123. package/runtime/packages/infra/src/video_sum_infra/logging.py +54 -0
  124. package/runtime/packages/infra/src/video_sum_infra/paths.py +6 -0
  125. package/runtime/packages/infra/src/video_sum_infra/runtime.py +485 -0
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # BiliSum
2
2
 
3
- `bilisum` is the npx helper for BiliSum, an AI video summarizer and knowledge-base tool for Bilibili, YouTube, and local videos.
3
+ `bilisum` starts the local BiliSum browser service from npx.
4
4
 
5
5
  ```bash
6
6
  npx bilisum
7
- npx bilisum release
8
- npx bilisum docker
7
+ npx bilisum start --port 3839
8
+ npx bilisum doctor
9
9
  ```
10
10
 
11
- The desktop app is distributed through GitHub Releases. The npx package stays small and points users to the latest release or Docker quick start.
11
+ Python 3.12 is required. On first run, BiliSum creates a managed Python virtual environment under the user's local app data directory.
package/bin/bilisum.js CHANGED
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { execFileSync, spawn } = require("node:child_process");
4
- const { existsSync, readFileSync } = require("node:fs");
5
- const { join } = require("node:path");
3
+ const { spawn, spawnSync } = require("node:child_process");
4
+ const { existsSync, mkdirSync, readFileSync } = require("node:fs");
5
+ const { dirname, join } = require("node:path");
6
6
 
7
7
  const RELEASES_URL = "https://github.com/lycohana/BiliSum/releases/latest";
8
8
  const REPO_URL = "https://github.com/lycohana/BiliSum";
9
- const DOCKER_IMAGE = "lycohana/bilisum:latest";
9
+ const DEFAULT_PORT = "3838";
10
+ const PACKAGE_ROOT = join(__dirname, "..");
11
+ const RUNTIME_ROOT = join(PACKAGE_ROOT, "runtime");
10
12
 
11
13
  function readVersion() {
12
- const packagePath = join(__dirname, "..", "package.json");
14
+ const packagePath = join(PACKAGE_ROOT, "package.json");
13
15
  if (!existsSync(packagePath)) {
14
16
  return "unknown";
15
17
  }
@@ -23,89 +25,292 @@ function printHelp() {
23
25
  console.log("AI 视频总结与知识库工具,深度优化 B 站体验,同时支持 YouTube 和本地视频。");
24
26
  console.log("");
25
27
  console.log("Usage:");
26
- console.log(" npx bilisum Show this help");
27
- console.log(" npx bilisum --version Print package version");
28
- console.log(" npx bilisum release Open the latest GitHub release");
29
- console.log(" npx bilisum docker Print a Docker quick-start command");
28
+ console.log(" npx bilisum Start the local BiliSum service");
29
+ console.log(" npx bilisum start [options] Start the local BiliSum service");
30
+ console.log(" npx bilisum doctor Check Python/runtime setup");
31
+ console.log(" npx bilisum --version Print package version");
32
+ console.log(" npx bilisum release Open the latest GitHub release");
33
+ console.log("");
34
+ console.log("Options:");
35
+ console.log(" --host <host> Host, default 127.0.0.1");
36
+ console.log(" --port <port> Port, default 3838");
37
+ console.log(" --python <path> Python 3.12 executable");
38
+ console.log(" --data <path> Data directory");
39
+ console.log(" --env KEY=VALUE Pass an environment variable");
40
+ console.log(" --reinstall Recreate the managed Python venv");
41
+ console.log(" --no-open Do not open the browser");
30
42
  console.log("");
31
43
  console.log(`Latest release: ${RELEASES_URL}`);
32
44
  console.log(`Repository: ${REPO_URL}`);
33
45
  }
34
46
 
35
- function printDockerCommand() {
36
- console.log("Docker quick start:");
37
- console.log("");
38
- console.log(`docker run --rm -it -p 3838:3838 -v bilisum-data:/data ${DOCKER_IMAGE}`);
39
- console.log("");
40
- console.log("Then open http://127.0.0.1:3838");
41
- }
47
+ function parseStartOptions(args) {
48
+ const options = {
49
+ host: process.env.BILISUM_HOST || "127.0.0.1",
50
+ port: process.env.BILISUM_PORT || DEFAULT_PORT,
51
+ python: process.env.BILISUM_PYTHON || "",
52
+ data: process.env.BILISUM_DATA || defaultDataDir(),
53
+ env: [],
54
+ reinstall: false,
55
+ open: true,
56
+ };
42
57
 
43
- function openUrl(url) {
44
- const platform = process.platform;
45
- const command = platform === "win32" ? "cmd" : platform === "darwin" ? "open" : "xdg-open";
46
- const args = platform === "win32" ? ["/c", "start", "", url] : [url];
58
+ for (let index = 0; index < args.length; index += 1) {
59
+ const arg = args[index];
60
+ if (arg === "--host") {
61
+ options.host = readOptionValue(args, ++index, arg);
62
+ } else if (arg === "--port" || arg === "-p") {
63
+ options.port = readOptionValue(args, ++index, arg);
64
+ } else if (arg === "--python") {
65
+ options.python = readOptionValue(args, ++index, arg);
66
+ } else if (arg === "--data") {
67
+ options.data = readOptionValue(args, ++index, arg);
68
+ } else if (arg === "--env" || arg === "-e") {
69
+ options.env.push(readOptionValue(args, ++index, arg));
70
+ } else if (arg === "--reinstall") {
71
+ options.reinstall = true;
72
+ } else if (arg === "--no-open") {
73
+ options.open = false;
74
+ } else {
75
+ throw new Error(`Unknown option: ${arg}`);
76
+ }
77
+ }
47
78
 
48
- try {
49
- const child = spawn(command, args, {
50
- detached: true,
51
- stdio: "ignore",
52
- windowsHide: true,
53
- });
54
- child.on("error", () => {
55
- console.log(url);
56
- });
57
- child.unref();
58
- console.log(`Opened ${url}`);
59
- } catch {
60
- console.log(url);
79
+ return options;
80
+ }
81
+
82
+ function readOptionValue(args, index, option) {
83
+ const value = args[index];
84
+ if (!value || value.startsWith("--")) {
85
+ throw new Error(`${option} requires a value`);
61
86
  }
87
+ return value;
62
88
  }
63
89
 
64
- function isDockerAvailable() {
65
- try {
66
- execFileSync("docker", ["--version"], { stdio: "ignore" });
67
- return true;
68
- } catch {
69
- return false;
90
+ function defaultBaseDir() {
91
+ if (process.env.BILISUM_NPX_HOME) {
92
+ return process.env.BILISUM_NPX_HOME;
70
93
  }
94
+ if (process.platform === "win32") {
95
+ return join(process.env.LOCALAPPDATA || process.env.USERPROFILE || process.cwd(), "BiliSum", "npx");
96
+ }
97
+ return join(process.env.XDG_DATA_HOME || join(process.env.HOME || process.cwd(), ".local", "share"), "bilisum", "npx");
71
98
  }
72
99
 
73
- function main() {
74
- const [command] = process.argv.slice(2);
100
+ function defaultDataDir() {
101
+ return join(defaultBaseDir(), "data");
102
+ }
75
103
 
76
- if (!command || command === "help" || command === "-h" || command === "--help") {
77
- printHelp();
78
- return;
104
+ function venvDir() {
105
+ return join(defaultBaseDir(), `venv-${readVersion()}`);
106
+ }
107
+
108
+ function pythonInVenv() {
109
+ return process.platform === "win32" ? join(venvDir(), "Scripts", "python.exe") : join(venvDir(), "bin", "python");
110
+ }
111
+
112
+ function findPython(explicitPython) {
113
+ const candidates = [];
114
+ if (explicitPython) {
115
+ candidates.push({ command: explicitPython, args: [] });
116
+ }
117
+ if (process.platform === "win32") {
118
+ candidates.push({ command: "py", args: ["-3.12"] });
79
119
  }
120
+ candidates.push({ command: "python3.12", args: [] });
121
+ candidates.push({ command: "python3", args: [] });
122
+ candidates.push({ command: "python", args: [] });
80
123
 
81
- if (command === "version" || command === "-v" || command === "--version") {
82
- console.log(readVersion());
83
- return;
124
+ for (const candidate of candidates) {
125
+ const check = spawnSync(candidate.command, [
126
+ ...candidate.args,
127
+ "-c",
128
+ "import sys; raise SystemExit(0 if sys.version_info >= (3, 12) else 1)",
129
+ ], { stdio: "ignore", windowsHide: true });
130
+ if (check.status === 0) {
131
+ return candidate;
132
+ }
84
133
  }
85
134
 
86
- if (command === "release" || command === "releases" || command === "download") {
87
- openUrl(RELEASES_URL);
88
- return;
135
+ throw new Error("Python 3.12 was not found. Install Python 3.12 or pass --python <path>.");
136
+ }
137
+
138
+ function runChecked(command, args, options = {}) {
139
+ const result = spawnSync(command, args, {
140
+ stdio: "inherit",
141
+ windowsHide: false,
142
+ ...options,
143
+ });
144
+ if (result.error) {
145
+ throw result.error;
89
146
  }
147
+ if (result.status !== 0) {
148
+ throw new Error(`${command} ${args.join(" ")} failed with exit code ${result.status}`);
149
+ }
150
+ }
90
151
 
91
- if (command === "repo" || command === "github") {
92
- openUrl(REPO_URL);
93
- return;
152
+ function ensureRuntime() {
153
+ if (!existsSync(join(RUNTIME_ROOT, "apps", "service", "pyproject.toml"))) {
154
+ throw new Error("BiliSum runtime files are missing from this npm package. Please reinstall bilisum.");
94
155
  }
156
+ if (!existsSync(join(RUNTIME_ROOT, "apps", "web", "static", "index.html"))) {
157
+ throw new Error("BiliSum web static files are missing from this npm package. Please reinstall bilisum.");
158
+ }
159
+ }
160
+
161
+ function ensureVenv(options) {
162
+ ensureRuntime();
163
+ const pythonPath = pythonInVenv();
164
+ const marker = join(venvDir(), ".bilisum-installed");
165
+ if (existsSync(pythonPath) && existsSync(marker) && !options.reinstall) {
166
+ return pythonPath;
167
+ }
168
+
169
+ const sourcePython = findPython(options.python);
170
+ mkdirSync(dirname(venvDir()), { recursive: true });
171
+
172
+ console.log("Preparing BiliSum Python runtime. This may take a minute on first run...");
173
+ runChecked(sourcePython.command, [...sourcePython.args, "-m", "venv", venvDir()]);
174
+
175
+ runChecked(pythonPath, ["-m", "pip", "install", "--upgrade", "pip", "setuptools", "wheel", "hatchling"]);
176
+ runChecked(pythonPath, [
177
+ "-m",
178
+ "pip",
179
+ "install",
180
+ join(RUNTIME_ROOT, "packages", "infra"),
181
+ join(RUNTIME_ROOT, "packages", "core"),
182
+ join(RUNTIME_ROOT, "apps", "service"),
183
+ ]);
184
+
185
+ mkdirSync(venvDir(), { recursive: true });
186
+ require("node:fs").writeFileSync(marker, readVersion(), "utf8");
187
+ return pythonPath;
188
+ }
95
189
 
96
- if (command === "docker") {
97
- printDockerCommand();
98
- if (!isDockerAvailable()) {
99
- console.log("");
100
- console.log("Docker was not detected on this machine.");
190
+ function startService(args) {
191
+ const options = parseStartOptions(args);
192
+ const pythonPath = ensureVenv(options);
193
+ const dataDir = options.data;
194
+ const cacheDir = join(dataDir, "cache");
195
+ const tasksDir = join(dataDir, "tasks");
196
+ mkdirSync(cacheDir, { recursive: true });
197
+ mkdirSync(tasksDir, { recursive: true });
198
+
199
+ const env = {
200
+ ...process.env,
201
+ VIDEO_SUM_HOST: options.host,
202
+ VIDEO_SUM_PORT: options.port,
203
+ VIDEO_SUM_APP_DATA_ROOT: dataDir,
204
+ VIDEO_SUM_DATA_DIR: dataDir,
205
+ VIDEO_SUM_CACHE_DIR: cacheDir,
206
+ VIDEO_SUM_TASKS_DIR: tasksDir,
207
+ VIDEO_SUM_DATABASE_URL: `sqlite:///${join(dataDir, "video_sum.db").replace(/\\/g, "/")}`,
208
+ VIDEO_SUM_WEB_STATIC_DIR: join(RUNTIME_ROOT, "apps", "web", "static"),
209
+ };
210
+ for (const item of options.env) {
211
+ const equals = item.indexOf("=");
212
+ if (equals <= 0) {
213
+ throw new Error(`Invalid --env value: ${item}`);
101
214
  }
102
- return;
215
+ env[item.slice(0, equals)] = item.slice(equals + 1);
216
+ }
217
+
218
+ const url = `http://${options.host}:${options.port}`;
219
+ console.log(`Starting BiliSum at ${url}`);
220
+ console.log(`Data directory: ${dataDir}`);
221
+ console.log("");
222
+
223
+ const child = spawn(pythonPath, ["-m", "video_sum_service"], {
224
+ env,
225
+ stdio: "inherit",
226
+ windowsHide: false,
227
+ });
228
+
229
+ if (options.open) {
230
+ setTimeout(() => openUrl(url), 1800);
103
231
  }
104
232
 
105
- console.error(`Unknown command: ${command}`);
106
- console.error("");
107
- printHelp();
108
- process.exitCode = 1;
233
+ child.on("exit", (code, signal) => {
234
+ if (signal) {
235
+ process.kill(process.pid, signal);
236
+ return;
237
+ }
238
+ process.exitCode = code || 0;
239
+ });
240
+ }
241
+
242
+ function doctor(args) {
243
+ const options = parseStartOptions(args);
244
+ ensureRuntime();
245
+ const python = findPython(options.python);
246
+ console.log(`BiliSum package: ${readVersion()}`);
247
+ console.log(`Python command: ${[python.command, ...python.args].join(" ")}`);
248
+ console.log(`Runtime root: ${RUNTIME_ROOT}`);
249
+ console.log(`Venv: ${venvDir()}`);
250
+ console.log(`Data: ${options.data}`);
251
+ }
252
+
253
+ function openUrl(url) {
254
+ const platform = process.platform;
255
+ const command = platform === "win32" ? "cmd" : platform === "darwin" ? "open" : "xdg-open";
256
+ const args = platform === "win32" ? ["/c", "start", "", url] : [url];
257
+ const child = spawn(command, args, {
258
+ detached: true,
259
+ stdio: "ignore",
260
+ windowsHide: true,
261
+ });
262
+ child.on("error", () => {
263
+ console.log(url);
264
+ });
265
+ child.unref();
266
+ }
267
+
268
+ function main() {
269
+ const [command, ...args] = process.argv.slice(2);
270
+
271
+ try {
272
+ if (!command) {
273
+ startService([]);
274
+ return;
275
+ }
276
+
277
+ if (command === "start" || command === "serve") {
278
+ startService(args);
279
+ return;
280
+ }
281
+
282
+ if (command === "doctor") {
283
+ doctor(args);
284
+ return;
285
+ }
286
+
287
+ if (command === "help" || command === "-h" || command === "--help") {
288
+ printHelp();
289
+ return;
290
+ }
291
+
292
+ if (command === "version" || command === "-v" || command === "--version") {
293
+ console.log(readVersion());
294
+ return;
295
+ }
296
+
297
+ if (command === "release" || command === "releases" || command === "download") {
298
+ openUrl(RELEASES_URL);
299
+ return;
300
+ }
301
+
302
+ if (command === "repo" || command === "github") {
303
+ openUrl(REPO_URL);
304
+ return;
305
+ }
306
+
307
+ throw new Error(`Unknown command: ${command}`);
308
+ } catch (error) {
309
+ console.error(error instanceof Error ? error.message : String(error));
310
+ console.error("");
311
+ printHelp();
312
+ process.exitCode = 1;
313
+ }
109
314
  }
110
315
 
111
316
  main();
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "bilisum",
3
- "version": "1.13.1",
4
- "description": "BiliSum npx launcher for release downloads and Docker usage.",
3
+ "version": "1.13.3",
4
+ "description": "Start the local BiliSum service from npx.",
5
5
  "bin": {
6
6
  "bilisum": "bin/bilisum.js"
7
7
  },
8
8
  "files": [
9
9
  "bin",
10
+ "runtime",
10
11
  "README.md"
11
12
  ],
13
+ "scripts": {
14
+ "prepack": "node scripts/prepare-runtime.js",
15
+ "postpack": "node scripts/cleanup-runtime.js"
16
+ },
12
17
  "engines": {
13
18
  "node": ">=18"
14
19
  },
@@ -0,0 +1 @@
1
+ 1.13.3
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27.0"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "video-sum-service"
7
+ version = "1.13.3"
8
+ description = "Local backend service for the video summarizer."
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "fastapi>=0.115,<1.0",
12
+ "uvicorn[standard]>=0.34,<1.0",
13
+ "pydantic>=2.10,<3.0",
14
+ "video-sum-core",
15
+ "video-sum-infra",
16
+ ]
17
+
18
+ [project.optional-dependencies]
19
+ knowledge = [
20
+ "chromadb>=1.0.0",
21
+ "sentence-transformers>=3.0",
22
+ ]
23
+
24
+ [project.scripts]
25
+ video-sum-service = "video_sum_service.main:run"
26
+ video-sum-transcribe-worker = "video_sum_service.transcribe_worker:run"
27
+
28
+ [tool.hatch.build.targets.wheel]
29
+ packages = ["src/video_sum_service"]
@@ -0,0 +1 @@
1
+ """Local backend service package."""
@@ -0,0 +1,5 @@
1
+ from video_sum_service.main import run
2
+
3
+
4
+ if __name__ == "__main__":
5
+ run()