@bpmnkit/plugins 0.0.11 → 0.0.12

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.
@@ -12,6 +12,7 @@
12
12
  * (el) => { (el as HTMLElement).style.display = active ? "none" : ""; }
13
13
  * );
14
14
  * },
15
+ * onAskAI: (query) => aiBridgePlugin.ask(query),
15
16
  * });
16
17
  *
17
18
  * const editor = new BpmnEditor({ container, xml, plugins: [palette] });
@@ -23,10 +24,160 @@ import { computeDiagramBounds } from "@bpmnkit/canvas";
23
24
  import { Bpmn } from "@bpmnkit/core";
24
25
  import { injectCommandPaletteStyles } from "./css.js";
25
26
  export { COMMAND_PALETTE_CSS, COMMAND_PALETTE_STYLE_ID, injectCommandPaletteStyles, } from "./css.js";
27
+ // ── Matching ──────────────────────────────────────────────────────────────────
28
+ /**
29
+ * Returns true when every whitespace-separated word in `query` appears
30
+ * somewhere in `text` (case-insensitive). This lets "add gateway" match
31
+ * "Add Exclusive Gateway" even though it is not a contiguous substring.
32
+ */
33
+ function wordsMatch(text, query) {
34
+ const target = text.toLowerCase();
35
+ return query
36
+ .toLowerCase()
37
+ .split(/\s+/)
38
+ .filter(Boolean)
39
+ .every((w) => target.includes(w));
40
+ }
41
+ // ── Docs registry ─────────────────────────────────────────────────────────────
42
+ const DOCS_BASE_DEFAULT = "https://docs.bpmnkit.com";
43
+ const DOC_ENTRIES = [
44
+ {
45
+ title: "Quick Start",
46
+ path: "/getting-started/quick-start/",
47
+ keywords: ["start", "install", "begin", "setup", "first", "hello", "quickstart"],
48
+ },
49
+ {
50
+ title: "Installation",
51
+ path: "/getting-started/installation/",
52
+ keywords: ["install", "npm", "pnpm", "yarn", "add", "package", "require"],
53
+ },
54
+ {
55
+ title: "Concepts",
56
+ path: "/getting-started/concepts/",
57
+ keywords: ["concept", "bpmn", "process", "element", "overview", "intro", "what"],
58
+ },
59
+ {
60
+ title: "Building Processes",
61
+ path: "/guides/building-processes/",
62
+ keywords: ["build", "create", "process", "task", "flow", "sequence", "diagram", "guide"],
63
+ },
64
+ {
65
+ title: "Gateways",
66
+ path: "/guides/gateways/",
67
+ keywords: [
68
+ "gateway",
69
+ "exclusive",
70
+ "parallel",
71
+ "inclusive",
72
+ "split",
73
+ "merge",
74
+ "xor",
75
+ "condition",
76
+ "branch",
77
+ "fork",
78
+ ],
79
+ },
80
+ {
81
+ title: "Simulation",
82
+ path: "/guides/simulation/",
83
+ keywords: ["simulate", "run", "test", "engine", "execute", "play", "simulation"],
84
+ },
85
+ {
86
+ title: "Deployment",
87
+ path: "/guides/deployment/",
88
+ keywords: ["deploy", "camunda", "cluster", "zeebe", "publish", "production", "upload"],
89
+ },
90
+ {
91
+ title: "AI Guide",
92
+ path: "/guides/ai/",
93
+ keywords: [
94
+ "ai",
95
+ "artificial",
96
+ "intelligence",
97
+ "llm",
98
+ "claude",
99
+ "copilot",
100
+ "gemini",
101
+ "assist",
102
+ "chat",
103
+ "improve",
104
+ ],
105
+ },
106
+ {
107
+ title: "@bpmnkit/core",
108
+ path: "/packages/core/",
109
+ keywords: [
110
+ "core",
111
+ "parser",
112
+ "builder",
113
+ "xml",
114
+ "export",
115
+ "import",
116
+ "layout",
117
+ "compact",
118
+ "serialize",
119
+ ],
120
+ },
121
+ {
122
+ title: "@bpmnkit/editor",
123
+ path: "/packages/editor/",
124
+ keywords: ["editor", "edit", "modeler", "interactive", "canvas", "plugin"],
125
+ },
126
+ {
127
+ title: "@bpmnkit/engine",
128
+ path: "/packages/engine/",
129
+ keywords: ["engine", "execute", "run", "simulate", "worker", "job", "token", "fire"],
130
+ },
131
+ {
132
+ title: "@bpmnkit/api",
133
+ path: "/packages/api/",
134
+ keywords: ["api", "client", "camunda", "rest", "http", "zeebe", "operate", "instance"],
135
+ },
136
+ {
137
+ title: "@bpmnkit/canvas",
138
+ path: "/packages/canvas/",
139
+ keywords: ["canvas", "viewer", "svg", "render", "view", "display", "embed"],
140
+ },
141
+ {
142
+ title: "Connector Generator",
143
+ path: "/packages/connector-gen/",
144
+ keywords: ["connector", "openapi", "swagger", "template", "generate", "rest", "http", "api"],
145
+ },
146
+ {
147
+ title: "casen CLI",
148
+ path: "/cli/casen/",
149
+ keywords: [
150
+ "cli",
151
+ "command",
152
+ "terminal",
153
+ "casen",
154
+ "tui",
155
+ "profile",
156
+ "job",
157
+ "incident",
158
+ "process",
159
+ "mcp",
160
+ ],
161
+ },
162
+ {
163
+ title: "casen connector",
164
+ path: "/cli/connector/",
165
+ keywords: ["connector", "cli", "generate", "api", "catalog", "swagger", "openapi"],
166
+ },
167
+ ];
168
+ // Shown when the query is empty
169
+ const FEATURED_DOC_PATHS = new Set([
170
+ "/getting-started/quick-start/",
171
+ "/guides/building-processes/",
172
+ "/guides/ai/",
173
+ "/cli/casen/",
174
+ ]);
26
175
  // ── Module-level singleton — only one palette open at a time ──────────────────
