forge-openclaw-plugin 0.2.60 → 0.2.65
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.
- package/README.md +121 -51
- package/dist/assets/{board-B1V3M__K.js → board-DUwMfZvN.js} +1 -1
- package/dist/assets/index-B9VOpR7r.css +1 -0
- package/dist/assets/index-DoHjjze2.js +90 -0
- package/dist/assets/{motion-CltSTItx.js → motion-Crg3QyXD.js} +1 -1
- package/dist/assets/{table-B-VrSFx8.js → table-CTlDeYRs.js} +1 -1
- package/dist/assets/{ui-DUqM4jkt.js → ui-CJPaElbj.js} +1 -1
- package/dist/assets/{vendor-C0otBhgu.js → vendor-BdrT2htV.js} +217 -207
- package/dist/companion-iroh/darwin-arm64/forge-companion-iroh +0 -0
- package/dist/companion-iroh/darwin-x64/forge-companion-iroh +0 -0
- package/dist/companion-iroh/linux-x64/forge-companion-iroh +0 -0
- package/dist/companion-iroh-src/Cargo.lock +4559 -0
- package/dist/companion-iroh-src/Cargo.toml +37 -0
- package/dist/companion-iroh-src/src/lib.rs +279 -0
- package/dist/companion-iroh-src/src/main.rs +478 -0
- package/dist/companion-iroh-src/src/protocol.rs +129 -0
- package/dist/gamification-previews/dark-fantasy-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/dark-fantasy-mascot.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/dramatic-smithie-mascot.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-trophy-tasks-anvil-marathon.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-trophy-xp-levels-the-first-heat.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-item-unlock-streaks-molten-crown-fire.webp +0 -0
- package/dist/gamification-previews/mind-locksmith-mascot.webp +0 -0
- package/dist/index.html +7 -7
- package/dist/openclaw/parity.js +27 -0
- package/dist/openclaw/plugin-entry-shared.js +2 -2
- package/dist/openclaw/plugin-sdk-types.d.ts +2 -1
- package/dist/openclaw/routes.d.ts +4 -0
- package/dist/openclaw/routes.js +112 -3
- package/dist/openclaw/tools.js +32 -4
- package/dist/server/server/migrations/059_data_backup_retention.sql +2 -0
- package/dist/server/server/src/app.js +288 -61
- package/dist/server/server/src/data-management-types.js +2 -0
- package/dist/server/server/src/discovery-advertiser.js +13 -0
- package/dist/server/server/src/health.js +58 -3
- package/dist/server/server/src/movement.js +16 -1
- package/dist/server/server/src/openapi.js +410 -9
- package/dist/server/server/src/repositories/rewards.js +60 -0
- package/dist/server/server/src/services/companion-iroh.js +425 -0
- package/dist/server/server/src/services/data-management.js +32 -2
- package/dist/server/server/src/services/doctor.js +762 -0
- package/dist/server/server/src/services/gamification.js +75 -3
- package/dist/server/server/src/services/life-force.js +166 -25
- package/dist/server/server/src/web.js +88 -12
- package/dist/server/src/lib/api.js +9 -0
- package/dist/server/src/lib/gamification-catalog.js +1 -1
- package/openclaw.plugin.json +85 -3
- package/package.json +10 -6
- package/server/migrations/059_data_backup_retention.sql +2 -0
- package/skills/forge-openclaw/SKILL.md +80 -19
- package/skills/forge-openclaw/entity_conversation_playbooks.md +283 -25
- package/skills/forge-openclaw/psyche_entity_playbooks.md +82 -0
- package/dist/assets/index-BwKAPo98.css +0 -1
- package/dist/assets/index-Dy7c-dRY.js +0 -90
package/README.md
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
# Forge OpenClaw Plugin
|
|
2
2
|
|
|
3
|
-
`forge-openclaw-plugin` is the
|
|
4
|
-
When the plugin targets `localhost` or `127.0.0.1`, it auto-starts the bundled Forge runtime so the local install path stays one-step.
|
|
3
|
+
`forge-openclaw-plugin` is the OpenClaw bridge for Forge.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
For normal installs, start with the single-command Forge installer:
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npx forge-memory
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
It installs the Forge UI/runtime first, discovers OpenClaw, Hermes, and Codex in
|
|
12
|
+
the background, lets you choose adapters from a guided checkbox flow, and keeps
|
|
13
|
+
every selected surface pointed at the same real Forge data folder. Use the direct
|
|
14
|
+
OpenClaw commands below only for plugin-specific debugging, source-linking, or
|
|
15
|
+
manual recovery.
|
|
16
|
+
|
|
17
|
+
It gives OpenClaw a clear way to:
|
|
18
|
+
|
|
19
|
+
- start or reach the local Forge runtime
|
|
20
|
+
- open the Forge web app
|
|
21
|
+
- read the current operator overview
|
|
22
|
+
- create and update goals, projects, issues, tasks, notes, wiki pages, health records, preferences, and Psyche records
|
|
23
|
+
- run Forge Doctor when the local setup looks wrong
|
|
24
|
+
|
|
25
|
+
When the plugin targets `localhost` or `127.0.0.1`, it can auto-start the bundled Forge runtime. That is why current OpenClaw installers may ask for explicit approval during install.
|
|
12
26
|
|
|
13
27
|
## Open the UI
|
|
14
28
|
|
|
@@ -24,10 +38,18 @@ For a normal local install, the Forge UI address is usually:
|
|
|
24
38
|
http://127.0.0.1:4317/forge/
|
|
25
39
|
```
|
|
26
40
|
|
|
27
|
-
That `4317` backend URL is the stable entrypoint
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
That `4317` backend URL is the stable entrypoint for normal local plugin installs.
|
|
42
|
+
|
|
43
|
+
Albert's MacBook also has a repo-local development mode used for plugin/dashboard work.
|
|
44
|
+
The restored 6-hour Tailscale automation exposes `/forge` through the `4317` backend as
|
|
45
|
+
`http://127.0.0.1:4317/forge/`, while that backend is started locally with
|
|
46
|
+
`FORGE_OPENCLAW_DEV=1` and proxies the Vite dev server at `127.0.0.1:3027`. A correct
|
|
47
|
+
dev-mode response contains `/forge/@vite/client` and `/forge/src/main.tsx`.
|
|
48
|
+
|
|
49
|
+
That environment flag is only for the repo-local development machine. Normal plugin
|
|
50
|
+
installs on other machines use the packaged runtime by default and should not be forced
|
|
51
|
+
into source-backed dev mode. The restored automation also must not expose `/forge-dev` or
|
|
52
|
+
point `/forge` at bare `http://127.0.0.1:3027`.
|
|
31
53
|
|
|
32
54
|
You can also ask the agent to call the UI entry tool and return the exact current address.
|
|
33
55
|
|
|
@@ -35,10 +57,13 @@ If you want Forge to use a specific local data folder, set `dataRoot` in the plu
|
|
|
35
57
|
|
|
36
58
|
Default data path:
|
|
37
59
|
|
|
38
|
-
- local installs
|
|
39
|
-
- set `dataRoot`
|
|
60
|
+
- local installs default to `~/.forge/forge.sqlite`
|
|
61
|
+
- the user can set `dataRoot` to use another folder
|
|
62
|
+
- when `dataRoot` is set, Forge stores `forge.sqlite` directly inside that folder
|
|
63
|
+
|
|
64
|
+
If you want the data to live somewhere specific for persistence or backup reasons, set `dataRoot` explicitly in the plugin config and restart the gateway. When debugging storage, check the config and the live runtime path before moving or merging database files.
|
|
40
65
|
|
|
41
|
-
|
|
66
|
+
The Forge web app also exposes these controls in `Settings -> Data`. Use it to see the live data folder, move current data, adopt an existing Forge data folder, create a manual backup, enable automatic backups, and choose how many days of automatic backups Forge should keep. Automatic retention only cleans automatic backups; manual and safety backups stay in place.
|
|
42
67
|
|
|
43
68
|
## What Forge looks like
|
|
44
69
|
|
|
@@ -116,8 +141,8 @@ Recommended shared setup:
|
|
|
116
141
|
|
|
117
142
|
1. Run one shared Forge runtime.
|
|
118
143
|
2. Point OpenClaw, Hermes, and the browser UI at that same runtime.
|
|
119
|
-
3.
|
|
120
|
-
|
|
144
|
+
3. Use one explicit shared `dataRoot` when several adapters must share the same
|
|
145
|
+
database.
|
|
121
146
|
4. Create the human and bot users in `Settings -> Users`.
|
|
122
147
|
5. Use `userId` on writes and `userIds` on reads.
|
|
123
148
|
|
|
@@ -130,9 +155,9 @@ Current sharing behavior is intentionally clear:
|
|
|
130
155
|
tasks, notes, or strategy nodes
|
|
131
156
|
|
|
132
157
|
If OpenClaw and Hermes are supposed to collaborate inside one Forge system, the
|
|
133
|
-
important thing is not only matching `origin` and `port`.
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
important thing is not only matching `origin` and `port`. Either leave every
|
|
159
|
+
adapter on the default `~/.forge` root or set one explicit `dataRoot`, then
|
|
160
|
+
verify that each live runtime has opened that database.
|
|
136
161
|
|
|
137
162
|
## Strategies And Alignment Metrics
|
|
138
163
|
|
|
@@ -213,47 +238,96 @@ OpenClaw tool coverage for those areas is explicit:
|
|
|
213
238
|
The sports UI route is `/forge/sports`, while the backend overview route remains
|
|
214
239
|
`/api/v1/health/fitness`. Sleep lives at `/forge/sleep` and `/api/v1/health/sleep`.
|
|
215
240
|
|
|
216
|
-
## Install
|
|
241
|
+
## Advanced Install
|
|
217
242
|
|
|
218
|
-
|
|
243
|
+
Prefer `npx forge-memory` for normal installs. The direct commands in this
|
|
244
|
+
section are for OpenClaw-specific debugging, source-linking, and recovery.
|
|
245
|
+
|
|
246
|
+
### Published Package
|
|
247
|
+
|
|
248
|
+
Use this path when you want the released Forge plugin from npm:
|
|
219
249
|
|
|
220
250
|
```bash
|
|
221
|
-
openclaw plugins install forge-openclaw-plugin
|
|
251
|
+
openclaw plugins install --dangerously-force-unsafe-install forge-openclaw-plugin
|
|
222
252
|
openclaw plugins enable forge-openclaw-plugin
|
|
223
|
-
node -e 'const fs=require("fs"); const p=process.env.HOME+"/.openclaw/openclaw.json"; const j=JSON.parse(fs.readFileSync(p,"utf8")); j.plugins ??= {}; j.plugins.allow = Array.from(new Set([...(j.plugins.allow || []), "forge-openclaw-plugin"])); fs.writeFileSync(p, JSON.stringify(j, null, 2)+"\n");'
|
|
224
253
|
openclaw gateway restart
|
|
225
254
|
openclaw forge health
|
|
255
|
+
openclaw forge ui
|
|
226
256
|
```
|
|
227
257
|
|
|
228
|
-
|
|
258
|
+
Tested on OpenClaw `2026.5.4`: plain `openclaw plugins install forge-openclaw-plugin` is blocked by the plugin scanner because Forge contains local runtime startup helpers. The documented command uses OpenClaw's explicit approval flag and installs without the old config-edit workaround.
|
|
259
|
+
|
|
260
|
+
Check what OpenClaw loaded:
|
|
229
261
|
|
|
230
262
|
```bash
|
|
231
|
-
|
|
232
|
-
node -e 'const cp=require("child_process"); const fs=require("fs"); const path=require("path"); const p=process.env.HOME+"/.openclaw/openclaw.json"; const j=JSON.parse(fs.readFileSync(p,"utf8")); const pluginPath=path.join(cp.execSync("npm root -g",{encoding:"utf8"}).trim(),"forge-openclaw-plugin"); j.plugins ??= {}; j.plugins.allow = Array.from(new Set([...(j.plugins.allow || []), "forge-openclaw-plugin"])); j.plugins.load ??= {}; j.plugins.load.paths = Array.from(new Set([...(j.plugins.load.paths || []), pluginPath])); j.plugins.entries ??= {}; j.plugins.entries["forge-openclaw-plugin"] = { enabled: true, config: { origin: "http://127.0.0.1", port: 4317, actorLabel: "", timeoutMs: 15000 } }; fs.writeFileSync(p, JSON.stringify(j, null, 2)+"\n"); console.log("Configured", pluginPath);'
|
|
233
|
-
openclaw gateway restart
|
|
234
|
-
openclaw plugins info forge-openclaw-plugin
|
|
263
|
+
openclaw plugins inspect forge-openclaw-plugin --runtime
|
|
235
264
|
openclaw forge health
|
|
236
265
|
```
|
|
237
266
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
`openclaw plugins enable forge-openclaw-plugin` marks the plugin enabled, but it does not guarantee that `plugins.allow` was repaired. The `node -e ...` command above preserves the current allow list and appends `"forge-openclaw-plugin"` if it is missing.
|
|
267
|
+
### Local Development From This Repo
|
|
241
268
|
|
|
242
|
-
|
|
269
|
+
Use this path when you are editing Forge and want OpenClaw to load this checkout directly:
|
|
243
270
|
|
|
244
271
|
```bash
|
|
245
|
-
openclaw plugins install ./
|
|
272
|
+
openclaw plugins install --link --dangerously-force-unsafe-install ./openclaw-plugin
|
|
246
273
|
openclaw plugins enable forge-openclaw-plugin
|
|
247
|
-
node -e 'const fs=require("fs"); const p=process.env.HOME+"/.openclaw/openclaw.json"; const j=JSON.parse(fs.readFileSync(p,"utf8")); j.plugins ??= {}; j.plugins.allow = Array.from(new Set([...(j.plugins.allow || []), "forge-openclaw-plugin"])); fs.writeFileSync(p, JSON.stringify(j, null, 2)+"\n");'
|
|
248
274
|
openclaw gateway restart
|
|
275
|
+
openclaw plugins inspect forge-openclaw-plugin --runtime
|
|
249
276
|
openclaw forge health
|
|
250
277
|
```
|
|
251
278
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
279
|
+
Use `--link` for active local development. Omit `--link` when you want to test the copied package layout that a normal install receives.
|
|
280
|
+
|
|
281
|
+
If you are running the command from the monorepo root instead of the Forge repo root, use:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
openclaw plugins install --link --dangerously-force-unsafe-install ./projects/forge/openclaw-plugin
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Manual Fallback For Older OpenClaw Builds
|
|
288
|
+
|
|
289
|
+
Use this only if your OpenClaw installer does not support `--dangerously-force-unsafe-install` or still refuses to install Forge. It installs the npm package, adds the package folder to `plugins.load.paths`, enables the plugin, and keeps the default local Forge runtime on `127.0.0.1:4317`.
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
npm install -g forge-openclaw-plugin
|
|
293
|
+
node <<'NODE'
|
|
294
|
+
const cp = require("node:child_process");
|
|
295
|
+
const fs = require("node:fs");
|
|
296
|
+
const path = require("node:path");
|
|
297
|
+
|
|
298
|
+
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
|
299
|
+
const pluginPath = path.join(
|
|
300
|
+
cp.execSync("npm root -g", { encoding: "utf8" }).trim(),
|
|
301
|
+
"forge-openclaw-plugin"
|
|
302
|
+
);
|
|
303
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
304
|
+
|
|
305
|
+
config.plugins ??= {};
|
|
306
|
+
config.plugins.allow = Array.from(
|
|
307
|
+
new Set([...(config.plugins.allow ?? []), "forge-openclaw-plugin"])
|
|
308
|
+
);
|
|
309
|
+
config.plugins.load ??= {};
|
|
310
|
+
config.plugins.load.paths = Array.from(
|
|
311
|
+
new Set([...(config.plugins.load.paths ?? []), pluginPath])
|
|
312
|
+
);
|
|
313
|
+
config.plugins.entries ??= {};
|
|
314
|
+
config.plugins.entries["forge-openclaw-plugin"] = {
|
|
315
|
+
enabled: true,
|
|
316
|
+
config: {
|
|
317
|
+
origin: "http://127.0.0.1",
|
|
318
|
+
port: 4317,
|
|
319
|
+
actorLabel: "",
|
|
320
|
+
timeoutMs: 15000
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
325
|
+
console.log(`Configured ${pluginPath}`);
|
|
326
|
+
NODE
|
|
327
|
+
openclaw gateway restart
|
|
328
|
+
openclaw plugins inspect forge-openclaw-plugin --runtime
|
|
329
|
+
openclaw forge health
|
|
330
|
+
```
|
|
257
331
|
|
|
258
332
|
Equivalent config:
|
|
259
333
|
|
|
@@ -265,7 +339,7 @@ Equivalent config:
|
|
|
265
339
|
"forge-openclaw-plugin": {
|
|
266
340
|
enabled: true,
|
|
267
341
|
config: {
|
|
268
|
-
dataRoot: "
|
|
342
|
+
dataRoot: "/absolute/path/to/forge-data",
|
|
269
343
|
actorLabel: "",
|
|
270
344
|
apiToken: ""
|
|
271
345
|
}
|
|
@@ -295,7 +369,8 @@ Recommended local behavior:
|
|
|
295
369
|
|
|
296
370
|
- leave `actorLabel` blank so Forge can inherit the trusted local operator label automatically
|
|
297
371
|
- leave `apiToken` blank for localhost and trusted Tailscale setups
|
|
298
|
-
-
|
|
372
|
+
- keep `dataRoot` aligned across OpenClaw, Hermes, Codex, and the browser runtime when they should share data
|
|
373
|
+
- before changing or merging data roots, back up every candidate Forge database and verify which database the live runtime is using
|
|
299
374
|
|
|
300
375
|
## Doctor And Runtime Config
|
|
301
376
|
|
|
@@ -318,10 +393,12 @@ Diagnostic entrypoints:
|
|
|
318
393
|
|
|
319
394
|
```bash
|
|
320
395
|
openclaw forge doctor
|
|
396
|
+
openclaw forge doctor --json
|
|
397
|
+
openclaw forge doctor --fix
|
|
321
398
|
npm run doctor --prefix ./projects/forge
|
|
322
399
|
```
|
|
323
400
|
|
|
324
|
-
The doctor output
|
|
401
|
+
The doctor output includes explicit runtime, settings, SQLite storage, entity-link, hierarchy, reward, and gamification checks. It also returns concrete issues and proposed fixes. Fixes are never applied by a normal read; `openclaw forge doctor --fix` applies only Doctor-marked safe fixes.
|
|
325
402
|
|
|
326
403
|
Then restart the gateway:
|
|
327
404
|
|
|
@@ -329,14 +406,7 @@ Then restart the gateway:
|
|
|
329
406
|
openclaw gateway restart
|
|
330
407
|
```
|
|
331
408
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
```bash
|
|
335
|
-
openclaw plugins install ./projects/forge
|
|
336
|
-
openclaw gateway restart
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
That repo-local path is the fallback only. The published package stays on the SDK `definePluginEntry` entrypoint. The OpenClaw plugin id is `forge-openclaw-plugin`, while the product name stays `Forge` and the CLI namespace stays `forge`.
|
|
409
|
+
The OpenClaw plugin id is `forge-openclaw-plugin`, the product name is `Forge`, and the CLI namespace is `forge`.
|
|
340
410
|
|
|
341
411
|
## Recommended usage
|
|
342
412
|
|
|
@@ -465,7 +535,7 @@ The startup error now points at that log file when the child process exits befor
|
|
|
465
535
|
The reliable publication path for the Forge plugin is:
|
|
466
536
|
|
|
467
537
|
1. publish `forge-openclaw-plugin` to npm
|
|
468
|
-
2. verify `openclaw plugins install forge-openclaw-plugin`
|
|
538
|
+
2. verify `openclaw plugins install --dangerously-force-unsafe-install forge-openclaw-plugin`
|
|
469
539
|
3. add Forge to the OpenClaw community plugin listing with the npm package and GitHub repo
|
|
470
540
|
|
|
471
541
|
The repo now supports a tag-driven GitHub Actions release path for step 1. The normal
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as c,R as I,a as Ne}from"./vendor-
|
|
1
|
+
import{r as c,R as I,a as Ne}from"./vendor-BdrT2htV.js";function Mn(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return c.useMemo(()=>r=>{t.forEach(o=>o(r))},t)}const nt=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function we(e){const t=Object.prototype.toString.call(e);return t==="[object Window]"||t==="[object global]"}function mt(e){return"nodeType"in e}function z(e){var t,n;return e?we(e)?e:mt(e)&&(t=(n=e.ownerDocument)==null?void 0:n.defaultView)!=null?t:window:window}function yt(e){const{Document:t}=z(e);return e instanceof t}function Be(e){return we(e)?!1:e instanceof z(e).HTMLElement}function Vt(e){return e instanceof z(e).SVGElement}function xe(e){return e?we(e)?e.document:mt(e)?yt(e)?e:Be(e)||Vt(e)?e.ownerDocument:document:document:document}const V=nt?c.useLayoutEffect:c.useEffect;function rt(e){const t=c.useRef(e);return V(()=>{t.current=e}),c.useCallback(function(){for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return t.current==null?void 0:t.current(...r)},[])}function On(){const e=c.useRef(null),t=c.useCallback((r,o)=>{e.current=setInterval(r,o)},[]),n=c.useCallback(()=>{e.current!==null&&(clearInterval(e.current),e.current=null)},[]);return[t,n]}function Pe(e,t){t===void 0&&(t=[e]);const n=c.useRef(e);return V(()=>{n.current!==e&&(n.current=e)},t),n}function Fe(e,t){const n=c.useRef();return c.useMemo(()=>{const r=e(n.current);return n.current=r,r},[...t])}function Je(e){const t=rt(e),n=c.useRef(null),r=c.useCallback(o=>{o!==n.current&&(t==null||t(o,n.current)),n.current=o},[]);return[n,r]}function _e(e){const t=c.useRef();return c.useEffect(()=>{t.current=e},[e]),t.current}let ut={};function $e(e,t){return c.useMemo(()=>{if(t)return t;const n=ut[e]==null?0:ut[e]+1;return ut[e]=n,e+"-"+n},[e,t])}function qt(e){return function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return r.reduce((i,s)=>{const a=Object.entries(s);for(const[l,u]of a){const d=i[l];d!=null&&(i[l]=d+e*u)}return i},{...t})}}const ye=qt(1),Qe=qt(-1);function In(e){return"clientX"in e&&"clientY"in e}function ot(e){if(!e)return!1;const{KeyboardEvent:t}=z(e.target);return t&&e instanceof t}function Nn(e){if(!e)return!1;const{TouchEvent:t}=z(e.target);return t&&e instanceof t}function Ze(e){if(Nn(e)){if(e.touches&&e.touches.length){const{clientX:t,clientY:n}=e.touches[0];return{x:t,y:n}}else if(e.changedTouches&&e.changedTouches.length){const{clientX:t,clientY:n}=e.changedTouches[0];return{x:t,y:n}}}return In(e)?{x:e.clientX,y:e.clientY}:null}const fe=Object.freeze({Translate:{toString(e){if(!e)return;const{x:t,y:n}=e;return"translate3d("+(t?Math.round(t):0)+"px, "+(n?Math.round(n):0)+"px, 0)"}},Scale:{toString(e){if(!e)return;const{scaleX:t,scaleY:n}=e;return"scaleX("+t+") scaleY("+n+")"}},Transform:{toString(e){if(e)return[fe.Translate.toString(e),fe.Scale.toString(e)].join(" ")}},Transition:{toString(e){let{property:t,duration:n,easing:r}=e;return t+" "+n+"ms "+r}}}),kt="a,frame,iframe,input:not([type=hidden]):not(:disabled),select:not(:disabled),textarea:not(:disabled),button:not(:disabled),*[tabindex]";function Tn(e){return e.matches(kt)?e:e.querySelector(kt)}const Ln={display:"none"};function kn(e){let{id:t,value:n}=e;return I.createElement("div",{id:t,style:Ln},n)}function Pn(e){let{id:t,announcement:n,ariaLiveType:r="assertive"}=e;const o={position:"fixed",top:0,left:0,width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0 0 0 0)",clipPath:"inset(100%)",whiteSpace:"nowrap"};return I.createElement("div",{id:t,style:o,role:"status","aria-live":r,"aria-atomic":!0},n)}function zn(){const[e,t]=c.useState("");return{announce:c.useCallback(r=>{r!=null&&t(r)},[]),announcement:e}}const Gt=c.createContext(null);function Bn(e){const t=c.useContext(Gt);c.useEffect(()=>{if(!t)throw new Error("useDndMonitor must be used within a children of <DndContext>");return t(e)},[e,t])}function Fn(){const[e]=c.useState(()=>new Set),t=c.useCallback(r=>(e.add(r),()=>e.delete(r)),[e]);return[c.useCallback(r=>{let{type:o,event:i}=r;e.forEach(s=>{var a;return(a=s[o])==null?void 0:a.call(s,i)})},[e]),t]}const $n={draggable:`
|
|
2
2
|
To pick up a draggable item, press the space bar.
|
|
3
3
|
While dragging, use the arrow keys to move the item.
|
|
4
4
|
Press space again to drop the item in its new position, or press escape to cancel.
|