@jesonliu/lark-claudecode-bridge 1.0.6 → 1.2.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 +6 -4
- package/assets/web/css/main.css +46 -0
- package/assets/web/index.html +1 -0
- package/assets/web/js/pages/apps.js +118 -6
- package/assets/web/js/pages/claude.js +4 -7
- package/assets/web/js/pages/overview.js +57 -8
- package/assets/web/js/pages/permissions.js +45 -10
- package/assets/web/js/ui.js +167 -0
- package/config.example.yaml +20 -2
- package/dist/config-defaults.js +2 -1
- package/dist/config-defaults.js.map +1 -1
- package/dist/config.d.ts +4 -2
- package/dist/config.js +80 -5
- package/dist/config.js.map +1 -1
- package/dist/executor/claude-executor.d.ts +3 -0
- package/dist/executor/claude-executor.js +3 -0
- package/dist/executor/claude-executor.js.map +1 -1
- package/dist/executor/notify-server.d.ts +4 -18
- package/dist/executor/notify-server.js +6 -74
- package/dist/executor/notify-server.js.map +1 -1
- package/dist/executor/permission-gate.d.ts +10 -0
- package/dist/executor/permission-gate.js +24 -7
- package/dist/executor/permission-gate.js.map +1 -1
- package/dist/gateway/card-builder.d.ts +30 -19
- package/dist/gateway/card-builder.js +63 -46
- package/dist/gateway/card-builder.js.map +1 -1
- package/dist/gateway/diff-card.d.ts +1 -2
- package/dist/gateway/diff-card.js +2 -3
- package/dist/gateway/diff-card.js.map +1 -1
- package/dist/gateway/feishu-gateway.d.ts +2 -2
- package/dist/gateway/feishu-gateway.js +35 -5
- package/dist/gateway/feishu-gateway.js.map +1 -1
- package/dist/gateway/progress-card.d.ts +15 -5
- package/dist/gateway/progress-card.js +29 -14
- package/dist/gateway/progress-card.js.map +1 -1
- package/dist/index.js +198 -94
- package/dist/index.js.map +1 -1
- package/dist/notify-sop.d.ts +1 -1
- package/dist/notify-sop.js +21 -26
- package/dist/notify-sop.js.map +1 -1
- package/dist/session/commands.d.ts +20 -2
- package/dist/session/commands.js +58 -17
- package/dist/session/commands.js.map +1 -1
- package/dist/types.d.ts +27 -7
- package/dist/web/autostart.d.ts +49 -0
- package/dist/web/autostart.js +250 -0
- package/dist/web/autostart.js.map +1 -0
- package/dist/web/config-api.js +14 -2
- package/dist/web/config-api.js.map +1 -1
- package/dist/web/server.js +38 -1
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -30,6 +30,18 @@ export interface FeishuAppConfig {
|
|
|
30
30
|
* 通常无须配置:~/.claude 已启用的 marketplace 插件由 plugin-discovery 自动加载;
|
|
31
31
|
* 显式配置用于开发期直指源码目录(同名时优先于自动发现) */
|
|
32
32
|
plugins?: PluginRef[];
|
|
33
|
+
/** 机器人角色:primary(缺省,主机器人——全技能/全插件/全工作区,配对码准入);
|
|
34
|
+
* deputy(分身——按用途限定能力,艾特即用,供他人使用)。存量配置未配 role 行为不变 */
|
|
35
|
+
role?: 'primary' | 'deputy';
|
|
36
|
+
/** deputy 专用:技能白名单(必填,透传 SDK Options.skills)——未列出的技能对模型不可见
|
|
37
|
+
* 且被 Skill 工具拒绝。注意 SDK 官方语义是「上下文过滤器非沙箱」:技能文件仍在磁盘、
|
|
38
|
+
* 可被 Read/Bash 读到,硬隔离需配合工具级限制(本期按用户决策不做) */
|
|
39
|
+
allowedSkills?: string[];
|
|
40
|
+
/** deputy 专用:插件白名单(可选)——自动发现的插件按 name 过滤,未列出的剔除;
|
|
41
|
+
* 显式 app.plugins 始终保留(开发期直指源码目录的场景) */
|
|
42
|
+
allowedPlugins?: string[];
|
|
43
|
+
/** deputy 专用:工作区锁定(必填)——任务强制运行在首个允许的工作区,/ws 切换被拒 */
|
|
44
|
+
allowedWorkspaces?: string[];
|
|
33
45
|
}
|
|
34
46
|
/** 工作区:name + path。旧版 type(code-dev/generic)已废弃(#6)——计划模式改为
|
|
35
47
|
* 通道级 /plan 命令切换,diff 收尾改为 git 仓库自动判定;旧配置携带 type 仅 warn 忽略 */
|
|
@@ -38,10 +50,13 @@ export interface Workspace {
|
|
|
38
50
|
path: string;
|
|
39
51
|
}
|
|
40
52
|
/** 权限白名单配置:字段可选——未配置的字段回退内置默认(读工具 + Bash + 危险命令表,见 permission-gate)。
|
|
41
|
-
* allowTools 配置即整体替换内置默认(不与默认合并);dangerousCommands 为 Bash
|
|
53
|
+
* allowTools 配置即整体替换内置默认(不与默认合并);dangerousCommands 为 Bash 危险命令正则(命中弹确认卡);
|
|
54
|
+
* allowAllTools 为「全部工具免确认」开关,缺省开——开启后除命中 dangerousCommands 的 Bash 外一律直通,
|
|
55
|
+
* 关闭则回落 allowTools 白名单语义 */
|
|
42
56
|
export interface PermissionsConfig {
|
|
43
57
|
allowTools?: string[];
|
|
44
58
|
dangerousCommands?: RegExp[];
|
|
59
|
+
allowAllTools?: boolean;
|
|
45
60
|
}
|
|
46
61
|
/** Web 配置页服务器(lcb start / lcb ui 内嵌,node:http 零依赖):enabled/host/port 均为启动时读取,改动需重启 */
|
|
47
62
|
export interface ServerConfig {
|
|
@@ -127,6 +142,11 @@ export interface BridgeConfig {
|
|
|
127
142
|
session?: SessionConfig;
|
|
128
143
|
/** 卡片展示;缺省 width=default(飞书默认宽度) */
|
|
129
144
|
card?: CardConfig;
|
|
145
|
+
/** 开机自启意图记录(整体可选):仅保存用户的开关选择,实际注册状态以 OS 查询为权威
|
|
146
|
+
* (概览页 GET /api/autostart 现查 Startup 文件夹/launchd/systemd) */
|
|
147
|
+
autostart?: {
|
|
148
|
+
enabled?: boolean;
|
|
149
|
+
};
|
|
130
150
|
}
|
|
131
151
|
/** 卡片展示配置(整体可选) */
|
|
132
152
|
export interface CardConfig {
|
|
@@ -169,9 +189,9 @@ export interface RejectedMessage {
|
|
|
169
189
|
}
|
|
170
190
|
/** 卡片回调决策:allow/deny/allow-session 为写工具确认卡;plan-* 为计划确认卡(feedback = 按意见修改时的用户输入);
|
|
171
191
|
* plan-view-file = 计划「查看完整方案」按钮触发,原文 md 直接 send_file 而非塞入卡片正文;
|
|
172
|
-
* qa-* 为提问卡;
|
|
173
|
-
*
|
|
174
|
-
export type CardDecision = 'allow' | 'deny' | 'allow-session' | 'plan-approve' | 'plan-revise' | 'plan-reject' | 'plan-view-file' | 'qa-pick' | 'qa-submit' | '
|
|
192
|
+
* qa-* 为提问卡;output-* 为结论尾卡(完整回复多卡的最后一张:确认方案 / 按意见修改
|
|
193
|
+
* 引导,点击即发起新一轮任务) */
|
|
194
|
+
export type CardDecision = 'allow' | 'deny' | 'allow-session' | 'plan-approve' | 'plan-revise' | 'plan-reject' | 'plan-view-file' | 'qa-pick' | 'qa-submit' | 'output-confirm' | 'output-revise' | 'ws-switch';
|
|
175
195
|
export interface CardActionValue {
|
|
176
196
|
requestId: string;
|
|
177
197
|
decision: CardDecision;
|
|
@@ -180,10 +200,10 @@ export interface CardActionValue {
|
|
|
180
200
|
qIndex?: number;
|
|
181
201
|
option?: string;
|
|
182
202
|
/** form 容器提交时回传的全部输入项(name → 值):qa_form 的 custom_N、
|
|
183
|
-
* plan_form/
|
|
203
|
+
* plan_form/result_form 的 feedback 均在此(0.20.0 泛化,取代只解析 feedback 单键) */
|
|
184
204
|
formValue?: Record<string, string>;
|
|
185
|
-
/**
|
|
186
|
-
|
|
205
|
+
/** ws-switch:目标工作区名(/ws 工作区卡片的切换按钮) */
|
|
206
|
+
ws?: string;
|
|
187
207
|
}
|
|
188
208
|
export interface CardActionEvent {
|
|
189
209
|
value: CardActionValue;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Windows 旧版 schtasks 任务名(仅迁移清理用:ONLOGON 触发器需管理员,已改用 Startup 文件夹) */
|
|
2
|
+
export declare const AUTOSTART_TASK_NAME = "LarkClaudeCodeBridge";
|
|
3
|
+
/** Windows Startup 文件夹启动器文件名 */
|
|
4
|
+
export declare const AUTOSTART_STARTUP_VBS = "lark-claudecode-bridge.vbs";
|
|
5
|
+
/** 任务管理器「启动应用」对 Startup 文件夹项的禁用标志键(值名 = 启动器文件名) */
|
|
6
|
+
export declare const AUTOSTART_APPROVED_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\StartupFolder";
|
|
7
|
+
/** macOS LaunchAgent Label(= plist 文件名去后缀) */
|
|
8
|
+
export declare const AUTOSTART_LABEL = "com.lark-claudecode-bridge";
|
|
9
|
+
/** Linux systemd 用户服务单元名 */
|
|
10
|
+
export declare const AUTOSTART_UNIT = "lark-claudecode-bridge.service";
|
|
11
|
+
type ExecFileFn = (file: string, args: string[], cb: (err: Error | null, stdout: string | Buffer, stderr: string | Buffer) => void) => void;
|
|
12
|
+
export interface AutostartDeps {
|
|
13
|
+
platform?: NodeJS.Platform;
|
|
14
|
+
execFileFn?: ExecFileFn;
|
|
15
|
+
configDir?: string;
|
|
16
|
+
homeDir?: string;
|
|
17
|
+
/** Windows %APPDATA%(Startup 文件夹根);缺省 env APPDATA,缺失再按 homeDir 标准布局推导 */
|
|
18
|
+
appDataDir?: string;
|
|
19
|
+
/** dist/bin/lcb.js 绝对路径;缺省视为入口不可用(tsx 源码模式)→ supported:false */
|
|
20
|
+
entryPath?: string;
|
|
21
|
+
/** node 可执行文件;缺省 process.execPath */
|
|
22
|
+
nodePath?: string;
|
|
23
|
+
uid?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface AutostartStatus {
|
|
26
|
+
/** dist 入口可用且平台受支持(tsx 源码模式 false,页面按钮禁用) */
|
|
27
|
+
supported: boolean;
|
|
28
|
+
/** OS 层已注册(权威判定,非 config 意图) */
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
platform: NodeJS.Platform;
|
|
31
|
+
/** 人类可读实现方式 / 异常原因(页面 hint 展示) */
|
|
32
|
+
detail?: string;
|
|
33
|
+
/** 生成的启动器文件路径(展示用) */
|
|
34
|
+
registeredPath?: string;
|
|
35
|
+
/** 已注册但启动器内容与当前安装不符(换 Node 等)→ 提示关闭再开启 */
|
|
36
|
+
stale?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 期望启动器内容(纯函数,注册写盘与 stale 比对共用单源)。
|
|
40
|
+
* Windows = wscript VBS(隐藏窗口不闪控制台);macOS = launchd plist;Linux = systemd unit。
|
|
41
|
+
* KeepAlive=false / Restart=on-failure 刻意偏离 deploy/ 模板(true/always):配置页有「停止」
|
|
42
|
+
* 按钮,守护拉起会跟用户手动停止互相打架;崩溃不自愈由 PID 探活 + 页面手动启动兜底。
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildAutostartLauncher(platform: NodeJS.Platform, nodePath: string, entry: string, configDir: string): string;
|
|
45
|
+
/** 查询 OS 层注册状态(enabled 权威判定 + stale 比对) */
|
|
46
|
+
export declare function getAutostartStatus(deps?: AutostartDeps): Promise<AutostartStatus>;
|
|
47
|
+
/** 注册 / 注销开机自启。OS 操作失败抛错(stderr 首行摘要);调用方(server)失败时不回写 config 意图 */
|
|
48
|
+
export declare function setAutostartEnabled(enabled: boolean, deps?: AutostartDeps): Promise<AutostartStatus>;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// 开机自启(概览页开关):三平台注册 / 注销 / 状态查询。纯逻辑全依赖注入
|
|
2
|
+
// (platform / execFile / 路径 / uid 可替换,tests/web/autostart.test.ts 零真实系统调用)。
|
|
3
|
+
//
|
|
4
|
+
// Windows = Startup 文件夹 VBS:explorer 登录时执行,wscript 隐藏窗口(无黑框)。
|
|
5
|
+
// 纯文件操作、普通用户可写——schtasks ONLOGON 触发器需管理员提升(真机报 Access is
|
|
6
|
+
// denied),已弃用;开启/关闭时 best-effort 清理旧任务与任务管理器禁用标志,失败不阻断。
|
|
7
|
+
// macOS = launchctl bootstrap gui/uid(already bootstrapped 先 bootout 重试);
|
|
8
|
+
// Linux = systemd --user(daemon-reload 必须在 enable 前)。
|
|
9
|
+
//
|
|
10
|
+
// 启动命令统一指向 process.execPath + resolveLcbEntry().entry + start:npm 全局包是就地
|
|
11
|
+
// 覆盖更新(node_modules/@jesonliu/... 路径不变),更新后自启自然有效;换 Node / 移动安装
|
|
12
|
+
// 目录后磁盘启动器内容与期望不符 → stale 置位,页面提示关闭再开启即可修复。
|
|
13
|
+
//
|
|
14
|
+
// 注册状态以 OS 查询为权威(config.autostart.enabled 仅意图记录,供配置页回显)。
|
|
15
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
16
|
+
import { existsSync, mkdirSync, readFileSync, rmdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { dirname, join } from 'node:path';
|
|
19
|
+
import { CONFIG_DIR } from '../config.js';
|
|
20
|
+
/** Windows 旧版 schtasks 任务名(仅迁移清理用:ONLOGON 触发器需管理员,已改用 Startup 文件夹) */
|
|
21
|
+
export const AUTOSTART_TASK_NAME = 'LarkClaudeCodeBridge';
|
|
22
|
+
/** Windows Startup 文件夹启动器文件名 */
|
|
23
|
+
export const AUTOSTART_STARTUP_VBS = 'lark-claudecode-bridge.vbs';
|
|
24
|
+
/** 任务管理器「启动应用」对 Startup 文件夹项的禁用标志键(值名 = 启动器文件名) */
|
|
25
|
+
export const AUTOSTART_APPROVED_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\StartupFolder';
|
|
26
|
+
/** macOS LaunchAgent Label(= plist 文件名去后缀) */
|
|
27
|
+
export const AUTOSTART_LABEL = 'com.lark-claudecode-bridge';
|
|
28
|
+
/** Linux systemd 用户服务单元名 */
|
|
29
|
+
export const AUTOSTART_UNIT = 'lark-claudecode-bridge.service';
|
|
30
|
+
/** 统一 execFile 包装:永不 reject,按退出码分支(err.code 可能是数字退出码或 'ENOENT' 等字符串) */
|
|
31
|
+
function run(deps, file, args) {
|
|
32
|
+
const execFileFn = deps.execFileFn ?? execFileCb;
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
execFileFn(file, args, (err, stdout, stderr) => {
|
|
35
|
+
const rawCode = err?.code;
|
|
36
|
+
resolve({
|
|
37
|
+
code: err ? (typeof rawCode === 'number' ? rawCode : 1) : 0,
|
|
38
|
+
stdout: String(stdout ?? ''),
|
|
39
|
+
stderr: String(stderr ?? ''),
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** stderr 首行摘要(schtasks / launchctl / systemctl 的报错都足够一句话说清) */
|
|
45
|
+
function errSummary(stderr) {
|
|
46
|
+
const line = stderr.trim().split(/\r?\n/)[0] ?? '';
|
|
47
|
+
return line.slice(0, 200) || '未知错误';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* VBS 读写单源(utf16le + BOM):wscript 按 UTF-16 解析带 BOM 的 .vbs——utf8 写盘会被按
|
|
51
|
+
* ANSI 读,node/entry 路径含非 ASCII 字符时启动器静默失效。写读同源保证 stale 比对有效。
|
|
52
|
+
*/
|
|
53
|
+
function writeVbs(path, content) {
|
|
54
|
+
writeFileSync(path, '' + content, 'utf16le');
|
|
55
|
+
}
|
|
56
|
+
function readVbs(path) {
|
|
57
|
+
return readFileSync(path, 'utf16le').replace(/^/, '');
|
|
58
|
+
}
|
|
59
|
+
/** win32 启动器路径:Startup 文件夹(explorer 登录时逐项执行,.vbs 由 wscript 解释) */
|
|
60
|
+
function win32LauncherPath(d) {
|
|
61
|
+
return join(d.appDataDir, 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup', AUTOSTART_STARTUP_VBS);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* win32 best-effort 迁移清理(enable / disable 共用,全部无条件忽略失败):
|
|
65
|
+
* ① 旧版 schtasks ONLOGON 任务——需管理员已弃用,残留会导致登录双启动;
|
|
66
|
+
* ② 任务管理器「启动应用」禁用标志——配置页本次点击是最新意图,重开应立即生效;
|
|
67
|
+
* ③ 旧版遗留启动器(CONFIG_DIR/autostart/)。
|
|
68
|
+
*/
|
|
69
|
+
async function win32CleanupLegacy(deps, d) {
|
|
70
|
+
await run(deps, 'schtasks', ['/Delete', '/TN', AUTOSTART_TASK_NAME, '/F']);
|
|
71
|
+
await run(deps, 'reg', ['delete', AUTOSTART_APPROVED_KEY, '/v', AUTOSTART_STARTUP_VBS, '/f']);
|
|
72
|
+
try {
|
|
73
|
+
const legacyDir = join(d.configDir, 'autostart');
|
|
74
|
+
rmSync(join(legacyDir, 'lcb-autostart.vbs'), { force: true });
|
|
75
|
+
rmdirSync(legacyDir); // 仅空目录可删;目录里有用户文件则整体保留
|
|
76
|
+
}
|
|
77
|
+
catch { /* best-effort */ }
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 期望启动器内容(纯函数,注册写盘与 stale 比对共用单源)。
|
|
81
|
+
* Windows = wscript VBS(隐藏窗口不闪控制台);macOS = launchd plist;Linux = systemd unit。
|
|
82
|
+
* KeepAlive=false / Restart=on-failure 刻意偏离 deploy/ 模板(true/always):配置页有「停止」
|
|
83
|
+
* 按钮,守护拉起会跟用户手动停止互相打架;崩溃不自愈由 PID 探活 + 页面手动启动兜底。
|
|
84
|
+
*/
|
|
85
|
+
export function buildAutostartLauncher(platform, nodePath, entry, configDir) {
|
|
86
|
+
if (platform === 'win32') {
|
|
87
|
+
const q = (s) => s.replace(/"/g, '""'); // VBS 字符串内引号翻倍(路径本身不含引号,防御性)
|
|
88
|
+
return [
|
|
89
|
+
`' lark-claudecode-bridge 开机自启启动器(Web 配置页生成,勿手改):隐藏窗口 + 不等待`,
|
|
90
|
+
`CreateObject("WScript.Shell").Run """${q(nodePath)}"" ""${q(entry)}"" start", 0, False`,
|
|
91
|
+
'',
|
|
92
|
+
].join('\n');
|
|
93
|
+
}
|
|
94
|
+
if (platform === 'darwin') {
|
|
95
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
96
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
97
|
+
<plist version="1.0">
|
|
98
|
+
<dict>
|
|
99
|
+
<key>Label</key><string>${AUTOSTART_LABEL}</string>
|
|
100
|
+
<key>ProgramArguments</key>
|
|
101
|
+
<array>
|
|
102
|
+
<string>${nodePath}</string>
|
|
103
|
+
<string>${entry}</string>
|
|
104
|
+
<string>start</string>
|
|
105
|
+
</array>
|
|
106
|
+
<key>RunAtLoad</key><true/>
|
|
107
|
+
<!-- KeepAlive=false 刻意偏离 deploy 模板(true):配置页有「停止」按钮,true 会把手动停掉的桥无限拉起 -->
|
|
108
|
+
<key>KeepAlive</key><false/>
|
|
109
|
+
<key>WorkingDirectory</key><string>${configDir}</string>
|
|
110
|
+
<key>StandardOutPath</key><string>${join(configDir, 'logs', 'launchd.out.log')}</string>
|
|
111
|
+
<key>StandardErrorPath</key><string>${join(configDir, 'logs', 'launchd.err.log')}</string>
|
|
112
|
+
</dict>
|
|
113
|
+
</plist>
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
// linux(deploy/ 同名 unit 的运行时生成版)
|
|
117
|
+
return `[Unit]
|
|
118
|
+
Description=lark-claudecode-bridge(Web 配置页生成的用户级自启)
|
|
119
|
+
After=network-online.target
|
|
120
|
+
|
|
121
|
+
[Service]
|
|
122
|
+
ExecStart=${nodePath} ${entry} start
|
|
123
|
+
WorkingDirectory=${configDir}
|
|
124
|
+
# on-failure 刻意偏离 deploy 模板的 always:与配置页「停止」按钮共存(手动停止不再被拉起)
|
|
125
|
+
Restart=on-failure
|
|
126
|
+
RestartSec=5
|
|
127
|
+
|
|
128
|
+
[Install]
|
|
129
|
+
WantedBy=default.target
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
/** 平台实现要点:文件路径 / 注册注销命令 / 状态判定。统一在 deps 解析后工作 */
|
|
133
|
+
function resolveDeps(deps) {
|
|
134
|
+
const homeDir = deps.homeDir ?? homedir();
|
|
135
|
+
return {
|
|
136
|
+
platform: deps.platform ?? process.platform,
|
|
137
|
+
configDir: deps.configDir ?? CONFIG_DIR,
|
|
138
|
+
homeDir,
|
|
139
|
+
// explorer 以 APPDATA 定位 Startup 文件夹:优先环境变量,缺失再按标准布局推导
|
|
140
|
+
appDataDir: deps.appDataDir ?? process.env.APPDATA ?? join(homeDir, 'AppData', 'Roaming'),
|
|
141
|
+
nodePath: deps.nodePath ?? process.execPath,
|
|
142
|
+
uid: deps.uid ?? process.getuid?.() ?? 0,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** 平台不支持 / 入口缺失时的统一兜底状态 */
|
|
146
|
+
function unsupported(platform, detail) {
|
|
147
|
+
return { supported: false, enabled: false, platform, detail };
|
|
148
|
+
}
|
|
149
|
+
/** 查询 OS 层注册状态(enabled 权威判定 + stale 比对) */
|
|
150
|
+
export async function getAutostartStatus(deps = {}) {
|
|
151
|
+
const d = resolveDeps(deps);
|
|
152
|
+
if (!deps.entryPath)
|
|
153
|
+
return unsupported(d.platform, '未找到 dist/bin/lcb.js:源码(tsx)运行模式不支持开机自启,请手动运行 lcb start');
|
|
154
|
+
const launcher = buildAutostartLauncher(d.platform, d.nodePath, deps.entryPath, d.configDir);
|
|
155
|
+
if (d.platform === 'win32') {
|
|
156
|
+
// 文件即注册物:查询零外部命令(Node 读盘无 mojibake,编码可靠)
|
|
157
|
+
const vbsPath = win32LauncherPath(d);
|
|
158
|
+
const vbsExists = existsSync(vbsPath);
|
|
159
|
+
const stale = vbsExists && readVbs(vbsPath) !== launcher;
|
|
160
|
+
return {
|
|
161
|
+
supported: true, enabled: vbsExists, platform: d.platform,
|
|
162
|
+
detail: `Windows 登录启动(Startup 文件夹 · 可在任务管理器「启动应用」中管理)`,
|
|
163
|
+
registeredPath: vbsPath, ...(stale ? { stale: true } : {}),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (d.platform === 'darwin') {
|
|
167
|
+
const plistPath = join(d.homeDir, 'Library', 'LaunchAgents', `${AUTOSTART_LABEL}.plist`);
|
|
168
|
+
const p = await run(deps, 'launchctl', ['print', `gui/${d.uid}/${AUTOSTART_LABEL}`]);
|
|
169
|
+
const plistExists = existsSync(plistPath);
|
|
170
|
+
const stale = p.code === 0 && plistExists && readFileSync(plistPath, 'utf8') !== launcher;
|
|
171
|
+
return {
|
|
172
|
+
supported: true, enabled: p.code === 0 && plistExists, platform: d.platform,
|
|
173
|
+
detail: `macOS LaunchAgent · ${AUTOSTART_LABEL}(登录时启动)`,
|
|
174
|
+
registeredPath: plistPath, ...(stale ? { stale: true } : {}),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (d.platform === 'linux') {
|
|
178
|
+
const unitPath = join(d.homeDir, '.config', 'systemd', 'user', AUTOSTART_UNIT);
|
|
179
|
+
const ie = await run(deps, 'systemctl', ['--user', 'is-enabled', AUTOSTART_UNIT]);
|
|
180
|
+
const unitExists = existsSync(unitPath);
|
|
181
|
+
const stale = ie.code === 0 && unitExists && readFileSync(unitPath, 'utf8') !== launcher;
|
|
182
|
+
return {
|
|
183
|
+
supported: true, enabled: ie.code === 0 && ie.stdout.trim() === 'enabled' && unitExists, platform: d.platform,
|
|
184
|
+
detail: `Linux systemd 用户服务 · ${AUTOSTART_UNIT}(登录时启动;无桌面常驻服务器需 loginctl enable-linger)`,
|
|
185
|
+
registeredPath: unitPath, ...(stale ? { stale: true } : {}),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return unsupported(d.platform, `平台 ${d.platform} 暂不支持自动注册,请参考 deploy/ 目录模板手动配置`);
|
|
189
|
+
}
|
|
190
|
+
/** 注册 / 注销开机自启。OS 操作失败抛错(stderr 首行摘要);调用方(server)失败时不回写 config 意图 */
|
|
191
|
+
export async function setAutostartEnabled(enabled, deps = {}) {
|
|
192
|
+
const d = resolveDeps(deps);
|
|
193
|
+
if (!deps.entryPath)
|
|
194
|
+
return unsupported(d.platform, '未找到 dist/bin/lcb.js:源码(tsx)运行模式不支持开机自启,请手动运行 lcb start');
|
|
195
|
+
if (d.platform === 'win32') {
|
|
196
|
+
// 先 best-effort 清理旧物(失败不阻断),再执行主操作(纯文件写/删,普通用户必成)
|
|
197
|
+
await win32CleanupLegacy(deps, d);
|
|
198
|
+
const vbsPath = win32LauncherPath(d);
|
|
199
|
+
if (enabled) {
|
|
200
|
+
mkdirSync(dirname(vbsPath), { recursive: true });
|
|
201
|
+
writeVbs(vbsPath, buildAutostartLauncher(d.platform, d.nodePath, deps.entryPath, d.configDir));
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
rmSync(vbsPath, { force: true });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (d.platform === 'darwin') {
|
|
208
|
+
const plistPath = join(d.homeDir, 'Library', 'LaunchAgents', `${AUTOSTART_LABEL}.plist`);
|
|
209
|
+
if (enabled) {
|
|
210
|
+
mkdirSync(dirname(plistPath), { recursive: true });
|
|
211
|
+
writeFileSync(plistPath, buildAutostartLauncher(d.platform, d.nodePath, deps.entryPath, d.configDir), 'utf8');
|
|
212
|
+
// 优先 bootstrap(10.11+);已加载(旧注册/手动 load 残留)→ bootout 后重试一次
|
|
213
|
+
let r = await run(deps, 'launchctl', ['bootstrap', `gui/${d.uid}`, plistPath]);
|
|
214
|
+
if (r.code !== 0) {
|
|
215
|
+
await run(deps, 'launchctl', ['bootout', `gui/${d.uid}/${AUTOSTART_LABEL}`]);
|
|
216
|
+
r = await run(deps, 'launchctl', ['bootstrap', `gui/${d.uid}`, plistPath]);
|
|
217
|
+
}
|
|
218
|
+
if (r.code !== 0)
|
|
219
|
+
throw new Error(`launchctl bootstrap 失败:${errSummary(r.stderr)}`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
await run(deps, 'launchctl', ['bootout', `gui/${d.uid}/${AUTOSTART_LABEL}`]); // 未加载时失败:忽略
|
|
223
|
+
rmSync(plistPath, { force: true });
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else if (d.platform === 'linux') {
|
|
227
|
+
const unitPath = join(d.homeDir, '.config', 'systemd', 'user', AUTOSTART_UNIT);
|
|
228
|
+
if (enabled) {
|
|
229
|
+
mkdirSync(dirname(unitPath), { recursive: true });
|
|
230
|
+
writeFileSync(unitPath, buildAutostartLauncher(d.platform, d.nodePath, deps.entryPath, d.configDir), 'utf8');
|
|
231
|
+
// 顺序必须 daemon-reload 在前:unit 未被 systemd 识别时 enable 会静默失败
|
|
232
|
+
let r = await run(deps, 'systemctl', ['--user', 'daemon-reload']);
|
|
233
|
+
if (r.code !== 0)
|
|
234
|
+
throw new Error(`systemctl daemon-reload 失败:${errSummary(r.stderr)}(WSL/容器未启用 systemd?)`);
|
|
235
|
+
r = await run(deps, 'systemctl', ['--user', 'enable', '--now', AUTOSTART_UNIT]);
|
|
236
|
+
if (r.code !== 0)
|
|
237
|
+
throw new Error(`systemctl enable 失败:${errSummary(r.stderr)}`);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
await run(deps, 'systemctl', ['--user', 'disable', '--now', AUTOSTART_UNIT]); // 未注册时失败:忽略
|
|
241
|
+
rmSync(unitPath, { force: true });
|
|
242
|
+
await run(deps, 'systemctl', ['--user', 'daemon-reload']);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
return unsupported(d.platform, `平台 ${d.platform} 暂不支持自动注册,请参考 deploy/ 目录模板手动配置`);
|
|
247
|
+
}
|
|
248
|
+
return getAutostartStatus(deps);
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=autostart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../../src/web/autostart.ts"],"names":[],"mappings":"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"}
|
package/dist/web/config-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { sameApps } from '../config.js';
|
|
2
|
-
import { DEFAULT_ALLOW_TOOLS_LIST, DEFAULT_DANGEROUS_COMMAND_SOURCES } from '../executor/permission-gate.js';
|
|
2
|
+
import { DEFAULT_ALLOW_ALL_TOOLS, DEFAULT_ALLOW_TOOLS_LIST, DEFAULT_DANGEROUS_COMMAND_SOURCES } from '../executor/permission-gate.js';
|
|
3
3
|
export function maskSecret(value) {
|
|
4
4
|
if (!value)
|
|
5
5
|
return { secretSet: false };
|
|
@@ -150,12 +150,24 @@ export function appStatusSummary(apps, started) {
|
|
|
150
150
|
export function applyPermissionDisplayDefaults(doc) {
|
|
151
151
|
const p = doc.permissions;
|
|
152
152
|
if (p === undefined || p === null) {
|
|
153
|
-
return {
|
|
153
|
+
return {
|
|
154
|
+
...doc,
|
|
155
|
+
permissions: {
|
|
156
|
+
allow_all_tools: DEFAULT_ALLOW_ALL_TOOLS,
|
|
157
|
+
allow_tools: [...DEFAULT_ALLOW_TOOLS_LIST],
|
|
158
|
+
dangerous_commands: [...DEFAULT_DANGEROUS_COMMAND_SOURCES],
|
|
159
|
+
},
|
|
160
|
+
};
|
|
154
161
|
}
|
|
155
162
|
if (typeof p !== 'object' || Array.isArray(p))
|
|
156
163
|
return doc; // 脏形状:loadConfig/parseConfigText 会拦,GET 原样透出
|
|
157
164
|
const np = { ...p };
|
|
158
165
|
let changed = false;
|
|
166
|
+
// 判空用 undefined/null 而非真值:显式 false(用户主动关闭开关)必须原样回显,不能被缺省 true 覆盖
|
|
167
|
+
if (np.allow_all_tools === undefined || np.allow_all_tools === null) {
|
|
168
|
+
np.allow_all_tools = DEFAULT_ALLOW_ALL_TOOLS;
|
|
169
|
+
changed = true;
|
|
170
|
+
}
|
|
159
171
|
if (np.allow_tools === undefined || np.allow_tools === null) {
|
|
160
172
|
np.allow_tools = [...DEFAULT_ALLOW_TOOLS_LIST];
|
|
161
173
|
changed = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-api.js","sourceRoot":"","sources":["../../src/web/config-api.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,wBAAwB,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"config-api.js","sourceRoot":"","sources":["../../src/web/config-api.ts"],"names":[],"mappings":"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"}
|
package/dist/web/server.js
CHANGED
|
@@ -26,10 +26,11 @@ import { builtinCommands, createSlashApiClient, ensureBuiltins, expectedCommands
|
|
|
26
26
|
import { removeMarketplaceIfUnused, resolvePluginMarketplace, runPluginCli, updateAllPlugins } from '../executor/plugin-manager.js';
|
|
27
27
|
import { invalidatePluginCache, listAvailablePlugins, listInstalledPlugins, loadEnabledPlugins } from '../executor/plugin-discovery.js';
|
|
28
28
|
import { bridgeStatus, resolveLcbEntry, restartBridgeWithHelper, spawnBridgeDetached, stopBridgeByPid } from './lifecycle.js';
|
|
29
|
+
import { getAutostartStatus, setAutostartEnabled } from './autostart.js';
|
|
29
30
|
import { checkUpdate, hasNewerVersion, installMode, runUpdate } from './update.js';
|
|
30
31
|
import { checkLarkCliAuth, checkLarkCliLatest, detectLarkCli, detectLarkCliSkill, getLarkCliConfigStatus, getLarkCliDeviceStatus, runLarkCliActionFlow, startLarkCliConfigFlow, startLarkCliDeviceAuth, } from '../lark-cli-manager.js';
|
|
31
32
|
/** PUT /api/config 参与整段替换的顶级键;body 未携带的键保持磁盘原文(含注释) */
|
|
32
|
-
const PUT_SECTIONS = ['apps', 'workspaces', 'defaults', 'concurrency', 'permissions', 'server', 'claude', 'slash_commands', 'transcripts', 'session', 'card'];
|
|
33
|
+
const PUT_SECTIONS = ['apps', 'workspaces', 'defaults', 'concurrency', 'permissions', 'server', 'claude', 'slash_commands', 'transcripts', 'session', 'card', 'autostart'];
|
|
33
34
|
const WEB_ROOT = fileURLToPath(new URL('../../assets/web', import.meta.url));
|
|
34
35
|
const INDEX_HTML_PATH = join(WEB_ROOT, 'index.html');
|
|
35
36
|
/** 静态模块仅限 js/css 两前缀 + 扩展名白名单(纵深防御:目录内误放的敏感文件不可被 serve) */
|
|
@@ -1064,6 +1065,42 @@ async function handle(req, res, ctx) {
|
|
|
1064
1065
|
return json(res, 502, { error: `更新失败:${e instanceof Error ? e.message : String(e)}` });
|
|
1065
1066
|
}
|
|
1066
1067
|
}
|
|
1068
|
+
// ---- 开机自启(概览页开关):GET 查 OS 实际状态;POST 注册/注销并回写意图 ----
|
|
1069
|
+
if (path === '/api/autostart' && req.method === 'GET') {
|
|
1070
|
+
const entry = resolveLcbEntry();
|
|
1071
|
+
if (!entry.ok) {
|
|
1072
|
+
return json(res, 200, { supported: false, enabled: false, platform: process.platform, detail: entry.error });
|
|
1073
|
+
}
|
|
1074
|
+
return json(res, 200, await getAutostartStatus({ entryPath: entry.entry })); // 查询失败走外层 catch → 500
|
|
1075
|
+
}
|
|
1076
|
+
if (path === '/api/autostart' && req.method === 'POST') {
|
|
1077
|
+
if (firstRun)
|
|
1078
|
+
return json(res, 404, { error: '尚无配置文件(首次安装),请先完成 bootstrap 向导' });
|
|
1079
|
+
const entry = resolveLcbEntry();
|
|
1080
|
+
if (!entry.ok)
|
|
1081
|
+
return json(res, 400, { error: entry.error }); // tsx 源码模式:明确拒绝
|
|
1082
|
+
const body = await readJsonBody(req);
|
|
1083
|
+
const enabled = body.enabled === true;
|
|
1084
|
+
try {
|
|
1085
|
+
// 先 OS 注册(失败即中断、意图不落盘),再写 config 意图——写失败可容忍(下次开关自愈)。
|
|
1086
|
+
// autostart 值未变时跳过重写:整段 set 会丢掉段内手写注释(同 PUT /api/config 的折损规避)
|
|
1087
|
+
const status = await setAutostartEnabled(enabled, { entryPath: entry.entry });
|
|
1088
|
+
const rawText = readFileSync(ctx.configPath, 'utf8');
|
|
1089
|
+
const oldJs = parseDocument(rawText).toJS();
|
|
1090
|
+
const intent = { enabled };
|
|
1091
|
+
if (JSON.stringify(oldJs.autostart ?? null) !== JSON.stringify(intent)) {
|
|
1092
|
+
const doc = parseDocument(rawText);
|
|
1093
|
+
doc.set('autostart', intent);
|
|
1094
|
+
const text = doc.toString();
|
|
1095
|
+
parseConfigText(text, ctx.configPath); // 写盘前内存校验:拒绝坏配置落盘
|
|
1096
|
+
writeAtomic(ctx.configPath, text);
|
|
1097
|
+
}
|
|
1098
|
+
return json(res, 200, status);
|
|
1099
|
+
}
|
|
1100
|
+
catch (e) {
|
|
1101
|
+
return json(res, 502, { error: `开机自启${enabled ? '开启' : '关闭'}失败:${e instanceof Error ? e.message : String(e)}` });
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1067
1104
|
// ---- 飞书官方 CLI(@larksuite/cli)状态 / 授权 / 安装 ----
|
|
1068
1105
|
if (path === '/api/lark-cli' && req.method === 'GET') {
|
|
1069
1106
|
const d = await detectLarkCli().catch(() => ({ installed: false }));
|