@wu529778790/open-im 1.9.3-beta.7 → 1.9.3-beta.8
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.
|
@@ -40,7 +40,7 @@ export declare const PAGE_TEXTS: {
|
|
|
40
40
|
readonly serviceIdleMeta: "Bridge has not been started yet";
|
|
41
41
|
readonly listSeparator: ", ";
|
|
42
42
|
readonly platformsTitle: "Platforms";
|
|
43
|
-
readonly platformsHint: "Disabled platforms keep
|
|
43
|
+
readonly platformsHint: "Follow the setup checklist on Overview first. Disabled platforms still keep saved values.";
|
|
44
44
|
readonly enabled: "Enabled";
|
|
45
45
|
readonly readyState: "Ready";
|
|
46
46
|
readonly setupRequired: "Setup required";
|
|
@@ -81,7 +81,7 @@ export declare const PAGE_TEXTS: {
|
|
|
81
81
|
readonly optional: "Optional";
|
|
82
82
|
readonly commaSeparatedIds: "Comma-separated IDs";
|
|
83
83
|
readonly aiTitle: "AI Tooling";
|
|
84
|
-
readonly aiHint: "";
|
|
84
|
+
readonly aiHint: "Pick the default tool first. Claude SDK uses API keys in ~/.claude/settings.json (editable below). Codex / CodeBuddy need a CLI path.";
|
|
85
85
|
readonly claudeNote: "Claude credentials are still read from environment variables or ~/.claude/settings.json. This page manages local bridge config, not Claude account auth.";
|
|
86
86
|
readonly aiCommonTitle: "Shared defaults";
|
|
87
87
|
readonly aiCommonHint: "Choose the default AI tool first. Tool-specific fields are shown below.";
|
|
@@ -134,6 +134,36 @@ export declare const PAGE_TEXTS: {
|
|
|
134
134
|
readonly saveBtn: "Save";
|
|
135
135
|
readonly jsonValid: "Valid JSON";
|
|
136
136
|
readonly jsonInvalid: "Invalid JSON: {error}";
|
|
137
|
+
readonly wizardTitle: "First-time setup";
|
|
138
|
+
readonly wizardStep1Title: "Connect an IM channel";
|
|
139
|
+
readonly wizardStep1Desc: "Enable at least one platform below and fill every required field. Use Check config when available.";
|
|
140
|
+
readonly wizardStep2Title: "Set the default AI tool";
|
|
141
|
+
readonly wizardStep2Desc: "Claude SDK: API keys live in ~/.claude/settings.json (expand on this page). Codex / CodeBuddy: set the CLI path in the AI section.";
|
|
142
|
+
readonly wizardStep3Title: "Validate and save";
|
|
143
|
+
readonly wizardStep3Desc: "Click Validate, then Save config. Fix any errors shown in the banner above.";
|
|
144
|
+
readonly wizardStep4Title: "Start the bridge";
|
|
145
|
+
readonly wizardStep4Desc: "Open Service and click Start bridge. If it exits, read ~/.open-im/logs.";
|
|
146
|
+
readonly wizardStatusDone: "Done";
|
|
147
|
+
readonly wizardStatusTodo: "To do";
|
|
148
|
+
readonly wizardJumpPlatforms: "Open Platforms";
|
|
149
|
+
readonly wizardJumpAi: "Open AI";
|
|
150
|
+
readonly wizardJumpService: "Open Service";
|
|
151
|
+
readonly validationNoPlatformEnabled: "Enable at least one IM platform and fill its required credentials before saving.";
|
|
152
|
+
readonly validationPlatformIncomplete: "Platform \"{platform}\" is enabled but these required fields are empty: {fields}";
|
|
153
|
+
readonly validationAiCodexNoCli: "Default AI is Codex but Codex CLI path is empty. Set it under AI Tooling or change the default tool.";
|
|
154
|
+
readonly validationAiCodebuddyNoCli: "Default AI is CodeBuddy but CodeBuddy CLI path is empty. Set it under AI Tooling or change the default tool.";
|
|
155
|
+
readonly onboardingTitle: "Welcome to open-im";
|
|
156
|
+
readonly onboardingDismiss: "Got it";
|
|
157
|
+
readonly onboardingReadme: "README (setup)";
|
|
158
|
+
readonly onboardingBody: "<p><strong>open-im</strong> bridges Telegram, Feishu, QQ, WeWork, DingTalk, and WorkBuddy to Claude / Codex / CodeBuddy on your machine.</p><ol style=\"margin:12px 0 12px 18px;line-height:1.65\"><li>Pick <strong>one</strong> chat app in <strong>Platforms</strong> and paste credentials (see hints under each field).</li><li>Set the <strong>default AI</strong> and, for Claude SDK, API keys in <strong>~/.claude/settings.json</strong> on this page.</li><li>Use <strong>Validate</strong> then <strong>Save config</strong>, then <strong>Start bridge</strong> under Service.</li><li>CLI alternative: run <code style=\"background:var(--bg-tertiary);padding:2px 6px;border-radius:4px\">open-im init</code> in a terminal.</li></ol>";
|
|
159
|
+
readonly tipTelegramToken: "From Telegram, open <a href=\"https://t.me/BotFather\" target=\"_blank\" rel=\"noopener\">@BotFather</a> → /newbot → copy the token.";
|
|
160
|
+
readonly tipFeishuAppId: "Feishu Open Platform → your app → Credentials → App ID.";
|
|
161
|
+
readonly tipFeishuSecret: "Same page → App Secret (click show / reset if needed).";
|
|
162
|
+
readonly tipQqAppId: "<a href=\"https://bot.q.qq.com\" target=\"_blank\" rel=\"noopener\">QQ bot console</a> → your bot → App ID.";
|
|
163
|
+
readonly tipQqSecret: "Same console → App Secret.";
|
|
164
|
+
readonly tipWeworkCorp: "WeCom admin → app → view Corp ID (or smart-bot Bot ID) and Secret.";
|
|
165
|
+
readonly tipDingtalkClient: "<a href=\"https://open-dev.dingtalk.com\" target=\"_blank\" rel=\"noopener\">DingTalk Open Platform</a> → internal app → App Key & App Secret.";
|
|
166
|
+
readonly tipWorkbuddyToken: "Use terminal <code>open-im init</code> for WorkBuddy OAuth, or paste tokens from CodeBuddy login.";
|
|
137
167
|
};
|
|
138
168
|
readonly zh: {
|
|
139
169
|
readonly pageTitle: "open-im 本地控制台";
|
|
@@ -174,7 +204,7 @@ export declare const PAGE_TEXTS: {
|
|
|
174
204
|
readonly serviceIdleMeta: "桥接服务尚未启动";
|
|
175
205
|
readonly listSeparator: "、";
|
|
176
206
|
readonly platformsTitle: "平台配置";
|
|
177
|
-
readonly platformsHint: "
|
|
207
|
+
readonly platformsHint: "建议先在概览页按引导步骤操作。禁用的平台仍保留已保存的值。";
|
|
178
208
|
readonly enabled: "启用";
|
|
179
209
|
readonly readyState: "已就绪";
|
|
180
210
|
readonly setupRequired: "需要完成配置";
|
|
@@ -214,7 +244,7 @@ export declare const PAGE_TEXTS: {
|
|
|
214
244
|
readonly optional: "可选";
|
|
215
245
|
readonly commaSeparatedIds: "多个 ID 用逗号分隔";
|
|
216
246
|
readonly aiTitle: "AI 工具配置";
|
|
217
|
-
readonly aiHint: "";
|
|
247
|
+
readonly aiHint: "先选默认 AI。Claude SDK 的 API Key 写在 ~/.claude/settings.json(下方可编辑)。Codex / CodeBuddy 需填 CLI 路径。";
|
|
218
248
|
readonly claudeNote: "Claude 凭证仍然从环境变量或 ~/.claude/settings.json 读取。这个页面只管理本地桥接配置,不负责 Claude 账号登录。";
|
|
219
249
|
readonly aiCommonTitle: "公共默认配置";
|
|
220
250
|
readonly aiCommonHint: "先选择默认 AI 工具,下方再显示对应的工具专属配置。";
|
|
@@ -264,5 +294,35 @@ export declare const PAGE_TEXTS: {
|
|
|
264
294
|
readonly saveBtn: "保存";
|
|
265
295
|
readonly jsonValid: "JSON 有效";
|
|
266
296
|
readonly jsonInvalid: "JSON 无效:{error}";
|
|
297
|
+
readonly wizardTitle: "首次使用引导";
|
|
298
|
+
readonly wizardStep1Title: "接入一个 IM 渠道";
|
|
299
|
+
readonly wizardStep1Desc: "在下方启用至少一个平台,并填写所有必填项。有条件时用「校验配置」测试凭证。";
|
|
300
|
+
readonly wizardStep2Title: "设置默认 AI 工具";
|
|
301
|
+
readonly wizardStep2Desc: "Claude SDK:API Key 写在 ~/.claude/settings.json(本页可展开编辑)。Codex / CodeBuddy:在 AI 区填 CLI 路径。";
|
|
302
|
+
readonly wizardStep3Title: "校验并保存";
|
|
303
|
+
readonly wizardStep3Desc: "先点「校验」,再点「保存配置」。按顶部提示修复错误。";
|
|
304
|
+
readonly wizardStep4Title: "启动桥接";
|
|
305
|
+
readonly wizardStep4Desc: "到「服务」区点「启动桥接」。若马上退出,查 ~/.open-im/logs 日志。";
|
|
306
|
+
readonly wizardStatusDone: "已完成";
|
|
307
|
+
readonly wizardStatusTodo: "待完成";
|
|
308
|
+
readonly wizardJumpPlatforms: "打开平台配置";
|
|
309
|
+
readonly wizardJumpAi: "打开 AI 配置";
|
|
310
|
+
readonly wizardJumpService: "打开服务控制";
|
|
311
|
+
readonly validationNoPlatformEnabled: "保存前请至少启用一个 IM 平台,并填完必填凭证。";
|
|
312
|
+
readonly validationPlatformIncomplete: "平台「{platform}」已启用,但以下必填项为空:{fields}";
|
|
313
|
+
readonly validationAiCodexNoCli: "默认 AI 为 Codex,但 Codex CLI 路径为空。请在 AI 区填写,或改默认工具。";
|
|
314
|
+
readonly validationAiCodebuddyNoCli: "默认 AI 为 CodeBuddy,但 CodeBuddy CLI 路径为空。请在 AI 区填写,或改默认工具。";
|
|
315
|
+
readonly onboardingTitle: "欢迎使用 open-im";
|
|
316
|
+
readonly onboardingDismiss: "知道了";
|
|
317
|
+
readonly onboardingReadme: "README(部署说明)";
|
|
318
|
+
readonly onboardingBody: "<p><strong>open-im</strong> 在本机把 Telegram、飞书、QQ、企微、钉钉、WorkBuddy 等渠道连到 Claude / Codex / CodeBuddy。</p><ol style=\"margin:12px 0 12px 18px;line-height:1.65\"><li>在<strong>平台配置</strong>选一个聊天应用,按字段下方提示填凭证。</li><li>设<strong>默认 AI</strong>;用 Claude SDK 时把 API Key 写进<strong>~/.claude/settings.json</strong>(本页可编辑)。</li><li>先<strong>校验</strong>再<strong>保存配置</strong>,然后到<strong>服务</strong>启动桥接。</li><li>也可在终端运行 <code style=\"background:var(--bg-tertiary);padding:2px 6px;border-radius:4px\">open-im init</code> 交互配置。</li></ol>";
|
|
319
|
+
readonly tipTelegramToken: "在 Telegram 搜 <a href=\"https://t.me/BotFather\" target=\"_blank\" rel=\"noopener\">@BotFather</a>,发 /newbot 创建机器人后复制 Token。";
|
|
320
|
+
readonly tipFeishuAppId: "飞书开放平台 → 应用 → 凭证与基础信息 → App ID。";
|
|
321
|
+
readonly tipFeishuSecret: "同一页 App Secret(可重置后查看)。";
|
|
322
|
+
readonly tipQqAppId: "<a href=\"https://bot.q.qq.com\" target=\"_blank\" rel=\"noopener\">QQ 开放平台</a> → 机器人 → App ID。";
|
|
323
|
+
readonly tipQqSecret: "同一处获取 App Secret。";
|
|
324
|
+
readonly tipWeworkCorp: "企业微信管理后台 → 应用 → 查省 Corp ID / 智能机器人 Bot ID 与 Secret。";
|
|
325
|
+
readonly tipDingtalkClient: "<a href=\"https://open-dev.dingtalk.com\" target=\"_blank\" rel=\"noopener\">钉钉开放平台</a> → 企业内部应用 → AppKey / AppSecret。";
|
|
326
|
+
readonly tipWorkbuddyToken: "建议在终端运行 <code>open-im init</code> 完成 WorkBuddy 授权;或粘贴 CodeBuddy 登录后的 Token。";
|
|
267
327
|
};
|
|
268
328
|
};
|
|
@@ -40,7 +40,7 @@ export const PAGE_TEXTS = {
|
|
|
40
40
|
serviceIdleMeta: "Bridge has not been started yet",
|
|
41
41
|
listSeparator: ", ",
|
|
42
42
|
platformsTitle: "Platforms",
|
|
43
|
-
platformsHint: "Disabled platforms keep
|
|
43
|
+
platformsHint: "Follow the setup checklist on Overview first. Disabled platforms still keep saved values.",
|
|
44
44
|
enabled: "Enabled",
|
|
45
45
|
readyState: "Ready",
|
|
46
46
|
setupRequired: "Setup required",
|
|
@@ -81,7 +81,7 @@ export const PAGE_TEXTS = {
|
|
|
81
81
|
optional: "Optional",
|
|
82
82
|
commaSeparatedIds: "Comma-separated IDs",
|
|
83
83
|
aiTitle: "AI Tooling",
|
|
84
|
-
aiHint: "",
|
|
84
|
+
aiHint: "Pick the default tool first. Claude SDK uses API keys in ~/.claude/settings.json (editable below). Codex / CodeBuddy need a CLI path.",
|
|
85
85
|
claudeNote: "Claude credentials are still read from environment variables or ~/.claude/settings.json. This page manages local bridge config, not Claude account auth.",
|
|
86
86
|
aiCommonTitle: "Shared defaults",
|
|
87
87
|
aiCommonHint: "Choose the default AI tool first. Tool-specific fields are shown below.",
|
|
@@ -134,6 +134,36 @@ export const PAGE_TEXTS = {
|
|
|
134
134
|
saveBtn: "Save",
|
|
135
135
|
jsonValid: "Valid JSON",
|
|
136
136
|
jsonInvalid: "Invalid JSON: {error}",
|
|
137
|
+
wizardTitle: "First-time setup",
|
|
138
|
+
wizardStep1Title: "Connect an IM channel",
|
|
139
|
+
wizardStep1Desc: "Enable at least one platform below and fill every required field. Use Check config when available.",
|
|
140
|
+
wizardStep2Title: "Set the default AI tool",
|
|
141
|
+
wizardStep2Desc: "Claude SDK: API keys live in ~/.claude/settings.json (expand on this page). Codex / CodeBuddy: set the CLI path in the AI section.",
|
|
142
|
+
wizardStep3Title: "Validate and save",
|
|
143
|
+
wizardStep3Desc: "Click Validate, then Save config. Fix any errors shown in the banner above.",
|
|
144
|
+
wizardStep4Title: "Start the bridge",
|
|
145
|
+
wizardStep4Desc: "Open Service and click Start bridge. If it exits, read ~/.open-im/logs.",
|
|
146
|
+
wizardStatusDone: "Done",
|
|
147
|
+
wizardStatusTodo: "To do",
|
|
148
|
+
wizardJumpPlatforms: "Open Platforms",
|
|
149
|
+
wizardJumpAi: "Open AI",
|
|
150
|
+
wizardJumpService: "Open Service",
|
|
151
|
+
validationNoPlatformEnabled: "Enable at least one IM platform and fill its required credentials before saving.",
|
|
152
|
+
validationPlatformIncomplete: "Platform \"{platform}\" is enabled but these required fields are empty: {fields}",
|
|
153
|
+
validationAiCodexNoCli: "Default AI is Codex but Codex CLI path is empty. Set it under AI Tooling or change the default tool.",
|
|
154
|
+
validationAiCodebuddyNoCli: "Default AI is CodeBuddy but CodeBuddy CLI path is empty. Set it under AI Tooling or change the default tool.",
|
|
155
|
+
onboardingTitle: "Welcome to open-im",
|
|
156
|
+
onboardingDismiss: "Got it",
|
|
157
|
+
onboardingReadme: "README (setup)",
|
|
158
|
+
onboardingBody: "<p><strong>open-im</strong> bridges Telegram, Feishu, QQ, WeWork, DingTalk, and WorkBuddy to Claude / Codex / CodeBuddy on your machine.</p><ol style=\"margin:12px 0 12px 18px;line-height:1.65\"><li>Pick <strong>one</strong> chat app in <strong>Platforms</strong> and paste credentials (see hints under each field).</li><li>Set the <strong>default AI</strong> and, for Claude SDK, API keys in <strong>~/.claude/settings.json</strong> on this page.</li><li>Use <strong>Validate</strong> then <strong>Save config</strong>, then <strong>Start bridge</strong> under Service.</li><li>CLI alternative: run <code style=\"background:var(--bg-tertiary);padding:2px 6px;border-radius:4px\">open-im init</code> in a terminal.</li></ol>",
|
|
159
|
+
tipTelegramToken: 'From Telegram, open <a href="https://t.me/BotFather" target="_blank" rel="noopener">@BotFather</a> → /newbot → copy the token.',
|
|
160
|
+
tipFeishuAppId: "Feishu Open Platform → your app → Credentials → App ID.",
|
|
161
|
+
tipFeishuSecret: "Same page → App Secret (click show / reset if needed).",
|
|
162
|
+
tipQqAppId: '<a href="https://bot.q.qq.com" target="_blank" rel="noopener">QQ bot console</a> → your bot → App ID.',
|
|
163
|
+
tipQqSecret: "Same console → App Secret.",
|
|
164
|
+
tipWeworkCorp: "WeCom admin → app → view Corp ID (or smart-bot Bot ID) and Secret.",
|
|
165
|
+
tipDingtalkClient: '<a href="https://open-dev.dingtalk.com" target="_blank" rel="noopener">DingTalk Open Platform</a> → internal app → App Key & App Secret.',
|
|
166
|
+
tipWorkbuddyToken: 'Use terminal <code>open-im init</code> for WorkBuddy OAuth, or paste tokens from CodeBuddy login.',
|
|
137
167
|
},
|
|
138
168
|
zh: {
|
|
139
169
|
pageTitle: "open-im \u672c\u5730\u63a7\u5236\u53f0",
|
|
@@ -174,7 +204,7 @@ export const PAGE_TEXTS = {
|
|
|
174
204
|
serviceIdleMeta: "\u6865\u63a5\u670d\u52a1\u5c1a\u672a\u542f\u52a8",
|
|
175
205
|
listSeparator: "\u3001",
|
|
176
206
|
platformsTitle: "\u5e73\u53f0\u914d\u7f6e",
|
|
177
|
-
platformsHint: "\u7981\u7528\u7684\u5e73\u53f0\
|
|
207
|
+
platformsHint: "\u5efa\u8bae\u5148\u5728\u6982\u89c8\u9875\u6309\u5f15\u5bfc\u6b65\u9aa4\u64cd\u4f5c\u3002\u7981\u7528\u7684\u5e73\u53f0\u4ecd\u4fdd\u7559\u5df2\u4fdd\u5b58\u7684\u503c\u3002",
|
|
178
208
|
enabled: "\u542f\u7528",
|
|
179
209
|
readyState: "\u5df2\u5c31\u7eea",
|
|
180
210
|
setupRequired: "\u9700\u8981\u5b8c\u6210\u914d\u7f6e",
|
|
@@ -214,7 +244,7 @@ export const PAGE_TEXTS = {
|
|
|
214
244
|
optional: "\u53ef\u9009",
|
|
215
245
|
commaSeparatedIds: "\u591a\u4e2a ID \u7528\u9017\u53f7\u5206\u9694",
|
|
216
246
|
aiTitle: "AI \u5de5\u5177\u914d\u7f6e",
|
|
217
|
-
aiHint: "",
|
|
247
|
+
aiHint: "\u5148\u9009\u9ed8\u8ba4 AI\u3002Claude SDK \u7684 API Key \u5199\u5728 ~/.claude/settings.json\uff08\u4e0b\u65b9\u53ef\u7f16\u8f91\uff09\u3002Codex / CodeBuddy \u9700\u586b CLI \u8def\u5f84\u3002",
|
|
218
248
|
claudeNote: "Claude \u51ed\u8bc1\u4ecd\u7136\u4ece\u73af\u5883\u53d8\u91cf\u6216 ~/.claude/settings.json \u8bfb\u53d6\u3002\u8fd9\u4e2a\u9875\u9762\u53ea\u7ba1\u7406\u672c\u5730\u6865\u63a5\u914d\u7f6e\uff0c\u4e0d\u8d1f\u8d23 Claude \u8d26\u53f7\u767b\u5f55\u3002",
|
|
219
249
|
aiCommonTitle: "\u516c\u5171\u9ed8\u8ba4\u914d\u7f6e",
|
|
220
250
|
aiCommonHint: "\u5148\u9009\u62e9\u9ed8\u8ba4 AI \u5de5\u5177\uff0c\u4e0b\u65b9\u518d\u663e\u793a\u5bf9\u5e94\u7684\u5de5\u5177\u4e13\u5c5e\u914d\u7f6e\u3002",
|
|
@@ -264,5 +294,35 @@ export const PAGE_TEXTS = {
|
|
|
264
294
|
saveBtn: "\u4fdd\u5b58",
|
|
265
295
|
jsonValid: "JSON \u6709\u6548",
|
|
266
296
|
jsonInvalid: "JSON \u65e0\u6548\uff1a{error}",
|
|
297
|
+
wizardTitle: "\u9996\u6b21\u4f7f\u7528\u5f15\u5bfc",
|
|
298
|
+
wizardStep1Title: "\u63a5\u5165\u4e00\u4e2a IM \u6e20\u9053",
|
|
299
|
+
wizardStep1Desc: "\u5728\u4e0b\u65b9\u542f\u7528\u81f3\u5c11\u4e00\u4e2a\u5e73\u53f0\uff0c\u5e76\u586b\u5199\u6240\u6709\u5fc5\u586b\u9879\u3002\u6709\u6761\u4ef6\u65f6\u7528\u300c\u6821\u9a8c\u914d\u7f6e\u300d\u6d4b\u8bd5\u51ed\u8bc1\u3002",
|
|
300
|
+
wizardStep2Title: "\u8bbe\u7f6e\u9ed8\u8ba4 AI \u5de5\u5177",
|
|
301
|
+
wizardStep2Desc: "Claude SDK\uff1aAPI Key \u5199\u5728 ~/.claude/settings.json\uff08\u672c\u9875\u53ef\u5c55\u5f00\u7f16\u8f91\uff09\u3002Codex / CodeBuddy\uff1a\u5728 AI \u533a\u586b CLI \u8def\u5f84\u3002",
|
|
302
|
+
wizardStep3Title: "\u6821\u9a8c\u5e76\u4fdd\u5b58",
|
|
303
|
+
wizardStep3Desc: "\u5148\u70b9\u300c\u6821\u9a8c\u300d\uff0c\u518d\u70b9\u300c\u4fdd\u5b58\u914d\u7f6e\u300d\u3002\u6309\u9876\u90e8\u63d0\u793a\u4fee\u590d\u9519\u8bef\u3002",
|
|
304
|
+
wizardStep4Title: "\u542f\u52a8\u6865\u63a5",
|
|
305
|
+
wizardStep4Desc: "\u5230\u300c\u670d\u52a1\u300d\u533a\u70b9\u300c\u542f\u52a8\u6865\u63a5\u300d\u3002\u82e5\u9a6c\u4e0a\u9000\u51fa\uff0c\u67e5 ~/.open-im/logs \u65e5\u5fd7\u3002",
|
|
306
|
+
wizardStatusDone: "\u5df2\u5b8c\u6210",
|
|
307
|
+
wizardStatusTodo: "\u5f85\u5b8c\u6210",
|
|
308
|
+
wizardJumpPlatforms: "\u6253\u5f00\u5e73\u53f0\u914d\u7f6e",
|
|
309
|
+
wizardJumpAi: "\u6253\u5f00 AI \u914d\u7f6e",
|
|
310
|
+
wizardJumpService: "\u6253\u5f00\u670d\u52a1\u63a7\u5236",
|
|
311
|
+
validationNoPlatformEnabled: "\u4fdd\u5b58\u524d\u8bf7\u81f3\u5c11\u542f\u7528\u4e00\u4e2a IM \u5e73\u53f0\uff0c\u5e76\u586b\u5b8c\u5fc5\u586b\u51ed\u8bc1\u3002",
|
|
312
|
+
validationPlatformIncomplete: "\u5e73\u53f0\u300c{platform}\u300d\u5df2\u542f\u7528\uff0c\u4f46\u4ee5\u4e0b\u5fc5\u586b\u9879\u4e3a\u7a7a\uff1a{fields}",
|
|
313
|
+
validationAiCodexNoCli: "\u9ed8\u8ba4 AI \u4e3a Codex\uff0c\u4f46 Codex CLI \u8def\u5f84\u4e3a\u7a7a\u3002\u8bf7\u5728 AI \u533a\u586b\u5199\uff0c\u6216\u6539\u9ed8\u8ba4\u5de5\u5177\u3002",
|
|
314
|
+
validationAiCodebuddyNoCli: "\u9ed8\u8ba4 AI \u4e3a CodeBuddy\uff0c\u4f46 CodeBuddy CLI \u8def\u5f84\u4e3a\u7a7a\u3002\u8bf7\u5728 AI \u533a\u586b\u5199\uff0c\u6216\u6539\u9ed8\u8ba4\u5de5\u5177\u3002",
|
|
315
|
+
onboardingTitle: "\u6b22\u8fce\u4f7f\u7528 open-im",
|
|
316
|
+
onboardingDismiss: "\u77e5\u9053\u4e86",
|
|
317
|
+
onboardingReadme: "README\uff08\u90e8\u7f72\u8bf4\u660e\uff09",
|
|
318
|
+
onboardingBody: "<p><strong>open-im</strong> \u5728\u672c\u673a\u628a Telegram\u3001\u98de\u4e66\u3001QQ\u3001\u4f01\u5fae\u3001\u9489\u9489\u3001WorkBuddy \u7b49\u6e20\u9053\u8fde\u5230 Claude / Codex / CodeBuddy\u3002</p><ol style=\"margin:12px 0 12px 18px;line-height:1.65\"><li>\u5728<strong>\u5e73\u53f0\u914d\u7f6e</strong>\u9009\u4e00\u4e2a\u804a\u5929\u5e94\u7528\uff0c\u6309\u5b57\u6bb5\u4e0b\u65b9\u63d0\u793a\u586b\u51ed\u8bc1\u3002</li><li>\u8bbe<strong>\u9ed8\u8ba4 AI</strong>\uff1b\u7528 Claude SDK \u65f6\u628a API Key \u5199\u8fdb<strong>~/.claude/settings.json</strong>\uff08\u672c\u9875\u53ef\u7f16\u8f91\uff09\u3002</li><li>\u5148<strong>\u6821\u9a8c</strong>\u518d<strong>\u4fdd\u5b58\u914d\u7f6e</strong>\uff0c\u7136\u540e\u5230<strong>\u670d\u52a1</strong>\u542f\u52a8\u6865\u63a5\u3002</li><li>\u4e5f\u53ef\u5728\u7ec8\u7aef\u8fd0\u884c <code style=\"background:var(--bg-tertiary);padding:2px 6px;border-radius:4px\">open-im init</code> \u4ea4\u4e92\u914d\u7f6e\u3002</li></ol>",
|
|
319
|
+
tipTelegramToken: '\u5728 Telegram \u641c <a href="https://t.me/BotFather" target="_blank" rel="noopener">@BotFather</a>\uff0c\u53d1 /newbot \u521b\u5efa\u673a\u5668\u4eba\u540e\u590d\u5236 Token\u3002',
|
|
320
|
+
tipFeishuAppId: "\u98de\u4e66\u5f00\u653e\u5e73\u53f0 \u2192 \u5e94\u7528 \u2192 \u51ed\u8bc1\u4e0e\u57fa\u7840\u4fe1\u606f \u2192 App ID\u3002",
|
|
321
|
+
tipFeishuSecret: "\u540c\u4e00\u9875 App Secret\uff08\u53ef\u91cd\u7f6e\u540e\u67e5\u770b\uff09\u3002",
|
|
322
|
+
tipQqAppId: '<a href="https://bot.q.qq.com" target="_blank" rel="noopener">QQ \u5f00\u653e\u5e73\u53f0</a> \u2192 \u673a\u5668\u4eba \u2192 App ID\u3002',
|
|
323
|
+
tipQqSecret: "\u540c\u4e00\u5904\u83b7\u53d6 App Secret\u3002",
|
|
324
|
+
tipWeworkCorp: "\u4f01\u4e1a\u5fae\u4fe1\u7ba1\u7406\u540e\u53f0 \u2192 \u5e94\u7528 \u2192 \u67e5\u7701 Corp ID / \u667a\u80fd\u673a\u5668\u4eba Bot ID \u4e0e Secret\u3002",
|
|
325
|
+
tipDingtalkClient: '<a href="https://open-dev.dingtalk.com" target="_blank" rel="noopener">\u9489\u9489\u5f00\u653e\u5e73\u53f0</a> \u2192 \u4f01\u4e1a\u5185\u90e8\u5e94\u7528 \u2192 AppKey / AppSecret\u3002',
|
|
326
|
+
tipWorkbuddyToken: "\u5efa\u8bae\u5728\u7ec8\u7aef\u8fd0\u884c <code>open-im init</code> \u5b8c\u6210 WorkBuddy \u6388\u6743\uff1b\u6216\u7c98\u8d34 CodeBuddy \u767b\u5f55\u540e\u7684 Token\u3002",
|
|
267
327
|
}
|
|
268
328
|
};
|
|
@@ -10,6 +10,8 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
10
10
|
const aiTools = ["claude", "codex", "codebuddy"];
|
|
11
11
|
const STORAGE_KEY_LANG = "open-im-web-lang";
|
|
12
12
|
const STORAGE_KEY_DARK_MODE = "open-im-web-dark-mode";
|
|
13
|
+
const STORAGE_KEY_ONBOARDING = "open-im-dashboard-onboarding-v1";
|
|
14
|
+
const STORAGE_KEY_SAVED_SESSION = "open-im-setup-saved-session";
|
|
13
15
|
const POLLING_INTERVAL = 10000;
|
|
14
16
|
const toolLabels = { claude: "Claude", codex: "Codex", codebuddy: "CodeBuddy" };
|
|
15
17
|
|
|
@@ -67,6 +69,7 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
67
69
|
const texts = __PAGE_TEXTS__;
|
|
68
70
|
let currentMeta = null;
|
|
69
71
|
let cachedServiceData = null;
|
|
72
|
+
let lastHealthPayload = null;
|
|
70
73
|
let currentLang = (localStorage.getItem(STORAGE_KEY_LANG) || "").startsWith("zh") ? "zh" : ((navigator.language || "").startsWith("zh") ? "zh" : "en");
|
|
71
74
|
|
|
72
75
|
// Translation helper
|
|
@@ -166,6 +169,22 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
166
169
|
{ id: "resetJsonButtonText", key: "resetJson" },
|
|
167
170
|
{ id: "saveClaudeSettingsBtnText", key: "saveBtn" },
|
|
168
171
|
{ id: "saveOpenImConfigBtnText", key: "saveBtn" },
|
|
172
|
+
{ id: "wizardTitle", key: "wizardTitle" },
|
|
173
|
+
{ id: "wizardStep1Title", key: "wizardStep1Title" },
|
|
174
|
+
{ id: "wizardStep1Desc", key: "wizardStep1Desc" },
|
|
175
|
+
{ id: "wizardStep2Title", key: "wizardStep2Title" },
|
|
176
|
+
{ id: "wizardStep2Desc", key: "wizardStep2Desc" },
|
|
177
|
+
{ id: "wizardStep3Title", key: "wizardStep3Title" },
|
|
178
|
+
{ id: "wizardStep3Desc", key: "wizardStep3Desc" },
|
|
179
|
+
{ id: "wizardStep4Title", key: "wizardStep4Title" },
|
|
180
|
+
{ id: "wizardStep4Desc", key: "wizardStep4Desc" },
|
|
181
|
+
{ id: "wizardJumpPlatforms", key: "wizardJumpPlatforms" },
|
|
182
|
+
{ id: "wizardJumpAi", key: "wizardJumpAi" },
|
|
183
|
+
{ id: "wizardJumpService", key: "wizardJumpService" },
|
|
184
|
+
{ id: "wizardJumpService2", key: "wizardJumpService" },
|
|
185
|
+
{ id: "onboardingTitle", key: "onboardingTitle" },
|
|
186
|
+
{ id: "onboardingDismiss", key: "onboardingDismiss" },
|
|
187
|
+
{ id: "onboardingReadme", key: "onboardingReadme" },
|
|
169
188
|
],
|
|
170
189
|
platformLabels: {
|
|
171
190
|
enabled: { suffix: "-label", key: "enabled" },
|
|
@@ -274,6 +293,24 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
274
293
|
if (helpBlock) helpBlock.innerHTML = t(key);
|
|
275
294
|
});
|
|
276
295
|
|
|
296
|
+
// Short per-field tips (HTML)
|
|
297
|
+
[
|
|
298
|
+
["telegram-botToken-tip", "tipTelegramToken"],
|
|
299
|
+
["feishu-appId-tip", "tipFeishuAppId"],
|
|
300
|
+
["feishu-appSecret-tip", "tipFeishuSecret"],
|
|
301
|
+
["qq-appId-tip", "tipQqAppId"],
|
|
302
|
+
["qq-secret-tip", "tipQqSecret"],
|
|
303
|
+
["wework-corpId-tip", "tipWeworkCorp"],
|
|
304
|
+
["dingtalk-clientId-tip", "tipDingtalkClient"],
|
|
305
|
+
["workbuddy-accessToken-tip", "tipWorkbuddyToken"],
|
|
306
|
+
].forEach(([tipId, tipKey]) => {
|
|
307
|
+
const tipEl = el(tipId);
|
|
308
|
+
if (tipEl) tipEl.innerHTML = t(tipKey);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const onboardBody = el("onboardingBody");
|
|
312
|
+
if (onboardBody) onboardBody.innerHTML = t("onboardingBody");
|
|
313
|
+
|
|
277
314
|
// AI labels
|
|
278
315
|
LANGUAGE_UPDATES.aiLabels.forEach(({ id, key }) => {
|
|
279
316
|
const label = el(id + "-label");
|
|
@@ -300,6 +337,14 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
300
337
|
// Dark mode toggle aria-label
|
|
301
338
|
const darkModeToggle = el("darkModeToggle");
|
|
302
339
|
if (darkModeToggle) darkModeToggle.setAttribute("aria-label", t("darkModeToggle"));
|
|
340
|
+
|
|
341
|
+
const readmeLink = el("onboardingReadmeLink");
|
|
342
|
+
if (readmeLink && readmeLink instanceof HTMLAnchorElement) {
|
|
343
|
+
readmeLink.href = isZh
|
|
344
|
+
? "https://github.com/wu529778790/open-im/blob/main/README.zh-CN.md"
|
|
345
|
+
: "https://github.com/wu529778790/open-im/blob/main/README.md";
|
|
346
|
+
}
|
|
347
|
+
updateSetupWizard();
|
|
303
348
|
}
|
|
304
349
|
|
|
305
350
|
// AI tool switcher
|
|
@@ -331,6 +376,66 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
331
376
|
const liveSummary = el("liveSummary");
|
|
332
377
|
if (liveSummary) liveSummary.textContent = summary;
|
|
333
378
|
updateAiToolVisibility();
|
|
379
|
+
updateSetupWizard();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function hasReadyPlatform() {
|
|
383
|
+
return platformDefinitions.some((platform) => {
|
|
384
|
+
if (!getChecked(platform.key + "-enabled")) return false;
|
|
385
|
+
return platform.requiredFields.every((field) => getValue(platform.key + "-" + field).trim().length > 0);
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function aiStepComplete() {
|
|
390
|
+
const cmd = getValue("ai-aiCommand");
|
|
391
|
+
if (cmd === "codex") return getValue("ai-codexCliPath").trim().length > 0;
|
|
392
|
+
if (cmd === "codebuddy") return getValue("ai-codebuddyCliPath").trim().length > 0;
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function updateSetupWizard() {
|
|
397
|
+
const s1 = hasReadyPlatform();
|
|
398
|
+
const s2 = aiStepComplete();
|
|
399
|
+
const s3 = sessionStorage.getItem(STORAGE_KEY_SAVED_SESSION) === "1";
|
|
400
|
+
const s4 = Boolean(lastHealthPayload && lastHealthPayload.serviceStatus && lastHealthPayload.serviceStatus.running);
|
|
401
|
+
const done = [s1, s2, s3, s4];
|
|
402
|
+
for (let i = 0; i < 4; i += 1) {
|
|
403
|
+
const step = el("wizard-step-" + (i + 1));
|
|
404
|
+
if (step) step.classList.toggle("wizard-step--done", done[i]);
|
|
405
|
+
setText("wizardStep" + (i + 1) + "Status", done[i] ? t("wizardStatusDone") : t("wizardStatusTodo"));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function collectClientValidationErrors() {
|
|
410
|
+
const errors = [];
|
|
411
|
+
const anyEnabled = platformDefinitions.some((p) => getChecked(p.key + "-enabled"));
|
|
412
|
+
if (!anyEnabled) {
|
|
413
|
+
errors.push(t("validationNoPlatformEnabled"));
|
|
414
|
+
}
|
|
415
|
+
platformDefinitions.forEach((platform) => {
|
|
416
|
+
if (!getChecked(platform.key + "-enabled")) return;
|
|
417
|
+
const missing = platform.requiredFields.filter((field) => !getValue(platform.key + "-" + field).trim());
|
|
418
|
+
if (missing.length > 0) {
|
|
419
|
+
errors.push(t("validationPlatformIncomplete", { platform: platform.label, fields: missing.join(", ") }));
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
const cmd = getValue("ai-aiCommand");
|
|
423
|
+
if (cmd === "codex" && !getValue("ai-codexCliPath").trim()) {
|
|
424
|
+
errors.push(t("validationAiCodexNoCli"));
|
|
425
|
+
}
|
|
426
|
+
if (cmd === "codebuddy" && !getValue("ai-codebuddyCliPath").trim()) {
|
|
427
|
+
errors.push(t("validationAiCodebuddyNoCli"));
|
|
428
|
+
}
|
|
429
|
+
return errors;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function validateClientSideOrAbort() {
|
|
433
|
+
const errors = collectClientValidationErrors();
|
|
434
|
+
if (errors.length > 0) {
|
|
435
|
+
setMessage(errors.join(" "), "error");
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
return true;
|
|
334
439
|
}
|
|
335
440
|
|
|
336
441
|
// Update dashboard with health status
|
|
@@ -386,6 +491,9 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
386
491
|
el("statEnabledValue").textContent = String(enabledCount);
|
|
387
492
|
el("statServiceValue").textContent = serviceStatus.running ? t("serviceRunningShort") : t("serviceIdleShort");
|
|
388
493
|
|
|
494
|
+
lastHealthPayload = data;
|
|
495
|
+
updateSetupWizard();
|
|
496
|
+
|
|
389
497
|
return data;
|
|
390
498
|
} catch (error) {
|
|
391
499
|
console.error("Failed to update dashboard:", error);
|
|
@@ -684,6 +792,26 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
684
792
|
el("navAiBtn").onclick = () => scrollToSection("aiSection", "navAiBtn");
|
|
685
793
|
el("navServiceBtn").onclick = () => scrollToSection("serviceSection", "navServiceBtn");
|
|
686
794
|
|
|
795
|
+
document.querySelectorAll(".wizard-jump").forEach((jumpBtn) => {
|
|
796
|
+
jumpBtn.addEventListener("click", () => {
|
|
797
|
+
const sec = jumpBtn.getAttribute("data-section");
|
|
798
|
+
const nav = jumpBtn.getAttribute("data-nav");
|
|
799
|
+
if (sec && nav) scrollToSection(sec, nav);
|
|
800
|
+
});
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
const onboardBackdrop = el("onboardingBackdrop");
|
|
804
|
+
const onboardDismiss = el("onboardingDismiss");
|
|
805
|
+
if (onboardBackdrop && onboardDismiss) {
|
|
806
|
+
if (!localStorage.getItem(STORAGE_KEY_ONBOARDING)) {
|
|
807
|
+
onboardBackdrop.classList.remove("hidden");
|
|
808
|
+
}
|
|
809
|
+
onboardDismiss.onclick = () => {
|
|
810
|
+
localStorage.setItem(STORAGE_KEY_ONBOARDING, "1");
|
|
811
|
+
onboardBackdrop.classList.add("hidden");
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
|
|
687
815
|
// Language toggle
|
|
688
816
|
el("langButton").onclick = () => {
|
|
689
817
|
currentLang = currentLang === "zh" ? "en" : "zh";
|
|
@@ -700,12 +828,12 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
700
828
|
// Service buttons
|
|
701
829
|
el("validateButton").onclick = validate;
|
|
702
830
|
el("saveButton").onclick = async () => {
|
|
703
|
-
|
|
831
|
+
if (!validateClientSideOrAbort()) return;
|
|
704
832
|
await saveClaudeSettings();
|
|
705
833
|
await save();
|
|
706
834
|
};
|
|
707
835
|
el("startButton").onclick = async () => {
|
|
708
|
-
|
|
836
|
+
if (!validateClientSideOrAbort()) return;
|
|
709
837
|
await saveClaudeSettings();
|
|
710
838
|
await startService();
|
|
711
839
|
};
|
|
@@ -725,6 +853,7 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
725
853
|
async function validate() {
|
|
726
854
|
setBusy(true);
|
|
727
855
|
try {
|
|
856
|
+
if (!validateClientSideOrAbort()) return;
|
|
728
857
|
await request("/api/config/validate", { method: "POST", body: JSON.stringify(payload()) });
|
|
729
858
|
setMessage(t("validationOk"), "success");
|
|
730
859
|
} catch (error) {
|
|
@@ -737,11 +866,14 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
737
866
|
async function save() {
|
|
738
867
|
setBusy(true);
|
|
739
868
|
try {
|
|
869
|
+
if (!validateClientSideOrAbort()) return;
|
|
740
870
|
// First save JSON editor content if changed
|
|
741
871
|
await saveOpenImConfig();
|
|
742
872
|
// Then save form data
|
|
743
873
|
await request("/api/config/save?final=1", { method: "POST", body: JSON.stringify(payload()) });
|
|
874
|
+
sessionStorage.setItem(STORAGE_KEY_SAVED_SESSION, "1");
|
|
744
875
|
setMessage(t("saveOk"), "success");
|
|
876
|
+
updateSetupWizard();
|
|
745
877
|
} catch (error) {
|
|
746
878
|
setMessage(error.message || String(error), "error");
|
|
747
879
|
} finally {
|
|
@@ -778,9 +910,11 @@ export const PAGE_SCRIPT = String.raw ` const platformDefinitions = [
|
|
|
778
910
|
async function startService() {
|
|
779
911
|
setBusy(true);
|
|
780
912
|
try {
|
|
913
|
+
if (!validateClientSideOrAbort()) return;
|
|
781
914
|
await request("/api/config/save", { method: "POST", body: JSON.stringify(payload()) });
|
|
782
915
|
await request("/api/service/start", { method: "POST" });
|
|
783
916
|
await refreshStatus();
|
|
917
|
+
await updateDashboard();
|
|
784
918
|
setMessage(t("startOk"), "success");
|
|
785
919
|
} catch (error) {
|
|
786
920
|
setMessage(error.message || String(error), "error");
|
|
@@ -356,6 +356,149 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
356
356
|
line-height: 1;
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
+
/* Setup wizard (overview) */
|
|
360
|
+
.setup-wizard-card {
|
|
361
|
+
background: var(--bg-card);
|
|
362
|
+
border: 1px solid var(--border-subtle);
|
|
363
|
+
border-radius: var(--radius-lg);
|
|
364
|
+
padding: 20px 24px;
|
|
365
|
+
margin-bottom: 24px;
|
|
366
|
+
box-shadow: var(--shadow-sm);
|
|
367
|
+
}
|
|
368
|
+
.setup-wizard-card h2 {
|
|
369
|
+
margin: 0 0 16px;
|
|
370
|
+
font-size: 16px;
|
|
371
|
+
font-weight: 600;
|
|
372
|
+
color: var(--text-primary);
|
|
373
|
+
}
|
|
374
|
+
.wizard-steps {
|
|
375
|
+
display: grid;
|
|
376
|
+
gap: 12px;
|
|
377
|
+
}
|
|
378
|
+
@media (min-width: 900px) {
|
|
379
|
+
.wizard-steps {
|
|
380
|
+
grid-template-columns: repeat(2, 1fr);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
.wizard-step {
|
|
384
|
+
display: flex;
|
|
385
|
+
gap: 14px;
|
|
386
|
+
align-items: flex-start;
|
|
387
|
+
padding: 14px 16px;
|
|
388
|
+
border-radius: var(--radius-md);
|
|
389
|
+
border: 1px solid var(--border-subtle);
|
|
390
|
+
background: var(--bg-secondary);
|
|
391
|
+
transition: border-color var(--transition-fast), background var(--transition-fast);
|
|
392
|
+
}
|
|
393
|
+
.wizard-step--done {
|
|
394
|
+
border-color: var(--success-border);
|
|
395
|
+
background: var(--success-bg);
|
|
396
|
+
}
|
|
397
|
+
.wizard-step-badge {
|
|
398
|
+
flex-shrink: 0;
|
|
399
|
+
width: 28px;
|
|
400
|
+
height: 28px;
|
|
401
|
+
border-radius: 999px;
|
|
402
|
+
display: flex;
|
|
403
|
+
align-items: center;
|
|
404
|
+
justify-content: center;
|
|
405
|
+
font-size: 13px;
|
|
406
|
+
font-weight: 700;
|
|
407
|
+
background: var(--bg-tertiary);
|
|
408
|
+
color: var(--text-secondary);
|
|
409
|
+
}
|
|
410
|
+
.wizard-step--done .wizard-step-badge {
|
|
411
|
+
background: var(--success-text);
|
|
412
|
+
color: #fff;
|
|
413
|
+
}
|
|
414
|
+
.wizard-step-body {
|
|
415
|
+
flex: 1;
|
|
416
|
+
min-width: 0;
|
|
417
|
+
}
|
|
418
|
+
.wizard-step-title {
|
|
419
|
+
font-weight: 600;
|
|
420
|
+
font-size: 14px;
|
|
421
|
+
color: var(--text-primary);
|
|
422
|
+
margin-bottom: 4px;
|
|
423
|
+
}
|
|
424
|
+
.wizard-step-desc {
|
|
425
|
+
font-size: 13px;
|
|
426
|
+
color: var(--text-secondary);
|
|
427
|
+
line-height: 1.5;
|
|
428
|
+
margin-bottom: 8px;
|
|
429
|
+
}
|
|
430
|
+
.wizard-step-status {
|
|
431
|
+
font-size: 11px;
|
|
432
|
+
font-weight: 600;
|
|
433
|
+
text-transform: uppercase;
|
|
434
|
+
letter-spacing: 0.04em;
|
|
435
|
+
margin-bottom: 6px;
|
|
436
|
+
color: var(--text-tertiary);
|
|
437
|
+
}
|
|
438
|
+
.wizard-step--done .wizard-step-status {
|
|
439
|
+
color: var(--success-text);
|
|
440
|
+
}
|
|
441
|
+
.field-inline-tip {
|
|
442
|
+
font-size: 12px;
|
|
443
|
+
color: var(--text-tertiary);
|
|
444
|
+
line-height: 1.45;
|
|
445
|
+
margin-top: 6px;
|
|
446
|
+
}
|
|
447
|
+
.field-inline-tip a {
|
|
448
|
+
color: var(--accent-primary);
|
|
449
|
+
}
|
|
450
|
+
.field-inline-tip code {
|
|
451
|
+
font-size: 11px;
|
|
452
|
+
background: var(--bg-tertiary);
|
|
453
|
+
padding: 1px 5px;
|
|
454
|
+
border-radius: var(--radius-xs);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/* First-visit onboarding */
|
|
458
|
+
.onboarding-backdrop {
|
|
459
|
+
position: fixed;
|
|
460
|
+
inset: 0;
|
|
461
|
+
background: rgba(15, 23, 42, 0.45);
|
|
462
|
+
z-index: 100;
|
|
463
|
+
display: flex;
|
|
464
|
+
align-items: center;
|
|
465
|
+
justify-content: center;
|
|
466
|
+
padding: 24px;
|
|
467
|
+
}
|
|
468
|
+
.onboarding-backdrop.hidden {
|
|
469
|
+
display: none;
|
|
470
|
+
}
|
|
471
|
+
.onboarding-card {
|
|
472
|
+
background: var(--bg-card);
|
|
473
|
+
color: var(--text-primary);
|
|
474
|
+
border-radius: var(--radius-xl);
|
|
475
|
+
max-width: 520px;
|
|
476
|
+
width: 100%;
|
|
477
|
+
padding: 28px 28px 24px;
|
|
478
|
+
box-shadow: var(--shadow-lg);
|
|
479
|
+
border: 1px solid var(--border-subtle);
|
|
480
|
+
}
|
|
481
|
+
.onboarding-card h2 {
|
|
482
|
+
margin: 0 0 12px;
|
|
483
|
+
font-size: 20px;
|
|
484
|
+
font-weight: 700;
|
|
485
|
+
}
|
|
486
|
+
.onboarding-card .onboarding-body {
|
|
487
|
+
font-size: 14px;
|
|
488
|
+
color: var(--text-secondary);
|
|
489
|
+
line-height: 1.55;
|
|
490
|
+
}
|
|
491
|
+
.onboarding-card .onboarding-body p {
|
|
492
|
+
margin: 0 0 8px;
|
|
493
|
+
}
|
|
494
|
+
.onboarding-actions {
|
|
495
|
+
display: flex;
|
|
496
|
+
flex-wrap: wrap;
|
|
497
|
+
gap: 10px;
|
|
498
|
+
margin-top: 20px;
|
|
499
|
+
align-items: center;
|
|
500
|
+
}
|
|
501
|
+
|
|
359
502
|
/* Platform Cards */
|
|
360
503
|
.platform-grid {
|
|
361
504
|
display: grid;
|
|
@@ -839,6 +982,48 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
839
982
|
<div class="stat-value" id="statServiceValue">Idle</div>
|
|
840
983
|
</div>
|
|
841
984
|
</div>
|
|
985
|
+
|
|
986
|
+
<div class="setup-wizard-card">
|
|
987
|
+
<h2 id="wizardTitle">First-time setup</h2>
|
|
988
|
+
<div class="wizard-steps" id="wizardSteps">
|
|
989
|
+
<div class="wizard-step" id="wizard-step-1">
|
|
990
|
+
<div class="wizard-step-badge">1</div>
|
|
991
|
+
<div class="wizard-step-body">
|
|
992
|
+
<div class="wizard-step-status" id="wizardStep1Status">To do</div>
|
|
993
|
+
<div class="wizard-step-title" id="wizardStep1Title">Connect an IM channel</div>
|
|
994
|
+
<div class="wizard-step-desc" id="wizardStep1Desc"></div>
|
|
995
|
+
<button type="button" class="btn btn-secondary btn-sm wizard-jump" data-section="configSection" data-nav="navPlatformsBtn" id="wizardJumpPlatforms">Open Platforms</button>
|
|
996
|
+
</div>
|
|
997
|
+
</div>
|
|
998
|
+
<div class="wizard-step" id="wizard-step-2">
|
|
999
|
+
<div class="wizard-step-badge">2</div>
|
|
1000
|
+
<div class="wizard-step-body">
|
|
1001
|
+
<div class="wizard-step-status" id="wizardStep2Status">To do</div>
|
|
1002
|
+
<div class="wizard-step-title" id="wizardStep2Title">Set the default AI tool</div>
|
|
1003
|
+
<div class="wizard-step-desc" id="wizardStep2Desc"></div>
|
|
1004
|
+
<button type="button" class="btn btn-secondary btn-sm wizard-jump" data-section="aiSection" data-nav="navAiBtn" id="wizardJumpAi">Open AI</button>
|
|
1005
|
+
</div>
|
|
1006
|
+
</div>
|
|
1007
|
+
<div class="wizard-step" id="wizard-step-3">
|
|
1008
|
+
<div class="wizard-step-badge">3</div>
|
|
1009
|
+
<div class="wizard-step-body">
|
|
1010
|
+
<div class="wizard-step-status" id="wizardStep3Status">To do</div>
|
|
1011
|
+
<div class="wizard-step-title" id="wizardStep3Title">Validate and save</div>
|
|
1012
|
+
<div class="wizard-step-desc" id="wizardStep3Desc"></div>
|
|
1013
|
+
<button type="button" class="btn btn-secondary btn-sm wizard-jump" data-section="serviceSection" data-nav="navServiceBtn" id="wizardJumpService">Open Service</button>
|
|
1014
|
+
</div>
|
|
1015
|
+
</div>
|
|
1016
|
+
<div class="wizard-step" id="wizard-step-4">
|
|
1017
|
+
<div class="wizard-step-badge">4</div>
|
|
1018
|
+
<div class="wizard-step-body">
|
|
1019
|
+
<div class="wizard-step-status" id="wizardStep4Status">To do</div>
|
|
1020
|
+
<div class="wizard-step-title" id="wizardStep4Title">Start the bridge</div>
|
|
1021
|
+
<div class="wizard-step-desc" id="wizardStep4Desc"></div>
|
|
1022
|
+
<button type="button" class="btn btn-secondary btn-sm wizard-jump" data-section="serviceSection" data-nav="navServiceBtn" id="wizardJumpService2">Open Service</button>
|
|
1023
|
+
</div>
|
|
1024
|
+
</div>
|
|
1025
|
+
</div>
|
|
1026
|
+
</div>
|
|
842
1027
|
</section>
|
|
843
1028
|
|
|
844
1029
|
<!-- Platforms Section -->
|
|
@@ -864,6 +1049,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
864
1049
|
<div class="form-group">
|
|
865
1050
|
<label class="form-label" id="telegram-botToken-label">Bot Token</label>
|
|
866
1051
|
<input id="telegram-botToken" class="form-input mono" type="password" />
|
|
1052
|
+
<div class="field-inline-tip" id="telegram-botToken-tip"></div>
|
|
867
1053
|
</div>
|
|
868
1054
|
<div class="form-group">
|
|
869
1055
|
<label class="form-label" id="telegram-proxy-label">Proxy (optional)</label>
|
|
@@ -906,10 +1092,12 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
906
1092
|
<div class="form-group">
|
|
907
1093
|
<label class="form-label" id="feishu-appId-label">App ID</label>
|
|
908
1094
|
<input id="feishu-appId" class="form-input mono" type="text" />
|
|
1095
|
+
<div class="field-inline-tip" id="feishu-appId-tip"></div>
|
|
909
1096
|
</div>
|
|
910
1097
|
<div class="form-group">
|
|
911
1098
|
<label class="form-label" id="feishu-appSecret-label">App Secret</label>
|
|
912
1099
|
<input id="feishu-appSecret" class="form-input mono" type="password" />
|
|
1100
|
+
<div class="field-inline-tip" id="feishu-appSecret-tip"></div>
|
|
913
1101
|
</div>
|
|
914
1102
|
<div class="form-group">
|
|
915
1103
|
<label class="form-label" id="feishu-aiCommand-label">AI Tool</label>
|
|
@@ -947,10 +1135,12 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
947
1135
|
<div class="form-group">
|
|
948
1136
|
<label class="form-label" id="qq-appId-label">App ID</label>
|
|
949
1137
|
<input id="qq-appId" class="form-input mono" type="text" />
|
|
1138
|
+
<div class="field-inline-tip" id="qq-appId-tip"></div>
|
|
950
1139
|
</div>
|
|
951
1140
|
<div class="form-group">
|
|
952
1141
|
<label class="form-label" id="qq-secret-label">App Secret</label>
|
|
953
1142
|
<input id="qq-secret" class="form-input mono" type="password" />
|
|
1143
|
+
<div class="field-inline-tip" id="qq-secret-tip"></div>
|
|
954
1144
|
</div>
|
|
955
1145
|
<div class="form-group">
|
|
956
1146
|
<label class="form-label" id="qq-aiCommand-label">AI Tool</label>
|
|
@@ -988,6 +1178,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
988
1178
|
<div class="form-group">
|
|
989
1179
|
<label class="form-label" id="wework-corpId-label">Corp ID / Bot ID</label>
|
|
990
1180
|
<input id="wework-corpId" class="form-input mono" type="text" />
|
|
1181
|
+
<div class="field-inline-tip" id="wework-corpId-tip"></div>
|
|
991
1182
|
</div>
|
|
992
1183
|
<div class="form-group">
|
|
993
1184
|
<label class="form-label" id="wework-secret-label">Secret</label>
|
|
@@ -1029,6 +1220,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
1029
1220
|
<div class="form-group">
|
|
1030
1221
|
<label class="form-label" id="dingtalk-clientId-label">Client ID / AppKey</label>
|
|
1031
1222
|
<input id="dingtalk-clientId" class="form-input mono" type="password" />
|
|
1223
|
+
<div class="field-inline-tip" id="dingtalk-clientId-tip"></div>
|
|
1032
1224
|
</div>
|
|
1033
1225
|
<div class="form-group">
|
|
1034
1226
|
<label class="form-label" id="dingtalk-clientSecret-label">Client Secret / AppSecret</label>
|
|
@@ -1083,6 +1275,7 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
1083
1275
|
<div class="form-group">
|
|
1084
1276
|
<label class="form-label" id="workbuddy-accessToken-label">Access Token</label>
|
|
1085
1277
|
<input id="workbuddy-accessToken" class="form-input mono" type="password" autocomplete="off" />
|
|
1278
|
+
<div class="field-inline-tip" id="workbuddy-accessToken-tip"></div>
|
|
1086
1279
|
</div>
|
|
1087
1280
|
<div class="form-group">
|
|
1088
1281
|
<label class="form-label" id="workbuddy-refreshToken-label">Refresh Token</label>
|
|
@@ -1259,6 +1452,17 @@ export const PAGE_HTML_PREFIX = String.raw `<!doctype html>
|
|
|
1259
1452
|
</div>
|
|
1260
1453
|
</section>
|
|
1261
1454
|
|
|
1455
|
+
<div id="onboardingBackdrop" class="onboarding-backdrop hidden" role="dialog" aria-modal="true" aria-labelledby="onboardingTitle">
|
|
1456
|
+
<div class="onboarding-card">
|
|
1457
|
+
<h2 id="onboardingTitle">Welcome</h2>
|
|
1458
|
+
<div id="onboardingBody" class="onboarding-body"></div>
|
|
1459
|
+
<div class="onboarding-actions">
|
|
1460
|
+
<button type="button" class="btn btn-primary" id="onboardingDismiss">Got it</button>
|
|
1461
|
+
<a href="https://github.com/wu529778790/open-im/blob/main/README.zh-CN.md" target="_blank" rel="noopener" class="btn btn-ghost" id="onboardingReadmeLink"><span id="onboardingReadme">README</span></a>
|
|
1462
|
+
</div>
|
|
1463
|
+
</div>
|
|
1464
|
+
</div>
|
|
1465
|
+
|
|
1262
1466
|
</div>
|
|
1263
1467
|
</main>
|
|
1264
1468
|
</div>
|