@caoruhua/open-claude-remote 0.1.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/LICENSE +21 -0
- package/README.md +449 -0
- package/dist/api/auth-routes.d.ts +4 -0
- package/dist/api/auth-routes.d.ts.map +1 -0
- package/dist/api/auth-routes.js +7 -0
- package/dist/api/auth-routes.js.map +1 -0
- package/dist/api/config-routes.d.ts +4 -0
- package/dist/api/config-routes.d.ts.map +1 -0
- package/dist/api/config-routes.js +180 -0
- package/dist/api/config-routes.js.map +1 -0
- package/dist/api/health-routes.d.ts +3 -0
- package/dist/api/health-routes.d.ts.map +1 -0
- package/dist/api/health-routes.js +9 -0
- package/dist/api/health-routes.js.map +1 -0
- package/dist/api/hook-routes.d.ts +4 -0
- package/dist/api/hook-routes.d.ts.map +1 -0
- package/dist/api/hook-routes.js +32 -0
- package/dist/api/hook-routes.js.map +1 -0
- package/dist/api/instance-routes.d.ts +20 -0
- package/dist/api/instance-routes.d.ts.map +1 -0
- package/dist/api/instance-routes.js +128 -0
- package/dist/api/instance-routes.js.map +1 -0
- package/dist/api/push-routes.d.ts +5 -0
- package/dist/api/push-routes.d.ts.map +1 -0
- package/dist/api/push-routes.js +45 -0
- package/dist/api/push-routes.js.map +1 -0
- package/dist/api/router.d.ts +19 -0
- package/dist/api/router.d.ts.map +1 -0
- package/dist/api/router.js +37 -0
- package/dist/api/router.js.map +1 -0
- package/dist/api/status-routes.d.ts +5 -0
- package/dist/api/status-routes.d.ts.map +1 -0
- package/dist/api/status-routes.js +17 -0
- package/dist/api/status-routes.js.map +1 -0
- package/dist/attach.d.ts +9 -0
- package/dist/attach.d.ts.map +1 -0
- package/dist/attach.js +155 -0
- package/dist/attach.js.map +1 -0
- package/dist/auth/auth-middleware.d.ts +52 -0
- package/dist/auth/auth-middleware.d.ts.map +1 -0
- package/dist/auth/auth-middleware.js +124 -0
- package/dist/auth/auth-middleware.js.map +1 -0
- package/dist/auth/rate-limiter.d.ts +37 -0
- package/dist/auth/rate-limiter.d.ts.map +1 -0
- package/dist/auth/rate-limiter.js +81 -0
- package/dist/auth/rate-limiter.js.map +1 -0
- package/dist/auth/token-generator.d.ts +9 -0
- package/dist/auth/token-generator.d.ts.map +1 -0
- package/dist/auth/token-generator.js +15 -0
- package/dist/auth/token-generator.js.map +1 -0
- package/dist/cli-utils.d.ts +19 -0
- package/dist/cli-utils.d.ts.map +1 -0
- package/dist/cli-utils.js +132 -0
- package/dist/cli-utils.js.map +1 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +58 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +146 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +329 -0
- package/dist/config.js.map +1 -0
- package/dist/hooks/hook-receiver.d.ts +39 -0
- package/dist/hooks/hook-receiver.d.ts.map +1 -0
- package/dist/hooks/hook-receiver.js +46 -0
- package/dist/hooks/hook-receiver.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +353 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/logger.d.ts +8 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +90 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/notification/dingtalk-service.d.ts +24 -0
- package/dist/notification/dingtalk-service.d.ts.map +1 -0
- package/dist/notification/dingtalk-service.js +94 -0
- package/dist/notification/dingtalk-service.js.map +1 -0
- package/dist/pty/output-buffer.d.ts +25 -0
- package/dist/pty/output-buffer.d.ts.map +1 -0
- package/dist/pty/output-buffer.js +58 -0
- package/dist/pty/output-buffer.js.map +1 -0
- package/dist/pty/pty-manager.d.ts +45 -0
- package/dist/pty/pty-manager.d.ts.map +1 -0
- package/dist/pty/pty-manager.js +108 -0
- package/dist/pty/pty-manager.js.map +1 -0
- package/dist/pty/types.d.ts +11 -0
- package/dist/pty/types.d.ts.map +1 -0
- package/dist/pty/types.js +2 -0
- package/dist/pty/types.js.map +1 -0
- package/dist/pty/virtual-pty.d.ts +37 -0
- package/dist/pty/virtual-pty.d.ts.map +1 -0
- package/dist/pty/virtual-pty.js +161 -0
- package/dist/pty/virtual-pty.js.map +1 -0
- package/dist/push/push-service.d.ts +87 -0
- package/dist/push/push-service.d.ts.map +1 -0
- package/dist/push/push-service.js +301 -0
- package/dist/push/push-service.js.map +1 -0
- package/dist/registry/instance-registry.d.ts +32 -0
- package/dist/registry/instance-registry.d.ts.map +1 -0
- package/dist/registry/instance-registry.js +115 -0
- package/dist/registry/instance-registry.js.map +1 -0
- package/dist/registry/instance-spawner.d.ts +33 -0
- package/dist/registry/instance-spawner.d.ts.map +1 -0
- package/dist/registry/instance-spawner.js +91 -0
- package/dist/registry/instance-spawner.js.map +1 -0
- package/dist/registry/port-finder.d.ts +8 -0
- package/dist/registry/port-finder.d.ts.map +1 -0
- package/dist/registry/port-finder.js +35 -0
- package/dist/registry/port-finder.js.map +1 -0
- package/dist/registry/shared-token.d.ts +11 -0
- package/dist/registry/shared-token.d.ts.map +1 -0
- package/dist/registry/shared-token.js +82 -0
- package/dist/registry/shared-token.js.map +1 -0
- package/dist/registry/stop-instances.d.ts +27 -0
- package/dist/registry/stop-instances.d.ts.map +1 -0
- package/dist/registry/stop-instances.js +212 -0
- package/dist/registry/stop-instances.js.map +1 -0
- package/dist/session/session-controller.d.ts +58 -0
- package/dist/session/session-controller.d.ts.map +1 -0
- package/dist/session/session-controller.js +273 -0
- package/dist/session/session-controller.js.map +1 -0
- package/dist/terminal/terminal-relay.d.ts +29 -0
- package/dist/terminal/terminal-relay.d.ts.map +1 -0
- package/dist/terminal/terminal-relay.js +106 -0
- package/dist/terminal/terminal-relay.js.map +1 -0
- package/dist/utils/ansi-filter.d.ts +41 -0
- package/dist/utils/ansi-filter.d.ts.map +1 -0
- package/dist/utils/ansi-filter.js +147 -0
- package/dist/utils/ansi-filter.js.map +1 -0
- package/dist/utils/file-lock.d.ts +23 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +125 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/ip-monitor.d.ts +39 -0
- package/dist/utils/ip-monitor.d.ts.map +1 -0
- package/dist/utils/ip-monitor.js +114 -0
- package/dist/utils/ip-monitor.js.map +1 -0
- package/dist/utils/network.d.ts +19 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +54 -0
- package/dist/utils/network.js.map +1 -0
- package/dist/utils/pid-file.d.ts +10 -0
- package/dist/utils/pid-file.d.ts.map +1 -0
- package/dist/utils/pid-file.js +30 -0
- package/dist/utils/pid-file.js.map +1 -0
- package/dist/utils/qrcode-banner.d.ts +6 -0
- package/dist/utils/qrcode-banner.d.ts.map +1 -0
- package/dist/utils/qrcode-banner.js +16 -0
- package/dist/utils/qrcode-banner.js.map +1 -0
- package/dist/ws/ws-handler.d.ts +10 -0
- package/dist/ws/ws-handler.d.ts.map +1 -0
- package/dist/ws/ws-handler.js +36 -0
- package/dist/ws/ws-handler.js.map +1 -0
- package/dist/ws/ws-server.d.ts +78 -0
- package/dist/ws/ws-server.d.ts.map +1 -0
- package/dist/ws/ws-server.js +223 -0
- package/dist/ws/ws-server.js.map +1 -0
- package/frontend-dist/assets/index-BKudo1Dw.css +32 -0
- package/frontend-dist/assets/index-BqqB1hYe.js +141 -0
- package/frontend-dist/index.html +15 -0
- package/frontend-dist/sw.js +46 -0
- package/package.json +79 -0
- package/shared-dist/constants.d.ts +10 -0
- package/shared-dist/constants.d.ts.map +1 -0
- package/shared-dist/constants.js +10 -0
- package/shared-dist/constants.js.map +1 -0
- package/shared-dist/defaults.d.ts +30 -0
- package/shared-dist/defaults.d.ts.map +1 -0
- package/shared-dist/defaults.js +31 -0
- package/shared-dist/defaults.js.map +1 -0
- package/shared-dist/index.d.ts +5 -0
- package/shared-dist/index.d.ts.map +1 -0
- package/shared-dist/index.js +5 -0
- package/shared-dist/index.js.map +1 -0
- package/shared-dist/instance.d.ts +25 -0
- package/shared-dist/instance.d.ts.map +1 -0
- package/shared-dist/instance.js +7 -0
- package/shared-dist/instance.js.map +1 -0
- package/shared-dist/question-utils.d.ts +15 -0
- package/shared-dist/question-utils.d.ts.map +1 -0
- package/shared-dist/question-utils.js +24 -0
- package/shared-dist/question-utils.js.map +1 -0
- package/shared-dist/ws-protocol.d.ts +60 -0
- package/shared-dist/ws-protocol.d.ts.map +1 -0
- package/shared-dist/ws-protocol.js +5 -0
- package/shared-dist/ws-protocol.js.map +1 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户配置文件结构 (~/.claude-remote/config.json)
|
|
3
|
+
* 这些是用户可以持久化的配置项
|
|
4
|
+
*/
|
|
5
|
+
export interface UserConfig {
|
|
6
|
+
/** 服务端口 (默认: 3000) */
|
|
7
|
+
port?: number;
|
|
8
|
+
/** 绑定地址 (默认: 0.0.0.0) */
|
|
9
|
+
host?: string;
|
|
10
|
+
/** 认证 Token (默认: 自动生成共享 Token) */
|
|
11
|
+
token?: string;
|
|
12
|
+
/** Claude CLI 命令路径 (默认: claude) */
|
|
13
|
+
claudeCommand?: string;
|
|
14
|
+
/** Claude CLI 额外参数 */
|
|
15
|
+
claudeArgs?: string[];
|
|
16
|
+
/** Claude 工作目录 (默认: 当前目录) */
|
|
17
|
+
claudeCwd?: string;
|
|
18
|
+
/** Session TTL 毫秒数 (默认: 24小时) */
|
|
19
|
+
sessionTtlMs?: number;
|
|
20
|
+
/** 认证速率限制 (每分钟每 IP 次数, 默认: 5) */
|
|
21
|
+
authRateLimit?: number;
|
|
22
|
+
/** 输出缓冲区最大行数 (默认: 10000) */
|
|
23
|
+
maxBufferLines?: number;
|
|
24
|
+
/** 实例名称 (默认: 工作目录名) */
|
|
25
|
+
instanceName?: string;
|
|
26
|
+
/** 快捷输入列表 */
|
|
27
|
+
shortcuts?: Array<{
|
|
28
|
+
label: string;
|
|
29
|
+
data: string;
|
|
30
|
+
enabled: boolean;
|
|
31
|
+
desc?: string;
|
|
32
|
+
}>;
|
|
33
|
+
/** 自定义命令列表 */
|
|
34
|
+
commands?: Array<{
|
|
35
|
+
label: string;
|
|
36
|
+
command: string;
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
desc?: string;
|
|
39
|
+
}>;
|
|
40
|
+
/** 预设工作目录列表 */
|
|
41
|
+
workspaces?: string[];
|
|
42
|
+
/** 钉钉群机器人 Webhook 配置 */
|
|
43
|
+
dingtalk?: {
|
|
44
|
+
/** Webhook URL */
|
|
45
|
+
webhookUrl: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 运行时配置结构 (融合用户配置 + CLI 参数 + 默认值)
|
|
50
|
+
*/
|
|
51
|
+
export interface AppConfig {
|
|
52
|
+
port: number;
|
|
53
|
+
host: string;
|
|
54
|
+
displayIp: string;
|
|
55
|
+
claudeCommand: string;
|
|
56
|
+
claudeArgs: string[];
|
|
57
|
+
claudeCwd: string;
|
|
58
|
+
token: string | null;
|
|
59
|
+
sessionTtlMs: number;
|
|
60
|
+
authRateLimit: number;
|
|
61
|
+
maxBufferLines: number;
|
|
62
|
+
instanceName: string;
|
|
63
|
+
logDir: string;
|
|
64
|
+
sessionCookieName: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 获取用户配置目录路径 (~/.claude-remote/)
|
|
68
|
+
*/
|
|
69
|
+
export declare function getUserConfigDir(): string;
|
|
70
|
+
/**
|
|
71
|
+
* 获取用户配置文件路径 (~/.claude-remote/config.json)
|
|
72
|
+
*/
|
|
73
|
+
export declare function getUserConfigPath(): string;
|
|
74
|
+
/**
|
|
75
|
+
* 加载用户配置文件
|
|
76
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
77
|
+
* @returns 用户配置对象,文件不存在或解析失败返回空对象
|
|
78
|
+
*/
|
|
79
|
+
export declare function loadUserConfig(configDir?: string): UserConfig;
|
|
80
|
+
/**
|
|
81
|
+
* CLI 覆盖参数 (优先级最高)
|
|
82
|
+
*/
|
|
83
|
+
export interface CliOverrides {
|
|
84
|
+
port?: number;
|
|
85
|
+
host?: string;
|
|
86
|
+
token?: string;
|
|
87
|
+
instanceName?: string;
|
|
88
|
+
claudeArgs?: string[];
|
|
89
|
+
noTerminal?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 加载运行时配置
|
|
93
|
+
* 优先级: CLI 参数 > 用户配置文件 > 默认值
|
|
94
|
+
*
|
|
95
|
+
* @param cliOverrides CLI 传入的覆盖参数
|
|
96
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
97
|
+
*/
|
|
98
|
+
export declare function loadConfig(cliOverrides?: CliOverrides, configDir?: string): AppConfig;
|
|
99
|
+
export declare function createSessionCookieName(port: number): string;
|
|
100
|
+
/** 默认快捷键列表 - 从 shared 包导入 */
|
|
101
|
+
export declare const DEFAULT_SHORTCUTS: NonNullable<UserConfig['shortcuts']>;
|
|
102
|
+
/** 默认命令列表 - 从 shared 包导入 */
|
|
103
|
+
export declare const DEFAULT_COMMANDS: NonNullable<UserConfig['commands']>;
|
|
104
|
+
/**
|
|
105
|
+
* 填充缺失的 shortcuts 到配置对象
|
|
106
|
+
*/
|
|
107
|
+
export declare function fillDefaultShortcuts(config: UserConfig): UserConfig;
|
|
108
|
+
/**
|
|
109
|
+
* 填充缺失的 commands 到配置对象
|
|
110
|
+
*/
|
|
111
|
+
export declare function fillDefaultCommands(config: UserConfig): UserConfig;
|
|
112
|
+
/**
|
|
113
|
+
* 生成 Claude Code 专属配置(包含 hook URL)
|
|
114
|
+
* @param port 服务端口
|
|
115
|
+
* @param existingSettings 可选的现有 settings 对象,会与 hooks 合并
|
|
116
|
+
*/
|
|
117
|
+
export declare function createClaudeSettings(port: number, existingSettings?: Record<string, unknown>): Record<string, unknown>;
|
|
118
|
+
/**
|
|
119
|
+
* 保存 Claude Code settings 到文件,返回文件路径
|
|
120
|
+
* 文件保存在 ~/.claude-remote/settings/{port}.json
|
|
121
|
+
* 注意:使用同步写入,仅在启动阶段调用
|
|
122
|
+
*/
|
|
123
|
+
export declare function saveClaudeSettings(settings: Record<string, unknown>, port: number, sharedConfigDir: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* 确保用户配置文件包含默认的 shortcuts 和 commands
|
|
126
|
+
* - 配置文件不存在时创建
|
|
127
|
+
* - shortcuts 或 commands 缺失或为空数组时写入默认值
|
|
128
|
+
* - 使用文件锁保护并发写入
|
|
129
|
+
*
|
|
130
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
131
|
+
* @returns shortcutsWritten/commandsWritten 是否写入了默认值
|
|
132
|
+
*/
|
|
133
|
+
export declare function ensureDefaultUserConfig(configDir?: string): Promise<{
|
|
134
|
+
shortcutsWritten: boolean;
|
|
135
|
+
commandsWritten: boolean;
|
|
136
|
+
}>;
|
|
137
|
+
/**
|
|
138
|
+
* 从 claudeArgs 中找到 --settings 参数的值
|
|
139
|
+
* 返回 { settingsPath: string, settingsValue: object, otherArgs: string[] } 或 null
|
|
140
|
+
*/
|
|
141
|
+
export declare function extractSettingsFromArgs(args: string[]): {
|
|
142
|
+
settingsPath: string;
|
|
143
|
+
settingsValue: Record<string, unknown>;
|
|
144
|
+
otherArgs: string[];
|
|
145
|
+
} | null;
|
|
146
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { DEFAULT_PORT, DEFAULT_SESSION_TTL_MS, DEFAULT_AUTH_RATE_LIMIT, DEFAULT_MAX_BUFFER_LINES, SETTINGS_DIR, CLAUDE_REMOTE_DIR, DEFAULT_SHORTCUTS as SHARED_DEFAULT_SHORTCUTS, DEFAULT_COMMANDS as SHARED_DEFAULT_COMMANDS, } from '../shared-dist/index.js';
|
|
2
|
+
import { basename, dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
5
|
+
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { detectLanIp, detectNonLoopbackIp } from './utils/network.js';
|
|
8
|
+
import { logger } from './logger/logger.js';
|
|
9
|
+
import { withFileLockAsync } from './utils/file-lock.js';
|
|
10
|
+
/** 配置文件名 */
|
|
11
|
+
const CONFIG_FILENAME = 'config.json';
|
|
12
|
+
/**
|
|
13
|
+
* 获取用户配置目录路径 (~/.claude-remote/)
|
|
14
|
+
*/
|
|
15
|
+
export function getUserConfigDir() {
|
|
16
|
+
return resolve(homedir(), CLAUDE_REMOTE_DIR);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 获取用户配置文件路径 (~/.claude-remote/config.json)
|
|
20
|
+
*/
|
|
21
|
+
export function getUserConfigPath() {
|
|
22
|
+
return resolve(getUserConfigDir(), CONFIG_FILENAME);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 加载用户配置文件
|
|
26
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
27
|
+
* @returns 用户配置对象,文件不存在或解析失败返回空对象
|
|
28
|
+
*/
|
|
29
|
+
export function loadUserConfig(configDir) {
|
|
30
|
+
const dir = configDir ?? getUserConfigDir();
|
|
31
|
+
const configPath = resolve(dir, CONFIG_FILENAME);
|
|
32
|
+
if (!existsSync(configPath)) {
|
|
33
|
+
logger.debug({ configPath }, 'User config file not found, using defaults');
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
38
|
+
const config = JSON.parse(content);
|
|
39
|
+
// 向后兼容:迁移旧的 defaultClaudeArgs 到 claudeArgs
|
|
40
|
+
const rawConfig = config;
|
|
41
|
+
if (!config.claudeArgs && rawConfig.defaultClaudeArgs) {
|
|
42
|
+
config.claudeArgs = rawConfig.defaultClaudeArgs;
|
|
43
|
+
logger.info('Migrated defaultClaudeArgs to claudeArgs');
|
|
44
|
+
}
|
|
45
|
+
logger.info({ configPath, keys: Object.keys(config) }, 'User config loaded');
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
logger.warn({ configPath, err }, 'Failed to parse user config, using defaults');
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 加载运行时配置
|
|
55
|
+
* 优先级: CLI 参数 > 用户配置文件 > 默认值
|
|
56
|
+
*
|
|
57
|
+
* @param cliOverrides CLI 传入的覆盖参数
|
|
58
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
59
|
+
*/
|
|
60
|
+
export function loadConfig(cliOverrides = {}, configDir) {
|
|
61
|
+
const userConfig = loadUserConfig(configDir);
|
|
62
|
+
// Detect IP for display (try private IP first, then any non-loopback)
|
|
63
|
+
const displayIp = detectLanIp() ?? detectNonLoopbackIp() ?? '127.0.0.1';
|
|
64
|
+
// 优先级: CLI > 用户配置 > 默认值
|
|
65
|
+
const port = cliOverrides.port ?? userConfig.port ?? DEFAULT_PORT;
|
|
66
|
+
const claudeCwd = userConfig.claudeCwd ?? process.cwd();
|
|
67
|
+
// 合并 claudeArgs:配置文件参数在前,命令行参数在后
|
|
68
|
+
const userArgs = userConfig.claudeArgs ?? [];
|
|
69
|
+
const cliArgs = cliOverrides.claudeArgs ?? [];
|
|
70
|
+
const mergedArgs = [...userArgs, ...cliArgs];
|
|
71
|
+
if (userArgs.length > 0 && cliArgs.length > 0) {
|
|
72
|
+
logger.info({ userArgs, cliArgs, mergedArgs }, 'Merged claudeArgs from config file and CLI');
|
|
73
|
+
}
|
|
74
|
+
const config = {
|
|
75
|
+
port,
|
|
76
|
+
host: cliOverrides.host ?? userConfig.host ?? '0.0.0.0',
|
|
77
|
+
displayIp,
|
|
78
|
+
claudeCommand: userConfig.claudeCommand ?? 'claude',
|
|
79
|
+
claudeArgs: mergedArgs,
|
|
80
|
+
claudeCwd,
|
|
81
|
+
token: cliOverrides.token ?? userConfig.token ?? null,
|
|
82
|
+
sessionTtlMs: userConfig.sessionTtlMs ?? DEFAULT_SESSION_TTL_MS,
|
|
83
|
+
authRateLimit: userConfig.authRateLimit ?? DEFAULT_AUTH_RATE_LIMIT,
|
|
84
|
+
maxBufferLines: userConfig.maxBufferLines ?? DEFAULT_MAX_BUFFER_LINES,
|
|
85
|
+
instanceName: cliOverrides.instanceName ?? userConfig.instanceName ?? basename(claudeCwd),
|
|
86
|
+
logDir: resolve(dirname(fileURLToPath(import.meta.url)), '../..', 'logs'),
|
|
87
|
+
sessionCookieName: createSessionCookieName(port),
|
|
88
|
+
};
|
|
89
|
+
logger.info({
|
|
90
|
+
port: config.port,
|
|
91
|
+
host: config.host,
|
|
92
|
+
displayIp: config.displayIp,
|
|
93
|
+
claudeCommand: config.claudeCommand,
|
|
94
|
+
sessionCookieName: config.sessionCookieName,
|
|
95
|
+
configSource: {
|
|
96
|
+
cli: Object.keys(cliOverrides).filter(k => cliOverrides[k] !== undefined),
|
|
97
|
+
user: Object.keys(userConfig).filter(k => userConfig[k] !== undefined),
|
|
98
|
+
},
|
|
99
|
+
}, 'Configuration loaded');
|
|
100
|
+
return config;
|
|
101
|
+
}
|
|
102
|
+
export function createSessionCookieName(port) {
|
|
103
|
+
return `session_id_p${port}`;
|
|
104
|
+
}
|
|
105
|
+
/** 默认快捷键列表 - 从 shared 包导入 */
|
|
106
|
+
export const DEFAULT_SHORTCUTS = SHARED_DEFAULT_SHORTCUTS;
|
|
107
|
+
/** 默认命令列表 - 从 shared 包导入 */
|
|
108
|
+
export const DEFAULT_COMMANDS = SHARED_DEFAULT_COMMANDS;
|
|
109
|
+
/**
|
|
110
|
+
* 填充缺失的 shortcuts 到配置对象
|
|
111
|
+
*/
|
|
112
|
+
export function fillDefaultShortcuts(config) {
|
|
113
|
+
if (config.shortcuts)
|
|
114
|
+
return config;
|
|
115
|
+
return { ...config, shortcuts: DEFAULT_SHORTCUTS };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 填充缺失的 commands 到配置对象
|
|
119
|
+
*/
|
|
120
|
+
export function fillDefaultCommands(config) {
|
|
121
|
+
if (config.commands)
|
|
122
|
+
return config;
|
|
123
|
+
return { ...config, commands: DEFAULT_COMMANDS };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 生成 Claude Code 专属配置(包含 hook URL)
|
|
127
|
+
* @param port 服务端口
|
|
128
|
+
* @param existingSettings 可选的现有 settings 对象,会与 hooks 合并
|
|
129
|
+
*/
|
|
130
|
+
export function createClaudeSettings(port, existingSettings) {
|
|
131
|
+
const hookUrl = `http://localhost:${port}/api/hook`;
|
|
132
|
+
// 使用 -d @- 从 stdin 读取 hook payload,避免 shell 转义问题
|
|
133
|
+
const hookCommand = `curl -s -X POST ${hookUrl} -H 'Content-Type: application/json' -d @-`;
|
|
134
|
+
const hooksConfig = {
|
|
135
|
+
hooks: {
|
|
136
|
+
Notification: [
|
|
137
|
+
{
|
|
138
|
+
matcher: "permission_prompt",
|
|
139
|
+
hooks: [{ type: "command", command: hookCommand }]
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
PreToolUse: [
|
|
143
|
+
{
|
|
144
|
+
matcher: "AskUserQuestion",
|
|
145
|
+
hooks: [{ type: "command", command: hookCommand }]
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
// 如果有现有 settings,合并 hooks 配置(保留用户自定义的其他 hook 事件)
|
|
151
|
+
// 注意:同名 hook 事件(Notification / PreToolUse)会被我们的配置覆盖,
|
|
152
|
+
// 因为这些事件是 claude-remote 正常工作的必要条件
|
|
153
|
+
if (existingSettings) {
|
|
154
|
+
const existingHooks = (existingSettings.hooks ?? {});
|
|
155
|
+
const overriddenKeys = Object.keys(hooksConfig.hooks).filter(k => k in existingHooks);
|
|
156
|
+
if (overriddenKeys.length > 0) {
|
|
157
|
+
logger.warn({ overriddenKeys }, 'User hook events overridden by claude-remote hooks');
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
...existingSettings,
|
|
161
|
+
hooks: { ...existingHooks, ...hooksConfig.hooks },
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return hooksConfig;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 保存 Claude Code settings 到文件,返回文件路径
|
|
168
|
+
* 文件保存在 ~/.claude-remote/settings/{port}.json
|
|
169
|
+
* 注意:使用同步写入,仅在启动阶段调用
|
|
170
|
+
*/
|
|
171
|
+
export function saveClaudeSettings(settings, port, sharedConfigDir) {
|
|
172
|
+
const settingsDir = resolve(sharedConfigDir, SETTINGS_DIR);
|
|
173
|
+
// 确保目录存在
|
|
174
|
+
if (!existsSync(settingsDir)) {
|
|
175
|
+
mkdirSync(settingsDir, { recursive: true });
|
|
176
|
+
}
|
|
177
|
+
const settingsPath = resolve(settingsDir, `${port}.json`);
|
|
178
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf-8');
|
|
179
|
+
logger.info({ settingsPath, port }, 'Claude settings saved to file');
|
|
180
|
+
return settingsPath;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 确保用户配置文件包含默认的 shortcuts 和 commands
|
|
184
|
+
* - 配置文件不存在时创建
|
|
185
|
+
* - shortcuts 或 commands 缺失或为空数组时写入默认值
|
|
186
|
+
* - 使用文件锁保护并发写入
|
|
187
|
+
*
|
|
188
|
+
* @param configDir 配置目录路径 (默认: ~/.claude-remote/)
|
|
189
|
+
* @returns shortcutsWritten/commandsWritten 是否写入了默认值
|
|
190
|
+
*/
|
|
191
|
+
export async function ensureDefaultUserConfig(configDir) {
|
|
192
|
+
const dir = configDir ?? getUserConfigDir();
|
|
193
|
+
const configPath = resolve(dir, CONFIG_FILENAME);
|
|
194
|
+
const lockPath = `${configPath}.lock`;
|
|
195
|
+
const result = { shortcutsWritten: false, commandsWritten: false };
|
|
196
|
+
try {
|
|
197
|
+
await withFileLockAsync(lockPath, async () => {
|
|
198
|
+
// 确保配置目录存在
|
|
199
|
+
if (!existsSync(dir)) {
|
|
200
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
201
|
+
}
|
|
202
|
+
// 读取现有配置(使用 try-catch 处理文件不存在和解析错误)
|
|
203
|
+
let config;
|
|
204
|
+
let needsWrite = false;
|
|
205
|
+
try {
|
|
206
|
+
const content = await readFile(configPath, 'utf-8');
|
|
207
|
+
config = JSON.parse(content);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
if (err.code === 'ENOENT') {
|
|
211
|
+
// 文件不存在,使用空对象
|
|
212
|
+
config = {};
|
|
213
|
+
}
|
|
214
|
+
else if (err instanceof SyntaxError) {
|
|
215
|
+
// JSON 解析失败,备份损坏文件后覆盖默认值
|
|
216
|
+
const backupPath = `${configPath}.backup-${Date.now()}`;
|
|
217
|
+
try {
|
|
218
|
+
const corruptContent = await readFile(configPath, 'utf-8');
|
|
219
|
+
await writeFile(backupPath, corruptContent, { mode: 0o600 });
|
|
220
|
+
logger.warn({ configPath, backupPath }, 'Failed to parse user config, backed up corrupt file and overwriting with defaults');
|
|
221
|
+
}
|
|
222
|
+
catch (backupErr) {
|
|
223
|
+
logger.warn({ configPath, backupErr }, 'Failed to backup corrupt config file, proceeding with defaults');
|
|
224
|
+
}
|
|
225
|
+
config = {};
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
throw err;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// 检查 shortcuts
|
|
232
|
+
if (!config.shortcuts || config.shortcuts.length === 0) {
|
|
233
|
+
config.shortcuts = DEFAULT_SHORTCUTS;
|
|
234
|
+
result.shortcutsWritten = true;
|
|
235
|
+
needsWrite = true;
|
|
236
|
+
}
|
|
237
|
+
// 检查 commands
|
|
238
|
+
if (!config.commands || config.commands.length === 0) {
|
|
239
|
+
config.commands = DEFAULT_COMMANDS;
|
|
240
|
+
result.commandsWritten = true;
|
|
241
|
+
needsWrite = true;
|
|
242
|
+
}
|
|
243
|
+
// 写入配置(如果需要)
|
|
244
|
+
if (needsWrite) {
|
|
245
|
+
await writeFile(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
246
|
+
logger.info({
|
|
247
|
+
configPath,
|
|
248
|
+
shortcutsWritten: result.shortcutsWritten,
|
|
249
|
+
commandsWritten: result.commandsWritten,
|
|
250
|
+
}, 'Default shortcuts/commands written to user config');
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
// 失败时记录日志但不阻塞启动
|
|
256
|
+
logger.warn({ configPath, err }, 'Failed to ensure default user config, continuing startup');
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 从 claudeArgs 中找到 --settings 参数的值
|
|
262
|
+
* 返回 { settingsPath: string, settingsValue: object, otherArgs: string[] } 或 null
|
|
263
|
+
*/
|
|
264
|
+
export function extractSettingsFromArgs(args) {
|
|
265
|
+
let settingsPath = null;
|
|
266
|
+
let settingsValue = null;
|
|
267
|
+
const otherArgs = [];
|
|
268
|
+
for (let i = 0; i < args.length; i++) {
|
|
269
|
+
const arg = args[i];
|
|
270
|
+
if (arg === '--settings' && i + 1 < args.length) {
|
|
271
|
+
const value = args[i + 1];
|
|
272
|
+
i++; // 无论解析成功与否,都跳过 value 参数
|
|
273
|
+
// 检查是文件路径还是 JSON 字符串
|
|
274
|
+
if (existsSync(value)) {
|
|
275
|
+
settingsPath = value;
|
|
276
|
+
try {
|
|
277
|
+
settingsValue = JSON.parse(readFileSync(value, 'utf-8'));
|
|
278
|
+
logger.info({ settingsPath }, 'Loaded user settings file for merging');
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
logger.warn({ settingsPath, err: e }, 'Failed to parse user settings file, ignoring');
|
|
282
|
+
otherArgs.push(arg, value);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
// 可能是 JSON 字符串,尝试解析
|
|
287
|
+
try {
|
|
288
|
+
settingsValue = JSON.parse(value);
|
|
289
|
+
logger.info('Detected inline JSON settings for merging');
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
// 不是 JSON,保留原样
|
|
293
|
+
otherArgs.push(arg, value);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else if (arg.startsWith('--settings=')) {
|
|
298
|
+
const value = arg.slice('--settings='.length);
|
|
299
|
+
if (existsSync(value)) {
|
|
300
|
+
settingsPath = value;
|
|
301
|
+
try {
|
|
302
|
+
settingsValue = JSON.parse(readFileSync(value, 'utf-8'));
|
|
303
|
+
logger.info({ settingsPath }, 'Loaded user settings file for merging');
|
|
304
|
+
}
|
|
305
|
+
catch (e) {
|
|
306
|
+
logger.warn({ settingsPath, err: e }, 'Failed to parse user settings file, ignoring');
|
|
307
|
+
otherArgs.push(arg);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
try {
|
|
312
|
+
settingsValue = JSON.parse(value);
|
|
313
|
+
logger.info('Detected inline JSON settings for merging');
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
otherArgs.push(arg);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
otherArgs.push(arg);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (settingsValue) {
|
|
325
|
+
return { settingsPath: settingsPath || 'inline', settingsValue, otherArgs };
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
/**
|
|
3
|
+
* Raw hook payload from Claude Code hooks (Notification / PreToolUse).
|
|
4
|
+
*/
|
|
5
|
+
export interface HookPayload {
|
|
6
|
+
message?: string;
|
|
7
|
+
notification_type?: string;
|
|
8
|
+
hook_event_name?: string;
|
|
9
|
+
session_id?: string;
|
|
10
|
+
tool_name?: string;
|
|
11
|
+
tool_input?: Record<string, unknown>;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Simplified notification info emitted from hook processing.
|
|
16
|
+
*/
|
|
17
|
+
export interface HookNotification {
|
|
18
|
+
tool: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Structured result from processHook.
|
|
23
|
+
*/
|
|
24
|
+
export interface HookResult {
|
|
25
|
+
type: 'notification' | 'ignored';
|
|
26
|
+
notification?: HookNotification;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Receives and parses Hook HTTP POST from Claude Code.
|
|
30
|
+
* Emits 'notification' events for permission prompts.
|
|
31
|
+
*/
|
|
32
|
+
export declare class HookReceiver extends EventEmitter {
|
|
33
|
+
/**
|
|
34
|
+
* Process an incoming hook payload.
|
|
35
|
+
*/
|
|
36
|
+
processHook(payload: HookPayload): HookResult;
|
|
37
|
+
private extractToolFromMessage;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=hook-receiver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-receiver.d.ts","sourceRoot":"","sources":["../../src/hooks/hook-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,GAAG,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAKD;;;GAGG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU;IAiC7C,OAAO,CAAC,sBAAsB;CAK/B"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { logger } from '../logger/logger.js';
|
|
3
|
+
// Pattern: "Claude needs your permission to use <ToolName>"
|
|
4
|
+
const PERMISSION_TOOL_RE = /permission to use (\S+)$/;
|
|
5
|
+
/**
|
|
6
|
+
* Receives and parses Hook HTTP POST from Claude Code.
|
|
7
|
+
* Emits 'notification' events for permission prompts.
|
|
8
|
+
*/
|
|
9
|
+
export class HookReceiver extends EventEmitter {
|
|
10
|
+
/**
|
|
11
|
+
* Process an incoming hook payload.
|
|
12
|
+
*/
|
|
13
|
+
processHook(payload) {
|
|
14
|
+
logger.info({ payload }, 'Hook received');
|
|
15
|
+
// PreToolUse: ignore all PreToolUse events
|
|
16
|
+
if (payload.hook_event_name === 'PreToolUse') {
|
|
17
|
+
logger.debug({ toolName: payload.tool_name }, 'PreToolUse event ignored');
|
|
18
|
+
return { type: 'ignored' };
|
|
19
|
+
}
|
|
20
|
+
// Notification: only handle permission_prompt
|
|
21
|
+
if (payload.notification_type && payload.notification_type !== 'permission_prompt') {
|
|
22
|
+
logger.debug({ notificationType: payload.notification_type }, 'Non-permission hook ignored');
|
|
23
|
+
return { type: 'ignored' };
|
|
24
|
+
}
|
|
25
|
+
// Extract tool name: prefer explicit tool_name, then parse from message
|
|
26
|
+
const toolName = payload.tool_name
|
|
27
|
+
?? this.extractToolFromMessage(payload.message)
|
|
28
|
+
?? 'unknown_tool';
|
|
29
|
+
const message = payload.message
|
|
30
|
+
?? (payload.tool_name ? `Tool call: ${payload.tool_name}` : 'Approval requested (no details provided)');
|
|
31
|
+
const notification = {
|
|
32
|
+
tool: String(toolName),
|
|
33
|
+
message: String(message),
|
|
34
|
+
};
|
|
35
|
+
logger.info({ tool: notification.tool }, 'Hook notification created');
|
|
36
|
+
this.emit('notification', notification);
|
|
37
|
+
return { type: 'notification', notification };
|
|
38
|
+
}
|
|
39
|
+
extractToolFromMessage(message) {
|
|
40
|
+
if (!message)
|
|
41
|
+
return null;
|
|
42
|
+
const match = PERMISSION_TOOL_RE.exec(message);
|
|
43
|
+
return match ? match[1] : null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=hook-receiver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-receiver.js","sourceRoot":"","sources":["../../src/hooks/hook-receiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA+B7C,4DAA4D;AAC5D,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,YAAY;IAC5C;;OAEG;IACH,WAAW,CAAC,OAAoB;QAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;QAE1C,2CAA2C;QAC3C,IAAI,OAAO,CAAC,eAAe,KAAK,YAAY,EAAE,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,0BAA0B,CAAC,CAAC;YAC1E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,8CAA8C;QAC9C,IAAI,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,KAAK,mBAAmB,EAAE,CAAC;YACnF,MAAM,CAAC,KAAK,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,iBAAiB,EAAE,EAAE,6BAA6B,CAAC,CAAC;YAC7F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,wEAAwE;QACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS;eAC7B,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,OAAO,CAAC;eAC5C,cAAc,CAAC;QAEpB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;eAC1B,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC;QAE1G,MAAM,YAAY,GAAqB;YACrC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC;YACtB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;SACzB,CAAC;QAEF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,2BAA2B,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;IAChD,CAAC;IAEO,sBAAsB,CAAC,OAAgB;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAmI,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAkBjL,wBAAsB,WAAW,CAAC,YAAY,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyWhF"}
|