CLAUDE.md
packages/frontend/editor-ui/src/app/stores/workflowDocument/CLAUDE.mdCLAUDE.md
Quality
58/100
Scores the file, not the repository.Length
554 words
8 headings · 4 code blocksRepository
199k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# workflowDocument store — Agent Guidelines23## Core pattern: apply/public method split45Every composable in this folder follows a two-layer pattern:67**Public methods** (exposed) — represent user intent. Handle normalization,8deduplication, and preparation. Call apply methods internally.910**Apply methods** (private) — the **only** functions that mutate refs. Each11apply method writes to the ref and fires an event hook. Never expose apply12methods from the composable.1314```15Component → publicMethod() → normalize → applyXxx() → ref + event hook16```1718This split exists to support CRDT in the future: local user actions,19remote CRDT sync, and undo/redo all converge on the same private apply20methods inside the composable.2122## Event hooks2324Every composable exposes change notifications via `createEventHook` from25`@vueuse/core`. Event payloads must extend `ChangeEvent` from `./types.ts`:2627```typescript28import { createEventHook } from '@vueuse/core';29import type { ChangeEvent, ChangeAction } from './types';3031type MyChangeEvent = ChangeEvent<{ /* domain-specific fields */ }>;32const onMyChange = createEventHook<MyChangeEvent>();33```3435- Fire `void onMyChange.trigger(...)` inside every apply method36- Expose only the `.on` subscriber: `onMyChange: onMyChange.on`37- Use `CHANGE_ACTION.ADD | UPDATE | DELETE` for the `action` field3839## Reactivity invariant: events carry reactive references4041When an apply method emits a node (or any tracked entity) in its event42payload, the payload must contain the **reactive proxy** read back from the43ref — NOT the raw input received by the apply method.4445Vue creates proxies lazily on read from a reactive container. The raw object46passed into the apply method and the proxy returned by `nodes.value[i]` share47underlying state but are different JS references. Subscribers that store the48raw reference lose reactivity on subsequent property mutations: property reads49on the raw object create no dependencies, and downstream computeds never50invalidate when the underlying node is mutated through its proxy.5152Pattern — read back from the ref after the mutation, emit the proxy:5354```typescript55function applyAddNode(node: INodeUi) {56 nodes.value.push(node);57 const reactiveNode = nodes.value[nodes.value.length - 1]; // proxy58 void onChange.trigger({59 action: CHANGE_ACTION.ADD,60 payload: { node: reactiveNode },61 });62}63```6465This invariant is locked by the `addNode emits the reactive proxy from66nodes.value` test in `useWorkflowDocumentNodes.test.ts`. Any new apply method67that emits a tracked entity must follow the same pattern and add an68equivalent test.6970## Adding a new composable — checklist71721. Create event hook with typed payload extending `ChangeEvent`732. Write private `apply*()` methods — each mutates the ref and fires the hook743. Write public methods — normalize input, then call apply754. Return: readonly refs, public methods, `onXxxChange: hook.on`765. Never return apply methods7778## Anti-patterns7980| Don't | Do instead |81|-------|------------|82| Mutate refs outside apply methods | All ref writes go through apply |83| Expose apply methods from composable | Keep them private (not in return) |84| Use action objects / `onChange` router | Public methods call apply directly |85| Use `dataPinningEventBus` or global event bus | Use scoped `createEventHook` |86| Import global stores inside composable | Inject dependencies via function params |8788## Dependency injection8990Composables receive external dependencies as constructor params, not via91global store imports. This keeps them testable and makes coupling explicit:9293```typescript94export function useWorkflowDocumentFoo(deps: {95 getNodeByName: (name: string) => INodeUi | undefined;96}) { ... }97```9899## Reference implementation100101See `useWorkflowDocumentActive.ts` — the simplest complete example of the102apply/public pattern with event hooks.103
Also in n8n-io/n8n
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| n8n-io/n8n.agents/skills/AGENTS.md · 199k | AGENTS.md | setuparchagent-behaviour | 58/100 | 3 days ago | |
| n8n-io/n8n.github/CLAUDE.md · 199k | CLAUDE.md | styleagent-behaviour | 48/100 | 3 days ago | |
| n8n-io/n8nAGENTS.md · 199k | AGENTS.md | setupbuildtestlint-format+8 | 96/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/ai-workflow-builder.ee/AGENTS.md · 199k | AGENTS.md | agent-behaviour | 53/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/db/AGENTS.md · 199k | AGENTS.md | database | 39/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/engine/AGENTS.md · 199k | AGENTS.md | archdo-not | 59/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/instance-ai/CLAUDE.md · 199k | CLAUDE.md | buildteststyletesting-strategy+1 | 89/100 | 3 days ago | |
| n8n-io/n8npackages/cli/AGENTS.md · 199k | AGENTS.md | lint-format | 55/100 | 3 days ago | |
| n8n-io/n8npackages/cli/src/modules/n8n-packages/CLAUDE.md · 199k | CLAUDE.md | stylearchdependenciesmonorepo+2 | 69/100 | 3 days ago | |
| n8n-io/n8npackages/frontend/AGENTS.md · 199k | AGENTS.md | style | 40/100 | 3 days ago | |
| n8n-io/n8npackages/nodes-base/AGENTS.md · 199k | AGENTS.md | teststylearchtypes+5 | 89/100 | 3 days ago | |
| n8n-io/n8npackages/testing/playwright/AGENTS.md · 199k | AGENTS.md | setupbuildtestlint-format+8 | 96/100 | 3 days ago | |
| n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199k | AGENTS.md | buildteststylearch+3 | 100/100 | 3 days ago | |
| n8n-io/n8nscripts/instance-seeding/AGENTS.md · 199k | AGENTS.md | setupstyledo-not | 65/100 | 3 days ago |
Diff against .agents/skills/AGENTS.md Diff against .github/CLAUDE.md Diff against AGENTS.md Diff against packages/@n8n/ai-workflow-builder.ee/AGENTS.md Diff against packages/@n8n/db/AGENTS.md Diff against packages/@n8n/engine/AGENTS.md Diff against packages/@n8n/instance-ai/CLAUDE.md Diff against packages/cli/AGENTS.md Diff against packages/cli/src/modules/n8n-packages/CLAUDE.md Diff against packages/frontend/AGENTS.md Diff against packages/nodes-base/AGENTS.md Diff against packages/testing/playwright/AGENTS.md Diff against packages/@n8n/agents/AGENTS.md Diff against scripts/instance-seeding/AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| dotCMS/corecore-web/CLAUDE.md · 950 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| dotCMS/coreCLAUDE.md · 950 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | 3 days ago | |
| lollipopkit/flutter_server_boxCLAUDE.md · 8.3k | CLAUDE.md | buildteststylearch+2 | 98/100 | 3 days ago | |
| skillrecordings/egghead-nextCLAUDE.md · 1.4k | CLAUDE.md | setupbuildtestlint-format+8 | 97/100 | 3 days ago | |
| MetaMask/metamask-design-systemCLAUDE.md · 34 | CLAUDE.md | buildtestlint-formatstyle+5 | 97/100 | 3 days ago |
