@whoz-oss/coday-web 0.0.0-workstream-forge.205 → 0.0.0-workstream-forge.207
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/index.js +50 -1
- package/launcher.js +37 -2
- package/package.json +7 -4
package/index.js
CHANGED
|
@@ -4,7 +4,17 @@ import { dirname, resolve } from 'path';
|
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
5
|
import { spawn, spawnSync } from 'child_process';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
chooseMode,
|
|
9
|
+
nxArgs,
|
|
10
|
+
nxEnv,
|
|
11
|
+
parseWorkspaceDir,
|
|
12
|
+
resolveConfigDir,
|
|
13
|
+
serverArgs,
|
|
14
|
+
shouldRunDoctor,
|
|
15
|
+
wantsDoctorOnly,
|
|
16
|
+
withoutCommand,
|
|
17
|
+
} from './launcher.js';
|
|
8
18
|
|
|
9
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
20
|
const __dirname = dirname(__filename);
|
|
@@ -17,6 +27,9 @@ const __dirname = dirname(__filename);
|
|
|
17
27
|
* bundled `nx` on it, so the server, AgentOS and the Factory each get their own pane and log file.
|
|
18
28
|
* 3. No TTY (desktop apps), --managed or CODAY_NO_NX=1: runs everything inside the server process,
|
|
19
29
|
* exactly like before (it still prints `Server is running on http://localhost:PORT`).
|
|
30
|
+
*
|
|
31
|
+
* Before 2, it runs the `doctor` preflight (implemented in the bundled server, nothing duplicated here) so that a
|
|
32
|
+
* missing Java or an unwritable config directory is said in plain scrollback, not inside an Nx pane that scrolls away.
|
|
20
33
|
*/
|
|
21
34
|
|
|
22
35
|
// Create require function for resolving packages
|
|
@@ -151,7 +164,43 @@ function runNx() {
|
|
|
151
164
|
return undefined;
|
|
152
165
|
}
|
|
153
166
|
|
|
167
|
+
/**
|
|
168
|
+
* The exit code `doctor` uses for "a check blocks the start" (DOCTOR_BLOCKED_EXIT in
|
|
169
|
+
* apps/server/src/lib/runtime/doctor.ts). It is deliberately not 1: that is what the server exits with on any
|
|
170
|
+
* unhandled error, and a preflight that merely crashed must never be what stops Coday.
|
|
171
|
+
*/
|
|
172
|
+
const DOCTOR_BLOCKED_EXIT = 2;
|
|
173
|
+
|
|
174
|
+
/** Run the bundled server's `doctor`, inheriting the terminal so it prints its own report. */
|
|
175
|
+
function runDoctor(argv) {
|
|
176
|
+
return spawnSync(process.execPath, [serverMainPath, 'doctor', ...serverArgs(argv)], {
|
|
177
|
+
stdio: 'inherit',
|
|
178
|
+
env: process.env,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Preflight before the Nx TUI takes the terminal. Only a genuine blocker stops the start; anything else (a spawn
|
|
184
|
+
* error, a signal, a crash of the preflight itself) warns and carries on, like `runNx` falls back when the
|
|
185
|
+
* `workspace` command fails.
|
|
186
|
+
*/
|
|
187
|
+
function preflight() {
|
|
188
|
+
if (!shouldRunDoctor({ mode, argv: rawArgs, env: process.env })) return;
|
|
189
|
+
const result = runDoctor(rawArgs);
|
|
190
|
+
if (result.status === 0) return;
|
|
191
|
+
if (result.status === DOCTOR_BLOCKED_EXIT) process.exit(result.status);
|
|
192
|
+
const why = result.error?.message ?? (result.signal ? `killed by ${result.signal}` : `exit code ${result.status}`);
|
|
193
|
+
console.warn(`Preflight could not run (${why}): starting anyway.`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// `coday-web doctor`: the report is the whole job, whatever the terminal is.
|
|
197
|
+
if (wantsDoctorOnly(rawArgs)) {
|
|
198
|
+
const result = runDoctor(withoutCommand(rawArgs));
|
|
199
|
+
process.exit(result.error ? 1 : (result.status ?? 1));
|
|
200
|
+
}
|
|
201
|
+
|
|
154
202
|
console.log(`Coday Web: ${mode} mode (${reason})`);
|
|
203
|
+
preflight();
|
|
155
204
|
(mode === 'nx' ? Promise.resolve().then(runNx) : runManaged()).catch((error) => {
|
|
156
205
|
console.error('Failed to start server:', error);
|
|
157
206
|
process.exit(1);
|
package/launcher.js
CHANGED
|
@@ -34,9 +34,44 @@ export function resolveConfigDir(argv, home = homedir()) {
|
|
|
34
34
|
return join(home, '.coday');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/**
|
|
37
|
+
/** Flags the launcher handles itself; the server never sees them. Both `--flag` and `--flag=value` forms. */
|
|
38
|
+
const LAUNCHER_FLAGS = ['--managed', '--skip-doctor'];
|
|
39
|
+
|
|
40
|
+
const hasFlag = (argv, flag) => argv.some((a) => a === flag || a.startsWith(`${flag}=`));
|
|
41
|
+
|
|
42
|
+
/** The arguments the server must see: the launcher's own are removed. */
|
|
38
43
|
export function serverArgs(argv) {
|
|
39
|
-
return argv.filter((a) => a
|
|
44
|
+
return argv.filter((a) => !LAUNCHER_FLAGS.some((flag) => a === flag || a.startsWith(`${flag}=`)));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* `coday-web doctor`: run the preflight and nothing else. Same rule as the bundled server's `parseCommand` (the
|
|
49
|
+
* first positional wins), so the command means the same thing with or without a terminal — without this the Nx
|
|
50
|
+
* branch would print the report and then start the whole stack, which is not what anyone typing `doctor` wants.
|
|
51
|
+
*/
|
|
52
|
+
export function wantsDoctorOnly(argv) {
|
|
53
|
+
return argv.find((a) => !a.startsWith('-')) === 'doctor';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The same arguments without that leading command word, so it is not handed to the server twice. */
|
|
57
|
+
export function withoutCommand(argv) {
|
|
58
|
+
const at = argv.findIndex((a) => !a.startsWith('-'));
|
|
59
|
+
return at === -1 ? argv : [...argv.slice(0, at), ...argv.slice(at + 1)];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Whether to run the `doctor` preflight before starting.
|
|
64
|
+
*
|
|
65
|
+
* Only in `nx` mode, and for one reason: the Nx TUI is about to take the terminal, so a blocking problem must be said
|
|
66
|
+
* in plain scrollback first. The managed mode is the desktop apps, which have their own installer and show the same
|
|
67
|
+
* facts in the first-run wizard, so they are left alone (and spared the extra process).
|
|
68
|
+
*
|
|
69
|
+
* `--skip-doctor` / `CODAY_SKIP_DOCTOR=1` bypasses it, for anyone who knows better than the checks.
|
|
70
|
+
*/
|
|
71
|
+
export function shouldRunDoctor({ mode, argv, env }) {
|
|
72
|
+
if (mode !== 'nx') return false;
|
|
73
|
+
if (hasFlag(argv, '--skip-doctor')) return false;
|
|
74
|
+
return !(env.CODAY_SKIP_DOCTOR === '1' || env.CODAY_SKIP_DOCTOR === 'true');
|
|
40
75
|
}
|
|
41
76
|
|
|
42
77
|
/** Marker the server's `workspace` command prints before the directory it generated. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whoz-oss/coday-web",
|
|
3
|
-
"version": "0.0.0-workstream-forge.
|
|
3
|
+
"version": "0.0.0-workstream-forge.207",
|
|
4
4
|
"repository": "https://github.com/whoz-oss/coday",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,9 +13,12 @@
|
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"nx": "23.1.1",
|
|
16
|
-
"@whoz-oss/coday-client": "0.0.0-workstream-forge.
|
|
17
|
-
"@whoz-oss/coday-factory-cockpit": "0.0.0-workstream-forge.
|
|
18
|
-
"@whoz-oss/coday-server": "0.0.0-workstream-forge.
|
|
16
|
+
"@whoz-oss/coday-client": "0.0.0-workstream-forge.207",
|
|
17
|
+
"@whoz-oss/coday-factory-cockpit": "0.0.0-workstream-forge.207",
|
|
18
|
+
"@whoz-oss/coday-server": "0.0.0-workstream-forge.207"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
19
22
|
},
|
|
20
23
|
"publishConfig": {
|
|
21
24
|
"access": "public"
|