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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

### 新增

- P1.2:`freeos org export-standalone` 默认 `--mode full` 写出可商业化 openXYOS **源码包**(`openxyos/` Apache-2.0 完整 App.tsx 树 + `slice/` MIT 宿主桥 + `modules.json` 对照清单)。`--mode slice` 保留原先 org-ui SPA + `FREEOS_UPSTREAM` 反代。工作室智能体对话不导出;组织沟通协作在完整树。说明见 `docs/org-export.md`。
- Organization P1.1(双向资产总线):`freeos org loop run` / `POST /api/org-module/loop/run` / `assets apply` 在托管组织运行时、`OPENXYOS_BASE_URL` 或 `{FREEOS_HOME}/org-os/runtime.json` 可用时,把资产包 ingest 进当前**组织工作区租户**(`remote_applied=true`),不再只写 `openxyos-mirror/`。无运行时地址时仍为镜像-only,且不拉起 Node。回流后同事仍登记为 `org-<slug>` 聊天智能体。FreeOS 工作室账号与组织房间身份分开。说明见 `docs/asset-loop.md`。
- P0.2:openXYOS → FreeOS 能力迁移图(`docs/org-capability-migration-map.md` / `.zh-CN.md` + `docs/org-capability-migration-map.json`)。按域记录原生宿主 / org-ui 切片 / 托管 Node iframe / 可选边车 / 仅导出;波次为资产总线 → 导出 → 双身份 UX → 本地模型/知识库 → 拆除 Node。不改运行时。
- Organization Phase 5(默认安装器瘦身):Windows/macOS/Linux 默认包装与 Docker Compose 保持 **单进程 FreeOS + 宿主内 Organization**,不捆绑、不解压、不自动拉起 openXYOS Node。`FREEOS_ORG_SIDECAR=1` 与 `SHIP_OPENXYOS_RUNTIME=1` 仍是可选高级路径。文档对齐 #55 / ADR 001 / ADR 003 / `docs/org-export.md`。`modules/openxyos` 保留给导出与开发,不是默认运行时。
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ The TypeScript sidecar under `modules/openxyos/` is an optional **transition bri
| CLI | `uv run freeos org enable` · `uv run freeos org status` · `uv run freeos org loop run` |
| Plugin | Admin → Plugins → **Organization OS** (`org-os`) |
| API | `PATCH /api/org-module` with `{ "enabled": true }` |
| Standalone commercial site | `uv run freeos org export-standalone --out dist/openxyos-web` — see [docs/org-export.md](docs/org-export.md) |
| Standalone commercial site | `uv run freeos org export-standalone --out dist/openxyos-web` — default `--mode full` writes an openXYOS source tree plus host-bridge slice; see [docs/org-export.md](docs/org-export.md) |

Optional Node sidecar (export/sync/advanced deploy only):

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ curl -fsSL https://finnie-1258344699.cos.ap-guangzhou.myqcloud.com/octop/install
| Linux | `FreeOS-desktop-linux-amd64-<version>.tar.gz` / `FreeOS-desktop-linux-arm64-<version>.tar.gz` |
| 飞牛 NAS(FnOS) | `Octop-fnos-docker-<version>.fpk`(依赖 Docker)/ `Octop-fnos-native-<version>.fpk`(无需 Docker)— 通过应用中心安装 |

桌面客户端说明见 [desktop/README.md](desktop/README.md),飞牛打包指南见 [fnos/README.md](fnos/README.md)。独立商业组织站见 [docs/org-export.md](docs/org-export.md)(`freeos org export-standalone`),不是默认安装器里的第二套 Node。
桌面客户端说明见 [desktop/README.md](desktop/README.md),飞牛打包指南见 [fnos/README.md](fnos/README.md)。独立商业组织站见 [docs/org-export.md](docs/org-export.md)(`freeos org export-standalone`,默认导出完整 openXYOS 源码树),不是默认安装器里的第二套 Node。

**备选 — PyPI**(若你已自行管理 Python 环境):

Expand Down
4 changes: 2 additions & 2 deletions docs/architecture-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ FreeOS/Octop remains the execution runtime.
- [ADR 001](adr/001-single-process-model.md) — single process, no external queue
- [ADR 003](adr/003-org-ui-single-source-dual-delivery.md) — org-ui single source, dual delivery (Accepted; read the Current banner)
- [org-merge-plan.md](org-merge-plan.md) — Phases 0–5 history; Phase-5 zero-Node is a transition default
- [org-export.md](org-export.md) — standalone commercial Organization site (`freeos org export-standalone`)
- [org-export.md](org-export.md) — standalone commercial openXYOS source pack (`freeos org export-standalone`)
- [asset-loop.md](asset-loop.md) — operator self-growth loop
- [ADR index](adr/)

