Restructure agent config: unified .agents/skills + wiki/architecture
Replace per-tool rule trees (.cursor/rules, .claude/rules, .codex/rules) with a single wiki/architecture/ source — 11 pages + README — readable as plain markdown by any agent. Canonical skills live in .agents/skills/; .claude/skills, .cursor/skills, .codex/skills are directory symlinks. AGENTS.md is the entrypoint (rewritten as a lean overview, no per-tool path lists). CLAUDE.md, GEMINI.md, and .github/copilot-instructions.md all point to it. Add open-pr skill (uses .github/pull_request_template.md as the source of truth for the PR body) and remove the dangling .claude/CLAUDE.md relative symlink. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
ca333dd912
commit
cf07fcaa97
@@ -0,0 +1,77 @@
|
||||
# Tools
|
||||
|
||||
*Editor tools structure in `apps/editor`.*
|
||||
|
||||
Applies to: `apps/editor/components/tools/**`.
|
||||
|
||||
Tools are React components that capture user input (pointer, keyboard) and translate it into `useScene` mutations. They live exclusively in `apps/editor/components/tools/`.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
`ToolManager` reads `useEditor` (phase + mode + tool) and mounts the active tool component. When the tool changes, the old component unmounts, cleaning up any transient state.
|
||||
|
||||
See `apps/editor/components/tools/tool-manager.tsx`.
|
||||
|
||||
## Tool Categories by Phase
|
||||
|
||||
**Site**
|
||||
- `site-boundary-editor` — draw/edit property boundary polygon
|
||||
|
||||
**Structure**
|
||||
- `wall-tool` — draw walls segment by segment
|
||||
- `slab-tool` + `slab-boundary-editor` + `slab-hole-editor`
|
||||
- `ceiling-tool` + `ceiling-boundary-editor` + `ceiling-hole-editor`
|
||||
- `roof-tool`
|
||||
- `door-tool` + `door-move-tool`
|
||||
- `window-tool` + `window-move-tool`
|
||||
- `item-tool` + `item-move-tool`
|
||||
- `zone-tool` + `zone-boundary-editor`
|
||||
|
||||
**Furnish**
|
||||
- `item-tool` — place furniture
|
||||
|
||||
**Shared utilities**
|
||||
- `polygon-editor` — reusable boundary/hole editing logic
|
||||
- `cursor-sphere` — 3D cursor visualisation
|
||||
|
||||
## Pattern
|
||||
|
||||
```tsx
|
||||
// apps/editor/components/tools/my-tool/index.tsx
|
||||
import { useScene } from '@pascal-app/core'
|
||||
import { useEditor } from '../../store/use-editor'
|
||||
|
||||
export function MyTool() {
|
||||
const createNode = useScene(s => s.createNode)
|
||||
const setTool = useEditor(s => s.setTool)
|
||||
|
||||
// Pointer handlers mutate the scene store directly.
|
||||
// No local geometry — use a renderer for any preview mesh.
|
||||
|
||||
return (
|
||||
<mesh onPointerDown={handleDown} onPointerMove={handleMove}>
|
||||
{/* ghost / preview geometry only */}
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **Tools mutate `useScene` for committed changes and `useLiveTransforms` for ephemeral drag state.** A tool's end-of-interaction write (click-to-commit, release-to-commit) goes to `useScene` and is captured in undo history. Per-mouse-move previews go to `useLiveTransforms` so history and subscribers aren't spammed.
|
||||
- **Live-drag exception for direct mesh transforms.** During an active drag a tool may apply a transform offset directly to `sceneRegistry.nodes.get(id).position`/`rotation`/`scale` *when and only when* the same offset is mirrored into `useLiveTransforms` for that node. This exception exists because the 3D renderers don't reconcile `useLiveTransforms` onto `mesh.position` yet; once a `LiveTransformSystem` does that, this exception goes away. Conditions:
|
||||
- The mesh offset must mirror the `useLiveTransforms` entry (same delta on both), so anything reading `useLiveTransforms` sees the same preview as the 3D view.
|
||||
- The offset must be cleared on tool unmount, cancel, *and* commit — both `mesh.position.set(0, 0, 0)` and `useLiveTransforms.clear(id)`.
|
||||
- The tool must not generate or mutate geometry in this path — only transform writes. Geometry generation still belongs in a core system.
|
||||
- **No business logic in tools** — delegate geometry/constraint rules to core systems.
|
||||
- **Preview geometry is local** — transient meshes shown while a tool is active live in the tool component, not in the scene store.
|
||||
- **Clean up on unmount** — remove any pending/incomplete nodes *and* any live transforms/mesh offsets when the tool unmounts.
|
||||
- **Tools must not import from `@pascal-app/viewer`** — use the scene store and core hooks only. `sceneRegistry` is exported from `@pascal-app/core` and is the allowed door into the Three.js graph for the narrow purposes above.
|
||||
- Each tool should handle a single, well-scoped interaction. Split complex tools (e.g. "draw + move") into separate components selected by `useEditor`.
|
||||
|
||||
## Adding a New Tool
|
||||
|
||||
1. Create `apps/editor/components/tools/<name>/index.tsx`.
|
||||
2. Register the tool in `ToolManager` under the correct phase and mode.
|
||||
3. Add the tool identifier to the `useEditor` tool union type.
|
||||
4. If the tool requires new node types, add schema + renderer + system first.
|
||||
Reference in New Issue
Block a user