@jesonliu/lark-claudecode-bridge 1.0.4 → 1.0.6

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.
@@ -1,12 +1,14 @@
1
- // ============ 飞书扫码授权(设备流):页面内二维码弹窗 ============
2
- // 与「拉终端」并列的第二条授权路径——把 lark-cli 的 device flow 搬到配置页里,用户直接
3
- // 扫码完成,不用切窗口。它不经过终端探测,因此无桌面 / SSH 环境同样可用(那条路上
4
- // 「去终端授权」原本是无出口的死路)。
1
+ // ============ 飞书配置应用 / 扫码授权:页面内二维码弹窗 ============
2
+ // 与「拉终端」并列的第二条路径——把 lark-cli 的 config init 与 device flow 都搬到配置页里,
3
+ // 用户直接扫码完成,不用切窗口。它不经过终端探测,因此无桌面 / SSH 环境同样可用
4
+ // (那条路上「去终端」原本是无出口的死路)。
5
5
  //
6
- // 三段式(后端编排,见 src/lark-cli-manager.ts 的设备流一节):
7
- // ① POST /device/start → 拿 verification_url + 二维码(base64 PNG)
8
- // ② 用户用飞书扫码
9
- // ③ 后端后台跑 `auth login --device-code` 收尾,前端只轮询零成本的内存态端点
6
+ // 同一个弹窗里两个阶段(phase),因为它们是**一条连续的路**:
7
+ // config:应用还没配置时,先扫码创建/绑定飞书应用(后端 spawn `config init --new` 并
8
+ // 从其输出里流式解析授权链接——官方 README 与内置 skill 规定的用法)
9
+ // auth :再扫码授权(设备流,三段式见 src/lark-cli-manager.ts 的设备流一节)
10
+ // 配置完成后**自动接续**授权,用户不需要关掉弹窗再来一次(后端配置会话置 done 前
11
+ // 已用 checkAuth() 复检过「确实配上了」,所以接续时设备流的前置守卫必然放行)。
10
12
  //
11
13
  // **device_code 全程只存后端内存,从不下发到浏览器。**
12
14
  //
