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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ target/
node_modules/
**/node_modules/
crates/ironclaw_webui_v2_static/static/dist/
crates/ironclaw_webui_v2/frontend/dist/
30 changes: 26 additions & 4 deletions .github/workflows/code_style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,24 @@ jobs:
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- name: Enable pnpm for setup-node cache
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
if: contains(matrix.flags, '--all-features')
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml
- name: Enable pnpm
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
if: contains(matrix.flags, '--all-features')
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
shared-key: clippy
Expand Down Expand Up @@ -223,13 +234,24 @@ jobs:
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
components: clippy
- name: Enable pnpm for setup-node cache
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
if: contains(matrix.flags, '--all-features')
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml
- name: Enable pnpm
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
if: contains(matrix.flags, '--all-features')
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: windows-${{ matrix.name }}
Expand Down
37 changes: 35 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,28 @@ jobs:
if: matrix.has_postgres
run: echo "DATABASE_URL=postgres://postgres:postgres@localhost/ironclaw_test" >> "$GITHUB_ENV"

- name: Enable pnpm for setup-node cache
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm

- name: Install Node.js for WebUI bundle build
if: contains(matrix.flags, '--all-features')
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml

- name: Enable pnpm
if: contains(matrix.flags, '--all-features')
run: corepack enable pnpm

- name: Install WebUI frontend dependencies
if: contains(matrix.flags, '--all-features')
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile

- name: Generate coverage
run: cargo llvm-cov ${{ matrix.flags }} --workspace --lcov --output-path lcov.info

Expand Down Expand Up @@ -180,12 +202,23 @@ jobs:
- name: Clean coverage workspace
run: cargo llvm-cov clean --workspace

- name: Enable pnpm for setup-node cache
run: corepack enable pnpm

- name: Install Node.js for WebUI bundle build
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml

- name: Enable pnpm
run: corepack enable pnpm

- name: Install WebUI frontend dependencies
Comment thread
BenKurrek marked this conversation as resolved.
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile

# Pre-build the reborn binary under the same llvm-cov env so the E2E
# fixtures find it cached instead of doing a cold instrumented build
Expand Down
24 changes: 20 additions & 4 deletions .github/workflows/platform-and-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,20 @@ jobs:
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
targets: wasm32-wasip2
- name: Enable pnpm for setup-node cache
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml
- name: Enable pnpm
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: wasm-extensions
Expand Down Expand Up @@ -299,12 +307,20 @@ jobs:
persist-credentials: false
- name: Install Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
- name: Enable pnpm for setup-node cache
run: corepack enable pnpm
- name: Install Node.js for WebUI bundle builds
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml
- name: Enable pnpm
run: corepack enable pnpm
- name: Install WebUI frontend dependencies
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: bench
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/reborn-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,23 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable

- name: Enable pnpm for setup-node cache
run: corepack enable pnpm

- name: Install Node.js for WebUI bundle build
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml

- name: Enable pnpm
run: corepack enable pnpm

- name: Install WebUI frontend dependencies
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile

- name: Restore Rust cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/reborn-playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,23 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable

- name: Enable pnpm for setup-node cache
run: corepack enable pnpm

- name: Install Node.js for WebUI bundle build
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml

- name: Enable pnpm
run: corepack enable pnpm

- name: Install WebUI frontend dependencies
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile

- name: Restore Rust cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
Expand Down
36 changes: 23 additions & 13 deletions .github/workflows/reborn-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,27 @@ jobs:
echo "needs_webui_node=${needs_webui_node}" >> "${GITHUB_OUTPUT}"
echo "sccache_dist_enabled=${sccache_dist_enabled}" >> "${GITHUB_OUTPUT}"

- name: Enable pnpm for setup-node cache
if: ${{ steps.bucket-settings.outputs.needs_webui_node == 'true' }}
run: corepack enable pnpm

