Claude / Cursor users: See
CLAUDE.mdfor project-specific MANDATORY rules (language, bug handling, frontend protocol, Trellis workflow shortcuts).
This file applies to the entire FlowScope monorepo.
FlowScope is a Rust + TypeScript monorepo. Key areas:
crates/Rust workspace (core engine, wasm, CLI, export).packages/TypeScript packages (@pondpilot/flowscope-core,@pondpilot/flowscope-react).app/demo web app (Vite + React).vscode/VS Code extension +vscode/webview-ui.
- No
.cursor/rules/,.cursorrules, or.github/copilot-instructions.mdfound.
- Use
justas the task runner (seejustfile). - Use
yarnfor Node workspaces. - Use
cargofor Rust workspace. - Node.js 18+ and Rust 1.82+ expected (see
README.md).
just build(WASM + TypeScript packages).just build-rust(Rust workspace debug build).just build-rust-release(Rust workspace release build).just build-cli(CLI release build).just build-cli-serve(CLI with embedded web UI, release build).just build-cli-serve-debug(CLI with embedded web UI, debug build).just build-wasm(runs./scripts/build-rust.sh).just build-ts(runsyarn build:ts).just run(build + dev server).
The CLI serve feature embeds the web app using rust-embed at compile time. This requires the app to be built first:
cd app && yarn build- Build frontend assets toapp/dist/cargo build -p flowscope-cli --features serve- Compile CLI with embedded assets
The just build-cli-serve target handles this dependency automatically.
just dev(Vite dev server athttp://localhost:5173).yarn dev(fromapp/if you want direct Vite usage).just cli -- <args>(run CLI in debug mode).just cli-release -- <args>(run CLI in release mode).
必须按以下顺序依次启动,缺少任一步骤页面功能不完整:
Step 1 — 启动前端 Vite dev server(端口 3000)
cd app && yarn dev- 访问地址:
http://localhost:3000/ - Vite 将
/api/*请求反向代理到http://localhost:3099 - 如需修改代理目标:
FLOWSCOPE_API_PROXY=http://localhost:9099 yarn dev
Step 2 — 编译并启动后端 CLI serve(端口 3099)
# 首次或代码变更后需重新编译
cargo build -p flowscope-cli --features serve
# 启动服务(必须带 --audit-log 参数,路径相对于项目根目录)
./target/debug/flowscope --serve --port 3099 --audit-log data/audit.db- 后端监听地址:
http://127.0.0.1:3099/ --audit-log:指定 SQLite 审计日志文件路径,启动时必须携带,否则审计功能不可用data/audit.db目录需提前存在:mkdir -p data
说"打包发布"就严格按下面步骤走,不要临时拼步骤。
约束:生产分析在 CLI serve 后端跑,前端只走 REST,不需要
wasm-pack。 服务器是 CentOS 7 / glibc 2.17,必须用cargo zigbuild,不能用cargo build或cross build。
cargo test -p flowscope-core --lib # 核心单测必须全绿
python3 ./scripts/regression-test-sql.py # 真实 SQL 回归(要求 0 failed)cd app && yarn build && cd ..
# 产物:app/dist/rm -rf crates/flowscope-cli/embedded-app
mkdir -p crates/flowscope-cli/embedded-app
cp -R app/dist/. crates/flowscope-cli/embedded-app/
# 自检(无输出为正常)
diff -q app/dist/index.html crates/flowscope-cli/embedded-app/index.htmlcargo zigbuild \
--target x86_64-unknown-linux-gnu.2.17 \
--target-dir target-zigbuild \
-p flowscope-cli \
--features serve \
--release
# 产物:target-zigbuild/x86_64-unknown-linux-gnu/release/flowscope验证 glibc 版本(最高必须是 2.17,出现 2.18+ 立即排查):
strings target-zigbuild/x86_64-unknown-linux-gnu/release/flowscope \
| grep '^GLIBC_' | sort -V -u | tail -3# 上传 H5 前端(zip 打包后上传)
cd app/dist && zip -qr "../../flowscope-h5-$(date +%Y%m%d-%H%M).zip" . && cd ../..
./scripts/upload-h5.sh # 自动选最新 flowscope-h5-*.zip,上传并 sha256 校验
# 上传 CLI 二进制(直接上传,无需压缩)
./scripts/upload-h5.sh target-zigbuild/x86_64-unknown-linux-gnu/release/flowscope两条命令各打印一个 URL:,记录备用。
将 Step 4 上传的 CLI CDN URL 交给运维,服务器侧使用独立的启动脚本完成部署和重启。
完整流程、回滚方案、双端一致性验证见 docs/release-workflow.md。
just lint(Rust + TypeScript lint).just lint-rust(cargo clippy --workspace -- -D warnings).just lint-ts(yarn workspaces run lint).just lint-fix(yarn workspaces run lint:fix).just fmt(Rust + TS formatting).just fmt-rust(cargo fmt --all).just fmt-check-rust(cargo fmt --all -- --check).just fmt-ts(runs Prettier across workspaces).just typecheck(yarn workspaces run typecheck).
just test(Rust + TS tests).just test-rust(cargo test --workspace).just test-rust-release(cargo test --workspace --release).just test-ts(yarn workspaces run test).just test-core(cargo test -p flowscope-core).just test-cli(cargo test -p flowscope-cli).just test-cli-serve(CLI tests with serve feature, builds app first).just test-lineage(cargo test -p flowscope-core --test lineage_engine).just test-lineage-verbose(same test with--nocapture).just regression-sql(build release CLI + runtest-sql/*.sqlregression: headline-field assertions forsqlType/insertType/targetTable/sourceTables/statementTypes/errorCount, pinned intest-sql/.regression-expect.json).just regression-sql-fast(same regression, skip rebuild — for SQL fixture iteration).just check-schema(Rust schema guard + TS schema compatibility).just coverage(generate HTML coverage report incoverage/, requirescargo-llvm-cov).just coverage-lcov(generate LCOV file atlcov.infofor CI/Codecov).just coverage-summary(print coverage summary to stdout).
just install(install Node dependencies).just setup(install deps + tools + hooks + build).just install-rust-tools(installswasm-packandcargo-watch).just install-hooks(installprekhooks).just clean(cargo clean + remove node_modules).just update-schema(regenerate API schema snapshot).just check(fmt check + lint + typecheck + schema checks).just check-all(Rust + TS + schema compatibility).just watch(rebuild Rust workspace on changes).just watch-test(run Rust tests on changes).just watch-lineage(run lineage tests on changes).
packages/core:yarn test,yarn test:watch,yarn lint,yarn typecheck.packages/react:yarn test,yarn test:watch,yarn lint,yarn typecheck.app:yarn dev,yarn build,yarn preview,yarn lint,yarn typecheck.vscode:npm run build,npm run build:webview,npm run watch,npm run typecheck.vscode/webview-ui:yarn build,yarn dev,yarn lint,yarn typecheck.
- Rust lineage tests:
just test-lineage-filter PATTERN. - Rust lineage tests (manual):
cargo test -p flowscope-core --test lineage_engine PATTERN. - Schema compatibility:
yarn workspace @pondpilot/flowscope-core test schema-compat.test.ts --silent. - For other Rust crates, use
cargo test -p <crate>then filter with a test name if needed.
- Follow standard Rust conventions (see
CONTRIBUTING.md). - Format with
cargo fmtbefore committing. - Lint with
cargo clippyand fix warnings. - Workspace uses Rust 2021 edition (see
Cargo.toml). - Avoid unused variables; if intentionally unused, prefix with
_. - Keep modules small and focused;
flowscope-coreuses a layered analyzer.
- Use
ParseErrorfor fatal parsing failures returned viaResult<T, ParseError>. - Use
Issuefor non-fatal analysis problems (collected and returned alongside results). flowscope-cliusesanyhow::ResultwithContextfor CLI errors.flowscope-exportand analyzer input usethiserror::Errorfor structured errors.
flowscope-core emits 5 edge variants (EdgeType in
crates/flowscope-core/src/types/response.rs). The choice is part of the
analyzer ↔ renderer contract — do not invent new types or change emission
rules without updating both sides and the spec below.
| Variant | JSON | Visual (light) | When emitted |
|---|---|---|---|
DataFlow |
data_flow |
Solid grey (#94A3B8) |
Plain column passthrough (expression is None). |
Derivation |
derivation |
Dashed purple (#8B5CF6, 6 4) |
Column with any transformation: function, arithmetic, CASE, aggregate, CAST, etc. (expression is Some). |
JoinDependency |
join_dependency |
Dotted green (#10B981, 2 2) |
A JOIN operand that contributes NO column to the sink. Carries join_type + join_condition. |
Ownership |
ownership |
Not drawn (structural) | relation → column containment. Used by the UI for grouping, not as a visible edge. |
CrossStatement |
cross_statement |
Only in multi-statement views | Cross-file / cross-statement linkage (e.g. dbt ref(...)). statementIds carries a [producer, consumer] pair. |
Key rules:
DataFlow↔Derivationis decided byexpression.is_some()atcrates/flowscope-core/src/analyzer/query.rs:1077. NEVER set anexpressionon aDataFlowedge.JoinDependencyis emitted byadd_join_dependency_edges(crates/flowscope-core/src/analyzer/statements.rs:351) only for tables injoined_table_infothat do not already reach the sink viaDataFlow/Derivation.- Through node-collapse in
analyzer/transform.rs:226,Derivation"wins" overDataFlow— once a chain has a transformation, the collapsed edge staysDerivation. - Frontend renderer reads colors/dasharrays from
packages/react/src/constants.ts(COLORS.edges,EDGE_STYLES) and legend labels frompackages/react/src/components/Legend.tsx. Keep these in sync with the Rust enum.
Full contract, worked examples, invariants, and anti-patterns:
.trellis/spec/flowscope-core/backend/edge-types.md.
- TypeScript is strict (see
CONTRIBUTING.md). - ESM modules are used (
"type": "module"). - Use single quotes and trailing commas in multiline structures.
- Prettier config:
printWidth: 100tabWidth: 2semi: truesingleQuote: truetrailingComma:es5arrowParens:always
- ESLint config highlights:
@typescript-eslint/no-unused-vars: error, allow unused args with_prefix.@typescript-eslint/explicit-module-boundary-types: off.
- Add unit tests for new functionality (
CONTRIBUTING.md). - Add integration tests for complex features.
- Use fixtures under
crates/flowscope-core/tests/fixtures/when needed. - Keep test output clean; avoid noisy logs unless
--nocaptureis intended.
- Update documentation and
CHANGELOG.mdif a change requires it (seeCONTRIBUTING.md). - Docs index and specs live in
docs/README.md. - Usage guides live in
docs/guides/. - The CLI usage details live in
crates/flowscope-cli/README.md. - Core engine overview lives in
crates/flowscope-core/README.md.
Use a single repo tag for each release (vX.Y.Z) and align Rust workspace + npm package versions.
- Update versions:
Cargo.tomlworkspace version + workspace dependenciespackages/core/package.json,packages/react/package.json,packages/core/wasm/package.json- Update peer dependency on
@pondpilot/flowscope-coreinpackages/react
- Update
CHANGELOG.md:- Move Unreleased entries to
## [X.Y.Z] - YYYY-MM-DD - Summarize changes per crate/package
- Move Unreleased entries to
- Validate:
just fmt-rustjust test-coreyarn workspace @pondpilot/flowscope-react buildyarn workspace @pondpilot/flowscope-core build
- Publish crates (order matters):
cargo publish -p flowscope-corecargo publish -p flowscope-exportcargo publish -p flowscope-cli
- Publish npm packages:
yarn workspace @pondpilot/flowscope-core publish --access publicyarn workspace @pondpilot/flowscope-react publish --access public
- Tag + release:
git tag vX.Y.Zgit push origin vX.Y.Zgh release create vX.Y.Z --title "vX.Y.Z" --notes-file <notes>(use CHANGELOG notes)
- The demo app (
app/) and VS Code webview (vscode/webview-ui/) currently define no tests. - For full CI parity,
just checkruns formatting checks, lint, typecheck, and schema checks.
| 阶段 | 工具 | 时机 |
|---|---|---|
| 恢复任务 | /trellis-continue |
新会话开始 / 中断后续做(自动路由到正确 phase) |
| 需求不清晰 | /trellis-brainstorm |
规划前 |
| 开始编码前 | /trellis-before-dev |
每次切换 package 时 |
| 发现 bug | /trellis-break-loop |
bug 修复后立即 |
| 编码完成 | /trellis-check |
提交前 |
| 沉淀经验 | /trellis-update-spec |
break-loop 之后 |
| 任务收尾 | /trellis-finish-work |
work commit 之后立即(archive + 写 journal) |
| 架构定制 | /trellis-meta |
修改 .trellis/、platform hooks、skills、commands 时 |
These instructions are for AI assistants working in this project.
This project is managed by Trellis. The working knowledge you need lives under .trellis/:
.trellis/workflow.md— development phases, when to create tasks, skill routing.trellis/spec/— package- and layer-scoped coding guidelines (read before writing code in a given layer).trellis/workspace/— per-developer journals and session traces.trellis/tasks/— active and archived tasks (PRDs, research, jsonl context)
If a Trellis command is available on your platform (e.g. /trellis:finish-work, /trellis:continue), prefer it over manual steps. Not every platform exposes every command.
If you're using Codex or another agent-capable tool, additional project-scoped helpers may live in:
.agents/skills/— reusable Trellis skills.codex/agents/— optional custom subagents
Managed by Trellis. Edits outside this block are preserved; edits inside may be overwritten by a future trellis update.