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
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@ jobs:
run: |
npm run cli:build:prod -- --target=${{ matrix.target }}

- name: Prepare bundled Pi runtime
shell: bash
run: |
case "${{ matrix.target }}" in
aarch64-apple-darwin) platform=darwin; arch=arm64 ;;
x86_64-apple-darwin) platform=darwin; arch=x64 ;;
*-windows-msvc) platform=win32; arch=x64 ;;
*-linux-gnu) platform=linux; arch=x64 ;;
*) echo "Unsupported Pi release target: ${{ matrix.target }}" >&2; exit 1 ;;
esac
node scripts/prepare-pi-bundle.mjs --platform "$platform" --arch "$arch"
echo "FLOWIX_PI_TARGET_ARCH=$arch" >> "$GITHUB_ENV"

- name: Import Windows signing certificate for Tauri
if: matrix.target == 'x86_64-pc-windows-msvc'
shell: pwsh
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Flowix 是一款桌面笔记应用(**Tauri 2 + Rust 后端,React 19 + TS + T

```bash
export PATH="$HOME/.cargo/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
npm run tauri:dev # 推荐:独立 dev bundle ID (com.flowix.app.dev / "Flowix Dev"),可与生产 app 并存
npm run tauri:dev # 推荐:独立 dev bundle ID (com.flowix-dev.app / "Flowix Dev"),可与生产 app 并存
npm run tauri:dev:win # Windows 开发启动:使用 app/flowix-desktop/tauri.windows.dev.conf.json
npm run tauri dev # ⚠️ 走默认 tauri.conf.json,与生产同 bundle ID (com.flowix.app),已被生产占住时会立刻 exit 0
npm run dev # 仅前端 (localhost:1420)
Expand All @@ -35,12 +35,12 @@ cargo test --workspace --lib # 跑全部

通过差异化 Tauri 配置,让 dev 版与已安装的生产版同时运行:

- **dev**:`npm run tauri:dev` → `app/flowix-desktop/tauri.conf.dev.json` → bundle ID `com.flowix.app.dev` / `Flowix Dev`
- **dev**:`npm run tauri:dev` → `app/flowix-desktop/tauri.conf.dev.json` → bundle ID `com.flowix-dev.app` / `Flowix Dev`
- **生产**:`npm run tauri:build:prod` → `tauri.conf.json` + 平台覆盖层 + 签名覆盖层 → 平台专用 `tauri.*.production.local.json` → bundle ID `com.flowix.app` / `Flowix`

`tauri:dev` 通过 `--config` 指向独立配置,**不要**改 `tauri.conf.json` 的 `identifier` / `productName` / `mainBinaryName` / `bundle.macOS.bundleName` —— 这四个字段是生产身份的锚点。`tauri.conf.production.json` 作为覆盖层被 `tauri build --config` 深合并在 `tauri.conf.json` 之上,因此 dev 配置改动不会污染生产链路。

dev 与生产现使用不同 bundle ID(`com.flowix.app.dev` vs `com.flowix.app`),可同时运行且互不冲突(Tauri `app_data_dir` / `tauri-plugin-single-instance` lock 都按 identifier 派生)。代价:dev 首次运行需要重新授予一次 user-selected folder 授权(TCC 按 identifier 记忆授权),prod 已授予的不会带过来。视觉上仍通过 bundle name / 窗口标题区分(`Flowix Dev` vs `Flowix`)。URL scheme `flowix://` 仍共用,让浏览器深链能落到任一已装实例。
dev 与生产现使用不同 bundle ID(`com.flowix-dev.app` vs `com.flowix.app`),可同时运行且互不冲突(Tauri `app_data_dir` / `tauri-plugin-single-instance` lock 都按 identifier 派生)。代价:dev 首次运行需要重新授予一次 user-selected folder 授权(TCC 按 identifier 记忆授权),prod 已授予的不会带过来。视觉上仍通过 bundle name / 窗口标题区分(`Flowix Dev` vs `Flowix`)。Dev 使用独立 URL scheme `flowix-dev://`,以便浏览器回调明确交给 Dev 实例。

### macOS 本地生产包 ad-hoc 签名

Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,21 @@ git clone https://github.com/text2future/flowix.git
cd flowix
npm install

npm run tauri dev
npm run dev
npm run tauri build
npm run tauri:dev
npm run tauri:build:prod
```

Run `npm run dev` separately only when you want the Vite frontend without the Tauri desktop backend.

The desktop dev build (`npm run tauri:dev`) connects to `https://cloud.flowix.cc` by default. In Preferences → Development → Environment configuration, choose Staging or Prod; Flowix restarts to apply the change. The saved preference is authoritative and takes precedence over the build default. `--cloud-env=staging|prod` sets that default and is used until a preference is saved. The environments keep separate sign-in credentials and sync databases.

```bash
npm run tauri:dev -- --cloud-env=staging
npm run tauri:dev -- --cloud-env=prod
```

`npm run tauri:dev:pi` and `npm run tauri:dev:win` accept the same option. Production packages built with `npm run tauri:build:prod` always connect to `https://cloud.flowix.cc`, and do not show the environment selector. Running `npm run dev` alone starts only the Vite frontend; it does not start desktop Cloud sync.

The development environment requires Node.js 20+, Rust 1.75+ and Tauri v2; the desktop app supports macOS 14+ and Windows 10+.

## License
Expand Down
16 changes: 13 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,21 @@ git clone https://github.com/text2future/flowix.git
cd flowix
npm install

npm run tauri dev
npm run dev
npm run tauri build
npm run tauri:dev
npm run tauri:build:prod
```

单独运行 `npm run dev` 只启动 Vite 前端,不会启动 Tauri 桌面后端。

桌面开发版 `npm run tauri:dev` 默认连接 `https://cloud.flowix.cc`。在「偏好设置 → 开发 → 环境配置」中选择 Staging 或 Prod,Flowix 会重启以应用切换。首次启动默认使用 Prod;已保存的界面选择优先于构建默认值;`--cloud-env=staging|prod` 设置默认值,仅在尚未保存界面选择时生效:

```bash
npm run tauri:dev -- --cloud-env=staging
npm run tauri:dev -- --cloud-env=prod
```

`npm run tauri:dev:pi` 和 `npm run tauri:dev:win` 也接受该参数。正式包 `npm run tauri:build:prod` 始终连接 `https://cloud.flowix.cc`,不会显示环境下拉。单独运行 `npm run dev` 只启动 Vite 前端,不会启动桌面端 Cloud 同步。

开发环境要求 Node.js 20+、Rust 1.75+ 与 Tauri v2;桌面应用支持 macOS 14+ 与 Windows 10+。

## 许可协议
Expand Down
29 changes: 6 additions & 23 deletions app/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ members = [

# 锁定共用依赖到同一版本 ── 避免 backend / cli 走不一致版本。
[workspace.package]
version = "1.5.6"
version = "1.5.8"
edition = "2021"

# 锁定共用依赖到同一版本 ── 避免 backend / cli 走不一致版本。
Expand All @@ -25,7 +25,6 @@ serde_yaml = "0.9"
toml = "0.8"
tauri-plugin-process = "2"
tauri-plugin-updater = "2"
tauri-plugin-opener = "2"
chrono = { version = "0.4", features = ["serde"] }
dirs = "5.0"
walkdir = "2.4"
Expand Down
2 changes: 1 addition & 1 deletion app/flowix-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "flowix-cli"
version = "1.5.6"
version = "1.5.8"
description = "Flowix 命令行工具 ── 共享同一份 memo_file 存储, 跟桌面端 watcher 双向同步"
authors = ["Flowix Contributors"]
edition.workspace = true
Expand Down
6 changes: 3 additions & 3 deletions app/flowix-cli/src/collection_store.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Read-only collection dataset access shared by the CLI and MCP operation layer.
use crate::{errors::CliError, store};
use flowix_core::{
collection::{valid_id, CollectionDocument, CollectionPlacement, CollectionType},
collection::{display_name_for_path, valid_id, CollectionDocument, CollectionPlacement, CollectionType},
memo_file::FileManagementPolicy,
};
use rusqlite::Connection;
Expand All @@ -23,7 +23,7 @@ pub(crate) fn read(
}

let memo = store::open()?;
let notebook = flowix_core::MemoService::new(&memo).resolve_notebook(notebook_key)?;
let notebook = store::resolve_notebook_config(&memo, notebook_key)?;
let root = fs::canonicalize(&notebook.path)?;
let policy = FileManagementPolicy::from_notebook_root(&root);
let (path, document) = if let Some(id) = collection_id {
Expand All @@ -50,7 +50,7 @@ pub(crate) fn read(
"collection": {
"id": document.collection.id,
"type": document.collection.kind.as_str(),
"name": document.collection.name,
"name": display_name_for_path(&path, document.collection.placement),
"revision": document.collection.revision,
"createdAt": document.collection.created_at,
"updatedAt": document.collection.updated_at,
Expand Down
10 changes: 5 additions & 5 deletions app/flowix-cli/src/path_store.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Path-addressed note operations shared by the CLI, MCP and operation API.
use crate::{errors::CliError, store};
use flowix_core::{memo_file::NotebookConfig, MemoService, NoteService};
use flowix_core::{memo_file::NotebookConfig, NoteService};
use serde_json::{json, Value};
use std::{io::Read, path::Path};

Expand Down Expand Up @@ -67,7 +67,7 @@ fn document_json(document: &flowix_core::service::NoteDocument) -> Value {

pub(crate) fn list(notebook_key: &str) -> Result<Value, CliError> {
let mf = store::open()?;
let notebook = MemoService::new(&mf).resolve_notebook(notebook_key)?;
let notebook = store::resolve_notebook_config(&mf, notebook_key)?;
mf.reconcile_note_index_blocking(&notebook.id)?;
let notes = NoteService::new(&mf).list(&notebook.id)?;
Ok(json!({"notebookId": notebook.id, "notes": notes}))
Expand All @@ -84,7 +84,7 @@ pub(crate) fn create(notebook_key: &str, content: &str) -> Result<Value, CliErro
return Err(CliError::Usage("create: content is empty".into()));
}
let mf = store::open()?;
let notebook = MemoService::new(&mf).resolve_notebook(notebook_key)?;
let notebook = store::resolve_notebook_config(&mf, notebook_key)?;
let parent = flowix_core::memo_file::default_create_folder_for_notebook(Path::new(&notebook.path))
.map_err(CliError::Other)?;
let document = NoteService::new(&mf).create(
Expand Down Expand Up @@ -181,9 +181,9 @@ pub(crate) fn search(
})
.transpose()?;
let mf = store::open()?;
let configs = MemoService::new(&mf).list_notebooks()?;
let configs = mf.read_notebook_configs()?;
let selected = if let Some(key) = notebook_filter {
vec![MemoService::new(&mf).resolve_notebook(key)?]
vec![store::resolve_notebook_config(&mf, key)?]
} else {
configs
};
Expand Down
4 changes: 2 additions & 2 deletions app/flowix-cli/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};

use crate::errors::CliError;

/// 用户配置目录名 (~/.<NAME>/ 下放 index.db / boot/preference.json /
/// 用户配置目录名 (~/.<NAME>/ 下放 db/local.db / boot/preference.json /
/// agent-config.toml / boot/system.json 等)。
pub const USER_CONFIG_DIR_NAME: &str = ".flowix";

Expand All @@ -26,7 +26,7 @@ pub struct Resolved {
/// 或 `$XDG_DATA_HOME/flowix` (Linux)
#[allow(dead_code)]
pub app_data: PathBuf,
/// `~/.flowix/`. 笔记本注册表就存在这里 (`<config_dir>/index.db`).
/// `~/.flowix/`. 笔记本注册表位于 `<config_dir>/db/local.db`.
#[allow(dead_code)]
pub config_dir: PathBuf,
}
Expand Down
Loading
Loading