- name: Install Node.js for WebUI bundle builds
if: ${{ steps.bucket-settings.outputs.needs_webui_node == 'true' }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
with:
node-version: "22"
cache: "npm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/package-lock.json
cache: "pnpm"
cache-dependency-path: crates/ironclaw_webui_v2/frontend/pnpm-lock.yaml

- name: Enable pnpm
if: ${{ steps.bucket-settings.outputs.needs_webui_node == 'true' }}
run: corepack enable pnpm

- name: Install WebUI frontend dependencies
if: ${{ steps.bucket-settings.outputs.needs_webui_node == 'true' }}
run: |
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile

- name: Install mold and clang
run: |
Expand Down Expand Up @@ -704,18 +718,14 @@ jobs:
with:
node-version: "22"

- name: Run Reborn settings JS tests
- name: Enable pnpm
run: corepack enable pnpm

- name: Run Reborn WebUI frontend tests
run: |
mapfile -t tests < <(
find crates/ironclaw_webui_v2/static/js/pages/settings \
-type f \( -name '*.test.mjs' -o -name '*.test.js' \) \
| sort
)
if [ "${#tests[@]}" -eq 0 ]; then
echo "No Reborn settings JS tests found"
exit 1
fi
node --test "${tests[@]}"
cd crates/ironclaw_webui_v2/frontend
pnpm install --frozen-lockfile
pnpm test

qa-recorded-fixtures:
name: Reborn QA recorded fixtures
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/regression-test-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ jobs:
exit 0
fi

if grep -qE '^crates/ironclaw_webui_v2/static/js/.*\.test\.(js|mjs)$' <<< "$CHANGED_FILES"; then
if grep -qE '^crates/ironclaw_webui_v2/frontend/src/.*\.test\.(ts|mts)$' <<< "$CHANGED_FILES"; then
echo "Reborn WebUI v2 JS test file changes found."
exit 0
fi
Expand Down
11 changes: 11 additions & 0 deletions Dockerfile.reborn
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ COPY --from=node_toolchain /usr/local/lib/node_modules/ /usr/local/lib/node_modu

RUN ln -sf ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& ln -sf ../lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \
&& ln -sf ../lib/node_modules/corepack/dist/corepack.js /usr/local/bin/corepack \
&& node --version \
&& npm --version \
&& corepack --version \
&& corepack enable pnpm \
&& cargo install --locked cargo-chef@0.1.77

WORKDIR /app
Expand All @@ -48,6 +51,10 @@ ENV CARGO_PROFILE_DIST_PANIC=abort \
CARGO_PROFILE_DIST_CODEGEN_UNITS=1

COPY --from=planner /app/recipe.json recipe.json
COPY crates/ironclaw_webui_v2/frontend/ crates/ironclaw_webui_v2/frontend/
WORKDIR /app/crates/ironclaw_webui_v2/frontend
RUN pnpm install --frozen-lockfile
WORKDIR /app
RUN cargo chef cook \
--profile dist \
--package ironclaw_reborn_cli \
Expand All @@ -68,6 +75,10 @@ RUN mkdir -p src \
&& printf 'fn main() {}\n' > src/main.rs \
&& printf '\n' > src/lib.rs

WORKDIR /app/crates/ironclaw_webui_v2/frontend
RUN pnpm install --frozen-lockfile
WORKDIR /app

RUN cargo build \
--profile dist \
--package ironclaw_reborn_cli \
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ cargo run -q -p ironclaw_reborn_cli --bin ironclaw-reborn -- repl --confirm-host
### WebUI service

The Reborn WebUI is compiled behind the `webui-v2-beta` Cargo feature. Builds
with this feature require Node.js/npm so Cargo can generate and embed the SPA
bundle. Build or run the binary with that feature to enable the `serve`
with this feature require Node.js 22 with Corepack/pnpm so Cargo can generate
and embed the SPA bundle. Build or run the binary with that feature to enable the `serve`
command:

```bash
Expand Down Expand Up @@ -425,7 +425,7 @@ IronClaw is the AI assistant you can actually trust with your personal and profe

- Rust 1.96+
- PostgreSQL 15+ with [pgvector](https://github.com/pgvector/pgvector) extension
- Node.js 22+ (npm) for source builds that enable the `webui-v2-beta` feature
- Node.js 22+ with Corepack/pnpm for source builds that enable the `webui-v2-beta` feature
- NEAR AI account (authentication handled via setup wizard)
- `libclang` and a working C toolchain if you build the WeChat voice/SILK path from source

Expand Down
26 changes: 17 additions & 9 deletions crates/ironclaw_reborn_cli/src/commands/webui_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use ironclaw_reborn_composition::{
};
use ironclaw_reborn_webui_ingress::{
CompositeAuthenticator, SessionAuthenticator, SignedSessionLoginConfig,
build_signed_session_login, signed_session_store,
build_signed_session_login, empty_webui_v2_auth_providers_mount, signed_session_store,
};
use secrecy::SecretString;

Expand Down Expand Up @@ -50,7 +50,9 @@ pub(crate) struct LocalTriggerAccessBootstrapConfig {
/// Build the auth surface from resolved startup config.
///
/// With no SSO provider configured (`sso_startup` is `None`), the listener
/// keeps its plain env-bearer authenticator and mounts no public routes.
/// keeps its env-bearer authenticator, also validates signed session tokens
/// minted by the admin API, and mounts only the inert auth surface so
/// `/auth/providers` can return an empty provider list.
/// With providers configured, this layers the fail-closed email-domain
/// admission adapter on top of the runtime-owned canonical Reborn identity
/// resolver and hands the result to the ingress signed-session builder.
Expand Down Expand Up @@ -91,9 +93,10 @@ pub(crate) async fn build_webui_auth_surface(
session_authenticator,
env_authenticator,
));
let public_mount = empty_webui_v2_auth_providers_mount();
return Ok(WebuiAuthSurface {
authenticator,
public_mount: None,
public_mount: Some(public_mount),
});
};

Expand Down Expand Up @@ -231,10 +234,12 @@ mod tests {
}

#[tokio::test]
async fn no_sso_keeps_env_authenticator_and_mounts_no_public_routes() {
// With no SSO configured the surface is the plain env-bearer
// authenticator and no public login routes — the absent-resolver
// check must not fire on this path, and a bootstrap config is unused.
async fn no_sso_composes_env_and_session_auth_and_mounts_empty_provider_route() {
// With no SSO configured the surface still needs env-bearer access
// plus signed-session bearer access for admin-created users. It also
// mounts an inert public auth surface for provider discovery. The
// absent-resolver check must not fire on this path, and a bootstrap
// config is unused.
let result = build_webui_auth_surface(
None,
None,
Expand All @@ -247,8 +252,11 @@ mod tests {

match result {
Ok(surface) => assert!(
surface.public_mount.is_none(),
"no SSO must mount no public login routes"
surface.public_mount.as_ref().is_some_and(|mount| {
mount.descriptors.len() == 1
&& mount.descriptors[0].route_pattern().as_str() == "/auth/providers"
}),
"no SSO must mount only /auth/providers with an empty list"
),
Err(error) => panic!("no SSO is a valid configuration, got error: {error}"),
}
Expand Down
Loading
Loading