@barryfan2045/dsh-matrix 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 (206) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +286 -0
  3. package/THIRD_PARTY_NOTICES.md +53 -0
  4. package/assets/avatars/instance-01.png +0 -0
  5. package/assets/avatars/instance-02.png +0 -0
  6. package/assets/avatars/instance-03.png +0 -0
  7. package/assets/avatars/instance-04.png +0 -0
  8. package/assets/avatars/instance-05.png +0 -0
  9. package/assets/avatars/instance-06.png +0 -0
  10. package/assets/avatars/instance-07.png +0 -0
  11. package/assets/avatars/instance-08.png +0 -0
  12. package/assets/avatars/instance-09.png +0 -0
  13. package/assets/avatars/instance-10.png +0 -0
  14. package/assets/avatars/instance-11.png +0 -0
  15. package/assets/avatars/instance-12.png +0 -0
  16. package/assets/avatars/management.png +0 -0
  17. package/cordis.patch.yml +13 -0
  18. package/dist/auth/admin-commands.d.ts +47 -0
  19. package/dist/auth/admin-commands.d.ts.map +1 -0
  20. package/dist/auth/admin-commands.js +112 -0
  21. package/dist/auth/admin-commands.js.map +1 -0
  22. package/dist/auth/challenge.d.ts +93 -0
  23. package/dist/auth/challenge.d.ts.map +1 -0
  24. package/dist/auth/challenge.js +104 -0
  25. package/dist/auth/challenge.js.map +1 -0
  26. package/dist/auth/store.d.ts +55 -0
  27. package/dist/auth/store.d.ts.map +1 -0
  28. package/dist/auth/store.js +124 -0
  29. package/dist/auth/store.js.map +1 -0
  30. package/dist/bridge/agent-commands.d.ts +39 -0
  31. package/dist/bridge/agent-commands.d.ts.map +1 -0
  32. package/dist/bridge/agent-commands.js +243 -0
  33. package/dist/bridge/agent-commands.js.map +1 -0
  34. package/dist/bridge/attachments-ledger.d.ts +54 -0
  35. package/dist/bridge/attachments-ledger.d.ts.map +1 -0
  36. package/dist/bridge/attachments-ledger.js +68 -0
  37. package/dist/bridge/attachments-ledger.js.map +1 -0
  38. package/dist/bridge/commands.d.ts +28 -0
  39. package/dist/bridge/commands.d.ts.map +1 -0
  40. package/dist/bridge/commands.js +18 -0
  41. package/dist/bridge/commands.js.map +1 -0
  42. package/dist/bridge/crypto-health.d.ts +37 -0
  43. package/dist/bridge/crypto-health.d.ts.map +1 -0
  44. package/dist/bridge/crypto-health.js +38 -0
  45. package/dist/bridge/crypto-health.js.map +1 -0
  46. package/dist/bridge/group-gate.d.ts +38 -0
  47. package/dist/bridge/group-gate.d.ts.map +1 -0
  48. package/dist/bridge/group-gate.js +49 -0
  49. package/dist/bridge/group-gate.js.map +1 -0
  50. package/dist/bridge/instance-lock.d.ts +10 -0
  51. package/dist/bridge/instance-lock.d.ts.map +1 -0
  52. package/dist/bridge/instance-lock.js +82 -0
  53. package/dist/bridge/instance-lock.js.map +1 -0
  54. package/dist/bridge/interactions.d.ts +62 -0
  55. package/dist/bridge/interactions.d.ts.map +1 -0
  56. package/dist/bridge/interactions.js +237 -0
  57. package/dist/bridge/interactions.js.map +1 -0
  58. package/dist/bridge/management-room.d.ts +13 -0
  59. package/dist/bridge/management-room.d.ts.map +1 -0
  60. package/dist/bridge/management-room.js +27 -0
  61. package/dist/bridge/management-room.js.map +1 -0
  62. package/dist/bridge/multi-project.d.ts +34 -0
  63. package/dist/bridge/multi-project.d.ts.map +1 -0
  64. package/dist/bridge/multi-project.js +44 -0
  65. package/dist/bridge/multi-project.js.map +1 -0
  66. package/dist/bridge/pipeline.d.ts +151 -0
  67. package/dist/bridge/pipeline.d.ts.map +1 -0
  68. package/dist/bridge/pipeline.js +502 -0
  69. package/dist/bridge/pipeline.js.map +1 -0
  70. package/dist/bridge/pmctl.d.ts +50 -0
  71. package/dist/bridge/pmctl.d.ts.map +1 -0
  72. package/dist/bridge/pmctl.js +272 -0
  73. package/dist/bridge/pmctl.js.map +1 -0
  74. package/dist/bridge/power-levels.d.ts +57 -0
  75. package/dist/bridge/power-levels.d.ts.map +1 -0
  76. package/dist/bridge/power-levels.js +92 -0
  77. package/dist/bridge/power-levels.js.map +1 -0
  78. package/dist/bridge/power-sync.d.ts +64 -0
  79. package/dist/bridge/power-sync.d.ts.map +1 -0
  80. package/dist/bridge/power-sync.js +121 -0
  81. package/dist/bridge/power-sync.js.map +1 -0
  82. package/dist/bridge/projects.d.ts +97 -0
  83. package/dist/bridge/projects.d.ts.map +1 -0
  84. package/dist/bridge/projects.js +288 -0
  85. package/dist/bridge/projects.js.map +1 -0
  86. package/dist/bridge/quote-cache.d.ts +38 -0
  87. package/dist/bridge/quote-cache.d.ts.map +1 -0
  88. package/dist/bridge/quote-cache.js +56 -0
  89. package/dist/bridge/quote-cache.js.map +1 -0
  90. package/dist/bridge/reply.d.ts +31 -0
  91. package/dist/bridge/reply.d.ts.map +1 -0
  92. package/dist/bridge/reply.js +122 -0
  93. package/dist/bridge/reply.js.map +1 -0
  94. package/dist/bridge/space-identity.d.ts +43 -0
  95. package/dist/bridge/space-identity.d.ts.map +1 -0
  96. package/dist/bridge/space-identity.js +92 -0
  97. package/dist/bridge/space-identity.js.map +1 -0
  98. package/dist/bridge/space-sync.d.ts +94 -0
  99. package/dist/bridge/space-sync.d.ts.map +1 -0
  100. package/dist/bridge/space-sync.js +137 -0
  101. package/dist/bridge/space-sync.js.map +1 -0
  102. package/dist/bridge/turn-commands.d.ts +28 -0
  103. package/dist/bridge/turn-commands.d.ts.map +1 -0
  104. package/dist/bridge/turn-commands.js +97 -0
  105. package/dist/bridge/turn-commands.js.map +1 -0
  106. package/dist/cli/config-store.d.ts +32 -0
  107. package/dist/cli/config-store.d.ts.map +1 -0
  108. package/dist/cli/config-store.js +118 -0
  109. package/dist/cli/config-store.js.map +1 -0
  110. package/dist/cli/crypto-store.d.ts +42 -0
  111. package/dist/cli/crypto-store.d.ts.map +1 -0
  112. package/dist/cli/crypto-store.js +70 -0
  113. package/dist/cli/crypto-store.js.map +1 -0
  114. package/dist/cli/device-prune.d.ts +105 -0
  115. package/dist/cli/device-prune.d.ts.map +1 -0
  116. package/dist/cli/device-prune.js +163 -0
  117. package/dist/cli/device-prune.js.map +1 -0
  118. package/dist/cli/index.d.ts +4 -0
  119. package/dist/cli/index.d.ts.map +1 -0
  120. package/dist/cli/index.js +584 -0
  121. package/dist/cli/index.js.map +1 -0
  122. package/dist/cli/log-filter.d.ts +32 -0
  123. package/dist/cli/log-filter.d.ts.map +1 -0
  124. package/dist/cli/log-filter.js +40 -0
  125. package/dist/cli/log-filter.js.map +1 -0
  126. package/dist/cli/pnpm-builds.d.ts +32 -0
  127. package/dist/cli/pnpm-builds.d.ts.map +1 -0
  128. package/dist/cli/pnpm-builds.js +73 -0
  129. package/dist/cli/pnpm-builds.js.map +1 -0
  130. package/dist/cli/profile-patch.d.ts +26 -0
  131. package/dist/cli/profile-patch.d.ts.map +1 -0
  132. package/dist/cli/profile-patch.js +56 -0
  133. package/dist/cli/profile-patch.js.map +1 -0
  134. package/dist/cli/setup.d.ts +39 -0
  135. package/dist/cli/setup.d.ts.map +1 -0
  136. package/dist/cli/setup.js +234 -0
  137. package/dist/cli/setup.js.map +1 -0
  138. package/dist/cli/systemd-hint.d.ts +11 -0
  139. package/dist/cli/systemd-hint.d.ts.map +1 -0
  140. package/dist/cli/systemd-hint.js +46 -0
  141. package/dist/cli/systemd-hint.js.map +1 -0
  142. package/dist/cli/systemd.d.ts +32 -0
  143. package/dist/cli/systemd.d.ts.map +1 -0
  144. package/dist/cli/systemd.js +58 -0
  145. package/dist/cli/systemd.js.map +1 -0
  146. package/dist/config.d.ts +54 -0
  147. package/dist/config.d.ts.map +1 -0
  148. package/dist/config.js +107 -0
  149. package/dist/config.js.map +1 -0
  150. package/dist/dsh/backend.d.ts +110 -0
  151. package/dist/dsh/backend.d.ts.map +1 -0
  152. package/dist/dsh/backend.js +481 -0
  153. package/dist/dsh/backend.js.map +1 -0
  154. package/dist/dsh/interactions.d.ts +50 -0
  155. package/dist/dsh/interactions.d.ts.map +1 -0
  156. package/dist/dsh/interactions.js +141 -0
  157. package/dist/dsh/interactions.js.map +1 -0
  158. package/dist/dsh/stream.d.ts +32 -0
  159. package/dist/dsh/stream.d.ts.map +1 -0
  160. package/dist/dsh/stream.js +109 -0
  161. package/dist/dsh/stream.js.map +1 -0
  162. package/dist/formatting.d.ts +14 -0
  163. package/dist/formatting.d.ts.map +1 -0
  164. package/dist/formatting.js +63 -0
  165. package/dist/formatting.js.map +1 -0
  166. package/dist/index.d.ts +8 -0
  167. package/dist/index.d.ts.map +1 -0
  168. package/dist/index.js +232 -0
  169. package/dist/index.js.map +1 -0
  170. package/dist/logger.d.ts +9 -0
  171. package/dist/logger.d.ts.map +1 -0
  172. package/dist/logger.js +28 -0
  173. package/dist/logger.js.map +1 -0
  174. package/dist/matrix/matrix-events.d.ts +49 -0
  175. package/dist/matrix/matrix-events.d.ts.map +1 -0
  176. package/dist/matrix/matrix-events.js +89 -0
  177. package/dist/matrix/matrix-events.js.map +1 -0
  178. package/dist/matrix/transport.d.ts +192 -0
  179. package/dist/matrix/transport.d.ts.map +1 -0
  180. package/dist/matrix/transport.js +510 -0
  181. package/dist/matrix/transport.js.map +1 -0
  182. package/dist/ports/attachments.d.ts +51 -0
  183. package/dist/ports/attachments.d.ts.map +1 -0
  184. package/dist/ports/attachments.js +27 -0
  185. package/dist/ports/attachments.js.map +1 -0
  186. package/dist/ports/backend.d.ts +159 -0
  187. package/dist/ports/backend.d.ts.map +1 -0
  188. package/dist/ports/backend.js +25 -0
  189. package/dist/ports/backend.js.map +1 -0
  190. package/dist/ports/interactions.d.ts +65 -0
  191. package/dist/ports/interactions.d.ts.map +1 -0
  192. package/dist/ports/interactions.js +15 -0
  193. package/dist/ports/interactions.js.map +1 -0
  194. package/dist/ports/streaming.d.ts +45 -0
  195. package/dist/ports/streaming.d.ts.map +1 -0
  196. package/dist/ports/streaming.js +23 -0
  197. package/dist/ports/streaming.js.map +1 -0
  198. package/dist/ports/transport.d.ts +68 -0
  199. package/dist/ports/transport.d.ts.map +1 -0
  200. package/dist/ports/transport.js +2 -0
  201. package/dist/ports/transport.js.map +1 -0
  202. package/dist/types.d.ts +53 -0
  203. package/dist/types.d.ts.map +1 -0
  204. package/dist/types.js +2 -0
  205. package/dist/types.js.map +1 -0
  206. package/package.json +80 -0
