dominds 1.25.19 → 1.26.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/README.md +17 -0
- package/README.zh.md +17 -0
- package/dist/apps/runtime.d.ts +2 -4
- package/dist/apps-host/client.d.ts +2 -5
- package/dist/apps-host/ipc-types.d.ts +2 -5
- package/dist/apps-host/ipc-types.js +5 -1
- package/dist/cli/cert.d.ts +2 -0
- package/dist/cli/cert.js +198 -0
- package/dist/cli/webui.d.ts +1 -1
- package/dist/cli/webui.js +34 -4
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +15 -3
- package/dist/docs/cli-usage.md +36 -0
- package/dist/docs/cli-usage.zh.md +36 -0
- package/dist/server/auth.d.ts +7 -0
- package/dist/server/auth.js +15 -4
- package/dist/server/certificates.d.ts +61 -0
- package/dist/server/certificates.js +418 -0
- package/dist/server/network-hosts.d.ts +5 -0
- package/dist/server/network-hosts.js +188 -0
- package/dist/server/server-core.d.ts +12 -1
- package/dist/server/server-core.js +26 -4
- package/dist/server/websocket-handler.d.ts +3 -2
- package/dist/server/websocket-handler.js +15 -8
- package/dist/server.d.ts +5 -0
- package/dist/server.js +101 -7
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -253,6 +253,23 @@ Platform note:
|
|
|
253
253
|
|
|
254
254
|
- Windows also registers `codex_inspect_and_patch_tools`; its `readonly_shell` tool runs through `cmd.exe`, so prefer allowlisted commands available in that shell/PATH, such as `rg`, `git`, `dir`, `type`, and `where`.
|
|
255
255
|
|
|
256
|
+
### Local HTTPS Certificates
|
|
257
|
+
|
|
258
|
+
Dominds always keeps an HTTP listener. When a valid certificate matching the current `--host` exists under `~/.dominds/certs/`, Dominds also starts HTTPS. Certificates match DNS/IP hostnames, not ports, so one certificate covers all Dominds WebUI ports on that host.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Create a 10-year self-signed certificate for detected non-loopback LAN hosts
|
|
262
|
+
dominds cert create
|
|
263
|
+
|
|
264
|
+
# Add explicit SAN hosts; --host can be repeated
|
|
265
|
+
dominds cert create --host 192.168.1.10 --host my-host.local
|
|
266
|
+
|
|
267
|
+
# Inspect whether a host can use an HTTPS certificate
|
|
268
|
+
dominds cert status --host 0.0.0.0
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
`localhost`, `loopback`, `127.0.0.0/8`, `::1`, `0.0.0.0`, and `::` are not certificate hosts. `0.0.0.0` / `::` only mean bind-all; certificate matching uses detected non-loopback LAN hosts. A bare `--port 5666` disables Dominds built-in HTTPS and assumes a front proxy handles HTTPS, while the default port behavior and `--port 5666+/-` may auto-enable built-in HTTPS when a matching certificate exists.
|
|
272
|
+
|
|
256
273
|
## Start from scratch
|
|
257
274
|
|
|
258
275
|
Starting from scratch means: create an empty folder, run `dominds`, let Setup generate the minimal `.minds/team.yaml`, then use the shadow team manager (`@fuxi`) to design a real team for your product.
|
package/README.zh.md
CHANGED
|
@@ -192,6 +192,23 @@ dominds
|
|
|
192
192
|
|
|
193
193
|
- Windows 也会注册 `codex_inspect_and_patch_tools`;其中 `readonly_shell` 通过 `cmd.exe` 执行,因此优先使用该 shell/PATH 中可用的白名单命令,例如 `rg`、`git`、`dir`、`type` 和 `where`。
|
|
194
194
|
|
|
195
|
+
### 本地 HTTPS 证书
|
|
196
|
+
|
|
197
|
+
Dominds 默认始终提供 HTTP 监听;当 `~/.dominds/certs/` 下存在匹配当前 `--host` 的有效证书时,会额外启用 HTTPS。证书按 DNS/IP 主机名匹配,不绑定端口,因此同一张证书可覆盖该主机上的所有 Dominds WebUI 端口。
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# 自动为检测到的一个或多个非 loopback LAN 主机创建 10 年有效的自签名证书
|
|
201
|
+
dominds cert create
|
|
202
|
+
|
|
203
|
+
# 显式指定证书 SAN,可重复 --host
|
|
204
|
+
dominds cert create --host 192.168.1.10 --host my-host.local
|
|
205
|
+
|
|
206
|
+
# 查看指定 host 是否能匹配到证书
|
|
207
|
+
dominds cert status --host 0.0.0.0
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`localhost`、`loopback`、`127.0.0.0/8`、`::1`、`0.0.0.0`、`::` 不会作为 HTTPS 证书主机;其中 `0.0.0.0` / `::` 仅表示绑定所有地址,匹配证书时会使用检测到的非 loopback LAN 主机。使用裸 `--port 5666` 启动时,Dominds 会认为 HTTPS 由前置代理负责,不启用内建 HTTPS;使用默认端口或 `--port 5666+/-` 时才会自动启用内建 HTTPS。
|
|
211
|
+
|
|
195
212
|
## 从零开始(空文件夹启动)
|
|
196
213
|
|
|
197
214
|
若暂无模板或团队配置,可直接从空目录启动:
|
package/dist/apps/runtime.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DomindsKernelEndpoint } from '@longrun-ai/kernel/app-host-contract';
|
|
1
2
|
import { type AppsHostClient } from '../apps-host/client';
|
|
2
3
|
export type DynamicAppToolAvailabilityResult = Readonly<{
|
|
3
4
|
status: 'ready';
|
|
@@ -36,8 +37,5 @@ export declare function resolveDynamicAppToolAvailabilityForMember(_params: {
|
|
|
36
37
|
}): Promise<DynamicAppToolAvailabilityResult>;
|
|
37
38
|
export declare function initAppsRuntime(params: {
|
|
38
39
|
rtwsRootAbs: string;
|
|
39
|
-
kernel:
|
|
40
|
-
host: string;
|
|
41
|
-
port: number;
|
|
42
|
-
}>;
|
|
40
|
+
kernel: DomindsKernelEndpoint;
|
|
43
41
|
}): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DomindsAppDynamicToolsetsContext, DomindsAppReminderOwnerApplyContext, DomindsAppReminderOwnerRenderContext, DomindsAppReminderOwnerUpdateContext, DomindsAppReminderRenderedMessage, DomindsAppRunControlContext, DomindsAppRunControlResult } from '@longrun-ai/kernel/app-host-contract';
|
|
1
|
+
import type { DomindsAppDynamicToolsetsContext, DomindsAppReminderOwnerApplyContext, DomindsAppReminderOwnerRenderContext, DomindsAppReminderOwnerUpdateContext, DomindsAppReminderRenderedMessage, DomindsAppRunControlContext, DomindsAppRunControlResult, DomindsKernelEndpoint } from '@longrun-ai/kernel/app-host-contract';
|
|
2
2
|
import type { DomindsAppHostReminderUpdateResult, DomindsAppHostToolResult, DomindsAppInstallJson, DomindsAppReminderApplyRequest, DomindsAppReminderApplyResult } from '@longrun-ai/kernel/app-json';
|
|
3
3
|
import type { ToolArguments } from '../tool';
|
|
4
4
|
import type { AppsHostMessageToKernel } from './ipc-types';
|
|
@@ -29,10 +29,7 @@ export type AppsHostReadyMessage = Extract<AppsHostMessageToKernel, {
|
|
|
29
29
|
}>;
|
|
30
30
|
export declare function startAppsHost(params: {
|
|
31
31
|
rtwsRootAbs: string;
|
|
32
|
-
kernel:
|
|
33
|
-
host: string;
|
|
34
|
-
port: number;
|
|
35
|
-
}>;
|
|
32
|
+
kernel: DomindsKernelEndpoint;
|
|
36
33
|
apps: ReadonlyArray<EnabledAppForHost>;
|
|
37
34
|
}): Promise<Readonly<{
|
|
38
35
|
client: AppsHostClient;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import type { DomindsAppReminderRenderedMessage, DomindsAppRunControlResult } from '@longrun-ai/kernel/app-host-contract';
|
|
1
|
+
import type { DomindsAppReminderRenderedMessage, DomindsAppRunControlResult, DomindsKernelEndpoint } from '@longrun-ai/kernel/app-host-contract';
|
|
2
2
|
import type { DomindsAppDialogReminderRequestBatch, DomindsAppHostReminderUpdateResult, DomindsAppInstallJson, DomindsAppReminderApplyRequest, DomindsAppReminderApplyResult, DomindsAppReminderState } from '@longrun-ai/kernel/app-json';
|
|
3
3
|
import type { LanguageCode } from '@longrun-ai/kernel/types/language';
|
|
4
4
|
import type { ToolArguments, ToolCallOutput } from '../tool';
|
|
5
5
|
export type AppsHostKernelInitMessage = Readonly<{
|
|
6
6
|
type: 'init';
|
|
7
7
|
rtwsRootAbs: string;
|
|
8
|
-
kernel:
|
|
9
|
-
host: string;
|
|
10
|
-
port: number;
|
|
11
|
-
}>;
|
|
8
|
+
kernel: DomindsKernelEndpoint;
|
|
12
9
|
apps: ReadonlyArray<Readonly<{
|
|
13
10
|
appId: string;
|
|
14
11
|
runtimePort: number | null;
|
|
@@ -126,9 +126,13 @@ function parseAppsHostMessageFromKernel(v) {
|
|
|
126
126
|
throw new Error('Invalid init message: rtwsRootAbs required');
|
|
127
127
|
if (!isRecord(kernel))
|
|
128
128
|
throw new Error('Invalid init message: kernel must be object');
|
|
129
|
+
const scheme = kernel['scheme'];
|
|
129
130
|
const host = asString(kernel['host']);
|
|
130
131
|
const portRaw = kernel['port'];
|
|
131
132
|
const port = typeof portRaw === 'number' && Number.isFinite(portRaw) ? Math.floor(portRaw) : null;
|
|
133
|
+
if (scheme !== 'http' && scheme !== 'https') {
|
|
134
|
+
throw new Error('Invalid init message: kernel.scheme must be http|https');
|
|
135
|
+
}
|
|
132
136
|
if (!host)
|
|
133
137
|
throw new Error('Invalid init message: kernel.host required');
|
|
134
138
|
if (port === null || port < 0) {
|
|
@@ -157,7 +161,7 @@ function parseAppsHostMessageFromKernel(v) {
|
|
|
157
161
|
}
|
|
158
162
|
return { appId, runtimePort, installJson: installJson };
|
|
159
163
|
});
|
|
160
|
-
return { type: 'init', rtwsRootAbs, kernel: { host, port }, apps: parsedApps };
|
|
164
|
+
return { type: 'init', rtwsRootAbs, kernel: { scheme, host, port }, apps: parsedApps };
|
|
161
165
|
}
|
|
162
166
|
if (type === 'tool_call') {
|
|
163
167
|
const callId = asString(v['callId']);
|
package/dist/cli/cert.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.main = main;
|
|
5
|
+
const auth_1 = require("../server/auth");
|
|
6
|
+
const certificates_1 = require("../server/certificates");
|
|
7
|
+
function printHelp() {
|
|
8
|
+
console.log(`
|
|
9
|
+
Dominds certificate tools
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
dominds cert create [--host <host>] [--days <days>] [--force]
|
|
13
|
+
dominds cert self-cert [--host <host>] [--days <days>] [--force]
|
|
14
|
+
dominds cert status --host <host> [--port <port>] [--origin]
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--host <host> Host name or IP address (default for create: detected non-loopback LAN hosts)
|
|
18
|
+
--days <days> Certificate validity in days (default: ${certificates_1.DEFAULT_SELF_SIGNED_CERT_DAYS})
|
|
19
|
+
--force Overwrite existing generated files
|
|
20
|
+
--port <port> Port for status --origin output
|
|
21
|
+
--origin Print only the effective origin, using https when a matching cert exists
|
|
22
|
+
--help Show this help message
|
|
23
|
+
|
|
24
|
+
Certificates live in ~/.dominds/certs/. A WebUI server automatically enables HTTPS when it finds
|
|
25
|
+
a certificate/key pair that matches the bind host or, for 0.0.0.0/::, a detected non-loopback LAN host.
|
|
26
|
+
`);
|
|
27
|
+
}
|
|
28
|
+
async function main(args = process.argv.slice(2)) {
|
|
29
|
+
const first = args[0];
|
|
30
|
+
if (first === undefined || first === '--help' || first === '-h') {
|
|
31
|
+
printHelp();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const action = parseAction(first);
|
|
35
|
+
if (action === null) {
|
|
36
|
+
console.error(`Error: Unknown cert subcommand '${first}'`);
|
|
37
|
+
printHelp();
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const options = parseOptions(args.slice(1), action);
|
|
41
|
+
if (options.kind === 'error') {
|
|
42
|
+
console.error(`Error: ${options.message}`);
|
|
43
|
+
printHelp();
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (action === 'create') {
|
|
47
|
+
const created = await (0, certificates_1.createSelfSignedCertificate)({
|
|
48
|
+
host: options.host,
|
|
49
|
+
altHosts: options.altHosts,
|
|
50
|
+
days: options.days,
|
|
51
|
+
force: options.force,
|
|
52
|
+
});
|
|
53
|
+
console.log(`Created self-signed certificate for ${created.host}`);
|
|
54
|
+
console.log(` hosts: ${created.hosts.join(', ')}`);
|
|
55
|
+
console.log(` cert: ${created.certPath}`);
|
|
56
|
+
console.log(` key: ${created.keyPath}`);
|
|
57
|
+
console.log(` meta: ${created.metadataPath}`);
|
|
58
|
+
console.log(` days: ${created.days}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (options.host === undefined) {
|
|
62
|
+
console.error('Error: cert status requires --host <host>');
|
|
63
|
+
printHelp();
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const lookup = await (0, certificates_1.findAutoHttpsCertificateForHost)({ host: options.host });
|
|
67
|
+
if (options.origin) {
|
|
68
|
+
if (options.port === undefined) {
|
|
69
|
+
console.error('Error: cert status --origin requires --port <port>');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
console.log((0, auth_1.formatServerOrigin)({
|
|
73
|
+
scheme: lookup.kind === 'found' ? 'https' : 'http',
|
|
74
|
+
host: lookup.kind === 'found' ? lookup.certificate.matchedHost : lookup.endpoint.urlHost,
|
|
75
|
+
port: options.port,
|
|
76
|
+
}));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
for (const diagnostic of lookup.diagnostics) {
|
|
80
|
+
console.warn(`warning: ${diagnostic.message}`);
|
|
81
|
+
}
|
|
82
|
+
if (lookup.kind === 'found') {
|
|
83
|
+
console.log(`HTTPS certificate: found`);
|
|
84
|
+
console.log(` cert: ${lookup.certificate.certPath}`);
|
|
85
|
+
console.log(` key: ${lookup.certificate.keyPath}`);
|
|
86
|
+
console.log(` matchedHost: ${lookup.certificate.matchedHost}`);
|
|
87
|
+
console.log(` validTo: ${lookup.certificate.validTo.toISOString()}`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
console.log(`HTTPS certificate: not found`);
|
|
91
|
+
console.log(` certsDir: ${lookup.certsDirAbs}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function parseAction(value) {
|
|
95
|
+
switch (value) {
|
|
96
|
+
case 'create':
|
|
97
|
+
case 'self-cert':
|
|
98
|
+
return 'create';
|
|
99
|
+
case 'status':
|
|
100
|
+
return 'status';
|
|
101
|
+
default:
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function parseOptions(args, action) {
|
|
106
|
+
let host;
|
|
107
|
+
let days;
|
|
108
|
+
const altHosts = [];
|
|
109
|
+
let force = false;
|
|
110
|
+
let port;
|
|
111
|
+
let origin = false;
|
|
112
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
113
|
+
const arg = args[i];
|
|
114
|
+
if (arg === '--host') {
|
|
115
|
+
const next = args[i + 1];
|
|
116
|
+
if (!next)
|
|
117
|
+
return { kind: 'error', message: '--host requires a value' };
|
|
118
|
+
if (host === undefined)
|
|
119
|
+
host = next;
|
|
120
|
+
else
|
|
121
|
+
altHosts.push(next);
|
|
122
|
+
i += 1;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (arg.startsWith('--host=')) {
|
|
126
|
+
const value = arg.slice('--host='.length);
|
|
127
|
+
if (host === undefined)
|
|
128
|
+
host = value;
|
|
129
|
+
else
|
|
130
|
+
altHosts.push(value);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (arg === '--days') {
|
|
134
|
+
const next = args[i + 1];
|
|
135
|
+
const parsed = next === undefined ? null : parseInteger(next);
|
|
136
|
+
if (parsed === null)
|
|
137
|
+
return { kind: 'error', message: '--days requires an integer' };
|
|
138
|
+
days = parsed;
|
|
139
|
+
i += 1;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (arg.startsWith('--days=')) {
|
|
143
|
+
const parsed = parseInteger(arg.slice('--days='.length));
|
|
144
|
+
if (parsed === null)
|
|
145
|
+
return { kind: 'error', message: '--days requires an integer' };
|
|
146
|
+
days = parsed;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (arg === '--port') {
|
|
150
|
+
const next = args[i + 1];
|
|
151
|
+
const parsed = next === undefined ? null : parseInteger(next);
|
|
152
|
+
if (parsed === null || parsed < 1 || parsed > 65535) {
|
|
153
|
+
return { kind: 'error', message: '--port requires a valid TCP port' };
|
|
154
|
+
}
|
|
155
|
+
port = parsed;
|
|
156
|
+
i += 1;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (arg.startsWith('--port=')) {
|
|
160
|
+
const parsed = parseInteger(arg.slice('--port='.length));
|
|
161
|
+
if (parsed === null || parsed < 1 || parsed > 65535) {
|
|
162
|
+
return { kind: 'error', message: '--port requires a valid TCP port' };
|
|
163
|
+
}
|
|
164
|
+
port = parsed;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (arg === '--force') {
|
|
168
|
+
force = true;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (arg === '--origin') {
|
|
172
|
+
origin = true;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (arg === '--help' || arg === '-h') {
|
|
176
|
+
printHelp();
|
|
177
|
+
process.exit(0);
|
|
178
|
+
}
|
|
179
|
+
if (!arg.startsWith('-') && host === undefined && action === 'create') {
|
|
180
|
+
host = arg;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
return { kind: 'error', message: `Unknown option '${arg}'` };
|
|
184
|
+
}
|
|
185
|
+
return { kind: 'ok', host, days, altHosts, force, port, origin };
|
|
186
|
+
}
|
|
187
|
+
function parseInteger(raw) {
|
|
188
|
+
if (!/^[0-9]+$/.test(raw))
|
|
189
|
+
return null;
|
|
190
|
+
const parsed = Number(raw);
|
|
191
|
+
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
192
|
+
}
|
|
193
|
+
if (require.main === module) {
|
|
194
|
+
main().catch((error) => {
|
|
195
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
196
|
+
process.exit(1);
|
|
197
|
+
});
|
|
198
|
+
}
|
package/dist/cli/webui.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* -p, --port <port> Port to listen on. Bare port is strict; suffix + tries higher ports; suffix - tries lower ports.
|
|
10
10
|
* -h, --host <host> Host to bind to (default: localhost)
|
|
11
11
|
* --nobrowser Do not open a browser (opt-out)
|
|
12
|
-
*
|
|
12
|
+
* --help Show help
|
|
13
13
|
*/
|
|
14
14
|
declare function main(args?: readonly string[]): Promise<void>;
|
|
15
15
|
export { main };
|
package/dist/cli/webui.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* -p, --port <port> Port to listen on. Bare port is strict; suffix + tries higher ports; suffix - tries lower ports.
|
|
11
11
|
* -h, --host <host> Host to bind to (default: localhost)
|
|
12
12
|
* --nobrowser Do not open a browser (opt-out)
|
|
13
|
-
*
|
|
13
|
+
* --help Show help
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.main = main;
|
|
@@ -22,6 +22,14 @@ const server_1 = require("../server");
|
|
|
22
22
|
const auth_1 = require("../server/auth");
|
|
23
23
|
const port_selection_1 = require("../server/port-selection");
|
|
24
24
|
const log = (0, log_1.createLogger)('webui');
|
|
25
|
+
function formatWebSocketEndpoint(params) {
|
|
26
|
+
const httpOrigin = (0, auth_1.formatServerOrigin)({
|
|
27
|
+
scheme: params.scheme === 'ws' ? 'http' : 'https',
|
|
28
|
+
host: params.host,
|
|
29
|
+
port: params.port,
|
|
30
|
+
});
|
|
31
|
+
return `${params.scheme}${httpOrigin.slice(httpOrigin.indexOf(':'))}/ws`;
|
|
32
|
+
}
|
|
25
33
|
function printHelp() {
|
|
26
34
|
console.log(`
|
|
27
35
|
WebUI Server for dominds
|
|
@@ -145,12 +153,34 @@ async function main(args = process.argv.slice(2)) {
|
|
|
145
153
|
});
|
|
146
154
|
const httpServer = started.httpServer;
|
|
147
155
|
const auth = started.auth;
|
|
148
|
-
const baseUrl =
|
|
156
|
+
const baseUrl = (0, auth_1.formatServerOrigin)({
|
|
157
|
+
scheme: 'http',
|
|
158
|
+
host: started.urlHost,
|
|
159
|
+
port: started.port,
|
|
160
|
+
});
|
|
149
161
|
log.info(`WebUI ready: ${baseUrl}`);
|
|
150
|
-
log.debug(`WebSocket endpoint:
|
|
162
|
+
log.debug(`WebSocket endpoint: ${formatWebSocketEndpoint({
|
|
163
|
+
scheme: 'ws',
|
|
164
|
+
host: started.urlHost,
|
|
165
|
+
port: started.port,
|
|
166
|
+
})}`);
|
|
167
|
+
if (started.httpsPort !== undefined && started.httpsUrlHost !== undefined) {
|
|
168
|
+
const httpsBaseUrl = (0, auth_1.formatServerOrigin)({
|
|
169
|
+
scheme: 'https',
|
|
170
|
+
host: started.httpsUrlHost,
|
|
171
|
+
port: started.httpsPort,
|
|
172
|
+
});
|
|
173
|
+
log.info(`HTTPS WebUI ready: ${httpsBaseUrl}`);
|
|
174
|
+
log.debug(`HTTPS WebSocket endpoint: ${formatWebSocketEndpoint({
|
|
175
|
+
scheme: 'wss',
|
|
176
|
+
host: started.httpsUrlHost,
|
|
177
|
+
port: started.httpsPort,
|
|
178
|
+
})}`);
|
|
179
|
+
}
|
|
151
180
|
if (auth.kind === 'enabled') {
|
|
152
181
|
const autoAuthUrl = (0, auth_1.formatAutoAuthUrl)({
|
|
153
|
-
|
|
182
|
+
scheme: 'http',
|
|
183
|
+
host: started.urlHost,
|
|
154
184
|
port: started.port,
|
|
155
185
|
authKey: auth.key,
|
|
156
186
|
});
|
package/dist/cli.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* man - Render toolset manual to stdout
|
|
14
14
|
* manual - Alias for man
|
|
15
15
|
* validate_team_def - Validate explicit team toolset declarations
|
|
16
|
+
* cert - Create and inspect local HTTPS certificates
|
|
16
17
|
* create - Create a new runtime workspace (rtws) from a template
|
|
17
18
|
* install - Install a Dominds App into this rtws
|
|
18
19
|
* doctor - Diagnose Dominds App state in this rtws
|
package/dist/cli.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* man - Render toolset manual to stdout
|
|
15
15
|
* manual - Alias for man
|
|
16
16
|
* validate_team_def - Validate explicit team toolset declarations
|
|
17
|
+
* cert - Create and inspect local HTTPS certificates
|
|
17
18
|
* create - Create a new runtime workspace (rtws) from a template
|
|
18
19
|
* install - Install a Dominds App into this rtws
|
|
19
20
|
* doctor - Diagnose Dominds App state in this rtws
|
|
@@ -70,6 +71,7 @@ const path = __importStar(require("path"));
|
|
|
70
71
|
const runtime_1 = require("./apps/runtime");
|
|
71
72
|
const dotenv_1 = require("./bootstrap/dotenv");
|
|
72
73
|
const rtws_cli_1 = require("./bootstrap/rtws-cli");
|
|
74
|
+
const cert_1 = require("./cli/cert");
|
|
73
75
|
const create_1 = require("./cli/create");
|
|
74
76
|
const disable_1 = require("./cli/disable");
|
|
75
77
|
const doctor_1 = require("./cli/doctor");
|
|
@@ -120,6 +122,7 @@ Subcommands:
|
|
|
120
122
|
man [options] Render toolset manual to stdout
|
|
121
123
|
manual [options] Alias for man
|
|
122
124
|
validate_team_def [options] Validate explicit team toolset declarations
|
|
125
|
+
cert [options] Create and inspect local HTTPS certificates
|
|
123
126
|
create [options] Create a new runtime workspace (rtws) from a template
|
|
124
127
|
install [options] Install a Dominds App into this rtws
|
|
125
128
|
doctor [options] Read-only diagnosis across manifest/lock/configuration/resolution/handshake
|
|
@@ -139,6 +142,7 @@ Examples:
|
|
|
139
142
|
dominds read # Read team configuration
|
|
140
143
|
dominds man ws_read --lang zh --all
|
|
141
144
|
dominds validate_team_def # Validate toolset references in .minds/team.yaml
|
|
145
|
+
dominds cert create --host 192.168.1.10
|
|
142
146
|
dominds create web-scaffold my-project # Create rtws from a template
|
|
143
147
|
dominds doctor @longrun-ai/web-dev # Diagnose a single app across all app-state layers
|
|
144
148
|
|
|
@@ -195,7 +199,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
195
199
|
printVersion();
|
|
196
200
|
process.exit(0);
|
|
197
201
|
}
|
|
198
|
-
const shouldSkipRtwsSetup =
|
|
202
|
+
const shouldSkipRtwsSetup = subcommand === 'cert' ||
|
|
203
|
+
subcommandArgs.includes('--help') ||
|
|
199
204
|
(subcommand === 'tui' && subcommandArgs.includes('-h')) ||
|
|
200
205
|
(subcommand === 'run' && subcommandArgs.includes('-h')) ||
|
|
201
206
|
(subcommand === 'read' && subcommandArgs.includes('-h')) ||
|
|
@@ -232,6 +237,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
232
237
|
configureEnvProxySupport();
|
|
233
238
|
}
|
|
234
239
|
const shouldLoadApps = subcommand !== 'webui' &&
|
|
240
|
+
subcommand !== 'cert' &&
|
|
235
241
|
subcommand !== 'create' &&
|
|
236
242
|
subcommand !== 'new' &&
|
|
237
243
|
subcommand !== 'install' &&
|
|
@@ -249,7 +255,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
249
255
|
if (shouldStartAppsHost) {
|
|
250
256
|
await (0, runtime_1.initAppsRuntime)({
|
|
251
257
|
rtwsRootAbs: process.cwd(),
|
|
252
|
-
kernel: { host: '127.0.0.1', port: 0 },
|
|
258
|
+
kernel: { scheme: 'http', host: '127.0.0.1', port: 0 },
|
|
253
259
|
});
|
|
254
260
|
}
|
|
255
261
|
}
|
|
@@ -279,6 +285,9 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
279
285
|
case 'validate_team_def':
|
|
280
286
|
await runSubcommand('validate_team_def', subcommandArgs);
|
|
281
287
|
break;
|
|
288
|
+
case 'cert':
|
|
289
|
+
await runSubcommand('cert', subcommandArgs);
|
|
290
|
+
break;
|
|
282
291
|
case 'create':
|
|
283
292
|
case 'new':
|
|
284
293
|
await runSubcommand('create', subcommandArgs);
|
|
@@ -325,6 +334,9 @@ async function runSubcommand(subcommand, args) {
|
|
|
325
334
|
else if (subcommand === 'validate_team_def') {
|
|
326
335
|
await (0, validate_team_def_1.main)(args);
|
|
327
336
|
}
|
|
337
|
+
else if (subcommand === 'cert') {
|
|
338
|
+
await (0, cert_1.main)(args);
|
|
339
|
+
}
|
|
328
340
|
else if (subcommand === 'create') {
|
|
329
341
|
await (0, create_1.main)(args);
|
|
330
342
|
}
|
|
@@ -352,7 +364,7 @@ async function runSubcommand(subcommand, args) {
|
|
|
352
364
|
}
|
|
353
365
|
}
|
|
354
366
|
catch (err) {
|
|
355
|
-
console.error(`Failed to execute subcommand '${subcommand}'
|
|
367
|
+
console.error(`Failed to execute subcommand '${subcommand}': ${err instanceof Error ? err.message : String(err)}`);
|
|
356
368
|
process.exit(1);
|
|
357
369
|
}
|
|
358
370
|
}
|
package/dist/docs/cli-usage.md
CHANGED
|
@@ -18,6 +18,7 @@ The `dominds` CLI provides a unified entry point, but the **primary interaction
|
|
|
18
18
|
- [Web UI Interface](#web-ui-interface)
|
|
19
19
|
- [Text User Interface (TUI) (Not Implemented Yet)](#text-user-interface-tui-not-implemented-yet)
|
|
20
20
|
- [Minds Reader](#minds-reader)
|
|
21
|
+
- [Certificate Tools](#certificate-tools)
|
|
21
22
|
- [rtws Creation](#rtws-creation)
|
|
22
23
|
- [Usage Examples](#usage-examples)
|
|
23
24
|
- [Dialog Storage](#dialog-storage)
|
|
@@ -32,6 +33,7 @@ The `dominds` package provides a unified CLI with subcommands:
|
|
|
32
33
|
| `dominds` or `dominds webui` | Start Web UI (default, recommended) | Web UI |
|
|
33
34
|
| `dominds tui` or `dominds run` | Terminal UI (planned; no stable implementation at the moment) | N/A |
|
|
34
35
|
| `dominds read` | Read and inspect rtws/team minds configuration | CLI |
|
|
36
|
+
| `dominds cert` | Create and inspect local WebUI HTTPS certificates | CLI |
|
|
35
37
|
| `dominds create` or `dominds new` | Create a new rtws (runtime workspace) from a template | CLI |
|
|
36
38
|
| `dominds help` | Show help message | CLI |
|
|
37
39
|
| `dominds --version` | Show version information | CLI |
|
|
@@ -54,6 +56,11 @@ dominds webui -C /path/to/my-rtws
|
|
|
54
56
|
# Minds reader: inspect team configuration
|
|
55
57
|
dominds read [options] [member-id]
|
|
56
58
|
|
|
59
|
+
# Certificate tools: create/inspect local HTTPS certificates
|
|
60
|
+
dominds cert create [--host <host>] [--days <days>] [--force]
|
|
61
|
+
dominds cert self-cert [--host <host>] [--days <days>] [--force]
|
|
62
|
+
dominds cert status --host <host> [--port <port>] [--origin]
|
|
63
|
+
|
|
57
64
|
# rtws creation: scaffold a new runtime workspace
|
|
58
65
|
dominds create <template> [directory]
|
|
59
66
|
dominds new <template> [directory] # alias for create
|
|
@@ -137,6 +144,35 @@ dominds read --only-prompt
|
|
|
137
144
|
dominds read --only-mem
|
|
138
145
|
```
|
|
139
146
|
|
|
147
|
+
### Certificate Tools
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
dominds cert create [--host <host>] [--days <days>] [--force]
|
|
151
|
+
dominds cert self-cert [--host <host>] [--days <days>] [--force]
|
|
152
|
+
dominds cert status --host <host> [--port <port>] [--origin]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Create or inspect local HTTPS certificates for the Dominds WebUI. Certificates live in `~/.dominds/certs/` and match DNS/IP hostnames, not ports; one certificate covers every WebUI port on that host.
|
|
156
|
+
|
|
157
|
+
**Options:**
|
|
158
|
+
|
|
159
|
+
- `--host <host>` - Certificate SAN hostname or IP; repeatable for certificate creation; defaults to one or more detected non-loopback LAN hosts
|
|
160
|
+
- `--days <days>` - Certificate validity in days (default: 3650, or 10 years)
|
|
161
|
+
- `--force` - Overwrite existing generated files
|
|
162
|
+
- `--port <port>` - Port used when formatting `status --origin`
|
|
163
|
+
- `--origin` - Print only the effective origin; HTTPS when a cert matches, HTTP otherwise
|
|
164
|
+
|
|
165
|
+
**Examples:**
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
dominds cert create
|
|
169
|
+
dominds cert create --host 192.168.1.10 --host my-host.local
|
|
170
|
+
dominds cert status --host 0.0.0.0
|
|
171
|
+
dominds cert status --host 0.0.0.0 --port 5666 --origin
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`localhost`, `loopback`, `127.0.0.0/8`, `::1`, `0.0.0.0`, and `::` are not certificate hosts. `0.0.0.0` / `::` only mean bind-all; certificate matching uses detected non-loopback LAN hosts.
|
|
175
|
+
|
|
140
176
|
### rtws Creation
|
|
141
177
|
|
|
142
178
|
```bash
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
- [Web UI 界面](#web-ui-界面)
|
|
19
19
|
- [文本用户界面 (TUI)(尚未实现)](#文本用户界面-tui尚未实现)
|
|
20
20
|
- [Minds 阅读器](#minds-阅读器)
|
|
21
|
+
- [证书工具](#证书工具)
|
|
21
22
|
- [rtws 创建](#rtws-创建)
|
|
22
23
|
- [使用示例](#使用示例)
|
|
23
24
|
- [对话存储](#对话存储)
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
| `dominds` 或 `dominds webui` | 启动 Web UI(默认、推荐) | Web UI |
|
|
33
34
|
| `dominds tui` 或 `dominds run` | 终端界面(规划中;当前版本暂不提供稳定) | N/A |
|
|
34
35
|
| `dominds read` | 读取/分析团队 minds 配置 | CLI |
|
|
36
|
+
| `dominds cert` | 创建/检查本机 WebUI HTTPS 证书 | CLI |
|
|
35
37
|
| `dominds create` 或 `dominds new` | 从模板创建新 rtws(运行时工作区) | CLI |
|
|
36
38
|
| `dominds help` | 显示帮助消息 | CLI |
|
|
37
39
|
| `dominds --version` | 显示版本信息 | CLI |
|
|
@@ -54,6 +56,11 @@ dominds webui -C /path/to/my-rtws
|
|
|
54
56
|
# Minds 阅读器:分析团队配置
|
|
55
57
|
dominds read [options] [member-id]
|
|
56
58
|
|
|
59
|
+
# 证书工具:创建/检查本机 HTTPS 证书
|
|
60
|
+
dominds cert create [--host <host>] [--days <days>] [--force]
|
|
61
|
+
dominds cert self-cert [--host <host>] [--days <days>] [--force]
|
|
62
|
+
dominds cert status --host <host> [--port <port>] [--origin]
|
|
63
|
+
|
|
57
64
|
# rtws 创建:搭建新项目/运行时工作区
|
|
58
65
|
dominds create <template> [directory]
|
|
59
66
|
dominds new <template> [directory] # create 的别名
|
|
@@ -144,6 +151,35 @@ dominds read --only-prompt
|
|
|
144
151
|
dominds read --only-mem
|
|
145
152
|
```
|
|
146
153
|
|
|
154
|
+
### 证书工具
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
dominds cert create [--host <host>] [--days <days>] [--force]
|
|
158
|
+
dominds cert self-cert [--host <host>] [--days <days>] [--force]
|
|
159
|
+
dominds cert status --host <host> [--port <port>] [--origin]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
创建或检查 Dominds WebUI 的本机 HTTPS 证书。证书保存在 `~/.dominds/certs/`,按 DNS/IP 主机名匹配,不绑定端口;同一张证书可覆盖该主机上的所有 WebUI 端口。
|
|
163
|
+
|
|
164
|
+
**选项:**
|
|
165
|
+
|
|
166
|
+
- `--host <host>` - 证书 SAN 主机名或 IP;创建证书时可重复指定;未指定时使用检测到的一个或多个非 loopback LAN 主机
|
|
167
|
+
- `--days <days>` - 证书有效天数(默认:3650,即 10 年)
|
|
168
|
+
- `--force` - 覆盖已有的同名生成文件
|
|
169
|
+
- `--port <port>` - `status --origin` 输出 URL 时使用的端口
|
|
170
|
+
- `--origin` - 仅输出有效访问 origin;找到证书时输出 HTTPS,否则输出 HTTP
|
|
171
|
+
|
|
172
|
+
**示例:**
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
dominds cert create
|
|
176
|
+
dominds cert create --host 192.168.1.10 --host my-host.local
|
|
177
|
+
dominds cert status --host 0.0.0.0
|
|
178
|
+
dominds cert status --host 0.0.0.0 --port 5666 --origin
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`localhost`、`loopback`、`127.0.0.0/8`、`::1`、`0.0.0.0`、`::` 不会作为 HTTPS 证书主机。`0.0.0.0` / `::` 只表示绑定所有地址,匹配证书时会使用检测到的非 loopback LAN 主机。
|
|
182
|
+
|
|
147
183
|
### rtws 创建
|
|
148
184
|
|
|
149
185
|
```bash
|
package/dist/server/auth.d.ts
CHANGED
|
@@ -37,7 +37,14 @@ export declare function isAuthEnabled(auth: AuthConfig): auth is Extract<AuthCon
|
|
|
37
37
|
export declare function getHttpAuthCheck(req: IncomingMessage, auth: AuthConfig): AuthCheckResult;
|
|
38
38
|
export declare function getHttpAuthCheckAllowUrlParam(req: IncomingMessage, auth: AuthConfig, requestUrl: URL): AuthCheckResult;
|
|
39
39
|
export declare function getWebSocketAuthCheck(req: IncomingMessage, auth: AuthConfig): AuthCheckResult;
|
|
40
|
+
export type ServerUrlScheme = 'http' | 'https';
|
|
41
|
+
export declare function formatServerOrigin(params: {
|
|
42
|
+
scheme: ServerUrlScheme;
|
|
43
|
+
host: string;
|
|
44
|
+
port: number;
|
|
45
|
+
}): string;
|
|
40
46
|
export declare function formatAutoAuthUrl(params: {
|
|
47
|
+
scheme?: ServerUrlScheme;
|
|
41
48
|
host: string;
|
|
42
49
|
port: number;
|
|
43
50
|
authKey: string;
|