@wu529778790/open-im 1.10.2-beta.4 → 1.10.2-beta.5
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 +5 -3
- package/README.zh-CN.md +5 -3
- package/dist/cli.js +1 -1
- package/dist/config-web-static.d.ts +1 -1
- package/dist/config-web-static.js +7 -4
- package/dist/config-web.js +3 -4
- package/package.json +4 -3
- package/dist/config-web-page.d.ts +0 -5
- package/dist/config-web-page.js +0 -32
- package/dist/config-web-page.test.d.ts +0 -1
- package/dist/config-web-page.test.js +0 -26
package/README.md
CHANGED
|
@@ -58,13 +58,13 @@ The published npm package includes **`web/dist`**. `open-im start` or `open-im d
|
|
|
58
58
|
- Default dashboard URL: **`http://127.0.0.1:39282`** (respects **`OPEN_IM_WEB_PORT`**)
|
|
59
59
|
- Override the URL shown/opened by the CLI with **`OPEN_IM_PUBLIC_WEB_URL`** (e.g. behind a reverse proxy)
|
|
60
60
|
|
|
61
|
-
If you install from source without running
|
|
61
|
+
If you install from source without running **`npm run build`** (which runs `web:build` + `tsc`), `web/dist` may be missing and **`GET /`** returns **503** until you build. Use **`npm run build:ts`** for TypeScript-only iteration (skips the web bundle).
|
|
62
62
|
|
|
63
63
|
### Local HTTP service
|
|
64
64
|
|
|
65
65
|
The running process listens on **`OPEN_IM_WEB_PORT`** (default **39282**):
|
|
66
66
|
|
|
67
|
-
- **`GET /`** — built-in dashboard when `web/dist` is present; otherwise a
|
|
67
|
+
- **`GET /`** — built-in dashboard when `web/dist` is present; otherwise **503** with a short plain-text hint
|
|
68
68
|
- **`/assets/*`** — static assets for the bundled SPA (when present)
|
|
69
69
|
- **`/api/*`** — JSON API used by the dashboard
|
|
70
70
|
|
|
@@ -88,7 +88,9 @@ In the repository:
|
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
90
|
npm run web:dev # Vite dev server; proxies /api to 127.0.0.1:39282
|
|
91
|
-
npm run
|
|
91
|
+
npm run build # web:build + tsc (use before running the compiled CLI with dashboard)
|
|
92
|
+
npm run build:ts # tsc only (no web/dist refresh)
|
|
93
|
+
npm run web:build # web/dist only
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
More detail: [CLAUDE.md](./CLAUDE.md), [AGENTS.md](./AGENTS.md).
|
package/README.zh-CN.md
CHANGED
|
@@ -58,13 +58,13 @@ open-im start
|
|
|
58
58
|
- 默认控制台地址:本机 **`http://127.0.0.1:39282`**(随 **`OPEN_IM_WEB_PORT`** 变化)
|
|
59
59
|
- 若需自定义打开的链接(例如反向代理后的地址),可设置 **`OPEN_IM_PUBLIC_WEB_URL`**
|
|
60
60
|
|
|
61
|
-
若从源码安装且未执行
|
|
61
|
+
若从源码安装且未执行 **`npm run build`**(内含 `web:build`),可能没有 `web/dist`,此时 **`GET /`** 会返回 **503** 直至构建完成。仅改 TypeScript 时可使用 **`npm run build:ts`** 跳过前端构建。
|
|
62
62
|
|
|
63
63
|
### 本机 HTTP 服务
|
|
64
64
|
|
|
65
65
|
进程监听 **`OPEN_IM_WEB_PORT`**(默认 **39282**):
|
|
66
66
|
|
|
67
|
-
- **`GET /`** — 有 `web/dist`
|
|
67
|
+
- **`GET /`** — 有 `web/dist` 时返回内置仪表盘;否则 **503** 纯文本提示
|
|
68
68
|
- **`/assets/*`** — 内置前端静态资源(有构建产物时)
|
|
69
69
|
- **`/api/*`** — JSON API
|
|
70
70
|
|
|
@@ -86,7 +86,9 @@ export OPEN_IM_WEB_HOST=0.0.0.0
|
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
88
|
npm run web:dev # Vite;将 /api 代理到 127.0.0.1:39282
|
|
89
|
-
npm run
|
|
89
|
+
npm run build # web:build + tsc;发布前与日常请用此命令
|
|
90
|
+
npm run build:ts # 仅 tsc(不更新 web/dist)
|
|
91
|
+
npm run web:build # 仅构建 web/dist
|
|
90
92
|
```
|
|
91
93
|
|
|
92
94
|
更多开发说明见 [CLAUDE.md](./CLAUDE.md)、[AGENTS.md](./AGENTS.md)。
|
package/dist/cli.js
CHANGED
|
@@ -142,7 +142,7 @@ async function cmdDashboard() {
|
|
|
142
142
|
const publicUrl = getPublicWebDashboardUrl();
|
|
143
143
|
console.log(`\nWeb dashboard: ${publicUrl}`);
|
|
144
144
|
if (!getWebDistDir()) {
|
|
145
|
-
console.log("Note: web/dist not found —
|
|
145
|
+
console.log("Note: web/dist not found — GET / returns 503 until you run npm run build (or npm run web:build), or use the published npm package.");
|
|
146
146
|
}
|
|
147
147
|
if (server.loginUrl) {
|
|
148
148
|
console.log(`Remote login: ${server.loginUrl}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import type { OutgoingHttpHeaders } from "node:http";
|
|
3
|
-
/** npm 包内 `web/dist
|
|
3
|
+
/** npm 包内 `web/dist`(相对本文件 `../web/dist`;开发时亦可匹配 `process.cwd()/web/dist`) */
|
|
4
4
|
export declare function getWebDistDir(): string | null;
|
|
5
5
|
/**
|
|
6
6
|
* 若存在内置 `web/dist`,则对 GET 返回对应静态文件(含 `/` → index.html)。
|
|
@@ -12,12 +12,15 @@ const MIME = {
|
|
|
12
12
|
".woff2": "font/woff2",
|
|
13
13
|
".map": "application/json",
|
|
14
14
|
};
|
|
15
|
-
/** npm 包内 `web/dist
|
|
15
|
+
/** npm 包内 `web/dist`(相对本文件 `../web/dist`;开发时亦可匹配 `process.cwd()/web/dist`) */
|
|
16
16
|
export function getWebDistDir() {
|
|
17
17
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const
|
|
19
|
-
if (existsSync(join(
|
|
20
|
-
return
|
|
18
|
+
const fromPackage = join(here, "..", "web", "dist");
|
|
19
|
+
if (existsSync(join(fromPackage, "index.html")))
|
|
20
|
+
return fromPackage;
|
|
21
|
+
const fromCwd = join(process.cwd(), "web", "dist");
|
|
22
|
+
if (resolve(fromCwd) !== resolve(fromPackage) && existsSync(join(fromCwd, "index.html")))
|
|
23
|
+
return fromCwd;
|
|
21
24
|
return null;
|
|
22
25
|
}
|
|
23
26
|
function resolveUnderRoot(root, pathname) {
|
package/dist/config-web.js
CHANGED
|
@@ -8,7 +8,6 @@ import { DWClient } from "dingtalk-stream";
|
|
|
8
8
|
import { WEB_CONFIG_PORT, getPublicWebDashboardUrl } from "./constants.js";
|
|
9
9
|
import { CONFIG_PATH, getClaudeConfigHome, loadClaudeSettingsEnv, saveClaudeSettingsEnv, loadConfig, loadFileConfig, saveFileConfig } from "./config.js";
|
|
10
10
|
import { getWebDistDir, tryServeDashboardStatic } from "./config-web-static.js";
|
|
11
|
-
import { getConfigWebLandingHtml } from "./config-web-page.js";
|
|
12
11
|
import { getServiceStatus, startBackgroundService, stopBackgroundService } from "./service-control.js";
|
|
13
12
|
import { initWeWork, stopWeWork } from "./wework/client.js";
|
|
14
13
|
import { createLogger } from "./logger.js";
|
|
@@ -806,8 +805,8 @@ export async function startWebConfigServer(options) {
|
|
|
806
805
|
if (request.method === "GET" && requestUrl.pathname === "/") {
|
|
807
806
|
if (tryServeDashboardStatic(requestUrl, request, response, mergeCors))
|
|
808
807
|
return;
|
|
809
|
-
response.writeHead(
|
|
810
|
-
response.end(
|
|
808
|
+
response.writeHead(503, mergeCors(request, { "content-type": "text/plain; charset=utf-8" }));
|
|
809
|
+
response.end("open-im: web/dist is missing. Run npm run build in the repository root, then restart.\n");
|
|
811
810
|
return;
|
|
812
811
|
}
|
|
813
812
|
if (request.method === "GET" && requestUrl.pathname === "/api/config") {
|
|
@@ -1067,7 +1066,7 @@ export async function runWebConfigFlow(options) {
|
|
|
1067
1066
|
log.info("Full dashboard UI is bundled (same origin as API).");
|
|
1068
1067
|
}
|
|
1069
1068
|
else {
|
|
1070
|
-
log.info(`API base: ${apiUrl} — install has no web/dist;
|
|
1069
|
+
log.info(`API base: ${apiUrl} — install has no web/dist; GET / returns 503 until you run npm run build.`);
|
|
1071
1070
|
}
|
|
1072
1071
|
if (started.loginUrl) {
|
|
1073
1072
|
log.info(`Remote login (first visit): ${started.loginUrl}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wu529778790/open-im",
|
|
3
|
-
"version": "1.10.2-beta.
|
|
3
|
+
"version": "1.10.2-beta.5",
|
|
4
4
|
"description": "Multi-platform IM bridge for AI CLI tools (Claude, Codex, CodeBuddy)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"LICENSE"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc",
|
|
17
|
+
"build": "npm run web:build && tsc",
|
|
18
|
+
"build:ts": "tsc",
|
|
18
19
|
"dev": "tsx src/index.ts",
|
|
19
20
|
"init": "tsx src/cli.ts init",
|
|
20
21
|
"start": "node dist/cli.js start",
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
"lint": "eslint src",
|
|
27
28
|
"web:build": "npm --prefix web run build",
|
|
28
29
|
"web:dev": "npm --prefix web run dev",
|
|
29
|
-
"prepublishOnly": "npm run
|
|
30
|
+
"prepublishOnly": "npm run build"
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
|
32
33
|
"dingtalk",
|
package/dist/config-web-page.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { getPublicWebDashboardUrl } from "./constants.js";
|
|
2
|
-
function escapeHtml(s) {
|
|
3
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* 无内置 `web/dist` 时的极简落地页(例如从源码运行且未执行 web:build)。
|
|
7
|
-
* 发布到 npm 的包通常包含构建产物,由 config-web-static 直接提供 SPA。
|
|
8
|
-
*/
|
|
9
|
-
export function getConfigWebLandingHtml() {
|
|
10
|
-
const web = escapeHtml(getPublicWebDashboardUrl());
|
|
11
|
-
return `<!doctype html>
|
|
12
|
-
<html lang="en">
|
|
13
|
-
<head>
|
|
14
|
-
<meta charset="utf-8" />
|
|
15
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16
|
-
<title>open-im</title>
|
|
17
|
-
<style>
|
|
18
|
-
body { font-family: system-ui, -apple-system, Segoe UI, sans-serif; max-width: 40rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.55; color: #111827; background: #f9fafb; }
|
|
19
|
-
a { color: #2563eb; }
|
|
20
|
-
code { font-size: 0.9em; background: #e5e7eb; padding: 0.15em 0.4em; border-radius: 4px; word-break: break-all; }
|
|
21
|
-
h1 { font-size: 1.25rem; }
|
|
22
|
-
</style>
|
|
23
|
-
</head>
|
|
24
|
-
<body>
|
|
25
|
-
<h1>open-im</h1>
|
|
26
|
-
<p>No bundled dashboard (<code>web/dist</code> missing). Run <code>npm run web:build</code> in the repo, or install the published npm package.</p>
|
|
27
|
-
<p>Console URL when bundled: <a href="${web}">${web}</a></p>
|
|
28
|
-
<p>API base: <code id="api"></code></p>
|
|
29
|
-
<script>document.getElementById("api").textContent = location.origin;</script>
|
|
30
|
-
</body>
|
|
31
|
-
</html>`;
|
|
32
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { getConfigWebLandingHtml } from "./config-web-page.js";
|
|
3
|
-
import { getDefaultLocalDashboardUrl, getPublicWebDashboardUrl } from "./constants.js";
|
|
4
|
-
describe("config web landing page", () => {
|
|
5
|
-
it("does not embed legacy full-dashboard markers", () => {
|
|
6
|
-
const html = getConfigWebLandingHtml();
|
|
7
|
-
expect(html).not.toContain("__PAGE_TEXTS__");
|
|
8
|
-
expect(html).not.toContain("heroBodyFull");
|
|
9
|
-
expect(html).not.toContain("Local AI bridge");
|
|
10
|
-
});
|
|
11
|
-
it("links to the dashboard URL and explains missing bundle", () => {
|
|
12
|
-
const url = getPublicWebDashboardUrl();
|
|
13
|
-
const html = getConfigWebLandingHtml();
|
|
14
|
-
expect(html).toContain(url);
|
|
15
|
-
expect(html).toContain("web/dist");
|
|
16
|
-
});
|
|
17
|
-
it("includes API origin script hook", () => {
|
|
18
|
-
const html = getConfigWebLandingHtml();
|
|
19
|
-
expect(html).toContain('id="api"');
|
|
20
|
-
expect(html).toContain("location.origin");
|
|
21
|
-
});
|
|
22
|
-
it("defaults public dashboard to local http", () => {
|
|
23
|
-
expect(getDefaultLocalDashboardUrl()).toMatch(/^http:\/\/127\.0\.0\.1:\d+$/);
|
|
24
|
-
expect(getPublicWebDashboardUrl()).toMatch(/^http:\/\/127\.0\.0\.1:\d+$/);
|
|
25
|
-
});
|
|
26
|
-
});
|