27
176
  let _closeCurrent = null;
28
177
  // ── Icons ─────────────────────────────────────────────────────────────────────
29
178
  const SEARCH_ICON = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="6.5" cy="6.5" r="4"/><line x1="10" y1="10" x2="14" y2="14"/></svg>';
179
+ const EXTERNAL_ICON = '<svg viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 2H2a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V7.5"/><polyline points="7.5 1 11 1 11 4.5"/><line x1="11" y1="1" x2="5.5" y2="6.5"/></svg>';
180
+ const AI_ICON = '<svg viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a.5.5 0 0 1 .46.31l1.46 3.46 3.46 1.46a.5.5 0 0 1 0 .94l-3.46 1.46L8.46 11.1a.5.5 0 0 1-.92 0L6.08 7.63 2.62 6.17a.5.5 0 0 1 0-.94l3.46-1.46L7.54.31A.5.5 0 0 1 8 0zm0 2.08L6.96 4.54a.5.5 0 0 1-.28.28L4.22 5.7l2.46 1.04a.5.5 0 0 1 .28.28L8 9.48l1.04-2.46a.5.5 0 0 1 .28-.28L11.78 5.7 9.32 4.82a.5.5 0 0 1-.28-.28L8 2.08zm5 8.42a.5.5 0 0 1 .46.31l.6 1.43 1.43.6a.5.5 0 0 1 0 .92l-1.43.6-.6 1.43a.5.5 0 0 1-.92 0l-.6-1.43-1.43-.6a.5.5 0 0 1 0-.92l1.43-.6.6-1.43A.5.5 0 0 1 13 10.5zm0 1.79-.27.63a.5.5 0 0 1-.28.28l-.63.27.63.27a.5.5 0 0 1 .28.28l.27.63.27-.63a.5.5 0 0 1 .28-.28l.63-.27-.63-.27a.5.5 0 0 1-.28-.28L13 12.29z"/></svg>';
30
181
  // ── Theme helper ──────────────────────────────────────────────────────────────
