sessix-server 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.
Files changed (61) hide show
  1. package/dist/approval/ApprovalProxy.d.ts +86 -0
  2. package/dist/approval/ApprovalProxy.d.ts.map +1 -0
  3. package/dist/approval/ApprovalProxy.js +363 -0
  4. package/dist/approval/ApprovalProxy.js.map +1 -0
  5. package/dist/hooks/HookInstaller.d.ts +55 -0
  6. package/dist/hooks/HookInstaller.d.ts.map +1 -0
  7. package/dist/hooks/HookInstaller.js +215 -0
  8. package/dist/hooks/HookInstaller.js.map +1 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +3115 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/mdns/MdnsService.d.ts +36 -0
  14. package/dist/mdns/MdnsService.d.ts.map +1 -0
  15. package/dist/mdns/MdnsService.js +66 -0
  16. package/dist/mdns/MdnsService.js.map +1 -0
  17. package/dist/notification/ActivityPushChannel.d.ts +54 -0
  18. package/dist/notification/ActivityPushChannel.d.ts.map +1 -0
  19. package/dist/notification/ActivityPushChannel.js +235 -0
  20. package/dist/notification/ActivityPushChannel.js.map +1 -0
  21. package/dist/notification/ExpoNotificationChannel.d.ts +17 -0
  22. package/dist/notification/ExpoNotificationChannel.d.ts.map +1 -0
  23. package/dist/notification/ExpoNotificationChannel.js +57 -0
  24. package/dist/notification/ExpoNotificationChannel.js.map +1 -0
  25. package/dist/notification/MacNotificationChannel.d.ts +22 -0
  26. package/dist/notification/MacNotificationChannel.d.ts.map +1 -0
  27. package/dist/notification/MacNotificationChannel.js +33 -0
  28. package/dist/notification/MacNotificationChannel.js.map +1 -0
  29. package/dist/notification/NotificationService.d.ts +50 -0
  30. package/dist/notification/NotificationService.d.ts.map +1 -0
  31. package/dist/notification/NotificationService.js +177 -0
  32. package/dist/notification/NotificationService.js.map +1 -0
  33. package/dist/providers/ExecutionProvider.d.ts +60 -0
  34. package/dist/providers/ExecutionProvider.d.ts.map +1 -0
  35. package/dist/providers/ExecutionProvider.js +3 -0
  36. package/dist/providers/ExecutionProvider.js.map +1 -0
  37. package/dist/providers/ProcessProvider.d.ts +117 -0
  38. package/dist/providers/ProcessProvider.d.ts.map +1 -0
  39. package/dist/providers/ProcessProvider.js +507 -0
  40. package/dist/providers/ProcessProvider.js.map +1 -0
  41. package/dist/server.d.ts +32 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +3054 -0
  44. package/dist/server.js.map +1 -0
  45. package/dist/session/ProjectReader.d.ts +44 -0
  46. package/dist/session/ProjectReader.d.ts.map +1 -0
  47. package/dist/session/ProjectReader.js +471 -0
  48. package/dist/session/ProjectReader.js.map +1 -0
  49. package/dist/session/SessionFileWatcher.d.ts +35 -0
  50. package/dist/session/SessionFileWatcher.d.ts.map +1 -0
  51. package/dist/session/SessionFileWatcher.js +207 -0
  52. package/dist/session/SessionFileWatcher.js.map +1 -0
  53. package/dist/session/SessionManager.d.ts +114 -0
  54. package/dist/session/SessionManager.d.ts.map +1 -0
  55. package/dist/session/SessionManager.js +356 -0
  56. package/dist/session/SessionManager.js.map +1 -0
  57. package/dist/ws/WsBridge.d.ts +55 -0
  58. package/dist/ws/WsBridge.d.ts.map +1 -0
  59. package/dist/ws/WsBridge.js +220 -0
  60. package/dist/ws/WsBridge.js.map +1 -0
  61. package/package.json +38 -0
@@ -0,0 +1,215 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HookInstaller.js","sourceRoot":"","sources":["../../src/hooks/HookInstaller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}