Update: 将子项目从 submodule 转为完整内容

- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用
- 添加所有子项目的完整源代码
- 保留原始 .git 为 .git.bak 备份
This commit is contained in:
freedak
2026-07-04 19:20:46 +08:00
parent 54d6465fa7
commit f7a720204a
3360 changed files with 802660 additions and 3 deletions
@@ -0,0 +1,160 @@
# Building and Packaging
This page covers release artifacts from the current **NomiFun** monorepo: the
React SPA, `nomifun-web`, Tauri desktop bundles, updater payloads, Docker, and
native Linux service files.
For day-to-day loops, see [`development.md`](development.md). For operator
deployment, see [`../guides/web-server-deployment.md`](../guides/web-server-deployment.md).
## Current Status
| Artifact | Current state |
| --- | --- |
| SPA (`ui/dist`) | Built by `bun run build:ui`; consumed by desktop and web hosts. |
| `nomifun-web` | Supported self-hosted binary; auth on by default. |
| Tauri desktop bundles | Built by `bun run build` for the current OS. |
| macOS Developer ID signing + notarization | Supported through `bun run build:signed` when local Apple signing credentials are configured. |
| Tauri updater artifacts | `bun run build:updater` emits updater `.sig` files; production endpoint/key management still needs release setup. |
| Docker / Compose | Local image and compose stack are supported; no public registry image is promised here. |
| Native Linux + systemd | Unit and README live under `packaging/linux/`. |
| Windows signing | Requires an external code-signing certificate; not configured by this repository. |
## SPA
```bash
bun run build:ui
```
Output: `ui/dist/`.
Desktop builds bundle this directory through `frontendDist` in
`apps/desktop/tauri.conf.json`. `nomifun-web` serves it from `--dist` /
`NOMIFUN_WEB_DIST`; when running from the repo, the default points at
`../../ui/dist` from `apps/web`.
## Web Binary
```bash
bun run build:ui
cargo build --release -p nomifun-web
```
Runtime requirements:
- built SPA directory;
- writable data directory;
- Bun on `PATH`, unless the binary was built with `NOMIFUN_EMBED_BUN=1`;
- configured auth/admin flow, or explicit `--insecure-no-auth` for trusted
loopback-only development.
Example:
```bash
target/release/nomifun-web --host 127.0.0.1 --port 8787 --dist ui/dist
```
First browser visit creates the admin account unless `NOMIFUN_ADMIN_USERNAME`
and `NOMIFUN_ADMIN_PASSWORD` pre-seed it.
## Desktop Bundles
```bash
bun run build
```
This runs Tauri build with `apps/desktop/tauri.conf.json`, builds the SPA first,
then creates OS-specific bundles under `target/release/bundle/`.
Product identity comes from `apps/desktop/tauri.conf.json`:
- `productName: "NomiFun"`
- `identifier: "com.nomifun.desktop"`
- version from workspace package metadata
- dev URL `http://localhost:5173`
- bundled frontend `../../ui/dist`
Tauri desktop bundles are best built on their target OS. Cross-OS desktop
packaging is not part of the supported workflow.
## macOS Signing and Notarization
Unsigned/ad-hoc macOS artifacts are useful for local testing but are not suitable
for distributing to other people. To produce a Developer ID signed and notarized
DMG:
```bash
cp apps/desktop/signing/.env.signing.example apps/desktop/signing/.env.signing
# fill local Apple signing/notary values
bun run build:signed
```
The real `.env.signing` file and Apple private keys are ignored by git. The
wrapper script is [`scripts/desktop-build-signed.sh`](../../scripts/desktop-build-signed.sh);
the detailed setup guide is
[`apps/desktop/signing/README.md`](../../apps/desktop/signing/README.md).
## Updater Artifacts
```bash
bun run build:updater
```
This enables Tauri's `createUpdaterArtifacts` and emits `.sig` files next to the
installers. These signatures are for the Tauri updater, not for OS trust. macOS
Gatekeeper still requires Developer ID signing/notarization; Windows still needs
code signing.
The updater scaffold exists, but a production release still needs:
- production updater key management;
- hosted `latest.json` endpoint;
- release-channel policy;
- renderer flow for download/apply/restart beyond the current check surface.
See [`apps/desktop/updater/README.md`](../../apps/desktop/updater/README.md).
## Docker
```bash
docker compose up -d --build
```
The root `Dockerfile` builds the SPA with Bun, builds `nomifun-web` in release
mode, and copies the binary plus `ui/dist` into a slim runtime image. Compose
starts one `nomifun` service on port `8787` with `/data` as `NOMIFUN_DATA_DIR`.
Open `http://<server>:8787` after boot. If no admin was pre-seeded, the first
reachable browser gets the first-run admin setup screen.
The optional Caddy service in `docker-compose.yml` is commented out; use it or a
similar reverse proxy for TLS and set `NOMIFUN_HTTPS=true` when the browser
reaches the app over HTTPS.
## Native Linux + systemd
See [`packaging/linux/README.md`](../../packaging/linux/README.md). The short
shape is:
```bash
bun install
bun run build:ui
cargo build --release -p nomifun-web
sudo cp target/release/nomifun-web /opt/nomifun/
sudo cp -r ui/dist/. /opt/nomifun/web/
sudo cp packaging/linux/nomifun-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now nomifun-web
```
For systemd, set `SHELL` explicitly if agent child processes need a shell; a
nologin service user often has none.
## Checks Before Sharing an Artifact
- Run `cargo check --workspace`.
- Run `bun run build:ui`.
- For desktop, build on the target OS and smoke-test launch.
- For macOS distribution, validate `codesign`, `spctl`, and `xcrun stapler`.
- For web/Docker, verify first-run admin setup, login, `/health`, and WebSocket
connection through the intended host/reverse proxy.
@@ -0,0 +1,148 @@
# 构建与打包
本页说明当前 **NomiFun** monorepo 能产出的发布物:React SPA、`nomifun-web`
Tauri 桌面包、updater 产物、Docker 镜像和 Linux systemd 部署文件。
日常开发循环见 [`development.zh.md`](development.zh.md)。部署运行见
[`../guides/web-server-deployment.zh.md`](../guides/web-server-deployment.zh.md)。
## 当前状态
| 产物 | 当前状态 |
| --- | --- |
| SPA (`ui/dist`) | `bun run build:ui` 构建;桌面和 Web host 都使用它。 |
| `nomifun-web` | 支持的自托管 binary;默认开启鉴权。 |
| Tauri 桌面包 | `bun run build` 为当前 OS 构建。 |
| macOS Developer ID 签名 + 公证 | 已有 `bun run build:signed` 包装脚本;需要本机 Apple 签名配置。 |
| Tauri updater 产物 | `bun run build:updater` 会生成 updater `.sig`;生产 endpoint/key 管理仍需发布配置。 |
| Docker / Compose | 支持本地构建与 compose 运行;本文不承诺公开 registry 镜像。 |
| Native Linux + systemd | `packaging/linux/` 提供 unit 和说明。 |
| Windows 签名 | 需要外部代码签名证书;仓库内未配置。 |
## SPA
```bash
bun run build:ui
```
输出目录是 `ui/dist/`
桌面构建通过 `apps/desktop/tauri.conf.json``frontendDist` 打包该目录。
`nomifun-web` 通过 `--dist` / `NOMIFUN_WEB_DIST` 服务它;从仓库内运行时,
默认路径相对 `apps/web` 指向 `../../ui/dist`
## Web Binary
```bash
bun run build:ui
cargo build --release -p nomifun-web
```
运行要求:
- 已构建的 SPA 目录;
- 可写数据目录;
- `PATH` 上有 Bun,除非构建时使用 `NOMIFUN_EMBED_BUN=1`
- 默认鉴权/admin 初始化流程,或仅在可信本地开发中显式使用 `--insecure-no-auth`
示例:
```bash
target/release/nomifun-web --host 127.0.0.1 --port 8787 --dist ui/dist
```
未预置 `NOMIFUN_ADMIN_USERNAME` / `NOMIFUN_ADMIN_PASSWORD` 时,首次浏览器访问会创建管理员。
## 桌面包
```bash
bun run build
```
该命令调用 Tauri build,先构建 SPA,再在 `target/release/bundle/` 下生成当前
OS 的安装包/应用包。
产品身份来自 `apps/desktop/tauri.conf.json`
- `productName: "NomiFun"`
- `identifier: "com.nomifun.desktop"`
- 版本来自 workspace package metadata
- dev URL `http://localhost:5173`
- bundled frontend `../../ui/dist`
桌面包应在目标 OS 上构建。跨 OS 桌面打包不是当前支持流程。
## macOS 签名与公证
ad-hoc 签名产物只适合本地测试,不适合发给别人。生成 Developer ID 签名并公证的 DMG
```bash
cp apps/desktop/signing/.env.signing.example apps/desktop/signing/.env.signing
# 填写本机 Apple 签名/公证信息
bun run build:signed
```
真实 `.env.signing` 与 Apple 私钥不会入库。包装脚本在
[`scripts/desktop-build-signed.sh`](../../scripts/desktop-build-signed.sh),详细配置见
[`apps/desktop/signing/README.md`](../../apps/desktop/signing/README.md)。
## Updater 产物
```bash
bun run build:updater
```
该命令启用 Tauri `createUpdaterArtifacts`,在安装包旁生成 `.sig`。这些签名只给
Tauri updater 使用,不等于 OS 信任:macOS 仍需要 Developer ID 签名/公证;
Windows 仍需要代码签名证书。
生产发布仍需补齐:
- 生产 updater 密钥管理;
- 托管 `latest.json` endpoint
- 发布 channel 策略;
- renderer 中下载、应用、重启的完整流程。
见 [`apps/desktop/updater/README.md`](../../apps/desktop/updater/README.md)。
## Docker
```bash
docker compose up -d --build
```
`Dockerfile` 用 Bun 构建 SPA,用 Cargo 构建 release `nomifun-web`,再把 binary
`ui/dist` 复制到 slim runtime image。Compose 启动一个 `nomifun` 服务,
端口 `8787``/data` 作为 `NOMIFUN_DATA_DIR`
启动后访问 `http://<server>:8787`。如果没有预置管理员,第一个能访问到的浏览器
会看到首次管理员设置页。
`docker-compose.yml` 中的 Caddy 服务默认注释。需要 TLS 时可启用它或使用其他反向代理;
浏览器通过 HTTPS 访问时设置 `NOMIFUN_HTTPS=true`
## Native Linux + systemd
见 [`packaging/linux/README.md`](../../packaging/linux/README.md)。基本形态:
```bash
bun install
bun run build:ui
cargo build --release -p nomifun-web
sudo cp target/release/nomifun-web /opt/nomifun/
sudo cp -r ui/dist/. /opt/nomifun/web/
sudo cp packaging/linux/nomifun-web.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now nomifun-web
```
systemd 环境中,如果 agent 子进程需要 shell,请显式设置 `SHELL`nologin 服务用户
通常没有可用 shell。
## 分发前检查
- `cargo check --workspace`
- `bun run build:ui`
- 桌面包在目标 OS 上构建并 smoke test 启动。
- macOS 分发前验证 `codesign``spctl``xcrun stapler`
- Web/Docker 验证首次管理员设置、登录、`/health` 和目标反向代理下的 WebSocket。
@@ -0,0 +1,161 @@
# Development
This page is for people changing **NomiFun** itself: the React SPA, the Rust
backend, the agent engine, or the Tauri shell. If you only want to install or
operate the product, start with
[`../getting-started/installation.md`](../getting-started/installation.md) or
[`../guides/web-server-deployment.md`](../guides/web-server-deployment.md).
The current repository is the active Tauri monorepo. Earlier Electron-era phase
plans and audits are not kept in the repo; consult git history if you need that
background.
## Prerequisites
| Tool | Minimum | Why |
| --- | --- | --- |
| Rust | stable, edition 2024 | Workspace uses resolver `3` and edition `2024`. |
| Bun | >= 1.3.13 | Frontend package manager, Vite runner, and runtime dependency for agent tooling. |
| Tauri CLI v2 | from `devDependencies` | Invoked through `bun run dev`, `bun run build`, and related scripts. |
| Git | recent | Required by development workflows and several built-in tools. |
| Native build tools | platform-specific | Needed for SQLite, TLS, libgit2, WebKit/WebView dependencies, and bundled native crates. |
Platform notes:
- Windows: MSVC C++ build tools and WebView2 runtime.
- macOS: Xcode Command Line Tools.
- Linux: `build-essential cmake clang pkg-config perl git`; desktop builds also need WebKitGTK 4.1 development headers.
## Install
```bash
git clone <repo-url> nomifun-tauri
cd nomifun-tauri
bun install
cargo check --workspace
```
The root `package.json` has one Bun workspace: `ui/`. Rust crates are resolved by
the root `Cargo.toml`.
## Development Loops
| Command | Use when | What runs |
| --- | --- | --- |
| `bun run dev:ui` | UI-only work that can tolerate missing API calls | Vite on `http://localhost:5173`; no backend. |
| `bun run dev:web` | Browser + backend iteration with auth disabled | `nomifun-web --port 8787 --dist ui/dist --insecure-no-auth` plus Vite dev server. |
| `bun run serve:web` | Running the production-style web host from source | `nomifun-web` on `http://127.0.0.1:8787`; serves built `ui/dist`; auth on by default. |
| `bun run dev` | Desktop/Tauri work | Tauri dev shell, Vite, and embedded backend under the desktop local-trust policy. |
`serve:web` expects a built SPA:
```bash
bun run build:ui
bun run serve:web
```
`dev:web` is a convenience loop that starts API and UI together. It uses
`--insecure-no-auth`, so keep it on localhost or an isolated network.
The desktop loop does **not** use the old Electron process model. The Tauri
shell links `nomifun-app`, starts the backend in-process on a free localhost
port, injects `window.__backendPort` and `window.__nomiLocalTrust`, and the
renderer presents that per-boot trust secret on every request.
## Verification
| Command | Coverage |
| --- | --- |
| `cargo check --workspace` | All Rust crates and app hosts compile. |
| `cargo test -p <crate>` | Focused Rust tests for one crate. |
| `bun run typecheck` | Renderer TypeScript. |
| `bun run check:i18n` | Generated i18n key types are up to date. |
| `bun run check:theme` | Theme token contract. |
| `bun run help --check` | Root script help output is current. |
| `bun run build:ui` | Production Vite build. |
| `bun run build` | Tauri desktop release bundle for the current OS. |
For a broad pre-PR check, run:
```bash
cargo check --workspace
bun run typecheck
bun run check:i18n
bun run check:theme
bun run help --check
```
## Backend CLI
`nomifun-app` still ships a standalone `nomicore` binary. The app hosts do not
spawn it, but it is useful for diagnostics, stdio MCP bridges, and public
capability calls.
Current subcommands:
- `mcp-requirement-stdio`
- `mcp-knowledge-stdio`
- `mcp-gateway-stdio`
- `mcp-open-stdio`
- `mcp-computer-stdio`
- `mcp-browser-stdio`
- `terminal-hook --event <kind>`
- `doctor`
- `tools`
- `call <name> [json-args]`
- `agent "<goal>"`
When agents fail to launch, start with:
```bash
cargo run -p nomifun-app --bin nomicore -- doctor
```
It probes installed agent CLIs from the same PATH shape the backend uses and
prints a table to stdout.
## Data and Work Directories
All hosts share the same unset default data directory:
- Windows: `%LOCALAPPDATA%\NomiFun\Nomi`
- macOS: `~/Library/Application Support/NomiFun/Nomi`
- Linux: `$XDG_DATA_HOME/NomiFun/Nomi` or `~/.local/share/NomiFun/Nomi`
The data dir contains SQLite state, logs, Bun runtime cache, extension data,
agent state, and other persistent local state. The backend takes an exclusive
`server.lock` before opening the database, so two live backends cannot use the
same data directory at the same time.
For isolated development, set an explicit directory:
```bash
NOMIFUN_DATA_DIR=/tmp/nomifun-dev bun run serve:web
NOMIFUN_DATA_DIR=/tmp/nomifun-dev bun run dev
```
Desktop app semantics append the channel-specific `Nomi` leaf; web and
`nomicore` take the env value literally. See
[`../reference/configuration.md`](../reference/configuration.md) before relying
on this in automation.
`NOMIFUN_WORK_DIR` controls where conversation workspaces are created. If unset,
the backend falls back to the data dir.
## Logs
Logs go to stdout and to `<data-dir>/logs/nomicore.log`. Use:
```bash
NOMIFUN_LOG_LEVEL='info,nomifun_mcp=trace' bun run serve:web
```
or pass `--log-level` to `nomicore` / `nomifun-web` directly. The value is a
`tracing_subscriber::EnvFilter` directive.
## Where to Read Next
- [`project-structure.md`](project-structure.md) for the repo map.
- [`../architecture/backend-crates.md`](../architecture/backend-crates.md) for crate ownership.
- [`../architecture/frontend.md`](../architecture/frontend.md) for routes and host adapters.
- [`building-and-packaging.md`](building-and-packaging.md) for release artifacts.
@@ -0,0 +1,154 @@
# 开发
本页面向修改 **NomiFun** 仓库本身的人:React SPA、Rust 后端、agent 引擎或
Tauri 桌面壳。如果只是安装或部署,请先看
[`../getting-started/installation.zh.md`](../getting-started/installation.zh.md)
或 [`../guides/web-server-deployment.zh.md`](../guides/web-server-deployment.zh.md)。
当前仓库已经是活跃的 Tauri monorepo。旧 Electron 迁移阶段的计划、审计与设计稿
不在仓库中保留;需要这些背景时请查阅 git 历史。
## 前置工具
| 工具 | 最低要求 | 用途 |
| --- | --- | --- |
| Rust | stableedition 2024 | Workspace 使用 resolver `3` 和 edition `2024`。 |
| Bun | >= 1.3.13 | 前端包管理、Vite runner,也被 agent 运行时使用。 |
| Tauri CLI v2 | 来自 `devDependencies` | 通过 `bun run dev` / `bun run build` 调用,无需全局安装。 |
| Git | 较新版本 | 开发流程和部分内置工具需要。 |
| 原生编译工具 | 按平台 | SQLite、TLS、libgit2、WebKit/WebView 与原生 crate 需要。 |
平台提示:
- WindowsMSVC C++ Build Tools 与 WebView2 runtime。
- macOSXcode Command Line Tools。
- Linux`build-essential cmake clang pkg-config perl git`;构建桌面端还需要 WebKitGTK 4.1 开发包。
## 安装依赖
```bash
git clone <repo-url> nomifun-tauri
cd nomifun-tauri
bun install
cargo check --workspace
```
`package.json` 只有一个 Bun workspace`ui/`。Rust crate 由根 `Cargo.toml`
管理。
## 开发循环
| 命令 | 适用场景 | 实际运行内容 |
| --- | --- | --- |
| `bun run dev:ui` | 纯 UI 工作,可接受 API 请求失败 | Vite on `http://localhost:5173`,不启动后端。 |
| `bun run dev:web` | 浏览器 + 后端联调,关闭登录 | `nomifun-web --port 8787 --dist ui/dist --insecure-no-auth` 加 Vite。 |
| `bun run serve:web` | 从源码跑生产形态 Web host | `nomifun-web` on `http://127.0.0.1:8787`,服务 `ui/dist`,默认开启登录。 |
| `bun run dev` | 桌面/Tauri 开发 | Tauri dev shell、Vite、桌面本地信任策略下的嵌入式后端。 |
`serve:web` 需要先构建 SPA
```bash
bun run build:ui
bun run serve:web
```
`dev:web` 会同时启动 API 与 UI,并使用 `--insecure-no-auth`,只适合 localhost
或隔离网络。
桌面循环已经不是旧 Electron 模型。Tauri shell 直接链接 `nomifun-app`,在进程内
启动后端,选择一个空闲 localhost 端口,注入 `window.__backendPort`
`window.__nomiLocalTrust`,renderer 每次请求都会带上这个本次启动生成的信任
secret。
## 验证命令
| 命令 | 覆盖范围 |
| --- | --- |
| `cargo check --workspace` | 所有 Rust crate 和 app host 编译。 |
| `cargo test -p <crate>` | 单个 crate 的 Rust 测试。 |
| `bun run typecheck` | Renderer TypeScript。 |
| `bun run check:i18n` | i18n key 类型生成是否最新。 |
| `bun run check:theme` | 主题 token 契约。 |
| `bun run help --check` | 根脚本帮助文本。 |
| `bun run build:ui` | 生产 Vite 构建。 |
| `bun run build` | 当前 OS 的 Tauri 桌面包。 |
提交前常用组合:
```bash
cargo check --workspace
bun run typecheck
bun run check:i18n
bun run check:theme
bun run help --check
```
## 后端 CLI
`nomifun-app` 仍然提供独立 `nomicore` binary。app host 不会 spawn 它,但诊断、
stdio MCP bridge 和公开能力调用仍会用到。
当前子命令:
- `mcp-requirement-stdio`
- `mcp-knowledge-stdio`
- `mcp-gateway-stdio`
- `mcp-open-stdio`
- `mcp-computer-stdio`
- `mcp-browser-stdio`
- `terminal-hook --event <kind>`
- `doctor`
- `tools`
- `call <name> [json-args]`
- `agent "<goal>"`
agent 无法启动时,先跑:
```bash
cargo run -p nomifun-app --bin nomicore -- doctor
```
它会按后端看到的 PATH 探测各个 agent CLI,并把结果打印到 stdout。
## 数据目录与工作目录
所有 host 未显式覆盖时共享同一个默认数据目录:
- Windows`%LOCALAPPDATA%\NomiFun\Nomi`
- macOS`~/Library/Application Support/NomiFun/Nomi`
- Linux`$XDG_DATA_HOME/NomiFun/Nomi``~/.local/share/NomiFun/Nomi`
数据目录包含 SQLite、日志、Bun runtime cache、extension 数据和 agent 状态。
后端启动时会先拿 `{data_dir}/server.lock` 独占锁,避免两个活跃后端同时写同一
目录。
隔离开发环境时显式指定:
```bash
NOMIFUN_DATA_DIR=/tmp/nomifun-dev bun run serve:web
NOMIFUN_DATA_DIR=/tmp/nomifun-dev bun run dev
```
桌面端会追加 channel 对应的 `Nomi` leafWeb host 和 `nomicore` 按 env 值字面
使用。自动化脚本依赖这个行为前,请先读
[`../reference/configuration.zh.md`](../reference/configuration.zh.md)。
`NOMIFUN_WORK_DIR` 控制会话工作区位置;未设置时回退到数据目录。
## 日志
日志同时写 stdout 和 `<data-dir>/logs/nomicore.log`。示例:
```bash
NOMIFUN_LOG_LEVEL='info,nomifun_mcp=trace' bun run serve:web
```
也可以把 `--log-level` 直接传给 `nomicore` / `nomifun-web`。该值是
`tracing_subscriber::EnvFilter` 语法。
## 继续阅读
- [`project-structure.zh.md`](project-structure.zh.md)
- [`../architecture/backend-crates.md`](../architecture/backend-crates.md)
- [`../architecture/frontend.md`](../architecture/frontend.md)
- [`building-and-packaging.zh.md`](building-and-packaging.zh.md)
@@ -0,0 +1,222 @@
# Project Structure
This is the authoritative repo map for **NomiFun**. It tells you which
directory holds what, what each Rust crate is responsible for, and the one
architectural rule that keeps the agent engine extractable. For the
deep-dive on backend layering see
[`../architecture/backend-crates.md`](../architecture/backend-crates.md);
for the runtime story (how the two app hosts boot the same backend) see
[`../architecture/overview.md`](../architecture/overview.md).
## Top-level layout
```
nomifun-tauri/
├── apps/
│ ├── web/ nomifun-web bin: standalone server (API + SPA)
│ └── desktop/ nomifun-desktop bin: Tauri shell (embedded backend)
├── crates/
│ ├── agent/ 15 nomi-* crates — the AI agent engine
│ ├── backend/ 29 nomifun-* crates — the HTTP/WS backend
│ └── shared/ 2 genuine cross-layer crates
├── ui/ React SPA (Vite + UnoCSS), the only Bun workspace
│ ├── src/common/ cross-host code: API clients, types, utils
│ ├── src/platform/ tiny host bridge (storage / logger / theme)
│ ├── src/renderer/ pages, components, hooks, services, styles
│ ├── public/ static assets
│ ├── index.html Vite entry
│ └── vite.config.ts Vite config
├── docs/
│ ├── getting-started/ install + first run
│ ├── guides/ task-focused how-tos for end users
│ ├── architecture/ how NomiFun is built (runtime, crates, frontend)
│ ├── reference/ configuration, API surface, troubleshooting
│ ├── contributing/ this directory
│ ├── specs/ dated engineering design docs (historical)
│ ├── audit/ dated audit reports (historical)
│ ├── superpowers/ session-scoped planning artifacts (historical)
│ └── archive/ historical-doc policy
├── packaging/
│ └── linux/ nomifun-web.service systemd unit + README
├── Cargo.toml Rust workspace (resolver "3", edition 2024)
├── package.json root scripts (dev:ui/build, web, dev/build)
├── Dockerfile nomifun-web container image
├── docker-compose.yml single-service compose for the web host
├── Caddyfile optional TLS reverse proxy (commented in compose)
├── README.md project introduction
└── STATUS.md current technical status snapshot
```
The Cargo workspace members are exactly:
```toml
[workspace]
resolver = "3"
members = ["crates/agent/*", "crates/backend/*", "crates/shared/*", "apps/web", "apps/desktop"]
```
`crates/shared/*` is now active. Keep new shared crates rare: if a crate belongs
only to the backend or only to the agent engine, keep it in that owning group.
## App hosts
| Path | Binary | Role |
| --- | --- | --- |
| [`apps/web`](../../apps/web) | `nomifun-web` | Standalone server. Boots the unified backend in-process and serves the built SPA from the same port. Authentication on by default; `--insecure-no-auth` opts back into the desktop trust model. Replaces the old Node `web-host`. |
| [`apps/desktop`](../../apps/desktop) | `nomifun-desktop` | Tauri shell. Picks a free localhost port, starts the same backend in-process, injects `window.__backendPort` and `window.__nomiLocalTrust`, and loads the SPA into the WebView. Single-instance + dialog + notification + deep-link + updater plugins registered. |
Both hosts link `nomifun-app` directly — there is no spawned `nomicore`
binary in either flow. The `nomicore` binary still exists as the
`[[bin]]` of `nomifun-app` for headless / CI use and for the
`nomicore doctor` self-check.
## Crate groups
The Rust crates are grouped by origin and naming convention. The grouping
is the migration unit: each top-level directory under `crates/` corresponds
to a future independent repository.
| Directory | Prefix | Count | Role | Future repo |
| --- | --- | --- | --- | --- |
| [`crates/agent/`](../../crates/agent) | `nomi-*` | 15 | AI agent engine. Self-contained — no dependency on any `nomifun-*` crate. | historical extraction target |
| [`crates/backend/`](../../crates/backend) | `nomifun-*` | 29 | HTTP/WS server, data layer, auth, sessions, cron, knowledge, terminal, companion, public gateway, ... | historical extraction target |
| [`crates/shared/`](../../crates/shared) | mixed | 2 | Cross-layer utilities used by both sides. | shared |
## The agent-layer seam
Backend feature code should normally go through
[`crates/backend/nomifun-ai-agent`](../../crates/backend/nomifun-ai-agent)
when it needs agent types or agent execution. Most backend crates import
agent-facing types via
`nomifun_ai_agent::{nomi_config, nomi_types, RequirementSink}`.
The current workspace has feature-gated direct-dependency exceptions in
`nomifun-app` and `nomifun-gateway` for browser/computer-use bridge tooling.
When you add a new backend crate that needs an agent type:
1. Prefer not to add `nomi-* = ...` to your `Cargo.toml`.
2. Re-export what you need through `nomifun-ai-agent` or use what is already
re-exported there.
3. Consume it via `use nomifun_ai_agent::nomi_types::...;` etc.
4. If a direct dependency is required for a bridge/facade, gate it behind a
feature and document the exception in the crate manifest and architecture
docs.
Why: this keeps the agent engine mostly independent and prevents feature crates
from silently tying themselves to engine internals.
## `crates/agent/` — 15 `nomi-*` crates (the AI agent engine)
| Crate | One-line role |
| --- | --- |
| [`nomi-types`](../../crates/agent/nomi-types) | Pure, provider-neutral data types shared across all `nomi-*` crates. No dependencies on other agent crates. |
| [`nomi-protocol`](../../crates/agent/nomi-protocol) | JSON stream protocol for host ↔ agent communication: events (agent → host), commands (host → agent), approval manager. |
| [`nomi-compact`](../../crates/agent/nomi-compact) | Conversation-window compaction: fold / json / level / sanitize / TOON formatting. |
| [`nomi-config`](../../crates/agent/nomi-config) | Runtime configuration layer — `Config`, `ProviderCompat`, auth, hooks, provider-specific configs, file-cache. |
| [`nomi-providers`](../../crates/agent/nomi-providers) | LLM provider clients: Anthropic, Bedrock, OpenAI, Vertex; shared retry / streaming. |
| [`nomi-tools`](../../crates/agent/nomi-tools) | Built-in tools registry: bash, edit, glob, grep, read, tool-search, file-cache. |
| [`nomi-mcp`](../../crates/agent/nomi-mcp) | MCP client used by the agent: config, manager, protocol, tool-proxy, transports. |
| [`nomi-skills`](../../crates/agent/nomi-skills) | Skills system: discovery, frontmatter, loader, executor, hooks, conditional / context modifiers, bundled. |
| [`nomi-memory`](../../crates/agent/nomi-memory) | Long-term cross-session memory — preferences, feedback, project context, external references. |
| [`nomi-agent`](../../crates/agent/nomi-agent) | Core engine: session orchestration, bootstrap, commands, compaction, confirm, output sinks. |
| [`nomi-cli`](../../crates/agent/nomi-cli) | Standalone `nomi` binary that drives the engine without a host process. |
| [`nomi-computer`](../../crates/agent/nomi-computer) | Desktop computer-use tool implementation. |
| [`nomi-a11y`](../../crates/agent/nomi-a11y) | Accessibility helpers used by computer-use flows. |
| [`nomi-browser-engine`](../../crates/agent/nomi-browser-engine) | Self-hosted browser/CDP automation engine. |
| [`nomi-browser`](../../crates/agent/nomi-browser) | Browser-use tool layer. |
## `crates/backend/` — 29 `nomifun-*` crates (the backend)
| Crate | One-line role |
| --- | --- |
| [`nomifun-common`](../../crates/backend/nomifun-common) | Shared primitives: `AppError`, enums, ID generation, AES-GCM crypto, timestamps, pagination, common constants. |
| [`nomifun-assets`](../../crates/backend/nomifun-assets) | Backend-served static logo assets (`include_dir!`). |
| [`nomifun-db`](../../crates/backend/nomifun-db) | SQLite layer: `init_database`, embedded migrations, models, repository traits + sqlx implementations. |
| [`nomifun-api-types`](../../crates/backend/nomifun-api-types) | Every HTTP request/response DTO and the `WebSocketMessage` envelope; the renderer's TS types mirror this crate. |
| [`nomifun-realtime`](../../crates/backend/nomifun-realtime) | WebSocket connection manager, broadcaster, token-validated upgrade handler, message router. |
| [`nomifun-runtime`](../../crates/backend/nomifun-runtime) | Embeds bun (zstd-compressed) at build time, extracts to OS cache on first run; `enhance_process_path` merge for child processes. |
| [`nomifun-auth`](../../crates/backend/nomifun-auth) | JWT auth, bcrypt, login / refresh / setup routes, CSRF double-submit, security headers, rate limiting, `CurrentUser` extractor. |
| [`nomifun-system`](../../crates/backend/nomifun-system) | System services: provider management, model fetching, settings, version checks, Bedrock probe. |
| [`nomifun-file`](../../crates/backend/nomifun-file) | Filesystem operations: read/write, path safety, file watching, snapshots, zip. |
| [`nomifun-office`](../../crates/backend/nomifun-office) | Office-document preview, format conversion, proxy, snapshot management. |
| [`nomifun-shell`](../../crates/backend/nomifun-shell) | OS shell integration: opener, tool detection, speech-to-text. |
| [`nomifun-ai-agent`](../../crates/backend/nomifun-ai-agent) | **The single bridge to `crates/agent/`.** Agent factory, registry, worker dispatch, ACP session persistence; re-exports `nomi_config` / `nomi_types` / `RequirementSink`. |
| [`nomifun-mcp`](../../crates/backend/nomifun-mcp) | MCP server config, multi-agent sync adapters, OAuth, connection testing. |
| [`nomifun-conversation`](../../crates/backend/nomifun-conversation) | Conversation + message CRUD with streaming relay, ACP error recovery, response middleware. |
| [`nomifun-extension`](../../crates/backend/nomifun-extension) | Extension registry: manifest parsing, hub installer, skill scanning, lifecycle hooks. |
| [`nomifun-channel`](../../crates/backend/nomifun-channel) | External channel integration: plugin system, pairing handshake, per-session messaging, formatter. |
| [`nomifun-team`](../../crates/backend/nomifun-team) | Multi-agent team sessions: role-based prompts, task board, mailbox, scheduling, crash detection. |
| [`nomifun-cron`](../../crates/backend/nomifun-cron) | Scheduled-job engine: cron scheduler, executor, lifecycle event emitter, busy-guard. |
| [`nomifun-requirement`](../../crates/backend/nomifun-requirement) | Requirements Platform: CRUD store + AutoWork orchestrator + completion notifier hooks. |
| [`nomifun-idmm`](../../crates/backend/nomifun-idmm) | Intelligent Decision-Making Mode: per-session supervision keeping agent / terminal sessions alive through provider faults. |
| [`nomifun-webhook`](../../crates/backend/nomifun-webhook) | Webhook management + AutoWork completion notifications (Lark/飞书 custom bots), per-tag bindings. |
| [`nomifun-terminal`](../../crates/backend/nomifun-terminal) | PTY-backed terminal sessions managed alongside conversations; streams output via the realtime broadcaster. |
| [`nomifun-assistant`](../../crates/backend/nomifun-assistant) | User-authored assistant management; merges built-in + user + extension assistants for `GET /api/assistants`. |
| [`nomifun-knowledge`](../../crates/backend/nomifun-knowledge) | Knowledge bases, bound-base state, and scoped knowledge MCP search. |
| [`nomifun-companion`](../../crates/backend/nomifun-companion) | Desktop companions, figures, shared memory, and companion-bound state. |
| [`nomifun-gateway`](../../crates/backend/nomifun-gateway) | Desktop Gateway MCP registry and platform capability tools. |
| [`nomifun-public`](../../crates/backend/nomifun-public) | Public `/mcp`, `/mcp-agent`, and `/v1` front doors with companion-token auth. |
| [`nomifun-secret`](../../crates/backend/nomifun-secret) | Per-companion browser-use secret storage. |
| [`nomifun-app`](../../crates/backend/nomifun-app) | Application crate: assembles every domain crate into the axum server with DI + middleware. Ships the `nomicore` binary. |
> The full backend layering — request lifecycle, who owns which routes, the
> agent seam in detail — is in
> [`../architecture/backend-crates.md`](../architecture/backend-crates.md).
## `apps/web` and `apps/desktop`
Both app crates are thin: they parse a small CLI, call into `nomifun-app`'s
public boot helpers, and own the shape of the host process.
```text
apps/web/src/main.rs ~165 lines
init runtime → init data layer → AppServices → create_router →
ServeDir(ui/dist) fallback → axum::serve
apps/desktop/src/main.rs ~250 lines
pick free port → init runtime → spawn embedded backend on a tokio
thread → tauri::Builder with single-instance/dialog/notification/
deep-link/updater plugins → window init-script injects window.__backendPort
```
`nomifun-app` exposes the boot entry as a library: `bootstrap`, `cli`,
`commands`, and a `run_embedded_server` helper, plus `AppServices` and
`create_router`. The `nomicore` bin is just one of three consumers.
## `ui/` — the React SPA
The frontend is a single Bun workspace, built with **plain Vite + UnoCSS**
(no `electron-vite`).
| Path | What lives here |
| --- | --- |
| [`ui/src/common/`](../../ui/src/common) | Cross-host code reused regardless of shell: `adapter/` (HTTP / WS bridges), `api/`, `chat/`, `config/`, `platform/`, `types/`, `update/`, `utils/`, plus the package barrel `index.ts`. |
| [`ui/src/platform/`](../../ui/src/platform) | The tiny host-bridge layer: `bridge.ts`, `logger.ts`, `storage.ts`, `theme.ts`. The renderer never imports Tauri / Electron APIs directly — it goes through this layer. |
| [`ui/src/renderer/`](../../ui/src/renderer) | The app itself: `pages/`, `components/`, `hooks/`, `services/`, `styles/`, `utils/`, `assets/`, `main.tsx`, `index.html`, `types.d.ts`. |
| [`ui/src/common/utils/shims/`](../../ui/src/common/utils/shims) | Stubs for renderer-safe compatibility paths and build-time aliases. |
| [`ui/public/`](../../ui/public) | Static assets copied straight to `ui/dist/` (icons, etc.). |
| `ui/vite.config.ts` | Vite config, including the externalized-shim aliases. |
| `ui/uno.config.ts` | UnoCSS preset config. |
| `ui/tsconfig.json` | TypeScript paths and aliases that match the directory shape above. |
## Other references
| Path | Contents |
| --- | --- |
| [`STATUS.md`](../../STATUS.md) | Current technical status snapshot. |
| [`apps/desktop/updater/README.md`](../../apps/desktop/updater/README.md) | Auto-update scaffold and release-key notes. |
| [`packaging/linux/README.md`](../../packaging/linux) | Headless Linux deployment: Docker (recommended), or native binary + systemd unit. |
## Where artifacts go
| Build | Output |
| --- | --- |
| `bun run build:ui` | `ui/dist/` (the SPA) |
| `cargo build -p nomifun-web` | `target/<profile>/nomifun-web` |
| `cargo build -p nomifun-app --bin nomicore` | `target/<profile>/nomicore` |
| `bun run build` | `target/<profile>/bundle/<format>/...` (per-OS Tauri bundles) |
| `docker compose build` | local image `nomifun-web:local` |
`target/`, `ui/dist/`, `data/`, and `node_modules/` are all gitignored. See
[`building-and-packaging.md`](building-and-packaging.md) for the per-output
details.
@@ -0,0 +1,89 @@
# 项目结构
这是 **NomiFun** 的当前仓库地图。后端分层详见
[`../architecture/backend-crates.md`](../architecture/backend-crates.md),运行时总览见
[`../architecture/overview.md`](../architecture/overview.md)。
## 顶层布局
```text
nomifun-tauri/
├── apps/
│ ├── web/ nomifun-web:独立 Web/API host
│ └── desktop/ nomifun-desktopTauri 桌面壳
├── crates/
│ ├── agent/ 15 个 nomi-* crateAI agent 引擎
│ ├── backend/ 29 个 nomifun-* crateHTTP/WS 后端
│ └── shared/ 2 个真正跨层共享 crate
├── ui/ React SPAVite + UnoCSS,唯一 Bun workspace
├── docs/ 当前文档、历史设计、审计与归档说明
├── packaging/linux/ nomifun-web systemd unit 与部署说明
├── Cargo.toml Rust workspace
├── package.json Bun/Tauri/Cargo 入口脚本
├── Dockerfile nomifun-web 容器镜像
├── docker-compose.yml Web host compose 示例
├── Caddyfile 可选 TLS reverse proxy
├── README.md
└── STATUS.md
```
Cargo workspace 当前成员:
```toml
members = ["crates/agent/*", "crates/backend/*", "crates/shared/*", "apps/web", "apps/desktop"]
```
## App Host
| 路径 | Binary | 职责 |
| --- | --- | --- |
| [`apps/web`](../../apps/web) | `nomifun-web` | 独立 Web/API host。进程内启动 `nomifun-app`,同端口提供 API、WebSocket 和 SPA。默认开启登录;`--insecure-no-auth` 仅供可信本地开发。 |
| [`apps/desktop`](../../apps/desktop) | `nomifun-desktop` | Tauri 桌面壳。进程内启动同一个后端,选择空闲 localhost 端口,注入 `window.__backendPort``window.__nomiLocalTrust`WebView 通过本地信任 token 访问后端。 |
两个 host 都直接链接 `nomifun-app``nomicore` 仍作为 `nomifun-app` 的独立
binary 存在,用于诊断、stdio MCP bridge、公开能力调用和无头场景;桌面/Web host
不会 spawn 它。
## Crate 分组
| 目录 | 前缀 | 数量 | 职责 |
| --- | --- | --- | --- |
| [`crates/agent/`](../../crates/agent) | `nomi-*` | 15 | AI agent 引擎,尽量保持独立。 |
| [`crates/backend/`](../../crates/backend) | `nomifun-*` | 29 | HTTP/WS 后端、数据层、认证、会话、cron、knowledge、terminal、companion、public gateway 等。 |
| [`crates/shared/`](../../crates/shared) | mixed | 2 | 真正跨 agent/backend 使用的共享工具。 |
## Agent 层接缝
后端代码需要 agent 类型或执行能力时,默认应通过
[`crates/backend/nomifun-ai-agent`](../../crates/backend/nomifun-ai-agent)。
它再导出常用的 `nomi_config``nomi_types``RequirementSink`
当前 workspace 仍存在少数 feature-gated 直接依赖例外:`nomifun-app`
`nomifun-gateway` 为 browser/computer-use bridge 工具直接触达部分 `nomi-*`
crate。新增后端 crate 时不要随手添加 `nomi-*` 依赖;若确实是 bridge/facade
例外,需要用 feature gate 并在架构文档中说明。
## 关键目录
| 路径 | 内容 |
| --- | --- |
| [`ui/src/common/`](../../ui/src/common) | 跨 host 的 API client、类型、adapter、工具函数。 |
| [`ui/src/platform/`](../../ui/src/platform) | host bridgestorage、logger、theme、平台能力。 |
| [`ui/src/renderer/`](../../ui/src/renderer) | 页面、组件、hooks、服务、样式和 renderer 入口。 |
| [`ui/src/common/utils/shims/`](../../ui/src/common/utils/shims) | renderer-safe 兼容 shim 与构建别名目标。 |
| [`docs/getting-started/`](../getting-started) | 安装与首次运行。 |
| [`docs/guides/`](../guides) | 用户任务指南。 |
| [`docs/architecture/`](../architecture) | 当前架构说明。 |
| [`docs/reference/`](../reference) | 配置、API、FAQ、troubleshooting。 |
## 制品位置
| 构建 | 输出 |
| --- | --- |
| `bun run build:ui` | `ui/dist/` |
| `cargo build -p nomifun-web` | `target/<profile>/nomifun-web` |
| `cargo build -p nomifun-app --bin nomicore` | `target/<profile>/nomicore` |
| `bun run build` | `target/<profile>/bundle/<format>/...` |
| `docker compose build` | 本地镜像 `nomifun-web:local` |
更多打包细节见 [`building-and-packaging.zh.md`](building-and-packaging.zh.md)。