31
182
  function resolveTheme(theme) {
32
183
  if (theme === "dark")
@@ -45,6 +196,13 @@ export function createCommandPalettePlugin(options = {}) {
45
196
  let _isZenMode = false;
46
197
  let _focusedIndex = 0;
47
198
  let _lastDefs = null;
199
+ let _focusableItems = [];
200
+ // null = unknown/checking, true = running, false = not running
201
+ let _proxyReady = null;
202
+ // incremented on each palette open to discard stale fetch results
203
+ let _proxyCheckId = 0;
204
+ // navigation stack — each pushView() adds one level, Escape pops
205
+ const _viewStack = [];
48
206
  const _extraCommands = [];
49
207
  const _unsubs = [];
50
208
  // ── Built-in commands (lazy — need _api set) ─────────────────────────────
@@ -147,6 +305,115 @@ export function createCommandPalettePlugin(options = {}) {
147
305
  }
148
306
  options.onZenModeChange?.(_isZenMode);
149
307
  }
308
+ // ── Proxy check ───────────────────────────────────────────────────────────
309
+ function startProxyCheck() {
310
+ if (!options.onAskAI)
311
+ return;
312
+ _proxyReady = null;
313
+ const checkId = ++_proxyCheckId;
314
+ const serverUrl = options.aiServerUrl ?? "http://localhost:3033";
315
+ fetch(`${serverUrl}/status`, { signal: AbortSignal.timeout(3000) })
316
+ .then((res) => res.json())
317
+ .then((data) => {
318
+ if (checkId !== _proxyCheckId)
319
+ return;
320
+ _proxyReady = Boolean(data?.ready);
321
+ if (_isOpen && _inputEl)
322
+ renderList(_inputEl.value);
323
+ })
324
+ .catch(() => {
325
+ if (checkId !== _proxyCheckId)
326
+ return;
327
+ _proxyReady = false;
328
+ if (_isOpen && _inputEl)
329
+ renderList(_inputEl.value);
330
+ });
331
+ }
332
+ // ── Section builders ──────────────────────────────────────────────────────
333
+ function buildCommandItems(query) {
334
+ const all = [...builtinCommands(), ..._extraCommands];
335
+ const cmds = query
336
+ ? all.filter((c) => wordsMatch(c.title, query) ||
337
+ (c.description != null && wordsMatch(c.description, query)))
338
+ : all;
339
+ return cmds.map((c) => ({
340
+ kind: "command",
341
+ title: c.title,
342
+ description: c.description,
343
+ action: c.action,
344
+ }));
345
+ }
346
+ function buildDocItems(query) {
347
+ const baseUrl = options.docsBaseUrl ?? DOCS_BASE_DEFAULT;
348
+ const entries = query.trim()
349
+ ? DOC_ENTRIES.filter((e) => {
350
+ const q = query.toLowerCase();
351
+ return e.title.toLowerCase().includes(q) || e.keywords.some((k) => k.includes(q));
352
+ }).slice(0, 4)
353
+ : DOC_ENTRIES.filter((e) => FEATURED_DOC_PATHS.has(e.path));
354
+ return entries.map((e) => ({
355
+ kind: "doc",
356
+ title: e.title,
357
+ description: "docs ↗",
358
+ action() {
359
+ window.open(baseUrl + e.path, "_blank", "noopener");
360
+ closePalette();
361
+ },
362
+ }));
363
+ }
364
+ function buildAiItem(query) {
365
+ const ready = _proxyReady;
366
+ const description = ready === null
367
+ ? "Checking server…"
368
+ : ready
369
+ ? "Send to AI assistant ↵"
370
+ : "npx @bpmnkit/proxy — then reopen";
371
+ return {
372
+ kind: "ai",
373
+ title: `Ask AI: "${query.trim()}"`,
374
+ description,
375
+ disabled: ready !== true,
376
+ action() {
377
+ if (ready !== true)
378
+ return;
379
+ options.onAskAI?.(query.trim());
380
+ closePalette();
381
+ },
382
+ };
383
+ }
384
+ function buildSections(query) {
385
+ // Pushed view: show only the pushed commands, no docs/AI
386
+ const activeView = _viewStack[_viewStack.length - 1];
387
+ if (activeView) {
388
+ const items = activeView.cmds
389
+ .filter((c) => !query ||
390
+ wordsMatch(c.title, query) ||
391
+ (c.description != null && wordsMatch(c.description, query)))
392
+ .map((c) => ({
393
+ kind: "command",
394
+ title: c.title,
395
+ description: c.description,
396
+ action: c.action,
397
+ }));
398
+ return items.length > 0 ? [{ items }] : [];
399
+ }
400
+ const sections = [];
401
+ const cmdItems = buildCommandItems(query);
402
+ if (cmdItems.length > 0)
403
+ sections.push({ items: cmdItems });
404
+ const docItems = buildDocItems(query);
405
+ if (docItems.length > 0)
406
+ sections.push({ label: "Documentation", items: docItems });
407
+ if (options.onAskAI && query.trim().length > 0) {
408
+ sections.push({ label: "AI", items: [buildAiItem(query)] });
409
+ }
410
+ // Show "Commands" label only when there are other sections too
411
+ const first = sections[0];
412
+ if (sections.length > 1 && first && !first.label && first.items.length > 0) {
413
+ first.label = "Commands";
414
+ }
415
+ return sections;
416
+ }
150
417
  // ── Palette open / close ──────────────────────────────────────────────────
151
418
  function openPalette() {
152
419
  if (!_api)
@@ -155,6 +422,7 @@ export function createCommandPalettePlugin(options = {}) {
155
422
  _closeCurrent = closePalette;
156
423
  _isOpen = true;
157
424
  _focusedIndex = 0;
425
+ startProxyCheck();
158
426
  const isDark = resolveTheme(_api.getTheme()) === "dark";
159
427
  const overlay = document.createElement("div");
160
428
  overlay.className = isDark
@@ -175,7 +443,7 @@ export function createCommandPalettePlugin(options = {}) {
175
443
  const input = document.createElement("input");
176
444
  input.type = "text";
177
445
  input.className = "bpmnkit-palette-input";
178
- input.placeholder = "Search commands\u2026";
446
+ input.placeholder = "Search commands or docs\u2026";
179
447
  input.setAttribute("autocomplete", "off");
180
448
  input.setAttribute("spellcheck", "false");
181
449
  searchRow.appendChild(input);
@@ -212,75 +480,113 @@ export function createCommandPalettePlugin(options = {}) {
212
480
  if (!_isOpen)
213
481
  return;
214
482
  _isOpen = false;
483
+ _proxyCheckId++; // invalidate any pending fetch
484
+ _proxyReady = null;
485
+ _viewStack.length = 0;
215
486
  if (_closeCurrent === closePalette)
216
487
  _closeCurrent = null;
217
488
  _overlayEl?.remove();
218
489
  _overlayEl = null;
219
490
  _inputEl = null;
220
491
  _listEl = null;
492
+ _focusableItems = [];
221
493
  }
222
- // ── List rendering ────────────────────────────────────────────────────────
223
- function filteredCommands(query) {
224
- const all = [...builtinCommands(), ..._extraCommands];
225
- if (!query)
226
- return all;
227
- const q = query.toLowerCase();
228
- return all.filter((c) => c.title.toLowerCase().includes(q) || c.description?.toLowerCase().includes(q));
494
+ function popView() {
495
+ _viewStack.pop();
496
+ const prev = _viewStack[_viewStack.length - 1];
497
+ if (_inputEl) {
498
+ _inputEl.value = "";
499
+ _inputEl.placeholder = prev?.placeholder ?? "Search commands or docs\u2026";
500
+ }
501
+ _focusedIndex = 0;
502
+ renderList("");
229
503
  }
504
+ // ── List rendering ────────────────────────────────────────────────────────
230
505
  function renderList(query) {
231
506
  if (!_listEl)
232
507
  return;
233
508
  _listEl.innerHTML = "";
234
- const cmds = filteredCommands(query);
235
- if (cmds.length === 0) {
509
+ _focusableItems = [];
510
+ const sections = buildSections(query);
511
+ const totalItems = sections.reduce((n, s) => n + s.items.length, 0);
512
+ if (totalItems === 0) {
236
513
  const empty = document.createElement("div");
237
514
  empty.className = "bpmnkit-palette-empty";
238
- empty.textContent = "No commands found";
515
+ const activeView = _viewStack[_viewStack.length - 1];
516
+ empty.textContent = activeView?.onConfirm
517
+ ? "Press \u21b5 to confirm, Esc to go back"
518
+ : "No commands found";
239
519
  _listEl.appendChild(empty);
240
520
  return;
241
521
  }
242
- if (_focusedIndex >= cmds.length)
522
+ if (_focusedIndex >= totalItems)
243
523
  _focusedIndex = 0;
244
- cmds.forEach((cmd, i) => {
245
- if (!_listEl)
246
- return;
247
- const item = document.createElement("div");
248
- item.className =
249
- i === _focusedIndex
250
- ? "bpmnkit-palette-item bpmnkit-palette-focused"
251
- : "bpmnkit-palette-item";
252
- item.setAttribute("role", "option");
253
- item.setAttribute("aria-selected", String(i === _focusedIndex));
254
- const titleEl = document.createElement("span");
255
- titleEl.className = "bpmnkit-palette-item-title";
256
- titleEl.textContent = cmd.title;
257
- item.appendChild(titleEl);
258
- if (cmd.description) {
259
- const descEl = document.createElement("span");
260
- descEl.className = "bpmnkit-palette-item-desc";
261
- descEl.textContent = cmd.description;
262
- item.appendChild(descEl);
524
+ for (const section of sections) {
525
+ if (section.label) {
526
+ const labelEl = document.createElement("div");
527
+ labelEl.className = "bpmnkit-palette-section";
528
+ labelEl.textContent = section.label;
529
+ _listEl.appendChild(labelEl);
263
530
  }
264
- item.addEventListener("pointerenter", () => {
265
- _focusedIndex = i;
266
- updateFocus();
267
- });
268
- item.addEventListener("pointerdown", (e) => {
269
- e.preventDefault();
270
- cmd.action();
271
- });
272
- _listEl.appendChild(item);
273
- });
531
+ for (const item of section.items) {
532
+ const focusableIdx = _focusableItems.length;
533
+ _focusableItems.push(item);
534
+ const el = document.createElement("div");
535
+ el.className = buildItemClass(item, focusableIdx);
536
+ el.setAttribute("role", "option");
537
+ el.setAttribute("aria-selected", String(focusableIdx === _focusedIndex));
538
+ el.setAttribute("aria-disabled", String(item.disabled ?? false));
539
+ // Leading icon
540
+ if (item.kind === "doc" || item.kind === "ai") {
541
+ const iconSpan = document.createElement("span");
542
+ iconSpan.className = "bpmnkit-palette-item-icon";
543
+ iconSpan.innerHTML = item.kind === "doc" ? EXTERNAL_ICON : AI_ICON;
544
+ el.appendChild(iconSpan);
545
+ }
546
+ const titleEl = document.createElement("span");
547
+ titleEl.className = "bpmnkit-palette-item-title";
548
+ titleEl.textContent = item.title;
549
+ el.appendChild(titleEl);
550
+ if (item.description) {
551
+ const descEl = document.createElement("span");
552
+ descEl.className = "bpmnkit-palette-item-desc";
553
+ descEl.textContent = item.description;
554
+ el.appendChild(descEl);
555
+ }
556
+ el.addEventListener("pointerenter", () => {
557
+ _focusedIndex = focusableIdx;
558
+ updateFocus();
559
+ });
560
+ el.addEventListener("pointerdown", (e) => {
561
+ e.preventDefault();
562
+ if (!item.disabled)
563
+ item.action();
564
+ });
565
+ _listEl.appendChild(el);
566
+ }
567
+ }
568
+ }
569
+ function buildItemClass(item, idx) {
570
+ const classes = ["bpmnkit-palette-item"];
571
+ if (item.kind !== "command")
572
+ classes.push(`bpmnkit-palette-item--${item.kind}`);
573
+ if (item.disabled)
574
+ classes.push("bpmnkit-palette-item--disabled");
575
+ if (idx === _focusedIndex)
576
+ classes.push("bpmnkit-palette-focused");
577
+ return classes.join(" ");
274
578
  }
275
579
  function updateFocus() {
276
580
  if (!_listEl)
277
581
  return;
278
582
  const items = _listEl.querySelectorAll(".bpmnkit-palette-item");
279
- items.forEach((item, i) => {
280
- const focused = i === _focusedIndex;
281
- item.classList.toggle("bpmnkit-palette-focused", focused);
282
- item.setAttribute("aria-selected", String(focused));
283
- });
583
+ let focusableIdx = 0;
584
+ for (const el of items) {
585
+ const focused = focusableIdx === _focusedIndex;
586
+ el.classList.toggle("bpmnkit-palette-focused", focused);
587
+ el.setAttribute("aria-selected", String(focused));
588
+ focusableIdx++;
589
+ }
284
590
  }
285
591
  function scrollFocusedIntoView() {
286
592
  if (!_listEl)
@@ -293,8 +599,7 @@ export function createCommandPalettePlugin(options = {}) {
293
599
  function onPaletteKeyDown(e) {
294
600
  if (!_listEl || !_inputEl)
295
601
  return;
296
- const cmds = filteredCommands(_inputEl.value);
297
- const count = cmds.length;
602
+ const count = _focusableItems.length;
298
603
  if (e.key === "ArrowDown") {
299
604
  e.preventDefault();
300
605
  if (count > 0) {
@@ -313,13 +618,22 @@ export function createCommandPalettePlugin(options = {}) {
313
618
  }
314
619
  else if (e.key === "Enter") {
315
620
  e.preventDefault();
316
- const cmd = cmds[_focusedIndex];
317
- if (cmd)
318
- cmd.action();
621
+ const activeView = _viewStack[_viewStack.length - 1];
622
+ if (activeView?.onConfirm) {
623
+ activeView.onConfirm(_inputEl.value);
624
+ closePalette();
625
+ return;
626
+ }
627
+ const item = _focusableItems[_focusedIndex];
628
+ if (item && !item.disabled)
629
+ item.action();
319
630
  }
320
631
  else if (e.key === "Escape") {
321
632
  e.preventDefault();
322
- closePalette();
633
+ if (_viewStack.length > 0)
634
+ popView();
635
+ else
636
+ closePalette();
323
637
  }
324
638
  }
325
639
  const onDocKeyDown = (e) => {
@@ -373,6 +687,22 @@ export function createCommandPalettePlugin(options = {}) {
373
687
  }
374
688
  };
375
689
  },
690
+ pushView(cmds, opts = {}) {
691
+ if (!_isOpen)
692
+ return;
693
+ const view = {
694
+ cmds,
695
+ placeholder: opts.placeholder ?? "Select\u2026",
696
+ onConfirm: opts.onConfirm,
697
+ };
698
+ _viewStack.push(view);
699
+ if (_inputEl) {
700
+ _inputEl.value = "";
701
+ _inputEl.placeholder = view.placeholder;
702
+ }
703
+ _focusedIndex = 0;
704
+ renderList("");
705
+ },
376
706
  };
377
707
  }
378
708
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * @bpmnkit/canvas-plugin-command-palette-editor — editor extension for the
3
- * command palette plugin. Adds one command per BPMN element type.
3
+ * command palette plugin. Adds one command per BPMN element type. When
4
+ * executed, shows a second-step picker listing candidate source nodes to
5
+ * connect after. Falls back to `setTool` (free-click placement) when the
6
+ * diagram is empty.
4
7
  *
5
8
  * Must be used together with `@bpmnkit/canvas-plugin-command-palette`.
6
9
  *
@@ -11,9 +14,7 @@
11
14
  *
12
15
  * let editorRef: BpmnEditor | null = null;
13
16
  * const palette = createCommandPalettePlugin({ ... });
14
- * const paletteEditor = createCommandPaletteEditorPlugin(palette, (tool) => {
15
- * editorRef?.setTool(tool);
16
- * });
17
+ * const paletteEditor = createCommandPaletteEditorPlugin(palette, () => editorRef);
17
18
  * const editor = new BpmnEditor({ container, xml, plugins: [palette, paletteEditor] });
18
19
  * editorRef = editor;
19
20
  * ```
@@ -21,15 +22,19 @@
21
22
  * @packageDocumentation
22
23
  */
23
24
  import type { CanvasPlugin } from "@bpmnkit/canvas";
25
+ import type { CreateShapeType } from "@bpmnkit/editor";
24
26
  import type { CommandPalettePlugin } from "../command-palette/index.js";
27
+ /** Subset of BpmnEditor needed by this plugin. */
28
+ export interface EditorLike {
29
+ setTool(tool: string): void;
30
+ addConnectedElement(sourceId: string, type: CreateShapeType, name?: string): string | null;
31
+ }
25
32
  /**
26
33
  * Creates the editor command palette extension plugin.
27
34
  *
28
- * @param palette - The base command palette plugin returned by
29
- * `createCommandPalettePlugin`. Commands are registered into it.
30
- * @param setTool - Callback that activates an element creation tool on the
31
- * editor (e.g. `editor.setTool`). May reference the editor lazily — it is
32
- * only called when the user executes a command, well after construction.
35
+ * @param palette The base command palette plugin.
36
+ * @param getEditor Lazy getter returning the editor instance (or null before
37
+ * it is created). Called only when the user executes a command.
33
38
  */
34
- export declare function createCommandPaletteEditorPlugin(palette: CommandPalettePlugin, setTool: (tool: string) => void): CanvasPlugin;
39
+ export declare function createCommandPaletteEditorPlugin(palette: CommandPalettePlugin, getEditor: () => EditorLike | null): CanvasPlugin;
35
40
  //# sourceMappingURL=index.d.ts.map