bilisum 1.13.2 → 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 +157 -76
  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` starts BiliSum from npx with the official Docker image.
3
+ `bilisum` starts the local BiliSum browser service from npx.
4
4
 
5
5
  ```bash
6
6
  npx bilisum
7
- npx bilisum start --port 3839 --pull
8
- npx bilisum docker
7
+ npx bilisum start --port 3839
8
+ npx bilisum doctor
9
9
  ```
10
10
 
11
- Docker Desktop is required. The desktop app is still distributed through GitHub Releases.
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,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { execFileSync, spawn, spawnSync } = 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 DEFAULT_IMAGE = "lycohana/bilisum:latest";
10
9
  const DEFAULT_PORT = "3838";
10
+ const PACKAGE_ROOT = join(__dirname, "..");
11
+ const RUNTIME_ROOT = join(PACKAGE_ROOT, "runtime");
11
12
 
12
13
  function readVersion() {
13
- const packagePath = join(__dirname, "..", "package.json");
14
+ const packagePath = join(PACKAGE_ROOT, "package.json");
14
15
  if (!existsSync(packagePath)) {
15
16
  return "unknown";
16
17
  }
@@ -24,20 +25,19 @@ function printHelp() {
24
25
  console.log("AI 视频总结与知识库工具,深度优化 B 站体验,同时支持 YouTube 和本地视频。");
25
26
  console.log("");
26
27
  console.log("Usage:");
27
- console.log(" npx bilisum Start BiliSum with Docker");
28
- console.log(" npx bilisum start [options] Start BiliSum with Docker");
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");
29
31
  console.log(" npx bilisum --version Print package version");
30
32
  console.log(" npx bilisum release Open the latest GitHub release");
31
- console.log(" npx bilisum docker Print the Docker command");
32
33
  console.log("");
33
34
  console.log("Options:");
34
- console.log(" --port <port> Host port, default 3838");
35
- console.log(" --image <image> Docker image, default lycohana/bilisum:latest");
36
- console.log(" --name <name> Container name, default bilisum");
37
- console.log(" --data <volume-or-path> Data volume/path, default bilisum-data");
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");
38
39
  console.log(" --env KEY=VALUE Pass an environment variable");
39
- console.log(" --pull Pull the image before starting");
40
- console.log(" --detach, -d Run container in background");
40
+ console.log(" --reinstall Recreate the managed Python venv");
41
41
  console.log(" --no-open Do not open the browser");
42
42
  console.log("");
43
43
  console.log(`Latest release: ${RELEASES_URL}`);
@@ -46,32 +46,29 @@ function printHelp() {
46
46
 
47
47
  function parseStartOptions(args) {
48
48
  const options = {
49
+ host: process.env.BILISUM_HOST || "127.0.0.1",
49
50
  port: process.env.BILISUM_PORT || DEFAULT_PORT,
50
- image: process.env.BILISUM_DOCKER_IMAGE || DEFAULT_IMAGE,
51
- name: process.env.BILISUM_CONTAINER_NAME || "bilisum",
52
- data: process.env.BILISUM_DATA || "bilisum-data",
51
+ python: process.env.BILISUM_PYTHON || "",
52
+ data: process.env.BILISUM_DATA || defaultDataDir(),
53
53
  env: [],
54
- pull: false,
55
- detach: false,
54
+ reinstall: false,
56
55
  open: true,
57
56
  };
58
57
 
59
58
  for (let index = 0; index < args.length; index += 1) {
60
59
  const arg = args[index];
61
- if (arg === "--port" || arg === "-p") {
60
+ if (arg === "--host") {
61
+ options.host = readOptionValue(args, ++index, arg);
62
+ } else if (arg === "--port" || arg === "-p") {
62
63
  options.port = readOptionValue(args, ++index, arg);
63
- } else if (arg === "--image") {
64
- options.image = readOptionValue(args, ++index, arg);
65
- } else if (arg === "--name") {
66
- options.name = readOptionValue(args, ++index, arg);
64
+ } else if (arg === "--python") {
65
+ options.python = readOptionValue(args, ++index, arg);
67
66
  } else if (arg === "--data") {
68
67
  options.data = readOptionValue(args, ++index, arg);
69
68
  } else if (arg === "--env" || arg === "-e") {
70
69
  options.env.push(readOptionValue(args, ++index, arg));
71
- } else if (arg === "--pull") {
72
- options.pull = true;
73
- } else if (arg === "--detach" || arg === "-d") {
74
- options.detach = true;
70
+ } else if (arg === "--reinstall") {
71
+ options.reinstall = true;
75
72
  } else if (arg === "--no-open") {
76
73
  options.open = false;
77
74
  } else {
@@ -90,68 +87,141 @@ function readOptionValue(args, index, option) {
90
87
  return value;
91
88
  }
92
89
 
93
- function dockerCommand(options) {
94
- const args = ["run", "--rm"];
95
- if (options.detach) {
96
- args.push("-d");
97
- } else {
98
- args.push("-it");
99
- }
100
-
101
- args.push("--name", options.name);
102
- args.push("-p", `${options.port}:3838`);
103
- args.push("-v", `${options.data}:/data`);
104
-
105
- const envKeys = [
106
- "VIDEO_SUM_LLM_ENABLED",
107
- "VIDEO_SUM_LLM_BASE_URL",
108
- "VIDEO_SUM_LLM_MODEL",
109
- "VIDEO_SUM_LLM_API_KEY",
110
- "VIDEO_SUM_TRANSCRIPTION_PROVIDER",
111
- "VIDEO_SUM_SILICONFLOW_ASR_BASE_URL",
112
- "VIDEO_SUM_SILICONFLOW_ASR_MODEL",
113
- "VIDEO_SUM_SILICONFLOW_ASR_API_KEY",
114
- "VIDEO_SUM_YTDLP_COOKIES_FILE",
115
- ];
116
- for (const key of envKeys) {
117
- if (process.env[key]) {
118
- args.push("-e", `${key}=${process.env[key]}`);
119
- }
90
+ function defaultBaseDir() {
91
+ if (process.env.BILISUM_NPX_HOME) {
92
+ return process.env.BILISUM_NPX_HOME;
120
93
  }
121
- for (const value of options.env) {
122
- args.push("-e", value);
94
+ if (process.platform === "win32") {
95
+ return join(process.env.LOCALAPPDATA || process.env.USERPROFILE || process.cwd(), "BiliSum", "npx");
123
96
  }
97
+ return join(process.env.XDG_DATA_HOME || join(process.env.HOME || process.cwd(), ".local", "share"), "bilisum", "npx");
98
+ }
99
+
100
+ function defaultDataDir() {
101
+ return join(defaultBaseDir(), "data");
102
+ }
103
+
104
+ function venvDir() {
105
+ return join(defaultBaseDir(), `venv-${readVersion()}`);
106
+ }
124
107
 
125
- args.push(options.image);
126
- return args;
108
+ function pythonInVenv() {
109
+ return process.platform === "win32" ? join(venvDir(), "Scripts", "python.exe") : join(venvDir(), "bin", "python");
127
110
  }
128
111
 
129
- function printDockerCommand(options = parseStartOptions([])) {
130
- console.log(["docker", ...dockerCommand(options)].join(" "));
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"] });
119
+ }
120
+ candidates.push({ command: "python3.12", args: [] });
121
+ candidates.push({ command: "python3", args: [] });
122
+ candidates.push({ command: "python", args: [] });
123
+
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
+ }
133
+ }
134
+
135
+ throw new Error("Python 3.12 was not found. Install Python 3.12 or pass --python <path>.");
131
136
  }
132
137
 
133
- function ensureDocker() {
134
- const result = spawnSync("docker", ["--version"], { stdio: "ignore", windowsHide: true });
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;
146
+ }
135
147
  if (result.status !== 0) {
136
- throw new Error("Docker was not detected. Install Docker Desktop, then run npx bilisum again.");
148
+ throw new Error(`${command} ${args.join(" ")} failed with exit code ${result.status}`);
149
+ }
150
+ }
151
+
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.");
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.");
137
158
  }
138
159
  }
139
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
+ }
189
+
140
190
  function startService(args) {
141
191
  const options = parseStartOptions(args);
142
- ensureDocker();
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 });
143
198
 
144
- if (options.pull) {
145
- execFileSync("docker", ["pull", options.image], { stdio: "inherit" });
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}`);
214
+ }
215
+ env[item.slice(0, equals)] = item.slice(equals + 1);
146
216
  }
