sessix-server 0.2.8 → 0.3.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.
Files changed (60) hide show
  1. package/dist/index.js +693 -105
  2. package/dist/server.js +660 -93
  3. package/package.json +10 -1
  4. package/dist/approval/ApprovalProxy.d.ts +0 -86
  5. package/dist/approval/ApprovalProxy.d.ts.map +0 -1
  6. package/dist/approval/ApprovalProxy.js +0 -363
  7. package/dist/approval/ApprovalProxy.js.map +0 -1
  8. package/dist/hooks/HookInstaller.d.ts +0 -55
  9. package/dist/hooks/HookInstaller.d.ts.map +0 -1
  10. package/dist/hooks/HookInstaller.js +0 -215
  11. package/dist/hooks/HookInstaller.js.map +0 -1
  12. package/dist/index.d.ts +0 -2
  13. package/dist/index.d.ts.map +0 -1
  14. package/dist/index.js.map +0 -1
  15. package/dist/mdns/MdnsService.d.ts +0 -36
  16. package/dist/mdns/MdnsService.d.ts.map +0 -1
  17. package/dist/mdns/MdnsService.js +0 -66
  18. package/dist/mdns/MdnsService.js.map +0 -1
  19. package/dist/notification/ActivityPushChannel.d.ts +0 -54
  20. package/dist/notification/ActivityPushChannel.d.ts.map +0 -1
  21. package/dist/notification/ActivityPushChannel.js +0 -235
  22. package/dist/notification/ActivityPushChannel.js.map +0 -1
  23. package/dist/notification/ExpoNotificationChannel.d.ts +0 -17
  24. package/dist/notification/ExpoNotificationChannel.d.ts.map +0 -1
  25. package/dist/notification/ExpoNotificationChannel.js +0 -57
  26. package/dist/notification/ExpoNotificationChannel.js.map +0 -1
  27. package/dist/notification/MacNotificationChannel.d.ts +0 -22
  28. package/dist/notification/MacNotificationChannel.d.ts.map +0 -1
  29. package/dist/notification/MacNotificationChannel.js +0 -33
  30. package/dist/notification/MacNotificationChannel.js.map +0 -1
  31. package/dist/notification/NotificationService.d.ts +0 -50
  32. package/dist/notification/NotificationService.d.ts.map +0 -1
  33. package/dist/notification/NotificationService.js +0 -177
  34. package/dist/notification/NotificationService.js.map +0 -1
  35. package/dist/providers/ExecutionProvider.d.ts +0 -60
  36. package/dist/providers/ExecutionProvider.d.ts.map +0 -1
  37. package/dist/providers/ExecutionProvider.js +0 -3
  38. package/dist/providers/ExecutionProvider.js.map +0 -1
  39. package/dist/providers/ProcessProvider.d.ts +0 -117
  40. package/dist/providers/ProcessProvider.d.ts.map +0 -1
  41. package/dist/providers/ProcessProvider.js +0 -507
  42. package/dist/providers/ProcessProvider.js.map +0 -1
  43. package/dist/server.d.ts.map +0 -1
  44. package/dist/server.js.map +0 -1
  45. package/dist/session/ProjectReader.d.ts +0 -44
  46. package/dist/session/ProjectReader.d.ts.map +0 -1
  47. package/dist/session/ProjectReader.js +0 -471
  48. package/dist/session/ProjectReader.js.map +0 -1
  49. package/dist/session/SessionFileWatcher.d.ts +0 -35
  50. package/dist/session/SessionFileWatcher.d.ts.map +0 -1
  51. package/dist/session/SessionFileWatcher.js +0 -207
  52. package/dist/session/SessionFileWatcher.js.map +0 -1
  53. package/dist/session/SessionManager.d.ts +0 -114
  54. package/dist/session/SessionManager.d.ts.map +0 -1
  55. package/dist/session/SessionManager.js +0 -356
  56. package/dist/session/SessionManager.js.map +0 -1
  57. package/dist/ws/WsBridge.d.ts +0 -55
  58. package/dist/ws/WsBridge.d.ts.map +0 -1
  59. package/dist/ws/WsBridge.js +0 -220
  60. package/dist/ws/WsBridge.js.map +0 -1
