@makinbakin/sdk 0.0.1-rc.20 → 0.0.1-rc.21

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 (110) hide show
  1. package/_internal/app/components/agent-select.d.ts +10 -1
  2. package/_internal/app/components/asset-picker.d.ts +25 -0
  3. package/_internal/app/components/charts/bar-chart.d.ts +16 -0
  4. package/_internal/app/components/charts/chart-data-table.d.ts +31 -0
  5. package/_internal/app/components/charts/chart-explainer.d.ts +9 -0
  6. package/_internal/app/components/charts/chart-tooltip.d.ts +8 -0
  7. package/_internal/app/components/charts/line-chart.d.ts +13 -0
  8. package/_internal/app/components/charts/palette.d.ts +24 -0
  9. package/_internal/app/components/charts/sparkline.d.ts +12 -0
  10. package/_internal/app/components/charts/stacked-column-chart.d.ts +40 -0
  11. package/_internal/app/components/confirm-dialog.d.ts +23 -2
  12. package/_internal/app/components/conversation/activity-group.d.ts +15 -0
  13. package/_internal/app/components/conversation/agent-turn.d.ts +36 -0
  14. package/_internal/app/components/conversation/attention.d.ts +56 -0
  15. package/_internal/app/components/conversation/composer.d.ts +35 -0
  16. package/_internal/app/components/conversation/conversation-empty-state.d.ts +8 -0
  17. package/_internal/app/components/conversation/conversation-panel.d.ts +33 -0
  18. package/_internal/app/components/conversation/conversation.d.ts +14 -0
  19. package/_internal/app/components/conversation/fold.d.ts +129 -0
  20. package/_internal/app/components/conversation/notification-sound.d.ts +8 -0
  21. package/_internal/app/components/conversation/relative-time.d.ts +8 -0
  22. package/_internal/app/components/conversation/reply-toast.d.ts +15 -0
  23. package/_internal/app/components/conversation/thread-id.d.ts +8 -0
  24. package/_internal/app/components/conversation/tool-call-drawer.d.ts +7 -0
  25. package/_internal/app/components/conversation/turn-recorder.d.ts +37 -0
  26. package/_internal/app/components/conversation/use-conversation-attention.d.ts +64 -0
  27. package/_internal/app/components/conversation/use-conversation-thread.d.ts +55 -0
  28. package/_internal/app/components/conversation/user-message.d.ts +11 -0
  29. package/_internal/app/components/danger-zone.d.ts +28 -0
  30. package/_internal/app/components/empty-state.d.ts +5 -2
  31. package/_internal/app/components/plugin-header.d.ts +4 -3
  32. package/_internal/app/components/save-bar.d.ts +32 -0
  33. package/_internal/app/components/score-overlay.d.ts +33 -0
  34. package/_internal/app/components/search-degraded-chip.d.ts +4 -0
  35. package/_internal/app/components/search-partial-chip.d.ts +13 -0
  36. package/_internal/app/components/search-unavailable.d.ts +12 -0
  37. package/_internal/app/components/section-card.d.ts +22 -0
  38. package/_internal/app/components/segmented-control.d.ts +28 -0
  39. package/_internal/app/components/stat-tile.d.ts +26 -0
  40. package/_internal/app/components/status-badge.d.ts +19 -0
  41. package/_internal/app/components/turn-output-view.d.ts +57 -0
  42. package/_internal/app/components/ui/button.d.ts +1 -1
  43. package/_internal/app/components/underline-tabs.d.ts +6 -2
  44. package/_internal/app/components/unsaved-changes-guard.d.ts +34 -0
  45. package/_internal/app/core/conversation-turns.d.ts +148 -0
  46. package/_internal/app/core/logger.d.ts +1 -0
  47. package/_internal/app/hooks/use-file-drop.d.ts +25 -0
  48. package/_internal/app/hooks/use-history-back.d.ts +1 -0
  49. package/_internal/app/hooks/use-json-fetch.d.ts +5 -0
  50. package/_internal/app/hooks/use-query-state.d.ts +2 -0
  51. package/_internal/app/hooks/use-schedule.d.ts +45 -0
  52. package/_internal/app/hooks/use-search.d.ts +27 -8
  53. package/_internal/app/hooks/use-toast.d.ts +3 -3
  54. package/_internal/app/lib/browser-notify.d.ts +12 -1
  55. package/_internal/core/adapters/runtime/concepts.d.ts +547 -49
  56. package/_internal/core/adapters/runtime/errors.d.ts +13 -1
  57. package/_internal/core/adapters/runtime/helpers.d.ts +19 -0
  58. package/_internal/core/adapters/runtime/index.d.ts +5 -2
  59. package/_internal/core/adapters/runtime/testing.d.ts +79 -0
  60. package/_internal/core/adapters/runtime/turn-activity.d.ts +23 -0
  61. package/_internal/core/adapters/shared.d.ts +122 -12
  62. package/_internal/core/content-dir.d.ts +8 -0
  63. package/_internal/core/docs/route.d.ts +1 -1
  64. package/_internal/core/format/structured.d.ts +44 -0
  65. package/_internal/core/format.d.ts +5 -1
  66. package/_internal/core/media/downscale.d.ts +18 -0
  67. package/_internal/core/media/sharp-loader.d.ts +36 -0
  68. package/_internal/core/plugin-types.d.ts +102 -39
  69. package/_internal/core/routing/define.d.ts +26 -3
  70. package/_internal/core/routing/dispatcher.d.ts +15 -6
  71. package/_internal/core/routing/index.d.ts +1 -1
  72. package/_internal/core/routing/types.d.ts +13 -70
  73. package/_internal/core/storage/atomic-write.d.ts +11 -0
  74. package/_internal/core/tasks/store.d.ts +129 -0
  75. package/_internal/core/tasks/testing.d.ts +2 -0
  76. package/_internal/{plugins/workflows/lib → core/workflows}/notification-channel-registry.d.ts +1 -1
  77. package/_internal/plugins/team/types.d.ts +47 -0
  78. package/_internal/plugins/workflows/hooks/use-notification-channels.d.ts +1 -1
  79. package/components/index.d.ts +87 -19
  80. package/components/index.js +32904 -15368
  81. package/hooks/index.d.ts +24 -4
  82. package/hooks/index.js +837 -561
  83. package/hooks/router.d.ts +20 -4
  84. package/index.d.ts +5 -50
  85. package/index.js +223 -406
  86. package/internal/index.d.ts +70 -0
  87. package/internal/index.js +409 -0
  88. package/package.json +9 -2
  89. package/register.d.ts +19 -1
  90. package/routing/index.js +175 -147
  91. package/slots/index.js +20 -1
  92. package/testing/index.d.ts +122 -0
  93. package/testing/index.js +21874 -0
  94. package/types/index.d.ts +4 -0
  95. package/types/index.js +16 -0
  96. package/utils/index.d.ts +28 -25
  97. package/utils/index.js +279 -263
  98. package/_internal/app/components/integrated-brainstorm/activity.d.ts +0 -23
  99. package/_internal/app/components/integrated-brainstorm/collapsed-header.d.ts +0 -14
  100. package/_internal/app/components/integrated-brainstorm/empty-state.d.ts +0 -5
  101. package/_internal/app/components/integrated-brainstorm/index.d.ts +0 -8
  102. package/_internal/app/components/integrated-brainstorm/input-row.d.ts +0 -16
  103. package/_internal/app/components/integrated-brainstorm/message-list.d.ts +0 -8
  104. package/_internal/app/components/integrated-brainstorm/session.d.ts +0 -16
  105. package/_internal/app/components/integrated-brainstorm/sse.d.ts +0 -8
  106. package/_internal/app/components/integrated-brainstorm/thinking-indicator.d.ts +0 -19
  107. package/_internal/app/components/integrated-brainstorm/types.d.ts +0 -63
  108. package/_internal/app/components/integrated-brainstorm/use-auto-grow.d.ts +0 -6
  109. package/_internal/app/components/integrated-brainstorm/use-brainstorm-state.d.ts +0 -21
  110. /package/_internal/{plugins/models → app}/hooks/use-available-models.d.ts +0 -0