147
217
 
148
- const url = `http://127.0.0.1:${options.port}`;
218
+ const url = `http://${options.host}:${options.port}`;
149
219
  console.log(`Starting BiliSum at ${url}`);
150
- console.log("");
151
- printDockerCommand(options);
220
+ console.log(`Data directory: ${dataDir}`);
152
221
  console.log("");
153
222
 
154
- const child = spawn("docker", dockerCommand(options), {
223
+ const child = spawn(pythonPath, ["-m", "video_sum_service"], {
224
+ env,
155
225
  stdio: "inherit",
156
226
  windowsHide: false,
157
227
  });
@@ -169,6 +239,17 @@ function startService(args) {
169
239
  });
170
240
  }
171
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
+
172
253
  function openUrl(url) {
173
254
  const platform = process.platform;
174
255
  const command = platform === "win32" ? "cmd" : platform === "darwin" ? "open" : "xdg-open";
@@ -198,6 +279,11 @@ function main() {
198
279
  return;
199
280
  }
200
281
 
282
+ if (command === "doctor") {
283
+ doctor(args);
284
+ return;
285
+ }
286
+
201
287
  if (command === "help" || command === "-h" || command === "--help") {
202
288
  printHelp();
203
289
  return;
@@ -218,11 +304,6 @@ function main() {
218
304
  return;
219
305
  }
220
306
 
221
- if (command === "docker") {
222
- printDockerCommand(parseStartOptions(args));
223
- return;
224
- }
225
-
226
307
  throw new Error(`Unknown command: ${command}`);
227
308
  } catch (error) {
228
309
  console.error(error instanceof Error ? error.message : String(error));
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "bilisum",
3
- "version": "1.13.2",
4
- "description": "Start BiliSum from npx with the official Docker image.",
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()