@@ -1,215 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HookInstaller = void 0;
4
- const promises_1 = require("node:fs/promises");
5
- const node_path_1 = require("node:path");
6
- const node_os_1 = require("node:os");
7
- /** Sessix hook 脚本存放目录 */
8
- const SESSIX_HOOKS_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.sessix', 'hooks');
9
- /** Hook 脚本文件路径 */
10
- const HOOK_SCRIPT_PATH = (0, node_path_1.join)(SESSIX_HOOKS_DIR, 'approval-hook.sh');
11
- /** Claude Code settings.json 路径 */
12
- const CLAUDE_SETTINGS_PATH = (0, node_path_1.join)((0, node_os_1.homedir)(), '.claude', 'settings.json');
13
- /** hook 脚本命令(使用 ~ 前缀,Claude Code 会展开) */
14
- const HOOK_COMMAND = '~/.sessix/hooks/approval-hook.sh';
15
- /**
16
- * approval-hook.sh 脚本模板
17
- *
18
- * 仅在 Sessix 管理的会话中激活(检查 SESSIX_SESSION_ID 环境变量)。
19
- * 将 hook payload 发送到 Sessix HTTP 审批端点,等待用户决定。
20
- * 通过 exit code 向 Claude Code 报告批准结果:
21
- * - exit 0: 批准(用户同意或服务器超时自动批准)
22
- * - exit 1: 拒绝(用户明确拒绝)
23
- */
24
- const HOOK_SCRIPT_TEMPLATE = `#!/bin/bash
25
- # Sessix Approval Hook
26
- # 仅在 Sessix 管理的会话中激活
27
-
28
- if [ -z "$SESSIX_SESSION_ID" ]; then
29
- exit 0
30
- fi
31
-
32
- # 从 stdin 读取 hook payload
33
- PAYLOAD=$(cat)
34
-
35
- # 获取项目路径(当前工作目录)
36
- PROJECT_PATH="$PWD"
37
-
38
- # 发送审批请求到 Sessix 服务器(长轮询,超时时间 > 300s)
39
- RESPONSE=$(curl -s -X POST "http://localhost:3746/hook/approval" \\
40
- -H "Content-Type: application/json" \\
41
- -d "{\\"sessionId\\": \\"$SESSIX_SESSION_ID\\", \\"projectPath\\": \\"$PROJECT_PATH\\", \\"payload\\": $PAYLOAD}" \\
42
- --max-time 330 \\
43
- 2>/dev/null)
44
-
45
- if [ $? -ne 0 ] || [ -z "$RESPONSE" ]; then
46
- # 如果 Sessix 服务器不可用,默认放行(exit 0 = 批准)
47
- exit 0
48
- fi
49
-
50
- # 解析服务器响应
51
- DECISION=\$(echo "$RESPONSE" | grep -o '\\"decision\\":\\"[^"]*\\"' | cut -d'"' -f4)
52
-
53
- if [ "$DECISION" = "allow" ]; then
54
- # 用户批准或服务器超时自动批准
55
- exit 0
56
- elif [ "$DECISION" = "deny" ]; then
57
- # 用户明确拒绝
58
- exit 1
59
- else
60
- # 未知响应,默认放行
61
- exit 0
62
- fi
63
- `;
64
- /**
65
- * Hook 安装器
66
- *
67
- * 负责将 Sessix 的审批 hook 脚本安装到 Claude Code 中:
68
- * 1. 创建 ~/.sessix/hooks/ 目录并写入 approval-hook.sh
69
- * 2. 在 ~/.claude/settings.json 中注册 PreToolUse hook
70
- */
71
- class HookInstaller {
72
- /**
73
- * 安装 hook
74
- *
75
- * 1. 创建 ~/.sessix/hooks/ 目录
76
- * 2. 写入 approval-hook.sh 脚本
77
- * 3. 赋予执行权限
78
- * 4. 更新 Claude Code settings.json 添加 hook 配置
79
- */
80
- async install() {
81
- // 1. 创建 hooks 目录
82
- await (0, promises_1.mkdir)(SESSIX_HOOKS_DIR, { recursive: true });
83
- // 2. 写入 hook 脚本
84
- await (0, promises_1.writeFile)(HOOK_SCRIPT_PATH, HOOK_SCRIPT_TEMPLATE, 'utf-8');
85
- // 3. 添加执行权限
86
- await (0, promises_1.chmod)(HOOK_SCRIPT_PATH, 0o755);
87
- // 4. 更新 Claude Code settings.json
88
- await this.addHookToSettings();
89
- console.log('[HookInstaller] Hook 安装完成');
90
- }
91
- /**
92
- * 卸载 hook
93
- *
94
- * 从 Claude Code settings.json 中移除 Sessix hook 配置。
95
- * 注意:不删除 hook 脚本文件(保持幂等性,避免误删)。
96
- */
97
- async uninstall() {
98
- await this.removeHookFromSettings();
99
- console.log('[HookInstaller] Hook 已卸载');
100
- }
101
- /**
102
- * 检查 hook 是否已安装
103
- * 脚本文件和 settings.json 配置必须同时存在才算已安装
104
- */
105
- async isInstalled() {
106
- // 检查脚本文件是否存在
107
- let scriptExists = false;
108
- try {
109
- await (0, promises_1.access)(HOOK_SCRIPT_PATH);
110
- scriptExists = true;
111
- }
112
- catch {
113
- // 脚本不存在
114
- }
115
- // 检查 settings.json 中是否有 Sessix hook 配置
116
- const settings = await this.readClaudeSettings();
117
- const configExists = this.hasHookConfig(settings);
118
- // 两者都存在才算已安装
119
- return scriptExists && configExists;
120
- }
121
- // ============================================
122
- // 内部方法
123
- // ============================================
124
- /**
125
- * 向 Claude Code settings.json 添加 Sessix hook 配置
126
- */
127
- async addHookToSettings() {
128
- let settings = await this.readClaudeSettings();
129
- // 如果已经存在,跳过
130
- if (this.hasHookConfig(settings)) {
131
- console.log('[HookInstaller] Hook 配置已存在,跳过');
132
- return;
133
- }
134
- // 确保 hooks 和 PreToolUse 结构存在
135
- if (!settings.hooks) {
136
- settings.hooks = {};
137
- }
138
- if (!settings.hooks.PreToolUse) {
139
- settings.hooks.PreToolUse = [];
140
- }
141
- // 添加 Sessix hook 配置
142
- settings.hooks.PreToolUse.push({
143
- matcher: '',
144
- hooks: [
145
- {
146
- type: 'command',
147
- command: HOOK_COMMAND,
148
- },
149
- ],
150
- });
151
- await this.writeClaudeSettings(settings);
152
- }
153
- /**
154
- * 从 Claude Code settings.json 移除 Sessix hook 配置
155
- */
156
- async removeHookFromSettings() {
157
- let settings = await this.readClaudeSettings();
158
- if (!settings.hooks?.PreToolUse) {
159
- return;
160
- }
161
- // 过滤掉包含 Sessix hook 命令的条目
162
- settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter((entry) => !this.isSessionHookEntry(entry));
163
- // 如果 PreToolUse 为空,删除它
164
- if (settings.hooks.PreToolUse.length === 0) {
165
- delete settings.hooks.PreToolUse;
166
- }
167
- // 如果 hooks 为空,删除它
168
- if (Object.keys(settings.hooks).length === 0) {
169
- delete settings.hooks;
170
- }
171
- await this.writeClaudeSettings(settings);
172
- }
173
- /**
174
- * 读取 Claude Code settings.json
175
- */
176
- async readClaudeSettings() {
177
- try {
178
- const content = await (0, promises_1.readFile)(CLAUDE_SETTINGS_PATH, 'utf-8');
179
- return JSON.parse(content);
180
- }
181
- catch {
182
- // 文件不存在或解析失败,返回空对象
183
- return {};
184
- }
185
- }
186
- /**
187
- * 写入 Claude Code settings.json
188
- */
189
- async writeClaudeSettings(settings) {
190
- // 确保 .claude 目录存在
191
- await (0, promises_1.mkdir)((0, node_path_1.join)((0, node_os_1.homedir)(), '.claude'), { recursive: true });
192
- await (0, promises_1.writeFile)(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
193
- }
194
- /**
195
- * 检查 settings 中是否已包含 Sessix hook 配置
196
- */
197
- hasHookConfig(settings) {
198
- const preToolUse = settings?.hooks?.PreToolUse;
199
- if (!Array.isArray(preToolUse)) {
200
- return false;
201
- }
202
- return preToolUse.some((entry) => this.isSessionHookEntry(entry));
203
- }
204
- /**
205
- * 判断一个 hook 条目是否是 Sessix 的
206
- */
207
- isSessionHookEntry(entry) {
208
- if (!entry?.hooks || !Array.isArray(entry.hooks)) {
209
- return false;
210
- }
211
- return entry.hooks.some((hook) => hook.type === 'command' && hook.command === HOOK_COMMAND);
212
- }
213
- }
214
- exports.HookInstaller = HookInstaller;
215
- //# sourceMappingURL=HookInstaller.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HookInstaller.js","sourceRoot":"","sources":["../../src/hooks/HookInstaller.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,36 +0,0 @@
1
- /** mDNS 服务配置 */
2
- interface MdnsServiceOptions {
3
- /** WebSocket 端口 */
4
- wsPort: number;
5
- /** HTTP 审批端口 */
6
- httpPort: number;
7
- /** 服务版本 */
8
- version?: string;
9
- }
10
- /**
11
- * mDNS 局域网广播服务
12
- *
13
- * 使用 bonjour-service 在局域网内广播 Sessix 服务,
14
- * 让手机端能自动发现 Mac 上运行的 Sessix 服务器。
15
- *
16
- * 广播协议:_sessix._tcp
17
- * TXT 记录包含版本号和 HTTP 端口信息。
18
- */
19
- export declare class MdnsService {
20
- private bonjour;
21
- private service;
22
- private wsPort;
23
- private httpPort;
24
- private version;
25
- constructor(options: MdnsServiceOptions);
26
- /**
27
- * 启动 mDNS 广播
28
- */
29
- start(): void;
30
- /**
31
- * 停止 mDNS 广播
32
- */
33
- stop(): void;
34
- }
35
- export {};
36
- //# sourceMappingURL=MdnsService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MdnsService.d.ts","sourceRoot":"","sources":["../../src/mdns/MdnsService.ts"],"names":[],"mappings":"AAEA,gBAAgB;AAChB,UAAU,kBAAkB;IAC1B,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,OAAO,CAAQ;gBAEX,OAAO,EAAE,kBAAkB;IAMvC;;OAEG;IACH,KAAK,IAAI,IAAI;IAqBb;;OAEG;IACH,IAAI,IAAI,IAAI;CAeb"}
@@ -1,66 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MdnsService = void 0;
7
- const bonjour_service_1 = __importDefault(require("bonjour-service"));
8
- /**
9
- * mDNS 局域网广播服务
10
- *
11
- * 使用 bonjour-service 在局域网内广播 Sessix 服务,
12
- * 让手机端能自动发现 Mac 上运行的 Sessix 服务器。
13
- *
14
- * 广播协议:_sessix._tcp
15
- * TXT 记录包含版本号和 HTTP 端口信息。
16
- */
17
- class MdnsService {
18
- bonjour = null;
19
- service = null;
20
- wsPort;
21
- httpPort;
22
- version;
23
- constructor(options) {
24
- this.wsPort = options.wsPort;
25
- this.httpPort = options.httpPort;
26
- this.version = options.version ?? '0.1.0';
27
- }
28
- /**
29
- * 启动 mDNS 广播
30
- */
31
- start() {
32
- if (this.bonjour) {
33
- console.warn('[MdnsService] 服务已在运行中');
34
- return;
35
- }
36
- this.bonjour = new bonjour_service_1.default();
37
- this.service = this.bonjour.publish({
38
- name: 'Sessix',
39
- type: 'sessix',
40
- port: this.wsPort,
41
- txt: {
42
- version: this.version,
43
- httpPort: String(this.httpPort),
44
- },
45
- });
46
- console.log(`[MdnsService] mDNS 广播已启动: _sessix._tcp 端口 ${this.wsPort}`);
47
- }
48
- /**
49
- * 停止 mDNS 广播
50
- */
51
- stop() {
52
- if (this.service) {
53
- this.service.stop?.(() => {
54
- console.log('[MdnsService] 服务广播已停止');
55
- });
56
- this.service = null;
57
- }
58
- if (this.bonjour) {
59
- this.bonjour.destroy();
60
- this.bonjour = null;
61
- }
62
- console.log('[MdnsService] mDNS 服务已关闭');
63
- }
64
- }
65
- exports.MdnsService = MdnsService;
66
- //# sourceMappingURL=MdnsService.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MdnsService.js","sourceRoot":"","sources":["../../src/mdns/MdnsService.ts"],"names":[],"mappings":";;;;;;AAAA,sEAAuD;AAYvD;;;;;;;;GAQG;AACH,MAAa,WAAW;IACd,OAAO,GAAwC,IAAI,CAAA;IACnD,OAAO,GAAmB,IAAI,CAAA;IAC9B,MAAM,CAAQ;IACd,QAAQ,CAAQ;IAChB,OAAO,CAAQ;IAEvB,YAAY,OAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAA;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;YACrC,OAAM;QACR,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAI,yBAAO,EAAE,CAAA;QAE5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YAClC,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,GAAG,EAAE;gBACH,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;aAChC;SACF,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACzE,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE;gBACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;YACtC,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACrB,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAA;YACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACrB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;IACzC,CAAC;CACF;AAvDD,kCAuDC"}
@@ -1,54 +0,0 @@
1
- /**
2
- * ActivityKit Push 通知渠道
3
- *
4
- * 通过 APNs HTTP/2 直接发送 ActivityKit push notification,
5
- * 用于在 App 后台时更新 Live Activity 内容。
6
- *
7
- * 注意:ActivityKit push 使用独立的 push token(不同于普通推送 token),
8
- * 由 Activity 启动时生成,通过 pushTokenUpdates 获取。
9
- */
10
- export interface ActivityPushConfig {
11
- /** Apple Developer Team ID */
12
- teamId: string;
13
- /** APNs Auth Key ID */
14
- keyId: string;
15
- /** APNs Auth Key (.p8) 文件路径 */
16
- authKeyPath: string;
17
- /** 是否使用沙箱环境(开发模式) */
18
- sandbox?: boolean;
19
- }
20
- export declare class ActivityPushChannel {
21
- /** sessionId -> activityPushToken */
22
- private tokens;
23
- private teamId;
24
- private keyId;
25
- private authKey;
26
- private apnsHost;
27
- /** 缓存的 JWT token + 过期时间 */
28
- private cachedJwt;
29
- /** 复用的 HTTP/2 长连接 */
30
- private http2Client;
31
- constructor(config: ActivityPushConfig);
32
- /** 获取或新建 HTTP/2 长连接 */
33
- private getHttp2Client;
34
- /** 注册 Activity push token */
35
- addToken(sessionId: string, token: string): void;
36
- /** 移除 Activity push token */
37
- removeToken(sessionId: string): void;
38
- /** 发送 content-state 更新到指定会话的 Live Activity */
39
- updateActivity(sessionId: string, contentState: Record<string, unknown>): Promise<void>;
40
- /** 发送带通知的 content-state 更新(审批请求时使用) */
41
- updateActivityWithAlert(sessionId: string, contentState: Record<string, unknown>, alert: {
42
- title: string;
43
- body: string;
44
- }): Promise<void>;
45
- /** 结束指定会话的 Live Activity */
46
- endActivity(sessionId: string, contentState: Record<string, unknown>): Promise<void>;
47
- /** 检查是否有指定会话的 token */
48
- hasToken(sessionId: string): boolean;
49
- /** 发送 APNs HTTP/2 请求 */
50
- private sendToAPNs;
51
- /** 生成或获取缓存的 APNs JWT token */
52
- private getJWT;
53
- }
54
- //# sourceMappingURL=ActivityPushChannel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ActivityPushChannel.d.ts","sourceRoot":"","sources":["../../src/notification/ActivityPushChannel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,qBAAa,mBAAmB;IAC9B,qCAAqC;IACrC,OAAO,CAAC,MAAM,CAA4B;IAE1C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAQ;IAExB,2BAA2B;IAC3B,OAAO,CAAC,SAAS,CAAoD;IAErE,qBAAqB;IACrB,OAAO,CAAC,WAAW,CAAwC;gBAE/C,MAAM,EAAE,kBAAkB;IAUtC,uBAAuB;IACvB,OAAO,CAAC,cAAc;IAgBtB,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhD,6BAA6B;IAC7B,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIpC,8CAA8C;IACxC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7F,uCAAuC;IACjC,uBAAuB,CAC3B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GACrC,OAAO,CAAC,IAAI,CAAC;IAqBhB,4BAA4B;IACtB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB1F,uBAAuB;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC,wBAAwB;YACV,UAAU;IA0DxB,8BAA8B;IAC9B,OAAO,CAAC,MAAM;CA4Bf"}
@@ -1,235 +0,0 @@
1
- "use strict";
2
- /**
3
- * ActivityKit Push 通知渠道
4
- *
5
- * 通过 APNs HTTP/2 直接发送 ActivityKit push notification,
6
- * 用于在 App 后台时更新 Live Activity 内容。
7
- *
8
- * 注意:ActivityKit push 使用独立的 push token(不同于普通推送 token),
9
- * 由 Activity 启动时生成,通过 pushTokenUpdates 获取。
10
- */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || (function () {
28
- var ownKeys = function(o) {
29
- ownKeys = Object.getOwnPropertyNames || function (o) {
30
- var ar = [];
31
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
- return ar;
33
- };
34
- return ownKeys(o);
35
- };
36
- return function (mod) {
37
- if (mod && mod.__esModule) return mod;
38
- var result = {};
39
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
- __setModuleDefault(result, mod);
41
- return result;
42
- };
43
- })();
44
- Object.defineProperty(exports, "__esModule", { value: true });
45
- exports.ActivityPushChannel = void 0;
46
- const http2 = __importStar(require("node:http2"));
47
- const fs = __importStar(require("node:fs"));
48
- const crypto = __importStar(require("node:crypto"));
49
- class ActivityPushChannel {
50
- /** sessionId -> activityPushToken */
51
- tokens = new Map();
52
- teamId;
53
- keyId;
54
- authKey;
55
- apnsHost;
56
- /** 缓存的 JWT token + 过期时间 */
57
- cachedJwt = null;
58
- /** 复用的 HTTP/2 长连接 */
59
- http2Client = null;
60
- constructor(config) {
61
- this.teamId = config.teamId;
62
- this.keyId = config.keyId;
63
- this.authKey = fs.readFileSync(config.authKeyPath, 'utf-8');
64
- this.apnsHost = config.sandbox
65
- ? 'api.sandbox.push.apple.com'
66
- : 'api.push.apple.com';
67
- console.log(`[ActivityPushChannel] 已初始化 (${config.sandbox ? '沙箱' : '生产'}模式)`);
68
- }
69
- /** 获取或新建 HTTP/2 长连接 */
70
- getHttp2Client() {
71
- if (this.http2Client && !this.http2Client.destroyed && !this.http2Client.closed) {
72
- return this.http2Client;
73
- }
74
- this.http2Client = http2.connect(`https://${this.apnsHost}`);
75
- this.http2Client.on('error', (err) => {
76
- console.warn('[ActivityPushChannel] HTTP/2 连接错误,将在下次请求时重建:', err.message);
77
- this.http2Client?.destroy();
78
- this.http2Client = null;
79
- });
80
- this.http2Client.on('close', () => {
81
- this.http2Client = null;
82
- });
83
- return this.http2Client;
84
- }
85
- /** 注册 Activity push token */
86
- addToken(sessionId, token) {
87
- this.tokens.set(sessionId, token);
88
- console.log(`[ActivityPushChannel] 已注册 token: session=${sessionId}`);
89
- }
90
- /** 移除 Activity push token */
91
- removeToken(sessionId) {
92
- this.tokens.delete(sessionId);
93
- }
94
- /** 发送 content-state 更新到指定会话的 Live Activity */
95
- async updateActivity(sessionId, contentState) {
96
- const token = this.tokens.get(sessionId);
97
- if (!token)
98
- return;
99
- const payload = {
100
- aps: {
101
- timestamp: Math.floor(Date.now() / 1000),
102
- event: 'update',
103
- 'content-state': contentState,
104
- },
105
- };
106
- try {
107
- await this.sendToAPNs(token, payload);
108
- }
109
- catch (err) {
110
- console.warn(`[ActivityPushChannel] 更新失败 session=${sessionId}:`, err);
111
- }
112
- }
113
- /** 发送带通知的 content-state 更新(审批请求时使用) */
114
- async updateActivityWithAlert(sessionId, contentState, alert) {
115
- const token = this.tokens.get(sessionId);
116
- if (!token)
117
- return;
118
- const payload = {
119
- aps: {
120
- timestamp: Math.floor(Date.now() / 1000),
121
- event: 'update',
122
- 'content-state': contentState,
123
- alert,
124
- sound: 'default',
125
- },
126
- };
127
- try {
128
- await this.sendToAPNs(token, payload);
129
- }
130
- catch (err) {
131
- console.warn(`[ActivityPushChannel] 带提醒更新失败 session=${sessionId}:`, err);
132
- }
133
- }
134
- /** 结束指定会话的 Live Activity */
135
- async endActivity(sessionId, contentState) {
136
- const token = this.tokens.get(sessionId);
137
- if (!token)
138
- return;
139
- const payload = {
140
- aps: {
141
- timestamp: Math.floor(Date.now() / 1000),
142
- event: 'end',
143
- 'content-state': contentState,
144
- },
145
- };
146
- try {
147
- await this.sendToAPNs(token, payload);
148
- }
149
- catch (err) {
150
- console.warn(`[ActivityPushChannel] 结束失败 session=${sessionId}:`, err);
151
- }
152
- this.tokens.delete(sessionId);
153
- }
154
- /** 检查是否有指定会话的 token */
155
- hasToken(sessionId) {
156
- return this.tokens.has(sessionId);
157
- }
158
- /** 发送 APNs HTTP/2 请求 */
159
- async sendToAPNs(deviceToken, payload) {
160
- const topic = 'com.kachun.sessix.push-type.liveactivity';
161
- const jwt = this.getJWT();
162
- const payloadStr = JSON.stringify(payload);
163
- return new Promise((resolve, reject) => {
164
- let client;
165
- try {
166
- client = this.getHttp2Client();
167
- }
168
- catch (err) {
169
- return reject(err);
170
- }
171
- const req = client.request({
172
- ':method': 'POST',
173
- ':path': `/3/device/${deviceToken}`,
174
- 'authorization': `bearer ${jwt}`,
175
- 'apns-topic': topic,
176
- 'apns-push-type': 'liveactivity',
177
- 'apns-priority': '10',
178
- 'apns-expiration': String(Math.floor(Date.now() / 1000) + 30),
179
- 'content-type': 'application/json',
180
- 'content-length': Buffer.byteLength(payloadStr),
181
- });
182
- let statusCode = 0;
183
- let responseData = '';
184
- req.on('response', (headers) => {
185
- statusCode = Number(headers[':status'] ?? 0);
186
- });
187
- req.on('data', (chunk) => {
188
- responseData += chunk;
189
- });
190
- req.on('end', () => {
191
- if (statusCode === 200) {
192
- resolve();
193
- }
194
- else {
195
- // 连接可能已损坏,重置以便下次重建
196
- if (statusCode === 0) {
197
- this.http2Client?.destroy();
198
- this.http2Client = null;
199
- }
200
- reject(new Error(`APNs 返回 ${statusCode}: ${responseData}`));
201
- }
202
- });
203
- req.on('error', (err) => {
204
- reject(err);
205
- });
206
- req.write(payloadStr);
207
- req.end();
208
- });
209
- }
210
- /** 生成或获取缓存的 APNs JWT token */
211
- getJWT() {
212
- const now = Math.floor(Date.now() / 1000);
213
- // JWT 有效期 50 分钟(Apple 限制 60 分钟)
214
- if (this.cachedJwt && this.cachedJwt.expiresAt > now) {
215
- return this.cachedJwt.token;
216
- }
217
- const header = Buffer.from(JSON.stringify({
218
- alg: 'ES256',
219
- kid: this.keyId,
220
- })).toString('base64url');
221
- const claims = Buffer.from(JSON.stringify({
222
- iss: this.teamId,
223
- iat: now,
224
- })).toString('base64url');
225
- const signingInput = `${header}.${claims}`;
226
- const sign = crypto.createSign('SHA256');
227
- sign.update(signingInput);
228
- const signature = sign.sign(this.authKey, 'base64url');
229
- const token = `${signingInput}.${signature}`;
230
- this.cachedJwt = { token, expiresAt: now + 3000 }; // 50 分钟
231
- return token;
232
- }
233
- }
234
- exports.ActivityPushChannel = ActivityPushChannel;
235
- //# sourceMappingURL=ActivityPushChannel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ActivityPushChannel.js","sourceRoot":"","sources":["../../src/notification/ActivityPushChannel.ts"],"names":[],"mappings":"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"}