Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
0a6549d
fix(editor): store scans locally without host uploads
anisayakmitra-in Aug 28, 2026
2b074cd
Host hooks for a guided tour: targets, a success cue, snapping and ca…
wass08 Aug 28, 2026
39ed028
editor: let a host tour point at the snapping chips (#730)
wass08 Aug 28, 2026
67ea40e
editor: fix roof and placement previews (#718)
sudhir9297 Aug 28, 2026
8bc5467
feat(editor): expose exportFloorplanPdf from the package entry (#636)
SomSamantray Aug 31, 2026
88dacbe
fix(packaging): declare license on @pascal-app/editor, ship LICENSE i…
Aymericr Aug 31, 2026
8315192
Carry scene materials through Load Build (#729)
alxbouchard Aug 31, 2026
1a5d2b0
fix(mcp): report skipped persistence instead of silently dropping liv…
Aymericr Aug 31, 2026
290370d
nodes: improve modular cabinet constraints and finishes (#719)
sudhir9297 Aug 31, 2026
8dc31d2
fix(editor): correct wall editing and roof controls (#738)
sudhir9297 Aug 31, 2026
91b7862
viewer: fix lean-to roof mitering across connected runs (#739)
sudhir9297 Aug 31, 2026
c712f57
editor: don't put an empty plugin manager in an empty rail (#741)
Snoopy147 Aug 31, 2026
ee2e984
editor: capture-mode camera suite — FOV lens, walk/drone framing, key…
wass08 Sep 1, 2026
1a9c011
editor: keep walk/drone snapshot framing as clean as orbit's (#743)
wass08 Sep 1, 2026
d1f1977
deps: cap zod below 4.5.0 (#744)
Aymericr Sep 1, 2026
3c39e27
core: project AnyNode discriminators to bare literals (#745)
Aymericr Sep 1, 2026
fdf71c9
core: type node metadata as a record instead of z.json() (#746)
Aymericr Sep 1, 2026
0a7535b
deps: lift the zod cap to >=4.5.4 <4.6 (#747)
Aymericr Sep 1, 2026
9ed8a99
core: lazy per-kind compiled node parsers behind a flag (#748)
Aymericr Sep 1, 2026
a6d02e7
viewer: re-resolve dangling library material refs; paint picker defau…
wass08 Sep 1, 2026
9b01a10
registry: declarative def.toolOptions + shared ToolOptionsPanel; roof…
wass08 Sep 1, 2026
12cb40d
editor: single-writer ToolMode FSM for mode/tool (#751)
wass08 Sep 1, 2026
9cdafb0
editor: level-follow camera, snapshot walk/drone suite, opening place…
wass08 Sep 1, 2026
83400c9
feat(cabinet): support exact sizing and run-aware editing (#753)
sudhir9297 Sep 2, 2026
3a5fdde
?perf instrumentation suite: real GPU timestamps, system tracks, acti…
wass08 Sep 2, 2026
8a6c43f
Add presentation.findInCatalog opt-out for the action menu's find but…
wass08 Sep 2, 2026
5c058b9
capture-viewer: render extracted JSON preview artifacts (#757)
Aymericr Sep 2, 2026
17e7f4d
Dirty-lifecycle correctness: guarded dirty set, undo phantom sweep, a…
wass08 Sep 2, 2026
19327a9
editor: a failed scene load shows an error with retry instead of an e…
wass08 Sep 2, 2026
ab0aa82
Node batching: items, columns, doors and windows draw through Batched…
wass08 Sep 4, 2026
16928b3
Wall batching stays live in cutaway (#761)
wass08 Sep 4, 2026
c405122
Wall load fixes: treatment fan-out, one CSG cut per wall, capture dra…
wass08 Sep 4, 2026
eaf492c
Wall batch test: drive the frame function directly (#763)
wass08 Sep 4, 2026
529af0c
CSG union tests: give the rounded-opening unions a 30 s budget (#764)
wass08 Sep 4, 2026
ee48e10
feat: capture explicit camera poses with correlated snapshot results
Aymericr Sep 5, 2026
33490dc
Merge remote-tracking branch 'origin/main' into feat/spielberg-shot-c…
Aymericr Sep 7, 2026
a5addb7
fix: isolate background captures and expose synchronous edit context
Aymericr Sep 7, 2026
88ef4f6
fix(editor): queue manual snapshots during background uploads
Aymericr Sep 7, 2026
ba417cd
fix(editor): tie snapshot cleanup to capture and scene lifetimes
Aymericr Sep 7, 2026
505013b
Merge pull request #768 from pascalorg/feat/spielberg-shot-capture
Aymericr Sep 7, 2026
5e208bb
perf(viewer): outline reuses scene depth and renders masks from proxi…
wass08 Sep 7, 2026
80f45f9
perf(viewer): cached pointer-event raycasts and camera-drag throttle …
wass08 Sep 7, 2026
c31fb63
perf(viewer): cache wall cutout facing instead of re-evaluating every…
wass08 Sep 7, 2026
c3afd16
perf(viewer): zone and overlay passes render from indexed roots (#776)
wass08 Sep 7, 2026
aa653f2
mcp: add furniture assessments and public agent skills (#777)
Aymericr Sep 8, 2026
2e63949
ci: enable trusted publishing for MCP and CLI releases (#779)
Aymericr Sep 8, 2026
5e0f985
docs: add verified candidate CLI preview (#780)
Aymericr Sep 8, 2026
72d4451
Require measured evidence and target-scoped furniture checks (#781)
Aymericr Sep 8, 2026
c405176
Document skill validation and safe preview activation (#782)
Aymericr Sep 8, 2026
0757ff2
editor: Add duct and pipe fittings, routing, and system checks (#769)
sudhir9297 Sep 8, 2026
cbb44d1
perf(editor): instance the ceiling corner brackets per level (#784)
wass08 Sep 8, 2026
75fd5fd
perf(nodes): skip animation mixers for items without clips (#785)
wass08 Sep 8, 2026
e7dc753
feat(capture): add shared clay previews and dollhouse rendering
Aymericr Sep 8, 2026
7e4d2d4
Merge remote-tracking branch 'origin/main' into feat/capture-clay-review
Aymericr Sep 8, 2026
51a66f2
docs(capture): document local previews and mesh presentation
Aymericr Sep 8, 2026
15e7b32
Merge pull request #788 from pascalorg/feat/capture-clay-review
Aymericr Sep 8, 2026
458ae29
Split canopy regression matrix into independent tests
Aymericr Sep 9, 2026
35f8665
Merge pull request #790 from pascalorg/fix/canopy-ci-matrix-cases
Aymericr Sep 9, 2026
6e6e5e8
feat(skills): fail closed on missing furniture inputs
Aymericr Sep 9, 2026
029bfda
Merge pull request #791 from pascalorg/feat/furniture-fit-missing-inp…
Aymericr Sep 9, 2026
b425ec4
perf(nodes): batch ceiling undersides and slab bodies (charter row 16…
wass08 Sep 9, 2026
9c8c610
test(nodes): run source-system probes from a package-local file, not …
wass08 Sep 9, 2026
32c3c8a
test(nodes): establish probe mocks before any fiber/react import (#793)
wass08 Sep 9, 2026
1a56c9a
skills: make furniture follow-ups blocker-aware (#794)
Aymericr Sep 9, 2026
fbe7718
docs: record agent skills 0.1.4 release source (#795)
Aymericr Sep 9, 2026
dfb1c11
docs(skills): prepare OpenAI plugin submission
Aymericr Sep 9, 2026
c58339d
Merge pull request #796 from pascalorg/chore/openai-plugin-readiness-…
Aymericr Sep 9, 2026
0fe434e
docs(skills): complete OpenAI review fixtures
Aymericr Sep 9, 2026
7163fce
Merge pull request #797 from pascalorg/chore/openai-review-materials-…
Aymericr Sep 9, 2026
aed6718
docs(skills): prepare ClawHub publication
Aymericr Sep 9, 2026
5ee7ca5
Merge pull request #798 from pascalorg/chore/clawhub-readiness-20260909
Aymericr Sep 9, 2026
df12698
fix(plugin): require MCP for OpenAI submission (#799)
Aymericr Sep 9, 2026
ff953a1
feat(mcp): add tool execution middleware
Aymericr Sep 9, 2026
f758c63
Merge pull request #801 from pascalorg/feat/mcp-tool-executor-20260909
Aymericr Sep 9, 2026
f03912f
docs(skills): record 0.1.6 as released
Aymericr Sep 9, 2026
ea1d6a4
Merge pull request #802 from pascalorg/docs/skills-release-0.1.6-inte…
Aymericr Sep 9, 2026
6ac73da
fix(mcp): propagate tool cancellation
Aymericr Sep 9, 2026
0419601
Merge pull request #803 from pascalorg/fix/mcp-execution-cancellation…
Aymericr Sep 9, 2026
c2597da
fix(mcp): preserve executor on tool updates
Aymericr Sep 9, 2026
c156615
Merge pull request #804 from pascalorg/fix/mcp-tool-update-executor-2…
Aymericr Sep 9, 2026
d674d60
chore(skills): harden ClawHub bundles
Aymericr Sep 9, 2026
57cbaae
test(skills): reject ClawHub ignore overrides
Aymericr Sep 9, 2026
c4a7371
Merge pull request #806 from pascalorg/fix/clawhub-skill-ignore-20260909
Aymericr Sep 9, 2026
6200e3f
Add official MCP Registry publishing
Aymericr Sep 9, 2026
3db59fc
Merge pull request #808 from pascalorg/feat/mcp-registry-discovery
Aymericr Sep 9, 2026
1cfaba9
ci(mcp): verify live catalog consistency
Aymericr Sep 9, 2026
bc6c6a6
Merge pull request #809 from pascalorg/chore/mcp-registry-catalog-con…
Aymericr Sep 9, 2026
981e762
feat(skills): bundle local Claude MCP connector
Aymericr Sep 9, 2026
9cb081e
docs(skills): correct Claude MCP upgrade guidance
Aymericr Sep 9, 2026
b0aa85c
Merge pull request #810 from pascalorg/feat/claude-plugin-local-mcp-017
Aymericr Sep 9, 2026
76f5bb0
docs(skills): record 0.1.7 release
Aymericr Sep 9, 2026
ed562c3
Merge pull request #811 from pascalorg/docs/agent-skills-017-release-…
Aymericr Sep 9, 2026
7bcb28e
fix(skills): hide maintainer workflows from discovery
Aymericr Sep 9, 2026
81ca1b7
fix(mcp): classify all tool side effects
Aymericr Sep 9, 2026
f107eda
Merge pull request #812 from pascalorg/feat/agent-discoverability-wave-2
Aymericr Sep 9, 2026
b422fe2
docs(openai): add tool annotation justifications (#813)
Aymericr Sep 10, 2026
20425d7
feat(cli): add hosted agent claim command (#815)
Aymericr Sep 10, 2026
0788fd2
fix(ci): authenticate CLI npm publish (#816)
Aymericr Sep 10, 2026
7cd7546
fix(ci): restore OIDC for CLI publishing (#817)
Aymericr Sep 10, 2026
8ca0b79
feat(cli): prefill hosted agent claim (#818)
Aymericr Sep 10, 2026
c41c39a
docs(cli): publish verified agent claim preview (#819)
Aymericr Sep 10, 2026
5dabbc3
feat(cli): report hosted agent status (#821)
Aymericr Sep 10, 2026
ac81648
docs(cli): publish verified agent status preview (#822)
Aymericr Sep 10, 2026
cbaed2c
feat(skills): add human-openable fit prechecks (#824)
Aymericr Sep 10, 2026
20cbb20
docs(skills): record agent report release evidence (#825)
Aymericr Sep 10, 2026
4f7d7c9
perf: scope undo/redo invalidation to changed geometry and cleared pr…
wass08 Sep 10, 2026
5388948
perf: drain initial wall builds within the time budget (charter row 6…
wass08 Sep 10, 2026
69f2552
Experience fix pass: placement, selection rotation, roof, stairs, cap…
wass08 Sep 10, 2026
d21fa36
test(editor): resolve history probe modules from packages that depend…
wass08 Sep 10, 2026
7ec084f
feat(editor): streamline connected pipe and duct drafting (#827)
sudhir9297 Sep 10, 2026
68f34b8
skills: portable mcp.json, channel manifests, validator parity (#829)
Aymericr Sep 10, 2026
d460449
skills: make skills/ the Claude plugin root (#832)
Aymericr Sep 10, 2026
4be0c9f
skills: bundle the hosted Pascal MCP server with a key prompt (#835)
Aymericr Sep 10, 2026
831c300
ci(release): graduate prerelease versions on stable bumps (#837)
Aymericr Sep 10, 2026
02bab2a
perf(cli): prune build-only files from the portable runtime (#838)
Aymericr Sep 10, 2026
b083ffd
perf(editor): re-encode fitting thumbnails as 256px webp (#842)
Aymericr Sep 11, 2026
77aef84
chore(editor): drop unreferenced public assets (#843)
Aymericr Sep 11, 2026
81c03a7
ci(release): publish through npm trusted publishing only (#839)
Aymericr Sep 11, 2026
aa2dc24
feat(cli): ship a small CLI that downloads the web editor runtime (#845)
Aymericr Sep 11, 2026
0031296
docs(skills): describe the hosted-only capture tools (#846)
Aymericr Sep 11, 2026
527a364
feat(plugins): add optional hosted auth to the Cursor plugin (#849)
Aymericr Sep 11, 2026
a13f1f9
perf: per-slab invalidation, candidate-scoped temporal reconciliation…
wass08 Sep 11, 2026
330286f
editor: integrate Environment with generic host and export APIs (#831)
AxiomeCG Sep 11, 2026
9ad31cb
refactor(packages): fold capture packages into core and viewer (#851)
Aymericr Sep 11, 2026
3f27843
fix(editor): declare @react-three/test-renderer where the lifecycle t…
wass08 Sep 11, 2026
d1b7696
ci(release): drop registry-url so npm uses OIDC trusted publishing (#…
Aymericr Sep 11, 2026
2ce944c
ci(release): log npm verbosely to surface OIDC exchange errors (#856)
Aymericr Sep 11, 2026
d4e82fd
fix(capture): cache preview artifacts, retry failed downloads, and cl…
Aymericr Sep 11, 2026
0ef40bc
release: @pascal-app/core@1.0.0 @pascal-app/viewer@1.0.0 @pascal-app/…
Aymericr Sep 12, 2026
b5e7eee
docs: replace the CLI preview instructions with the published npm CLI…
Aymericr Sep 12, 2026
33d421a
docs: describe the release workflow and refresh the validation scope …
Aymericr Sep 12, 2026
69e54f0
fix(editor): keep manifold-3d out of consumer bundler graphs (#735)
Aymericr Sep 12, 2026
baf5ad8
mcp: make batch-first apply_patch the stated default (#767)
ActArtech Sep 12, 2026
c0f643f
fix(editor): type optional ancestor traversal for downstream consumer…
FenjuFu Sep 12, 2026
f220080
fix(viewer): clamp GLB floor animation on slow frames (#820)
FenjuFu Sep 12, 2026
4097540
fix(skills): compare bundle paths without a hardcoded separator (#848)
dajiaohuang Sep 12, 2026
1ee56ba
Carry collections through Save Build / Load Build (#783)
chiliec Sep 12, 2026
385890f
fix(mcp): declare 2020-12 dialect for tools/list schemas (#787)
chiliec Sep 12, 2026
e1e5da1
fix(ifc-converter): preserve imported beam geometry (#841)
tripdancer0916 Sep 12, 2026
a11304a
fix(editor): skip roof support levels in the floorplan export (#847)
dajiaohuang Sep 12, 2026
9131580
fix(cli): preserve configured Mint host origin (#778)
Zhao0335 Sep 12, 2026
7254139
fix(editor): respect export scope when collecting floorplan schedules…
Zhao0335 Sep 12, 2026
409576b
Merge main and keep local scan uploads visible
Aymericr Sep 12, 2026
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
  •  
  •  
  •  
27 changes: 27 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "pascal",
"interface": {
"displayName": "Pascal"
},
"plugins": [
{
"name": "pascal-agent-skills",
"version": "0.1.8",
"description": "Create, inspect, validate, and assess furniture layouts with bounded next actions in Pascal through MCP.",
"author": {
"name": "Pascal",
"email": "support@pascal.app",
"url": "https://pascal.app"
},
"source": {
"source": "local",
"path": "./"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
2 changes: 2 additions & 0 deletions .agents/skills/open-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: open-pr
description: Open a pull request on pascalorg/editor using the repo's PR template. Use when the user asks to open/create a PR, push and PR, or ship a branch in the editor repo.
metadata:
internal: true
allowed-tools: Bash(git *) Bash(gh *) Read
---

Expand Down
216 changes: 216 additions & 0 deletions .agents/skills/open-pr2/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
---
name: open-pr2
description: Open or update a pull request on pascalorg/editor with a plain-language issue-and-fix description based on the full branch diff. Use only when the user explicitly asks for OpenPR2 or /open-pr2.
metadata:
internal: true
disable-model-invocation: true
allowed-tools: Bash(git *) Bash(gh *) Bash(bun *) Read
---

# OpenPR2

Open or update a pull request against `pascalorg/editor` from the current branch. Keep the repository's PR template, but write the body like one developer explaining the change to another.

## 1. Pre-flight

Inspect the working tree and the whole branch before writing anything:

```bash
git status
git branch --show-current
git log --oneline main..HEAD
git diff --stat main...HEAD
git diff --name-status main...HEAD
```

Read the relevant parts of `git diff main...HEAD`. Do not build the description from the latest commit alone or from conversation memory.

Stop if:

- The current branch is `main`. Ask the user to create a feature branch first.
- The branch has no commits ahead of `main`.
- There are uncommitted changes the user has not asked to commit.

For a non-trivial change, run checks that match the affected packages. Prefer focused tests plus:

```bash
bun run check-types
bun run build
```

Do not open a PR when a required check fails. Report the failure instead. Do not claim that a command or manual test passed unless it was run.

## 2. Read the current PR template

Read `.github/pull_request_template.md` every time. Its headings and checklist wording are the source of truth.

Keep the template headings in the same order:

1. `## What does this PR do?`
2. `## How to test`
3. `## Screenshots / screen recording`
4. `## Checklist`

Do not replace them with `Summary`, `Details`, `Validation`, or custom headings unless the template itself changes.

## 3. Write the title

- Keep it under 70 characters when practical.
- State the result, not the activity. Prefer `fix(editor): keep curved room slabs attached` over `update wall files`.
- Add a package scope when one package clearly owns the change, such as `core:`, `viewer:`, `editor:`, or `mcp:`.
- Avoid vague verbs such as `improve`, `enhance`, `update`, or `refactor` when a concrete verb fits.

## 4. Write the body in plain language

### What does this PR do?

The reviewer should understand every changed behavior without opening the diff. Do not compress unrelated fixes into a paragraph or a long bullet.

Give each problem its own short item. Use this exact shape:

```markdown
- **Short feature or problem name**
- Issue: One short sentence describing what was wrong or missing.
- Fixed: One short sentence describing the behavior after this PR.
```

Add one more indented sentence only when the reviewer needs an important constraint, risk, or design decision. Keep it short and do not add labels such as `Details`, `Technical`, or `Implementation`.

Example:

```markdown
- **Curved triangular rooms**
- Issue: Slabs and ceilings kept a straight corner after curving a wall.
- Fixed: Both surfaces now rebuild from the curved room boundary.

- **Wall and fence thickness**
- Issue: Thickness could only be changed from the settings panel.
- Fixed: Each face now has a circular thickness handle in 2D and 3D.
- The centerline stays fixed, and the change uses one undo step.
```

Keep the item title concrete. Start with product behavior, not filenames or function names. Cover every meaningful user-visible fix on the branch. Combine items only when they describe the same problem and the same fix.

Avoid this compressed style:

```text
This PR fixes curved wall topology, adds thickness handles, improves floor-plan previews, updates roof paint slots, and cleans up roof controls.
```

Link issues with `Fixes #123` or `Refs #123` when applicable. Never invent an issue number.

### How to test

Write numbered reviewer steps. Put the action on the numbered line and the expected result on a short indented line.

Good:

```text
1. Create a triangular room and curve one wall.
- The slab and ceiling should follow the curved corner with no gap.

2. Drag either wall thickness dot.
- The wall should stay centered while its thickness changes.
```

List automated commands only when they were run. Include pass counts when they are known and useful. Do not turn the section into a dump of every command used during development.

### Screenshots / screen recording

- Preserve any existing media verbatim when updating a PR.
- For a visual or interactive change, add the supplied media. If none exists, write `Not added yet.`
- For a non-visual change, write `N/A, no visual change.`
- Do not claim that a recording exists when it does not.

### Checklist

Copy every checklist line from the current template verbatim.

- Tick an item only when it is true.
- `bun dev` is checked only after local runtime testing.
- The code-style item is checked only after the requested style command passes.
- Documentation is checked when docs were updated or when the item explicitly says it is not applicable. Otherwise leave it unchecked.
- Confirm the actual base branch before checking the target-branch item.

## 5. Human writing pass

Before submitting, read the title and body once as a reviewer who has not seen the branch.

Rewrite anything that fails these checks:

- Use plain words and short sentences.
- Say what the change does. Avoid phrases that could describe any PR.
- Remove filler, hype, sales language, and chatbot phrases.
- Remove repeated points and details that the diff explains on its own.
- Avoid jargon unless the repository uses the term and the reviewer needs it.
- Avoid forced lists, excessive bold text, em dashes, and long parenthetical asides.
- Prefer active voice.
- Keep a human rhythm. The body should not read like generated release notes.
- Make every test step concrete and verifiable.

If the summary sounds too small, add the missing problem or behavior. If it sounds dense, remove implementation trivia before shortening the explanation of the bug.

## 6. Push and find the PR

Push the current branch:

```bash
git push -u origin HEAD
```

Check whether it already has a PR:

```bash
gh pr view --json number,url,title,body 2>/dev/null
```

### No existing PR

Create one with `gh pr create`. Pass the body through a quoted heredoc so Markdown stays intact:

```bash
gh pr create --title "<title>" --body "$(cat <<'EOF'
<body using the current PR template>
EOF
)"
```

### Existing PR

Do not create another PR. Update the current one from the full branch diff.

Before rewriting it:

```bash
gh pr view --json number,title,body,url
git log --oneline main..HEAD
git diff --stat main...HEAD
```

When rebuilding the body:

- Preserve `Fixes #123` and `Refs #123` lines.
- Preserve screenshots, recordings, links, and embedded images verbatim unless the user supplied replacements.
- Preserve the user's checklist state for work that remains true. Never change an unchecked item to checked without evidence.
- Keep extra reviewer notes that are still relevant.
- Remove old claims and test steps that no longer match the branch.
- Leave the title unchanged unless the branch's purpose clearly changed.

Apply the update with `gh pr edit <number> --body ...`. Change the title only when needed.

## 7. Verify and report

Read the PR back after creation or editing:

```bash
gh pr view --json number,url,title,body,baseRefName,headRefName
```

Confirm that the title, template sections, base branch, and body were saved correctly.

Return:

- PR URL
- Title
- Checks and tests actually run
- Any unchecked checklist item or missing recording the reviewer should know about
4 changes: 3 additions & 1 deletion .agents/skills/review-architecture/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
name: review-architecture
description: Review a PR against the Pascal architectural rules — package boundaries (core/viewer/editor/nodes), the registry-driven composition model (def.geometry / def.renderer / def.system), legacy-dispatch regressions, the slots + world-scale-UV convention for new nodes/geometry, hook hygiene (useEditor/useScene/useViewer), and selector performance. Use when the user asks to review a PR, audit a branch, or check that changes respect the codebase's architecture.
metadata:
internal: true
allowed-tools: Bash(git *) Bash(gh *) Read Grep Glob
---

Expand Down Expand Up @@ -121,7 +123,7 @@ If the PR adds or modifies a node kind, check against `wiki/architecture/node-de
- New state added to `useViewer` must be presentation-only (selection, camera, level mode, display toggles). Editor-only state (active tool, phase, edit mode, paint preview, floorplan state) goes in `useEditor`.
- **Node code does not import `useScene` directly.** A kind's geometry / system / tool should read and write through `SceneApi` (passed in by the framework) or `GeometryContext`. Direct `useScene.getState()` calls inside `packages/nodes/src/<kind>/` are a smell — they bypass the registry's IoC point and make the code harder to test.
- **Live drag motion is imperative, not store-driven.** Tools must not call `useLiveTransforms.set(...)` per `grid:move` tick to animate registered parametric kinds — the selector path doesn't reliably re-render and the mesh visibly disappears mid-drag. Use `sceneRegistry.nodes.get(node.id)?.position.set(x, y, z)` instead, and commit once at the end via `useScene.temporal.getState().resume() → updateNode → pause()`. The reference implementation is `MoveRegistryNodeTool`. This is the *only* sanctioned use of imperative mesh transforms by a tool; flag any other location that does the same.
- **Data-driven drags preview via `useLiveNodeOverrides`, never per-tick `useScene`.** A kind whose geometry is recomputed from data fields (wall `start`/`end`, opening host-cut, endpoint reshape) previews by publishing field patches to `useLiveNodeOverrides` (merged by `getEffectiveWall` / `getEffectiveNode`), writing the scene store **once on commit**. A tool that calls `useScene.updateNodes`/`updateNode` on `grid:move` (or any per-pointer-move tick) is a **blocker** — it swaps the `nodes` map ref and re-renders every `useScene(s => s.nodes)` subscriber app-wide each frame (`markDirty` per tick is fine). Grep tell: `updateNode(s)?(` in an `onGridMove`/`onMove`/`applyPreview` path under `packages/nodes/src/<kind>/`. See `wiki/architecture/tools.md` § "Data-driven live drag".
- **Data-driven drags preview via `useLiveNodeOverrides`, never per-tick `useScene`.** A kind whose geometry is recomputed from data fields (wall `start`/`end`, opening host-cut, endpoint reshape) previews by publishing field patches to `useLiveNodeOverrides` (merged by `getEffectiveWall` / `getEffectiveNode`), writing the scene store **once on commit**. A tool that calls `useScene.updateNodes`/`updateNode` on `grid:move` (or any per-pointer-move tick) is a **blocker** — it swaps the `nodes` map ref and re-renders every `useScene(s => s.nodes)` subscriber app-wide each frame. `markDirty` per tick is fine **for bounded gestures** (drag marks drain every frame); a `useFrame`/animation loop that marks dirty for as long as something animates is a **blocker** — the scene can then never settle to DIRTY 0. Animations signal rebuilds through their own records (`useInteractive` animations), marking dirty once on completion; see `wiki/architecture/node-definitions.md` § "`geometry` + `system`". Grep tell: `updateNode(s)?(` in an `onGridMove`/`onMove`/`applyPreview` path under `packages/nodes/src/<kind>/`. See `wiki/architecture/tools.md` § "Data-driven live drag".

### D. Selector performance

Expand Down
24 changes: 24 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
"name": "pascal",
"version": "0.1.8",
"description": "Public Pascal workflows for MCP-capable agents.",
"owner": {
"name": "Pascal"
},
"plugins": [
{
"name": "pascal-agent-skills",
"source": "./skills",
"description": "Create, inspect, validate, and assess furniture layouts with bounded next actions in Pascal through MCP.",
"author": {
"name": "Pascal",
"email": "support@pascal.app",
"url": "https://pascal.app"
},
"version": "0.1.8",
"category": "productivity",
"skills": ["./pascal-3d", "./furniture-fit"]
}
]
}
37 changes: 37 additions & 0 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "pascal-agent-skills",
"version": "0.1.8",
"description": "Create, inspect, validate, and assess furniture layouts with bounded next actions in Pascal through MCP.",
"author": {
"name": "Pascal",
"email": "support@pascal.app",
"url": "https://pascal.app"
},
"homepage": "https://editor.pascal.app/docs/developers/mcp",
"repository": "https://github.com/pascalorg/editor",
"license": "MIT",
"keywords": ["pascal", "3d", "architecture", "mcp", "furniture", "spatial"],
"skills": "./skills/",
"interface": {
"displayName": "Pascal",
"shortDescription": "Build 3D scenes and check fit",
"longDescription": "Use Pascal's MCP tools to work with editable building scenes, validate and save results, and produce bounded furniture footprint reports with explicit evidence, limitations, and blocker-aware next actions.",
"developerName": "Pascal",
"category": "Developer Tools",
"capabilities": [
"Build and edit 3D scenes",
"Validate spatial layouts",
"Assess furniture footprints"
],
"websiteURL": "https://editor.pascal.app/docs/developers/mcp",
"privacyPolicyURL": "https://editor.pascal.app/privacy",
"termsOfServiceURL": "https://editor.pascal.app/terms",
"defaultPrompt": [
"Use Pascal to inspect this building project, make the requested bounded edit, validate it, save it, and return the editor URL.",
"Check whether this furniture footprint fits in a measured Pascal room, including rotations, collisions, and door access."
],
"brandColor": "#171717",
"composerIcon": "./assets/pascal-mark.svg",
"logo": "./assets/pascal-mark-plate.svg"
}
}
16 changes: 16 additions & 0 deletions .cursor-plugin/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"mcpServers": {
"pascal": {
"type": "stdio",
"command": "pascal",
"args": ["mcp", "connect"]
},
"pascal-hosted": {
"type": "http",
"url": "https://editor.pascal.app/api/mcp",
"headers": {
"Authorization": "Bearer ${PASCAL_API_KEY}"
}
}
}
}
42 changes: 42 additions & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "pascal-agent-skills",
"displayName": "Pascal",
"version": "0.1.8",
"description": "Create, inspect, validate, and assess furniture layouts with bounded next actions in Pascal through MCP.",
"author": {
"name": "Pascal",
"email": "support@pascal.app"
},
"homepage": "https://editor.pascal.app/docs/developers/mcp",
"repository": "https://github.com/pascalorg/editor",
"license": "MIT",
"logo": "assets/pascal-mark-plate.svg",
"keywords": [
"pascal",
"3d",
"architecture",
"mcp",
"furniture",
"spatial"
],
"category": "developer-tools",
"tags": [
"3d",
"architecture",
"floor-plan",
"furniture",
"mcp"
],
"skills": "./skills/",
"variables": {
"type": "object",
"properties": {
"PASCAL_API_KEY": {
"type": "string",
"title": "Pascal API key (hosted)",
"description": "Optional. Create a key under Settings -> API keys at editor.pascal.app to reach your hosted projects, Pascal Capture scans, and shared workspaces. Leave it unset to use only the local Pascal CLI."
}
}
},
"mcpServers": "./.cursor-plugin/mcp.json"
}
Loading