@@ -0,0 +1,584 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dsh-matrix 运维 CLI — 一条命令管全生命周期。
4
+ *
5
+ * dsh-matrix setup 配置向导(交互或 --yes 非交互),写 ~/.dsh/dsh-matrix.json(0600)
6
+ * dsh-matrix install-profile 真正执行: 放行加密原生库构建 + dsh plugin --profile <p> add <本包> + 幂等生成 profile patch
7
+ * dsh-matrix enable 安装 systemd user unit(dsh-matrix.service)并开机自启、立即启动
8
+ * dsh-matrix start|stop|restart|disable 服务生命周期
9
+ * dsh-matrix status|logs journalctl 查看状态/跟踪日志([--level debug|info|warn|error])
10
+ * dsh-matrix run 前台运行(等价 dsh --profile <实例名>)
11
+ * dsh-matrix reset-crypto E2EE 静默失效时复位 crypto 存储([--purge] 直接删 / [--dir <路径>] 自定义位置)
12
+ * dsh-matrix prune-devices 清理账号上的孤儿设备(默认只列出,--yes 才真删)
13
+ * dsh-matrix -v | help
14
+ *
15
+ * 命令树手写 arg 解析(仿 pi-courier src/cli.ts),零新依赖。
16
+ * 单实例锁不在本 CLI(属桥运行时)。
17
+ */
18
+ import { spawnSync } from 'node:child_process';
19
+ import * as fs from 'node:fs';
20
+ import * as os from 'node:os';
21
+ import * as path from 'node:path';
22
+ import { fileURLToPath } from 'node:url';
23
+ import { dshHome, loadOpsConfig } from "./config-store.js";
24
+ import { buildLogFilterArgs } from "./log-filter.js";
25
+ import { planProfilePatch } from "./profile-patch.js";
26
+ import { planPnpmBuildAllowance } from "./pnpm-builds.js";
27
+ import { buildUserUnit, homeserverProxyHost } from "./systemd.js";
28
+ import { busFailureHint, dirOwnerUid } from "./systemd-hint.js";
29
+ import { runSetup } from "./setup.js";
30
+ import { applyCryptoReset, cryptoStoreDir, planCryptoReset, readCryptoStoreDeviceId } from "./crypto-store.js";
31
+ import { chooseLoginIdentity, createMatrixAdminOps, formatLastSeen, loginForToken, planDevicePrune } from "./device-prune.js";
32
+ const SERVICE_NAME = 'dsh-matrix';
33
+ const SERVICE_UNIT = `${SERVICE_NAME}.service`;
34
+ // ---------------------------------------------------------------------------
35
+ // 路径与外部命令小工具
36
+ // ---------------------------------------------------------------------------
37
+ /** 本包根目录(dist/cli/ 的上两级;npm 安装态同样成立)。 */
38
+ function projectDir() {
39
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
40
+ }
41
+ function packageVersion() {
42
+ try {
43
+ const pkg = JSON.parse(fs.readFileSync(path.join(projectDir(), 'package.json'), 'utf-8'));
44
+ return pkg.version ?? 'unknown';
45
+ }
46
+ catch {
47
+ return 'unknown';
48
+ }
49
+ }
50
+ /** 找 dsh 启动器绝对路径:先同目录 bin(node <path> 可直接执行),再 PATH。 */
51
+ export function resolveDshBin(execPath = process.execPath) {
52
+ const candidate = path.join(path.dirname(execPath), 'dsh');
53
+ if (fs.existsSync(candidate))
54
+ return fs.realpathSync(candidate);
55
+ const which = spawnSync('which', ['dsh'], { encoding: 'utf-8' });
56
+ const found = which.status === 0 ? which.stdout.trim() : '';
57
+ if (found && fs.existsSync(found)) {
58
+ try {
59
+ return fs.realpathSync(found);
60
+ }
61
+ catch {
62
+ return found;
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ function userUnitPath() {
68
+ return path.join(os.homedir(), '.config', 'systemd', 'user', SERVICE_UNIT);
69
+ }
70
+ /** spawn `systemctl --user ...`,stderr 回显并留给 su-trap 提示判断。 */
71
+ function spawnSystemctlUser(args, quiet = false) {
72
+ const res = spawnSync('systemctl', ['--user', ...args], { stdio: ['inherit', 'inherit', 'pipe'] });
73
+ const stderr = res.stderr?.toString() ?? '';
74
+ // quiet:调用方预期到"没装 unit"之类的常态失败(自救路径),别把 systemd 的原文漏出去
75
+ if (stderr && !quiet)
76
+ process.stderr.write(stderr);
77
+ return { status: res.status ?? 1, stderr };
78
+ }
79
+ function systemctlUser(args) {
80
+ const { status, stderr } = spawnSystemctlUser(args);
81
+ if (status !== 0) {
82
+ console.error(`❌ systemctl --user ${args.join(' ')} 失败(退出码 ${status})`);
83
+ const hint = busFailureHint({
84
+ euid: typeof process.getuid === 'function' ? process.getuid() : -1,
85
+ xdgRuntimeDir: process.env.XDG_RUNTIME_DIR,
86
+ xdgOwnerUid: dirOwnerUid(process.env.XDG_RUNTIME_DIR),
87
+ stderr,
88
+ });
89
+ if (hint)
90
+ console.error(hint);
91
+ }
92
+ return status;
93
+ }
94
+ function requireConfig() {
95
+ const cfg = loadOpsConfig();
96
+ if (!cfg) {
97
+ console.error(`❌ 未找到运维配置。先运行: dsh-matrix setup`);
98
+ process.exit(1);
99
+ }
100
+ return cfg;
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // 手写 arg 解析(仿 pi-courier:cmd + rest,子命令内部自解析)
104
+ // ---------------------------------------------------------------------------
105
+ const SETUP_VALUE_FLAGS = ['--homeserver', '--username', '--password', '--token', '--trusted', '--workdir', '--profile', '--log-level'];
106
+ function parseSetupFlags(args) {
107
+ const flags = {};
108
+ for (let i = 0; i < args.length; i++) {
109
+ const a = args[i];
110
+ if (a === '--yes') {
111
+ flags.yes = true;
112
+ continue;
113
+ }
114
+ const key = SETUP_VALUE_FLAGS.includes(a ?? '') ? a : undefined;
115
+ if (!key)
116
+ return { error: `未知参数: ${a}` };
117
+ const value = args[++i];
118
+ if (value === undefined)
119
+ return { error: `${key} 缺少取值` };
120
+ switch (key) {
121
+ case '--homeserver':
122
+ flags.homeserver = value;
123
+ break;
124
+ case '--username':
125
+ flags.username = value;
126
+ break;
127
+ case '--password':
128
+ flags.password = value;
129
+ break;
130
+ case '--token':
131
+ flags.token = value;
132
+ break;
133
+ case '--trusted':
134
+ flags.trusted = value;
135
+ break;
136
+ case '--workdir':
137
+ flags.workdir = value;
138
+ break;
139
+ case '--profile':
140
+ flags.profile = value;
141
+ break;
142
+ case '--log-level':
143
+ flags.logLevel = value;
144
+ break;
145
+ }
146
+ }
147
+ return flags;
148
+ }
149
+ /** 从 status/logs 参数里拆 `--level <lvl>`,其余为位置参数。 */
150
+ function splitLevel(args) {
151
+ let level = 'info';
152
+ const positional = [];
153
+ for (let i = 0; i < args.length; i++) {
154
+ if (args[i] === '--level')
155
+ level = args[++i] ?? '';
156
+ else
157
+ positional.push(args[i]);
158
+ }
159
+ return { level, positional };
160
+ }
161
+ // ---------------------------------------------------------------------------
162
+ // 子命令
163
+ // ---------------------------------------------------------------------------
164
+ async function cmdSetup(args) {
165
+ const flags = parseSetupFlags(args);
166
+ if ('error' in flags) {
167
+ console.error(`❌ ${flags.error}`);
168
+ process.exit(1);
169
+ }
170
+ process.exitCode = await runSetup(flags);
171
+ }
172
+ /**
173
+ * T13:复位 crypto 存储(自救入口)。
174
+ *
175
+ * 先把服务停下(存储不能在被占用时动),再按计划备份/删除,最后把代价讲清楚:
176
+ * 换存储 = 换设备身份,对方会看到一个新设备、需要重新验证,历史加密消息也解不开。
177
+ */
178
+ function cmdResetCrypto() {
179
+ // 刻意**不** requireConfig:这是出事后的自救入口,配置本身可能已经不在或坏掉,
180
+ // 而复位只需要知道家目录(crypto 路径与配置无关)。
181
+ const argv = process.argv.slice(2);
182
+ const purge = argv.includes('--purge');
183
+ // dataDir 是**桥侧**配置(profile patch 里的 matrix-bridge.config.dataDir),CLI 看不到,
184
+ // 所以默认按标准位置算;真自定义过就用 --dir 指过来。
185
+ const dirFlag = argv.indexOf('--dir');
186
+ const dir = dirFlag !== -1 && argv[dirFlag + 1]
187
+ ? argv[dirFlag + 1]
188
+ : cryptoStoreDir({ dshHome: dshHome() });
189
+ // 服务在跑就先停:存储被占用时改名/删除会把运行中的进程搞坏。
190
+ // 刻意用**静默**的 spawn:没装 unit(退出码 5)是常态,不该因此打一行刺眼的 ❌。
191
+ const stop = spawnSystemctlUser(['stop', SERVICE_NAME], true);
192
+ console.log(stop.status === 0 ? '⏸️ 已停止 dsh-matrix 服务' : 'ℹ️ 服务未在运行(或未安装),继续');
193
+ const plan = planCryptoReset({ dir, purge, stamp: new Date().toISOString().replace(/[:.]/g, '-') });
194
+ if (plan.action === 'absent') {
195
+ console.log(`ℹ️ ${plan.dir}: ${plan.reason}`);
196
+ return;
197
+ }
198
+ applyCryptoReset(plan);
199
+ console.log(`🔐 ${plan.dir}: ${plan.reason}`);
200
+ if (plan.target)
201
+ console.log(` 旧存储备份在: ${plan.target}`);
202
+ console.log('');
203
+ console.log('⚠️ 代价(请确认能接受):');
204
+ console.log(' • 换存储 = 换设备身份:Element 等客户端会看到一个新设备,需要重新验证;');
205
+ console.log(' • 旧的历史加密消息解不开(密钥在旧存储里)。');
206
+ console.log(' 恢复服务: dsh-matrix enable (或 start)');
207
+ }
208
+ /**
209
+ * T14 后续:清理账号上的**孤儿设备**(默认只是列出,--yes / 交互确认才真删)。
210
+ *
211
+ * 为什么要它:桥以前每次密码登录都不带 device_id,Synapse 每次都新建一个设备
212
+ * (T14 已修),账号上于是攒下一堆私钥早已作废的孤儿 —— 它们仍参与每次加密发送的
213
+ * 设备列表,把首次 sendMessage 拖到分钟级。删设备**不可逆**,所以这里:
214
+ * 默认只列出、当前桥设备永远保留、并且**复用桥的设备身份登录**(否则这个清理命令
215
+ * 自己又会造一个新设备)。
216
+ */
217
+ async function cmdPruneDevices(args) {
218
+ const yes = args.includes('--yes');
219
+ const keepFlag = args.indexOf('--keep-days');
220
+ const keepDays = keepFlag === -1 ? 0 : Number(args[keepFlag + 1]);
221
+ if (!Number.isFinite(keepDays) || keepDays < 0) {
222
+ console.error('❌ --keep-days 需要一个 >= 0 的数字');
223
+ process.exitCode = 1;
224
+ return;
225
+ }
226
+ const cfg = requireConfig();
227
+ // 桥侧 dataDir 可能被自定义过(profile patch 里的 dataDir),CLI 看不到,所以给个显式入口。
228
+ const dataDirFlag = args.indexOf('--data-dir');
229
+ const dataDir = dataDirFlag !== -1 ? args[dataDirFlag + 1] : undefined;
230
+ const cryptoDir = cryptoStoreDir({ dshHome: dshHome(), ...(dataDir ? { dataDir } : {}) });
231
+ // 拿一个 token。**本命令绝不新建设备**(见 chooseLoginIdentity):优先用 accessToken,
232
+ // 否则按桥的**存储设备身份**登录 —— 一个清理孤儿设备的工具自己再造一个设备就荒唐了。
233
+ const stored = cfg.accessToken ? undefined : readCryptoStoreDeviceId(cryptoDir);
234
+ const choice = chooseLoginIdentity({
235
+ ...(cfg.accessToken ? { accessToken: cfg.accessToken } : {}),
236
+ ...(cfg.username ? { username: cfg.username } : {}),
237
+ ...(cfg.password ? { password: cfg.password } : {}),
238
+ ...(stored ? { storedDeviceId: stored } : {}),
239
+ cryptoDir,
240
+ });
241
+ if (choice.mode === 'unavailable') {
242
+ console.error(`❌ ${choice.message}`);
243
+ process.exitCode = 1;
244
+ return;
245
+ }
246
+ let accessToken;
247
+ let userId;
248
+ let keepDevice;
249
+ if (choice.mode === 'token') {
250
+ accessToken = cfg.accessToken;
251
+ const who = await createMatrixAdminOps({ homeserver: cfg.homeserver, accessToken, userId: '' }).whoAmI();
252
+ userId = who.user_id;
253
+ keepDevice = who.device_id ?? '';
254
+ }
255
+ else {
256
+ const login = await loginForToken({
257
+ homeserver: cfg.homeserver,
258
+ username: cfg.username,
259
+ password: cfg.password,
260
+ deviceId: choice.deviceId,
261
+ });
262
+ accessToken = login.accessToken;
263
+ userId = login.userId;
264
+ keepDevice = login.deviceId ?? choice.deviceId;
265
+ console.log(`🔑 已按桥的设备身份登录(复用 ${choice.deviceId},未新建设备)`);
266
+ }
267
+ if (!keepDevice) {
268
+ console.error('❌ 拿不到当前设备身份,无法安全判断该删谁。中止,未删任何设备');
269
+ process.exitCode = 1;
270
+ return;
271
+ }
272
+ const ops = createMatrixAdminOps({
273
+ homeserver: cfg.homeserver,
274
+ accessToken,
275
+ userId,
276
+ ...(cfg.password ? { password: cfg.password } : {}),
277
+ });
278
+ const devices = await ops.listDevices();
279
+ const now = Date.now();
280
+ const plan = planDevicePrune({ devices, keep: keepDevice, now, keepDays });
281
+ const doomed = new Set(plan.remove.map((d) => d.device_id));
282
+ console.log('');
283
+ console.log(`账号 ${userId} 共 ${devices.length} 个设备(保留 ${keepDevice}):`);
284
+ for (const d of devices) {
285
+ const mark = d.device_id === keepDevice ? '🛡️ 保留' : doomed.has(d.device_id) ? '🗑️ 删除' : '⏸️ 保留';
286
+ console.log(` ${mark} ${d.device_id.padEnd(12)} ${formatLastSeen(d.last_seen_ts, now)}`);
287
+ }
288
+ console.log('');
289
+ if (plan.remove.length === 0) {
290
+ console.log('✅ 没有需要清理的孤儿设备。');
291
+ return;
292
+ }
293
+ if (!plan.keepFound) {
294
+ console.warn(`⚠️ 当前设备 ${keepDevice} 不在设备列表里(可能已在别处登出),请核对后再删。`);
295
+ }
296
+ console.log(`计划删除 ${plan.remove.length} 个孤儿设备。`);
297
+ if (!yes) {
298
+ if (process.stdin.isTTY) {
299
+ const agreed = await confirmDelete(`确认删除这 ${plan.remove.length} 个设备?此操作不可逆。输入 yes 继续: `);
300
+ if (!agreed) {
301
+ console.log('已取消,未删除任何设备。');
302
+ return;
303
+ }
304
+ }
305
+ else {
306
+ console.log('这是演练(没有删任何设备)。确认无误后加 --yes 真删:');
307
+ console.log(` dsh-matrix prune-devices --yes${keepDays > 0 ? ` --keep-days ${keepDays}` : ''}`);
308
+ return;
309
+ }
310
+ }
311
+ let removed = 0;
312
+ const failed = [];
313
+ for (const d of plan.remove) {
314
+ try {
315
+ await ops.deleteDevice(d.device_id);
316
+ removed += 1;
317
+ console.log(`🗑️ 已删除 ${d.device_id}`);
318
+ }
319
+ catch (error) {
320
+ failed.push(d.device_id);
321
+ console.error(`❌ ${d.device_id} 删除失败: ${error.message}`);
322
+ }
323
+ }
324
+ console.log('');
325
+ console.log(`完成:删除 ${removed} 个,失败 ${failed.length} 个。`);
326
+ if (failed.length > 0) {
327
+ console.log(' 失败多半是缺密码(删设备要 UI auth):给运维配置补上 password,');
328
+ console.log(' 或去 Element 的「会话 / 设备」列表里手动登出这些设备。');
329
+ process.exitCode = 1;
330
+ }
331
+ }
332
+ /** 交互确认(只在 TTY 下调用);读不到输入一律按"取消"处理,绝不默认删。 */
333
+ async function confirmDelete(prompt) {
334
+ const readline = await import('node:readline/promises');
335
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
336
+ try {
337
+ const answer = await rl.question(prompt);
338
+ return answer.trim().toLowerCase() === 'yes';
339
+ }
340
+ catch {
341
+ return false;
342
+ }
343
+ finally {
344
+ rl.close();
345
+ }
346
+ }
347
+ function cmdInstallProfile() {
348
+ const cfg = requireConfig();
349
+ const dshBin = resolveDshBin();
350
+ if (!dshBin) {
351
+ console.error('❌ 找不到 dsh 启动器(PATH 里应有 `dsh`)。先安装 DSH:npm i -g @deepseek-ai/dsh');
352
+ process.exit(1);
353
+ }
354
+ // 1. 先放行加密原生库的构建脚本:否则首次 `dsh plugin add` 会以
355
+ // ERR_PNPM_IGNORED_BUILDS 中止 —— 依赖虽已写入 package.json,但命令非零
356
+ // 退出,dsh 不再往下走,bundles 没挂上,用户看到的是「装了却没生效」。
357
+ // dsh 只在 profile 缺 package.json 时才 initProfile,所以这里预建的目录
358
+ // 与 pnpm-workspace.yaml 不会被它覆盖。
359
+ const profileDir = path.join(dshHome(), 'profiles', cfg.profile);
360
+ const workspacePath = path.join(profileDir, 'pnpm-workspace.yaml');
361
+ const workspaceExisting = fs.existsSync(workspacePath) ? fs.readFileSync(workspacePath, 'utf-8') : null;
362
+ const workspacePlan = planPnpmBuildAllowance(workspaceExisting);
363
+ if (workspacePlan.action === 'skip') {
364
+ console.log(`⏭️ ${workspacePath}: ${workspacePlan.reason}`);
365
+ }
366
+ else {
367
+ fs.mkdirSync(profileDir, { recursive: true });
368
+ fs.writeFileSync(workspacePath, workspacePlan.text);
369
+ console.log(`🔧 ${workspacePath}: ${workspacePlan.reason}`);
370
+ }
371
+ // 2. bundle 安装(dsh 自己会初始化缺失的 profile 目录;pnpm add 幂等)。
372
+ console.log(`📦 dsh plugin --profile ${cfg.profile} add ${projectDir()}`);
373
+ const add = spawnSync(process.execPath, [dshBin, 'plugin', '--profile', cfg.profile, 'add', projectDir()], { stdio: 'inherit' });
374
+ if ((add.status ?? 1) !== 0) {
375
+ console.error(`❌ dsh plugin add 失败(退出码 ${add.status})`);
376
+ process.exit(add.status ?? 1);
377
+ }
378
+ // 3. profile 用户层 patch:幂等写入 matrix-bridge 覆盖行(目录随 DSH_HOME)。
379
+ const patchPath = path.join(dshHome(), 'profiles', cfg.profile, 'cordis.patch.yml');
380
+ const existing = fs.existsSync(patchPath) ? fs.readFileSync(patchPath, 'utf-8') : null;
381
+ const plan = planProfilePatch(existing, cfg);
382
+ if (plan.action === 'skip') {
383
+ console.log(`⏭️ ${patchPath}: ${plan.reason}`);
384
+ }
385
+ else {
386
+ fs.mkdirSync(path.dirname(patchPath), { recursive: true });
387
+ fs.writeFileSync(patchPath, plan.text, { mode: 0o600 });
388
+ fs.chmodSync(patchPath, 0o600); // 已存在文件 writeFileSync 不改权限,显式收紧(内含密码)
389
+ console.log(`📝 ${patchPath}: ${plan.action === 'create' ? '已生成' : '已追加'} matrix-bridge 覆盖行(0600)`);
390
+ }
391
+ console.log('');
392
+ console.log(`✅ profile "${cfg.profile}" 已就绪。试跑: dsh-matrix run;常驻: dsh-matrix enable`);
393
+ }
394
+ function cmdEnable() {
395
+ const cfg = requireConfig();
396
+ const dshBin = resolveDshBin();
397
+ if (!dshBin) {
398
+ console.error('❌ 找不到 dsh 启动器(PATH 里应有 `dsh`)。');
399
+ process.exit(1);
400
+ }
401
+ const host = homeserverProxyHost(cfg.homeserver);
402
+ if (!host) {
403
+ console.warn(`⚠️ 无法从 homeserver "${cfg.homeserver ?? '(未配置)'}" 提取主机名,unit 将不带 NO_PROXY(坏代理环境可能卡桥)。`);
404
+ }
405
+ const unit = buildUserUnit({
406
+ nodeBin: process.execPath,
407
+ dshBin,
408
+ profile: cfg.profile,
409
+ dshHome: dshHome(),
410
+ ...(host ? { noProxyHost: host } : {}),
411
+ });
412
+ const unitPath = userUnitPath();
413
+ fs.mkdirSync(path.dirname(unitPath), { recursive: true });
414
+ fs.writeFileSync(unitPath, unit);
415
+ console.log(`📝 已写入 ${unitPath}`);
416
+ // daemon-reload 与 enable --now 独立执行、各自报错(照搬 pi-courier issue #60 教训)。
417
+ const failed = [];
418
+ if (systemctlUser(['daemon-reload']) !== 0)
419
+ failed.push('daemon-reload');
420
+ if (systemctlUser(['enable', '--now', SERVICE_NAME]) !== 0)
421
+ failed.push(`enable --now ${SERVICE_NAME}`);
422
+ if (failed.length > 0) {
423
+ console.error(`❌ 服务未能启用(unit 文件已写入,但 systemd 操作失败: ${failed.join(', ')})。`);
424
+ process.exit(1);
425
+ }
426
+ console.log('✅ 服务已启用并启动(登录会话自启)。');
427
+ console.log(` 日志: journalctl --user -u ${SERVICE_NAME} -f 或 dsh-matrix logs`);
428
+ }
429
+ function cmdDisable() {
430
+ const unitPath = userUnitPath();
431
+ if (!fs.existsSync(unitPath)) {
432
+ console.error('❌ 服务未安装(unit 文件不存在)。');
433
+ process.exit(1);
434
+ }
435
+ if (systemctlUser(['disable', '--now', SERVICE_NAME]) !== 0) {
436
+ console.error('ℹ️ unit 文件已保留;修复环境后可重试 `dsh-matrix disable` 或 `dsh-matrix enable`。');
437
+ process.exit(1);
438
+ }
439
+ fs.rmSync(unitPath, { force: true });
440
+ systemctlUser(['daemon-reload']);
441
+ console.log(`✅ 服务已停止并卸载。恢复: dsh-matrix enable(配置不受影响)。`);
442
+ }
443
+ function cmdService(action) {
444
+ if (!fs.existsSync(userUnitPath())) {
445
+ console.error(`❌ 服务未安装。先运行 \`dsh-matrix enable\`。`);
446
+ process.exit(1);
447
+ }
448
+ const code = systemctlUser([action, SERVICE_NAME]);
449
+ if (code !== 0)
450
+ process.exit(code);
451
+ console.log(`✅ ${action} 完成。`);
452
+ }
453
+ function cmdStatusLogs(action, args) {
454
+ if (!fs.existsSync(userUnitPath())) {
455
+ console.error(`❌ 服务未安装。先运行 \`dsh-matrix enable\`。`);
456
+ process.exit(1);
457
+ }
458
+ if (action === 'status') {
459
+ const st = spawnSystemctlUser(['status', SERVICE_NAME]);
460
+ if (st.status !== 0) {
461
+ // 下面的日志窗口是历史,先声明服务现状查询失败,别让用户误判在跑(issue #61 教训)。
462
+ console.error(`⚠️ 服务状态查询失败(退出码 ${st.status})——以下为 journald 历史日志,不代表服务当前在运行。`);
463
+ }
464
+ }
465
+ const { level, positional } = splitLevel(args);
466
+ if (positional.length > 0) {
467
+ console.error('❌ dsh-matrix 为单桥实例,日志不支持项目过滤(多余参数: ' + positional.join(' ') + ')');
468
+ process.exit(1);
469
+ }
470
+ const filter = buildLogFilterArgs({
471
+ unit: SERVICE_NAME,
472
+ level,
473
+ follow: action === 'logs',
474
+ ...(action === 'status' ? { lineCount: 15 } : {}),
475
+ });
476
+ if (!filter.ok) {
477
+ console.error(`❌ ${filter.message}`);
478
+ process.exit(1);
479
+ }
480
+ const journalArgs = action === 'status' ? ['--no-pager', ...filter.args] : filter.args;
481
+ const res = spawnSync('journalctl', journalArgs, { stdio: 'inherit' });
482
+ // logs 为 follow 模式,Ctrl+C 退出码非 0 属正常;status 的退出码有意义。
483
+ if (res.status !== 0 && action === 'status')
484
+ process.exit(res.status ?? 1);
485
+ }
486
+ function cmdRun() {
487
+ const cfg = requireConfig();
488
+ const dshBin = resolveDshBin();
489
+ if (!dshBin) {
490
+ console.error('❌ 找不到 dsh 启动器(PATH 里应有 `dsh`)。');
491
+ process.exit(1);
492
+ }
493
+ const res = spawnSync(process.execPath, [dshBin, '--profile', cfg.profile], { stdio: 'inherit' });
494
+ if (res.error) {
495
+ console.error(`❌ 启动 dsh 失败: ${res.error.message}`);
496
+ process.exit(1);
497
+ }
498
+ process.exit(res.status ?? 1);
499
+ }
500
+ // ---------------------------------------------------------------------------
501
+ // usage + main
502
+ // ---------------------------------------------------------------------------
503
+ function usage() {
504
+ console.log(`dsh-matrix — Matrix 聊天驱动的 DSH 桥运维 CLI
505
+
506
+ 用法:
507
+ dsh-matrix setup [选项] 配置向导(写 ~/.dsh/dsh-matrix.json,0600)
508
+ --yes 非交互模式(需给全下列参数)
509
+ --homeserver <url> Matrix homeserver
510
+ --username <u> --password <p> 登录方式一:账密
511
+ --token <t> 登录方式二:粘贴 access token(与上面二选一)
512
+ --trusted <@u:dom,..> 信任用户 MXID(逗号分隔)
513
+ --workdir <dir> agent 工作目录(默认 ~/dsh-matrix-work)
514
+ --profile <name> 实例名=dsh profile 名(默认 matrix)
515
+ --log-level <lvl> debug|info|warn|error(默认 info)
516
+ dsh-matrix install-profile 挂载 bundle 并幂等生成 profile patch(内含凭据,0600)
517
+ dsh-matrix enable 安装 systemd user unit 并自启+启动
518
+ dsh-matrix start|stop|restart|disable 服务生命周期
519
+ dsh-matrix status [--level <lvl>] 服务状态 + 最近 15 条日志
520
+ dsh-matrix logs [--level <lvl>] 跟踪日志(Ctrl+C 退出)
521
+ dsh-matrix run 前台运行(等价 dsh --profile <实例名>)
522
+ dsh-matrix reset-crypto E2EE 静默失效时复位 crypto 存储(--purge 直接删)
523
+ dsh-matrix prune-devices 清理账号上遗留的孤儿设备(默认只列出,--yes 才真删)
524
+ --yes 确认删除(--keep-days <n> 可顺带保留最近 n 天活动过的)
525
+ --data-dir <dir> 桥的 dataDir(crypto 存储在 <dataDir>/matrix-crypto)
526
+ dsh-matrix -v | help 版本 / 帮助`);
527
+ }
528
+ async function main() {
529
+ const [cmd, ...rest] = process.argv.slice(2);
530
+ switch (cmd) {
531
+ case 'setup':
532
+ await cmdSetup(rest);
533
+ break;
534
+ case 'install-profile':
535
+ cmdInstallProfile();
536
+ break;
537
+ case 'reset-crypto':
538
+ cmdResetCrypto();
539
+ break;
540
+ case 'prune-devices':
541
+ await cmdPruneDevices(rest);
542
+ break;
543
+ case 'enable':
544
+ cmdEnable();
545
+ break;
546
+ case 'disable':
547
+ cmdDisable();
548
+ break;
549
+ case 'start':
550
+ case 'stop':
551
+ case 'restart':
552
+ cmdService(cmd);
553
+ break;
554
+ case 'status':
555
+ case 'logs':
556
+ cmdStatusLogs(cmd, rest);
557
+ break;
558
+ case 'run':
559
+ cmdRun();
560
+ break;
561
+ case 'help':
562
+ case '--help':
563
+ case '-h':
564
+ case undefined:
565
+ usage();
566
+ if (cmd === undefined)
567
+ process.exitCode = 1;
568
+ break;
569
+ case 'version':
570
+ case '--version':
571
+ case '-v':
572
+ console.log(packageVersion());
573
+ break;
574
+ default:
575
+ usage();
576
+ console.error(`\n❌ 未知命令: ${cmd}`);
577
+ process.exitCode = 1;
578
+ }
579
+ }
580
+ main().catch((err) => {
581
+ console.error('[dsh-matrix] fatal:', err.message);
582
+ process.exit(1);
583
+ });
584
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * `dsh-matrix logs/status` 的 journalctl argv 构建(纯函数)。
3
+ *
4
+ * 移植自 pi-courier src/log-filter.ts(spec #34),改语义:
5
+ * dsh-matrix 桥是单实例、日志行没有项目标签(logger 输出格式为
6
+ * `[ISO时间] [LEVEL] 正文`),故去掉 requestedProjects/availableLabels,
7
+ * 只保留 --level 阈值过滤。级别过滤原理不变:journalctl 不解析自定义字段,
8
+ * `-p` 在 StandardOutput=inherit 下无效,必须用 `--grep` 锚定行内 `[LEVEL] `。
9
+ * 要求 journalctl 带 PCRE2(`--grep`/`--case`);缺失时由 journalctl 报错,
10
+ * 不做静默降级。
11
+ */
12
+ export type FilterLevel = 'debug' | 'info' | 'warn' | 'error';
13
+ export declare function parseFilterLevel(value: string): FilterLevel | null;
14
+ export interface LogFilterRequest {
15
+ /** unit 名(不含 .service),CLI 传 SERVICE_NAME 常量。 */
16
+ unit: string;
17
+ /** 已拆出的级别字符串;非法值由本模块报错,便于 CLI 统一提示。 */
18
+ level: string;
19
+ /** 跟踪模式:logs=true,status=false。 */
20
+ follow: boolean;
21
+ /** status 用:-n <lineCount> 放在过滤器之后。 */
22
+ lineCount?: number;
23
+ }
24
+ export type LogFilterResult = {
25
+ ok: true;
26
+ args: string[];
27
+ } | {
28
+ ok: false;
29
+ message: string;
30
+ };
31
+ export declare function buildLogFilterArgs(req: LogFilterRequest): LogFilterResult;
32
+ //# sourceMappingURL=log-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-filter.d.ts","sourceRoot":"","sources":["../../src/cli/log-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAU7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAIlE;AAED,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,MAAM,EAAE,OAAO,CAAA;IACf,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,eAAe,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3F,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,eAAe,CAgBzE"}