@@ -23,7 +25,12 @@ export function fmtRemain(sec) {
23
25
  return `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
24
26
  }
25
27
 
26
- /** 纯函数(可测):终态 → 给用户看的一句话 */
28
+ /** 纯函数(可测):与后端 needsLarkCliConfig 同源——detail 含 not_configured 即「未配置应用」 */
29
+ export function larkNotConfigured(r) {
30
+ return r?.auth?.state === 'unauthorized' && /not_configured/i.test(r?.auth?.detail || '');
31
+ }
32
+
33
+ /** 纯函数(可测):授权阶段终态 → 给用户看的一句话 */
27
34
  export function deviceStateHint(state, error) {
28
35
  if (state === 'done') return '✅ 授权完成,可以关闭本弹窗了。';
29
36
  if (state === 'expired') return error || '二维码已过期,请重新生成。';
@@ -33,19 +40,39 @@ export function deviceStateHint(state, error) {
33
40
  return '';
34
41
  }
35
42
 
43
+ /** 纯函数(可测):配置阶段终态 → 给用户看的一句话 */
44
+ export function configStateHint(state, error) {
45
+ if (state === 'done') return '✅ 飞书应用已配置,接着申请授权二维码。';
46
+ if (state === 'expired') return error || '配置链接已失效,请重新生成二维码。';
47
+ // 配置这条路每一步都在浏览器里,失败原因多半是「没走完」——把两个出口都点出来
48
+ if (state === 'failed') return error || '配置未完成,可重新生成二维码再试,或改用终端窗口。';
49
+ if (state === 'none') return error || '配置会话已失效(桥接器可能已重启),请重新生成二维码。';
50
+ return '';
51
+ }
52
+
53
+ const STATE_TAG = { done: 'ok', expired: 'warn', failed: 'warn', none: 'warn' };
54
+ const STATE_LABEL = {
55
+ config: { done: '已配置', expired: '已过期', failed: '未完成', none: '未完成' },
56
+ auth: { done: '已授权', expired: '已过期', failed: '未完成', none: '未完成' },
57
+ };
58
+
36
59
  /**
37
- * 打开扫码授权弹窗。
60
+ * 打开飞书配置 / 扫码授权弹窗。未配置应用时自动进入 config 阶段,配完接续 auth 阶段。
38
61
  * @param {object} opts
39
62
  * @param {(r:any)=>void} [opts.onChange] 收到最新 /api/lark-cli 结果时回调,用于同步刷新概览行
40
- * @param {()=>void} [opts.onTerminal] 用户选「改用终端窗口」时回调,接回既有终端链路
63
+ * @param {()=>void} [opts.onTerminal] 授权阶段选「改用终端窗口」时回调
64
+ * @param {()=>void} [opts.onConfigTerminal] 配置阶段选「改用终端窗口」时回调
41
65
  * @param {boolean} [opts.wasAuthorized] 打开时的授权态快照:区分「本来就好」与「本次扫码完成」
66
+ * @param {boolean} [opts.notConfigured] 应用未配置(not_configured):先走 config 阶段
42
67
  */
43
- export function openLarkCliDeviceDialog({ onChange, onTerminal, wasAuthorized = false } = {}) {
68
+ export function openLarkCliDeviceDialog({
69
+ onChange, onTerminal, onConfigTerminal, wasAuthorized = false, notConfigured = false,
70
+ } = {}) {
44
71
  const { mask, unmount } = mountDialog(`
45
72
  <div class="modal dlg" role="dialog" aria-modal="true" style="width:min(520px,94vw)">
46
- <h3 class="dlg-title">飞书授权(扫码完成)</h3>
47
- <div class="dlg-msg">用飞书 App 扫描下方二维码,按提示确认授权。授权成功后本页会自动更新。</div>
48
- <div id="lqdBody"><div class="hint">正在向飞书申请授权二维码…</div></div>
73
+ <h3 class="dlg-title" id="lqdTitle">飞书授权(扫码完成)</h3>
74
+ <div class="dlg-msg" id="lqdLead"></div>
75
+ <div id="lqdBody"><div class="hint">正在向飞书申请二维码…</div></div>
49
76
  <div class="dlg-foot">
50
77
  <button class="btn" data-lqd="terminal">改用终端窗口</button>
51
78
  <button class="btn" data-lqd="copy" hidden>复制链接</button>
@@ -54,10 +81,19 @@ export function openLarkCliDeviceDialog({ onChange, onTerminal, wasAuthorized =
54
81
  </div>
55
82
  </div>`);
56
83
 
84
+ const titleEl = mask.querySelector('#lqdTitle');
85
+ const leadEl = mask.querySelector('#lqdLead');
57
86
  const body = mask.querySelector('#lqdBody');
58
87
  const btnCopy = mask.querySelector('[data-lqd="copy"]');
59
88
  const btnRegen = mask.querySelector('[data-lqd="regen"]');
89
+ const btnTerminal = mask.querySelector('[data-lqd="terminal"]');
90
+ const btnClose = mask.querySelector('[data-lqd="close"]');
91
+
92
+ // needConfig 必须是可变绑定:配置完成后就地翻掉,doStart 才能接着走授权
93
+ let needConfig = !!notConfigured;
94
+ let phase = needConfig ? 'config' : 'auth';
60
95
  let session = null; // 最近一次 start 的响应(存链接与二维码)
96
+ let painted = {}; // 已画出去的内容:相同内容不重画,免得二维码每隔 2s 闪一下
61
97
  let baseLeft = 0; // 服务端给的剩余秒数
62
98
  let baseAt = 0; // 收到该秒数时的本地时刻
63
99
  let poll = null;
@@ -73,53 +109,90 @@ export function openLarkCliDeviceDialog({ onChange, onTerminal, wasAuthorized =
73
109
  // 一个一打开就已过期的二维码
74
110
  const remainNow = () => Math.max(0, baseLeft - (Date.now() - baseAt) / 1000);
75
111
 
76
- const paintReady = (s) => {
112
+ const setLead = (text) => { leadEl.textContent = text; };
113
+ const setTitle = (text) => { titleEl.textContent = text; };
114
+
115
+ const hideActions = () => { btnCopy.hidden = true; btnRegen.hidden = true; };
116
+
117
+ const paintQr = (s) => {
77
118
  const qr = s.qrDataUrl
78
- ? `<div class="qr-box"><img src="${esc(s.qrDataUrl)}" alt="飞书授权二维码" width="220" height="220"></div>`
119
+ ? `<div class="qr-box"><img src="${esc(s.qrDataUrl)}" alt="飞书二维码" width="220" height="220"></div>`
79
120
  : '<div class="hint" style="margin-top:8px">二维码生成失败,请复制下方链接在飞书中打开。</div>';
121
+ // 倒计时只在服务端给了有效期时才显示:配置流拿不到有效期,编一个数字只会误导用户
122
+ const life = typeof s.expiresInSec === 'number'
123
+ ? `二维码 <b id="lqdLeft">${fmtRemain(remainNow())}</b> 后失效`
124
+ : '若二维码失效,点「重新生成二维码」即可';
80
125
  body.innerHTML = qr
81
- + `<div class="hint" style="margin-top:8px">二维码 <b id="lqdLeft">${fmtRemain(remainNow())}</b> 后失效`
126
+ + `<div class="hint" style="margin-top:8px">${life}`
82
127
  + (s.userCode ? ` · 授权码 <span class="chip">${esc(s.userCode)}</span>` : '')
83
128
  + '</div>'
84
129
  + `<div class="hint qr-url">${esc(s.verificationUrl || '')}</div>`;
85
130
  btnCopy.hidden = false;
86
131
  btnRegen.hidden = false;
132
+ painted = { url: s.verificationUrl, qr: s.qrDataUrl };
87
133
  };
88
134
 
89
135
  const paintDone = (state, { identity, error } = {}) => {
90
- const tag = state === 'done' ? 'ok' : 'warn';
91
- const label = state === 'done' ? '已授权' : state === 'expired' ? '已过期' : '未完成';
92
- body.innerHTML = `<div><span class="tag ${tag}">${label}</span>`
136
+ const label = (STATE_LABEL[phase] || STATE_LABEL.auth)[state] || '未完成';
137
+ const hint = phase === 'config' ? configStateHint(state, error) : deviceStateHint(state, error);
138
+ body.innerHTML = `<div><span class="tag ${STATE_TAG[state] || 'warn'}">${label}</span>`
93
139
  + (identity ? ` <span class="chip">${esc(identity)}</span>` : '')
94
140
  + '</div>'
95
- + `<div class="hint" style="margin-top:8px">${esc(deviceStateHint(state, error))}</div>`;
141
+ + `<div class="hint" style="margin-top:8px">${esc(hint)}</div>`;
96
142
  btnCopy.hidden = true;
97
143
  btnRegen.hidden = state === 'done';
98
144
  };
99
145
 
146
+ /** 后端把前置问题写成了可照做的文案(未安装 / 探测不出 / 已配置),直接透出 */
147
+ const paintFail = (msg) => {
148
+ body.innerHTML = '<div><span class="tag warn">无法发起</span></div>'
149
+ + `<div class="hint" style="margin-top:8px">${esc(msg)}</div>`;
150
+ btnCopy.hidden = true;
151
+ btnRegen.hidden = false; // 给出路:失败也要能重来,不留死胡同
152
+ };
153
+
100
154
  /** 拉一次概览数据同步行内状态(拿不到就算了,别让弹窗崩) */
101
155
  const syncRow = async () => {
102
- if (!onChange) return;
156
+ if (!onChange) return null;
103
157
  const cur = await api('GET', '/api/lark-cli').catch(() => null);
104
158
  if (cur) onChange(cur);
105
159
  return cur;
106
160
  };
107
161
 
162
+ const startPolling = () => {
163
+ poll = setInterval(doPoll, POLL_MS);
164
+ tick = setInterval(() => {
165
+ const el = body.querySelector('#lqdLeft');
166
+ if (el) el.textContent = fmtRemain(remainNow());
167
+ }, TICK_MS);
168
+ };
169
+
108
170
  const doPoll = async () => {
109
171
  if (closed) return;
172
+ const endpoint = phase === 'config' ? '/api/lark-cli/config/status' : '/api/lark-cli/device/status';
110
173
  let r;
111
174
  try {
112
- r = await api('GET', '/api/lark-cli/device/status');
175
+ r = await api('GET', endpoint);
113
176
  } catch {
114
177
  return; // 静默重试:桥接器重启时会短暂失联,弹错反而吓人
115
178
  }
116
179
  if (closed) return;
117
180
  if (r.state === 'pending') {
118
- // 以服务端时间为准校正倒计时基准(每次轮询都对一次表)
119
- baseLeft = r.expiresInSec ?? remainNow();
120
- baseAt = Date.now();
181
+ if (phase === 'auth') {
182
+ // 以服务端时间为准校正倒计时基准(每次轮询都对一次表)
183
+ baseLeft = r.expiresInSec ?? remainNow();
184
+ baseAt = Date.now();
185
+ return;
186
+ }
187
+ // 配置流:链接与二维码要等子进程吐出来。start 若没等到就返回了,这里补画
188
+ // (内容没变就不重画——每 2s 重建一次 <img> 会让二维码闪)
189
+ if (r.verificationUrl && (painted.url !== r.verificationUrl || painted.qr !== r.qrDataUrl)) {
190
+ session = { ...(session || {}), ...r };
191
+ paintQr(session);
192
+ }
121
193
  return;
122
194
  }
195
+ if (phase === 'config') return finishConfigPhase(r);
123
196
  stopTimers();
124
197
  if (r.state === 'none') {
125
198
  // 内存态被冲(桥接器重启),但用户可能已经扫完了:回查授权态兜底,
@@ -133,31 +206,88 @@ export function openLarkCliDeviceDialog({ onChange, onTerminal, wasAuthorized =
133
206
  paintDone(r.state, { identity: r.identity, error: r.error });
134
207
  };
135
208
 
136
- const doStart = async (regenerate) => {
209
+ /**
210
+ * 配置完成 → 同一个弹窗里就地接续授权,兑现「完成后自动接着走授权登录」的承诺。
211
+ * 后端置 done 之前已用 checkAuth() 复检确认应用真的配上了,所以设备流的前置守卫必然放行。
212
+ */
213
+ const continueToAuth = async () => {
214
+ phase = 'auth';
215
+ needConfig = false;
216
+ await syncRow(); // 概览行先翻成「已配置」
217
+ if (closed) return;
218
+ toast('✅ 飞书应用已配置,接着申请授权二维码');
219
+ await startAuth(false);
220
+ };
221
+
222
+ const finishConfigPhase = async (r) => {
137
223
  stopTimers();
224
+ if (r.state === 'done') return continueToAuth();
225
+ if (r.state === 'none') {
226
+ // 内存态被冲(桥接器重启),但用户可能已经在浏览器里配完了:回查兜底
227
+ const cur = await syncRow();
228
+ if (cur && !larkNotConfigured(cur)) return continueToAuth();
229
+ }
230
+ return paintDone(r.state, { error: r.error });
231
+ };
232
+
233
+ const startAuth = async (regenerate) => {
234
+ stopTimers();
235
+ setTitle('飞书授权(扫码完成)');
236
+ setLead('用飞书 App 扫描下方二维码,按提示确认授权。授权成功后本页会自动更新。');
138
237
  body.innerHTML = '<div class="hint">正在向飞书申请授权二维码…</div>';
139
- btnCopy.hidden = true;
140
- btnRegen.hidden = true;
238
+ hideActions();
141
239
  try {
142
240
  session = await api('POST', '/api/lark-cli/device/start', { regenerate: !!regenerate });
143
241
  } catch (e) {
144
242
  // 后端把「未安装」「应用未配置」等前置问题写成了可照做的文案,直接透出
145
- body.innerHTML = `<div><span class="tag warn">无法发起</span></div>`
146
- + `<div class="hint" style="margin-top:8px">${esc(e.message)}</div>`;
147
- toast(e.message, true);
243
+ paintFail(e.message);
148
244
  return;
149
245
  }
150
246
  if (closed) return;
151
247
  baseLeft = session.expiresInSec ?? 0;
152
248
  baseAt = Date.now();
153
- paintReady(session);
154
- poll = setInterval(doPoll, POLL_MS);
155
- tick = setInterval(() => {
156
- const el = body.querySelector('#lqdLeft');
157
- if (el) el.textContent = fmtRemain(remainNow());
158
- }, TICK_MS);
249
+ painted = {};
250
+ paintQr(session);
251
+ startPolling();
159
252
  };
160
253
 
254
+ const startConfig = async (regenerate) => {
255
+ stopTimers();
256
+ setTitle('飞书配置(扫码完成)');
257
+ setLead('用飞书 App 扫描下方二维码,按提示创建或绑定飞书应用。'
258
+ + '完成后会自动接着申请授权二维码,不用回到本页重来。');
259
+ body.innerHTML = '<div class="hint">正在向飞书申请配置二维码…</div>';
260
+ hideActions();
261
+ try {
262
+ session = await api('POST', '/api/lark-cli/config/start', { regenerate: !!regenerate });
263
+ } catch (e) {
264
+ // 打开弹窗时的 notConfigured 快照可能已经过期(用户刚在别处配好了,后端据此拒绝)。
265
+ // 回查一次,确实已配置就直接接续授权,而不是把一个已经过时的错误甩给用户。
266
+ const cur = await syncRow();
267
+ if (cur && !larkNotConfigured(cur)) return continueToAuth();
268
+ paintFail(e.message);
269
+ return;
270
+ }
271
+ if (closed) return;
272
+ painted = {};
273
+ if (session.state === 'pending') {
274
+ if (session.verificationUrl) paintQr(session);
275
+ else paintWait(); // 链接要等子进程输出,交给轮询补画
276
+ startPolling();
277
+ return;
278
+ }
279
+ return paintDone(session.state, { error: session.error });
280
+ };
281
+
282
+ /** 配置链接还没吐出来时的过渡态(仍然给「重新生成」这条出路,不让人干等) */
283
+ const paintWait = () => {
284
+ body.innerHTML = '<div class="hint">正在向飞书申请配置二维码…(通常几秒内出现)</div>';
285
+ btnCopy.hidden = true;
286
+ btnRegen.hidden = false;
287
+ };
288
+
289
+ const doStart = (regenerate) => (phase === 'config' ? startConfig(regenerate) : startAuth(regenerate));
290
+
161
291
  const close = () => {
162
292
  closed = true;
163
293
  stopTimers();
@@ -166,17 +296,21 @@ export function openLarkCliDeviceDialog({ onChange, onTerminal, wasAuthorized =
166
296
  };
167
297
  const unbind = bindDialogKeys((k) => { if (k === 'Escape') close(); });
168
298
 
169
- mask.querySelector('[data-lqd="close"]').onclick = close;
170
- mask.querySelector('[data-lqd="regen"]').onclick = () => void doStart(true);
299
+ btnClose.onclick = close;
300
+ btnRegen.onclick = () => void doStart(true);
171
301
  // 关弹窗**不动后端会话**(沿用终端弹窗「关弹窗不中断流程」的既有理念):
172
- // 重新打开时 start 不带 regenerate → 后端幂等复用同一个 device code,二维码原样回来
173
- mask.querySelector('[data-lqd="terminal"]').onclick = () => { close(); onTerminal?.(); };
302
+ // 重新打开时 start 不带 regenerate → 后端幂等复用同一个会话,二维码原样回来
303
+ btnTerminal.onclick = () => {
304
+ const cb = phase === 'config' ? onConfigTerminal : onTerminal;
305
+ close();
306
+ cb?.();
307
+ };
174
308
  btnCopy.onclick = async () => {
175
309
  const url = session?.verificationUrl;
176
310
  if (!url) return;
177
311
  try {
178
312
  await navigator.clipboard.writeText(url);
179
- toast('授权链接已复制');
313
+ toast('链接已复制');
180
314
  } catch {
181
315
  toast('复制失败,请手动选中链接复制', true);
182
316
  }
@@ -2,7 +2,9 @@
2
2
  // 桥接器启停 / 版本更新(宿主进程管理:embedded 页面随进程生死,独立页面经 PID 跨进程操作)
3
3
  import { S, $, esc, toast, api, refresh } from '../core.js';
4
4
  import { bindDialogKeys, confirmDialog, mountDialog, progressDialog } from '../ui.js';
5
- import { openLarkCliDeviceDialog } from './larkcli-device.js';
5
+ // larkNotConfigured 与后端 needsLarkCliConfig 同源(detail 含 not_configured 即「未配置应用」),
6
+ // 判定只有一份、放在弹窗模块里,避免两处漂移
7
+ import { larkNotConfigured, openLarkCliDeviceDialog } from './larkcli-device.js';
6
8
 
7
9
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
8
10
  const UPD = { checkedAt: 0, data: null };
@@ -122,11 +124,12 @@ async function doCheckUpdate() {
122
124
  async function runUpdateFlow() {
123
125
  const running = S.status?.embedded || S.status?.bridge?.running;
124
126
  const extra = running ? ',完成后自动重启桥接器(页面将短暂失联后自动恢复)' : '(桥接器未在运行,下次启动生效)';
125
- if (!(await confirmDialog({ title: '一键更新', message: `将通过 npm 安装最新版本并同步更新飞书 CLI(@larksuite/cli)${extra},可能需要 1-2 分钟。`, confirmText: '开始更新' }))) return;
127
+ if (!(await confirmDialog({ title: '一键更新', message: `将通过 npm 安装桥接器最新版本${extra},可能需要 1-2 分钟。`, confirmText: '开始更新' }))) return;
126
128
  const btn = $('#btnUpdRun');
127
129
  if (btn) { btn.disabled = true; btn.textContent = '更新中…'; }
128
130
  try {
129
- await api('POST', '/api/update/run', { larkCli: true });
131
+ // 只更新桥接器自身:飞书 CLI 的更新在它自己那一行点「更新」,两条更新各自独立
132
+ await api('POST', '/api/update/run');
130
133
  UPD.checkedAt = 0; LARKCLI.checkedAt = 0;
131
134
  if (running) await restartFlow();
132
135
  else toast('✅ 更新完成,下次启动生效');
@@ -137,11 +140,6 @@ async function runUpdateFlow() {
137
140
  }
138
141
  }
139
142
 
140
- /** 纯函数(可测):与后端 needsLarkCliConfig 同源——detail 含 not_configured 即「未配置应用」 */
141
- function larkCliNotConfigured(r) {
142
- return r?.auth?.state === 'unauthorized' && /not_configured/i.test(r?.auth?.detail || '');
143
- }
144
-
145
143
  /** 纯函数(可测):概览表格行里「飞书 CLI」的状态 HTML(不含操作按钮,按钮由 render 按需挂) */
146
144
  export function larkCliStatHtml(r) {
147
145
  if (!r) return '<span class="hint">未检查</span>';
@@ -162,14 +160,29 @@ export function larkCliStatHtml(r) {
162
160
  }
163
161
 
164
162
  /**
165
- * 扫码授权弹窗(授权主路径)。弹窗里的「改用终端窗口」接回既有终端链路——
166
- * 那条路一行没改,仍是拉不起无桌面环境时的兜底,也保留了在终端里补跑命令的能力。
163
+ * 纯函数(可测):概览行主入口按钮的文案——按「点开后会先走哪一步」命名,
164
+ * 不出现「按钮写扫码授权、点开弹窗却是配置二维码」的错位。
165
+ * 未配置应用时弹窗从 config 阶段起步(见 openDeviceDialog 与 larkcli-device.js),故叫「配置应用」。
166
+ * 探测不出(unknown)**不**算未配置:误判会把已配好应用的用户反复推去重配,按「扫码授权」处理。
167
+ */
168
+ export function larkCliPrimaryLabel(r) {
169
+ if (r?.auth?.state === 'authorized') return '重新授权';
170
+ return larkNotConfigured(r) ? '配置应用' : '扫码授权';
171
+ }
172
+
173
+ /**
174
+ * 扫码弹窗(配置 + 授权的主路径)。未配置应用时它从**配置阶段**起步:页面内直接出示
175
+ * 配置二维码,用户扫完在浏览器里建好应用,弹窗自动接续出示授权二维码——全程不切窗口,
176
+ * 无桌面 / SSH 环境下同样走得通(那条路上「去终端向导」原本是无出口的死路)。
177
+ * 两个阶段的「改用终端窗口」都接回既有终端链路:那条路一行没改,保留补跑命令的能力。
167
178
  */
168
179
  function openDeviceDialog() {
169
180
  openLarkCliDeviceDialog({
170
181
  wasAuthorized: LARKCLI.data?.auth?.state === 'authorized',
182
+ notConfigured: larkNotConfigured(LARKCLI.data),
171
183
  onChange: (r) => { LARKCLI.data = r; LARKCLI.checkedAt = Date.now(); renderLarkCliResult(); },
172
184
  onTerminal: () => void larkCliActionFlow('auth'),
185
+ onConfigTerminal: () => void larkCliActionFlow('config'),
173
186
  });
174
187
  }
175
188
 
@@ -190,12 +203,13 @@ function renderLarkCliResult() {
190
203
  };
191
204
  if (!r.installed) { add('安装', 'install'); return; }
192
205
  if (r.hasUpdate) add('更新', 'update');
193
- // 未配置应用(not_configured)优先给「配置应用」向导;其余一律给授权入口——
194
- // 已授权也给(token 会过期,随时可重走一遍 device flow 刷新)。
195
- // 授权走**页面内二维码**(主路径,无桌面环境同样可用);终端窗口降级为弹窗里的备选。
196
- if (larkCliNotConfigured(r)) add('配置应用', 'config');
197
- else if (r.auth?.state === 'authorized') add('重新授权', 'auth-device');
198
- else add('扫码授权', 'auth-device');
206
+ // 入口常驻,且已授权也给(token 会过期,随时可重走一遍 device flow 刷新)。
207
+ // 走**页面内二维码**(主路径,无桌面环境同样可用);终端窗口降级为弹窗里的备选。
208
+ // 文案跟着「弹窗会先走哪一步」走(见 larkCliPrimaryLabel):未配置应用时弹窗从配置阶段
209
+ // 起步、先出配置二维码,按钮就叫「配置应用」;已配置才是「扫码授权」。
210
+ // **入口数量不变**——三种状态都是同一个弹窗(op 一律 auth-device),只是弹窗按前置条件
211
+ // 决定先出哪种二维码(见 openDeviceDialog 与 larkcli-device.js)。
212
+ add(larkCliPrimaryLabel(r), 'auth-device');
199
213
  if (r.skill && !r.skill.installed) add('装 SKILL', 'skill');
200
214
  }
201
215
 
@@ -331,6 +345,8 @@ async function larkCliActionFlow(op = 'install') {
331
345
  },
332
346
  config: {
333
347
  what: '配置应用',
348
+ // 这是**备选**路径:主路径已改成弹窗里的配置二维码(见 larkcli-device.js 的 config 阶段),
349
+ // 只有用户在弹窗里显式点「改用终端窗口」才会走到这里
334
350
  msg: '将打开一个终端窗口执行 <code>lark-cli config init --new</code>:按窗口打印的链接在浏览器完成飞书应用创建,'
335
351
  + '完成后会自动进入授权登录。'
336
352
  + '<br><br>若本机没有可用终端(无桌面 / SSH 会话),需在服务器上手动执行该命令。',
@@ -346,7 +362,11 @@ async function larkCliActionFlow(op = 'install') {
346
362
  const rowBtn = $('#larkCliArea button');
347
363
  if (rowBtn) rowBtn.disabled = true;
348
364
  // 先弹进度框再发请求:静默降级那条路最长 5 分钟,没有它页面会静默无反馈
349
- const dlg = progressDialog({ title: `飞书 CLI ${what}`, note: op === 'skill' ? '正在安装 SKILL…' : '正在探测可用终端…' });
365
+ const dlg = progressDialog({
366
+ title: `飞书 CLI ${what}`,
367
+ note: op === 'skill' ? '正在安装 SKILL…' : '正在探测可用终端…',
368
+ reportMaxHeight: op === 'skill' ? 360 : 220, // SKILL 要列 28 条名单,默认 220px 只够十来行
369
+ });
350
370
  try {
351
371
  const r = await api('POST', '/api/lark-cli/action', { op });
352
372
  if (r.mode === 'terminal') {
@@ -354,7 +374,14 @@ async function larkCliActionFlow(op = 'install') {
354
374
  openLarkCliTerminalDialog(op);
355
375
  toast('已拉起终端窗口,请在终端里完成操作');
356
376
  } else {
357
- dlg.setNote(String(r.output || '').trim().slice(-600) || '完成');
377
+ // SKILL 装完展示扫盘得到的名单,而不是 npx 那段带 ANSI 的进度表原文
378
+ // (名单由后端 listLarkCliSkills 扫 ~/.claude/skills 得出,比解析输出可靠)
379
+ if (op === 'skill' && Array.isArray(r.skills) && r.skills.length) {
380
+ dlg.setNote(`已同步 ${r.skills.length} 个 SKILL\n\n`
381
+ + r.skills.map((s) => `• ${s}`).join('\n'));
382
+ } else {
383
+ dlg.setNote(String(r.output || '').trim().slice(-600) || '完成');
384
+ }
358
385
  if (r.reason) dlg.appendLog(`⚠️ 未使用终端:${r.reason}`);
359
386
  const done = op === 'skill' ? '✅ SKILL 安装完成,重启桥接器后飞书会话可见' : `✅ 飞书 CLI ${what}完成`;
360
387
  dlg.finish(true, done);
@@ -200,8 +200,11 @@ export function initDrawer() {
200
200
  * 观感与 plugins.js 的 runOpDialog 一致,但那个与插件页的 busyText / report / update-all 的
201
201
  * 真实 i/N 推进深度耦合,泛化它等于改一个正在工作的界面(`main.css` 明确要求向后兼容)。
202
202
  * 这里单独实现语义单一的版本,重复记为可接受代价。
203
+ *
204
+ * @param {number} [opts.reportMaxHeight] 输出区最大高度(px)。默认 220 适合几行总结;
205
+ * 要展示成片清单(如 SKILL 名单)的调用方传更大的值。
203
206
  */
204
- export function progressDialog({ title = '执行中', note = '请稍候…' } = {}) {
207
+ export function progressDialog({ title = '执行中', note = '请稍候…', reportMaxHeight = 220 } = {}) {
205
208
  const { mask, unmount } = mountDialog(`
206
209
  <div class="modal" role="dialog" aria-modal="true" style="width:min(640px,94vw)">
207
210
  <div style="display:flex;align-items:center;gap:10px">
@@ -209,7 +212,7 @@ export function progressDialog({ title = '执行中', note = '请稍候…' } =
209
212
  <b class="pd-title">${esc(title)}</b>
210
213
  </div>
211
214
  <div class="prog"><div class="prog-bar"></div></div>
212
- <pre class="report" style="margin-top:12px;max-height:220px"></pre>
215
+ <pre class="report" style="margin-top:12px;max-height:${Number(reportMaxHeight) || 220}px"></pre>
213
216
  <div class="savebar" style="justify-content:flex-end">
214
217
  <button class="btn primary" hidden>关闭</button>
215
218
  </div>
package/dist/bin/lcb.js CHANGED
@@ -16,7 +16,7 @@ import { VERSION } from '../version.js';
16
16
  import { join } from 'node:path';
17
17
  import { ensureRuntimeDirs } from '../util/runtime-dirs.js';
18
18
  import { installLogTee, cleanupOldLogs } from '../util/log-tee.js';
19
- import { ensureLarkCli, AGENT_CONTEXT_ENV_KEYS } from '../lark-cli-manager.js';
19
+ import { checkLarkCliAtStartup, AGENT_CONTEXT_ENV_KEYS } from '../lark-cli-manager.js';
20
20
  function showPending(access) {
21
21
  const pending = access.listPending();
22
22
  if (pending.length)
@@ -64,9 +64,10 @@ async function main() {
64
64
  // claude 会话(飞书里跑 lark-cli 命令)、web API 探测等所有下游子进程一并干净
65
65
  for (const k of AGENT_CONTEXT_ENV_KEYS)
66
66
  delete process.env[k];
67
- // 深度拥抱飞书:后台检测/安装官方 Lark CLI(@larksuite/cli),不 await 不阻塞启动;
68
- // 失败仅告警(npm 源不可达等不影响桥接器本身)
69
- void ensureLarkCli().catch((e) => console.warn('[lark-cli] 检测流程异常(不影响启动):', e instanceof Error ? e.message : e));
67
+ // 深度拥抱飞书:后台**只检测**官方 Lark CLI(@larksuite/cli)并提示去处,不 await
68
+ // 不阻塞启动。安装/更新/授权统一下沉到 Web 配置页——启动时静默装会让用户跳过
69
+ // 官方流程的 config/auth 两步,打开配置页时 CLI 就绪却无从授权(见 checkLarkCliAtStartup)
70
+ void checkLarkCliAtStartup().catch((e) => console.warn('[lark-cli] 检测流程异常(不影响启动):', e instanceof Error ? e.message : e));
70
71
  await startBridge(CONFIG_PATH);
71
72
  // 前台监听 stdin:管理员可直接在运行终端输入配对码批准。
72
73
  // 现读现批(每次 load 新实例再 approve):桥运行中 beginPairing 写入的新 pending
@@ -1 +1 @@
1
- {"version":3,"file":"lcb.js","sourceRoot":"","sources":["../../src/bin/lcb.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lcb.js","sourceRoot":"","sources":["../../src/bin/lcb.ts"],"names":[],"mappings":"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"}