Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* text=auto
node/ui/** text eol=lf
node/ui-src/** text eol=lf
37 changes: 37 additions & 0 deletions .github/workflows/platform-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Verify committed UI assets
run: npm run verify:ui-assets

- name: Run syntax checks
run: npm run lint

Expand Down Expand Up @@ -102,3 +105,37 @@ jobs:
env:
CRP_NATIVE_KEYRING_SMOKE: "1"
run: node scripts/native-keyring-smoke.mjs

canonical-ui:
name: Canonical Linux UI build
runs-on: ubuntu-latest
defaults:
run:
working-directory: node
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.19.0
package-manager-cache: false

- name: Install dependencies
run: npm ci

- name: Generate canonical UI artifact
run: npm run build:ui

- name: Upload canonical UI artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: crp-canonical-ui-${{ github.run_id }}
path: node/ui/**
include-hidden-files: true
if-no-files-found: error
retention-days: 14
7 changes: 6 additions & 1 deletion .github/workflows/release-preflight.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
- "node/bin/**"
- "node/src/**"
- "node/ui/**"
- "node/ui-src/**"
- "node/scripts/**"
- "node/test/package-content.test.mjs"
- "node/test/native-keyring-smoke.test.mjs"
Expand All @@ -17,6 +18,7 @@ on:
- "node/package-lock.json"
- "node/.changeset/**"
- "node/RELEASING.md"
- ".gitattributes"

permissions:
contents: read
Expand All @@ -37,12 +39,15 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
node-version: 22.19.0
package-manager-cache: false

- name: Install dependencies
run: npm ci

- name: Verify canonical UI checkout
run: npm run verify:ui-build

- name: Run syntax checks
run: npm run lint

Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,32 @@ permissions:
id-token: write

jobs:
canonical-ui:
name: Verify canonical UI checkout
runs-on: ubuntu-latest
defaults:
run:
working-directory: node
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.19.0
package-manager-cache: false

- name: Install dependencies
run: npm ci

- name: Verify canonical UI checkout
run: npm run verify:ui-build

release:
needs: canonical-ui
runs-on: ubuntu-latest
defaults:
run:
Expand Down
8 changes: 7 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- CLI and supervisor entrypoint: `node/bin/crp.mjs`
- Proxy worker: `node/src/server.mjs`
- Provider, credential, and control-plane modules: `node/src/`
- Local Web management UI: `node/ui/` (target architecture)
- Local Web management UI source: `node/ui-src/app/` and `node/ui-src/src/`; generated static export: `node/ui/`
- Tests: `node/test/`

## Working Rules
Expand Down Expand Up @@ -127,6 +127,12 @@
- Unbounded database maintenance must not run synchronously before the Worker readiness acknowledgement.
- Replacement background maintenance must wait for confirmed cancellation of prior work on the same resource.
- Upgrade tests must cover nonempty persisted databases and maintenance exceeding startup deadlines.
- Next.js migrations must move ordinary business components out of the reserved `pages` directory before building.
- CSP hash sources must retain their required single quotes and pass real-browser hydration verification.
- Tailwind migrations must define the legacy CSS cascade order and verify that new utilities take effect.
- Authenticated preview diagnostics must not print response headers containing `Set-Cookie`.
- Static UI release validation must use a clean checkout with canonical LF line endings.
- Canonical verification must compare the untouched checked-in UI before any build replaces it.

## Required Checks

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ npx @cluic/codex-remote-proxy ui

`crp ui` starts or discovers the local supervisor and opens the management UI. A saved explicit language choice wins; otherwise the interface uses the first supported Chinese or English browser/system preference and falls back to English. Inferred language is not persisted.

The current development UI is implemented in `node/ui-src/` with React, TypeScript, and Vite. Those tools are build-time only: the package and Admin server still ship exactly `ui/index.html`, `ui/app.js`, and `ui/styles.css`, with no frontend runtime server, remote font, CDN, telemetry, source map, or dynamic chunk.
The management UI is implemented in `node/ui-src/` with Next.js App Router, React, TypeScript, Tailwind CSS, shadcn source components backed by Base UI, and Lucide icons. The default Webpack build produces a reviewed static export and asset manifest under `node/ui/`; the package needs no frontend runtime server and the Admin server serves every route and chunk from the same loopback origin. The UI uses no remote font, CDN, telemetry, or source map. Clean Ubuntu Node 22 is the canonical build environment: release gates compare its generated output with the checkout before any candidate build replaces `node/ui/`. Linux, macOS, and Windows validate the committed source digest, manifest, CSP, resources, package allowlist, and their platform-specific tests.

## What You Can Manage

Expand Down Expand Up @@ -241,7 +241,7 @@ Tests use temporary homes, synthetic credentials, injected adapters, and loopbac

The serial `core-chain` gate exercises the real CLI, Admin server, registry/provider service, WorkerManager, forked proxy worker, fixed ports, provider switching with an in-flight request, restart, shutdown, and secret scans. It deliberately substitutes an in-memory credential adapter and loopback upstreams, so it does not prove native credential access or a real external provider.

Release evidence must include lint, UI typecheck/build/exact three-file verification, the deterministic Node suite, Chromium English/Chinese responsive coverage, the exact package-content allowlist, runtime audit, and the visual comparison recorded in `design-qa.md`. Deterministic fixtures do not claim real Codex history, native credentials, login-start execution, or an external provider; those remain platform/human gates for the reviewed release tree.
Release evidence must include lint, UI typecheck/build/exact manifest verification, the deterministic Node suite, Chromium English/Chinese responsive coverage, the exact package-content allowlist, runtime audit, and the visual comparison recorded in `design-qa.md`. Deterministic fixtures do not claim real Codex history, native credentials, login-start execution, or an external provider; those remain platform/human gates for the reviewed release tree.

Supervisor discovery uses a bounded 2-second liveness probe while normal Admin operations use a separate 30-second timeout, so a successful provider test is not misreported as `SUPERVISOR_UNAVAILABLE`. Proxy targets are joined structurally, so base URLs with or without a trailing slash produce one path separator.

Expand Down
4 changes: 2 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ npx @cluic/codex-remote-proxy ui

`crp ui` 会启动或发现本地 Supervisor,并打开管理界面。已保存的明确语言选择优先;否则按浏览器/系统语言偏好选择第一个受支持的中文或英文,均不匹配时默认英文。推断出的语言不会写入浏览器存储。

当前开发版界面使用 `node/ui-src/` 中的 React、TypeScript 与 Vite 实现。这些工具只参与构建;发布包和 Admin Server 仍然只交付 `ui/index.html`、`ui/app.js` 与 `ui/styles.css`,不需要前端运行时服务器,也不包含远程字体、CDN、遥测、source map 或动态 chunk。
管理界面使用 `node/ui-src/` 中的 Next.js App Router、React、TypeScript、Tailwind CSS、基于 Base UI 的 shadcn 源码组件和 Lucide 图标实现。默认 Webpack 构建会在 `node/ui/` 生成经过审核的静态导出及资源清单;发布包不需要前端运行时服务器,Admin Server 从同一个回环来源提供全部页面和 chunk。界面不包含远程字体、CDN、遥测或 source map。干净的 Ubuntu Node 22 是规范构建环境:发布门禁会在任何候选构建覆盖 `node/ui/` 前,将其生成结果与 checkout 比较。Linux、macOS 和 Windows 会校验已提交的源摘要、清单、CSP、资源、package allowlist 及各自的平台测试。

## 可以管理什么

Expand Down Expand Up @@ -240,7 +240,7 @@ npm pack --dry-run --json --ignore-scripts

串行 `core-chain` 门禁会覆盖真实 CLI、Admin 服务、registry/provider service、WorkerManager、fork 出的代理 Worker、固定端口、存在进行中请求时的提供商切换、重启、关闭和密钥扫描。该门禁会有意替换为内存凭据适配器和 loopback 上游,因此不能证明原生凭据读取或真实外部提供商链路。

发布证据必须包含 lint、UI 类型检查/构建/精确三文件同步验证、确定性 Node 测试、Chromium 英中双语响应式矩阵、精确发布包白名单、生产依赖审计,以及 `design-qa.md` 中的视觉对比。确定性 fixture 不代表真实 Codex 历史、原生凭据、登录启动执行或外部 provider 证据;这些仍属于对应发布代码树的平台/人工门禁。
发布证据必须包含 lint、UI 类型检查/构建/精确资源清单验证、确定性 Node 测试、Chromium 英中双语响应式矩阵、精确发布包白名单、生产依赖审计,以及 `design-qa.md` 中的视觉对比。确定性 fixture 不代表真实 Codex 历史、原生凭据、登录启动执行或外部 provider 证据;这些仍属于对应发布代码树的平台/人工门禁。

Supervisor 发现使用有界的 2 秒探活,普通 Admin 操作另用 30 秒超时,因此已经成功的 provider test 不会再被误报为 `SUPERVISOR_UNAVAILABLE`。代理目标通过结构化方式拼接,无论 base URL 是否带尾斜杠都只产生一个路径分隔符。

Expand Down
10 changes: 10 additions & 0 deletions design-qa.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CRP Overview Redesign QA

## Next.js management UI migration — 2026-09-05

This section supersedes the earlier Vite and fixed three-file UI architecture descriptions. The real CRP management UI now uses a Next.js App Router static export with React, Tailwind CSS, shadcn source components backed by Base UI, and Lucide icons. It keeps the existing same-origin Admin API, in-memory control/CSRF state, explicit fragmentless management recovery, bilingual copy, and every Provider, mapping, routing, Capture, access-key, Metrics, and System mutation contract; no demo data is present in production routes.

- The approved compact light-green console direction now covers all routes. Overview keeps live routing decisions, account quota, Metrics and the 84-day Token heatmap; its route decision surface uses a deep-green operational rail without changing scheduler semantics.
- Dialogs, mobile navigation, forwarding details, buttons, badges, separators, tooltips, and menus use the shared shadcn/Base UI layer. Forwarding details retain on-demand abortable loading, Summary/Request/Response separation, exact raw-body copy, record stepping, Escape/backdrop behavior, and focus return.
- The deterministic Webpack static export is served from the existing loopback Admin origin through a generated asset manifest. CSP allows only the exact reviewed inline bootstrap hashes for each generated route; external assets, remote fonts, source maps, inline style attributes, and runtime frontend servers remain absent. Release CI separately reproduces the manifest on every supported platform.
- Final UI verification passed: typecheck, the deterministic static build, byte-exact manifest verification, lint across 78 source files, the exact package-content check 3/3, and Chromium E2E 73/73. Full and runtime dependency audits reported zero vulnerabilities. The full `npm test` run reached the serial fixed-port core-real-chain gate but could not bind `127.0.0.1:15100` because the user's existing CRP service owns it; that service was not stopped or changed, and this is not reported as a core-chain pass.
- Settled Overview evidence: `output/next-ui-migration-2026-09-05/pages/overview-settled-1440x900.png` and `output/next-ui-migration-2026-09-05/pages/overview-settled-390x844.png`. Final forwarding list/detail evidence is under `output/next-ui-migration-2026-09-05/pages/e2e-release-final/`. The isolated, synthetic-data, fragmentless preview is available locally at `http://localhost:4318/`; it does not use the user's running CRP service.

## 0.4.20 startup regression follow-up — 2026-09-05

Root cause: the forwarding metadata covering index was created synchronously inside Capture initialization, before the proxy Worker could send its configured acknowledgement. On a nonempty, body-heavy database, one-time index construction could exceed the existing five-second acknowledgement deadline. A running `crp update` correctly rolled back when activation failed; an update performed after shutdown did not need to restart a previously stopped Worker, so the same failure appeared later at `crp start`. The npm 0.4.20 artifact's integrity and all 46 shipped files were verified against the reviewed release commit, ruling out a mismatched package as the explanation.
Expand Down
5 changes: 5 additions & 0 deletions node/.changeset/next-ui-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cluic/codex-remote-proxy": patch
---

Migrate the complete local management UI to a static Next.js App Router build using Tailwind CSS and shadcn components backed by Base UI while preserving the existing Admin API and security behavior.
8 changes: 5 additions & 3 deletions node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ npx @cluic/codex-remote-proxy ui

`crp ui` is the normal setup and management entry point. It starts or discovers the loopback supervisor, opens the local management UI, and supports complete English and Simplified Chinese interfaces.

The current development source is a responsive React + TypeScript SPA under `ui-src/`, built with Vite. Build tools and source are not shipped: the package contains exactly `ui/index.html`, `ui/app.js`, and `ui/styles.css` for the existing same-origin Admin server.
The responsive management UI under `ui-src/` uses Next.js App Router, React, TypeScript, Tailwind CSS, shadcn source components backed by Base UI, and Lucide icons. Build tools and source are not shipped: the default Webpack-backed `build:ui` creates a reviewed static export and `.crp-ui-manifest.json` under `ui/`, and the Admin server serves its pages, Flight data, and hashed chunks from the same loopback origin without a frontend runtime server. Clean Ubuntu Node 22 is the canonical compiler environment. Release gates run `verify:ui-build` against the untouched checkout there; platform jobs use `verify:ui-assets` to bind the committed manifest to its source digest and security policy while retaining their native checks.

Release artifacts use a clean Ubuntu Node 22 Webpack build as the canonical output. Platform jobs validate the committed manifest and security policy alongside their native tests; local host builds must not replace the canonical `ui/` tree.

## Product Behavior

Expand Down Expand Up @@ -178,11 +180,11 @@ node --test test/package-content.test.mjs test/native-keyring-smoke.test.mjs tes
npm pack --dry-run --json --ignore-scripts
```

The current package-content test requires the exact reviewed 47-file allowlist, including provider presets/build metadata, the route preview and provider scheduler, client-key store/private-token support, Forwarding Records service, the isolated Capture index worker, start-at-login service, and exactly three generated UI assets. It rejects UI development source, runtime state, credentials, tests, Changesets, logs, databases, and generated output outside the reviewed UI files. Deterministic tests use temporary homes, synthetic credentials, injected credential adapters, and loopback upstreams.
The package-content test compares the exact reviewed allowlist, including provider presets/build metadata, the route preview and provider scheduler, client-key store/private-token support, Forwarding Records service, the isolated Capture index worker, start-at-login service, and every file declared by the generated UI asset manifest. It rejects UI development source, runtime state, credentials, tests, Changesets, logs, databases, and generated output outside the reviewed UI files. Deterministic tests use temporary homes, synthetic credentials, injected credential adapters, and loopback upstreams.

The serial `core-chain` group uses the production CLI/Admin/registry/provider/WorkerManager/forked-worker path and proves switching, in-flight snapshots, restart, shutdown, cleanup, and secret scans. Its injected memory credential adapter and loopback upstreams do not satisfy the separate real native-keyring/external-provider gate.

Release evidence must include lint, UI typecheck/build/exact-output verification, deterministic Node tests, Chromium English/Chinese responsive coverage, the exact 44-file package allowlist, runtime audit, and the comparison recorded in `../design-qa.md`. Deterministic fixtures do not prove real native-keyring, login-start execution, or external-upstream behavior; those remain platform/human gates.
Release evidence must include lint, UI typecheck/build/exact-manifest verification, deterministic Node tests, Chromium English/Chinese responsive coverage, the exact reviewed package allowlist, runtime audit, and the comparison recorded in `../design-qa.md`. Deterministic fixtures do not prove real native-keyring, login-start execution, or external-upstream behavior; those remain platform/human gates.

Supervisor discovery applies a 2-second liveness probe and returns a client with a separate 30-second operation timeout. Proxy forwarding joins base and incoming URLs structurally, preserving base paths and query parameters while avoiding duplicate path separators. The retained `provider add --api-key <KEY>` behavior and broader child-environment minimization remain explicit future follow-up work and do not block local core completion.

Expand Down
Loading
Loading