@jesonliu/lark-claudecode-bridge 0.11.0 → 0.13.0
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 +81 -46
- package/assets/web/index.html +1416 -0
- package/config.example.yaml +22 -2
- package/dist/auth-precheck.d.ts +5 -2
- package/dist/auth-precheck.js +8 -2
- package/dist/auth-precheck.js.map +1 -1
- package/dist/bin/lcb.js +32 -3
- package/dist/bin/lcb.js.map +1 -1
- package/dist/claude-config.d.ts +19 -0
- package/dist/claude-config.js +76 -0
- package/dist/claude-config.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +1 -0
- package/dist/cli/setup-wizard.js +4 -0
- package/dist/cli/setup-wizard.js.map +1 -1
- package/dist/config-defaults.d.ts +4 -0
- package/dist/config-defaults.js +15 -0
- package/dist/config-defaults.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.js +190 -6
- package/dist/config.js.map +1 -1
- package/dist/executor/permission-gate.d.ts +8 -1
- package/dist/executor/permission-gate.js +21 -14
- package/dist/executor/permission-gate.js.map +1 -1
- package/dist/executor/plugin-discovery.d.ts +11 -0
- package/dist/executor/plugin-discovery.js +28 -0
- package/dist/executor/plugin-discovery.js.map +1 -1
- package/dist/executor/plugin-manager.d.ts +19 -0
- package/dist/executor/plugin-manager.js +84 -0
- package/dist/executor/plugin-manager.js.map +1 -0
- package/dist/feishu/slash-commands.d.ts +77 -0
- package/dist/feishu/slash-commands.js +188 -0
- package/dist/feishu/slash-commands.js.map +1 -0
- package/dist/index.js +80 -17
- package/dist/index.js.map +1 -1
- package/dist/session/commands.d.ts +16 -1
- package/dist/session/commands.js +33 -1
- package/dist/session/commands.js.map +1 -1
- package/dist/session/plugin-command.d.ts +14 -0
- package/dist/session/plugin-command.js +110 -0
- package/dist/session/plugin-command.js.map +1 -0
- package/dist/types.d.ts +58 -0
- package/dist/util/open-browser.d.ts +1 -0
- package/dist/util/open-browser.js +20 -0
- package/dist/util/open-browser.js.map +1 -0
- package/dist/util/server-url.d.ts +3 -0
- package/dist/util/server-url.js +10 -0
- package/dist/util/server-url.js.map +1 -0
- package/dist/web/config-api.d.ts +50 -0
- package/dist/web/config-api.js +184 -0
- package/dist/web/config-api.js.map +1 -0
- package/dist/web/lifecycle.d.ts +52 -0
- package/dist/web/lifecycle.js +167 -0
- package/dist/web/lifecycle.js.map +1 -0
- package/dist/web/model-list.d.ts +36 -0
- package/dist/web/model-list.js +101 -0
- package/dist/web/model-list.js.map +1 -0
- package/dist/web/server.d.ts +22 -0
- package/dist/web/server.js +543 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/update.d.ts +26 -0
- package/dist/web/update.js +64 -0
- package/dist/web/update.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// 模型列表拉取(Web 配置页「拉取模型」按钮)。厂商无关:模型可能来自 Anthropic 官方、
|
|
2
|
+
// OpenAI 风格中转站或任意兼容网关,故 URL 拼接兼容带/不带 /v1 的 base、认证头双发、
|
|
3
|
+
// 响应形状宽容解析。纯函数与 fetch 分离(fetchFn 可注入,测试免网络)。
|
|
4
|
+
export const DEFAULT_MODEL_BASE = 'https://api.anthropic.com';
|
|
5
|
+
/** body 明文凭证优先;空/缺省回落磁盘 claude 段(带 profile_name 时回落该档案);两处皆无 → error(联合类型便于路由层直接 400) */
|
|
6
|
+
export function resolveModelFetchParams(body, disk) {
|
|
7
|
+
const pick = (v) => (typeof v === 'string' && v.trim() ? v.trim() : undefined);
|
|
8
|
+
// 档案编辑抽屉场景:body.profile_name 指定档案,磁盘回落取该档案(而非顶层)的凭证与 base_url
|
|
9
|
+
const pname = pick(body.profile_name);
|
|
10
|
+
const prof = pname ? disk?.profiles?.find((p) => p.name === pname) : undefined;
|
|
11
|
+
let baseUrl = pick(body.base_url);
|
|
12
|
+
if (!baseUrl)
|
|
13
|
+
baseUrl = (pname ? prof?.baseUrl : undefined) ?? disk?.baseUrl ?? DEFAULT_MODEL_BASE;
|
|
14
|
+
const bToken = pick(body.auth_token);
|
|
15
|
+
const bKey = pick(body.api_key);
|
|
16
|
+
// pname 命中档案时严格用档案凭证(档案选了哪种类型就按哪种,顶层不混入);否则回落顶层
|
|
17
|
+
const dToken = (pname && prof ? prof.authToken : disk?.authToken)?.trim() || undefined;
|
|
18
|
+
const dKey = (pname && prof ? prof.apiKey : disk?.apiKey)?.trim() || undefined;
|
|
19
|
+
// 优先级:body 明文(用户刚输入、尚未保存,按其选择的类型)> 磁盘(档案/顶层,token 型先于 key 型)
|
|
20
|
+
if (bToken)
|
|
21
|
+
return { baseUrl, credType: 'auth_token', credential: bToken };
|
|
22
|
+
if (bKey)
|
|
23
|
+
return { baseUrl, credType: 'api_key', credential: bKey };
|
|
24
|
+
if (dToken)
|
|
25
|
+
return { baseUrl, credType: 'auth_token', credential: dToken };
|
|
26
|
+
if (dKey)
|
|
27
|
+
return { baseUrl, credType: 'api_key', credential: dKey };
|
|
28
|
+
return {
|
|
29
|
+
error: '未找到可用凭证:请在表单填入 Auth Token / API Key 后重试(无须先保存),或保存 managed 模式凭证。'
|
|
30
|
+
+ 'inherit 模式使用本机 ~/.claude 登录,页面无法代取其凭证。',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** GET 模型列表的 URL+请求头:双发认证头(OpenAI 风格认 Bearer、Anthropic 风格认 x-api-key),
|
|
34
|
+
* anthropic-version 对非 Anthropic 网关是未知头、按惯例忽略,无害 */
|
|
35
|
+
export function buildModelListRequest(p) {
|
|
36
|
+
const base = p.baseUrl.replace(/\/+$/, ''); // 剥尾部斜杠
|
|
37
|
+
const url = /\/v\d+$/.test(base) ? `${base}/models` : `${base}/v1/models`;
|
|
38
|
+
return {
|
|
39
|
+
url,
|
|
40
|
+
headers: {
|
|
41
|
+
Accept: 'application/json',
|
|
42
|
+
'anthropic-version': '2023-06-01',
|
|
43
|
+
Authorization: `Bearer ${p.credential}`,
|
|
44
|
+
'x-api-key': p.credential,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** 宽容解析多形状模型列表:{data:[{id}]}(OpenAI/Anthropic 通用)/ {data:["id"]} / {models:[...]} / {result:[...]} */
|
|
49
|
+
export function parseModelList(payload) {
|
|
50
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
51
|
+
throw new Error('无法识别的响应格式(期望 JSON 对象含 data/models 数组)');
|
|
52
|
+
}
|
|
53
|
+
const candidates = payload.data
|
|
54
|
+
?? payload.models
|
|
55
|
+
?? payload.result;
|
|
56
|
+
if (!Array.isArray(candidates)) {
|
|
57
|
+
throw new Error('无法识别的响应格式(期望 data/models 数组)');
|
|
58
|
+
}
|
|
59
|
+
const ids = new Set();
|
|
60
|
+
for (const item of candidates) {
|
|
61
|
+
const id = typeof item === 'string' ? item
|
|
62
|
+
: (item && typeof item === 'object' && typeof item.id === 'string')
|
|
63
|
+
? item.id
|
|
64
|
+
: undefined;
|
|
65
|
+
if (id?.trim())
|
|
66
|
+
ids.add(id.trim());
|
|
67
|
+
}
|
|
68
|
+
return [...ids].sort();
|
|
69
|
+
}
|
|
70
|
+
/** 实际拉取:全局 fetch(Node≥20 自带),AbortController 超时;非 2xx 抛带状态码+截断 body 的 Error */
|
|
71
|
+
export async function fetchModelList(p, fetchFn = fetch, timeoutMs = 15000) {
|
|
72
|
+
const { url, headers } = buildModelListRequest(p);
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
75
|
+
let res;
|
|
76
|
+
try {
|
|
77
|
+
res = await fetchFn(url, { method: 'GET', headers, signal: controller.signal });
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
throw new Error(`模型列表请求失败:${e instanceof Error ? e.message : String(e)}(请检查 BASE_URL 可达性;也可直接手动填写模型名)`);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
clearTimeout(timer);
|
|
84
|
+
}
|
|
85
|
+
const text = await res.text().catch(() => '');
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
throw new Error(`模型列表拉取失败:HTTP ${res.status} ${text.slice(0, 200)}(也可直接手动填写模型名)`);
|
|
88
|
+
}
|
|
89
|
+
let payload;
|
|
90
|
+
try {
|
|
91
|
+
payload = JSON.parse(text);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
throw new Error(`响应不是合法 JSON(前 200 字符:${text.slice(0, 200) || '(空)'});也可直接手动填写模型名`);
|
|
95
|
+
}
|
|
96
|
+
const models = parseModelList(payload);
|
|
97
|
+
if (!models.length)
|
|
98
|
+
throw new Error('响应中没有模型条目;也可直接手动填写模型名');
|
|
99
|
+
return models;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=model-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-list.js","sourceRoot":"","sources":["../../src/web/model-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ServerConfig } from '../types.js';
|
|
2
|
+
export interface WebServerOptions {
|
|
3
|
+
/** server 段配置;缺省用默认(firstRun 无配置文件场景) */
|
|
4
|
+
server?: ServerConfig;
|
|
5
|
+
configPath?: string;
|
|
6
|
+
/** true = lcb start 内嵌(页面顶栏标识 + status.apps 显示启动态) */
|
|
7
|
+
embedded?: boolean;
|
|
8
|
+
/** 启动后自动开浏览器 */
|
|
9
|
+
autoOpen?: boolean;
|
|
10
|
+
appsStarted?: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
started: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
/** embedded 模式下页面停止/重启自身进程的优雅关闭回调(lcb start 注入 shutdown) */
|
|
15
|
+
selfStop?: () => void;
|
|
16
|
+
}
|
|
17
|
+
export interface WebServerHandle {
|
|
18
|
+
url: string;
|
|
19
|
+
port: number;
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function startWebServer(opts?: WebServerOptions): Promise<WebServerHandle | null>;
|