codeforge-dev 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.devcontainer/.env +22 -0
  2. package/.devcontainer/CHANGELOG.md +197 -0
  3. package/.devcontainer/CLAUDE.md +117 -0
  4. package/.devcontainer/README.md +222 -0
  5. package/.devcontainer/config/main-system-prompt.md +502 -0
  6. package/.devcontainer/config/settings.json +47 -0
  7. package/.devcontainer/devcontainer.json +94 -0
  8. package/.devcontainer/features/README.md +113 -0
  9. package/.devcontainer/features/agent-browser/README.md +65 -0
  10. package/.devcontainer/features/agent-browser/devcontainer-feature.json +23 -0
  11. package/.devcontainer/features/agent-browser/install.sh +79 -0
  12. package/.devcontainer/features/ast-grep/README.md +24 -0
  13. package/.devcontainer/features/ast-grep/devcontainer-feature.json +24 -0
  14. package/.devcontainer/features/ast-grep/install.sh +51 -0
  15. package/.devcontainer/features/ccstatusline/README.md +296 -0
  16. package/.devcontainer/features/ccstatusline/devcontainer-feature.json +19 -0
  17. package/.devcontainer/features/ccstatusline/install.sh +290 -0
  18. package/.devcontainer/features/ccusage/README.md +205 -0
  19. package/.devcontainer/features/ccusage/devcontainer-feature.json +38 -0
  20. package/.devcontainer/features/ccusage/install.sh +132 -0
  21. package/.devcontainer/features/claude-code/README.md +498 -0
  22. package/.devcontainer/features/claude-code/config/settings.json +36 -0
  23. package/.devcontainer/features/claude-code/config/system-prompt.md +118 -0
  24. package/.devcontainer/features/claude-code/config/world-building-sp.md +1432 -0
  25. package/.devcontainer/features/claude-code/devcontainer-feature.json +42 -0
  26. package/.devcontainer/features/claude-code/install.sh +466 -0
  27. package/.devcontainer/features/claude-monitor/README.md +74 -0
  28. package/.devcontainer/features/claude-monitor/devcontainer-feature.json +38 -0
  29. package/.devcontainer/features/claude-monitor/install.sh +99 -0
  30. package/.devcontainer/features/lsp-servers/README.md +85 -0
  31. package/.devcontainer/features/lsp-servers/devcontainer-feature.json +40 -0
  32. package/.devcontainer/features/lsp-servers/install.sh +116 -0
  33. package/.devcontainer/features/mcp-qdrant/CHANGES.md +399 -0
  34. package/.devcontainer/features/mcp-qdrant/README.md +474 -0
  35. package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +57 -0
  36. package/.devcontainer/features/mcp-qdrant/install.sh +295 -0
  37. package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +129 -0
  38. package/.devcontainer/features/mcp-reasoner/README.md +177 -0
  39. package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +20 -0
  40. package/.devcontainer/features/mcp-reasoner/install.sh +177 -0
  41. package/.devcontainer/features/mcp-reasoner/poststart-hook.sh +67 -0
  42. package/.devcontainer/features/notify-hook/README.md +86 -0
  43. package/.devcontainer/features/notify-hook/devcontainer-feature.json +23 -0
  44. package/.devcontainer/features/notify-hook/install.sh +38 -0
  45. package/.devcontainer/features/splitrail/README.md +140 -0
  46. package/.devcontainer/features/splitrail/devcontainer-feature.json +34 -0
  47. package/.devcontainer/features/splitrail/install.sh +129 -0
  48. package/.devcontainer/features/tree-sitter/README.md +138 -0
  49. package/.devcontainer/features/tree-sitter/devcontainer-feature.json +52 -0
  50. package/.devcontainer/features/tree-sitter/install.sh +173 -0
  51. package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +106 -0
  52. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +7 -0
  53. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json +17 -0
  54. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-file.py +101 -0
  55. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +7 -0
  56. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +17 -0
  57. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +137 -0
  58. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/.claude-plugin/plugin.json +8 -0
  59. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/SKILL.md +387 -0
  60. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/cli-flags-and-output.md +312 -0
  61. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/sdk-and-mcp.md +569 -0
  62. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/SKILL.md +309 -0
  63. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/compose-services.md +438 -0
  64. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/dockerfile-patterns.md +340 -0
  65. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/SKILL.md +412 -0
  66. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/container-lifecycle.md +388 -0
  67. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/resources-and-security.md +444 -0
  68. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/SKILL.md +344 -0
  69. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/middleware-and-lifespan.md +254 -0
  70. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/pydantic-models.md +245 -0
  71. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/routing-and-dependencies.md +255 -0
  72. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/sse-and-streaming.md +318 -0
  73. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/SKILL.md +345 -0
  74. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/agents-and-tools.md +271 -0
  75. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/models-and-streaming.md +422 -0
  76. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/SKILL.md +220 -0
  77. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/cross-vendor-principles.md +139 -0
  78. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/patterns-and-antipatterns.md +376 -0
  79. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/skill-authoring-patterns.md +356 -0
  80. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/SKILL.md +329 -0
  81. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/advanced-queries.md +314 -0
  82. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/javascript-patterns.md +323 -0
  83. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/python-patterns.md +354 -0
  84. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/schema-and-pragmas.md +326 -0
  85. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/SKILL.md +356 -0
  86. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/ai-sdk-svelte.md +128 -0
  87. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/component-patterns.md +332 -0
  88. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/layercake.md +203 -0
  89. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/migration-guide.md +350 -0
  90. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/runes-and-reactivity.md +328 -0
  91. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/spa-and-routing.md +262 -0
  92. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/svelte-dnd-action.md +181 -0
  93. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/SKILL.md +414 -0
  94. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/fastapi-testing.md +411 -0
  95. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/svelte-testing.md +538 -0
  96. package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +7 -0
  97. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/.claude-plugin/plugin.json +7 -0
  98. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/hooks/hooks.json +17 -0
  99. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +110 -0
  100. package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/.claude-plugin/plugin.json +7 -0
  101. package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +17 -0
  102. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +7 -0
  103. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +17 -0
  104. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/.claude-plugin/plugin.json +7 -0
  105. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/hooks/hooks.json +17 -0
  106. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +108 -0
  107. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272create-pr.md +337 -0
  108. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272new.md +166 -0
  109. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272review-commit.md +290 -0
  110. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272work.md +257 -0
  111. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json +8 -0
  112. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md +184 -0
  113. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +6 -0
  114. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +14 -0
  115. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +989 -0
  116. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +33 -0
  117. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
  118. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +71 -0
  119. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +68 -0
  120. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +120 -0
  121. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +133 -0
  122. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +253 -0
  123. package/.devcontainer/scripts/setup-aliases.sh +80 -0
  124. package/.devcontainer/scripts/setup-config.sh +28 -0
  125. package/.devcontainer/scripts/setup-irie-claude.sh +32 -0
  126. package/.devcontainer/scripts/setup-plugins.sh +80 -0
  127. package/.devcontainer/scripts/setup.sh +58 -0
  128. package/LICENSE.txt +674 -0
  129. package/README.md +267 -0
  130. package/package.json +44 -0
  131. package/setup.js +83 -0
