@very_aq/codex-cli-web 0.0.1
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/LICENSE +21 -0
- package/README.md +228 -0
- package/README.zh-CN.md +228 -0
- package/package.json +38 -0
- package/server/dist/admin/userAdminRoutes.d.ts +7 -0
- package/server/dist/admin/userAdminRoutes.js +91 -0
- package/server/dist/admin/userAdminRoutes.js.map +1 -0
- package/server/dist/app.d.ts +22 -0
- package/server/dist/app.js +993 -0
- package/server/dist/app.js.map +1 -0
- package/server/dist/auth/adminInit.d.ts +41 -0
- package/server/dist/auth/adminInit.js +126 -0
- package/server/dist/auth/adminInit.js.map +1 -0
- package/server/dist/auth/bootstrapAdmin.d.ts +6 -0
- package/server/dist/auth/bootstrapAdmin.js +11 -0
- package/server/dist/auth/bootstrapAdmin.js.map +1 -0
- package/server/dist/auth/httpAuth.d.ts +16 -0
- package/server/dist/auth/httpAuth.js +31 -0
- package/server/dist/auth/httpAuth.js.map +1 -0
- package/server/dist/auth/password.d.ts +2 -0
- package/server/dist/auth/password.js +68 -0
- package/server/dist/auth/password.js.map +1 -0
- package/server/dist/auth/requireAdmin.d.ts +2 -0
- package/server/dist/auth/requireAdmin.js +14 -0
- package/server/dist/auth/requireAdmin.js.map +1 -0
- package/server/dist/auth/roles.d.ts +3 -0
- package/server/dist/auth/roles.js +13 -0
- package/server/dist/auth/roles.js.map +1 -0
- package/server/dist/auth/session.d.ts +24 -0
- package/server/dist/auth/session.js +127 -0
- package/server/dist/auth/session.js.map +1 -0
- package/server/dist/auth/sqlite/authDb.d.ts +18 -0
- package/server/dist/auth/sqlite/authDb.js +26 -0
- package/server/dist/auth/sqlite/authDb.js.map +1 -0
- package/server/dist/auth/sqlite/legacyImport.d.ts +22 -0
- package/server/dist/auth/sqlite/legacyImport.js +208 -0
- package/server/dist/auth/sqlite/legacyImport.js.map +1 -0
- package/server/dist/auth/sqlite/schema.d.ts +11 -0
- package/server/dist/auth/sqlite/schema.js +47 -0
- package/server/dist/auth/sqlite/schema.js.map +1 -0
- package/server/dist/auth/sqlite/sqliteUserStore.d.ts +12 -0
- package/server/dist/auth/sqlite/sqliteUserStore.js +194 -0
- package/server/dist/auth/sqlite/sqliteUserStore.js.map +1 -0
- package/server/dist/auth/userStore.d.ts +19 -0
- package/server/dist/auth/userStore.js +26 -0
- package/server/dist/auth/userStore.js.map +1 -0
- package/server/dist/auth/userTypes.d.ts +13 -0
- package/server/dist/auth/userTypes.js +3 -0
- package/server/dist/auth/userTypes.js.map +1 -0
- package/server/dist/chat/attachmentPathRedaction.d.ts +5 -0
- package/server/dist/chat/attachmentPathRedaction.js +67 -0
- package/server/dist/chat/attachmentPathRedaction.js.map +1 -0
- package/server/dist/chat/chatItemEnricher.d.ts +5 -0
- package/server/dist/chat/chatItemEnricher.js +40 -0
- package/server/dist/chat/chatItemEnricher.js.map +1 -0
- package/server/dist/chat/codexEventProjector.d.ts +33 -0
- package/server/dist/chat/codexEventProjector.js +482 -0
- package/server/dist/chat/codexEventProjector.js.map +1 -0
- package/server/dist/chat/contextUsageProjector.d.ts +10 -0
- package/server/dist/chat/contextUsageProjector.js +472 -0
- package/server/dist/chat/contextUsageProjector.js.map +1 -0
- package/server/dist/chat/fileChangeExtractor.d.ts +5 -0
- package/server/dist/chat/fileChangeExtractor.js +121 -0
- package/server/dist/chat/fileChangeExtractor.js.map +1 -0
- package/server/dist/chat/markdown/markdownAst.d.ts +5 -0
- package/server/dist/chat/markdown/markdownAst.js +154 -0
- package/server/dist/chat/markdown/markdownAst.js.map +1 -0
- package/server/dist/chat/systemToolCallSummary.d.ts +10 -0
- package/server/dist/chat/systemToolCallSummary.js +112 -0
- package/server/dist/chat/systemToolCallSummary.js.map +1 -0
- package/server/dist/chat/terminal/terminalPlainText.d.ts +14 -0
- package/server/dist/chat/terminal/terminalPlainText.js +139 -0
- package/server/dist/chat/terminal/terminalPlainText.js.map +1 -0
- package/server/dist/chat/textMetrics.d.ts +9 -0
- package/server/dist/chat/textMetrics.js +24 -0
- package/server/dist/chat/textMetrics.js.map +1 -0
- package/server/dist/chat/threadTurnsProjector.d.ts +12 -0
- package/server/dist/chat/threadTurnsProjector.js +292 -0
- package/server/dist/chat/threadTurnsProjector.js.map +1 -0
- package/server/dist/chat/todoPlanProjector.d.ts +8 -0
- package/server/dist/chat/todoPlanProjector.js +94 -0
- package/server/dist/chat/todoPlanProjector.js.map +1 -0
- package/server/dist/chat/todoPlanTypes.d.ts +21 -0
- package/server/dist/chat/todoPlanTypes.js +3 -0
- package/server/dist/chat/todoPlanTypes.js.map +1 -0
- package/server/dist/chat/types.d.ts +138 -0
- package/server/dist/chat/types.js +3 -0
- package/server/dist/chat/types.js.map +1 -0
- package/server/dist/cli/configArg.d.ts +21 -0
- package/server/dist/cli/configArg.js +70 -0
- package/server/dist/cli/configArg.js.map +1 -0
- package/server/dist/codex/appServerProcess.d.ts +24 -0
- package/server/dist/codex/appServerProcess.js +56 -0
- package/server/dist/codex/appServerProcess.js.map +1 -0
- package/server/dist/codex/cliArgs.d.ts +17 -0
- package/server/dist/codex/cliArgs.js +34 -0
- package/server/dist/codex/cliArgs.js.map +1 -0
- package/server/dist/codex/codexAppServer.d.ts +103 -0
- package/server/dist/codex/codexAppServer.js +206 -0
- package/server/dist/codex/codexAppServer.js.map +1 -0
- package/server/dist/codex/jsonl.d.ts +4 -0
- package/server/dist/codex/jsonl.js +23 -0
- package/server/dist/codex/jsonl.js.map +1 -0
- package/server/dist/codex/jsonrpc.d.ts +43 -0
- package/server/dist/codex/jsonrpc.js +96 -0
- package/server/dist/codex/jsonrpc.js.map +1 -0
- package/server/dist/config/serverConfig.d.ts +150 -0
- package/server/dist/config/serverConfig.js +64 -0
- package/server/dist/config/serverConfig.js.map +1 -0
- package/server/dist/env.d.ts +101 -0
- package/server/dist/env.js +523 -0
- package/server/dist/env.js.map +1 -0
- package/server/dist/history/http/historyRoutes.d.ts +18 -0
- package/server/dist/history/http/historyRoutes.js +67 -0
- package/server/dist/history/http/historyRoutes.js.map +1 -0
- package/server/dist/history/index.d.ts +24 -0
- package/server/dist/history/index.js +30 -0
- package/server/dist/history/index.js.map +1 -0
- package/server/dist/history/ingest/historyIngestService.d.ts +15 -0
- package/server/dist/history/ingest/historyIngestService.js +42 -0
- package/server/dist/history/ingest/historyIngestService.js.map +1 -0
- package/server/dist/history/projector/extractIds.d.ts +36 -0
- package/server/dist/history/projector/extractIds.js +111 -0
- package/server/dist/history/projector/extractIds.js.map +1 -0
- package/server/dist/history/projector/projectCodexEvent.d.ts +27 -0
- package/server/dist/history/projector/projectCodexEvent.js +845 -0
- package/server/dist/history/projector/projectCodexEvent.js.map +1 -0
- package/server/dist/history/query/historyQueryService.d.ts +34 -0
- package/server/dist/history/query/historyQueryService.js +170 -0
- package/server/dist/history/query/historyQueryService.js.map +1 -0
- package/server/dist/history/sqlite/schema.d.ts +11 -0
- package/server/dist/history/sqlite/schema.js +34 -0
- package/server/dist/history/sqlite/schema.js.map +1 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.d.ts +69 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.js +206 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.js.map +1 -0
- package/server/dist/history/types.d.ts +29 -0
- package/server/dist/history/types.js +3 -0
- package/server/dist/history/types.js.map +1 -0
- package/server/dist/index.d.ts +1 -0
- package/server/dist/index.js +166 -0
- package/server/dist/index.js.map +1 -0
- package/server/dist/security/executionPolicy.d.ts +33 -0
- package/server/dist/security/executionPolicy.js +72 -0
- package/server/dist/security/executionPolicy.js.map +1 -0
- package/server/dist/security/origin.d.ts +11 -0
- package/server/dist/security/origin.js +40 -0
- package/server/dist/security/origin.js.map +1 -0
- package/server/dist/settings/sqliteUserSettingsStore.d.ts +12 -0
- package/server/dist/settings/sqliteUserSettingsStore.js +62 -0
- package/server/dist/settings/sqliteUserSettingsStore.js.map +1 -0
- package/server/dist/settings/userSettingsRoutes.d.ts +8 -0
- package/server/dist/settings/userSettingsRoutes.js +55 -0
- package/server/dist/settings/userSettingsRoutes.js.map +1 -0
- package/server/dist/settings/userSettingsStore.d.ts +19 -0
- package/server/dist/settings/userSettingsStore.js +26 -0
- package/server/dist/settings/userSettingsStore.js.map +1 -0
- package/server/dist/settings/userSettingsTypes.d.ts +70 -0
- package/server/dist/settings/userSettingsTypes.js +196 -0
- package/server/dist/settings/userSettingsTypes.js.map +1 -0
- package/server/dist/status/codexTaskTracker.d.ts +21 -0
- package/server/dist/status/codexTaskTracker.js +123 -0
- package/server/dist/status/codexTaskTracker.js.map +1 -0
- package/server/dist/status/threadContextUsage.d.ts +19 -0
- package/server/dist/status/threadContextUsage.js +229 -0
- package/server/dist/status/threadContextUsage.js.map +1 -0
- package/server/dist/threadList/threadListServerCache.d.ts +10 -0
- package/server/dist/threadList/threadListServerCache.js +42 -0
- package/server/dist/threadList/threadListServerCache.js.map +1 -0
- package/server/dist/tools/cwdSuggest.d.ts +11 -0
- package/server/dist/tools/cwdSuggest.js +128 -0
- package/server/dist/tools/cwdSuggest.js.map +1 -0
- package/server/dist/workspace/accessControl.d.ts +16 -0
- package/server/dist/workspace/accessControl.js +82 -0
- package/server/dist/workspace/accessControl.js.map +1 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.d.ts +12 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.js +82 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.js.map +1 -0
- package/server/dist/workspace/threadAccess.d.ts +19 -0
- package/server/dist/workspace/threadAccess.js +22 -0
- package/server/dist/workspace/threadAccess.js.map +1 -0
- package/server/dist/workspace/threadListVisibility.d.ts +25 -0
- package/server/dist/workspace/threadListVisibility.js +104 -0
- package/server/dist/workspace/threadListVisibility.js.map +1 -0
- package/server/dist/workspace/userWorkspaceRoutes.d.ts +7 -0
- package/server/dist/workspace/userWorkspaceRoutes.js +124 -0
- package/server/dist/workspace/userWorkspaceRoutes.js.map +1 -0
- package/server/dist/workspace/userWorkspaceStore.d.ts +12 -0
- package/server/dist/workspace/userWorkspaceStore.js +23 -0
- package/server/dist/workspace/userWorkspaceStore.js.map +1 -0
- package/server/dist/ws/socketIoBridge.d.ts +32 -0
- package/server/dist/ws/socketIoBridge.js +194 -0
- package/server/dist/ws/socketIoBridge.js.map +1 -0
- package/server/dist/ws/types.d.ts +113 -0
- package/server/dist/ws/types.js +3 -0
- package/server/dist/ws/types.js.map +1 -0
- package/server/dist/ws/wsHub.d.ts +119 -0
- package/server/dist/ws/wsHub.js +1259 -0
- package/server/dist/ws/wsHub.js.map +1 -0
- package/web/dist/assets/index-CY6cnwQz.js +174 -0
- package/web/dist/assets/index-DI7kJHr2.css +32 -0
- package/web/dist/favicon-mask.svg +9 -0
- package/web/dist/favicon.svg +26 -0
- package/web/dist/index.html +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 codex-cli-web contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# codex-cli-web
|
|
2
|
+
|
|
3
|
+
> Local-first Web UI for Codex CLI, powered by `codex app-server` (JSON-RPC over stdio).
|
|
4
|
+
|
|
5
|
+
English | [简体中文](README.zh-CN.md)
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Highlights](#highlights)
|
|
10
|
+
- [Quickstart](#quickstart)
|
|
11
|
+
- [Web UI](#web-ui)
|
|
12
|
+
- [Configuration](#configuration)
|
|
13
|
+
- [Authentication and Multi-user](#authentication-and-multi-user)
|
|
14
|
+
- [History (SQLite)](#history-sqlite)
|
|
15
|
+
- [Uploads](#uploads)
|
|
16
|
+
- [Development](#development)
|
|
17
|
+
- [Contributing](#contributing)
|
|
18
|
+
- [Security](#security)
|
|
19
|
+
- [License](#license)
|
|
20
|
+
|
|
21
|
+
## Highlights
|
|
22
|
+
|
|
23
|
+
- Integrates with a locally installed `codex` CLI (this repository does not bundle Codex).
|
|
24
|
+
- Loopback-first network defaults (`127.0.0.1`) to reduce accidental exposure during local deployment.
|
|
25
|
+
- Multi-user authentication with admin-assigned workspace boundaries.
|
|
26
|
+
- Single-entry runtime configuration via `CODEX_CONFIG` (JSON string or JSON file path).
|
|
27
|
+
- SQLite-backed history pipeline (disable with `CODEX_WEB_HISTORY_MODE=off`).
|
|
28
|
+
|
|
29
|
+
## Quickstart
|
|
30
|
+
|
|
31
|
+
### Requirements
|
|
32
|
+
|
|
33
|
+
- Node.js 18+
|
|
34
|
+
- `codex` CLI installed and available on `PATH` (`codex --help` should work)
|
|
35
|
+
|
|
36
|
+
### Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm ci
|
|
40
|
+
# or: npm install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Run in development
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm run dev
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then open `http://127.0.0.1:5173`.
|
|
50
|
+
|
|
51
|
+
Dev mode uses:
|
|
52
|
+
|
|
53
|
+
- Web server: `127.0.0.1:8787`
|
|
54
|
+
- Vite UI: `127.0.0.1:5173`
|
|
55
|
+
- Proxy: `/api`, `/ws`, and `/socket.io` to the server
|
|
56
|
+
|
|
57
|
+
### Build and run (production)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run build
|
|
61
|
+
npm start
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Then open `http://127.0.0.1:8787`.
|
|
65
|
+
|
|
66
|
+
By default the server binds to loopback (`127.0.0.1`). To expose on LAN:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
CODEX_WEB_HOST=0.0.0.0 npm start
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Note: the server refuses to bind to a non-loopback host until admin initialization is completed on loopback.
|
|
73
|
+
Start on loopback first, complete the admin initialization flow in the Web UI, then restart with `CODEX_WEB_HOST=0.0.0.0`.
|
|
74
|
+
|
|
75
|
+
### Use as an npm CLI (`ccw`)
|
|
76
|
+
|
|
77
|
+
This section applies after the package is published to npm (or installed via npm from a local path).
|
|
78
|
+
|
|
79
|
+
With `npx` (no global install):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx -p codex-cli-web ccw --config ./config.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Global install:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install -g codex-cli-web
|
|
89
|
+
ccw --config ./config.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If you run from a git checkout and `ccw` fails with "missing `server/dist/index.js`", run:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm run build
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Web UI
|
|
99
|
+
|
|
100
|
+
This section describes the main Web UI entry points (matching the current runtime UI).
|
|
101
|
+
|
|
102
|
+

|
|
103
|
+
|
|
104
|
+
### Workspaces (workspace rail)
|
|
105
|
+
|
|
106
|
+
- The left workspace rail shows available workspace dirs (rendered as an initial letter or `/`). Click to switch the active workspace.
|
|
107
|
+
- The active workspace affects:
|
|
108
|
+
- Which threads are shown in the sidebar list
|
|
109
|
+
- The default `cwd` used when creating a new thread
|
|
110
|
+
|
|
111
|
+
### Sidebar (threads + settings)
|
|
112
|
+
|
|
113
|
+
- Primary actions: `New thread`, `Settings`.
|
|
114
|
+
- The `Settings` panel includes common actions like refresh thread list, logout, theme/locale toggles, accent/background colors, and compact view; admins also get a user management entry.
|
|
115
|
+
- Thread cards show the derived title, model provider, and last activity time; the archive button archives a thread.
|
|
116
|
+
|
|
117
|
+
### Main area and composer
|
|
118
|
+
|
|
119
|
+
- Header shortcuts: refresh current thread, quick new thread, view file changes (Changes), context usage, and WS connection status.
|
|
120
|
+
- The composer toolbar supports:
|
|
121
|
+
- Plan / Model / Reasoning effort (click to cycle)
|
|
122
|
+
- File uploads (pasting images also triggers upload)
|
|
123
|
+
- Type `/` for the slash command menu (or `/help`)
|
|
124
|
+
- Type `$` for the skills picker (loaded from the server)
|
|
125
|
+
|
|
126
|
+
## Configuration
|
|
127
|
+
|
|
128
|
+
### Config precedence
|
|
129
|
+
|
|
130
|
+
Runtime config is resolved in this order:
|
|
131
|
+
|
|
132
|
+
1. Environment variables
|
|
133
|
+
2. `CODEX_CONFIG` (inline JSON or a JSON file path)
|
|
134
|
+
3. Built-in defaults (`server/src/config/serverConfig.ts`)
|
|
135
|
+
|
|
136
|
+
### `CODEX_CONFIG` (single-entry config)
|
|
137
|
+
|
|
138
|
+
`CODEX_CONFIG` supports two forms:
|
|
139
|
+
|
|
140
|
+
- Inline JSON: `CODEX_CONFIG='{\"web\":{\"port\":9000}}' npm start`
|
|
141
|
+
- JSON file path: `CODEX_CONFIG=./config.json npm start`
|
|
142
|
+
|
|
143
|
+
This repository includes a commented example file: `config.json`.
|
|
144
|
+
|
|
145
|
+
### CLI config flag
|
|
146
|
+
|
|
147
|
+
The server parses a config flag at startup and maps it to `CODEX_CONFIG`:
|
|
148
|
+
|
|
149
|
+
- `--config ./config.json`
|
|
150
|
+
- `---config ./config.json` (compat)
|
|
151
|
+
- `--config=./config.json` (same)
|
|
152
|
+
- `---config=./config.json` (same)
|
|
153
|
+
|
|
154
|
+
### Common environment variables
|
|
155
|
+
|
|
156
|
+
- Web: `CODEX_WEB_HOST`, `CODEX_WEB_PORT`
|
|
157
|
+
- Auth: `SESSION_TOKEN`, `CODEX_WEB_AUTH_DB_PATH`
|
|
158
|
+
- Codex: `CODEX_BIN`, `CODEX_CWD`, `CODEX_ALLOWED_CWD_ROOTS`, `CODEX_APPROVAL_POLICY`, `CODEX_SANDBOX_MODE`, `CODEX_HISTORY_PERSISTENCE`, `CODEX_DISABLE_RESPONSE_STORAGE`
|
|
159
|
+
- Legacy import (optional): `CODEX_WEB_USERS_FILE`, `CODEX_WEB_USER_WORKSPACES_FILE`
|
|
160
|
+
- History: `CODEX_WEB_HISTORY_MODE`, `CODEX_WEB_HISTORY_DB_PATH`
|
|
161
|
+
- Uploads: `CODEX_WEB_UPLOAD_BASE_DIR`, `CODEX_WEB_MAX_UPLOAD_BYTES`
|
|
162
|
+
- `CODEX_CWD` is the base directory for relative cwd resolution, and is used when a new thread does not provide `cwd`.
|
|
163
|
+
|
|
164
|
+
### Thread loading
|
|
165
|
+
|
|
166
|
+
- `CODEX_WEB_OPEN_THREAD_TURNS_LIMIT`: max turns included when opening a thread (default: unlimited, equivalent to `Number.MAX_SAFE_INTEGER` / `9007199254740991`; set a number to cap the initial payload; set `all`, `unlimited`, or `infinite` to explicitly disable the cap).
|
|
167
|
+
|
|
168
|
+
## Authentication and Multi-user
|
|
169
|
+
|
|
170
|
+
This server supports multiple users with per-user workspace isolation.
|
|
171
|
+
|
|
172
|
+
- Admin initialization:
|
|
173
|
+
- On first install, no admin account is pre-created (the server does not auto-create `admin/pass`).
|
|
174
|
+
- The first visit to the login page enters the setup flow (backed by `POST /api/auth/bootstrap-admin/setup`), where you choose the admin username and password (minimum length: 8).
|
|
175
|
+
- Before setup is completed, the server refuses to bind to a non-loopback host (for example `0.0.0.0`).
|
|
176
|
+
- `pass` is only a legacy-compatibility marker for upgrade scenarios; it is not a usable default password on fresh installs, and setup rejects `pass` as a new password.
|
|
177
|
+
- Auth/settings DB: users, assigned workspaces, user-created workspace dirs, and per-user UI preferences are stored in SQLite.
|
|
178
|
+
- Override path with `CODEX_WEB_AUTH_DB_PATH` (default: `~/.codex_cli_web/auth.db`).
|
|
179
|
+
- Two workspace concepts (decoupled):
|
|
180
|
+
- `auth workspaces`: permission roots assigned by admin (returned by `/api/auth/me` as `workspaces`).
|
|
181
|
+
- `user-created workspaceDirs`: user-saved concrete cwd list (managed by `/api/workspaces/user-created`).
|
|
182
|
+
- Workspace isolation: non-admin users can only operate within workspaces assigned by admin.
|
|
183
|
+
- Enforced on both HTTP endpoints and WebSocket actions.
|
|
184
|
+
- Member access is enforced against admin-assigned `workspaces` only (it does not intersect with `CODEX_ALLOWED_CWD_ROOTS`).
|
|
185
|
+
|
|
186
|
+
## History (SQLite)
|
|
187
|
+
|
|
188
|
+
The web server can persist session history to SQLite.
|
|
189
|
+
|
|
190
|
+
- `CODEX_WEB_HISTORY_MODE`: `off` / `shadow` / `primary` (`shadow` is accepted for compatibility and currently behaves like `primary`)
|
|
191
|
+
- `CODEX_WEB_HISTORY_DB_PATH`: SQLite path (default: `~/.codex_cli_web/history.db`; relative paths resolve from repo/workspace root)
|
|
192
|
+
|
|
193
|
+
## Uploads
|
|
194
|
+
|
|
195
|
+
- `CODEX_WEB_UPLOAD_BASE_DIR`: upload base directory (default: `<CODEX_CWD>/.codex-web/uploads`, relative paths resolve from `CODEX_CWD`)
|
|
196
|
+
- `CODEX_WEB_MAX_UPLOAD_BYTES`: max bytes for a single file (default: `104857600` = 100MB)
|
|
197
|
+
|
|
198
|
+
## Development
|
|
199
|
+
|
|
200
|
+
### Commands
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run dev # run server + web in development mode
|
|
204
|
+
npm run build # build web then server
|
|
205
|
+
npm start # start built server
|
|
206
|
+
npm test # run server tests (Vitest)
|
|
207
|
+
npm run codex:generate # regenerate Codex protocol TS types (requires codex on PATH)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Project structure
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
server/ # Node/TypeScript app server, Codex process integration
|
|
214
|
+
web/ # React + Vite UI
|
|
215
|
+
docs/ # plans and project documents
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Contributing
|
|
219
|
+
|
|
220
|
+
See `CONTRIBUTING.md`.
|
|
221
|
+
|
|
222
|
+
## Security
|
|
223
|
+
|
|
224
|
+
See `SECURITY.md`.
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
This project is licensed under the MIT License. See `LICENSE`.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# codex-cli-web
|
|
2
|
+
|
|
3
|
+
> 面向 Codex CLI 的本机优先 Web UI,底层基于 `codex app-server`(通过 stdio 的 JSON-RPC)。
|
|
4
|
+
|
|
5
|
+
简体中文 | [English](README.md)
|
|
6
|
+
|
|
7
|
+
## 目录
|
|
8
|
+
|
|
9
|
+
- [亮点](#亮点)
|
|
10
|
+
- [快速开始](#快速开始)
|
|
11
|
+
- [Web UI](#web-ui)
|
|
12
|
+
- [配置](#配置)
|
|
13
|
+
- [认证与多用户](#认证与多用户)
|
|
14
|
+
- [历史(SQLite)](#历史sqlite)
|
|
15
|
+
- [上传](#上传)
|
|
16
|
+
- [开发](#开发)
|
|
17
|
+
- [开源协作](#开源协作)
|
|
18
|
+
- [安全策略](#安全策略)
|
|
19
|
+
- [许可证](#许可证)
|
|
20
|
+
|
|
21
|
+
## 亮点
|
|
22
|
+
|
|
23
|
+
- 对接本机已安装的 `codex` CLI(本仓库不内置 Codex)。
|
|
24
|
+
- 默认仅监听回环地址(`127.0.0.1`),降低本地部署时误对外暴露风险。
|
|
25
|
+
- 支持多用户认证,并按管理员分配的 workspace 边界隔离权限。
|
|
26
|
+
- 支持 `CODEX_CONFIG` 单入口运行时配置(内联 JSON 或 JSON 文件路径)。
|
|
27
|
+
- 提供 SQLite 历史链路(可通过 `CODEX_WEB_HISTORY_MODE=off` 关闭)。
|
|
28
|
+
|
|
29
|
+
## 快速开始
|
|
30
|
+
|
|
31
|
+
### 环境要求
|
|
32
|
+
|
|
33
|
+
- Node.js 18+
|
|
34
|
+
- 已安装并可执行 `codex` CLI(`codex --help` 可用)
|
|
35
|
+
|
|
36
|
+
### 安装依赖
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm ci
|
|
40
|
+
# 或:npm install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 开发模式启动
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm run dev
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
浏览器打开 `http://127.0.0.1:5173`。
|
|
50
|
+
|
|
51
|
+
开发模式默认:
|
|
52
|
+
|
|
53
|
+
- Web 服务:`127.0.0.1:8787`
|
|
54
|
+
- Vite 前端:`127.0.0.1:5173`
|
|
55
|
+
- 代理:`/api`、`/ws`、`/socket.io` 转发到服务端
|
|
56
|
+
|
|
57
|
+
### 构建与运行(生产模式)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run build
|
|
61
|
+
npm start
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
浏览器打开 `http://127.0.0.1:8787`。
|
|
65
|
+
|
|
66
|
+
默认仅监听回环地址(`127.0.0.1`)。如果要对局域网开放:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
CODEX_WEB_HOST=0.0.0.0 npm start
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
注意:管理员初始化未完成(或仍存在默认口令账号)时,服务会拒绝监听非回环地址。
|
|
73
|
+
建议先用回环地址启动,在 Web UI 完成管理员初始化后,再用 `CODEX_WEB_HOST=0.0.0.0` 重启。
|
|
74
|
+
|
|
75
|
+
### 作为 npm CLI 使用(`ccw`)
|
|
76
|
+
|
|
77
|
+
本节适用于“已发布到 npm 后”,或通过 npm 从本地路径安装包的场景。
|
|
78
|
+
|
|
79
|
+
使用 `npx`(无需全局安装):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx -p codex-cli-web ccw --config ./config.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
全局安装:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install -g codex-cli-web
|
|
89
|
+
ccw --config ./config.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
如果你是直接从 git 仓库运行,且 `ccw` 提示缺少 `server/dist/index.js`,先执行:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm run build
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Web UI
|
|
99
|
+
|
|
100
|
+
本节用于对齐当前 Web UI 的主要功能入口(与你提供的运行截图一致)。
|
|
101
|
+
|
|
102
|
+

|
|
103
|
+
|
|
104
|
+
### 工作区(Workspace rail)
|
|
105
|
+
|
|
106
|
+
- 左侧竖向轨道展示“可用工作区”列表(按目录名首字母/`/` 显示),点击可切换当前工作区。
|
|
107
|
+
- 当前工作区会影响:
|
|
108
|
+
- 侧栏线程列表的过滤范围;
|
|
109
|
+
- 新建线程默认使用的 `cwd`。
|
|
110
|
+
|
|
111
|
+
### 侧栏(线程 + 设置)
|
|
112
|
+
|
|
113
|
+
- 侧栏主入口:`新线程`、`设置`。
|
|
114
|
+
- `设置` 面板包含常用操作:刷新线程列表、登出、主题/语言切换、颜色(Accent/Background)、紧凑视图;管理员额外提供“用户管理”入口。
|
|
115
|
+
- 线程卡片展示:标题、模型提供方(model provider)、更新时间;右侧归档按钮可将线程归档。
|
|
116
|
+
|
|
117
|
+
### 主区与输入框
|
|
118
|
+
|
|
119
|
+
- 顶部常用按钮:刷新当前线程、快速新建线程、查看文件变更(Changes)、上下文使用率、WS 连接状态。
|
|
120
|
+
- 输入框工具栏支持:
|
|
121
|
+
- Plan / Model / Reasoning effort(可点击循环切换);
|
|
122
|
+
- 附件上传(也支持直接粘贴图片触发上传);
|
|
123
|
+
- 输入 `/` 打开 slash 命令菜单(也可用 `/help` 查看帮助);
|
|
124
|
+
- 输入 `$` 打开 skills 选择(会从服务端加载可用 skills)。
|
|
125
|
+
|
|
126
|
+
## 配置
|
|
127
|
+
|
|
128
|
+
### 配置优先级
|
|
129
|
+
|
|
130
|
+
运行时配置按以下顺序解析:
|
|
131
|
+
|
|
132
|
+
1. 环境变量
|
|
133
|
+
2. `CODEX_CONFIG`(内联 JSON 或 JSON 文件路径)
|
|
134
|
+
3. 内置默认值(`server/src/config/serverConfig.ts`)
|
|
135
|
+
|
|
136
|
+
### `CODEX_CONFIG`(单入口配置)
|
|
137
|
+
|
|
138
|
+
`CODEX_CONFIG` 支持两种形式:
|
|
139
|
+
|
|
140
|
+
- 内联 JSON:`CODEX_CONFIG='{\"web\":{\"port\":9000}}' npm start`
|
|
141
|
+
- JSON 文件路径:`CODEX_CONFIG=./config.json npm start`
|
|
142
|
+
|
|
143
|
+
本仓库提供了带 `+comment` 字段注释的示例文件:`config.json`。
|
|
144
|
+
|
|
145
|
+
### CLI 启动参数
|
|
146
|
+
|
|
147
|
+
服务端启动时会解析 config 参数,并同步到环境变量 `CODEX_CONFIG`:
|
|
148
|
+
|
|
149
|
+
- `--config ./config.json`
|
|
150
|
+
- `---config ./config.json`(兼容写法)
|
|
151
|
+
- `--config=./config.json`(等价写法)
|
|
152
|
+
- `---config=./config.json`(等价写法)
|
|
153
|
+
|
|
154
|
+
### 常用环境变量
|
|
155
|
+
|
|
156
|
+
- Web:`CODEX_WEB_HOST`、`CODEX_WEB_PORT`
|
|
157
|
+
- 认证:`SESSION_TOKEN`、`CODEX_WEB_AUTH_DB_PATH`
|
|
158
|
+
- Codex:`CODEX_BIN`、`CODEX_CWD`、`CODEX_ALLOWED_CWD_ROOTS`、`CODEX_APPROVAL_POLICY`、`CODEX_SANDBOX_MODE`、`CODEX_HISTORY_PERSISTENCE`、`CODEX_DISABLE_RESPONSE_STORAGE`
|
|
159
|
+
- 兼容导入(可选):`CODEX_WEB_USERS_FILE`、`CODEX_WEB_USER_WORKSPACES_FILE`
|
|
160
|
+
- 历史:`CODEX_WEB_HISTORY_MODE`、`CODEX_WEB_HISTORY_DB_PATH`
|
|
161
|
+
- 上传:`CODEX_WEB_UPLOAD_BASE_DIR`、`CODEX_WEB_MAX_UPLOAD_BYTES`
|
|
162
|
+
- `CODEX_CWD` 用于相对路径解析基准;新建线程未显式提供 `cwd` 时会使用该目录。
|
|
163
|
+
|
|
164
|
+
### 打开线程 turns 上限
|
|
165
|
+
|
|
166
|
+
- `CODEX_WEB_OPEN_THREAD_TURNS_LIMIT`:打开线程时首包返回的 turns 数量上限(默认不限制,等价于 `Number.MAX_SAFE_INTEGER` / `9007199254740991`;设置为数字可限制首包体积;设置为 `all`、`unlimited` 或 `infinite` 也可显式取消限制)。
|
|
167
|
+
|
|
168
|
+
## 认证与多用户
|
|
169
|
+
|
|
170
|
+
服务端支持多用户认证,并对不同用户的工作区权限进行隔离。
|
|
171
|
+
|
|
172
|
+
- 管理员初始化:
|
|
173
|
+
- 首次安装后,系统不会预置任何管理员账号(不会自动创建 `admin/pass`)。
|
|
174
|
+
- 首次打开登录页会进入初始化流程(后端接口 `POST /api/auth/bootstrap-admin/setup`),由你自行创建管理员用户名和密码(密码最少 8 位)。
|
|
175
|
+
- 在初始化完成前,服务拒绝监听非回环地址(例如 `0.0.0.0`)。
|
|
176
|
+
- `pass` 仅用于旧版本升级场景下的弱口令兼容检测,不是新安装时的默认可用密码;初始化流程也不允许把新密码设置为 `pass`。
|
|
177
|
+
- 认证/设置 DB:用户、工作区分配、用户自建工作目录、UI 偏好等都会持久化到 SQLite。
|
|
178
|
+
- 可用 `CODEX_WEB_AUTH_DB_PATH` 覆盖路径(默认:`<CODEX_CWD>/.codex-web/auth.db`)。
|
|
179
|
+
- 两个工作区概念(解耦):
|
|
180
|
+
- `auth workspaces`:管理员分配的权限根目录(`/api/auth/me` 的 `workspaces` 字段)。
|
|
181
|
+
- `user-created workspaceDirs`:用户保存的具体 cwd 列表(`/api/workspaces/user-created`)。
|
|
182
|
+
- 工作区隔离:非管理员只能在管理员分配的 workspaces 内操作。
|
|
183
|
+
- 同时在 HTTP 与 WebSocket 行为中强制校验。
|
|
184
|
+
- member 的访问边界只以管理员分配的 `workspaces` 为准(不会与 `CODEX_ALLOWED_CWD_ROOTS` 再取交集)。
|
|
185
|
+
|
|
186
|
+
## 历史(SQLite)
|
|
187
|
+
|
|
188
|
+
Web 服务可以将会话历史持久化到 SQLite。
|
|
189
|
+
|
|
190
|
+
- `CODEX_WEB_HISTORY_MODE`:`off` / `shadow` / `primary`(`shadow` 为兼容值,当前行为与 `primary` 一致)
|
|
191
|
+
- `CODEX_WEB_HISTORY_DB_PATH`:SQLite 文件路径(默认:`.codex-web/history.db`;相对路径以仓库/工作区根目录解析)
|
|
192
|
+
|
|
193
|
+
## 上传
|
|
194
|
+
|
|
195
|
+
- `CODEX_WEB_UPLOAD_BASE_DIR`:上传根目录(默认:`<CODEX_CWD>/.codex-web/uploads`;相对路径以 `CODEX_CWD` 解析)
|
|
196
|
+
- `CODEX_WEB_MAX_UPLOAD_BYTES`:单文件上限(默认:`104857600`,即 100MB)
|
|
197
|
+
|
|
198
|
+
## 开发
|
|
199
|
+
|
|
200
|
+
### 常用命令
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run dev # 同时启动 server + web(开发模式)
|
|
204
|
+
npm run build # 先构建 web,再构建 server
|
|
205
|
+
npm start # 启动构建后的服务
|
|
206
|
+
npm test # 运行 server 侧测试(Vitest)
|
|
207
|
+
npm run codex:generate # 重新生成 Codex 协议 TS 类型(需要 codex 在 PATH)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 目录结构
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
server/ # Node/TypeScript 服务端,负责对接 Codex 进程
|
|
214
|
+
web/ # React + Vite 前端
|
|
215
|
+
docs/ # 计划与项目文档
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## 开源协作
|
|
219
|
+
|
|
220
|
+
参见 `CONTRIBUTING.md`。
|
|
221
|
+
|
|
222
|
+
## 安全策略
|
|
223
|
+
|
|
224
|
+
参见 `SECURITY.md`。
|
|
225
|
+
|
|
226
|
+
## 许可证
|
|
227
|
+
|
|
228
|
+
本项目采用 MIT 许可证,详见 `LICENSE`。
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@very_aq/codex-cli-web",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"bin": {
|
|
6
|
+
"ccw": "bin/ccw"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/ccw",
|
|
10
|
+
"server/dist",
|
|
11
|
+
"web/dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"workspaces": [
|
|
15
|
+
"server",
|
|
16
|
+
"web"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "concurrently -n server,web -c blue,green --kill-others-on-fail \"npm -w server run dev\" \"wait-on http-get://127.0.0.1:8787/api/health && npm -w web run dev\"",
|
|
20
|
+
"build": "npm -w web run build && npm -w server run build",
|
|
21
|
+
"codex:generate": "npm -w server run codex:generate",
|
|
22
|
+
"start": "node server/dist/index.js",
|
|
23
|
+
"test": "npm -w server test",
|
|
24
|
+
"prepack": "npm run build",
|
|
25
|
+
"pack": "npm pack"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"better-sqlite3": "^11.8.1",
|
|
29
|
+
"busboy": "^1.6.0",
|
|
30
|
+
"express": "^4.19.2",
|
|
31
|
+
"socket.io": "^4.8.3",
|
|
32
|
+
"ws": "^8.17.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"concurrently": "^9.1.2",
|
|
36
|
+
"wait-on": "^8.0.5"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
exports.createUserAdminRoutes = createUserAdminRoutes;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const requireAdmin_1 = require("../auth/requireAdmin");
|
|
11
|
+
function toPublicUser(user) {
|
|
12
|
+
const { passwordHash: _passwordHash, ...rest } = user;
|
|
13
|
+
return rest;
|
|
14
|
+
}
|
|
15
|
+
function normalizeUsername(username) {
|
|
16
|
+
return String(username ?? "").trim();
|
|
17
|
+
}
|
|
18
|
+
function normalizeRole(role) {
|
|
19
|
+
return String(role ?? "").trim() === "admin" ? "admin" : "member";
|
|
20
|
+
}
|
|
21
|
+
function normalizeWorkspaceList(workspaces) {
|
|
22
|
+
const input = Array.isArray(workspaces) ? workspaces : [];
|
|
23
|
+
const seen = new Set();
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const w of input) {
|
|
26
|
+
const trimmed = String(w ?? "").trim();
|
|
27
|
+
if (!trimmed)
|
|
28
|
+
continue;
|
|
29
|
+
const resolved = node_path_1.default.resolve(trimmed);
|
|
30
|
+
if (seen.has(resolved))
|
|
31
|
+
continue;
|
|
32
|
+
seen.add(resolved);
|
|
33
|
+
out.push(resolved);
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
async function ensureWorkspaceDirectoriesExist(workspaces) {
|
|
38
|
+
for (const workspacePath of workspaces) {
|
|
39
|
+
// 分配路径不存在时自动创建,保证“分配即可用”。
|
|
40
|
+
await promises_1.default.mkdir(workspacePath, { recursive: true });
|
|
41
|
+
// 目录创建后再校验类型,避免路径指向文件造成后续权限语义异常。
|
|
42
|
+
const workspaceStat = await promises_1.default.stat(workspacePath);
|
|
43
|
+
if (!workspaceStat.isDirectory()) {
|
|
44
|
+
throw new Error(`workspace is not a directory: ${workspacePath}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function createUserAdminRoutes(opts) {
|
|
49
|
+
const router = express_1.default.Router();
|
|
50
|
+
router.use(requireAdmin_1.requireAdmin);
|
|
51
|
+
router.get("/users", async (_req, res) => {
|
|
52
|
+
const users = await opts.userStore.listUsers();
|
|
53
|
+
res.json({ ok: true, users: users.map(toPublicUser) });
|
|
54
|
+
});
|
|
55
|
+
router.post("/users", async (req, res) => {
|
|
56
|
+
const body = (req.body ?? {});
|
|
57
|
+
const username = normalizeUsername(body.username);
|
|
58
|
+
const password = String(body.password ?? "");
|
|
59
|
+
const role = normalizeRole(body.role);
|
|
60
|
+
if (!username || !password) {
|
|
61
|
+
res.status(400).json({ ok: false, error: "invalid_input" });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const created = await opts.userStore.createUser({ username, password, role });
|
|
66
|
+
res.json({ ok: true, user: toPublicUser(created) });
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
res.status(400).json({ ok: false, error: "create_failed", details: String(err) });
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
router.put("/users/:username/workspaces", async (req, res) => {
|
|
73
|
+
const username = normalizeUsername(req.params?.username);
|
|
74
|
+
const body = (req.body ?? {});
|
|
75
|
+
const workspaces = normalizeWorkspaceList(body.workspaces);
|
|
76
|
+
if (!username) {
|
|
77
|
+
res.status(400).json({ ok: false, error: "invalid_input" });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
await ensureWorkspaceDirectoriesExist(workspaces);
|
|
82
|
+
const updated = await opts.userStore.assignWorkspaces(username, workspaces);
|
|
83
|
+
res.json({ ok: true, user: toPublicUser(updated) });
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
res.status(400).json({ ok: false, error: "assign_failed", details: String(err) });
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return router;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=userAdminRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userAdminRoutes.js","sourceRoot":"","sources":["../../src/admin/userAdminRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Express } from "express";
|
|
2
|
+
import type { UserStore } from "./auth/userStore";
|
|
3
|
+
import type { CodexAppServer } from "./codex/codexAppServer";
|
|
4
|
+
import type { UserWorkspaceStore } from "./workspace/userWorkspaceStore";
|
|
5
|
+
import type { UserSettingsStore } from "./settings/userSettingsStore";
|
|
6
|
+
import type { HistoryQueryService } from "./history/query/historyQueryService";
|
|
7
|
+
type StatusSnapshot = {
|
|
8
|
+
codex?: unknown;
|
|
9
|
+
codexTask?: unknown;
|
|
10
|
+
ws?: unknown;
|
|
11
|
+
};
|
|
12
|
+
export declare function createApp(opts: {
|
|
13
|
+
sessionSecret: string;
|
|
14
|
+
startedAtMs?: number;
|
|
15
|
+
getStatusSnapshot?: () => StatusSnapshot;
|
|
16
|
+
codex?: CodexAppServer;
|
|
17
|
+
userStore?: UserStore;
|
|
18
|
+
userWorkspaceStore?: UserWorkspaceStore;
|
|
19
|
+
userSettingsStore?: UserSettingsStore;
|
|
20
|
+
historyQuery?: HistoryQueryService | null;
|
|
21
|
+
}): Express;
|
|
22
|
+
export {};
|