Expand Down Expand Up @@ -305,7 +305,7 @@ The Phase A work sits on the existing FreeOS bootstrap:
| Self-growth loop | Bridge | `freeos org loop run` · `/api/org-module/loop/run` |
| Colleague agents | Host agents table | `org-<slug>` · `{home}/org-agents/` · tenant `routing.json` |
| Org APIs | Host BFF + optional sidecar | `/api/org-module/*` in-host (announcements + org chart CRUD are in-host); sidecar `/api/org`, `/api/employees`, … until each remaining CRUD slice moves (see [org-merge-plan.md](org-merge-plan.md)) |
| Org UI | Host Dashboard (`org-ui`) | Native `/organization` workbench + Open-12 host routes (shared `dashboard/src/org-ui`). Standalone site is **exported** from the same source (`freeos org export-standalone` → Vite SPA + local JWT + proxy to host `/api/org-module`; see [org-export.md](org-export.md)). Sidecar `:3780` iframe is opt-in compat only |
| Org UI | Host Dashboard (`org-ui`) | Native `/organization` workbench + Open-12 host routes (shared `dashboard/src/org-ui`). Standalone commercial pack is **exported** (`freeos org export-standalone` → default full openXYOS source tree + MIT host-bridge slice; see [org-export.md](org-export.md)). Sidecar `:3780` iframe is opt-in compat only |

### Auth and tenant mapping