@@ -0,0 +1,262 @@
1
+ # SPA and Routing — Deep Dive
2
+
3
+ ## 1. SPA Configuration
4
+
5
+ ### Core Setup
6
+
7
+ Three changes convert a SvelteKit project to a single-page application:
8
+
9
+ **1. Install adapter-static:**
10
+
11
+ ```bash
12
+ npm install -D @sveltejs/adapter-static
13
+ ```
14
+
15
+ **2. Configure svelte.config.js:**
16
+
17
+ ```js
18
+ import adapter from '@sveltejs/adapter-static';
19
+
20
+ export default {
21
+ kit: {
22
+ adapter: adapter({
23
+ fallback: '200.html' // Serves the SPA shell for all unmatched routes
24
+ }),
25
+ prerender: {
26
+ entries: [] // Disable automatic prerendering
27
+ }
28
+ }
29
+ };
30
+ ```
31
+
32
+ **3. Disable SSR globally:**
33
+
34
+ ```js
35
+ // src/routes/+layout.js
36
+ export const ssr = false;
37
+ ```
38
+
39
+ The `fallback` page name depends on the hosting platform:
40
+ - `200.html` — Surge, many static hosts
41
+ - `index.html` — GitHub Pages, Netlify (with `_redirects` file)
42
+ - `404.html` — GitHub Pages alternative (handles as custom 404)
43
+
44
+ ### Why ssr = false in +layout.js
45
+
46
+ Setting `ssr = false` at the root layout propagates to all routes. Every page renders exclusively on the client. This means:
47
+
48
+ - No server-side rendering step
49
+ - No `+page.server.js` or `+layout.server.js` files (server load functions are unavailable)
50
+ - All data fetching occurs in `+page.js` load functions or in component effects
51
+ - `$app/environment` reports `browser` as always `true`
52
+
53
+ ## 2. File-Based Routing
54
+
55
+ SvelteKit uses the filesystem for routing. Each directory under `src/routes/` maps to a URL path:
56
+
57
+ ```
58
+ src/routes/
59
+ ├── +layout.svelte → root layout (wraps all pages)
60
+ ├── +page.svelte → /
61
+ ├── about/
62
+ │ └── +page.svelte → /about
63
+ ├── blog/
64
+ │ ├── +page.svelte → /blog
65
+ │ └── [slug]/
66
+ │ └── +page.svelte → /blog/:slug
67
+ └── (app)/
68
+ ├── +layout.svelte → shared layout for grouped routes
69
+ ├── dashboard/
70
+ │ └── +page.svelte → /dashboard
71
+ └── settings/
72
+ └── +page.svelte → /settings
73
+ ```
74
+
75
+ ### Dynamic Parameters
76
+
77
+ Square brackets define dynamic route segments:
78
+
79
+ ```
80
+ [slug] → single parameter (required)
81
+ [...rest] → catch-all (zero or more segments)
82
+ [[optional]] → optional parameter
83
+ ```
84
+
85
+ Access parameters in load functions or via the `$page` store:
86
+
87
+ ```js
88
+ // src/routes/blog/[slug]/+page.js
89
+ export function load({ params }) {
90
+ return { slug: params.slug };
91
+ }
92
+ ```
93
+
94
+ ### Route Groups
95
+
96
+ Parenthesized directories like `(app)` create layout groups without affecting the URL. Routes inside `(app)/` share a layout but the URL does not include `(app)`.
97
+
98
+ Use route groups to:
99
+ - Apply different layouts to different sections
100
+ - Separate authenticated and public routes
101
+ - Share a sidebar or navigation across a subset of pages
102
+
103
+ ## 3. Load Functions in SPA Mode
104
+
105
+ In SPA mode, only `+page.js` and `+layout.js` load functions are available (no `.server.js` variants).
106
+
107
+ ### Client-Only Load Function
108
+
109
+ ```js
110
+ // src/routes/dashboard/+page.js
111
+ export async function load({ fetch, params, url }) {
112
+ const res = await fetch('/api/dashboard');
113
+ const data = await res.json();
114
+ return { dashboard: data };
115
+ }
116
+ ```
117
+
118
+ The `fetch` provided by SvelteKit adds relative URL resolution and cookie forwarding. Prefer it over the global `fetch`.
119
+
120
+ ### Accessing Load Data
121
+
122
+ Load function return values are available as `data` in the corresponding `+page.svelte`:
123
+
124
+ ```svelte
125
+ <!-- src/routes/dashboard/+page.svelte -->
126
+ <script>
127
+ let { data } = $props();
128
+ </script>
129
+ <h1>Dashboard</h1>
130
+ <pre>{JSON.stringify(data.dashboard, null, 2)}</pre>
131
+ ```
132
+
133
+ ### Invalidation and Re-running Loads
134
+
135
+ Force a load function to re-run using `invalidate` or `invalidateAll`:
136
+
137
+ ```js
138
+ import { invalidate, invalidateAll } from '$app/navigation';
139
+
140
+ // Re-run load functions that depend on a specific URL
141
+ invalidate('/api/dashboard');
142
+
143
+ // Re-run all active load functions
144
+ invalidateAll();
145
+ ```
146
+
147
+ Load functions re-run when their dependencies change (URL parameters, `fetch` URLs, or `depends` keys).
148
+
149
+ Register custom dependency keys with `depends`:
150
+
151
+ ```js
152
+ export async function load({ fetch, depends }) {
153
+ depends('app:dashboard');
154
+ const res = await fetch('/api/dashboard');
155
+ return { dashboard: await res.json() };
156
+ }
157
+
158
+ // Later: invalidate('app:dashboard');
159
+ ```
160
+
161
+ ## 4. Prerendering in SPA Mode
162
+
163
+ Even with `ssr = false`, specific routes can be prerendered as static HTML:
164
+
165
+ ```js
166
+ // src/routes/about/+page.js
167
+ export const prerender = true;
168
+ ```
169
+
170
+ This generates a static `about/index.html` at build time. Useful for:
171
+ - Marketing pages that benefit from instant load
172
+ - SEO-critical pages (search engines see full HTML)
173
+ - Pages with no dynamic data
174
+
175
+ The rest of the application still uses the SPA fallback for client-side routing.
176
+
177
+ ### Prerender Configuration
178
+
179
+ Control prerender behavior in `svelte.config.js`:
180
+
181
+ ```js
182
+ export default {
183
+ kit: {
184
+ prerender: {
185
+ entries: ['/about', '/pricing'], // Explicitly list pages to prerender
186
+ handleHttpError: 'warn' // Warn instead of fail on broken links
187
+ }
188
+ }
189
+ };
190
+ ```
191
+
192
+ ## 5. Navigation
193
+
194
+ ### Programmatic Navigation
195
+
196
+ ```js
197
+ import { goto } from '$app/navigation';
198
+
199
+ // Navigate to a route
200
+ goto('/dashboard');
201
+
202
+ // Replace history entry (no back button)
203
+ goto('/login', { replaceState: true });
204
+
205
+ // Keep current scroll position
206
+ goto('/page', { noScroll: true });
207
+ ```
208
+
209
+ ### Navigation Lifecycle
210
+
211
+ ```js
212
+ import { beforeNavigate, afterNavigate, onNavigate } from '$app/navigation';
213
+
214
+ // Runs before leaving current page — can cancel navigation
215
+ beforeNavigate(({ cancel, to }) => {
216
+ if (hasUnsavedChanges && !confirm('Leave without saving?')) {
217
+ cancel();
218
+ }
219
+ });
220
+
221
+ // Runs after navigation completes — useful for analytics
222
+ afterNavigate(({ from, to }) => {
223
+ trackPageView(to?.url.pathname);
224
+ });
225
+
226
+ // Runs when navigation starts — returns a promise for view transitions
227
+ onNavigate((navigation) => {
228
+ // Optionally return a promise to delay navigation
229
+ });
230
+ ```
231
+
232
+ ### Page Store
233
+
234
+ Access the current URL, params, and route info via the `$page` store:
235
+
236
+ ```svelte
237
+ <script>
238
+ import { page } from '$app/stores';
239
+ </script>
240
+ <nav>
241
+ <a href="/" class:active={$page.url.pathname === '/'}>Home</a>
242
+ <a href="/about" class:active={$page.url.pathname === '/about'}>About</a>
243
+ </nav>
244
+ ```
245
+
246
+ ### Link Options
247
+
248
+ Control SvelteKit link behavior with `data-sveltekit-*` attributes:
249
+
250
+ ```html
251
+ <!-- Preload on hover (default behavior) -->
252
+ <a href="/about">About</a>
253
+
254
+ <!-- Preload immediately when link enters viewport -->
255
+ <a href="/about" data-sveltekit-preload-data="eager">About</a>
256
+
257
+ <!-- Disable SvelteKit handling (full page navigation) -->
258
+ <a href="/external" data-sveltekit-reload>External</a>
259
+
260
+ <!-- Replace history entry -->
261
+ <a href="/step2" data-sveltekit-replacestate>Next Step</a>
262
+ ```
@@ -0,0 +1,181 @@
1
+ # svelte-dnd-action — Reference
2
+
3
+ ## Mental Model
4
+
5
+ `svelte-dnd-action` is an action-based drag-and-drop library. The `use:dndzone` action transforms any container element into a drag-and-drop zone. Items are plain arrays managed with `$state`; the library emits events when the user drags (consider) and drops (finalize), and the component reassigns its items array in response. There is no separate state store or provider — the action reads items from its options and communicates changes through DOM events.
6
+
7
+ > Official documentation and examples: <https://github.com/isaacHagworthy/svelte-dnd-action>
8
+
9
+ ---
10
+
11
+ ## Core API
12
+
13
+ ### The dndzone Action
14
+
15
+ Apply `use:dndzone` to a container element. The action accepts an options object and emits two events:
16
+
17
+ ```svelte
18
+ <script>
19
+ import { dndzone } from 'svelte-dnd-action';
20
+
21
+ let items = $state([
22
+ { id: 1, name: 'Item A' },
23
+ { id: 2, name: 'Item B' },
24
+ { id: 3, name: 'Item C' }
25
+ ]);
26
+
27
+ function handleSort(e) {
28
+ items = e.detail.items;
29
+ }
30
+ </script>
31
+
32
+ <div
33
+ use:dndzone={{ items }}
34
+ onconsider={handleSort}
35
+ onfinalize={handleSort}
36
+ >
37
+ {#each items as item (item.id)}
38
+ <div>{item.name}</div>
39
+ {/each}
40
+ </div>
41
+ ```
42
+
43
+ ### Events
44
+
45
+ | Event | When | Purpose |
46
+ |-------|------|---------|
47
+ | `consider` | During drag (hover, reorder) | Preview the tentative new order; update items for visual feedback |
48
+ | `finalize` | On drop | Commit the final order; update items to persist the result |
49
+
50
+ Both events provide `e.detail.items` (the reordered array) and `e.detail.info` (metadata about the drag operation including `trigger` and `source`).
51
+
52
+ ### Options
53
+
54
+ | Option | Type | Default | Description |
55
+ |--------|------|---------|-------------|
56
+ | `items` | array | required | The array of items. Each must have a unique `id` property |
57
+ | `type` | string | internal ID | Zone type identifier. Only zones with matching types accept drops |
58
+ | `flipDurationMs` | number | 0 | Animation duration in ms for reorder transitions. Set to ~200 for smooth animations |
59
+ | `dragDisabled` | boolean | false | Disable dragging from this zone |
60
+ | `morphDisabled` | boolean | false | Disable morph animation when items move between zones |
61
+ | `dropFromOthersDisabled` | boolean | false | Prevent items from being dropped into this zone from other zones |
62
+ | `dropTargetStyle` | object | `{outline: ...}` | CSS styles applied to the zone when a dragged item hovers over it |
63
+ | `dropTargetClasses` | array | `[]` | CSS classes applied to the zone during hover |
64
+ | `transformDraggedElement` | function | undefined | Callback to modify the dragged element's appearance |
65
+ | `autoAriaDisabled` | boolean | false | Disable automatic ARIA attribute management |
66
+ | `centreDraggedOnCursor` | boolean | false | Center the dragged element on the cursor |
67
+ | `zoneTabIndex` | number | 0 | Tab index for the zone container |
68
+ | `minItems` | number | undefined | Minimum items the zone must retain |
69
+ | `maxItems` | number | undefined | Maximum items the zone accepts |
70
+ | `itemsOrientation` | string | inferred | `"vertical"`, `"horizontal"`, or `"grid"`. Usually auto-detected |
71
+ | `multiDrag` | boolean | false | Enable selecting and dragging multiple items |
72
+
73
+ ---
74
+
75
+ ## Drag Handle Pattern
76
+
77
+ Use `dragHandleZone` and `dragHandle` when only a specific element within each item should initiate dragging:
78
+
79
+ ```svelte
80
+ <script>
81
+ import { dragHandleZone, dragHandle } from 'svelte-dnd-action';
82
+
83
+ let items = $state([
84
+ { id: 1, name: 'Task A' },
85
+ { id: 2, name: 'Task B' }
86
+ ]);
87
+
88
+ function handleSort(e) {
89
+ items = e.detail.items;
90
+ }
91
+ </script>
92
+
93
+ <div
94
+ use:dragHandleZone={{ items }}
95
+ onconsider={handleSort}
96
+ onfinalize={handleSort}
97
+ >
98
+ {#each items as item (item.id)}
99
+ <div>
100
+ <span use:dragHandle aria-label="drag handle">☰</span>
101
+ <span>{item.name}</span>
102
+ </div>
103
+ {/each}
104
+ </div>
105
+ ```
106
+
107
+ `dragHandleZone` replaces `dndzone` on the container. `dragHandle` marks the grip element inside each item. All options and events remain the same.
108
+
109
+ ---
110
+
111
+ ## Svelte 5 Integration
112
+
113
+ ### Event Syntax
114
+
115
+ Svelte 5 uses `onconsider` and `onfinalize` (no colon). The Svelte 4 syntax `on:consider` and `on:finalize` does not work in runes mode:
116
+
117
+ ```svelte
118
+ <!-- Correct (Svelte 5) -->
119
+ <div use:dndzone={{ items }} onconsider={handleSort} onfinalize={handleSort}>
120
+
121
+ <!-- Wrong (Svelte 4 syntax) -->
122
+ <div use:dndzone={{ items }} on:consider={handleSort} on:finalize={handleSort}>
123
+ ```
124
+
125
+ ### State Management
126
+
127
+ Store items with `$state()` and reassign in event handlers. The library checks reference equality, so always reassign the entire array — never use `splice` or other in-place mutations in the handler:
128
+
129
+ ```js
130
+ let items = $state([...]);
131
+
132
+ function handleSort(e) {
133
+ items = e.detail.items; // full reassignment
134
+ }
135
+ ```
136
+
137
+ ### Version Requirement
138
+
139
+ Version **0.9.59+** is required for `$state` compatibility. Earlier versions do not correctly detect Svelte 5's reactive proxies and may fail silently or throw during drag operations.
140
+
141
+ ---
142
+
143
+ ## Shadow Item Handling
144
+
145
+ During a drag operation, the library inserts a shadow placeholder item into the items array to represent the drop position. This shadow item is visible to `$derived` computations over the items array.
146
+
147
+ Filter shadow items when computing derived values to avoid counting or displaying the placeholder:
148
+
149
+ ```js
150
+ import { SHADOW_ITEM_MARKER_PROPERTY_NAME } from 'svelte-dnd-action';
151
+
152
+ let items = $state([...]);
153
+ let realCount = $derived(
154
+ items.filter(i => !i[SHADOW_ITEM_MARKER_PROPERTY_NAME]).length
155
+ );
156
+ ```
157
+
158
+ The shadow item carries the `SHADOW_ITEM_MARKER_PROPERTY_NAME` property set to `true`. The companion constant `SHADOW_PLACEHOLDER_ITEM_ID` holds the shadow's `id` value for identity-based filtering.
159
+
160
+ ---
161
+
162
+ ## Exported Constants
163
+
164
+ | Constant | Purpose |
165
+ |----------|---------|
166
+ | `TRIGGERS` | Enum of drag trigger types (e.g., `DRAG_STARTED`, `DROPPED_INTO_ZONE`) |
167
+ | `SOURCES` | Enum of event sources (e.g., `POINTER`, `KEYBOARD`) |
168
+ | `SHADOW_ITEM_MARKER_PROPERTY_NAME` | Property name on shadow placeholder items |
169
+ | `SHADOW_PLACEHOLDER_ITEM_ID` | The `id` value assigned to shadow items |
170
+
171
+ Access trigger and source info from `e.detail.info`:
172
+
173
+ ```js
174
+ import { TRIGGERS, SOURCES } from 'svelte-dnd-action';
175
+
176
+ function handleFinalize(e) {
177
+ if (e.detail.info.trigger === TRIGGERS.DROPPED_INTO_ZONE) {
178
+ saveOrder(e.detail.items);
179
+ }
180
+ }
181
+ ```