package/hooks/index.js CHANGED
@@ -58,7 +58,7 @@ var require_use_sync_external_store_shim_development = __commonJS((exports) => {
58
58
  var cachedValue = getSnapshot();
59
59
  objectIs(value, cachedValue) || (console.error("The result of getSnapshot should be cached to avoid an infinite loop"), didWarnUncachedGetSnapshot = true);
60
60
  }
61
- cachedValue = useState11({
61
+ cachedValue = useState9({
62
62
  inst: { value, getSnapshot }
63
63
  });
64
64
  var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
@@ -67,7 +67,7 @@ var require_use_sync_external_store_shim_development = __commonJS((exports) => {
67
67
  inst.getSnapshot = getSnapshot;
68
68
  checkIfSnapshotChanged(inst) && forceUpdate({ inst });
69
69
  }, [subscribe, value, getSnapshot]);
70
- useEffect15(function() {
70
+ useEffect12(function() {
71
71
  checkIfSnapshotChanged(inst) && forceUpdate({ inst });
72
72
  return subscribe(function() {
73
73
  checkIfSnapshotChanged(inst) && forceUpdate({ inst });
@@ -90,7 +90,7 @@ var require_use_sync_external_store_shim_development = __commonJS((exports) => {
90
90
  return getSnapshot();
91
91
  }
92
92
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
93
- var objectIs = typeof Object.is === "function" ? Object.is : is, useState11 = React2.useState, useEffect15 = React2.useEffect, useLayoutEffect2 = React2.useLayoutEffect, useDebugValue2 = React2.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = typeof window === "undefined" || typeof window.document === "undefined" || typeof window.document.createElement === "undefined" ? useSyncExternalStore$1 : useSyncExternalStore$2;
93
+ var objectIs = typeof Object.is === "function" ? Object.is : is, useState9 = React2.useState, useEffect12 = React2.useEffect, useLayoutEffect2 = React2.useLayoutEffect, useDebugValue2 = React2.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = typeof window === "undefined" || typeof window.document === "undefined" || typeof window.document.createElement === "undefined" ? useSyncExternalStore$1 : useSyncExternalStore$2;
94
94
  exports.useSyncExternalStore = React2.useSyncExternalStore !== undefined ? React2.useSyncExternalStore : shim;
95
95
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
96
96
  })();
@@ -111,9 +111,9 @@ var require_with_selector_development = __commonJS((exports) => {
111
111
  return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
112
112
  }
113
113
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function" && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
114
- var shim = require_shim(), objectIs = typeof Object.is === "function" ? Object.is : is, useSyncExternalStore = shim.useSyncExternalStore, useRef9 = React3.useRef, useEffect15 = React3.useEffect, useMemo3 = React3.useMemo, useDebugValue2 = React3.useDebugValue;
114
+ var shim = require_shim(), objectIs = typeof Object.is === "function" ? Object.is : is, useSyncExternalStore = shim.useSyncExternalStore, useRef8 = React3.useRef, useEffect12 = React3.useEffect, useMemo3 = React3.useMemo, useDebugValue2 = React3.useDebugValue;
115
115
  exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
116
- var instRef = useRef9(null);
116
+ var instRef = useRef8(null);
117
117
  if (instRef.current === null) {
118
118
  var inst = { hasValue: false, value: null };
119
119
  instRef.current = inst;
@@ -152,7 +152,7 @@ var require_with_selector_development = __commonJS((exports) => {
152
152
  ];
153
153
  }, [getSnapshot, getServerSnapshot, selector, isEqual]);
154
154
  var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
155
- useEffect15(function() {
155
+ useEffect12(function() {
156
156
  inst.hasValue = true;
157
157
  inst.value = value;
158
158
  }, [value]);
@@ -238,12 +238,43 @@ function mapAuditMessage(event, data) {
238
238
  }
239
239
  case "task.updated":
240
240
  return `Updated: ${data.title}`;
241
+ case "task.routed": {
242
+ const parts = [data.model, data.thinking ? `thinking ${data.thinking}` : null].filter(Boolean);
243
+ const via = typeof data.source === "string" && data.source !== "inherit" ? ` via ${data.source === "class" ? "class route" : String(data.source).replace(/^tag:/, 'tag "') + '"'}` : "";
244
+ return `Routed to ${parts.join(", ") || "override"}${via}`;
245
+ }
241
246
  case "task.completion_suppressed":
242
247
  return `Ignored a duplicate completion${data.title ? ` of "${data.title}"` : ""} \u2014 ${data.firstAgent || "another run"} had already completed this task${data.firstChannel ? ` via ${data.firstChannel}` : ""}.`;
243
248
  case "task.dispatch_failure_ignored":
244
249
  return `A session error arrived after "${data.title || data.id}" had already moved to ${data.column || "done"} \u2014 no action needed.`;
245
250
  case "team.message_blocked":
246
251
  return `Blocked a message to ${data.agentId} \u2014 they are already running task ${data.taskId}.`;
252
+ case "brand.injected":
253
+ return `Brand '${data.brandId}' injected into dispatch${data.cardBytes ? ` (${data.cardBytes} B card)` : ""}`;
254
+ case "brand.dispatch_blocked":
255
+ return typeof data.message === "string" ? data.message : `Task waiting on missing brand '${data.brandId}'`;
256
+ case "brand.asset_missing":
257
+ return `Brand '${data.brandId}' has missing asset references`;
258
+ case "brand.created":
259
+ return `Created brand '${data.brandId}'`;
260
+ case "brand.updated":
261
+ return `Updated brand '${data.brandId}'`;
262
+ case "brand.deleted":
263
+ return `Deleted brand '${data.brandId}'`;
264
+ case "task.worktree_materialized":
265
+ return `Working in an isolated worktree of ${typeof data.repoPath === "string" ? data.repoPath.split("/").pop() : "the bound repo"} on branch ${data.branch} \u2014 the branch survives after the task settles`;
266
+ case "task.turn_aborted":
267
+ return data.reason === "superseded" ? `Stopped a stale attempt on "${data.title || data.id}" \u2014 a fresh attempt takes over` : `Stopped the in-flight attempt on "${data.title || data.id}"${data.reason ? ` (${data.reason})` : ""}`;
268
+ case "task.turn_force_released":
269
+ return `Released a hung attempt on task ${data.id} \u2014 its dispatch slot is free again`;
270
+ case "task.run_superseded":
271
+ return `Superseded a stalled attempt on "${data.title || data.id}" \u2014 it will be re-dispatched`;
272
+ case "task.repo_binding_blocked":
273
+ return typeof data.error === "string" ? `Task blocked: ${data.error}` : `Task blocked: repo binding failed`;
274
+ case "dispatch.concurrency_clamped":
275
+ return `Per-agent parallelism clamped to 1: the active runtime cannot isolate same-agent turns (requested ${data.requested})`;
276
+ case "asset.stale_run_write_suppressed":
277
+ return `Recorded a late save from a superseded run as version ${data.version} of ${data.assetId} WITHOUT promoting it \u2014 the current deliverable is unchanged`;
247
278
  case "system.init":
248
279
  return "Bakin started";
249
280
  case "system.dispatch_error":
@@ -261,6 +292,8 @@ function mapAuditMessage(event, data) {
261
292
  case "workflow.complete":
262
293
  return `Workflow complete${data.workflowId ? ` (${data.workflowId})` : ""}`;
263
294
  default: {
295
+ if (typeof data.message === "string" && data.message.trim())
296
+ return data.message;
264
297
  if (event.startsWith("exec.")) {
265
298
  const suffix = event.endsWith(".fail") ? " (failed)" : event.endsWith(".error") ? " (error)" : "";
266
299
  if (data.label)
@@ -285,6 +318,8 @@ function isNoisyEvent(evt) {
285
318
  return true;
286
319
  if (evt.eventName && isReadOnlyExecOk(evt.eventName))
287
320
  return true;
321
+ if (evt.eventName === "dispatch.registry_clobber")
322
+ return true;
288
323
  return false;
289
324
  }
290
325
  function isReadOnlyExecOk(eventName) {
@@ -392,7 +427,10 @@ function getRegistry() {
392
427
  listeners: new Set,
393
428
  badgesByPlugin: new Map,
394
429
  badgesSnapshot: new Map,
395
- badgeListeners: new Set
430
+ badgeListeners: new Set,
431
+ hitRenderersByPlugin: new Map,
432
+ hitRenderersSnapshot: new Map,
433
+ hitRendererListeners: new Set
396
434
  };
397
435
  }
398
436
  const registry = g.__bakinClientRegistry;
@@ -407,8 +445,24 @@ function getRegistry() {
407
445
  registry.badgesSnapshot = buildBadgesSnapshot(registry);
408
446
  if (!registry.badgeListeners)
409
447
  registry.badgeListeners = new Set;
448
+ if (!registry.hitRenderersByPlugin)
449
+ registry.hitRenderersByPlugin = new Map;
450
+ if (!registry.hitRenderersSnapshot)
451
+ registry.hitRenderersSnapshot = buildHitRenderersSnapshot(registry);
452
+ if (!registry.hitRendererListeners)
453
+ registry.hitRendererListeners = new Set;
410
454
  return registry;
411
455
  }
456
+ function buildHitRenderersSnapshot(registry) {
457
+ const snapshot = new Map;
458
+ for (const byType of registry.hitRenderersByPlugin.values()) {
459
+ for (const [type, renderer] of byType) {
460
+ if (!snapshot.has(type))
461
+ snapshot.set(type, renderer);
462
+ }
463
+ }
464
+ return snapshot;
465
+ }
412
466
  function buildBadgesSnapshot(registry) {
413
467
  const snapshot = new Map;
414
468
  for (const byNavItemId of registry.badgesByPlugin.values()) {
@@ -452,143 +506,6 @@ function setNavBadge(pluginId, navItemId, badge) {
452
506
  plugin.set(navItemId, { count: badge.count, tone: badge.tone });
453
507
  bumpBadges();
454
508
  }
455
- // packages/sdk/src/lazy.ts
456
- "use client";
457
- // packages/core/src/routing/operation-id.ts
458
- function operationIdFor(scope, method, path) {
459
- return `${scope}.${method.toLowerCase()}.${slugifyPath(path)}`;
460
- }
461
- function slugifyPath(path) {
462
- const trimmed = path.replace(/^\/+/, "").replace(/\/+$/, "");
463
- if (trimmed === "")
464
- return "root";
465
- const segments = trimmed.split("/").map((seg) => {
466
- if (seg.startsWith(":"))
467
- return camelToKebab(seg.slice(1));
468
- if (seg.startsWith("{") && seg.endsWith("}"))
469
- return camelToKebab(seg.slice(1, -1));
470
- return camelToKebab(seg);
471
- }).filter(Boolean);
472
- return segments.join("-");
473
- }
474
- function camelToKebab(input) {
475
- return input.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
476
- }
477
-
478
- // packages/core/src/routing/registry.ts
479
- function parseSegments(path) {
480
- return path.split("/").filter(Boolean).map((seg) => {
481
- if (seg === "*" || seg.startsWith("..."))
482
- return { kind: "wildcard" };
483
- if (seg.startsWith(":"))
484
- return { kind: "param", name: seg.slice(1) };
485
- if (seg.startsWith("{") && seg.endsWith("}")) {
486
- return { kind: "param", name: seg.slice(1, -1) };
487
- }
488
- return { kind: "literal", value: seg };
489
- });
490
- }
491
- function specificityScore(segments) {
492
- let score = 0;
493
- for (const seg of segments) {
494
- if (seg.kind === "literal")
495
- score += 2;
496
- else if (seg.kind === "param")
497
- score += 1;
498
- }
499
- return score;
500
- }
501
- function matchSegments(pathSegments, routeSegments) {
502
- const lastIsWildcard = routeSegments.length > 0 && routeSegments[routeSegments.length - 1].kind === "wildcard";
503
- if (!lastIsWildcard && pathSegments.length !== routeSegments.length)
504
- return null;
505
- if (lastIsWildcard && pathSegments.length < routeSegments.length - 1)
506
- return null;
507
- const params = {};
508
- for (let i = 0;i < routeSegments.length; i++) {
509
- const rseg = routeSegments[i];
510
- if (rseg.kind === "wildcard")
511
- return params;
512
- const pseg = pathSegments[i];
513
- if (rseg.kind === "literal") {
514
- if (rseg.value !== pseg)
515
- return null;
516
- } else {
517
- params[rseg.name] = pseg;
518
- }
519
- }
520
- return params;
521
- }
522
-
523
- class RouteRegistry {
524
- byMethod = new Map;
525
- operationIds = new Set;
526
- fullPaths = new Set;
527
- register(input) {
528
- const { route } = input;
529
- const pluginId = input.scope === "plugin" ? input.pluginId : null;
530
- const fullPath = pluginId !== null ? `/api/plugins/${pluginId}${route.path}` : route.path;
531
- const operationId = route.operationId ?? operationIdFor(pluginId ?? "core", route.method, route.path);
532
- const dupKey = `${route.method} ${fullPath}`;
533
- if (this.fullPaths.has(dupKey)) {
534
- throw new Error(`duplicate route registration: ${dupKey}`);
535
- }
536
- if (this.operationIds.has(operationId)) {
537
- throw new Error(`duplicate operationId: ${operationId} (route: ${dupKey})`);
538
- }
539
- this.fullPaths.add(dupKey);
540
- this.operationIds.add(operationId);
541
- const segments = parseSegments(fullPath);
542
- const indexed = {
543
- registered: {
544
- route,
545
- scope: pluginId ?? "core",
546
- fullPath,
547
- operationId
548
- },
549
- segments,
550
- score: specificityScore(segments)
551
- };
552
- let bucket = this.byMethod.get(route.method);
553
- if (!bucket) {
554
- bucket = [];
555
- this.byMethod.set(route.method, bucket);
556
- }
557
- bucket.push(indexed);
558
- bucket.sort((a, b) => b.score - a.score);
559
- return indexed.registered;
560
- }
561
- match(method, path) {
562
- const bucket = this.byMethod.get(method);
563
- if (!bucket)
564
- return null;
565
- const normalized = path.replace(/\/+$/, "") || "/";
566
- const pathSegments = normalized.split("/").filter(Boolean);
567
- for (const indexed of bucket) {
568
- const params = matchSegments(pathSegments, indexed.segments);
569
- if (params !== null) {
570
- return {
571
- ...indexed.registered,
572
- params
573
- };
574
- }
575
- }
576
- return null;
577
- }
578
- all() {
579
- const out = [];
580
- for (const bucket of this.byMethod.values()) {
581
- for (const entry of bucket)
582
- out.push(entry.registered);
583
- }
584
- return out;
585
- }
586
- clear() {
587
- this.byMethod.clear();
588
- this.operationIds.clear();
589
- this.fullPaths.clear();
590
- }
591
- }
592
509
  // node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
593
510
  var exports_external = {};
594
511
  __export(exports_external, {
@@ -14190,9 +14107,13 @@ function getBakinPaths() {
14190
14107
  inbox: join(home, "inbox"),
14191
14108
  tasks: join(home, "tasks"),
14192
14109
  workflows: join(home, "workflows"),
14110
+ brands: join(home, "brands"),
14111
+ chat: join(home, "chat"),
14193
14112
  settings: join(home, "settings.json"),
14194
14113
  logs: join(home, "logs"),
14195
- db: join(home, "bakin.db")
14114
+ antfly: join(home, "antfly"),
14115
+ db: join(home, "bakin.db"),
14116
+ bin: join(home, "bin")
14196
14117
  };
14197
14118
  }
14198
14119
 
@@ -14364,7 +14285,6 @@ function suppressPrettyInfo(entry) {
14364
14285
  "search-cleanup",
14365
14286
  "search-startup",
14366
14287
  "hot-reload-coordinator",
14367
- "mcporter",
14368
14288
  "dispatch",
14369
14289
  "dispatch-state",
14370
14290
  "dispatch-turns",
@@ -14465,95 +14385,234 @@ function createLogger(module) {
14465
14385
 
14466
14386
  // packages/core/src/routing/dispatcher.ts
14467
14387
  var log = createLogger("dispatcher");
14468
- // packages/core/src/routing/search-route.ts
14469
- var searchQuery = exports_external.object({
14470
- q: exports_external.string().min(1),
14471
- limit: exports_external.coerce.number().int().positive().max(500).optional(),
14472
- offset: exports_external.coerce.number().int().nonnegative().optional(),
14473
- facets: exports_external.string().optional()
14474
- });
14475
- var searchResponse = exports_external.object({
14476
- results: exports_external.array(exports_external.unknown()),
14477
- aggregations: exports_external.unknown().optional(),
14478
- meta: exports_external.object({
14479
- query: exports_external.string(),
14480
- total: exports_external.number(),
14481
- took_ms: exports_external.number(),
14482
- source: exports_external.string()
14483
- }).optional()
14484
- });
14485
- var errorResponse = exports_external.object({ error: exports_external.string() });
14486
- // src/hooks/use-nav-badge.ts
14487
- "use client";
14488
- function useNavBadge(pluginId, navItemId, badge) {
14489
- const key = badge ? `${badge.count ?? ""}:${badge.tone ?? ""}` : "null";
14490
- useEffect(() => {
14491
- setNavBadge(pluginId, navItemId, badge);
14492
- }, [pluginId, navItemId, key]);
14388
+ // packages/core/src/routing/operation-id.ts
14389
+ function operationIdFor(scope, method, path) {
14390
+ return `${scope}.${method.toLowerCase()}.${slugifyPath(path)}`;
14493
14391
  }
14494
- // src/hooks/use-debug.ts
14495
- "use client";
14496
- function useDebug() {
14497
- const debug = useContentStore((s) => s.debug);
14498
- const toggleDebug = useContentStore((s) => s.toggleDebug);
14499
- return [debug, toggleDebug];
14392
+ function slugifyPath(path) {
14393
+ const trimmed = path.replace(/^\/+/, "").replace(/\/+$/, "");
14394
+ if (trimmed === "")
14395
+ return "root";
14396
+ const segments = trimmed.split("/").map((seg) => {
14397
+ if (seg.startsWith(":"))
14398
+ return camelToKebab(seg.slice(1));
14399
+ if (seg.startsWith("{") && seg.endsWith("}"))
14400
+ return camelToKebab(seg.slice(1, -1));
14401
+ return camelToKebab(seg);
14402
+ }).filter(Boolean);
14403
+ return segments.join("-");
14500
14404
  }
14501
- // src/hooks/use-form-guard.ts
14502
- import { useEffect as useEffect2 } from "react";
14503
- "use client";
14504
- function useFormGuard(isDirty) {
14505
- useEffect2(() => {
14506
- if (!isDirty)
14507
- return;
14508
- const handler = (e) => {
14509
- e.preventDefault();
14510
- };
14511
- window.addEventListener("beforeunload", handler);
14512
- return () => window.removeEventListener("beforeunload", handler);
14513
- }, [isDirty]);
14405
+ function camelToKebab(input) {
14406
+ return input.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
14514
14407
  }
14515
- // src/hooks/use-json-fetch.ts
14516
- import { useCallback, useEffect as useEffect3, useRef, useState } from "react";
14517
- "use client";
14518
- function useJsonFetch(url2, opts) {
14519
- const [data, setData] = useState(null);
14520
- const [loading, setLoading] = useState(url2 !== null);
14521
- const [error48, setError] = useState(null);
14522
- const [nonce, setNonce] = useState(0);
14523
- const refresh = useCallback(() => setNonce((n) => n + 1), []);
14524
- const optsRef = useRef(opts);
14525
- optsRef.current = opts;
14526
- useEffect3(() => {
14527
- if (url2 === null) {
14528
- setData(null);
14529
- setLoading(false);
14530
- setError(null);
14531
- return;
14408
+
14409
+ // packages/core/src/routing/registry.ts
14410
+ function parseSegments(path) {
14411
+ return path.split("/").filter(Boolean).map((seg) => {
14412
+ if (seg === "*" || seg.startsWith("..."))
14413
+ return { kind: "wildcard" };
14414
+ if (seg.startsWith(":"))
14415
+ return { kind: "param", name: seg.slice(1) };
14416
+ if (seg.startsWith("{") && seg.endsWith("}")) {
14417
+ return { kind: "param", name: seg.slice(1, -1) };
14532
14418
  }
14533
- const controller = new AbortController;
14534
- setLoading(true);
14535
- setError(null);
14536
- fetch(url2, { ...optsRef.current, signal: controller.signal }).then(async (res) => {
14537
- if (!res.ok)
14538
- throw new Error(`Request failed (${res.status})`);
14539
- return await res.json();
14540
- }).then((json2) => {
14541
- if (controller.signal.aborted)
14542
- return;
14543
- setData(json2);
14544
- setLoading(false);
14545
- }).catch((err) => {
14546
- if (controller.signal.aborted || err?.name === "AbortError")
14547
- return;
14548
- setError(err instanceof Error ? err.message : "Request failed");
14549
- setLoading(false);
14550
- });
14551
- return () => controller.abort();
14552
- }, [url2, nonce]);
14553
- return { data, loading, error: error48, refresh };
14419
+ return { kind: "literal", value: seg };
14420
+ });
14554
14421
  }
14555
- // src/hooks/use-runtime-status.ts
14556
- import { useState as useState2, useEffect as useEffect4, useCallback as useCallback2 } from "react";
14422
+ function specificityScore(segments) {
14423
+ let score = 0;
14424
+ for (const seg of segments) {
14425
+ if (seg.kind === "literal")
14426
+ score += 2;
14427
+ else if (seg.kind === "param")
14428
+ score += 1;
14429
+ }
14430
+ return score;
14431
+ }
14432
+ function matchSegments(pathSegments, routeSegments) {
14433
+ const lastIsWildcard = routeSegments.length > 0 && routeSegments[routeSegments.length - 1].kind === "wildcard";
14434
+ if (!lastIsWildcard && pathSegments.length !== routeSegments.length)
14435
+ return null;
14436
+ if (lastIsWildcard && pathSegments.length < routeSegments.length - 1)
14437
+ return null;
14438
+ const params = {};
14439
+ for (let i = 0;i < routeSegments.length; i++) {
14440
+ const rseg = routeSegments[i];
14441
+ if (rseg.kind === "wildcard")
14442
+ return params;
14443
+ const pseg = pathSegments[i];
14444
+ if (rseg.kind === "literal") {
14445
+ if (rseg.value !== pseg)
14446
+ return null;
14447
+ } else {
14448
+ params[rseg.name] = pseg;
14449
+ }
14450
+ }
14451
+ return params;
14452
+ }
14453
+
14454
+ class RouteRegistry {
14455
+ byMethod = new Map;
14456
+ operationIds = new Set;
14457
+ fullPaths = new Set;
14458
+ register(input) {
14459
+ const { route } = input;
14460
+ const pluginId = input.scope === "plugin" ? input.pluginId : null;
14461
+ const fullPath = pluginId !== null ? `/api/plugins/${pluginId}${route.path}` : route.path;
14462
+ const operationId = route.operationId ?? operationIdFor(pluginId ?? "core", route.method, route.path);
14463
+ const dupKey = `${route.method} ${fullPath}`;
14464
+ if (this.fullPaths.has(dupKey)) {
14465
+ throw new Error(`duplicate route registration: ${dupKey}`);
14466
+ }
14467
+ if (this.operationIds.has(operationId)) {
14468
+ throw new Error(`duplicate operationId: ${operationId} (route: ${dupKey})`);
14469
+ }
14470
+ this.fullPaths.add(dupKey);
14471
+ this.operationIds.add(operationId);
14472
+ const segments = parseSegments(fullPath);
14473
+ const indexed = {
14474
+ registered: {
14475
+ route,
14476
+ scope: pluginId ?? "core",
14477
+ fullPath,
14478
+ operationId
14479
+ },
14480
+ segments,
14481
+ score: specificityScore(segments)
14482
+ };
14483
+ let bucket = this.byMethod.get(route.method);
14484
+ if (!bucket) {
14485
+ bucket = [];
14486
+ this.byMethod.set(route.method, bucket);
14487
+ }
14488
+ bucket.push(indexed);
14489
+ bucket.sort((a, b) => b.score - a.score);
14490
+ return indexed.registered;
14491
+ }
14492
+ match(method, path) {
14493
+ const bucket = this.byMethod.get(method);
14494
+ if (!bucket)
14495
+ return null;
14496
+ const normalized = path.replace(/\/+$/, "") || "/";
14497
+ const pathSegments = normalized.split("/").filter(Boolean);
14498
+ for (const indexed of bucket) {
14499
+ const params = matchSegments(pathSegments, indexed.segments);
14500
+ if (params !== null) {
14501
+ return {
14502
+ ...indexed.registered,
14503
+ params
14504
+ };
14505
+ }
14506
+ }
14507
+ return null;
14508
+ }
14509
+ all() {
14510
+ const out = [];
14511
+ for (const bucket of this.byMethod.values()) {
14512
+ for (const entry of bucket)
14513
+ out.push(entry.registered);
14514
+ }
14515
+ return out;
14516
+ }
14517
+ clear() {
14518
+ this.byMethod.clear();
14519
+ this.operationIds.clear();
14520
+ this.fullPaths.clear();
14521
+ }
14522
+ }
14523
+ // packages/core/src/routing/search-route.ts
14524
+ var searchQuery = exports_external.object({
14525
+ q: exports_external.string().min(1),
14526
+ limit: exports_external.coerce.number().int().positive().max(500).optional(),
14527
+ offset: exports_external.coerce.number().int().nonnegative().optional(),
14528
+ facets: exports_external.string().optional()
14529
+ });
14530
+ var searchResponse = exports_external.object({
14531
+ results: exports_external.array(exports_external.unknown()),
14532
+ aggregations: exports_external.unknown().optional(),
14533
+ meta: exports_external.object({
14534
+ query: exports_external.string(),
14535
+ total: exports_external.number(),
14536
+ took_ms: exports_external.number(),
14537
+ source: exports_external.string()
14538
+ }).optional()
14539
+ });
14540
+ var errorResponse = exports_external.object({ error: exports_external.string() });
14541
+ // src/hooks/use-nav-badge.ts
14542
+ "use client";
14543
+ function useNavBadge(pluginId, navItemId, badge) {
14544
+ const key = badge ? `${badge.count ?? ""}:${badge.tone ?? ""}` : "null";
14545
+ useEffect(() => {
14546
+ setNavBadge(pluginId, navItemId, badge);
14547
+ }, [pluginId, navItemId, key]);
14548
+ }
14549
+ // src/hooks/use-debug.ts
14550
+ "use client";
14551
+ function useDebug() {
14552
+ const debug = useContentStore((s) => s.debug);
14553
+ const toggleDebug = useContentStore((s) => s.toggleDebug);
14554
+ return [debug, toggleDebug];
14555
+ }
14556
+ // src/hooks/use-form-guard.ts
14557
+ import { useEffect as useEffect2 } from "react";
14558
+ "use client";
14559
+ function useFormGuard(isDirty) {
14560
+ useEffect2(() => {
14561
+ if (!isDirty)
14562
+ return;
14563
+ const handler = (e) => {
14564
+ e.preventDefault();
14565
+ };
14566
+ window.addEventListener("beforeunload", handler);
14567
+ return () => window.removeEventListener("beforeunload", handler);
14568
+ }, [isDirty]);
14569
+ }
14570
+ // src/hooks/use-json-fetch.ts
14571
+ import { useCallback, useEffect as useEffect3, useRef, useState } from "react";
14572
+ "use client";
14573
+ function useJsonFetch(url2, opts) {
14574
+ const [data, setData] = useState(null);
14575
+ const [loading, setLoading] = useState(url2 !== null);
14576
+ const [error48, setError] = useState(null);
14577
+ const [nonce, setNonce] = useState(0);
14578
+ const refresh = useCallback(() => setNonce((n) => n + 1), []);
14579
+ const optsRef = useRef(opts);
14580
+ optsRef.current = opts;
14581
+ useEffect3(() => {
14582
+ if (url2 === null) {
14583
+ setData(null);
14584
+ setLoading(false);
14585
+ setError(null);
14586
+ return;
14587
+ }
14588
+ const controller = new AbortController;
14589
+ setLoading(true);
14590
+ setError(null);
14591
+ fetch(url2, { ...optsRef.current, signal: controller.signal }).then(async (res) => {
14592
+ if (!res.ok)
14593
+ throw new Error(`Request failed (${res.status})`);
14594
+ return await res.json();
14595
+ }).then((json2) => {
14596
+ if (controller.signal.aborted)
14597
+ return;
14598
+ setData(json2);
14599
+ setLoading(false);
14600
+ }).catch((err) => {
14601
+ if (controller.signal.aborted || err?.name === "AbortError")
14602
+ return;
14603
+ setError(err instanceof Error ? err.message : "Request failed");
14604
+ setLoading(false);
14605
+ });
14606
+ return () => controller.abort();
14607
+ }, [url2, nonce]);
14608
+ return { data, loading, error: error48, refresh };
14609
+ }
14610
+ function usePluginJsonFetch(pluginId, path, opts) {
14611
+ const clean = path === null ? null : path.startsWith("/") ? path.slice(1) : path;
14612
+ return useJsonFetch(clean === null ? null : `/api/plugins/${pluginId}/${clean}`, opts);
14613
+ }
14614
+ // src/hooks/use-runtime-status.ts
14615
+ import { useState as useState2, useEffect as useEffect4, useCallback as useCallback2 } from "react";
14557
14616
  "use client";
14558
14617
  function useRuntimeStatus() {
14559
14618
  const [restartNeeded, setRestartNeeded] = useState2(false);
@@ -14584,39 +14643,59 @@ function useRuntimeStatus() {
14584
14643
  // src/hooks/use-query-state.ts
14585
14644
  import { useCallback as useCallback3, useMemo, useRef as useRef2 } from "react";
14586
14645
  "use client";
14646
+ var pendingPatch = new Map;
14647
+ var pendingPush = false;
14648
+ var pendingNav = null;
14649
+ var flushScheduled = false;
14650
+ function enqueueParamUpdate(key, value, push, router, pathname) {
14651
+ pendingPatch.set(key, value);
14652
+ pendingPush = pendingPush || push;
14653
+ pendingNav = { router, pathname };
14654
+ if (flushScheduled)
14655
+ return;
14656
+ flushScheduled = true;
14657
+ queueMicrotask(() => {
14658
+ const nav = pendingNav;
14659
+ const usePush = pendingPush;
14660
+ const patch = new Map(pendingPatch);
14661
+ pendingPatch.clear();
14662
+ pendingPush = false;
14663
+ pendingNav = null;
14664
+ flushScheduled = false;
14665
+ const params = new URLSearchParams(window.location.search);
14666
+ for (const [k, v] of patch) {
14667
+ if (v === null)
14668
+ params.delete(k);
14669
+ else
14670
+ params.set(k, v);
14671
+ }
14672
+ const qs = params.toString();
14673
+ const url2 = qs ? `${nav.pathname}?${qs}` : nav.pathname;
14674
+ if (usePush)
14675
+ nav.router.push(url2, { scroll: false });
14676
+ else
14677
+ nav.router.replace(url2, { scroll: false });
14678
+ });
14679
+ }
14587
14680
  function useQueryState(key, defaultValue = "") {
14588
14681
  const searchParams = useSearchParams();
14589
14682
  const router = useRouter();
14590
14683
  const pathname = usePathname();
14591
- const paramsRef = useRef2(searchParams);
14592
- paramsRef.current = searchParams;
14593
14684
  const pathnameRef = useRef2(pathname);
14594
14685
  pathnameRef.current = pathname;
14595
14686
  const value = searchParams.get(key) ?? defaultValue;
14596
- const buildUrl = useCallback3((v) => {
14597
- const params = new URLSearchParams(paramsRef.current.toString());
14598
- if (v === defaultValue) {
14599
- params.delete(key);
14600
- } else {
14601
- params.set(key, v);
14602
- }
14603
- const qs = params.toString();
14604
- return qs ? `${pathnameRef.current}?${qs}` : pathnameRef.current;
14605
- }, [key, defaultValue]);
14606
14687
  const setValue = useCallback3((v) => {
14607
- router.replace(buildUrl(v), { scroll: false });
14608
- }, [router, buildUrl]);
14688
+ enqueueParamUpdate(key, v === defaultValue ? null : v, false, router, pathnameRef.current);
14689
+ }, [key, defaultValue, router]);
14609
14690
  const pushValue = useCallback3((v) => {
14610
- router.push(buildUrl(v), { scroll: false });
14611
- }, [router, buildUrl]);
14691
+ enqueueParamUpdate(key, v === defaultValue ? null : v, true, router, pathnameRef.current);
14692
+ }, [key, defaultValue, router]);
14612
14693
  return [value, setValue, pushValue];
14613
14694
  }
14614
14695
  function useQueryArrayState(key) {
14615
14696
  const searchParams = useSearchParams();
14616
14697
  const router = useRouter();
14617
14698
  const pathname = usePathname();
14618
- const paramsRef = useRef2(searchParams);
14619
- paramsRef.current = searchParams;
14620
14699
  const pathnameRef = useRef2(pathname);
14621
14700
  pathnameRef.current = pathname;
14622
14701
  const value = useMemo(() => {
@@ -14626,15 +14705,8 @@ function useQueryArrayState(key) {
14626
14705
  return raw.split(",").filter(Boolean);
14627
14706
  }, [searchParams, key]);
14628
14707
  const setValue = useCallback3((v) => {
14629
- const params = new URLSearchParams(paramsRef.current.toString());
14630
- if (v.length === 0) {
14631
- params.delete(key);
14632
- } else {
14633
- params.set(key, v.join(","));
14634
- }
14635
- const qs = params.toString();
14636
- router.replace(qs ? `${pathnameRef.current}?${qs}` : pathnameRef.current, { scroll: false });
14637
- }, [router, key]);
14708
+ enqueueParamUpdate(key, v.length === 0 ? null : v.join(","), false, router, pathnameRef.current);
14709
+ }, [key, router]);
14638
14710
  return [value, setValue];
14639
14711
  }
14640
14712
  // src/hooks/use-schedule.ts
@@ -14643,6 +14715,7 @@ import { useState as useState3, useEffect as useEffect5, useCallback as useCallb
14643
14715
  function useScheduleJobs(options = {}) {
14644
14716
  const [jobs, setJobs] = useState3([]);
14645
14717
  const [loading, setLoading] = useState3(true);
14718
+ const [fetchFailed, setFetchFailed] = useState3(false);
14646
14719
  const optionsRef = useRef3(options);
14647
14720
  optionsRef.current = options;
14648
14721
  const fetchJobs = useCallback4(async () => {
@@ -14651,8 +14724,13 @@ function useScheduleJobs(options = {}) {
14651
14724
  if (res.ok) {
14652
14725
  const data = await res.json();
14653
14726
  setJobs(data.jobs || []);
14727
+ setFetchFailed(false);
14728
+ } else {
14729
+ setFetchFailed(true);
14654
14730
  }
14655
- } catch {} finally {
14731
+ } catch {
14732
+ setFetchFailed(true);
14733
+ } finally {
14656
14734
  setLoading(false);
14657
14735
  }
14658
14736
  }, []);
@@ -14801,6 +14879,7 @@ function useScheduleJobs(options = {}) {
14801
14879
  name: overrides.name ?? `${source.displayName} (copy)`,
14802
14880
  schedule: overrides.schedule ?? source.humanSchedule,
14803
14881
  agentId: overrides.agentId ?? source.agentId,
14882
+ teamId: overrides.teamId ?? source.teamId,
14804
14883
  taskPrompt: overrides.taskPrompt ?? source.taskPrompt,
14805
14884
  taskTitle: overrides.taskTitle ?? source.taskTitle,
14806
14885
  workflowId: overrides.workflowId ?? source.workflowId,
@@ -14820,7 +14899,9 @@ function useScheduleJobs(options = {}) {
14820
14899
  }, [jobs, fetchJobs]);
14821
14900
  return {
14822
14901
  jobs: filtered,
14902
+ allJobs: jobs,
14823
14903
  loading,
14904
+ fetchFailed,
14824
14905
  refresh: fetchJobs,
14825
14906
  pauseJob,
14826
14907
  resumeJob,
@@ -14833,6 +14914,47 @@ function useScheduleJobs(options = {}) {
14833
14914
  duplicateJob
14834
14915
  };
14835
14916
  }
14917
+ function useOccurrences(fromIso, toIso) {
14918
+ const [occurrences, setOccurrences] = useState3([]);
14919
+ const [events, setEvents] = useState3([]);
14920
+ const [unevaluated, setUnevaluated] = useState3([]);
14921
+ const [droppedProviders, setDroppedProviders] = useState3([]);
14922
+ const [loading, setLoading] = useState3(true);
14923
+ const fetchOccurrences = useCallback4(async () => {
14924
+ try {
14925
+ const res = await fetch(`/api/plugins/schedule/occurrences?from=${encodeURIComponent(fromIso)}&to=${encodeURIComponent(toIso)}`);
14926
+ if (res.ok) {
14927
+ const data = await res.json();
14928
+ setOccurrences(data.occurrences || []);
14929
+ setEvents(data.events || []);
14930
+ setUnevaluated(data.unevaluated || []);
14931
+ setDroppedProviders(data.droppedProviders || []);
14932
+ }
14933
+ } catch {} finally {
14934
+ setLoading(false);
14935
+ }
14936
+ }, [fromIso, toIso]);
14937
+ useEffect5(() => {
14938
+ fetchOccurrences();
14939
+ }, [fetchOccurrences]);
14940
+ useEffect5(() => {
14941
+ const es = new EventSource("/api/events");
14942
+ const handler = (event) => {
14943
+ try {
14944
+ const data = JSON.parse(event.data);
14945
+ if (data.type === "activity" && data.message?.includes("Schedule") || data.event?.startsWith("schedule.") || data.type === "taskboard" || data.event?.endsWith(".scheduled_events_changed")) {
14946
+ fetchOccurrences();
14947
+ }
14948
+ } catch {}
14949
+ };
14950
+ es.addEventListener("message", handler);
14951
+ return () => {
14952
+ es.removeEventListener("message", handler);
14953
+ es.close();
14954
+ };
14955
+ }, [fetchOccurrences]);
14956
+ return { occurrences, events, unevaluated, droppedProviders, loading, refresh: fetchOccurrences };
14957
+ }
14836
14958
  function useRunHistory(jobId, limit = 20) {
14837
14959
  const [runs, setRuns] = useState3([]);
14838
14960
  const [loading, setLoading] = useState3(false);
@@ -14903,18 +15025,19 @@ function useSearch(options = {}) {
14903
15025
  plugin,
14904
15026
  limit = 20,
14905
15027
  facets,
14906
- debounce: debounceMs = 250,
14907
- fallback
15028
+ types: types2,
15029
+ debounce: debounceMs = 250
14908
15030
  } = options;
14909
15031
  const [results, setResults] = useState5([]);
14910
15032
  const [aggregations, setAggregations] = useState5({});
14911
- const [loading, setLoading] = useState5(false);
15033
+ const [status, setStatus] = useState5("idle");
14912
15034
  const [error48, setError] = useState5(null);
14913
15035
  const [meta3, setMeta] = useState5(null);
14914
- const [, setQuery] = useState5("");
14915
15036
  const abortRef = useRef4(null);
14916
15037
  const timerRef = useRef4(null);
14917
15038
  const mountedRef = useRef4(true);
15039
+ const lastQueryRef = useRef4("");
15040
+ const typesKey = types2?.join(",");
14918
15041
  useEffect7(() => {
14919
15042
  mountedRef.current = true;
14920
15043
  return () => {
@@ -14930,13 +15053,13 @@ function useSearch(options = {}) {
14930
15053
  setAggregations({});
14931
15054
  setMeta(null);
14932
15055
  setError(null);
14933
- setLoading(false);
15056
+ setStatus("idle");
14934
15057
  return;
14935
15058
  }
14936
15059
  abortRef.current?.abort();
14937
15060
  const controller = new AbortController;
14938
15061
  abortRef.current = controller;
14939
- setLoading(true);
15062
+ setStatus("loading");
14940
15063
  setError(null);
14941
15064
  try {
14942
15065
  const params = new URLSearchParams({ q });
@@ -14944,25 +15067,29 @@ function useSearch(options = {}) {
14944
15067
  params.set("limit", String(limit));
14945
15068
  if (facets?.length)
14946
15069
  params.set("facets", facets.join(","));
15070
+ if (typesKey)
15071
+ params.set("types", typesKey);
14947
15072
  const url2 = plugin ? `/api/plugins/${plugin}/search?${params}` : `/api/search?${params}`;
14948
15073
  const res = await fetch(url2, { signal: controller.signal });
14949
15074
  if (!mountedRef.current)
14950
15075
  return;
15076
+ if (res.status === 503) {
15077
+ setResults([]);
15078
+ setAggregations({});
15079
+ setMeta(null);
15080
+ setStatus("unavailable");
15081
+ return;
15082
+ }
14951
15083
  if (!res.ok) {
14952
15084
  throw new Error(`Search failed: ${res.status}`);
14953
15085
  }
14954
15086
  const data = await res.json();
14955
15087
  if (!mountedRef.current)
14956
15088
  return;
14957
- if (data.results.length === 0 && data.meta?.source === "fallback" && fallback) {
14958
- setResults(fallback(q));
14959
- setAggregations({});
14960
- setMeta(data.meta);
14961
- } else {
14962
- setResults(data.results);
14963
- setAggregations(data.aggregations || {});
14964
- setMeta(data.meta || null);
14965
- }
15089
+ setResults(Array.isArray(data.results) ? data.results : []);
15090
+ setAggregations(data.aggregations || {});
15091
+ setMeta(data.meta || null);
15092
+ setStatus("ok");
14966
15093
  } catch (err) {
14967
15094
  if (!mountedRef.current)
14968
15095
  return;
@@ -14970,20 +15097,13 @@ function useSearch(options = {}) {
14970
15097
  return;
14971
15098
  const msg = err instanceof Error ? err.message : String(err);
14972
15099
  setError(msg);
14973
- if (fallback) {
14974
- setResults(fallback(q));
14975
- setAggregations({});
14976
- } else {
14977
- setResults([]);
14978
- setAggregations({});
14979
- }
14980
- } finally {
14981
- if (mountedRef.current)
14982
- setLoading(false);
15100
+ setResults([]);
15101
+ setAggregations({});
15102
+ setStatus("error");
14983
15103
  }
14984
- }, [plugin, limit, facets, fallback]);
15104
+ }, [plugin, limit, facets, typesKey]);
14985
15105
  const search = useCallback5((q) => {
14986
- setQuery(q);
15106
+ lastQueryRef.current = q;
14987
15107
  if (timerRef.current)
14988
15108
  clearTimeout(timerRef.current);
14989
15109
  if (!q.trim()) {
@@ -14991,24 +15111,38 @@ function useSearch(options = {}) {
14991
15111
  setAggregations({});
14992
15112
  setMeta(null);
14993
15113
  setError(null);
14994
- setLoading(false);
15114
+ setStatus("idle");
14995
15115
  return;
14996
15116
  }
14997
- setLoading(true);
15117
+ setStatus("loading");
14998
15118
  timerRef.current = setTimeout(() => executeSearch(q), debounceMs);
14999
15119
  }, [executeSearch, debounceMs]);
15120
+ const retry = useCallback5(() => {
15121
+ if (lastQueryRef.current.trim())
15122
+ executeSearch(lastQueryRef.current);
15123
+ }, [executeSearch]);
15000
15124
  const clear = useCallback5(() => {
15001
- setQuery("");
15125
+ lastQueryRef.current = "";
15002
15126
  setResults([]);
15003
15127
  setAggregations({});
15004
15128
  setMeta(null);
15005
15129
  setError(null);
15006
- setLoading(false);
15130
+ setStatus("idle");
15007
15131
  abortRef.current?.abort();
15008
15132
  if (timerRef.current)
15009
15133
  clearTimeout(timerRef.current);
15010
15134
  }, []);
15011
- return { results, aggregations, loading, error: error48, meta: meta3, search, clear };
15135
+ return {
15136
+ results,
15137
+ aggregations,
15138
+ status,
15139
+ loading: status === "loading",
15140
+ error: error48,
15141
+ meta: meta3,
15142
+ search,
15143
+ clear,
15144
+ retry
15145
+ };
15012
15146
  }
15013
15147
  // src/hooks/use-sidebar.ts
15014
15148
  import { useState as useState6, useEffect as useEffect8 } from "react";
@@ -15067,6 +15201,14 @@ function usePluginEvent(event, handler) {
15067
15201
 
15068
15202
  // src/lib/browser-notify.ts
15069
15203
  var STORAGE_KEY = "bakin-notifications-enabled";
15204
+ function navigateToUrl(url2) {
15205
+ const bridge = globalThis.__bakinNavigate;
15206
+ if (bridge) {
15207
+ bridge(url2);
15208
+ return;
15209
+ }
15210
+ window.location.assign(url2);
15211
+ }
15070
15212
  function isNotificationsSupported() {
15071
15213
  return typeof window !== "undefined" && "Notification" in window && window.isSecureContext;
15072
15214
  }
@@ -15075,12 +15217,19 @@ function isNotificationsEnabled() {
15075
15217
  return false;
15076
15218
  return localStorage.getItem(STORAGE_KEY) === "true" && Notification.permission === "granted";
15077
15219
  }
15078
- function sendBrowserNotification(title, body) {
15220
+ function sendBrowserNotification(title, body, url2) {
15079
15221
  if (!isNotificationsEnabled())
15080
15222
  return;
15081
15223
  if (document.hasFocus())
15082
15224
  return;
15083
- new Notification(title, { body, icon: "/favicon.ico" });
15225
+ const notification = new Notification(title, { body, icon: "/favicon.ico" });
15226
+ if (url2) {
15227
+ notification.onclick = () => {
15228
+ window.focus();
15229
+ navigateToUrl(url2);
15230
+ notification.close();
15231
+ };
15232
+ }
15084
15233
  }
15085
15234
 
15086
15235
  // src/hooks/use-sse.ts
@@ -15127,6 +15276,10 @@ function useSSE() {
15127
15276
  emitPluginEvent({ event: "taskboard" });
15128
15277
  return;
15129
15278
  }
15279
+ if (data.type === "turn-activity") {
15280
+ emitPluginEvent({ ...data, event: "turn-activity" });
15281
+ return;
15282
+ }
15130
15283
  if (data.type === "plugin:manifest-changed") {
15131
15284
  if (!isDevPluginHotReloadActive()) {
15132
15285
  window.location.reload();
@@ -15186,6 +15339,30 @@ function useSSE() {
15186
15339
  eventName: data.event
15187
15340
  });
15188
15341
  }
15342
+ if (data.type === "plugin-event" && data.event === "budget.incident_opened") {
15343
+ sendBrowserNotification("Budget alert", data.message || "A budget cap was reached \u2014 dispatch may be deferred", "/models?tab=spend");
15344
+ appendActivityEvent({
15345
+ id: `${data.timestamp || new Date().toISOString()}-budget-incident-${data.incidentId}`,
15346
+ ts: data.timestamp || new Date().toISOString(),
15347
+ type: "alert",
15348
+ agent: "system",
15349
+ message: data.message || "Budget incident opened",
15350
+ eventName: "budget.incident_opened",
15351
+ data: { incidentId: data.incidentId, scope: data.scope, scopeId: data.scopeId, lane: data.lane, window: data.window }
15352
+ });
15353
+ }
15354
+ if (data.type === "plugin-event" && data.event === "brand.dispatch_blocked") {
15355
+ sendBrowserNotification("Brand unavailable", data.message || `A task is waiting on brand '${data.brandId}'`, `/tasks?brand=${encodeURIComponent(data.brandId || "")}`);
15356
+ appendActivityEvent({
15357
+ id: `${data.timestamp || new Date().toISOString()}-brand-blocked-${data.taskId}`,
15358
+ ts: data.timestamp || new Date().toISOString(),
15359
+ type: "alert",
15360
+ agent: "system",
15361
+ message: data.message || "Task blocked on a missing brand",
15362
+ eventName: "brand.dispatch_blocked",
15363
+ data: { taskId: data.taskId, brandId: data.brandId }
15364
+ });
15365
+ }
15189
15366
  if (data.type === "alert") {
15190
15367
  appendActivityEvent({
15191
15368
  id: `${data.timestamp || new Date().toISOString()}-alert-system`,
@@ -15195,14 +15372,14 @@ function useSSE() {
15195
15372
  message: data.message || "Watchdog alert"
15196
15373
  });
15197
15374
  }
15198
- if (data.type === "reindex.start") {
15199
- emitPluginEvent({ event: "reindex.start", table: data.table });
15375
+ if (data.type === "search.rebuild.start") {
15376
+ emitPluginEvent({ event: "search.rebuild.start", table: data.table });
15200
15377
  }
15201
- if (data.type === "reindex.progress") {
15202
- emitPluginEvent({ event: "reindex.progress", table: data.table, indexed: data.indexed ?? 0 });
15378
+ if (data.type === "search.rebuild.progress") {
15379
+ emitPluginEvent({ event: "search.rebuild.progress", table: data.table, indexed: data.indexed ?? 0 });
15203
15380
  }
15204
- if (data.type === "reindex.complete") {
15205
- emitPluginEvent({ event: "reindex.complete", table: data.table, indexed: data.indexed ?? 0 });
15381
+ if (data.type === "search.rebuild.complete") {
15382
+ emitPluginEvent({ event: "search.rebuild.complete", table: data.table, indexed: data.indexed ?? 0 });
15206
15383
  }
15207
15384
  if (data.type === "reindex.batch_start") {
15208
15385
  appendActivityEvent({
@@ -15271,6 +15448,271 @@ function useSSE() {
15271
15448
  };
15272
15449
  }, [updateFile, setConnected, setHeartbeats, initialize, appendAuditEntry, appendActivityEvent, setSseConnected]);
15273
15450
  }
15451
+ // src/hooks/use-file-drop.ts
15452
+ import { useCallback as useCallback6, useState as useState7 } from "react";
15453
+ "use client";
15454
+ function useFileDrop({ accept, multiple = false, onFiles, onRejected }) {
15455
+ const [dragOver, setDragOver] = useState7(false);
15456
+ const matches = useCallback6((file2) => !accept?.length || accept.some((a) => file2.type.startsWith(a)), [accept]);
15457
+ const onDragOver = useCallback6((e) => {
15458
+ e.preventDefault();
15459
+ setDragOver(true);
15460
+ }, []);
15461
+ const onDragLeave = useCallback6((e) => {
15462
+ e.preventDefault();
15463
+ setDragOver(false);
15464
+ }, []);
15465
+ const onDrop = useCallback6((e) => {
15466
+ e.preventDefault();
15467
+ setDragOver(false);
15468
+ const all = Array.from(e.dataTransfer?.files ?? []);
15469
+ if (all.length === 0)
15470
+ return;
15471
+ const accepted = all.filter(matches);
15472
+ const sliced = multiple ? accepted : accepted.slice(0, 1);
15473
+ if (sliced.length > 0)
15474
+ onFiles(sliced);
15475
+ else
15476
+ onRejected?.(all);
15477
+ }, [matches, multiple, onFiles, onRejected]);
15478
+ return { dragOver, dropProps: { onDragOver, onDragLeave, onDrop } };
15479
+ }
15480
+ // src/hooks/use-history-back.ts
15481
+ import { useCallback as useCallback9 } from "react";
15482
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/routerContext.js
15483
+ import * as React$1 from "react";
15484
+ "use client";
15485
+ var routerContext = React$1.createContext(null);
15486
+
15487
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useRouter.js
15488
+ import * as React$12 from "react";
15489
+ "use client";
15490
+ function useRouter2(opts) {
15491
+ const value = React$12.useContext(routerContext);
15492
+ if (true) {
15493
+ if ((opts?.warn ?? true) && !value)
15494
+ console.warn("Warning: useRouter must be used inside a <RouterProvider> component!");
15495
+ }
15496
+ return value;
15497
+ }
15498
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/matchContext.js
15499
+ import * as React$13 from "react";
15500
+ "use client";
15501
+ var matchContext = React$13.createContext(undefined);
15502
+ var dummyMatchContext = React$13.createContext(undefined);
15503
+
15504
+ // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/isServer/development.js
15505
+ var isServer = undefined;
15506
+
15507
+ // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/utils.js
15508
+ var hasOwn = Object.prototype.hasOwnProperty;
15509
+ var isEnumerable = Object.prototype.propertyIsEnumerable;
15510
+ function replaceEqualDeep(prev, _next, _makeObj = () => ({}), _depth = 0) {
15511
+ if (isServer)
15512
+ return _next;
15513
+ if (prev === _next)
15514
+ return prev;
15515
+ if (_depth > 500)
15516
+ return _next;
15517
+ const next = _next;
15518
+ const array2 = isPlainArray(prev) && isPlainArray(next);
15519
+ if (!array2 && !(isPlainObject2(prev) && isPlainObject2(next)))
15520
+ return next;
15521
+ const prevItems = array2 ? prev : getEnumerableOwnKeys(prev);
15522
+ if (!prevItems)
15523
+ return next;
15524
+ const nextItems = array2 ? next : getEnumerableOwnKeys(next);
15525
+ if (!nextItems)
15526
+ return next;
15527
+ const prevSize = prevItems.length;
15528
+ const nextSize = nextItems.length;
15529
+ const copy = array2 ? new Array(nextSize) : _makeObj();
15530
+ let equalItems = 0;
15531
+ for (let i = 0;i < nextSize; i++) {
15532
+ const key = array2 ? i : nextItems[i];
15533
+ const p = prev[key];
15534
+ const n = next[key];
15535
+ if (p === n) {
15536
+ copy[key] = p;
15537
+ if (array2 ? i < prevSize : hasOwn.call(prev, key))
15538
+ equalItems++;
15539
+ continue;
15540
+ }
15541
+ if (p === null || n === null || typeof p !== "object" || typeof n !== "object") {
15542
+ copy[key] = n;
15543
+ continue;
15544
+ }
15545
+ const v = replaceEqualDeep(p, n, _makeObj, _depth + 1);
15546
+ copy[key] = v;
15547
+ if (v === p)
15548
+ equalItems++;
15549
+ }
15550
+ return prevSize === nextSize && equalItems === prevSize ? prev : copy;
15551
+ }
15552
+ function getEnumerableOwnKeys(o) {
15553
+ const names = Object.getOwnPropertyNames(o);
15554
+ for (const name of names)
15555
+ if (!isEnumerable.call(o, name))
15556
+ return false;
15557
+ const symbols = Object.getOwnPropertySymbols(o);
15558
+ if (symbols.length === 0)
15559
+ return names;
15560
+ const keys = names;
15561
+ for (const symbol2 of symbols) {
15562
+ if (!isEnumerable.call(o, symbol2))
15563
+ return false;
15564
+ keys.push(symbol2);
15565
+ }
15566
+ return keys;
15567
+ }
15568
+ function isPlainObject2(o) {
15569
+ if (!hasObjectPrototype(o))
15570
+ return false;
15571
+ const ctor = o.constructor;
15572
+ if (typeof ctor === "undefined")
15573
+ return true;
15574
+ const prot = ctor.prototype;
15575
+ if (!hasObjectPrototype(prot))
15576
+ return false;
15577
+ if (!prot.hasOwnProperty("isPrototypeOf"))
15578
+ return false;
15579
+ return true;
15580
+ }
15581
+ function hasObjectPrototype(o) {
15582
+ return Object.prototype.toString.call(o) === "[object Object]";
15583
+ }
15584
+ function isPlainArray(value) {
15585
+ return Array.isArray(value) && value.length === Object.keys(value).length;
15586
+ }
15587
+
15588
+ // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/invariant.js
15589
+ function invariant() {
15590
+ throw new Error("Invariant failed");
15591
+ }
15592
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useMatch.js
15593
+ import * as React$14 from "react";
15594
+ // node_modules/.bun/@tanstack+react-store@0.9.3+bf16f8eded5e12ee/node_modules/@tanstack/react-store/dist/esm/useStore.js
15595
+ var import_with_selector = __toESM(require_with_selector(), 1);
15596
+ import { useCallback as useCallback7 } from "react";
15597
+ function defaultCompare(a, b) {
15598
+ return a === b;
15599
+ }
15600
+ function useStore2(atom, selector, compare = defaultCompare) {
15601
+ const subscribe = useCallback7((handleStoreChange) => {
15602
+ if (!atom) {
15603
+ return () => {};
15604
+ }
15605
+ const { unsubscribe } = atom.subscribe(handleStoreChange);
15606
+ return unsubscribe;
15607
+ }, [atom]);
15608
+ const boundGetSnapshot = useCallback7(() => atom?.get(), [atom]);
15609
+ const selectedSnapshot = import_with_selector.useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
15610
+ return selectedSnapshot;
15611
+ }
15612
+
15613
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useMatch.js
15614
+ "use client";
15615
+ var dummyStore = {
15616
+ get: () => {
15617
+ return;
15618
+ },
15619
+ subscribe: () => ({ unsubscribe: () => {} })
15620
+ };
15621
+ function useMatch(opts) {
15622
+ const router = useRouter2();
15623
+ const nearestMatchId = React$14.useContext(opts.from ? dummyMatchContext : matchContext);
15624
+ const key = opts.from ?? nearestMatchId;
15625
+ const matchStore = key ? opts.from ? router.stores.getRouteMatchStore(key) : router.stores.matchStores.get(key) : undefined;
15626
+ if (isServer ?? router.isServer) {
15627
+ const match = matchStore?.get();
15628
+ if ((opts.shouldThrow ?? true) && !match) {
15629
+ if (true)
15630
+ throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : "a nearest match!"}`);
15631
+ invariant();
15632
+ }
15633
+ if (match === undefined)
15634
+ return;
15635
+ return opts.select ? opts.select(match) : match;
15636
+ }
15637
+ const previousResult = React$14.useRef(undefined);
15638
+ return useStore2(matchStore ?? dummyStore, (match) => {
15639
+ if ((opts.shouldThrow ?? true) && !match) {
15640
+ if (true)
15641
+ throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : "a nearest match!"}`);
15642
+ invariant();
15643
+ }
15644
+ if (match === undefined)
15645
+ return;
15646
+ const selected = opts.select ? opts.select(match) : match;
15647
+ if (opts.structuralSharing ?? router.options.defaultStructuralSharing) {
15648
+ const shared = replaceEqualDeep(previousResult.current, selected);
15649
+ previousResult.current = shared;
15650
+ return shared;
15651
+ }
15652
+ return selected;
15653
+ });
15654
+ }
15655
+
15656
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useParams.js
15657
+ function useParams(opts) {
15658
+ return useMatch({
15659
+ from: opts.from,
15660
+ shouldThrow: opts.shouldThrow,
15661
+ structuralSharing: opts.structuralSharing,
15662
+ strict: opts.strict,
15663
+ select: (match) => {
15664
+ const params = opts.strict === false ? match.params : match._strictParams;
15665
+ return opts.select ? opts.select(params) : params;
15666
+ }
15667
+ });
15668
+ }
15669
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useNavigate.js
15670
+ import * as React$15 from "react";
15671
+ "use client";
15672
+ function useNavigate(_defaultOpts) {
15673
+ const router = useRouter2();
15674
+ return React$15.useCallback((options) => {
15675
+ return router.navigate({
15676
+ ...options,
15677
+ from: options.from ?? _defaultOpts?.from
15678
+ });
15679
+ }, [_defaultOpts?.from, router]);
15680
+ }
15681
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useLocation.js
15682
+ import { useRef as useRef9 } from "react";
15683
+ function useLocation(opts) {
15684
+ const router = useRouter2();
15685
+ if (isServer ?? router.isServer) {
15686
+ const location = router.stores.location.get();
15687
+ return opts?.select ? opts.select(location) : location;
15688
+ }
15689
+ const previousResult = useRef9(undefined);
15690
+ return useStore2(router.stores.location, (location) => {
15691
+ const selected = opts?.select ? opts.select(location) : location;
15692
+ if (opts?.structuralSharing ?? router.options.defaultStructuralSharing) {
15693
+ const shared = replaceEqualDeep(previousResult.current, selected);
15694
+ previousResult.current = shared;
15695
+ return shared;
15696
+ }
15697
+ return selected;
15698
+ });
15699
+ }
15700
+
15701
+ // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/index.dev.js
15702
+ "use client";
15703
+
15704
+ // src/hooks/use-history-back.ts
15705
+ "use client";
15706
+ function useHistoryBack(fallbackTo) {
15707
+ const router = useRouter2();
15708
+ const navigate = useNavigate();
15709
+ return useCallback9(() => {
15710
+ if (router.history.canGoBack())
15711
+ router.history.back();
15712
+ else
15713
+ navigate({ to: fallbackTo });
15714
+ }, [router, navigate, fallbackTo]);
15715
+ }
15274
15716
  // src/hooks/use-toast.ts
15275
15717
  var DEFAULT_DURATION = {
15276
15718
  success: 4000,
@@ -15286,25 +15728,26 @@ var useToastStore = create((set2) => ({
15286
15728
  setTimeout(() => {
15287
15729
  set2((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) }));
15288
15730
  }, toast.duration ?? DEFAULT_DURATION[toast.type]);
15731
+ return id;
15289
15732
  },
15290
15733
  dismiss: (id) => set2((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) }))
15291
15734
  }));
15292
15735
  function toast(message, type = "info", duration3) {
15293
- useToastStore.getState().add({ message, type, ...duration3 ? { duration: duration3 } : {} });
15736
+ return useToastStore.getState().add({ message, type, ...duration3 ? { duration: duration3 } : {} });
15294
15737
  }
15295
15738
  // src/hooks/use-resizable-pane.ts
15296
- import { useCallback as useCallback6, useEffect as useEffect11, useRef as useRef7, useState as useState7 } from "react";
15739
+ import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef10, useState as useState8 } from "react";
15297
15740
  "use client";
15298
15741
  var KEY_STEP = 16;
15299
15742
  var KEY_STEP_LARGE = 64;
15300
15743
  function clamp(n, min, max) {
15301
15744
  return Math.min(max, Math.max(min, n));
15302
15745
  }
15303
- function readStored(def, min, max, prefix, storageKey) {
15304
- if (!storageKey || typeof window === "undefined")
15746
+ function readStored(def, min, max, prefix, storageKey2) {
15747
+ if (!storageKey2 || typeof window === "undefined")
15305
15748
  return clamp(def, min, max);
15306
15749
  try {
15307
- const raw = window.localStorage.getItem(prefix + storageKey);
15750
+ const raw = window.localStorage.getItem(prefix + storageKey2);
15308
15751
  if (!raw)
15309
15752
  return clamp(def, min, max);
15310
15753
  const parsed = Number.parseInt(raw, 10);
@@ -15314,22 +15757,22 @@ function readStored(def, min, max, prefix, storageKey) {
15314
15757
  return clamp(def, min, max);
15315
15758
  }
15316
15759
  }
15317
- function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, storagePrefix }) {
15318
- const [size, setSizeState] = useState7(() => readStored(defaultSize, minSize, maxSize, storagePrefix, storageKey));
15319
- const sizeRef = useRef7(size);
15320
- const dragging = useRef7(false);
15321
- const dragStart = useRef7(0);
15322
- const dragStartSize = useRef7(0);
15323
- const persist = useCallback6((n) => {
15324
- if (!storageKey || typeof window === "undefined")
15760
+ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey: storageKey2, storagePrefix }) {
15761
+ const [size, setSizeState] = useState8(() => readStored(defaultSize, minSize, maxSize, storagePrefix, storageKey2));
15762
+ const sizeRef = useRef10(size);
15763
+ const dragging = useRef10(false);
15764
+ const dragStart = useRef10(0);
15765
+ const dragStartSize = useRef10(0);
15766
+ const persist = useCallback10((n) => {
15767
+ if (!storageKey2 || typeof window === "undefined")
15325
15768
  return;
15326
15769
  try {
15327
- window.localStorage.setItem(storagePrefix + storageKey, String(clamp(n, minSize, maxSize)));
15770
+ window.localStorage.setItem(storagePrefix + storageKey2, String(clamp(n, minSize, maxSize)));
15328
15771
  } catch (err) {
15329
15772
  console.error("useResizablePane: failed to persist size", err);
15330
15773
  }
15331
- }, [storageKey, storagePrefix, minSize, maxSize]);
15332
- const setSize = useCallback6((n) => {
15774
+ }, [storageKey2, storagePrefix, minSize, maxSize]);
15775
+ const setSize = useCallback10((n) => {
15333
15776
  const next = clamp(n, minSize, maxSize);
15334
15777
  sizeRef.current = next;
15335
15778
  setSizeState(next);
@@ -15340,12 +15783,12 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15340
15783
  if (clamped !== sizeRef.current)
15341
15784
  setSize(clamped);
15342
15785
  }, [minSize, maxSize, setSize]);
15343
- const beginDrag = useCallback6((client) => {
15786
+ const beginDrag = useCallback10((client) => {
15344
15787
  dragging.current = true;
15345
15788
  dragStart.current = client;
15346
15789
  dragStartSize.current = sizeRef.current;
15347
15790
  }, []);
15348
- const onMove = useCallback6((client) => {
15791
+ const onMove = useCallback10((client) => {
15349
15792
  if (!dragging.current)
15350
15793
  return;
15351
15794
  const delta = dragStart.current - client;
@@ -15353,7 +15796,7 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15353
15796
  sizeRef.current = next;
15354
15797
  setSizeState(next);
15355
15798
  }, [minSize, maxSize]);
15356
- const endDrag = useCallback6(() => {
15799
+ const endDrag = useCallback10(() => {
15357
15800
  if (!dragging.current)
15358
15801
  return;
15359
15802
  dragging.current = false;
@@ -15361,7 +15804,7 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15361
15804
  document.body.style.cursor = "";
15362
15805
  document.body.style.userSelect = "";
15363
15806
  }, [persist]);
15364
- const onMouseDown = useCallback6((e) => {
15807
+ const onMouseDown = useCallback10((e) => {
15365
15808
  e.preventDefault();
15366
15809
  beginDrag(axis === "x" ? e.clientX : e.clientY);
15367
15810
  const move = (ev) => onMove(axis === "x" ? ev.clientX : ev.clientY);
@@ -15375,7 +15818,7 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15375
15818
  document.body.style.cursor = axis === "x" ? "col-resize" : "row-resize";
15376
15819
  document.body.style.userSelect = "none";
15377
15820
  }, [axis, beginDrag, onMove, endDrag]);
15378
- const onTouchStart = useCallback6((e) => {
15821
+ const onTouchStart = useCallback10((e) => {
15379
15822
  const touch = e.touches[0];
15380
15823
  if (!touch)
15381
15824
  return;
@@ -15397,7 +15840,7 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15397
15840
  document.addEventListener("touchend", up);
15398
15841
  document.addEventListener("touchcancel", up);
15399
15842
  }, [axis, beginDrag, onMove, endDrag]);
15400
- const onKeyDown = useCallback6((e) => {
15843
+ const onKeyDown = useCallback10((e) => {
15401
15844
  const growKey = axis === "x" ? "ArrowLeft" : "ArrowUp";
15402
15845
  const shrinkKey = axis === "x" ? "ArrowRight" : "ArrowDown";
15403
15846
  let dir = 0;
@@ -15430,26 +15873,26 @@ function useResizablePane({ axis, defaultSize, minSize, maxSize, storageKey, sto
15430
15873
 
15431
15874
  // src/hooks/use-vertical-resize.ts
15432
15875
  "use client";
15433
- function useVerticalResize({ defaultHeight, minHeight, maxHeight, storageKey }) {
15876
+ function useVerticalResize({ defaultHeight, minHeight, maxHeight, storageKey: storageKey2 }) {
15434
15877
  const { size, setSize, handleProps } = useResizablePane({
15435
15878
  axis: "y",
15436
15879
  defaultSize: defaultHeight,
15437
15880
  minSize: minHeight,
15438
15881
  maxSize: maxHeight,
15439
- storageKey,
15882
+ storageKey: storageKey2,
15440
15883
  storagePrefix: "bakin-vresize:"
15441
15884
  });
15442
15885
  return { height: size, setHeight: setSize, handleProps };
15443
15886
  }
15444
15887
  // src/hooks/use-horizontal-resize.ts
15445
15888
  "use client";
15446
- function useHorizontalResize({ defaultWidth, minWidth, maxWidth, storageKey }) {
15889
+ function useHorizontalResize({ defaultWidth, minWidth, maxWidth, storageKey: storageKey2 }) {
15447
15890
  const { size, setSize, handleProps } = useResizablePane({
15448
15891
  axis: "x",
15449
15892
  defaultSize: defaultWidth,
15450
15893
  minSize: minWidth,
15451
15894
  maxSize: maxWidth,
15452
- storageKey,
15895
+ storageKey: storageKey2,
15453
15896
  storagePrefix: "bakin-hresize:"
15454
15897
  });
15455
15898
  return { width: size, setWidth: setSize, handleProps };
@@ -15472,15 +15915,45 @@ async function parsePackageStatesResponse(res) {
15472
15915
  return {};
15473
15916
  }
15474
15917
  }
15918
+ var ROSTER_CACHE_KEY = "bakin-agent-roster-v1";
15919
+ function readRosterCache() {
15920
+ try {
15921
+ if (typeof window === "undefined")
15922
+ return null;
15923
+ const raw = window.localStorage.getItem(ROSTER_CACHE_KEY);
15924
+ if (!raw)
15925
+ return null;
15926
+ const parsed = JSON.parse(raw);
15927
+ if (!Array.isArray(parsed.agents))
15928
+ return null;
15929
+ const agents = parsed.agents.filter((a) => !!a && typeof a === "object" && typeof a.id === "string" && typeof a.name === "string");
15930
+ return {
15931
+ agents,
15932
+ displaySettings: parsed.displaySettings && typeof parsed.displaySettings === "object" ? parsed.displaySettings : {},
15933
+ mainAgentId: typeof parsed.mainAgentId === "string" ? parsed.mainAgentId : null
15934
+ };
15935
+ } catch {
15936
+ return null;
15937
+ }
15938
+ }
15939
+ function writeRosterCache(cache) {
15940
+ try {
15941
+ window.localStorage.setItem(ROSTER_CACHE_KEY, JSON.stringify(cache));
15942
+ } catch {}
15943
+ }
15944
+ var hydrated = readRosterCache();
15945
+ var hydratedMap = {};
15946
+ for (const a of hydrated?.agents ?? [])
15947
+ hydratedMap[a.id] = a;
15475
15948
  var useAgentStore = create((set2, get) => ({
15476
- agents: [],
15477
- agentIds: [],
15478
- agentMap: {},
15949
+ agents: hydrated?.agents ?? [],
15950
+ agentIds: (hydrated?.agents ?? []).map((a) => a.id),
15951
+ agentMap: hydratedMap,
15479
15952
  agentsWithStatus: [],
15480
- displaySettings: {},
15953
+ displaySettings: hydrated?.displaySettings ?? {},
15481
15954
  teams: [],
15482
15955
  packageStates: {},
15483
- mainAgentId: null,
15956
+ mainAgentId: hydrated?.mainAgentId ?? null,
15484
15957
  loaded: false,
15485
15958
  load: async () => {
15486
15959
  try {
@@ -15516,6 +15989,11 @@ var useAgentStore = create((set2, get) => ({
15516
15989
  mainAgentId: data.mainAgentId ?? null,
15517
15990
  loaded: true
15518
15991
  });
15992
+ writeRosterCache({
15993
+ agents,
15994
+ displaySettings: data.displaySettings,
15995
+ mainAgentId: data.mainAgentId ?? null
15996
+ });
15519
15997
  } catch {
15520
15998
  set2({ loaded: true });
15521
15999
  }
@@ -15567,7 +16045,7 @@ function hexToMuted(hex3, opacity = 0.2) {
15567
16045
  return `rgba(${r}, ${g}, ${b}, ${opacity})`;
15568
16046
  }
15569
16047
  // plugins/workflows/hooks/use-notification-channels.ts
15570
- import { useEffect as useEffect12, useState as useState8 } from "react";
16048
+ import { useEffect as useEffect12, useState as useState9 } from "react";
15571
16049
  "use client";
15572
16050
  var cached2 = null;
15573
16051
  var inFlight = null;
@@ -15589,7 +16067,7 @@ function fetchChannels() {
15589
16067
  return inFlight;
15590
16068
  }
15591
16069
  function useNotificationChannels() {
15592
- const [channels, setChannels] = useState8(() => cached2 ?? []);
16070
+ const [channels, setChannels] = useState9(() => cached2 ?? []);
15593
16071
  useEffect12(() => {
15594
16072
  if (cached2)
15595
16073
  return;
@@ -15613,8 +16091,8 @@ function getChannelInitials(id, channels) {
15613
16091
  return match.initials;
15614
16092
  return id.slice(0, 2).toUpperCase();
15615
16093
  }
15616
- // plugins/models/hooks/use-available-models.ts
15617
- import { useEffect as useEffect13, useState as useState9 } from "react";
16094
+ // src/hooks/use-available-models.ts
16095
+ import { useEffect as useEffect13, useState as useState10 } from "react";
15618
16096
  "use client";
15619
16097
  var cached3 = null;
15620
16098
  var inFlight2 = null;
@@ -15636,7 +16114,7 @@ function fetchAvailableModels() {
15636
16114
  return inFlight2;
15637
16115
  }
15638
16116
  function useAvailableModels() {
15639
- const [models, setModels] = useState9(() => cached3 ?? []);
16117
+ const [models, setModels] = useState10(() => cached3 ?? []);
15640
16118
  useEffect13(() => {
15641
16119
  if (cached3)
15642
16120
  return;
@@ -15651,239 +16129,31 @@ function useAvailableModels() {
15651
16129
  }, []);
15652
16130
  return models;
15653
16131
  }
15654
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/matchContext.js
15655
- import * as React$1 from "react";
15656
- "use client";
15657
- var matchContext = React$1.createContext(undefined);
15658
- var dummyMatchContext = React$1.createContext(undefined);
15659
-
15660
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/routerContext.js
15661
- import * as React$12 from "react";
15662
- "use client";
15663
- var routerContext = React$12.createContext(null);
15664
-
15665
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useRouter.js
15666
- import * as React$13 from "react";
15667
- "use client";
15668
- function useRouter2(opts) {
15669
- const value = React$13.useContext(routerContext);
15670
- if (true) {
15671
- if ((opts?.warn ?? true) && !value)
15672
- console.warn("Warning: useRouter must be used inside a <RouterProvider> component!");
15673
- }
15674
- return value;
15675
- }
15676
-
15677
- // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/isServer/development.js
15678
- var isServer = undefined;
15679
-
15680
- // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/utils.js
15681
- var hasOwn = Object.prototype.hasOwnProperty;
15682
- var isEnumerable = Object.prototype.propertyIsEnumerable;
15683
- function replaceEqualDeep(prev, _next, _makeObj = () => ({}), _depth = 0) {
15684
- if (isServer)
15685
- return _next;
15686
- if (prev === _next)
15687
- return prev;
15688
- if (_depth > 500)
15689
- return _next;
15690
- const next = _next;
15691
- const array2 = isPlainArray(prev) && isPlainArray(next);
15692
- if (!array2 && !(isPlainObject2(prev) && isPlainObject2(next)))
15693
- return next;
15694
- const prevItems = array2 ? prev : getEnumerableOwnKeys(prev);
15695
- if (!prevItems)
15696
- return next;
15697
- const nextItems = array2 ? next : getEnumerableOwnKeys(next);
15698
- if (!nextItems)
15699
- return next;
15700
- const prevSize = prevItems.length;
15701
- const nextSize = nextItems.length;
15702
- const copy = array2 ? new Array(nextSize) : _makeObj();
15703
- let equalItems = 0;
15704
- for (let i = 0;i < nextSize; i++) {
15705
- const key = array2 ? i : nextItems[i];
15706
- const p = prev[key];
15707
- const n = next[key];
15708
- if (p === n) {
15709
- copy[key] = p;
15710
- if (array2 ? i < prevSize : hasOwn.call(prev, key))
15711
- equalItems++;
15712
- continue;
15713
- }
15714
- if (p === null || n === null || typeof p !== "object" || typeof n !== "object") {
15715
- copy[key] = n;
15716
- continue;
15717
- }
15718
- const v = replaceEqualDeep(p, n, _makeObj, _depth + 1);
15719
- copy[key] = v;
15720
- if (v === p)
15721
- equalItems++;
15722
- }
15723
- return prevSize === nextSize && equalItems === prevSize ? prev : copy;
15724
- }
15725
- function getEnumerableOwnKeys(o) {
15726
- const names = Object.getOwnPropertyNames(o);
15727
- for (const name of names)
15728
- if (!isEnumerable.call(o, name))
15729
- return false;
15730
- const symbols = Object.getOwnPropertySymbols(o);
15731
- if (symbols.length === 0)
15732
- return names;
15733
- const keys = names;
15734
- for (const symbol2 of symbols) {
15735
- if (!isEnumerable.call(o, symbol2))
15736
- return false;
15737
- keys.push(symbol2);
15738
- }
15739
- return keys;
15740
- }
15741
- function isPlainObject2(o) {
15742
- if (!hasObjectPrototype(o))
15743
- return false;
15744
- const ctor = o.constructor;
15745
- if (typeof ctor === "undefined")
15746
- return true;
15747
- const prot = ctor.prototype;
15748
- if (!hasObjectPrototype(prot))
15749
- return false;
15750
- if (!prot.hasOwnProperty("isPrototypeOf"))
15751
- return false;
15752
- return true;
15753
- }
15754
- function hasObjectPrototype(o) {
15755
- return Object.prototype.toString.call(o) === "[object Object]";
15756
- }
15757
- function isPlainArray(value) {
15758
- return Array.isArray(value) && value.length === Object.keys(value).length;
15759
- }
15760
-
15761
- // node_modules/.bun/@tanstack+router-core@1.168.15/node_modules/@tanstack/router-core/dist/esm/invariant.js
15762
- function invariant() {
15763
- throw new Error("Invariant failed");
15764
- }
15765
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useMatch.js
15766
- import * as React$14 from "react";
15767
- // node_modules/.bun/@tanstack+react-store@0.9.3+bf16f8eded5e12ee/node_modules/@tanstack/react-store/dist/esm/useStore.js
15768
- var import_with_selector = __toESM(require_with_selector(), 1);
15769
- import { useCallback as useCallback7 } from "react";
15770
- function defaultCompare(a, b) {
15771
- return a === b;
15772
- }
15773
- function useStore2(atom, selector, compare = defaultCompare) {
15774
- const subscribe = useCallback7((handleStoreChange) => {
15775
- if (!atom) {
15776
- return () => {};
15777
- }
15778
- const { unsubscribe } = atom.subscribe(handleStoreChange);
15779
- return unsubscribe;
15780
- }, [atom]);
15781
- const boundGetSnapshot = useCallback7(() => atom?.get(), [atom]);
15782
- const selectedSnapshot = import_with_selector.useSyncExternalStoreWithSelector(subscribe, boundGetSnapshot, boundGetSnapshot, selector, compare);
15783
- return selectedSnapshot;
15784
- }
15785
-
15786
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useMatch.js
15787
- "use client";
15788
- var dummyStore = {
15789
- get: () => {
15790
- return;
15791
- },
15792
- subscribe: () => ({ unsubscribe: () => {} })
15793
- };
15794
- function useMatch(opts) {
15795
- const router = useRouter2();
15796
- const nearestMatchId = React$14.useContext(opts.from ? dummyMatchContext : matchContext);
15797
- const key = opts.from ?? nearestMatchId;
15798
- const matchStore = key ? opts.from ? router.stores.getRouteMatchStore(key) : router.stores.matchStores.get(key) : undefined;
15799
- if (isServer ?? router.isServer) {
15800
- const match = matchStore?.get();
15801
- if ((opts.shouldThrow ?? true) && !match) {
15802
- if (true)
15803
- throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : "a nearest match!"}`);
15804
- invariant();
15805
- }
15806
- if (match === undefined)
15807
- return;
15808
- return opts.select ? opts.select(match) : match;
15809
- }
15810
- const previousResult = React$14.useRef(undefined);
15811
- return useStore2(matchStore ?? dummyStore, (match) => {
15812
- if ((opts.shouldThrow ?? true) && !match) {
15813
- if (true)
15814
- throw new Error(`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : "a nearest match!"}`);
15815
- invariant();
15816
- }
15817
- if (match === undefined)
15818
- return;
15819
- const selected = opts.select ? opts.select(match) : match;
15820
- if (opts.structuralSharing ?? router.options.defaultStructuralSharing) {
15821
- const shared = replaceEqualDeep(previousResult.current, selected);
15822
- previousResult.current = shared;
15823
- return shared;
15824
- }
15825
- return selected;
15826
- });
15827
- }
15828
-
15829
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useParams.js
15830
- function useParams(opts) {
15831
- return useMatch({
15832
- from: opts.from,
15833
- shouldThrow: opts.shouldThrow,
15834
- structuralSharing: opts.structuralSharing,
15835
- strict: opts.strict,
15836
- select: (match) => {
15837
- const params = opts.strict === false ? match.params : match._strictParams;
15838
- return opts.select ? opts.select(params) : params;
15839
- }
15840
- });
15841
- }
15842
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useNavigate.js
15843
- import * as React$15 from "react";
15844
- "use client";
15845
- function useNavigate(_defaultOpts) {
15846
- const router = useRouter2();
15847
- return React$15.useCallback((options) => {
15848
- return router.navigate({
15849
- ...options,
15850
- from: options.from ?? _defaultOpts?.from
15851
- });
15852
- }, [_defaultOpts?.from, router]);
15853
- }
15854
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/useLocation.js
15855
- import { useRef as useRef10 } from "react";
15856
- function useLocation(opts) {
15857
- const router = useRouter2();
15858
- if (isServer ?? router.isServer) {
15859
- const location = router.stores.location.get();
15860
- return opts?.select ? opts.select(location) : location;
15861
- }
15862
- const previousResult = useRef10(undefined);
15863
- return useStore2(router.stores.location, (location) => {
15864
- const selected = opts?.select ? opts.select(location) : location;
15865
- if (opts?.structuralSharing ?? router.options.defaultStructuralSharing) {
15866
- const shared = replaceEqualDeep(previousResult.current, selected);
15867
- previousResult.current = shared;
15868
- return shared;
15869
- }
15870
- return selected;
15871
- });
15872
- }
15873
-
15874
- // node_modules/.bun/@tanstack+react-router@1.168.23+bf16f8eded5e12ee/node_modules/@tanstack/react-router/dist/esm/index.dev.js
15875
- "use client";
15876
-
15877
16132
  // packages/sdk/src/hooks/router.ts
15878
16133
  import { useMemo as useMemo2 } from "react";
16134
+ function toNavigationOptions(url2) {
16135
+ const hashIndex = url2.indexOf("#");
16136
+ const beforeHash = hashIndex >= 0 ? url2.slice(0, hashIndex) : url2;
16137
+ const hash2 = hashIndex >= 0 ? url2.slice(hashIndex + 1) : "";
16138
+ const queryIndex = beforeHash.indexOf("?");
16139
+ const to = queryIndex >= 0 ? beforeHash.slice(0, queryIndex) : beforeHash;
16140
+ const query = queryIndex >= 0 ? beforeHash.slice(queryIndex + 1) : "";
16141
+ const search = Object.create(null);
16142
+ for (const [key, raw] of new URLSearchParams(query))
16143
+ search[key] = raw;
16144
+ return { to, search, hash: hash2 };
16145
+ }
15879
16146
  function useRouter() {
15880
16147
  const navigate = useNavigate();
15881
16148
  return useMemo2(() => ({
15882
- push: (url2) => {
15883
- navigate({ to: url2 });
16149
+ push: (url2, opts) => {
16150
+ navigate({
16151
+ ...toNavigationOptions(url2),
16152
+ ...opts?.scroll === false ? { resetScroll: false } : {}
16153
+ });
15884
16154
  },
15885
16155
  replace: (url2) => {
15886
- navigate({ to: url2, replace: true });
16156
+ navigate({ ...toNavigationOptions(url2), replace: true, resetScroll: false });
15887
16157
  },
15888
16158
  back: () => {
15889
16159
  if (typeof window !== "undefined")
@@ -15941,16 +16211,20 @@ export {
15941
16211
  useRouter,
15942
16212
  useQueryState,
15943
16213
  useQueryArrayState,
16214
+ usePluginJsonFetch,
15944
16215
  usePluginEvent,
15945
16216
  usePathname,
15946
16217
  useParams2 as useParams,
15947
16218
  usePackageState,
16219
+ useOccurrences,
15948
16220
  useNotificationChannels,
15949
16221
  useNavBadge,
15950
16222
  useMainAgentId,
15951
16223
  useJsonFetch,
15952
16224
  useHorizontalResize,
16225
+ useHistoryBack,
15953
16226
  useFormGuard,
16227
+ useFileDrop,
15954
16228
  useDebug,
15955
16229
  useContentStore,
15956
16230
  useAvailableModels,
@@ -15961,8 +16235,10 @@ export {
15961
16235
  useAgentColor,
15962
16236
  useAgent,
15963
16237
  toast,
16238
+ toNavigationOptions,
15964
16239
  reorderBySearchResults,
15965
16240
  hexToMuted,
15966
16241
  getChannelLabel,
15967
- getChannelInitials
16242
+ getChannelInitials,
16243
+ emitPluginEvent
15968
16244
  };