Expand Down
12 changes: 7 additions & 5 deletions docs/org-capability-migration-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,24 +206,26 @@
"name_zh": "独立站导出(商业加售)",
"lives_today": [
"src/octop/modules/org_os/export_standalone.py",
"src/octop/cli/commands/org.py export-standalone",
"src/octop/cli/commands/org.py export-standalone --mode full|slice",
"scripts/org-export/template/",
"dashboard/src/org-ui (copied into dist)",
"scripts/org-export/pack/",
"modules/openxyos (copied into dist/openxyos)",
"dashboard/src/org-ui (copied into dist/slice)",
"docs/org-export.md"
],
"status": "export_only",
"depends_on_node": "partial",
"needed_for_commercial_export": "yes",
"priority": "P0",
"next_step": "Replace SPA + proxy to FREEOS_UPSTREAM /api/org-module with an exportable openXYOS source tree that a customer can self-host; today's package is an early delivery, not the finished product.",
"next_step": "Unify with POST /api/org-module/source/download; optional self-contained API inside the slice. Default --mode full already copies the openXYOS source tree; do not freeze slice-only SPA+proxy as the commercial artifact.",
"wave": "B-export",
"evidence": [
"docs/org-export.md transitional vs target table",
"docs/org-export.md dual-mode full vs slice",
"src/octop/modules/org_os/contract.py SHARED_ORG_UI_MODULES"
],
"tests": ["tests/unit/cli/test_org_export_standalone.py"],
"unknowns": [
"Self-contained org API inside the export package is still a stated target, not implemented."
"Self-contained org API inside the slice is still a stated follow-on, not implemented."
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions docs/org-capability-migration-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Priority: **P0 = 7** (waves A–D) · **P1 = 17** · **P2 = 10**.
| Domain | Status | Node? | Export? | Pri | Next engineering step |
|---|---|---|---|---|---|
| [Bidirectional assets bus](#1-bidirectional-assets-bus) | native_host | partial | yes | P0 | Host-owned ingest/export that does not need live Node `/api/freeos/ingest`. |
| [Export-standalone](#2-export-standalone-commercial-package) | export_only | partial | yes | P0 | Replace SPA+proxy with exportable openXYOS **source**. |
| [Export-standalone](#2-export-standalone-commercial-package) | export_only | partial | yes | P0 | Default `--mode full` writes the openXYOS **source tree**; `--mode slice` is the SPA+proxy host bridge. |
| [Tenant / auth (dual identity)](#3-tenant--auth-dual-identity) | managed_node_iframe | partial | yes | P0 | Two auth spaces; stop Node `/api/auth` as org-room authority. |
| [Local models](#4-local-models) | native_host | partial | yes | P0 | Org room uses the studio local-model pool, not sidecar `/api/settings/ai`. |
| [Host knowledge bases](#5-host-knowledge-bases) | native_host | no | partial | P0 | Keep local RAG default; cloud connectors optional. |
Expand Down Expand Up @@ -120,14 +120,14 @@ These shipping shapes still need a native port. They are bridges.

| | |
|---|---|
| **Lives today** | `export_standalone.py`, `freeos org export-standalone`, `scripts/org-export/template/`, copy of `dashboard/src/org-ui`, [org-export.md](org-export.md) |
| **Lives today** | `export_standalone.py`, `freeos org export-standalone` (`--mode full` default copies `modules/openxyos` + `slice/`), `scripts/org-export/template/` + `pack/`, copy of `dashboard/src/org-ui`, [org-export.md](org-export.md) |
| **Status** | `export_only` |
| **Depends on Node?** | partial (dev-time Node to build Vite; runtime proxies to FreeOS) |
| **Depends on Node?** | partial (full tree **runs** with Node; slice still proxies to FreeOS) |
| **Commercial export?** | yes |
| **Priority** | P0 · Wave B |
| **Next step** | Exportable openXYOS **source tree** a customer can self-host. SPA + `FREEOS_UPSTREAM` proxy is an early delivery, not the finished product. |
| **Next step** | Unify with `POST /api/org-module/source/download`; optional self-contained API inside the slice. Do not freeze slice-only SPA+proxy as the commercial artifact. |
| **Tests** | `tests/unit/cli/test_org_export_standalone.py` |
| **Unknown** | Self-contained org API inside the package is a stated target, not implemented. |
| **Unknown** | Slice self-contained org API is still a stated follow-on, not implemented. |

### 3. Tenant / auth (dual identity)

Expand Down
10 changes: 5 additions & 5 deletions docs/org-capability-migration-map.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
| 域 | 状态 | 依赖 Node? | 商业导出? | 优先级 | 下一步(一行) |
|---|---|---|---|---|---|
| [双向资产总线](#1-双向资产总线) | native_host | 部分 | 是 | P0 | 宿主自有 ingest/export,不依赖活着的 Node `/api/freeos/ingest`。 |
| [独立站导出](#2-独立站导出商业加售) | export_only | 部分 | 是 | P0 | 用可导出的 openXYOS **源码树** 替换 SPA+反代。 |
| [独立站导出](#2-独立站导出商业加售) | export_only | 部分 | 是 | P0 | 默认 `--mode full` 写出 openXYOS **源码树**;`--mode slice` 仍是 SPA+反代宿主桥。 |
| [租户与身份(双入口)](#3-租户与身份双入口) | managed_node_iframe | 部分 | 是 | P0 | 两套身份空间;组织房间不再以 Node `/api/auth` 为权威。 |
| [本地模型](#4-本地模型) | native_host | 部分 | 是 | P0 | 组织房间使用工作室同一套本机模型池,而不是边车 `/api/settings/ai`。 |
| [宿主知识库](#5-宿主知识库) | native_host | 否 | 部分 | P0 | 默认本地 RAG;云连接器可选。 |
Expand Down Expand Up @@ -120,14 +120,14 @@

| | |
|---|---|
| **今日位置** | `export_standalone.py`、`freeos org export-standalone`、`scripts/org-export/template/`、拷贝 `dashboard/src/org-ui`、[org-export.md](org-export.md) |
| **今日位置** | `export_standalone.py`、`freeos org export-standalone`(默认 `--mode full` 拷贝 `modules/openxyos` + `slice/`)、`scripts/org-export/template/` + `pack/`、拷贝 `dashboard/src/org-ui`、[org-export.md](org-export.md) |
| **状态** | `export_only` |
| **依赖 Node?** | 部分(构建 Vite 需要 Node;运行时反代到 FreeOS) |
| **依赖 Node?** | 部分(完整树 **运行** 需要 Node;slice 仍反代到 FreeOS) |
| **商业导出?** | 是 |
| **优先级** | P0 · 波次 B |
| **下一步** | 客户可自托管的 openXYOS **源码树**。SPA + `FREEOS_UPSTREAM` 反代只是早期交付,不是成品。 |
| **下一步** | 与 `POST /api/org-module/source/download` 合一;slice 内自包含 API 仍可选。不要把仅 slice 的 SPA+反代冻成商业交付物。 |
| **测试** | `tests/unit/cli/test_org_export_standalone.py` |
| **未知** | 包内自包含 org API 仍是目标,未实现。 |
| **未知** | slice 内自包含 org API 仍是跟进项,未实现。 |

### 3. 租户与身份(双入口)

Expand Down
89 changes: 63 additions & 26 deletions docs/org-export.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,58 @@
# 独立组织站导出(Phase 4 包 + Phase 5 默认安装器)
# 独立组织站导出(可商业化 openXYOS 源码包)

> **Historical vs Current.** **Current:** [产品契约](product-contract.zh-CN.md)。导出可商业化的 openXYOS **系统源码** 是目标;本页描述的 `export-standalone`(SPA + 反代到宿主)是早期交付,不是完成品。Phase-5 默认零 Node 与可选 sidecar/iframe 都是过渡桥。组织像工作室里另一间房间,与日常用法各自留白。本文件不改导出实现(那是后续项)。
> **Current:** [产品契约](product-contract.zh-CN.md)。`freeos org export-standalone` 默认写出可商业化的 openXYOS **系统源码**(`--mode full`:完整 `App.tsx` 树 + 宿主桥 slice)。`--mode slice` 仍是早期的 org-ui SPA + 反代,给只想对接宿主 `/api/org-module` 的场景。Phase-5 默认零 Node 与可选 sidecar/iframe 仍是过渡桥,不是本导出物。组织像工作室里另一间房间,与日常用法各自留白。

`freeos org export-standalone --out <dir>` 从 **同一套** `dashboard/src/org-ui` 生成可部署的 openXYOS 风格独立站。这是商业加售的早期交付物,不是第二份手维护前端。
`freeos org export-standalone --out <dir>` 从 FreeOS 检出生成 **一份可二次产品化的源码包**。默认不是「只有薄壳 + 反代」。

默认 FreeOS 安装器 **不** 捆绑 Node,也 **不** 自动拉起 openXYOS。Sidecar 仅作可选兼容(`FREEOS_ORG_SIDECAR=1` / `SHIP_OPENXYOS_RUNTIME=1`)。这是 **Phase 5** 已落地的默认拓扑(过渡态):一个 Python 进程 + 宿主内 Organization。
默认 FreeOS 安装器 **不** 捆绑 Node,也 **不** 自动拉起 openXYOS。Sidecar 仅作可选兼容(`FREEOS_ORG_SIDECAR=1` / `SHIP_OPENXYOS_RUNTIME=1`)。这是 **Phase 5** 已落地的默认拓扑(过渡态):一个 Python 进程 + 宿主内 Organization。导出是显式的商业/运营动作,不改变桌面包。

## 生成

在 FreeOS 源码检出里:

```bash
uv run freeos org export-standalone --out dist/openxyos-web
# 等同 --mode full
uv run freeos org export-standalone --out dist/openxyos-web --mode slice
```

输出目录自带:
### `--mode full`(默认)

- Vite + React 壳,路由对齐 OpenApp(`/app`、`/announcements`、`/org`、`/employees`、`/skills`、`/agents`、`/tasks`、`/knowledge`、`/reflections`、`/governance`、`/settings`)
- 拷贝后的 `src/org-ui`(不含测试)
- 独立 IdentityBridge:本地 JWT,键名 `openxyos.standalone.jwt`(**不是** Dashboard 的 `auth_token`)
- 登录页 → `POST /api/auth/login`
- `Dockerfile` + `docker-compose.yml` + `server/proxy.mjs`
| 路径 | 内容 | 许可证 |
|---|---|---|
| `openxyos/` | `modules/openxyos` 拷贝(完整 `App.tsx` + Express) | Apache-2.0 |
| `slice/` | `dashboard/src/org-ui` + Vite/Docker 宿主桥 | MIT |
| `modules.json` | 路由/模块清单,对照桌面 `/organization` | — |
| `README.md` / `README.zh-CN.md` | 含什么、仍反代什么、怎么跑、商业化说明 | — |

完整树用 Node 跑原来的组织前端(Open-12、商业垂类、组织沟通协作)。slice 仍把 `/api` 反代到 FreeOS。

**Chat 不导出。** `/chat` 只是深链说明页。
### `--mode slice`

模板源在 `scripts/org-export/template/`。改页面请改 `dashboard/src/org-ui`,再重新导出。
只写出 MIT SPA(与 full 包里的 `slice/` 相同):OpenApp 风格路由、本地 JWT、登录页、Docker、`server/proxy.mjs`。**工作室智能体对话不导出。** 组织沟通协作在完整树里;slice 的 `/chat` 是说明页。`/coverage` 展示与 App.tsx / 宿主清单的对照。

模板源在 `scripts/org-export/template/`(slice)与 `scripts/org-export/pack/`(full 包说明)。改宿主切片页面请改 `dashboard/src/org-ui`,再重新导出。

## 客户怎么跑

详见导出目录里的 `README.md`。最短路径:
详见导出目录里的 README。最短路径:

**完整组织应用(产品化):**

```bash
cd dist/openxyos-web/openxyos
npm ci
npm run dev
```

完整树使用 **组织房间自己的注册/登录**,与 FreeOS 工作室日常入口分开。

**宿主桥 slice:**

```bash
cd dist/openxyos-web
cd dist/openxyos-web/slice # 或 --mode slice 时的输出根
cp .env.example .env
# 把 FREEOS_UPSTREAM 指到已有 FreeOS(默认 http://127.0.0.1:8088)
# FREEOS_UPSTREAM 指向已有 FreeOS(默认 http://127.0.0.1:8088)
npm install
npm run dev
```
Expand All @@ -44,30 +63,48 @@ npm run dev
FREEOS_UPSTREAM=http://127.0.0.1:8088 docker compose up --build
```

浏览器打开 `http://127.0.0.1:3780`。**Historical / 当前实现:** 登录打 FreeOS `/api/auth/login`。**Current 契约:** 导出站最终应能带上组织房间自己的进入方式;不要把「用工作室日常入口登录独立站」写成终态模型。
浏览器打开 `http://127.0.0.1:3780`。slice 登录目前打宿主 `/api/auth/login`,只是过渡桥,不是组织房间终态。

## 对照桌面组织模块

导出根目录(full)或 `src/modules.json`(slice)列出:

## 过渡路径 vs 目标终态
- 已抽到 `org-ui` 的宿主切片
- Dashboard `/organization/…` 路由
- `App.tsx` / `OpenApp.tsx` 每条路由的 `in_slice` / `in_full_tree` / `host_route_exists`
- **有意省略**:工作室智能体对话;桌面 iframe / NSIS;slice 不含商业垂类与组织会话(完整树含)

| | 本波(可演示) | 目标终态 |
slice SPA 的 `/coverage` 用同一份清单做可视化对照。

## 仍走宿主反代的

| | `--mode slice` / `slice/` | `--mode full` 的 `openxyos/` |
|---|---|---|
| UI | 本包 SPA(org-ui) | 同一套 org-ui |
| API | 反向代理到 FreeOS `/api/org-module/*` | 本包自包含服务实现同一合同 |
| 身份 | 本地 JWT,登录打 FreeOS `/api/auth/login` | 客户自己的账号体系发本地 JWT |
| 安装器 | **已落地(Phase 5)**:默认零 Node,sidecar 仅 opt-in | 保持单进程;不把独立站 Node 打进默认安装包 |
| UI | org-ui SPA(Open-12) | 完整 App.tsx |
| API | 反代到 FreeOS `/api/org-module/*` | 自包含 Express |
| 身份 | 本地 JWT;登录打宿主(过渡桥) | 组织房间自己的 `/api/auth` |
| 安装器 | 不打进默认包 | 不打进默认包 |

`VITE_API_BASE` 默认 `/api`(同源)。不要在浏览器里直连另一个源的 FreeOS,除非那个宿主已配好 CORS。推荐始终走代理。
`VITE_API_BASE` 默认 `/api`(同源)。不要在浏览器里直连另一个源的 FreeOS,除非那个宿主已配好 CORS。slice 推荐始终走代理。

## 配置
## 配置(slice)

| 变量 | 时机 | 含义 |
|---|---|---|
| `VITE_API_BASE` | 构建 | SPA 的 API 前缀,默认 `/api` |
| `FREEOS_UPSTREAM` | 运行 | 拥有 `/api/org-module` 与 `/api/auth` 的 FreeOS 源 |
| `PORT` | `npm start` / Vite | 监听端口,默认 `3780` |

## 许可证

- **Apache-2.0**:`openxyos/`(及未改动拷贝),见该目录 `LICENSE` / `NOTICE`
- **MIT**:宿主桥 `slice/`(Vite 壳、IdentityBridge、拷贝的 org-ui、Docker/反代),见 `slice/LICENSE`
- 商标:`openXYOS` / `XYOS` 仅用于源码归属,见 `openxyos/TRADEMARKS.md`(若有)

## 非目标 / 残留

- 重写整套 Express → 独立 Node API(导出仍代理到宿主 `/api/org-module`)
- 迁 openXYOS Chat
- 把 slice 也做成自包含 Express(slice 仍反代宿主 `/api/org-module`)
- 导出 FreeOS / Octop **工作室智能体对话**(组织沟通协作在完整树里)
- 抽出 `packages/org-ui` monorepo(仅当 Dashboard Vite 图必须脱离时再做)
- 把独立站 Node 打进默认 Windows/macOS/Linux 安装器(明确不做)
- 与 `POST /api/org-module/source/download`(GitHub 上游 zip)合成单一产物(仍是跟进项)
Loading
Loading