@whoz-oss/coday-web 0.0.0-workstream-setup.8 → 0.0.0-workstream-forge.142
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 +115 -204
- package/index.js +38 -85
- package/package.json +4 -6
- package/launcher.js +0 -75
package/README.md
CHANGED
|
@@ -1,246 +1,157 @@
|
|
|
1
1
|
# Coday Web Package
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
the Express server, and runs AgentOS and the Factory next to them.
|
|
3
|
+
This package provides the web interface launcher for Coday, bundling both the client (Angular app) and server components into a single executable package.
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Architecture
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
npx @whoz-oss/coday-web
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
In a terminal (Nx mode, see below) the browser opens by itself, always on **`/welcome`**
|
|
13
|
-
(`http://localhost:3000/welcome`), as soon as the Express server listens and whatever the install: that page only talks
|
|
14
|
-
to Coday's own server, so it does not wait for AgentOS. On a **first run** it is the wizard. Otherwise (setup done, or an
|
|
15
|
-
install without a wizard: `--auth`, an external AgentOS, an existing install without a wizard identity) it is a plain
|
|
16
|
-
loading page (download, Java, AgentOS, Factory: nothing that reads as a setup) that follows the startup and leads into
|
|
17
|
-
the app by itself as soon as AgentOS is up. With an external `AGENTOS_URL` / `FACTORY_URL` the page has nothing to
|
|
18
|
-
download or start for that service and only waits for it to answer. Pass `--no-open` or set `CODAY_NO_OPEN=1` to keep
|
|
19
|
-
the browser closed (it is also never opened with `--auth`, a non-loopback host or `CI`). Without a terminal
|
|
20
|
-
(`--managed`, desktop apps) nothing is opened: open the URL printed as `Server is running on http://localhost:PORT`
|
|
21
|
-
yourself. The wizard is a four-step flow:
|
|
22
|
-
|
|
23
|
-
1. **Your email.** It becomes your user ID and the AgentOS administrator. AgentOS and Factory JARs start downloading in
|
|
24
|
-
the background as soon as the page is open.
|
|
25
|
-
2. **Providers.** Anthropic, OpenAI and/or Requesty, each with an API key. With several, drag the cards (or use the
|
|
26
|
-
arrows) to rank them: rank 1 is preferred. At least one is required.
|
|
27
|
-
3. **Files folder.** Pick the folder your agent reads and writes (default `~/Coday`, created when missing).
|
|
28
|
-
4. **Checklist.** Download %, Java, AgentOS, providers, models, your personal namespace, the Coday agent, then
|
|
29
|
-
**Start with Coday**.
|
|
30
|
-
|
|
31
|
-
**Java 25 or newer is required** (AgentOS and Factory run on the JVM). When it is missing the wizard says so and shows the
|
|
32
|
-
install command for your system, then continues by itself.
|
|
33
|
-
|
|
34
|
-
Once done, `<configDir>/web-setup.json` holds `{ identity, setupDone }` (never an API key: the keys go to AgentOS only).
|
|
35
|
-
To run the wizard again on a real install, stop Coday and delete `web-setup.json` **and** `<configDir>/agentos/data`
|
|
36
|
-
(AgentOS fixes its administrator at its first boot). For the local stack of the monorepo, use `web:local -- --fresh`
|
|
37
|
-
instead (see below).
|
|
38
|
-
|
|
39
|
-
The command is always the same, `npx @whoz-oss/coday-web`, and it always opens `/welcome`: the wizard while the setup is
|
|
40
|
-
not done, the loading page and then the app afterwards. The page appears once the launcher has generated the Nx
|
|
41
|
-
workspace, run `provision` and started the `server` task, which takes a few seconds (the Nx startup is most of it); it
|
|
42
|
-
does not wait for the downloads, Java or the JVMs.
|
|
43
|
-
|
|
44
|
-
### AgentOS that already has data
|
|
45
|
-
|
|
46
|
-
The wizard's email is made the AgentOS administrator only when AgentOS boots on an **empty** database. Pointed at a
|
|
47
|
-
database that already holds users, that email is a plain user: it still gets its personal namespace (AgentOS creates it on
|
|
48
|
-
its first request), but only an administrator can create the platform providers and set the files folder, so the apply stops
|
|
49
|
-
on AgentOS's refusal with a message saying so. Use the administrator's email, or an empty `<configDir>/agentos/data`.
|
|
50
|
-
|
|
51
|
-
### Model prices
|
|
52
|
-
|
|
53
|
-
The four models of each provider are created with their price (USD per million tokens: input, output, cache read, and
|
|
54
|
-
cache write for Anthropic), so AgentOS can estimate costs. Re-running the setup adds the prices to models created
|
|
55
|
-
before. They come from the providers' price lists and live in `apps/server/src/lib/setup/model-catalogue.ts`; Claude
|
|
56
|
-
Haiku 5.5 is priced at its base tier (prompts up to 100k tokens).
|
|
57
|
-
|
|
58
|
-
## How it runs
|
|
7
|
+
The web package acts as a thin orchestration layer:
|
|
59
8
|
|
|
60
9
|
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
│
|
|
70
|
-
|
|
71
|
-
|
|
10
|
+
┌─────────────────────────────────────────┐
|
|
11
|
+
│ coday-web (index.js) │
|
|
12
|
+
│ ┌───────────────────────────────────┐ │
|
|
13
|
+
│ │ 1. Resolve client package path │ │
|
|
14
|
+
│ │ 2. Set CODAY_CLIENT_PATH env var │ │
|
|
15
|
+
│ │ 3. Import and run server │ │
|
|
16
|
+
│ └───────────────────────────────────┘ │
|
|
17
|
+
└─────────────────────────────────────────┘
|
|
18
|
+
│
|
|
19
|
+
┌───────────┴───────────┐
|
|
20
|
+
▼ ▼
|
|
21
|
+
┌──────────────┐ ┌──────────────┐
|
|
22
|
+
│ coday-server │ │ coday-client │
|
|
23
|
+
│ (Express) │───────▶│ (Angular) │
|
|
24
|
+
└──────────────┘ └──────────────┘
|
|
72
25
|
```
|
|
73
26
|
|
|
74
|
-
|
|
75
|
-
(no daemon, no cloud, no cache) and runs the bundled `nx`. `provision` is a quick task (profile, secrets, Java check,
|
|
76
|
-
ports → `runtime/state.json`); `status`, `server`, `agentos` and `factory` are continuous tasks, each with its own
|
|
77
|
-
pane. The launcher runs ONE target, `nx run coday:status`, and `status` depends on the three services, so Nx starts
|
|
78
|
-
them for it. `agentos` prints *Waiting for first-run setup → http://localhost:3000/welcome* until you gave your email;
|
|
79
|
-
`factory` waits for AgentOS to be healthy. As soon as Express listens, the `server` task opens the browser on
|
|
80
|
-
`/welcome` (see *First run*); it never does when `--auth`, a non-loopback `--host`, `CI`, `--no-open` or
|
|
81
|
-
`CODAY_NO_OPEN` say so. Nothing waits for AgentOS before opening: the page shows the progress itself. For an external
|
|
82
|
-
AgentOS (`AGENTOS_URL`) / Factory (`FACTORY_URL`) the setup API probes those URLs, which is what the proxy targets.
|
|
83
|
-
- **The `status` pane.** The Nx TUI has no status bar, so a small dedicated task reads `runtime/state.json` and probes
|
|
84
|
-
the health URLs every second. It prints one line per meaningful change only: `agentos download 42%` (one line per
|
|
85
|
-
10%), `java ok` or the install hint, `agentos healthy :8224`, `factory healthy :8241`, `agentos external <origin>`
|
|
86
|
-
for an `AGENTOS_URL`/`FACTORY_URL`, and `Open -> http://localhost:3000/welcome` (the same line whatever the profile and
|
|
87
|
-
the setup state, same URL as the browser). In the
|
|
88
|
-
TUI, select a pane and pin it next to another one to keep the download and the URL on screen while you read the
|
|
89
|
-
logs of the others; press `?` for the key help of the Nx TUI. At startup `status` is pinned next to `server`: Nx
|
|
90
|
-
pins the initiating task and its first continuous dependency, but only for a single-target run (`nx run`), which is
|
|
91
|
-
why the launcher does not use `run-many`. That behaviour was derived from reading the Nx 23 sources (the native
|
|
92
|
-
TUI rendering of pinned panes could not be inspected): confirm it visually.
|
|
93
|
-
Because `status` depends on the services, none of them may exit while it runs (Nx would report an exited
|
|
94
|
-
dependency as crashed, and a failed one would skip `status`): a service that cannot start (no Java, download
|
|
95
|
-
failed, port taken) or that is external (`AGENTOS_URL`/`FACTORY_URL`) prints why and stays open until Ctrl+C.
|
|
96
|
-
- **Managed mode** (no TTY, `--managed`, or `CODAY_NO_NX=1`). Same code, one process, no Nx. The desktop apps spawn
|
|
97
|
-
`coday-web` without a terminal and keep working unchanged.
|
|
98
|
-
|
|
99
|
-
All the logic lives in the server package (`apps/server/src/lib/runtime`, `lib/setup`); the Nx workspace is only a
|
|
100
|
-
manifest calling `coday-server provision|agentos|factory|server|status`.
|
|
101
|
-
|
|
102
|
-
### Ports
|
|
103
|
-
|
|
104
|
-
The packaged stack prefers its own ports: **AgentOS 8224, Factory 8241, AgentOS embedded Neo4j Bolt 7788** (each falls
|
|
105
|
-
back to the next free port, the choice is written to `runtime/state.json`). The dev ports **8124 (AgentOS), 8141
|
|
106
|
-
(Factory) and 7688 (Bolt) are reserved for dev mode** (`pnpm web:serve:dev`, `bootRun`), so a packaged instance and a
|
|
107
|
-
dev stack run side by side without colliding or picking up each other's services.
|
|
108
|
-
|
|
109
|
-
### Logs
|
|
110
|
-
|
|
111
|
-
Each process writes to its own file, in addition to its pane / the console:
|
|
27
|
+
## Usage Modes
|
|
112
28
|
|
|
113
|
-
|
|
114
|
-
<configDir>/logs/server.log
|
|
115
|
-
<configDir>/logs/agentos.log
|
|
116
|
-
<configDir>/logs/factory.log
|
|
117
|
-
```
|
|
29
|
+
### Production Mode (Published Package)
|
|
118
30
|
|
|
119
|
-
|
|
31
|
+
Use the published npm package via npx:
|
|
120
32
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
`--server.address=127.0.0.1`, Factory `FACTORY_BIND_HOST=127.0.0.1`. AgentOS and Factory run with
|
|
125
|
-
`*_SECURITY_MODE=auth`. Secrets (`FACTORY_FAKE_IDP_SECRET`, AgentOS and Factory encryption key/salt) are generated once into
|
|
126
|
-
`<configDir>/runtime/secrets.json` (mode `0600`). An install that already holds unencrypted data keeps `NONE` for that
|
|
127
|
-
service and logs a warning (encrypting existing data is a manual migration).
|
|
128
|
-
|
|
129
|
-
The first-run setup API (`/api/setup/*`: folder browser, apply) only answers loopback callers and is disabled once the
|
|
130
|
-
setup is done. Deployments (`--auth`), an external AgentOS (`AGENTOS_URL`), an imposed `AGENTOS_EXTERNAL_USERID` and
|
|
131
|
-
existing installs without a wizard identity keep their previous behaviour: no wizard, no redirect.
|
|
33
|
+
```bash
|
|
34
|
+
# Using the published package
|
|
35
|
+
pnpm web
|
|
132
36
|
|
|
133
|
-
|
|
37
|
+
# Or directly with npx
|
|
38
|
+
npx @whoz-oss/coday-web --no_auth
|
|
39
|
+
```
|
|
134
40
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| `--managed` / `CODAY_NO_NX=1` | Force the single-process mode (no Nx) |
|
|
140
|
-
| `--no-open` / `CODAY_NO_OPEN=1` | Do not open the browser on start (only Nx mode opens it; never with `--auth`, a non-loopback host or `CI`) |
|
|
141
|
-
| `PORT` | Express port (strict when set; default 3000, 4100 in dev) |
|
|
142
|
-
| `AGENTOS_URL`, `FACTORY_URL` | Use an external AgentOS / Factory instead of managed ones |
|
|
143
|
-
| `AGENTOS_EXTERNAL_USERID` | Impose the identity forwarded to AgentOS (disables the wizard) |
|
|
144
|
-
| `CODAY_AGENTOS_VERSION`, `CODAY_FACTORY_VERSION` | JAR version to run (`dev` = JARs placed by hand in `<configDir>/{agentos,factory}`) |
|
|
145
|
-
| `CODAY_DEFAULT_FILES_DIR` | Folder proposed by the wizard instead of `~/Coday` |
|
|
146
|
-
| `CODAY_CLIENT_PATH`, `CODAY_FACTORY_COCKPIT_PATH` | Set by the launcher: where the static apps are |
|
|
147
|
-
| `BUILD_ENV=development` | Dev mode (proxy to the Angular dev servers) |
|
|
41
|
+
In production mode:
|
|
42
|
+
- The web launcher resolves the client package from node_modules
|
|
43
|
+
- Server serves pre-built static files from the client package
|
|
44
|
+
- Single process handles both server and client
|
|
148
45
|
|
|
149
|
-
|
|
46
|
+
### Development Mode (Local Sources)
|
|
150
47
|
|
|
151
|
-
|
|
152
|
-
is:
|
|
48
|
+
For development with live reload and local sources:
|
|
153
49
|
|
|
154
50
|
```bash
|
|
155
|
-
|
|
156
|
-
pnpm
|
|
157
|
-
pnpm nx run web:local -- --managed # single process, plain console (instead of the Nx TUI)
|
|
158
|
-
pnpm nx run web:local -- --no-open # do not open the browser (every restart would otherwise open a tab)
|
|
159
|
-
pnpm nx run web:local -- --port 3100 # pick the port
|
|
51
|
+
# Start both client and server in development mode
|
|
52
|
+
pnpm web:dev
|
|
160
53
|
```
|
|
161
54
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
55
|
+
This command:
|
|
56
|
+
- Starts the Angular dev server on port 4200 (with HMR)
|
|
57
|
+
- Starts the Express server on port 4100 (with tsx watch)
|
|
58
|
+
- Server proxies non-API requests to Angular dev server
|
|
59
|
+
- Changes to client or server code trigger automatic reloads
|
|
165
60
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Every run re-packs and re-installs (the code may have changed), overwrites the `dev`-layout JARs in
|
|
175
|
-
`config/{agentos,factory}` (`agentos-service-dev.jar`, plugins in `plugins/`; the data directories are left alone) and
|
|
176
|
-
runs the installed `coday-web --configDir ~/.coday-local/config` with `CODAY_AGENTOS_VERSION=dev
|
|
177
|
-
CODAY_FACTORY_VERSION=dev`. It prints every path and whether this is a **first run** (no `setupDone` in
|
|
178
|
-
`web-setup.json`) or a **resume**. Your `~/.coday` and `~/Coday` are never touched (the script refuses a root that is, or
|
|
179
|
-
lies in, them, your home or the repository), and nothing is published.
|
|
180
|
-
|
|
181
|
-
| Option / env | Effect |
|
|
182
|
-
|---|---|
|
|
183
|
-
| `--fresh` | Delete `config/` and `files/` (printed) before starting: a brand-new first run |
|
|
184
|
-
| `--managed`, `--port <n>` | Single-process mode, Express port |
|
|
185
|
-
| `--no-open` | Do not open the browser (also `CODAY_NO_OPEN=1`) |
|
|
186
|
-
| `--prepare-only` | Prepare everything, print the paths as JSON on the last line, no server |
|
|
187
|
-
| `--clean` | Delete the **whole** root when the server stops (setup and data included) |
|
|
188
|
-
| `CODAY_LOCAL_DIR=<dir>` | Use another root than `~/.coday-local` (`CODAY_FIRST_RUN_DIR` is a deprecated alias) |
|
|
61
|
+
**How it works in dev mode:**
|
|
62
|
+
1. Client runs with Angular CLI dev server (localhost:4200)
|
|
63
|
+
2. Server runs with tsx watch (localhost:4100)
|
|
64
|
+
3. Server detects `BUILD_ENV=development` and proxies to Angular
|
|
65
|
+
4. API routes (e.g., `/api/*`) are handled by the server
|
|
66
|
+
5. All other routes are proxied to Angular for client-side routing
|
|
189
67
|
|
|
190
|
-
|
|
68
|
+
## Development Workflow
|
|
191
69
|
|
|
192
|
-
|
|
193
|
-
(dummy keys, no LLM call) and checks the providers, models, personal namespace, Coday agent and shared folder through
|
|
194
|
-
the AgentOS REST API. It runs `web:local --fresh` on its own throwaway root (`FIRST_RUN_E2E_DIR` to choose it, it never
|
|
195
|
-
reads `CODAY_LOCAL_DIR`) and skips itself, with a reason, when Java 25 or the built JARs are missing.
|
|
70
|
+
### Running Individual Services
|
|
196
71
|
|
|
197
|
-
|
|
72
|
+
You can also run services separately for debugging:
|
|
198
73
|
|
|
199
74
|
```bash
|
|
200
|
-
|
|
201
|
-
pnpm
|
|
202
|
-
|
|
203
|
-
|
|
75
|
+
# Run only the client (Angular dev server)
|
|
76
|
+
pnpm client
|
|
77
|
+
|
|
78
|
+
# Run only the server (Express with tsx watch)
|
|
79
|
+
pnpm server
|
|
204
80
|
```
|
|
205
81
|
|
|
206
|
-
|
|
207
|
-
`web:dev-server` (Express, 4100), `web:dev-agentos` (`agentos-service:bootRun`, 8124) and `web:dev-factory`
|
|
208
|
-
(`factory-service:bootRun`, 8141). These are the dev-only ports; the packaged stack uses 8224 / 8241 (see *Ports*). The dev server uses the
|
|
209
|
-
external-service mode (`AGENTOS_URL`/`FACTORY_URL`), so the wizard is not shown: use `web:local -- --fresh` to test it.
|
|
82
|
+
### Building for Production
|
|
210
83
|
|
|
211
|
-
|
|
84
|
+
The web package depends on built client and server packages:
|
|
212
85
|
|
|
213
86
|
```bash
|
|
214
|
-
|
|
215
|
-
pnpm nx run-many
|
|
87
|
+
# Build all packages
|
|
88
|
+
pnpm nx run-many --target=build --projects=client,server,web
|
|
89
|
+
|
|
90
|
+
# Or build everything
|
|
91
|
+
pnpm nx run-many --target=build --all
|
|
216
92
|
```
|
|
217
93
|
|
|
218
|
-
|
|
94
|
+
### Testing Changes
|
|
95
|
+
|
|
96
|
+
When making changes to the web launcher:
|
|
97
|
+
|
|
98
|
+
1. Modify `apps/web/index.js`
|
|
99
|
+
2. Test with local server: `node apps/web/index.js --no_auth`
|
|
100
|
+
3. Verify client resolution works correctly
|
|
101
|
+
4. Check that server starts and serves the client
|
|
102
|
+
|
|
103
|
+
## Environment Variables
|
|
104
|
+
|
|
105
|
+
- `CODAY_CLIENT_PATH`: Set by the web launcher to tell server where client files are
|
|
106
|
+
- `BUILD_ENV`: Set to `development` by server's serve target for dev mode
|
|
107
|
+
- `PORT`: Override default server port (default: 3000 production, 4100 dev)
|
|
108
|
+
|
|
109
|
+
## Package Dependencies
|
|
219
110
|
|
|
220
111
|
```json
|
|
221
112
|
{
|
|
222
113
|
"@whoz-oss/coday-client": "workspace:*",
|
|
223
|
-
"@whoz-oss/coday-
|
|
224
|
-
"@whoz-oss/coday-server": "workspace:*",
|
|
225
|
-
"nx": "catalog:dev"
|
|
114
|
+
"@whoz-oss/coday-server": "workspace:*"
|
|
226
115
|
}
|
|
227
116
|
```
|
|
228
117
|
|
|
229
|
-
|
|
230
|
-
than the former thin launcher. Versions of the `platform:npm` packages move in lockstep: never edit them by hand.
|
|
118
|
+
These use workspace protocol in development and resolve to specific versions when published.
|
|
231
119
|
|
|
232
120
|
## Troubleshooting
|
|
233
121
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
122
|
+
### "Could not resolve @whoz-oss/coday-client package"
|
|
123
|
+
|
|
124
|
+
This means the client package isn't built or installed:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# In development
|
|
128
|
+
pnpm install
|
|
129
|
+
pnpm nx run client:build
|
|
130
|
+
|
|
131
|
+
# Or use the web:dev command which doesn't require builds
|
|
132
|
+
pnpm web:dev
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### "Failed to start server"
|
|
136
|
+
|
|
137
|
+
Check that all dependencies are installed:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
pnpm install
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Development mode not proxying correctly
|
|
144
|
+
|
|
145
|
+
Ensure both services are running:
|
|
146
|
+
1. Angular dev server should be on port 4200
|
|
147
|
+
2. Express server should be on port 4100
|
|
148
|
+
3. Access the app via http://localhost:4100
|
|
149
|
+
|
|
150
|
+
## Quick Reference
|
|
151
|
+
|
|
152
|
+
| Command | Mode | Ports | Use Case |
|
|
153
|
+
|---------|------|-------|----------|
|
|
154
|
+
| `pnpm web` | Production | 3000 | Testing published package |
|
|
155
|
+
| `pnpm web:dev` | Development | 4100→4200 | Active development |
|
|
156
|
+
| `pnpm client` | Development | 4200 | Client-only work |
|
|
157
|
+
| `pnpm server` | Development | 4100 | Server-only work |
|
package/index.js
CHANGED
|
@@ -2,30 +2,30 @@
|
|
|
2
2
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
3
3
|
import { dirname, resolve } from 'path';
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
|
-
import { spawn, spawnSync } from 'child_process';
|
|
6
5
|
import { createRequire } from 'module';
|
|
7
|
-
import { chooseMode, nxArgs, nxEnv, parseWorkspaceDir, resolveConfigDir, serverArgs } from './launcher.js';
|
|
8
6
|
|
|
9
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
8
|
const __dirname = dirname(__filename);
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Coday Web Launcher
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* 3.
|
|
19
|
-
* exactly like before (it still prints `Server is running on http://localhost:PORT`).
|
|
12
|
+
*
|
|
13
|
+
* This script orchestrates the web interface by:
|
|
14
|
+
* 1. Resolving the client package location at runtime
|
|
15
|
+
* 2. Setting the client path for the server to use
|
|
16
|
+
* 3. Delegating execution to the server package
|
|
20
17
|
*/
|
|
21
18
|
|
|
22
19
|
// Create require function for resolving packages
|
|
23
20
|
const require = createRequire(import.meta.url);
|
|
24
21
|
|
|
25
22
|
/**
|
|
26
|
-
* Resolve
|
|
23
|
+
* Resolve the client package location
|
|
24
|
+
*
|
|
25
|
+
* Tries multiple resolution strategies:
|
|
27
26
|
* 1. Standard node_modules resolution (production/npx)
|
|
28
|
-
* 2.
|
|
27
|
+
* 2. Workspace protocol resolution (development)
|
|
28
|
+
* 3. Relative path fallback (monorepo development)
|
|
29
29
|
*/
|
|
30
30
|
function resolveStaticPackagePath(packageName, developmentPath, displayName) {
|
|
31
31
|
const developmentBrowserPath = resolve(__dirname, developmentPath);
|
|
@@ -65,27 +65,7 @@ function resolveStaticPackagePath(packageName, developmentPath, displayName) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
const serverPackagePath = require.resolve('@whoz-oss/coday-server/package.json');
|
|
71
|
-
const packagedServerMainPath = resolve(dirname(serverPackagePath), 'server.js');
|
|
72
|
-
const developmentServerMainPath = resolve(__dirname, '../server/dist/server.js');
|
|
73
|
-
const serverMainPath = existsSync(packagedServerMainPath) ? packagedServerMainPath : developmentServerMainPath;
|
|
74
|
-
if (!existsSync(serverMainPath)) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
`Server entry point is missing. Checked paths: ${packagedServerMainPath}, ${developmentServerMainPath}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
return serverMainPath;
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.error('Could not resolve @whoz-oss/coday-server package.');
|
|
82
|
-
console.error('Please ensure dependencies are installed: pnpm install');
|
|
83
|
-
console.error('Error:', error.message);
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Resolve and expose static application paths to the server (and, through env inheritance, to every Nx task).
|
|
68
|
+
// Resolve and expose static application paths to the server.
|
|
89
69
|
const clientPath = resolveStaticPackagePath('@whoz-oss/coday-client', '../client/dist/browser', 'Client');
|
|
90
70
|
const factoryCockpitPath = resolveStaticPackagePath(
|
|
91
71
|
'@whoz-oss/coday-factory-cockpit',
|
|
@@ -98,61 +78,34 @@ process.env.CODAY_FACTORY_COCKPIT_PATH = factoryCockpitPath;
|
|
|
98
78
|
console.log(`Coday Web: Using client files from ${clientPath}`);
|
|
99
79
|
console.log(`Coday Web: Using factory cockpit files from ${factoryCockpitPath}`);
|
|
100
80
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
nxBin = require.resolve('nx/bin/nx.js');
|
|
118
|
-
} catch (error) {
|
|
119
|
-
console.warn(`Nx is not available (${error.message}): falling back to the in-process mode.`);
|
|
120
|
-
return runManaged();
|
|
81
|
+
// Import and run the server
|
|
82
|
+
// The server package exports its main module which starts the server
|
|
83
|
+
try {
|
|
84
|
+
// Try to resolve the server package
|
|
85
|
+
const serverPackagePath = require.resolve('@whoz-oss/coday-server/package.json');
|
|
86
|
+
const serverDir = dirname(serverPackagePath);
|
|
87
|
+
const packagedServerMainPath = resolve(serverDir, 'server.js');
|
|
88
|
+
const developmentServerMainPath = resolve(__dirname, '../server/dist/server.js');
|
|
89
|
+
const serverMainPath = existsSync(packagedServerMainPath)
|
|
90
|
+
? packagedServerMainPath
|
|
91
|
+
: developmentServerMainPath;
|
|
92
|
+
|
|
93
|
+
if (!existsSync(serverMainPath)) {
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Server entry point is missing. Checked paths: ${packagedServerMainPath}, ${developmentServerMainPath}`
|
|
96
|
+
);
|
|
121
97
|
}
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
});
|
|
129
|
-
const workspaceDir = parseWorkspaceDir(generated.stdout);
|
|
130
|
-
if (generated.status !== 0 || !workspaceDir || !existsSync(workspaceDir)) {
|
|
131
|
-
console.error('Could not generate the runtime workspace; falling back to the in-process mode.');
|
|
132
|
-
return runManaged();
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
console.log(`Coday Web: runtime workspace ${workspaceDir} (logs in ${resolve(configDir, 'logs')})`);
|
|
136
|
-
|
|
137
|
-
// 2. Run the continuous tasks. Nx draws one pane per process, in the terminal.
|
|
138
|
-
const nx = spawn(process.execPath, [nxBin, ...nxArgs()], {
|
|
139
|
-
cwd: workspaceDir,
|
|
140
|
-
env: nxEnv(process.env, configDir),
|
|
141
|
-
stdio: 'inherit',
|
|
142
|
-
});
|
|
143
|
-
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
|
|
144
|
-
process.on(signal, () => nx.kill(signal));
|
|
145
|
-
}
|
|
146
|
-
nx.on('error', (error) => {
|
|
147
|
-
console.error('Failed to start nx:', error.message);
|
|
98
|
+
|
|
99
|
+
// Import the server module
|
|
100
|
+
// Convert Windows absolute path to file:// URL for ESM import
|
|
101
|
+
const serverModuleURL = pathToFileURL(serverMainPath).href;
|
|
102
|
+
import(serverModuleURL).catch((error) => {
|
|
103
|
+
console.error('Failed to start server:', error);
|
|
148
104
|
process.exit(1);
|
|
149
105
|
});
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
console.log(`Coday Web: ${mode} mode (${reason})`);
|
|
155
|
-
(mode === 'nx' ? Promise.resolve().then(runNx) : runManaged()).catch((error) => {
|
|
156
|
-
console.error('Failed to start server:', error);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('Could not resolve @whoz-oss/coday-server package.');
|
|
108
|
+
console.error('Please ensure dependencies are installed: pnpm install');
|
|
109
|
+
console.error('Error:', error.message);
|
|
157
110
|
process.exit(1);
|
|
158
|
-
}
|
|
111
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whoz-oss/coday-web",
|
|
3
|
-
"version": "0.0.0-workstream-
|
|
3
|
+
"version": "0.0.0-workstream-forge.142",
|
|
4
4
|
"repository": "https://github.com/whoz-oss/coday",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,14 +8,12 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"index.js",
|
|
11
|
-
"launcher.js",
|
|
12
11
|
"README.md"
|
|
13
12
|
],
|
|
14
13
|
"dependencies": {
|
|
15
|
-
"
|
|
16
|
-
"@whoz-oss/coday-factory-cockpit": "0.0.0-workstream-
|
|
17
|
-
"@whoz-oss/coday-server": "0.0.0-workstream-
|
|
18
|
-
"@whoz-oss/coday-client": "0.0.0-workstream-setup.8"
|
|
14
|
+
"@whoz-oss/coday-client": "0.0.0-workstream-forge.142",
|
|
15
|
+
"@whoz-oss/coday-factory-cockpit": "0.0.0-workstream-forge.142",
|
|
16
|
+
"@whoz-oss/coday-server": "0.0.0-workstream-forge.142"
|
|
19
17
|
},
|
|
20
18
|
"publishConfig": {
|
|
21
19
|
"access": "public"
|
package/launcher.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure helpers of the coday-web launcher (no side effects at import time).
|
|
3
|
-
* Tested with `node --test` (see launcher.test.js, run by the `web:test` Nx target).
|
|
4
|
-
*/
|
|
5
|
-
import { homedir } from 'os';
|
|
6
|
-
import { join } from 'path';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Decide how to run: `nx` (generated workspace, one pane per process) or `managed` (everything in the
|
|
10
|
-
* server process, which is what the desktop apps need).
|
|
11
|
-
*
|
|
12
|
-
* managed when: `--managed` flag, `CODAY_NO_NX=1`, or stdout is not a TTY (desktop apps spawn us
|
|
13
|
-
* without one, and the Nx TUI needs a terminal anyway).
|
|
14
|
-
*/
|
|
15
|
-
export function chooseMode({ argv, env, isTTY }) {
|
|
16
|
-
if (argv.includes('--managed')) return { mode: 'managed', reason: '--managed flag' };
|
|
17
|
-
if (env.CODAY_NO_NX === '1' || env.CODAY_NO_NX === 'true') return { mode: 'managed', reason: 'CODAY_NO_NX is set' };
|
|
18
|
-
if (!isTTY) return { mode: 'managed', reason: 'no TTY (desktop app, CI, pipe)' };
|
|
19
|
-
return { mode: 'nx', reason: 'interactive terminal' };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** `--configDir <dir>` / `--configDir=<dir>` / `--coday_config_dir ...`, default `~/.coday`. */
|
|
23
|
-
export function resolveConfigDir(argv, home = homedir()) {
|
|
24
|
-
for (let i = 0; i < argv.length; i++) {
|
|
25
|
-
const arg = argv[i];
|
|
26
|
-
for (const flag of ['--configDir', '--coday_config_dir']) {
|
|
27
|
-
if (arg === flag && argv[i + 1]) return argv[i + 1];
|
|
28
|
-
if (arg.startsWith(`${flag}=`)) return arg.slice(flag.length + 1);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return join(home, '.coday');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** The arguments the server must see: the launcher's own (`--managed`) are removed. */
|
|
35
|
-
export function serverArgs(argv) {
|
|
36
|
-
return argv.filter((a) => a !== '--managed');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** Marker the server's `workspace` command prints before the directory it generated. */
|
|
40
|
-
export const WORKSPACE_MARKER = 'CODAY_RUNTIME_WORKSPACE=';
|
|
41
|
-
|
|
42
|
-
/** The generated workspace directory, found among any other stdout lines; undefined when absent. */
|
|
43
|
-
export function parseWorkspaceDir(stdout) {
|
|
44
|
-
const line = String(stdout ?? '')
|
|
45
|
-
.split('\n')
|
|
46
|
-
.map((l) => l.trim())
|
|
47
|
-
.reverse()
|
|
48
|
-
.find((l) => l.startsWith(WORKSPACE_MARKER));
|
|
49
|
-
const dir = line?.slice(WORKSPACE_MARKER.length).trim();
|
|
50
|
-
return dir || undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Arguments of `nx run`: ONE target, `coday:status`, whose continuous dependencies are the server, AgentOS and the
|
|
55
|
-
* Factory (each gets its own TUI pane). A single-target run makes the Nx TUI pin the initiating task (`status`) and
|
|
56
|
-
* its first continuous dependency (`server`) at startup; `run-many` pins nothing. The target names are those of
|
|
57
|
-
* NX_ENTRY_TASK / NX_SERVICES in apps/server/src/lib/runtime/workspace.ts (a server spec checks they match).
|
|
58
|
-
* `--parallel` only caps discrete tasks (`provision`): continuous tasks have their own threads.
|
|
59
|
-
*/
|
|
60
|
-
export function nxArgs() {
|
|
61
|
-
return ['run', 'coday:status', '--parallel=5', '--outputStyle=tui'];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Environment of the Nx process: no daemon, no cloud, no cache. */
|
|
65
|
-
export function nxEnv(env, configDir) {
|
|
66
|
-
return {
|
|
67
|
-
...env,
|
|
68
|
-
NX_DAEMON: 'false',
|
|
69
|
-
NX_NO_CLOUD: 'true',
|
|
70
|
-
NX_SKIP_NX_CACHE: 'true',
|
|
71
|
-
NX_TUI: 'true',
|
|
72
|
-
NX_WORKSPACE_DATA_DIRECTORY: join(configDir, 'runtime', '.nx'),
|
|
73
|
-
NX_CACHE_DIRECTORY: join(configDir, 'runtime', '.nx', 'cache'),
|
|
74
|
-
};
|
|
75
|
-
}
|