dominds 1.26.0 → 1.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/README.zh.md +3 -3
- package/dist/bootstrap/rtws-cli.d.ts +1 -0
- package/dist/bootstrap/rtws-cli.js +8 -8
- package/dist/cli/cert.d.ts +3 -1
- package/dist/cli/cert.js +69 -20
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +1 -1
- package/dist/cli/read.js +1 -1
- package/dist/cli/tui.js +1 -1
- package/dist/cli/webui.js +15 -5
- package/dist/cli-runner.d.ts +31 -0
- package/dist/cli-runner.js +349 -0
- package/dist/cli.d.ts +0 -31
- package/dist/cli.js +540 -304
- package/dist/docs/cli-usage.md +11 -10
- package/dist/docs/cli-usage.zh.md +11 -10
- package/dist/docs/dialog-persistence.md +1 -1
- package/dist/docs/dominds-terminology.md +2 -2
- package/dist/llm/kernel-driver/drive.js +19 -14
- package/dist/runtime/driver-messages.d.ts +2 -0
- package/dist/runtime/driver-messages.js +24 -4
- package/dist/server/certificates.js +1 -1
- package/dist/server/dominds-self-update.js +33 -121
- package/dist/server/network-hosts.js +140 -38
- package/dist/server-debug.d.ts +2 -0
- package/dist/server-debug.js +79 -0
- package/dist/server.js +4 -123
- package/dist/supervisor-protocol.d.ts +15 -0
- package/dist/supervisor-protocol.js +4 -0
- package/package.json +6 -5
- package/dist/server/dominds-self-update-restart-helper.d.ts +0 -15
- package/dist/server/dominds-self-update-restart-helper.js +0 -305
|
@@ -1,305 +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
|
-
const child_process_1 = require("child_process");
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
const net_1 = __importDefault(require("net"));
|
|
9
|
-
const time_1 = require("@longrun-ai/kernel/utils/time");
|
|
10
|
-
function isRecord(value) {
|
|
11
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
12
|
-
}
|
|
13
|
-
function isStringArray(value) {
|
|
14
|
-
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
15
|
-
}
|
|
16
|
-
function readString(value, key) {
|
|
17
|
-
const candidate = value[key];
|
|
18
|
-
if (typeof candidate !== 'string' || candidate.trim() === '') {
|
|
19
|
-
throw new Error(`Invalid Dominds restart helper payload: ${key} must be a non-empty string`);
|
|
20
|
-
}
|
|
21
|
-
return candidate;
|
|
22
|
-
}
|
|
23
|
-
function readNumber(value, key) {
|
|
24
|
-
const candidate = value[key];
|
|
25
|
-
if (typeof candidate !== 'number' || !Number.isFinite(candidate)) {
|
|
26
|
-
throw new Error(`Invalid Dominds restart helper payload: ${key} must be a finite number`);
|
|
27
|
-
}
|
|
28
|
-
return candidate;
|
|
29
|
-
}
|
|
30
|
-
function readPositiveInteger(value, key) {
|
|
31
|
-
const candidate = readNumber(value, key);
|
|
32
|
-
if (!Number.isInteger(candidate) || candidate <= 0) {
|
|
33
|
-
throw new Error(`Invalid Dominds restart helper payload: ${key} must be a positive integer`);
|
|
34
|
-
}
|
|
35
|
-
return candidate;
|
|
36
|
-
}
|
|
37
|
-
function readPort(value, key) {
|
|
38
|
-
const candidate = readPositiveInteger(value, key);
|
|
39
|
-
if (candidate > 65535) {
|
|
40
|
-
throw new Error(`Invalid Dominds restart helper payload: ${key} must be <= 65535`);
|
|
41
|
-
}
|
|
42
|
-
return candidate;
|
|
43
|
-
}
|
|
44
|
-
function parsePayload(raw) {
|
|
45
|
-
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
46
|
-
throw new Error('Missing Dominds restart helper payload');
|
|
47
|
-
}
|
|
48
|
-
const parsed = JSON.parse(raw);
|
|
49
|
-
if (!isRecord(parsed)) {
|
|
50
|
-
throw new Error('Invalid Dominds restart helper payload: expected an object');
|
|
51
|
-
}
|
|
52
|
-
const args = parsed['args'];
|
|
53
|
-
if (!isStringArray(args)) {
|
|
54
|
-
throw new Error('Invalid Dominds restart helper payload: args must be a string array');
|
|
55
|
-
}
|
|
56
|
-
const stdioMode = parsed['stdioMode'];
|
|
57
|
-
if (stdioMode !== 'inherit' && stdioMode !== 'ignore') {
|
|
58
|
-
throw new Error('Invalid Dominds restart helper payload: stdioMode must be inherit or ignore');
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
command: readString(parsed, 'command'),
|
|
62
|
-
args,
|
|
63
|
-
cwd: readString(parsed, 'cwd'),
|
|
64
|
-
host: readString(parsed, 'host'),
|
|
65
|
-
port: readPort(parsed, 'port'),
|
|
66
|
-
retiringPid: readPositiveInteger(parsed, 'retiringPid'),
|
|
67
|
-
forceKillAfterMs: readPositiveInteger(parsed, 'forceKillAfterMs'),
|
|
68
|
-
probeIntervalMs: readPositiveInteger(parsed, 'probeIntervalMs'),
|
|
69
|
-
portReleaseTimeoutMs: readPositiveInteger(parsed, 'portReleaseTimeoutMs'),
|
|
70
|
-
stdioMode,
|
|
71
|
-
traceFile: readString(parsed, 'traceFile'),
|
|
72
|
-
debugDir: readString(parsed, 'debugDir'),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function trace(payload, event, details = {}) {
|
|
76
|
-
const record = {
|
|
77
|
-
...details,
|
|
78
|
-
event,
|
|
79
|
-
capturedAt: (0, time_1.formatUnifiedTimestamp)(new Date()),
|
|
80
|
-
helperPid: process.pid,
|
|
81
|
-
platform: process.platform,
|
|
82
|
-
};
|
|
83
|
-
try {
|
|
84
|
-
fs_1.default.mkdirSync(payload.debugDir, { recursive: true });
|
|
85
|
-
fs_1.default.appendFileSync(payload.traceFile, `${JSON.stringify(record)}\n`, 'utf8');
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
89
|
-
console.error(`Failed to write Dominds restart helper trace: ${message}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
function isPortBusy(payload) {
|
|
93
|
-
return new Promise((resolve) => {
|
|
94
|
-
const socket = net_1.default.createConnection({ host: payload.host, port: payload.port });
|
|
95
|
-
let settled = false;
|
|
96
|
-
const finish = (busy) => {
|
|
97
|
-
if (settled)
|
|
98
|
-
return;
|
|
99
|
-
settled = true;
|
|
100
|
-
socket.destroy();
|
|
101
|
-
resolve(busy);
|
|
102
|
-
};
|
|
103
|
-
socket.once('connect', () => finish(true));
|
|
104
|
-
socket.once('error', () => finish(false));
|
|
105
|
-
socket.setTimeout(1000, () => finish(true));
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
function getErrorCode(error) {
|
|
109
|
-
return isRecord(error) && typeof error['code'] === 'string' ? error['code'] : '';
|
|
110
|
-
}
|
|
111
|
-
function assertValidRetiringPid(payload) {
|
|
112
|
-
if (!Number.isInteger(payload.retiringPid) || payload.retiringPid <= 0) {
|
|
113
|
-
throw new Error(`Invalid retiring Dominds pid for restart: ${String(payload.retiringPid)}`);
|
|
114
|
-
}
|
|
115
|
-
if (payload.retiringPid === process.pid) {
|
|
116
|
-
throw new Error(`Refusing to kill restart helper pid ${String(process.pid)}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
function isRetiringProcessAlive(payload) {
|
|
120
|
-
assertValidRetiringPid(payload);
|
|
121
|
-
try {
|
|
122
|
-
process.kill(payload.retiringPid, 0);
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
const code = getErrorCode(error);
|
|
127
|
-
if (code === 'ESRCH')
|
|
128
|
-
return false;
|
|
129
|
-
if (code === 'EPERM')
|
|
130
|
-
return true;
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
async function delayMs(ms) {
|
|
135
|
-
await new Promise((resolve) => {
|
|
136
|
-
setTimeout(resolve, ms);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
async function waitForRetiringProcessExit(payload, timeoutMs) {
|
|
140
|
-
const deadline = Date.now() + timeoutMs;
|
|
141
|
-
while (Date.now() < deadline) {
|
|
142
|
-
if (!isRetiringProcessAlive(payload))
|
|
143
|
-
return true;
|
|
144
|
-
await delayMs(payload.probeIntervalMs);
|
|
145
|
-
}
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
async function waitForPortReleaseUntil(payload, deadline) {
|
|
149
|
-
let consecutiveReady = 0;
|
|
150
|
-
while (Date.now() < deadline) {
|
|
151
|
-
if (!(await isPortBusy(payload))) {
|
|
152
|
-
consecutiveReady += 1;
|
|
153
|
-
if (consecutiveReady >= 2)
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
consecutiveReady = 0;
|
|
158
|
-
}
|
|
159
|
-
await delayMs(payload.probeIntervalMs);
|
|
160
|
-
}
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
async function runBestEffortKiller(payload, command, args) {
|
|
164
|
-
await new Promise((resolve) => {
|
|
165
|
-
trace(payload, 'helper.force_kill.spawn', { command, args });
|
|
166
|
-
const killer = (0, child_process_1.spawn)(command, [...args], {
|
|
167
|
-
stdio: payload.stdioMode,
|
|
168
|
-
windowsHide: payload.stdioMode !== 'inherit',
|
|
169
|
-
});
|
|
170
|
-
killer.once('error', (error) => {
|
|
171
|
-
trace(payload, 'helper.force_kill.error', { message: error.message });
|
|
172
|
-
resolve();
|
|
173
|
-
});
|
|
174
|
-
killer.once('exit', (code, signal) => {
|
|
175
|
-
trace(payload, 'helper.force_kill.exit', { code, signal });
|
|
176
|
-
resolve();
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
async function forceKillRetiringProcess(payload) {
|
|
181
|
-
assertValidRetiringPid(payload);
|
|
182
|
-
try {
|
|
183
|
-
process.kill(payload.retiringPid, 'SIGKILL');
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
const code = getErrorCode(error);
|
|
187
|
-
if (code === 'ESRCH')
|
|
188
|
-
return;
|
|
189
|
-
if (process.platform !== 'win32')
|
|
190
|
-
throw error;
|
|
191
|
-
}
|
|
192
|
-
if (process.platform === 'win32') {
|
|
193
|
-
await runBestEffortKiller(payload, 'taskkill.exe', ['/PID', String(payload.retiringPid), '/F']);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
async function runRestartHelper(payload) {
|
|
197
|
-
const detached = payload.stdioMode !== 'inherit';
|
|
198
|
-
trace(payload, 'helper.start', {
|
|
199
|
-
command: payload.command,
|
|
200
|
-
args: payload.args,
|
|
201
|
-
cwd: payload.cwd,
|
|
202
|
-
host: payload.host,
|
|
203
|
-
port: payload.port,
|
|
204
|
-
retiringPid: payload.retiringPid,
|
|
205
|
-
detached,
|
|
206
|
-
stdioMode: payload.stdioMode,
|
|
207
|
-
forceKillAfterMs: payload.forceKillAfterMs,
|
|
208
|
-
portReleaseTimeoutMs: payload.portReleaseTimeoutMs,
|
|
209
|
-
probeIntervalMs: payload.probeIntervalMs,
|
|
210
|
-
});
|
|
211
|
-
const forceKillDeadline = Date.now() + payload.forceKillAfterMs;
|
|
212
|
-
trace(payload, 'helper.wait_retiring_process_exit.start', {
|
|
213
|
-
retiringPid: payload.retiringPid,
|
|
214
|
-
timeoutMs: payload.forceKillAfterMs,
|
|
215
|
-
});
|
|
216
|
-
const exitedGracefully = await waitForRetiringProcessExit(payload, payload.forceKillAfterMs);
|
|
217
|
-
trace(payload, 'helper.wait_retiring_process_exit.finish', {
|
|
218
|
-
retiringPid: payload.retiringPid,
|
|
219
|
-
exited: exitedGracefully,
|
|
220
|
-
});
|
|
221
|
-
if (!exitedGracefully) {
|
|
222
|
-
trace(payload, 'helper.force_kill.start', { retiringPid: payload.retiringPid });
|
|
223
|
-
await forceKillRetiringProcess(payload);
|
|
224
|
-
trace(payload, 'helper.force_kill.finish', { retiringPid: payload.retiringPid });
|
|
225
|
-
trace(payload, 'helper.wait_retiring_process_exit_after_kill.start', {
|
|
226
|
-
retiringPid: payload.retiringPid,
|
|
227
|
-
timeoutMs: payload.portReleaseTimeoutMs,
|
|
228
|
-
});
|
|
229
|
-
const exitedAfterKill = await waitForRetiringProcessExit(payload, payload.portReleaseTimeoutMs);
|
|
230
|
-
trace(payload, 'helper.wait_retiring_process_exit_after_kill.finish', {
|
|
231
|
-
retiringPid: payload.retiringPid,
|
|
232
|
-
exited: exitedAfterKill,
|
|
233
|
-
});
|
|
234
|
-
if (!exitedAfterKill) {
|
|
235
|
-
throw new Error(`Dominds retiring process is still alive after force-killing pid ${String(payload.retiringPid)}`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
const portReleaseDeadline = Math.max(forceKillDeadline, Date.now() + payload.portReleaseTimeoutMs);
|
|
239
|
-
trace(payload, 'helper.wait_port_release.start', {
|
|
240
|
-
host: payload.host,
|
|
241
|
-
port: payload.port,
|
|
242
|
-
deadlineMsFromNow: portReleaseDeadline - Date.now(),
|
|
243
|
-
});
|
|
244
|
-
const portReleased = await waitForPortReleaseUntil(payload, portReleaseDeadline);
|
|
245
|
-
trace(payload, 'helper.wait_port_release.finish', {
|
|
246
|
-
host: payload.host,
|
|
247
|
-
port: payload.port,
|
|
248
|
-
released: portReleased,
|
|
249
|
-
});
|
|
250
|
-
if (!portReleased) {
|
|
251
|
-
throw new Error(`Dominds restart port is still busy after retiring pid ${String(payload.retiringPid)} exited; port=${String(payload.host)}:${String(payload.port)}`);
|
|
252
|
-
}
|
|
253
|
-
trace(payload, 'helper.spawn_new_process.start', {
|
|
254
|
-
command: payload.command,
|
|
255
|
-
args: payload.args,
|
|
256
|
-
cwd: payload.cwd,
|
|
257
|
-
detached,
|
|
258
|
-
stdioMode: payload.stdioMode,
|
|
259
|
-
});
|
|
260
|
-
const child = (0, child_process_1.spawn)(payload.command, [...payload.args], {
|
|
261
|
-
cwd: payload.cwd,
|
|
262
|
-
env: process.env,
|
|
263
|
-
detached,
|
|
264
|
-
stdio: payload.stdioMode,
|
|
265
|
-
shell: false,
|
|
266
|
-
windowsHide: payload.stdioMode !== 'inherit',
|
|
267
|
-
});
|
|
268
|
-
if (detached)
|
|
269
|
-
child.unref();
|
|
270
|
-
await new Promise((resolve, reject) => {
|
|
271
|
-
child.once('error', (error) => {
|
|
272
|
-
trace(payload, 'helper.spawn_new_process.error', {
|
|
273
|
-
command: payload.command,
|
|
274
|
-
args: payload.args,
|
|
275
|
-
cwd: payload.cwd,
|
|
276
|
-
message: error.message,
|
|
277
|
-
stack: error.stack ?? null,
|
|
278
|
-
});
|
|
279
|
-
reject(error);
|
|
280
|
-
});
|
|
281
|
-
child.once('spawn', resolve);
|
|
282
|
-
});
|
|
283
|
-
trace(payload, 'helper.spawn_new_process.finish', { childPid: child.pid ?? null });
|
|
284
|
-
trace(payload, 'helper.exit', { code: 0 });
|
|
285
|
-
}
|
|
286
|
-
async function main() {
|
|
287
|
-
let payload = null;
|
|
288
|
-
try {
|
|
289
|
-
payload = parsePayload(process.argv[2]);
|
|
290
|
-
await runRestartHelper(payload);
|
|
291
|
-
process.exit(0);
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
295
|
-
const stack = error instanceof Error ? (error.stack ?? null) : null;
|
|
296
|
-
if (payload !== null) {
|
|
297
|
-
trace(payload, 'helper.error', { message, stack });
|
|
298
|
-
}
|
|
299
|
-
console.error(message);
|
|
300
|
-
process.exit(1);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (require.main === module) {
|
|
304
|
-
void main();
|
|
305
|
-
}
|