{"owner":"xiangechen","repo":"chili3d","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":2587,"categories":["root-instruction","claude-rule","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md","plugins/helloworld-js/README.md","plugins/helloworld-ts/README.md"],"skills":{"AGENTS.md":"# Chili3D coding guidelines\n\n## Build & Test\n\n```bash\nnpm run dev            # Rspack dev server → localhost:8080\nnpm run build          # Production build (Rspack + SWC)\nnpm run test           # All tests (Rstest + Happy-DOM); npm run testc = with coverage\nnpm run check          # Biome lint + auto-fix (run before commits)\nnpm run format         # Biome + clang-format across all files\nnpm run build:wasm     # C++ → WebAssembly (CMake + Emscripten); setup:wasm = one-time deps\n\nnpx rstest packages/core/test/result.test.ts   # single file\nnpx rstest -t \"should handle error case\"       # filter by name\n```\n\n## Monorepo Structure\n\nBrowser-based parametric 3D CAD: OCCT C++ kernel compiled to WebAssembly, rendered with Three.js. npm workspace under `packages/`:\n\n```\nweb ──> builder ──> app ──> core\n                  ──> i18n / three / wasm ──> core\n                  ──> ui ──> core + element\n                  ──> parametric ──> core\n```\n\n- **`core`** — Everything abstract: shape interfaces, math, document model, reactive data (`Observable`, `Binding`, `PubSub`), `Result<T,E>`, undo, commands, serialization, plugins, services, UI abstractions\n- **`parametric`** — Parametric feature-list bodies (Onshape-style) plus the 2D sketch module (`src/sketch/`, wrapping the garlic constraint solver). A body stores no shapes — only an ordered feature list replayed through `registerFeature` handlers, so any upstream edit re-evaluates the chain; the bulk of the module is stable identity for sub-shapes across rebuilds (kernel history → tracked ids → stored `EdgeRef`/`ProfileRef`) and the timeline rules for which shape a reference resolves against.\n- **`wasm`** — Concrete `ShapeFactory` → OCCT via Emscripten; exports `initWasm()`\n- **`three`** — Three.js viewport, camera controller, visuals, highlighter, gizmo, mesh export\n- **`element`** — Custom reactive DOM elements (radio groups, expanders, data converters)\n- **`ui`** — App chrome: main window, ribbon, property panels, project tree, dialogs, toast, status bar\n- **`app`** — `Application`, body nodes (`bodys/`), command implementations, `CommandService`, `HotkeyService`\n- **`builder`** — `AppBuilder` fluent chain (`.useIndexedDB().useWasmOcc().useParametric().useThree().useUI().build()`), default ribbon layout; `mergeRibbonProfiles` merges module contributions (`SketchRibbonProfiles` from `@chili3d/parametric`, `ParametricRibbonProfiles`) into `DefaultRibbon`\n- **`i18n`** / **`storage`** / **`web`** — Locale data (en, zh-cn, pt-br) / IndexedDB persistence / entry point (loading screen, `?plugin=`/`?url=`/`?model=` params)\n\nImport via workspace names (`import { ... } from \"@chili3d/core\"`); one root `tsconfig.json` covers all packages.\n\n## C++ WASM (`cpp/`)\n\nOCCT v8.0.0 → `chili-wasm.wasm` via Emscripten. `cpp/src/`: `factory.cpp` (shape creation; the tracked ops report per-output history twice — single-valued `faceMap`/`edgeMap` keeping the first ancestor, plus flat (out, in) `faceAncestors`/`edgeAncestors` pairs keeping every derivation so boolean-merged faces record all their inputs), `shape.cpp` (topology traversal), `converter.cpp` (STEP/IGES/BREP/STL), `mesher.cpp` (B-rep → mesh), `geometry.cpp` (curve/surface queries). The Release build sets `-sDISABLE_EXCEPTION_CATCHING=1`, so any OCCT raise aborts the whole module and C++ try/catch is ineffective — the query files (`shape.cpp`/`mesher.cpp`/`geometry.cpp`) guard degenerate and null-geometry paths preventively (`IsGeometric`/`IsNull`/`IsDone` prechecks; `Edge::curve` reports degenerate edges through a JS-level throw, which still works with catching disabled), and the tracked sweep ops report cap faces through a separate `capFaces` channel on the tracked result (`LastShape()` of the sweep; empty when it coincides with `FirstShape()`, e.g. a 360° revolve). Output: `packages/wasm/lib/chili-wasm.{wasm,js,d.ts}`. C++ style: WebKit (clang-format); license LGPL-3.0 (TS is AGPL-3.0).\n\n## Key Patterns\n\n- **Interface-driven** — `core` defines interfaces; feature packages implement; `AppBuilder` wires at startup.\n- **Result pattern** — Fallible ops return `Result.ok(value)` / `Result.err(error)` (`core/src/foundation/result.ts`); never throw for expected failures.\n- **Reactive data** — `Observable` uses `getPrivateValue(key)` / `setPrivateValue(key, value)`; setting emits `emitPropertyChanged`. `ObservableCollection` powers property editor and project tree.\n- **Serialization** — `@serializable()` on classes, `@serialize()` on fields → `{ __cla$$__: \"ClassName\", ...props }`.\n- **Body nodes** — `app/src/bodys/`; extend `ParameterShapeNode`, implement `generateShape(): Result<IShape>`, `setPropertyEmitShapeChanged()` triggers re-evaluation.\n- **Commands** — `ICommand.execute(application): Promise<void>`; `CancelableCommand` adds `cancel()`, `AsyncController`, dispose stack.\n- **Undo/redo** — `Transaction` records snapshots, `History` keeps the stack; commands create transactions automatically.\n- **Plugins** — Loaded from URLs or `?plugin=`; manager in `core/src/plugin/` + `app/src/pluginManager.ts`; examples in `plugins/`.\n- **Global singleton** — `getCurrentApplication()` (from `core`) instead of DI threading.\n- **MCP server** — a separate package (`chili3d-mcp`, moved out of this repo): its `live_*` tools drive the user's open browser tab, and headless tools (`run_cad_program`, `render_preview`, …) are a server-side scratchpad. Units: millimetres; angles: degrees.\n\n## Testing\n\n- Rstest (not Jest/Vitest) + Happy-DOM; root `rstest.config.ts`, globals enabled (`describe`, `test`, `expect`); tests in `packages/*/test/`; legacy decorators enabled.\n- Reuse shared mocks from `@chili3d/core/test-utils` (`TestDocument`, `createMockDocument`, `createMockApplication`, `createMockVisual`, ...) instead of per-package copies; package-specific facades (e.g. `packages/ui/test/_helpers/`) extend them. `initializeI18n()` runs automatically via rstest `setupFiles` — never call it in test files.\n- Assertions must execute: none hidden in event callbacks (unless the callback is also asserted to fire), no tautologies (`x === true || x === false`), no `if (x) expect(...)` — assert the precondition, then the behavior; `await` every promise whose `.then` asserts.\n- Assert behavior, not absence of crashes: bare `not.toThrow()` / `toBeDefined()` is a smell; `querySelector` results need `not.toBeNull()`.\n- Restore global monkeypatches (`PubSub.default.pub`, `globalThis.fetch`, ...) in `finally`/`afterEach`, or use `rs.stubGlobal` + `rs.unstubAllGlobals()`.\n- Type `rs.fn` mocks with the real signature (`rs.fn((_edges: IEdge[]) => ...)`) so `mock.calls` typechecks; use `test.each` for near-identical repeated cases.\n\n## Code Style\n\n- Biome: 4-space indent, 110-col width, double quotes, semicolons always\n- `I`-prefixed behavioral interfaces — plain data-carrier shapes stay unprefixed (`...Data`, `...Ref`, `...Options`, e.g. `SketchData`, `EdgeRef`); `camelCase` functions/variables/files; `PascalCase` classes; `UPPER_SNAKE_CASE` constants\n- CSS Modules (`*.module.css`); type-only imports (`import type { IFoo }`)\n- Every TS file starts with the AGPL-3.0 header:\n\n```ts\n// Part of the Chili3d Project, under the AGPL-3.0 License.\n// See LICENSE file in the project root for full license information.\n```\n\n## Git\n\nCommits: `<emoji> <type>(<scope>): <description>` — ✨ `feat` · 🐛 `fix` · ♻️ `refactor` · ✅ `test` · 📝 `docs` · 💄 `style` · 🔧 `chore`. Scope = package name. Active branch: `dev` → PR to `main`.\n","CLAUDE.md":"AGENTS.md","plugins/helloworld-js/README.md":"# Chili3D js Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-js/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── README.md              # This file\n├── src/\n│   ├── extension.js       # Plugin main class\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\nPackage the plugin (creates .chiliplugin file):\n\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the .chiliplugin file into Chili3D.\n\n# Demo Plugin for Chili3D\n\nTo run the plugin, you need to start the chili3d server: at the root of the chili3d folder, run: `npm run start`. Then, start the plugin server: at the root of the plugin folder, run: `npm run preview`. The plugin server will start on port 8686. The plugin will be available at http://localhost:8080?plugin=http://localhost:8686.","plugins/helloworld-ts/README.md":"# Chili3D Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-ts/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── tsconfig.json          # TypeScript configuration\n├── README.md              # This file\n├── src/\n│   ├── index.ts       # Plugin main class\n│   └── commands/\n│       └── hello.ts       # Hello World command\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Build the plugin:\n```bash\nnpm run build\n```\n\n3. Package the plugin (creates .chiliplugin file):\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the `.chiliplugin` file into Chili3D.\n"},"files":{"AGENTS.md":"# Chili3D coding guidelines\n\n## Build & Test\n\n```bash\nnpm run dev            # Rspack dev server → localhost:8080\nnpm run build          # Production build (Rspack + SWC)\nnpm run test           # All tests (Rstest + Happy-DOM); npm run testc = with coverage\nnpm run check          # Biome lint + auto-fix (run before commits)\nnpm run format         # Biome + clang-format across all files\nnpm run build:wasm     # C++ → WebAssembly (CMake + Emscripten); setup:wasm = one-time deps\n\nnpx rstest packages/core/test/result.test.ts   # single file\nnpx rstest -t \"should handle error case\"       # filter by name\n```\n\n## Monorepo Structure\n\nBrowser-based parametric 3D CAD: OCCT C++ kernel compiled to WebAssembly, rendered with Three.js. npm workspace under `packages/`:\n\n```\nweb ──> builder ──> app ──> core\n                  ──> i18n / three / wasm ──> core\n                  ──> ui ──> core + element\n                  ──> parametric ──> core\n```\n\n- **`core`** — Everything abstract: shape interfaces, math, document model, reactive data (`Observable`, `Binding`, `PubSub`), `Result<T,E>`, undo, commands, serialization, plugins, services, UI abstractions\n- **`parametric`** — Parametric feature-list bodies (Onshape-style) plus the 2D sketch module (`src/sketch/`, wrapping the garlic constraint solver). A body stores no shapes — only an ordered feature list replayed through `registerFeature` handlers, so any upstream edit re-evaluates the chain; the bulk of the module is stable identity for sub-shapes across rebuilds (kernel history → tracked ids → stored `EdgeRef`/`ProfileRef`) and the timeline rules for which shape a reference resolves against.\n- **`wasm`** — Concrete `ShapeFactory` → OCCT via Emscripten; exports `initWasm()`\n- **`three`** — Three.js viewport, camera controller, visuals, highlighter, gizmo, mesh export\n- **`element`** — Custom reactive DOM elements (radio groups, expanders, data converters)\n- **`ui`** — App chrome: main window, ribbon, property panels, project tree, dialogs, toast, status bar\n- **`app`** — `Application`, body nodes (`bodys/`), command implementations, `CommandService`, `HotkeyService`\n- **`builder`** — `AppBuilder` fluent chain (`.useIndexedDB().useWasmOcc().useParametric().useThree().useUI().build()`), default ribbon layout; `mergeRibbonProfiles` merges module contributions (`SketchRibbonProfiles` from `@chili3d/parametric`, `ParametricRibbonProfiles`) into `DefaultRibbon`\n- **`i18n`** / **`storage`** / **`web`** — Locale data (en, zh-cn, pt-br) / IndexedDB persistence / entry point (loading screen, `?plugin=`/`?url=`/`?model=` params)\n\nImport via workspace names (`import { ... } from \"@chili3d/core\"`); one root `tsconfig.json` covers all packages.\n\n## C++ WASM (`cpp/`)\n\nOCCT v8.0.0 → `chili-wasm.wasm` via Emscripten. `cpp/src/`: `factory.cpp` (shape creation; the tracked ops report per-output history twice — single-valued `faceMap`/`edgeMap` keeping the first ancestor, plus flat (out, in) `faceAncestors`/`edgeAncestors` pairs keeping every derivation so boolean-merged faces record all their inputs), `shape.cpp` (topology traversal), `converter.cpp` (STEP/IGES/BREP/STL), `mesher.cpp` (B-rep → mesh), `geometry.cpp` (curve/surface queries). The Release build sets `-sDISABLE_EXCEPTION_CATCHING=1`, so any OCCT raise aborts the whole module and C++ try/catch is ineffective — the query files (`shape.cpp`/`mesher.cpp`/`geometry.cpp`) guard degenerate and null-geometry paths preventively (`IsGeometric`/`IsNull`/`IsDone` prechecks; `Edge::curve` reports degenerate edges through a JS-level throw, which still works with catching disabled), and the tracked sweep ops report cap faces through a separate `capFaces` channel on the tracked result (`LastShape()` of the sweep; empty when it coincides with `FirstShape()`, e.g. a 360° revolve). Output: `packages/wasm/lib/chili-wasm.{wasm,js,d.ts}`. C++ style: WebKit (clang-format); license LGPL-3.0 (TS is AGPL-3.0).\n\n## Key Patterns\n\n- **Interface-driven** — `core` defines interfaces; feature packages implement; `AppBuilder` wires at startup.\n- **Result pattern** — Fallible ops return `Result.ok(value)` / `Result.err(error)` (`core/src/foundation/result.ts`); never throw for expected failures.\n- **Reactive data** — `Observable` uses `getPrivateValue(key)` / `setPrivateValue(key, value)`; setting emits `emitPropertyChanged`. `ObservableCollection` powers property editor and project tree.\n- **Serialization** — `@serializable()` on classes, `@serialize()` on fields → `{ __cla$$__: \"ClassName\", ...props }`.\n- **Body nodes** — `app/src/bodys/`; extend `ParameterShapeNode`, implement `generateShape(): Result<IShape>`, `setPropertyEmitShapeChanged()` triggers re-evaluation.\n- **Commands** — `ICommand.execute(application): Promise<void>`; `CancelableCommand` adds `cancel()`, `AsyncController`, dispose stack.\n- **Undo/redo** — `Transaction` records snapshots, `History` keeps the stack; commands create transactions automatically.\n- **Plugins** — Loaded from URLs or `?plugin=`; manager in `core/src/plugin/` + `app/src/pluginManager.ts`; examples in `plugins/`.\n- **Global singleton** — `getCurrentApplication()` (from `core`) instead of DI threading.\n- **MCP server** — a separate package (`chili3d-mcp`, moved out of this repo): its `live_*` tools drive the user's open browser tab, and headless tools (`run_cad_program`, `render_preview`, …) are a server-side scratchpad. Units: millimetres; angles: degrees.\n\n## Testing\n\n- Rstest (not Jest/Vitest) + Happy-DOM; root `rstest.config.ts`, globals enabled (`describe`, `test`, `expect`); tests in `packages/*/test/`; legacy decorators enabled.\n- Reuse shared mocks from `@chili3d/core/test-utils` (`TestDocument`, `createMockDocument`, `createMockApplication`, `createMockVisual`, ...) instead of per-package copies; package-specific facades (e.g. `packages/ui/test/_helpers/`) extend them. `initializeI18n()` runs automatically via rstest `setupFiles` — never call it in test files.\n- Assertions must execute: none hidden in event callbacks (unless the callback is also asserted to fire), no tautologies (`x === true || x === false`), no `if (x) expect(...)` — assert the precondition, then the behavior; `await` every promise whose `.then` asserts.\n- Assert behavior, not absence of crashes: bare `not.toThrow()` / `toBeDefined()` is a smell; `querySelector` results need `not.toBeNull()`.\n- Restore global monkeypatches (`PubSub.default.pub`, `globalThis.fetch`, ...) in `finally`/`afterEach`, or use `rs.stubGlobal` + `rs.unstubAllGlobals()`.\n- Type `rs.fn` mocks with the real signature (`rs.fn((_edges: IEdge[]) => ...)`) so `mock.calls` typechecks; use `test.each` for near-identical repeated cases.\n\n## Code Style\n\n- Biome: 4-space indent, 110-col width, double quotes, semicolons always\n- `I`-prefixed behavioral interfaces — plain data-carrier shapes stay unprefixed (`...Data`, `...Ref`, `...Options`, e.g. `SketchData`, `EdgeRef`); `camelCase` functions/variables/files; `PascalCase` classes; `UPPER_SNAKE_CASE` constants\n- CSS Modules (`*.module.css`); type-only imports (`import type { IFoo }`)\n- Every TS file starts with the AGPL-3.0 header:\n\n```ts\n// Part of the Chili3d Project, under the AGPL-3.0 License.\n// See LICENSE file in the project root for full license information.\n```\n\n## Git\n\nCommits: `<emoji> <type>(<scope>): <description>` — ✨ `feat` · 🐛 `fix` · ♻️ `refactor` · ✅ `test` · 📝 `docs` · 💄 `style` · 🔧 `chore`. Scope = package name. Active branch: `dev` → PR to `main`.\n","CLAUDE.md":"AGENTS.md","plugins/helloworld-js/README.md":"# Chili3D js Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-js/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── README.md              # This file\n├── src/\n│   ├── extension.js       # Plugin main class\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\nPackage the plugin (creates .chiliplugin file):\n\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the .chiliplugin file into Chili3D.\n\n# Demo Plugin for Chili3D\n\nTo run the plugin, you need to start the chili3d server: at the root of the chili3d folder, run: `npm run start`. Then, start the plugin server: at the root of the plugin folder, run: `npm run preview`. The plugin server will start on port 8686. The plugin will be available at http://localhost:8080?plugin=http://localhost:8686.","plugins/helloworld-ts/README.md":"# Chili3D Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-ts/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── tsconfig.json          # TypeScript configuration\n├── README.md              # This file\n├── src/\n│   ├── index.ts       # Plugin main class\n│   └── commands/\n│       └── hello.ts       # Hello World command\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Build the plugin:\n```bash\nnpm run build\n```\n\n3. Package the plugin (creates .chiliplugin file):\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the `.chiliplugin` file into Chili3D.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/xiangechen/chili3d/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Chili3D coding guidelines\n\n## Build & Test\n\n```bash\nnpm run dev            # Rspack dev server → localhost:8080\nnpm run build          # Production build (Rspack + SWC)\nnpm run test           # All tests (Rstest + Happy-DOM); npm run testc = with coverage\nnpm run check          # Biome lint + auto-fix (run before commits)\nnpm run format         # Biome + clang-format across all files\nnpm run build:wasm     # C++ → WebAssembly (CMake + Emscripten); setup:wasm = one-time deps\n\nnpx rstest packages/core/test/result.test.ts   # single file\nnpx rstest -t \"should handle error case\"       # filter by name\n```\n\n## Monorepo Structure\n\nBrowser-based parametric 3D CAD: OCCT C++ kernel compiled to WebAssembly, rendered with Three.js. npm workspace under `packages/`:\n\n```\nweb ──> builder ──> app ──> core\n                  ──> i18n / three / wasm ──> core\n                  ──> ui ──> core + element\n                  ──> parametric ──> core\n```\n\n- **`core`** — Everything abstract: shape interfaces, math, document model, reactive data (`Observable`, `Binding`, `PubSub`), `Result<T,E>`, undo, commands, serialization, plugins, services, UI abstractions\n- **`parametric`** — Parametric feature-list bodies (Onshape-style) plus the 2D sketch module (`src/sketch/`, wrapping the garlic constraint solver). A body stores no shapes — only an ordered feature list replayed through `registerFeature` handlers, so any upstream edit re-evaluates the chain; the bulk of the module is stable identity for sub-shapes across rebuilds (kernel history → tracked ids → stored `EdgeRef`/`ProfileRef`) and the timeline rules for which shape a reference resolves against.\n- **`wasm`** — Concrete `ShapeFactory` → OCCT via Emscripten; exports `initWasm()`\n- **`three`** — Three.js viewport, camera controller, visuals, highlighter, gizmo, mesh export\n- **`element`** — Custom reactive DOM elements (radio groups, expanders, data converters)\n- **`ui`** — App chrome: main window, ribbon, property panels, project tree, dialogs, toast, status bar\n- **`app`** — `Application`, body nodes (`bodys/`), command implementations, `CommandService`, `HotkeyService`\n- **`builder`** — `AppBuilder` fluent chain (`.useIndexedDB().useWasmOcc().useParametric().useThree().useUI().build()`), default ribbon layout; `mergeRibbonProfiles` merges module contributions (`SketchRibbonProfiles` from `@chili3d/parametric`, `ParametricRibbonProfiles`) into `DefaultRibbon`\n- **`i18n`** / **`storage`** / **`web`** — Locale data (en, zh-cn, pt-br) / IndexedDB persistence / entry point (loading screen, `?plugin=`/`?url=`/`?model=` params)\n\nImport via workspace names (`import { ... } from \"@chili3d/core\"`); one root `tsconfig.json` covers all packages.\n\n## C++ WASM (`cpp/`)\n\nOCCT v8.0.0 → `chili-wasm.wasm` via Emscripten. `cpp/src/`: `factory.cpp` (shape creation; the tracked ops report per-output history twice — single-valued `faceMap`/`edgeMap` keeping the first ancestor, plus flat (out, in) `faceAncestors`/`edgeAncestors` pairs keeping every derivation so boolean-merged faces record all their inputs), `shape.cpp` (topology traversal), `converter.cpp` (STEP/IGES/BREP/STL), `mesher.cpp` (B-rep → mesh), `geometry.cpp` (curve/surface queries). The Release build sets `-sDISABLE_EXCEPTION_CATCHING=1`, so any OCCT raise aborts the whole module and C++ try/catch is ineffective — the query files (`shape.cpp`/`mesher.cpp`/`geometry.cpp`) guard degenerate and null-geometry paths preventively (`IsGeometric`/`IsNull`/`IsDone` prechecks; `Edge::curve` reports degenerate edges through a JS-level throw, which still works with catching disabled), and the tracked sweep ops report cap faces through a separate `capFaces` channel on the tracked result (`LastShape()` of the sweep; empty when it coincides with `FirstShape()`, e.g. a 360° revolve). Output: `packages/wasm/lib/chili-wasm.{wasm,js,d.ts}`. C++ style: WebKit (clang-format); license LGPL-3.0 (TS is AGPL-3.0).\n\n## Key Patterns\n\n- **Interface-driven** — `core` defines interfaces; feature packages implement; `AppBuilder` wires at startup.\n- **Result pattern** — Fallible ops return `Result.ok(value)` / `Result.err(error)` (`core/src/foundation/result.ts`); never throw for expected failures.\n- **Reactive data** — `Observable` uses `getPrivateValue(key)` / `setPrivateValue(key, value)`; setting emits `emitPropertyChanged`. `ObservableCollection` powers property editor and project tree.\n- **Serialization** — `@serializable()` on classes, `@serialize()` on fields → `{ __cla$$__: \"ClassName\", ...props }`.\n- **Body nodes** — `app/src/bodys/`; extend `ParameterShapeNode`, implement `generateShape(): Result<IShape>`, `setPropertyEmitShapeChanged()` triggers re-evaluation.\n- **Commands** — `ICommand.execute(application): Promise<void>`; `CancelableCommand` adds `cancel()`, `AsyncController`, dispose stack.\n- **Undo/redo** — `Transaction` records snapshots, `History` keeps the stack; commands create transactions automatically.\n- **Plugins** — Loaded from URLs or `?plugin=`; manager in `core/src/plugin/` + `app/src/pluginManager.ts`; examples in `plugins/`.\n- **Global singleton** — `getCurrentApplication()` (from `core`) instead of DI threading.\n- **MCP server** — a separate package (`chili3d-mcp`, moved out of this repo): its `live_*` tools drive the user's open browser tab, and headless tools (`run_cad_program`, `render_preview`, …) are a server-side scratchpad. Units: millimetres; angles: degrees.\n\n## Testing\n\n- Rstest (not Jest/Vitest) + Happy-DOM; root `rstest.config.ts`, globals enabled (`describe`, `test`, `expect`); tests in `packages/*/test/`; legacy decorators enabled.\n- Reuse shared mocks from `@chili3d/core/test-utils` (`TestDocument`, `createMockDocument`, `createMockApplication`, `createMockVisual`, ...) instead of per-package copies; package-specific facades (e.g. `packages/ui/test/_helpers/`) extend them. `initializeI18n()` runs automatically via rstest `setupFiles` — never call it in test files.\n- Assertions must execute: none hidden in event callbacks (unless the callback is also asserted to fire), no tautologies (`x === true || x === false`), no `if (x) expect(...)` — assert the precondition, then the behavior; `await` every promise whose `.then` asserts.\n- Assert behavior, not absence of crashes: bare `not.toThrow()` / `toBeDefined()` is a smell; `querySelector` results need `not.toBeNull()`.\n- Restore global monkeypatches (`PubSub.default.pub`, `globalThis.fetch`, ...) in `finally`/`afterEach`, or use `rs.stubGlobal` + `rs.unstubAllGlobals()`.\n- Type `rs.fn` mocks with the real signature (`rs.fn((_edges: IEdge[]) => ...)`) so `mock.calls` typechecks; use `test.each` for near-identical repeated cases.\n\n## Code Style\n\n- Biome: 4-space indent, 110-col width, double quotes, semicolons always\n- `I`-prefixed behavioral interfaces — plain data-carrier shapes stay unprefixed (`...Data`, `...Ref`, `...Options`, e.g. `SketchData`, `EdgeRef`); `camelCase` functions/variables/files; `PascalCase` classes; `UPPER_SNAKE_CASE` constants\n- CSS Modules (`*.module.css`); type-only imports (`import type { IFoo }`)\n- Every TS file starts with the AGPL-3.0 header:\n\n```ts\n// Part of the Chili3d Project, under the AGPL-3.0 License.\n// See LICENSE file in the project root for full license information.\n```\n\n## Git\n\nCommits: `<emoji> <type>(<scope>): <description>` — ✨ `feat` · 🐛 `fix` · ♻️ `refactor` · ✅ `test` · 📝 `docs` · 💄 `style` · 🔧 `chore`. Scope = package name. Active branch: `dev` → PR to `main`.\n","isInternal":false,"tokens":2013,"sizeBytes":7614},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/xiangechen/chili3d/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"AGENTS.md","isInternal":false,"tokens":3,"sizeBytes":9},{"name":"README.md","path":"plugins/helloworld-js/README.md","rawUrl":"https://raw.githubusercontent.com/xiangechen/chili3d/HEAD/plugins/helloworld-js/README.md","title":"helloworld-js Documentation","category":"plugin-manifest","format":"markdown","content":"# Chili3D js Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-js/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── README.md              # This file\n├── src/\n│   ├── extension.js       # Plugin main class\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\nPackage the plugin (creates .chiliplugin file):\n\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the .chiliplugin file into Chili3D.\n\n# Demo Plugin for Chili3D\n\nTo run the plugin, you need to start the chili3d server: at the root of the chili3d folder, run: `npm run start`. Then, start the plugin server: at the root of the plugin folder, run: `npm run preview`. The plugin server will start on port 8686. The plugin will be available at http://localhost:8080?plugin=http://localhost:8686.","isInternal":false,"tokens":302,"sizeBytes":1288},{"name":"README.md","path":"plugins/helloworld-ts/README.md","rawUrl":"https://raw.githubusercontent.com/xiangechen/chili3d/HEAD/plugins/helloworld-ts/README.md","title":"helloworld-ts Documentation","category":"plugin-manifest","format":"markdown","content":"# Chili3D Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-ts/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── tsconfig.json          # TypeScript configuration\n├── README.md              # This file\n├── src/\n│   ├── index.ts       # Plugin main class\n│   └── commands/\n│       └── hello.ts       # Hello World command\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Build the plugin:\n```bash\nnpm run build\n```\n\n3. Package the plugin (creates .chiliplugin file):\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the `.chiliplugin` file into Chili3D.\n","isInternal":false,"tokens":269,"sizeBytes":1169}],"systemPromptSnippet":"<yakaai_skills repo=\"xiangechen/chili3d\">\n<!-- File: AGENTS.md (Tokens: ~2013 | Category: root-instruction) -->\n# Chili3D coding guidelines\n\n## Build & Test\n\n```bash\nnpm run dev            # Rspack dev server → localhost:8080\nnpm run build          # Production build (Rspack + SWC)\nnpm run test           # All tests (Rstest + Happy-DOM); npm run testc = with coverage\nnpm run check          # Biome lint + auto-fix (run before commits)\nnpm run format         # Biome + clang-format across all files\nnpm run build:wasm     # C++ → WebAssembly (CMake + Emscripten); setup:wasm = one-time deps\n\nnpx rstest packages/core/test/result.test.ts   # single file\nnpx rstest -t \"should handle error case\"       # filter by name\n```\n\n## Monorepo Structure\n\nBrowser-based parametric 3D CAD: OCCT C++ kernel compiled to WebAssembly, rendered with Three.js. npm workspace under `packages/`:\n\n```\nweb ──> builder ──> app ──> core\n                  ──> i18n / three / wasm ──> core\n                  ──> ui ──> core + element\n                  ──> parametric ──> core\n```\n\n- **`core`** — Everything abstract: shape interfaces, math, document model, reactive data (`Observable`, `Binding`, `PubSub`), `Result<T,E>`, undo, commands, serialization, plugins, services, UI abstractions\n- **`parametric`** — Parametric feature-list bodies (Onshape-style) plus the 2D sketch module (`src/sketch/`, wrapping the garlic constraint solver). A body stores no shapes — only an ordered feature list replayed through `registerFeature` handlers, so any upstream edit re-evaluates the chain; the bulk of the module is stable identity for sub-shapes across rebuilds (kernel history → tracked ids → stored `EdgeRef`/`ProfileRef`) and the timeline rules for which shape a reference resolves against.\n- **`wasm`** — Concrete `ShapeFactory` → OCCT via Emscripten; exports `initWasm()`\n- **`three`** — Three.js viewport, camera controller, visuals, highlighter, gizmo, mesh export\n- **`element`** — Custom reactive DOM elements (radio groups, expanders, data converters)\n- **`ui`** — App chrome: main window, ribbon, property panels, project tree, dialogs, toast, status bar\n- **`app`** — `Application`, body nodes (`bodys/`), command implementations, `CommandService`, `HotkeyService`\n- **`builder`** — `AppBuilder` fluent chain (`.useIndexedDB().useWasmOcc().useParametric().useThree().useUI().build()`), default ribbon layout; `mergeRibbonProfiles` merges module contributions (`SketchRibbonProfiles` from `@chili3d/parametric`, `ParametricRibbonProfiles`) into `DefaultRibbon`\n- **`i18n`** / **`storage`** / **`web`** — Locale data (en, zh-cn, pt-br) / IndexedDB persistence / entry point (loading screen, `?plugin=`/`?url=`/`?model=` params)\n\nImport via workspace names (`import { ... } from \"@chili3d/core\"`); one root `tsconfig.json` covers all packages.\n\n## C++ WASM (`cpp/`)\n\nOCCT v8.0.0 → `chili-wasm.wasm` via Emscripten. `cpp/src/`: `factory.cpp` (shape creation; the tracked ops report per-output history twice — single-valued `faceMap`/`edgeMap` keeping the first ancestor, plus flat (out, in) `faceAncestors`/`edgeAncestors` pairs keeping every derivation so boolean-merged faces record all their inputs), `shape.cpp` (topology traversal), `converter.cpp` (STEP/IGES/BREP/STL), `mesher.cpp` (B-rep → mesh), `geometry.cpp` (curve/surface queries). The Release build sets `-sDISABLE_EXCEPTION_CATCHING=1`, so any OCCT raise aborts the whole module and C++ try/catch is ineffective — the query files (`shape.cpp`/`mesher.cpp`/`geometry.cpp`) guard degenerate and null-geometry paths preventively (`IsGeometric`/`IsNull`/`IsDone` prechecks; `Edge::curve` reports degenerate edges through a JS-level throw, which still works with catching disabled), and the tracked sweep ops report cap faces through a separate `capFaces` channel on the tracked result (`LastShape()` of the sweep; empty when it coincides with `FirstShape()`, e.g. a 360° revolve). Output: `packages/wasm/lib/chili-wasm.{wasm,js,d.ts}`. C++ style: WebKit (clang-format); license LGPL-3.0 (TS is AGPL-3.0).\n\n## Key Patterns\n\n- **Interface-driven** — `core` defines interfaces; feature packages implement; `AppBuilder` wires at startup.\n- **Result pattern** — Fallible ops return `Result.ok(value)` / `Result.err(error)` (`core/src/foundation/result.ts`); never throw for expected failures.\n- **Reactive data** — `Observable` uses `getPrivateValue(key)` / `setPrivateValue(key, value)`; setting emits `emitPropertyChanged`. `ObservableCollection` powers property editor and project tree.\n- **Serialization** — `@serializable()` on classes, `@serialize()` on fields → `{ __cla$$__: \"ClassName\", ...props }`.\n- **Body nodes** — `app/src/bodys/`; extend `ParameterShapeNode`, implement `generateShape(): Result<IShape>`, `setPropertyEmitShapeChanged()` triggers re-evaluation.\n- **Commands** — `ICommand.execute(application): Promise<void>`; `CancelableCommand` adds `cancel()`, `AsyncController`, dispose stack.\n- **Undo/redo** — `Transaction` records snapshots, `History` keeps the stack; commands create transactions automatically.\n- **Plugins** — Loaded from URLs or `?plugin=`; manager in `core/src/plugin/` + `app/src/pluginManager.ts`; examples in `plugins/`.\n- **Global singleton** — `getCurrentApplication()` (from `core`) instead of DI threading.\n- **MCP server** — a separate package (`chili3d-mcp`, moved out of this repo): its `live_*` tools drive the user's open browser tab, and headless tools (`run_cad_program`, `render_preview`, …) are a server-side scratchpad. Units: millimetres; angles: degrees.\n\n## Testing\n\n- Rstest (not Jest/Vitest) + Happy-DOM; root `rstest.config.ts`, globals enabled (`describe`, `test`, `expect`); tests in `packages/*/test/`; legacy decorators enabled.\n- Reuse shared mocks from `@chili3d/core/test-utils` (`TestDocument`, `createMockDocument`, `createMockApplication`, `createMockVisual`, ...) instead of per-package copies; package-specific facades (e.g. `packages/ui/test/_helpers/`) extend them. `initializeI18n()` runs automatically via rstest `setupFiles` — never call it in test files.\n- Assertions must execute: none hidden in event callbacks (unless the callback is also asserted to fire), no tautologies (`x === true || x === false`), no `if (x) expect(...)` — assert the precondition, then the behavior; `await` every promise whose `.then` asserts.\n- Assert behavior, not absence of crashes: bare `not.toThrow()` / `toBeDefined()` is a smell; `querySelector` results need `not.toBeNull()`.\n- Restore global monkeypatches (`PubSub.default.pub`, `globalThis.fetch`, ...) in `finally`/`afterEach`, or use `rs.stubGlobal` + `rs.unstubAllGlobals()`.\n- Type `rs.fn` mocks with the real signature (`rs.fn((_edges: IEdge[]) => ...)`) so `mock.calls` typechecks; use `test.each` for near-identical repeated cases.\n\n## Code Style\n\n- Biome: 4-space indent, 110-col width, double quotes, semicolons always\n- `I`-prefixed behavioral interfaces — plain data-carrier shapes stay unprefixed (`...Data`, `...Ref`, `...Options`, e.g. `SketchData`, `EdgeRef`); `camelCase` functions/variables/files; `PascalCase` classes; `UPPER_SNAKE_CASE` constants\n- CSS Modules (`*.module.css`); type-only imports (`import type { IFoo }`)\n- Every TS file starts with the AGPL-3.0 header:\n\n```ts\n// Part of the Chili3d Project, under the AGPL-3.0 License.\n// See LICENSE file in the project root for full license information.\n```\n\n## Git\n\nCommits: `<emoji> <type>(<scope>): <description>` — ✨ `feat` · 🐛 `fix` · ♻️ `refactor` · ✅ `test` · 📝 `docs` · 💄 `style` · 🔧 `chore`. Scope = package name. Active branch: `dev` → PR to `main`.\n\n<!-- File: CLAUDE.md (Tokens: ~3 | Category: claude-rule) -->\nAGENTS.md\n\n<!-- File: plugins/helloworld-js/README.md (Tokens: ~302 | Category: plugin-manifest) -->\n# Chili3D js Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-js/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── README.md              # This file\n├── src/\n│   ├── extension.js       # Plugin main class\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\nPackage the plugin (creates .chiliplugin file):\n\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the .chiliplugin file into Chili3D.\n\n# Demo Plugin for Chili3D\n\nTo run the plugin, you need to start the chili3d server: at the root of the chili3d folder, run: `npm run start`. Then, start the plugin server: at the root of the plugin folder, run: `npm run preview`. The plugin server will start on port 8686. The plugin will be available at http://localhost:8080?plugin=http://localhost:8686.\n\n<!-- File: plugins/helloworld-ts/README.md (Tokens: ~269 | Category: plugin-manifest) -->\n# Chili3D Demo Plugin\n\nA demonstration plugin for Chili3D showing the capabilities of the plugin system.\n\n## Features\n\n- **Hello World Command**: A simple command that displays a greeting message\n- **Ribbon Integration**: Adds a button to the Tools tab\n- **i18n Support**: Supports English and Chinese (Simplified)\n\n## Project Structure\n\n```\nhelloworld-ts/\n├── manifest.json          # Plugin manifest with metadata\n├── package.json           # NPM configuration\n├── tsconfig.json          # TypeScript configuration\n├── README.md              # This file\n├── src/\n│   ├── index.ts       # Plugin main class\n│   └── commands/\n│       └── hello.ts       # Hello World command\n└── icons/\n    └── hello.svg          # Command icon (optional)\n```\n\n## Development\n\n1. Install dependencies:\n```bash\nnpm install\n```\n\n2. Build the plugin:\n```bash\nnpm run build\n```\n\n3. Package the plugin (creates .chiliplugin file):\n```bash\nnpm run package\n```\n\nThe packaging script is cross-platform and works on both Windows (PowerShell) and macOS/Linux.\n\n## Installation\n\nDrag and drop the `.chiliplugin` file into Chili3D.\n</yakaai_skills>"}