@usesidekick/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +246 -0
  2. package/dist/index.d.mts +358 -0
  3. package/dist/index.d.ts +358 -0
  4. package/dist/index.js +2470 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +2403 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/jsx-dev-runtime.d.mts +21 -0
  9. package/dist/jsx-dev-runtime.d.ts +21 -0
  10. package/dist/jsx-dev-runtime.js +160 -0
  11. package/dist/jsx-dev-runtime.js.map +1 -0
  12. package/dist/jsx-dev-runtime.mjs +122 -0
  13. package/dist/jsx-dev-runtime.mjs.map +1 -0
  14. package/dist/jsx-runtime.d.mts +26 -0
  15. package/dist/jsx-runtime.d.ts +26 -0
  16. package/dist/jsx-runtime.js +150 -0
  17. package/dist/jsx-runtime.js.map +1 -0
  18. package/dist/jsx-runtime.mjs +109 -0
  19. package/dist/jsx-runtime.mjs.map +1 -0
  20. package/dist/server/index.d.mts +235 -0
  21. package/dist/server/index.d.ts +235 -0
  22. package/dist/server/index.js +642 -0
  23. package/dist/server/index.js.map +1 -0
  24. package/dist/server/index.mjs +597 -0
  25. package/dist/server/index.mjs.map +1 -0
  26. package/package.json +64 -0
  27. package/src/components/SidekickPanel.tsx +868 -0
  28. package/src/components/index.ts +1 -0
  29. package/src/context.tsx +157 -0
  30. package/src/flags.ts +47 -0
  31. package/src/index.ts +71 -0
  32. package/src/jsx-dev-runtime.ts +138 -0
  33. package/src/jsx-runtime.ts +159 -0
  34. package/src/loader.ts +35 -0
  35. package/src/primitives/behavior.ts +70 -0
  36. package/src/primitives/data.ts +91 -0
  37. package/src/primitives/index.ts +3 -0
  38. package/src/primitives/ui.ts +268 -0
  39. package/src/provider.tsx +1264 -0
  40. package/src/runtime-loader.ts +106 -0
  41. package/src/server/drizzle-adapter.ts +53 -0
  42. package/src/server/drizzle-schema.ts +16 -0
  43. package/src/server/generate.ts +578 -0
  44. package/src/server/handler.ts +343 -0
  45. package/src/server/index.ts +20 -0
  46. package/src/server/storage.ts +1 -0
  47. package/src/server/types.ts +49 -0
  48. package/src/types.ts +295 -0
package/dist/index.js ADDED
@@ -0,0 +1,2470 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ SidekickPanel: () => SidekickPanel,
34
+ SidekickProvider: () => SidekickProvider,
35
+ configureJsxRuntime: () => configureJsxRuntime,
36
+ createOverride: () => createOverride,
37
+ getFlag: () => getFlag,
38
+ getRegisteredOverrides: () => getRegisteredOverrides,
39
+ getSeenComponentsFromJsx: () => getSeenComponentsFromJsx,
40
+ isJsxRuntimeConfigured: () => isJsxRuntimeConfigured,
41
+ loadFlags: () => loadFlags,
42
+ onConfigChange: () => onConfigChange,
43
+ registerOverride: () => registerOverride,
44
+ saveFlags: () => saveFlags,
45
+ setFlag: () => setFlag,
46
+ toggleFlag: () => toggleFlag,
47
+ useActions: () => useActions,
48
+ useAddedColumns: () => useAddedColumns,
49
+ useColumnOrder: () => useColumnOrder,
50
+ useColumnRenames: () => useColumnRenames,
51
+ useComputedField: () => useComputedField,
52
+ useEventEmitter: () => useEventEmitter,
53
+ useFilter: () => useFilter,
54
+ useGroupByOptions: () => useGroupByOptions,
55
+ useHiddenColumns: () => useHiddenColumns,
56
+ useKeyboardShortcuts: () => useKeyboardShortcuts,
57
+ useMenuItems: () => useMenuItems,
58
+ usePropsModifier: () => usePropsModifier,
59
+ useSidekick: () => useSidekick,
60
+ useSidekickSafe: () => useSidekickSafe,
61
+ useSortOptions: () => useSortOptions,
62
+ useTabs: () => useTabs,
63
+ useValidations: () => useValidations
64
+ });
65
+ module.exports = __toCommonJS(index_exports);
66
+
67
+ // src/provider.tsx
68
+ var import_react5 = __toESM(require("react"));
69
+ var import_react_dom = require("react-dom");
70
+
71
+ // src/context.tsx
72
+ var import_react = require("react");
73
+ var SidekickContext = (0, import_react.createContext)(null);
74
+ function useSidekickSafe() {
75
+ return (0, import_react.useContext)(SidekickContext);
76
+ }
77
+ function useSidekick() {
78
+ const context = (0, import_react.useContext)(SidekickContext);
79
+ if (!context) {
80
+ throw new Error("useSidekick must be used within a SidekickProvider");
81
+ }
82
+ return context;
83
+ }
84
+ function useAddedColumns(tableId) {
85
+ const context = useSidekickSafe();
86
+ if (!context) return [];
87
+ return context.getColumns(tableId);
88
+ }
89
+ function useColumnRenames(tableId) {
90
+ const context = useSidekickSafe();
91
+ if (!context) return [];
92
+ return context.getColumnRenames(tableId);
93
+ }
94
+ function useHiddenColumns(tableId) {
95
+ const context = useSidekickSafe();
96
+ if (!context) return [];
97
+ return context.getHiddenColumns(tableId);
98
+ }
99
+ function useColumnOrder(tableId) {
100
+ const context = useSidekickSafe();
101
+ if (!context) return void 0;
102
+ return context.getColumnOrder(tableId);
103
+ }
104
+ function useMenuItems(menuId) {
105
+ const context = useSidekickSafe();
106
+ if (!context) return [];
107
+ return context.getMenuItems(menuId);
108
+ }
109
+ function useTabs(tabGroupId) {
110
+ const context = useSidekickSafe();
111
+ if (!context) return [];
112
+ return context.getTabs(tabGroupId);
113
+ }
114
+ function useActions(actionBarId) {
115
+ const context = useSidekickSafe();
116
+ if (!context) return [];
117
+ return context.getActions(actionBarId);
118
+ }
119
+ function useValidations(formId) {
120
+ const context = useSidekickSafe();
121
+ if (!context) return [];
122
+ return context.getValidations(formId);
123
+ }
124
+ function usePropsModifier(componentId, props) {
125
+ const context = useSidekickSafe();
126
+ if (!context) return props;
127
+ return context.applyPropsModifiers(componentId, props);
128
+ }
129
+ function useComputedField(fieldName, data) {
130
+ const context = useSidekickSafe();
131
+ if (!context) return void 0;
132
+ return context.getComputedValue(fieldName, data);
133
+ }
134
+ function useFilter(filterName, items) {
135
+ const context = useSidekickSafe();
136
+ if (!context) return items;
137
+ return context.applyFilters(filterName, items);
138
+ }
139
+ function useSortOptions(tableId) {
140
+ const context = useSidekickSafe();
141
+ if (!context) return [];
142
+ return context.getSortOptions(tableId);
143
+ }
144
+ function useGroupByOptions(tableId) {
145
+ const context = useSidekickSafe();
146
+ if (!context) return [];
147
+ return context.getGroupByOptions(tableId);
148
+ }
149
+ function useKeyboardShortcuts() {
150
+ const context = useSidekickSafe();
151
+ if (!context) return [];
152
+ return context.getKeyboardShortcuts();
153
+ }
154
+ function useEventEmitter() {
155
+ const context = useSidekickSafe();
156
+ if (!context) return () => {
157
+ };
158
+ return context.emitEvent;
159
+ }
160
+
161
+ // src/flags.ts
162
+ var STORAGE_KEY = "sidekick_flags";
163
+ function loadFlags() {
164
+ if (typeof window === "undefined") {
165
+ return {};
166
+ }
167
+ try {
168
+ const stored = localStorage.getItem(STORAGE_KEY);
169
+ return stored ? JSON.parse(stored) : {};
170
+ } catch {
171
+ return {};
172
+ }
173
+ }
174
+ function saveFlags(flags) {
175
+ if (typeof window === "undefined") {
176
+ return;
177
+ }
178
+ try {
179
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(flags));
180
+ } catch {
181
+ console.warn("[Sidekick] Failed to save flags to localStorage");
182
+ }
183
+ }
184
+ function getFlag(overrideId) {
185
+ const flags = loadFlags();
186
+ return flags[overrideId] ?? false;
187
+ }
188
+ function setFlag(overrideId, enabled) {
189
+ const flags = loadFlags();
190
+ flags[overrideId] = enabled;
191
+ saveFlags(flags);
192
+ }
193
+ function toggleFlag(overrideId) {
194
+ const current = getFlag(overrideId);
195
+ setFlag(overrideId, !current);
196
+ return !current;
197
+ }
198
+
199
+ // src/loader.ts
200
+ var overrideRegistry = /* @__PURE__ */ new Map();
201
+ function registerOverride(module2) {
202
+ overrideRegistry.set(module2.manifest.id, module2);
203
+ }
204
+ function getRegisteredOverrides() {
205
+ return Array.from(overrideRegistry.values());
206
+ }
207
+ function createOverride(manifest, activate) {
208
+ return { manifest, activate };
209
+ }
210
+
211
+ // src/primitives/ui.ts
212
+ function generateId() {
213
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
214
+ const r = Math.random() * 16 | 0;
215
+ const v = c === "x" ? r : r & 3 | 8;
216
+ return v.toString(16);
217
+ });
218
+ }
219
+ function createUIPrimitives(state, currentOverrideId) {
220
+ return {
221
+ wrap(componentName, wrapper, options = {}) {
222
+ const wrapped = {
223
+ id: generateId(),
224
+ overrideId: currentOverrideId,
225
+ wrapper,
226
+ priority: options.priority ?? 0,
227
+ where: options.where
228
+ };
229
+ const existing = state.wrappers.get(componentName) ?? [];
230
+ existing.push(wrapped);
231
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
232
+ state.wrappers.set(componentName, existing);
233
+ },
234
+ replace(componentName, replacement) {
235
+ state.replacements.set(componentName, replacement);
236
+ },
237
+ addStyles(css) {
238
+ const styles2 = {
239
+ id: generateId(),
240
+ overrideId: currentOverrideId,
241
+ css
242
+ };
243
+ state.styles.push(styles2);
244
+ },
245
+ addColumn(tableId, config) {
246
+ const column = {
247
+ id: generateId(),
248
+ overrideId: currentOverrideId,
249
+ tableId,
250
+ ...config
251
+ };
252
+ const existing = state.columns.get(tableId) ?? [];
253
+ existing.push(column);
254
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
255
+ state.columns.set(tableId, existing);
256
+ },
257
+ renameColumn(tableId, originalHeader, newHeader) {
258
+ const rename = {
259
+ id: generateId(),
260
+ overrideId: currentOverrideId,
261
+ tableId,
262
+ originalHeader,
263
+ newHeader
264
+ };
265
+ const existing = state.columnRenames.get(tableId) ?? [];
266
+ existing.push(rename);
267
+ state.columnRenames.set(tableId, existing);
268
+ },
269
+ hideColumn(tableId, header) {
270
+ const hidden = {
271
+ id: generateId(),
272
+ overrideId: currentOverrideId,
273
+ tableId,
274
+ header
275
+ };
276
+ const existing = state.hiddenColumns.get(tableId) ?? [];
277
+ existing.push(hidden);
278
+ state.hiddenColumns.set(tableId, existing);
279
+ },
280
+ reorderColumns(tableId, order) {
281
+ const columnOrder = {
282
+ id: generateId(),
283
+ overrideId: currentOverrideId,
284
+ tableId,
285
+ order
286
+ };
287
+ state.columnOrders.set(tableId, columnOrder);
288
+ },
289
+ filterRows(tableId, filter) {
290
+ const rowFilter = {
291
+ id: generateId(),
292
+ overrideId: currentOverrideId,
293
+ tableId,
294
+ filter
295
+ };
296
+ const existing = state.rowFilters.get(tableId) ?? [];
297
+ existing.push(rowFilter);
298
+ state.rowFilters.set(tableId, existing);
299
+ },
300
+ addMenuItem(menuId, config) {
301
+ const item = {
302
+ id: generateId(),
303
+ overrideId: currentOverrideId,
304
+ menuId,
305
+ ...config
306
+ };
307
+ const existing = state.menuItems.get(menuId) ?? [];
308
+ existing.push(item);
309
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
310
+ state.menuItems.set(menuId, existing);
311
+ },
312
+ addTab(tabGroupId, config) {
313
+ const tab = {
314
+ id: generateId(),
315
+ overrideId: currentOverrideId,
316
+ tabGroupId,
317
+ ...config
318
+ };
319
+ const existing = state.tabs.get(tabGroupId) ?? [];
320
+ existing.push(tab);
321
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
322
+ state.tabs.set(tabGroupId, existing);
323
+ },
324
+ modifyProps(componentId, modifier) {
325
+ const propsModifier = {
326
+ id: generateId(),
327
+ overrideId: currentOverrideId,
328
+ componentId,
329
+ modifier
330
+ };
331
+ const existing = state.propsModifiers.get(componentId) ?? [];
332
+ existing.push(propsModifier);
333
+ state.propsModifiers.set(componentId, existing);
334
+ },
335
+ addAction(actionBarId, config) {
336
+ const action = {
337
+ id: generateId(),
338
+ overrideId: currentOverrideId,
339
+ actionBarId,
340
+ ...config
341
+ };
342
+ const existing = state.actions.get(actionBarId) ?? [];
343
+ existing.push(action);
344
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
345
+ state.actions.set(actionBarId, existing);
346
+ },
347
+ addValidation(formId, fieldName, validate) {
348
+ const rule = {
349
+ id: generateId(),
350
+ overrideId: currentOverrideId,
351
+ formId,
352
+ fieldName,
353
+ validate
354
+ };
355
+ const existing = state.validations.get(formId) ?? [];
356
+ existing.push(rule);
357
+ state.validations.set(formId, existing);
358
+ },
359
+ setText(selector, text) {
360
+ if (typeof text !== "string") {
361
+ console.warn(`[Sidekick] setText expects a string value, got ${typeof text}. Ignoring.`);
362
+ return;
363
+ }
364
+ const mod = {
365
+ id: generateId(),
366
+ overrideId: currentOverrideId,
367
+ selector,
368
+ type: "setText",
369
+ value: text
370
+ };
371
+ state.domModifications.push(mod);
372
+ },
373
+ setAttribute(selector, attr, value) {
374
+ const mod = {
375
+ id: generateId(),
376
+ overrideId: currentOverrideId,
377
+ selector,
378
+ type: "setAttribute",
379
+ value: { attr, value }
380
+ };
381
+ state.domModifications.push(mod);
382
+ },
383
+ setStyle(selector, styles2) {
384
+ const mod = {
385
+ id: generateId(),
386
+ overrideId: currentOverrideId,
387
+ selector,
388
+ type: "setStyle",
389
+ value: styles2
390
+ };
391
+ state.domModifications.push(mod);
392
+ },
393
+ addClass(selector, className) {
394
+ const mod = {
395
+ id: generateId(),
396
+ overrideId: currentOverrideId,
397
+ selector,
398
+ type: "addClass",
399
+ value: className
400
+ };
401
+ state.domModifications.push(mod);
402
+ },
403
+ removeClass(selector, className) {
404
+ const mod = {
405
+ id: generateId(),
406
+ overrideId: currentOverrideId,
407
+ selector,
408
+ type: "removeClass",
409
+ value: className
410
+ };
411
+ state.domModifications.push(mod);
412
+ },
413
+ inject(selector, component, position = "after") {
414
+ const injection = {
415
+ id: generateId(),
416
+ overrideId: currentOverrideId,
417
+ selector,
418
+ position,
419
+ component
420
+ };
421
+ state.injections.push(injection);
422
+ }
423
+ };
424
+ }
425
+
426
+ // src/primitives/data.ts
427
+ function generateId2() {
428
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
429
+ const r = Math.random() * 16 | 0;
430
+ const v = c === "x" ? r : r & 3 | 8;
431
+ return v.toString(16);
432
+ });
433
+ }
434
+ function createDataPrimitives(state, currentOverrideId) {
435
+ return {
436
+ computed(fieldName, compute) {
437
+ const field = {
438
+ id: generateId2(),
439
+ overrideId: currentOverrideId,
440
+ fieldName,
441
+ compute
442
+ };
443
+ state.computedFields.set(fieldName, field);
444
+ },
445
+ addFilter(name, filter) {
446
+ const dataFilter = {
447
+ id: generateId2(),
448
+ overrideId: currentOverrideId,
449
+ name,
450
+ filter
451
+ };
452
+ state.filters.set(name, dataFilter);
453
+ },
454
+ transform(dataKey, transformFn) {
455
+ const transform2 = {
456
+ id: generateId2(),
457
+ overrideId: currentOverrideId,
458
+ dataKey,
459
+ transform: transformFn
460
+ };
461
+ state.transforms.set(dataKey, transform2);
462
+ },
463
+ intercept(pathPattern, handler) {
464
+ const interceptor = {
465
+ id: generateId2(),
466
+ overrideId: currentOverrideId,
467
+ pathPattern,
468
+ handler
469
+ };
470
+ state.interceptors.push(interceptor);
471
+ },
472
+ addSortOption(tableId, config) {
473
+ const sortOption = {
474
+ id: generateId2(),
475
+ overrideId: currentOverrideId,
476
+ tableId,
477
+ ...config
478
+ };
479
+ const existing = state.sortOptions.get(tableId) ?? [];
480
+ existing.push(sortOption);
481
+ state.sortOptions.set(tableId, existing);
482
+ },
483
+ addGroupBy(tableId, config) {
484
+ const groupByOption = {
485
+ id: generateId2(),
486
+ overrideId: currentOverrideId,
487
+ tableId,
488
+ ...config
489
+ };
490
+ const existing = state.groupByOptions.get(tableId) ?? [];
491
+ existing.push(groupByOption);
492
+ state.groupByOptions.set(tableId, existing);
493
+ }
494
+ };
495
+ }
496
+
497
+ // src/primitives/behavior.ts
498
+ function generateId3() {
499
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
500
+ const r = Math.random() * 16 | 0;
501
+ const v = c === "x" ? r : r & 3 | 8;
502
+ return v.toString(16);
503
+ });
504
+ }
505
+ function createBehaviorPrimitives(state, currentOverrideId) {
506
+ return {
507
+ onEvent(eventName, handler, options = {}) {
508
+ const eventHandler = {
509
+ id: generateId3(),
510
+ overrideId: currentOverrideId,
511
+ eventName,
512
+ handler,
513
+ priority: options.priority ?? 0
514
+ };
515
+ const existing = state.eventHandlers.get(eventName) ?? [];
516
+ existing.push(eventHandler);
517
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
518
+ state.eventHandlers.set(eventName, existing);
519
+ },
520
+ addKeyboardShortcut(keys, action, description) {
521
+ const shortcut = {
522
+ id: generateId3(),
523
+ overrideId: currentOverrideId,
524
+ keys,
525
+ action,
526
+ description
527
+ };
528
+ state.keyboardShortcuts.push(shortcut);
529
+ },
530
+ modifyRoute(pathPattern, handler) {
531
+ const modifier = {
532
+ id: generateId3(),
533
+ overrideId: currentOverrideId,
534
+ pathPattern,
535
+ handler
536
+ };
537
+ state.routeModifiers.push(modifier);
538
+ },
539
+ onDOMEvent(selector, eventType, handler) {
540
+ const listener = {
541
+ id: generateId3(),
542
+ overrideId: currentOverrideId,
543
+ selector,
544
+ eventType,
545
+ handler
546
+ };
547
+ state.domEventListeners.push(listener);
548
+ }
549
+ };
550
+ }
551
+
552
+ // src/runtime-loader.ts
553
+ var import_react2 = __toESM(require("react"));
554
+ var import_sucrase = require("sucrase");
555
+ function compileOverride(overrideData) {
556
+ try {
557
+ const transformed = (0, import_sucrase.transform)(overrideData.code, {
558
+ transforms: ["typescript", "jsx"],
559
+ jsxRuntime: "classic"
560
+ });
561
+ const exports2 = {};
562
+ const require2 = (moduleName) => {
563
+ if (moduleName === "react") return import_react2.default;
564
+ if (moduleName === "@usesidekick/react") {
565
+ return { createOverride, SDK: {} };
566
+ }
567
+ throw new Error(`Module not found: ${moduleName}`);
568
+ };
569
+ const reactDestructure = "var { useState, useEffect, useCallback, useMemo, useRef, useContext, useReducer, memo, forwardRef, createContext, Fragment } = React;\n";
570
+ const moduleFunction = new Function(
571
+ "exports",
572
+ "require",
573
+ "React",
574
+ "createOverride",
575
+ reactDestructure + transformed.code.replace(
576
+ /import\s+.*?from\s+['"].*?['"]/g,
577
+ ""
578
+ // Remove import statements, we inject dependencies
579
+ ).replace(
580
+ /export\s+default\s+/,
581
+ "exports.default = "
582
+ )
583
+ );
584
+ moduleFunction(exports2, require2, import_react2.default, createOverride);
585
+ if (!exports2.default) {
586
+ console.error(`[Sidekick] Override ${overrideData.id} has no default export`);
587
+ return null;
588
+ }
589
+ return {
590
+ id: overrideData.id,
591
+ name: overrideData.name,
592
+ description: overrideData.description,
593
+ enabled: overrideData.enabled,
594
+ activate: exports2.default.activate
595
+ };
596
+ } catch (error) {
597
+ console.error(`[Sidekick] Failed to compile override ${overrideData.id}:`, error);
598
+ return null;
599
+ }
600
+ }
601
+ async function fetchAndCompileOverrides(endpoint) {
602
+ try {
603
+ const response = await fetch(endpoint);
604
+ if (!response.ok) {
605
+ throw new Error(`Failed to fetch overrides: ${response.status}`);
606
+ }
607
+ const data = await response.json();
608
+ if (!data.success || !Array.isArray(data.overrides)) {
609
+ throw new Error("Invalid response format");
610
+ }
611
+ const compiled = [];
612
+ for (const override of data.overrides) {
613
+ const loaded = compileOverride(override);
614
+ if (loaded) {
615
+ compiled.push(loaded);
616
+ }
617
+ }
618
+ return compiled;
619
+ } catch (error) {
620
+ console.error("[Sidekick] Failed to fetch overrides:", error);
621
+ return [];
622
+ }
623
+ }
624
+
625
+ // src/jsx-runtime.ts
626
+ var import_react3 = __toESM(require("react"));
627
+ var GLOBAL_KEY = "__SIDEKICK_JSX_CONFIG__";
628
+ function getGlobalConfig() {
629
+ const g = globalThis;
630
+ if (!g[GLOBAL_KEY]) {
631
+ g[GLOBAL_KEY] = {
632
+ getWrapper: null,
633
+ getReplacement: null,
634
+ listeners: /* @__PURE__ */ new Set(),
635
+ seenComponents: /* @__PURE__ */ new Set()
636
+ };
637
+ }
638
+ return g[GLOBAL_KEY];
639
+ }
640
+ var getDebug = () => typeof window !== "undefined" && window.__SIDEKICK_DEBUG__;
641
+ var Fragment = import_react3.default.Fragment;
642
+ function configureJsxRuntime(wrapperGetter, replacementGetter) {
643
+ const config = getGlobalConfig();
644
+ config.getWrapper = wrapperGetter;
645
+ config.getReplacement = replacementGetter;
646
+ if (getDebug()) console.log("[Sidekick] JSX runtime configured (global)");
647
+ config.listeners.forEach((listener) => {
648
+ try {
649
+ listener();
650
+ } catch (e) {
651
+ console.error("[Sidekick] Config change listener error:", e);
652
+ }
653
+ });
654
+ }
655
+ function onConfigChange(listener) {
656
+ const config = getGlobalConfig();
657
+ config.listeners.add(listener);
658
+ return () => config.listeners.delete(listener);
659
+ }
660
+ function isJsxRuntimeConfigured() {
661
+ const config = getGlobalConfig();
662
+ return config.getWrapper !== null || config.getReplacement !== null;
663
+ }
664
+ function getSeenComponentsFromJsx() {
665
+ const config = getGlobalConfig();
666
+ return Array.from(config.seenComponents);
667
+ }
668
+
669
+ // src/jsx-dev-runtime.ts
670
+ var import_react4 = __toESM(require("react"));
671
+ var GLOBAL_KEY2 = "__SIDEKICK_JSX_CONFIG__";
672
+ function getGlobalConfig2() {
673
+ const g = globalThis;
674
+ if (!g[GLOBAL_KEY2]) {
675
+ g[GLOBAL_KEY2] = {
676
+ getWrapper: null,
677
+ getReplacement: null,
678
+ listeners: /* @__PURE__ */ new Set(),
679
+ seenComponents: /* @__PURE__ */ new Set()
680
+ };
681
+ }
682
+ return g[GLOBAL_KEY2];
683
+ }
684
+ var getDebug2 = () => typeof window !== "undefined" && window.__SIDEKICK_DEBUG__;
685
+ var Fragment2 = import_react4.default.Fragment;
686
+ function configureJsxDevRuntime(wrapperGetter, replacementGetter) {
687
+ const config = getGlobalConfig2();
688
+ config.getWrapper = wrapperGetter;
689
+ config.getReplacement = replacementGetter;
690
+ configureJsxRuntime(wrapperGetter, replacementGetter);
691
+ if (getDebug2()) console.log("[Sidekick] JSX dev runtime configured (global)");
692
+ }
693
+
694
+ // src/provider.tsx
695
+ var import_jsx_runtime3 = require("react/jsx-runtime");
696
+ function tableIdToComponentName(tableId) {
697
+ return tableId.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
698
+ }
699
+ function createAutoColumnWrapper(columns, renames, columnOrder, hiddenColumns, rowFilters) {
700
+ return (Original) => {
701
+ function AutoColumnInjector(props) {
702
+ const containerRef = (0, import_react5.useRef)(null);
703
+ const [cellTargets, setCellTargets] = (0, import_react5.useState)([]);
704
+ const allTasks = props.tasks || [];
705
+ const tasks = (0, import_react5.useMemo)(() => {
706
+ if (!rowFilters || rowFilters.length === 0) return allTasks;
707
+ return allTasks.filter(
708
+ (row) => rowFilters.every((rf) => rf.filter(row))
709
+ );
710
+ }, [allTasks]);
711
+ (0, import_react5.useEffect)(() => {
712
+ const container = containerRef.current;
713
+ if (!container) return;
714
+ const table = container.querySelector("table");
715
+ if (!table) return;
716
+ table.querySelectorAll("[data-sidekick-injected]").forEach((el) => el.remove());
717
+ table.querySelectorAll("[data-sidekick-hidden]").forEach((el) => {
718
+ el.style.display = "";
719
+ el.removeAttribute("data-sidekick-hidden");
720
+ });
721
+ if (renames.length > 0) {
722
+ const headers = table.querySelectorAll("thead th");
723
+ headers.forEach((th) => {
724
+ const text = th.textContent?.trim();
725
+ if (text) {
726
+ const rename = renames.find((r) => r.originalHeader === text);
727
+ if (rename) {
728
+ th.textContent = rename.newHeader;
729
+ }
730
+ }
731
+ });
732
+ }
733
+ if (columnOrder) {
734
+ const headerRow2 = table.querySelector("thead tr");
735
+ if (headerRow2) {
736
+ const ths = Array.from(headerRow2.querySelectorAll("th"));
737
+ const headerToIndex = /* @__PURE__ */ new Map();
738
+ ths.forEach((th, i) => {
739
+ const text = th.textContent?.trim() ?? "";
740
+ headerToIndex.set(text, i);
741
+ });
742
+ const orderedIndices = [];
743
+ const usedIndices = /* @__PURE__ */ new Set();
744
+ for (const headerName of columnOrder.order) {
745
+ const idx = headerToIndex.get(headerName);
746
+ if (idx !== void 0) {
747
+ orderedIndices.push(idx);
748
+ usedIndices.add(idx);
749
+ }
750
+ }
751
+ for (let i = 0; i < ths.length; i++) {
752
+ if (!usedIndices.has(i)) {
753
+ orderedIndices.push(i);
754
+ }
755
+ }
756
+ const sortedThs = orderedIndices.map((i) => ths[i]);
757
+ for (const th of sortedThs) {
758
+ headerRow2.appendChild(th);
759
+ }
760
+ const bodyRows2 = table.querySelectorAll("tbody tr");
761
+ bodyRows2.forEach((row) => {
762
+ const tds = Array.from(row.querySelectorAll("td"));
763
+ const sortedTds = orderedIndices.map((i) => tds[i]).filter(Boolean);
764
+ for (const td of sortedTds) {
765
+ row.appendChild(td);
766
+ }
767
+ });
768
+ }
769
+ }
770
+ if (hiddenColumns && hiddenColumns.length > 0) {
771
+ const headers = table.querySelectorAll("thead th");
772
+ const hiddenHeaders = new Set(hiddenColumns.map((h) => h.header));
773
+ const hiddenIndices = /* @__PURE__ */ new Set();
774
+ headers.forEach((th, i) => {
775
+ const text = th.textContent?.trim() ?? "";
776
+ if (hiddenHeaders.has(text)) {
777
+ th.style.display = "none";
778
+ th.setAttribute("data-sidekick-hidden", "true");
779
+ hiddenIndices.add(i);
780
+ }
781
+ });
782
+ if (hiddenIndices.size > 0) {
783
+ const bodyRows2 = table.querySelectorAll("tbody tr");
784
+ bodyRows2.forEach((row) => {
785
+ const tds = row.querySelectorAll("td");
786
+ tds.forEach((td, i) => {
787
+ if (hiddenIndices.has(i)) {
788
+ td.style.display = "none";
789
+ td.setAttribute("data-sidekick-hidden", "true");
790
+ }
791
+ });
792
+ });
793
+ }
794
+ }
795
+ const headerRow = table.querySelector("thead tr");
796
+ if (headerRow) {
797
+ for (const col of columns) {
798
+ const th = document.createElement("th");
799
+ th.className = "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider";
800
+ th.textContent = col.header;
801
+ th.setAttribute("data-sidekick-injected", "true");
802
+ headerRow.appendChild(th);
803
+ }
804
+ }
805
+ const bodyRows = table.querySelectorAll("tbody tr");
806
+ const targets = [];
807
+ bodyRows.forEach((row, rowIndex) => {
808
+ for (let colIndex = 0; colIndex < columns.length; colIndex++) {
809
+ const td = document.createElement("td");
810
+ td.className = "px-6 py-4 whitespace-nowrap text-sm text-gray-500";
811
+ td.setAttribute("data-sidekick-injected", "true");
812
+ row.appendChild(td);
813
+ targets.push({ element: td, taskIndex: rowIndex, colIndex });
814
+ }
815
+ });
816
+ setCellTargets(targets);
817
+ return () => {
818
+ table.querySelectorAll("[data-sidekick-injected]").forEach((el) => el.remove());
819
+ table.querySelectorAll("[data-sidekick-hidden]").forEach((el) => {
820
+ el.style.display = "";
821
+ el.removeAttribute("data-sidekick-hidden");
822
+ });
823
+ setCellTargets([]);
824
+ };
825
+ }, [tasks]);
826
+ const filteredProps = rowFilters && rowFilters.length > 0 ? { ...props, tasks } : props;
827
+ return import_react5.default.createElement(
828
+ import_react5.default.Fragment,
829
+ null,
830
+ import_react5.default.createElement(
831
+ "div",
832
+ { ref: containerRef },
833
+ import_react5.default.createElement(Original, filteredProps)
834
+ ),
835
+ ...cellTargets.map((target, idx) => {
836
+ const task = tasks[target.taskIndex];
837
+ const col = columns[target.colIndex];
838
+ if (!task || !col) return null;
839
+ const accessor = col.accessor;
840
+ const value = typeof accessor === "function" ? accessor(task) : task[accessor];
841
+ const content = col.render ? col.render(value, task) : import_react5.default.createElement("span", null, String(value ?? "-"));
842
+ return (0, import_react_dom.createPortal)(content, target.element, `sidekick-col-${idx}`);
843
+ })
844
+ );
845
+ }
846
+ AutoColumnInjector.displayName = `AutoColumnInjector(${Original.displayName || Original.name || "Component"})`;
847
+ return AutoColumnInjector;
848
+ };
849
+ }
850
+ function getComponentName(type) {
851
+ if (!type) return null;
852
+ if (typeof type === "function") {
853
+ const fn = type;
854
+ return fn.displayName || fn.name || null;
855
+ }
856
+ if (typeof type === "object" && type !== null) {
857
+ const obj = type;
858
+ if (obj.displayName) return obj.displayName;
859
+ if (obj.$$typeof?.toString() === "Symbol(react.lazy)") {
860
+ const payload = obj._payload;
861
+ if (payload && payload.status === "fulfilled" && payload.value) {
862
+ return getComponentName(payload.value);
863
+ }
864
+ }
865
+ if (obj.$$typeof) {
866
+ if (obj.type) return getComponentName(obj.type);
867
+ if (obj.render) return getComponentName(obj.render);
868
+ }
869
+ }
870
+ return null;
871
+ }
872
+ function transformElementTree(node, wrappers, replacements, wrapCache) {
873
+ if (node == null || typeof node === "boolean" || typeof node === "string" || typeof node === "number") {
874
+ return node;
875
+ }
876
+ if (Array.isArray(node)) {
877
+ let changed = false;
878
+ const result = node.map((child) => {
879
+ const transformed = transformElementTree(child, wrappers, replacements, wrapCache);
880
+ if (transformed !== child) changed = true;
881
+ return transformed;
882
+ });
883
+ return changed ? result : node;
884
+ }
885
+ if (!import_react5.default.isValidElement(node)) return node;
886
+ const element = node;
887
+ const originalType = element.type;
888
+ let newType = originalType;
889
+ let typeChanged = false;
890
+ if (typeof originalType === "function" || typeof originalType === "object" && originalType !== null) {
891
+ const name = getComponentName(originalType);
892
+ if (name) {
893
+ let resolvedType = originalType;
894
+ const maybeObj = originalType;
895
+ if (maybeObj.$$typeof?.toString() === "Symbol(react.lazy)" && maybeObj._payload?.status === "fulfilled" && maybeObj._payload?.value) {
896
+ resolvedType = maybeObj._payload.value;
897
+ }
898
+ const replacement = replacements.get(name);
899
+ if (replacement) {
900
+ newType = replacement;
901
+ typeChanged = true;
902
+ } else {
903
+ const componentWrappers = wrappers.get(name);
904
+ if (componentWrappers && componentWrappers.length > 0) {
905
+ if (!wrapCache.has(resolvedType)) {
906
+ const wrapped = componentWrappers.reduce(
907
+ (comp, { wrapper, where: wherePredicate }) => {
908
+ if (wherePredicate) {
909
+ const Wrapped = wrapper(comp);
910
+ const ConditionalWrapper = (props) => {
911
+ if (wherePredicate(props)) {
912
+ return import_react5.default.createElement(Wrapped, props);
913
+ }
914
+ return import_react5.default.createElement(comp, props);
915
+ };
916
+ ConditionalWrapper.displayName = `ConditionalWrap(${comp.displayName || comp.name || "Component"})`;
917
+ return ConditionalWrapper;
918
+ }
919
+ return wrapper(comp);
920
+ },
921
+ resolvedType
922
+ );
923
+ wrapCache.set(resolvedType, wrapped);
924
+ }
925
+ newType = wrapCache.get(resolvedType);
926
+ typeChanged = true;
927
+ }
928
+ }
929
+ }
930
+ }
931
+ const childrenProp = element.props.children;
932
+ const transformedChildren = childrenProp != null ? transformElementTree(childrenProp, wrappers, replacements, wrapCache) : childrenProp;
933
+ const childrenChanged = transformedChildren !== childrenProp;
934
+ if (!typeChanged && !childrenChanged) return node;
935
+ const { children: _children, ...restProps } = element.props;
936
+ return import_react5.default.createElement(
937
+ newType,
938
+ { ...restProps, key: element.key },
939
+ transformedChildren
940
+ );
941
+ }
942
+ function createInitialState() {
943
+ return {
944
+ overrides: [],
945
+ // UI state
946
+ wrappers: /* @__PURE__ */ new Map(),
947
+ replacements: /* @__PURE__ */ new Map(),
948
+ styles: [],
949
+ columns: /* @__PURE__ */ new Map(),
950
+ columnRenames: /* @__PURE__ */ new Map(),
951
+ hiddenColumns: /* @__PURE__ */ new Map(),
952
+ columnOrders: /* @__PURE__ */ new Map(),
953
+ rowFilters: /* @__PURE__ */ new Map(),
954
+ menuItems: /* @__PURE__ */ new Map(),
955
+ tabs: /* @__PURE__ */ new Map(),
956
+ propsModifiers: /* @__PURE__ */ new Map(),
957
+ actions: /* @__PURE__ */ new Map(),
958
+ validations: /* @__PURE__ */ new Map(),
959
+ // Data state
960
+ computedFields: /* @__PURE__ */ new Map(),
961
+ filters: /* @__PURE__ */ new Map(),
962
+ transforms: /* @__PURE__ */ new Map(),
963
+ interceptors: [],
964
+ sortOptions: /* @__PURE__ */ new Map(),
965
+ groupByOptions: /* @__PURE__ */ new Map(),
966
+ // Behavior state
967
+ eventHandlers: /* @__PURE__ */ new Map(),
968
+ keyboardShortcuts: [],
969
+ routeModifiers: [],
970
+ // DOM state
971
+ domModifications: [],
972
+ injections: [],
973
+ domEventListeners: []
974
+ };
975
+ }
976
+ function SidekickProvider({ children, overridesEndpoint }) {
977
+ const [state, setState] = (0, import_react5.useState)(createInitialState);
978
+ const [overrides, setOverrides] = (0, import_react5.useState)([]);
979
+ const [isReady, setIsReady] = (0, import_react5.useState)(false);
980
+ const stateRef = (0, import_react5.useRef)(state);
981
+ stateRef.current = state;
982
+ (0, import_react5.useEffect)(() => {
983
+ const initializeOverrides = async () => {
984
+ const newState = createInitialState();
985
+ const loadedOverrides = [];
986
+ if (overridesEndpoint) {
987
+ console.log("[Sidekick] Fetching overrides from:", overridesEndpoint);
988
+ const apiOverrides = await fetchAndCompileOverrides(overridesEndpoint);
989
+ console.log("[Sidekick] Fetched overrides:", apiOverrides.length);
990
+ for (const override of apiOverrides) {
991
+ loadedOverrides.push({
992
+ id: override.id,
993
+ name: override.name,
994
+ description: override.description,
995
+ version: "1.0.0",
996
+ enabled: override.enabled
997
+ });
998
+ if (override.enabled) {
999
+ console.log(`[Sidekick] Activating override: ${override.id}`);
1000
+ const sdk = {
1001
+ ui: createUIPrimitives(newState, override.id),
1002
+ data: createDataPrimitives(newState, override.id),
1003
+ behavior: createBehaviorPrimitives(newState, override.id)
1004
+ };
1005
+ try {
1006
+ override.activate(sdk);
1007
+ console.log(`[Sidekick] Activated override: ${override.id}`);
1008
+ } catch (error) {
1009
+ console.error(`[Sidekick] Failed to activate override ${override.id}:`, error);
1010
+ }
1011
+ }
1012
+ }
1013
+ } else {
1014
+ const registeredOverrides = getRegisteredOverrides();
1015
+ const flags = loadFlags();
1016
+ for (const module2 of registeredOverrides) {
1017
+ loadedOverrides.push({
1018
+ id: module2.manifest.id,
1019
+ name: module2.manifest.name,
1020
+ description: module2.manifest.description,
1021
+ version: module2.manifest.version,
1022
+ enabled: flags[module2.manifest.id] ?? false
1023
+ });
1024
+ }
1025
+ for (const module2 of registeredOverrides) {
1026
+ const isEnabled = flags[module2.manifest.id] ?? false;
1027
+ if (isEnabled) {
1028
+ console.log(`[Sidekick] Activating override: ${module2.manifest.id}`);
1029
+ const sdk = {
1030
+ ui: createUIPrimitives(newState, module2.manifest.id),
1031
+ data: createDataPrimitives(newState, module2.manifest.id),
1032
+ behavior: createBehaviorPrimitives(newState, module2.manifest.id)
1033
+ };
1034
+ await module2.activate(sdk);
1035
+ console.log(`[Sidekick] After activation, wrappers:`, Array.from(newState.wrappers.keys()));
1036
+ }
1037
+ }
1038
+ }
1039
+ newState.overrides = loadedOverrides;
1040
+ const tableIdsWithMods = /* @__PURE__ */ new Set();
1041
+ for (const tableId of newState.columns.keys()) tableIdsWithMods.add(tableId);
1042
+ for (const tableId of newState.columnRenames.keys()) tableIdsWithMods.add(tableId);
1043
+ for (const tableId of newState.columnOrders.keys()) tableIdsWithMods.add(tableId);
1044
+ for (const tableId of newState.hiddenColumns.keys()) tableIdsWithMods.add(tableId);
1045
+ for (const tableId of newState.rowFilters.keys()) tableIdsWithMods.add(tableId);
1046
+ for (const tableId of tableIdsWithMods) {
1047
+ const cols = newState.columns.get(tableId) ?? [];
1048
+ const tableRenames = newState.columnRenames.get(tableId) ?? [];
1049
+ const tableOrder = newState.columnOrders.get(tableId);
1050
+ const tableHidden = newState.hiddenColumns.get(tableId) ?? [];
1051
+ const tableRowFilters = newState.rowFilters.get(tableId) ?? [];
1052
+ if (cols.length === 0 && tableRenames.length === 0 && !tableOrder && tableHidden.length === 0 && tableRowFilters.length === 0) continue;
1053
+ const componentName = tableIdToComponentName(tableId);
1054
+ console.log(`[Sidekick] Auto-wrapping ${componentName} with ${cols.length} added columns, ${tableRenames.length} renames, ${tableOrder ? "reorder" : "no reorder"}, ${tableHidden.length} hidden, ${tableRowFilters.length} row filters`);
1055
+ const wrapped = {
1056
+ id: `auto-columns-${tableId}`,
1057
+ overrideId: "__sidekick-internal__",
1058
+ wrapper: createAutoColumnWrapper(cols, tableRenames, tableOrder, tableHidden, tableRowFilters),
1059
+ priority: -1e3
1060
+ // Low priority - runs after user wrappers
1061
+ };
1062
+ const existing = newState.wrappers.get(componentName) ?? [];
1063
+ existing.push(wrapped);
1064
+ existing.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
1065
+ newState.wrappers.set(componentName, existing);
1066
+ }
1067
+ setState(newState);
1068
+ stateRef.current = newState;
1069
+ setOverrides(loadedOverrides);
1070
+ const wrapperGetter = (name) => {
1071
+ const wrappers = stateRef.current.wrappers.get(name);
1072
+ if (!wrappers || wrappers.length === 0) return void 0;
1073
+ return (Component) => {
1074
+ return wrappers.reduce(
1075
+ (wrapped, { wrapper, where: wherePredicate }) => {
1076
+ if (wherePredicate) {
1077
+ const Wrapped = wrapper(wrapped);
1078
+ const ConditionalWrapper = (props) => {
1079
+ if (wherePredicate(props)) {
1080
+ return import_react5.default.createElement(Wrapped, props);
1081
+ }
1082
+ return import_react5.default.createElement(wrapped, props);
1083
+ };
1084
+ ConditionalWrapper.displayName = `ConditionalWrap(${wrapped.displayName || wrapped.name || "Component"})`;
1085
+ return ConditionalWrapper;
1086
+ }
1087
+ return wrapper(wrapped);
1088
+ },
1089
+ Component
1090
+ );
1091
+ };
1092
+ };
1093
+ const replacementGetter = (name) => {
1094
+ return stateRef.current.replacements.get(name);
1095
+ };
1096
+ console.log("[Sidekick] Configuring JSX runtime with", newState.wrappers.size, "wrappers,", newState.replacements.size, "replacements,", newState.columns.size, "column sets");
1097
+ configureJsxRuntime(wrapperGetter, replacementGetter);
1098
+ configureJsxDevRuntime(wrapperGetter, replacementGetter);
1099
+ console.log("[Sidekick] JSX runtime configured");
1100
+ setIsReady(true);
1101
+ };
1102
+ initializeOverrides();
1103
+ }, [overridesEndpoint]);
1104
+ (0, import_react5.useEffect)(() => {
1105
+ if (!isReady || typeof document === "undefined") return;
1106
+ const styleId = "sidekick-injected-styles";
1107
+ let styleEl = document.getElementById(styleId);
1108
+ if (!styleEl) {
1109
+ styleEl = document.createElement("style");
1110
+ styleEl.id = styleId;
1111
+ document.head.appendChild(styleEl);
1112
+ }
1113
+ styleEl.textContent = state.styles.map((s) => s.css).join("\n");
1114
+ return () => {
1115
+ if (styleEl && styleEl.parentNode) {
1116
+ styleEl.parentNode.removeChild(styleEl);
1117
+ }
1118
+ };
1119
+ }, [state.styles, isReady]);
1120
+ (0, import_react5.useEffect)(() => {
1121
+ if (!isReady) return;
1122
+ const wrapperGetter = (name) => {
1123
+ const wrappers = state.wrappers.get(name);
1124
+ if (!wrappers || wrappers.length === 0) return void 0;
1125
+ return (Component) => {
1126
+ return wrappers.reduce(
1127
+ (wrapped, { wrapper, where: wherePredicate }) => {
1128
+ if (wherePredicate) {
1129
+ const Wrapped = wrapper(wrapped);
1130
+ const ConditionalWrapper = (props) => {
1131
+ if (wherePredicate(props)) {
1132
+ return import_react5.default.createElement(Wrapped, props);
1133
+ }
1134
+ return import_react5.default.createElement(wrapped, props);
1135
+ };
1136
+ ConditionalWrapper.displayName = `ConditionalWrap(${wrapped.displayName || wrapped.name || "Component"})`;
1137
+ return ConditionalWrapper;
1138
+ }
1139
+ return wrapper(wrapped);
1140
+ },
1141
+ Component
1142
+ );
1143
+ };
1144
+ };
1145
+ const replacementGetter = (name) => {
1146
+ return state.replacements.get(name);
1147
+ };
1148
+ configureJsxRuntime(wrapperGetter, replacementGetter);
1149
+ configureJsxDevRuntime(wrapperGetter, replacementGetter);
1150
+ }, [state.wrappers, state.replacements, isReady]);
1151
+ (0, import_react5.useEffect)(() => {
1152
+ if (!isReady || typeof document === "undefined" || state.domModifications.length === 0) return;
1153
+ const originals = /* @__PURE__ */ new Map();
1154
+ function applyModifications() {
1155
+ for (const mod of state.domModifications) {
1156
+ let elements;
1157
+ try {
1158
+ elements = document.querySelectorAll(mod.selector);
1159
+ } catch {
1160
+ console.warn(`[Sidekick] Invalid CSS selector: "${mod.selector}"`);
1161
+ continue;
1162
+ }
1163
+ elements.forEach((el) => {
1164
+ const htmlEl = el;
1165
+ if (!originals.has(el)) {
1166
+ switch (mod.type) {
1167
+ case "setText": {
1168
+ const textNodes = [];
1169
+ const tw = document.createTreeWalker(htmlEl, NodeFilter.SHOW_TEXT);
1170
+ let tn;
1171
+ while (tn = tw.nextNode()) {
1172
+ textNodes.push({ node: tn, value: tn.nodeValue || "" });
1173
+ }
1174
+ originals.set(el, { type: "setText", value: textNodes });
1175
+ break;
1176
+ }
1177
+ case "setAttribute": {
1178
+ const { attr } = mod.value;
1179
+ originals.set(el, { type: "setAttribute", value: { attr, value: htmlEl.getAttribute(attr) } });
1180
+ break;
1181
+ }
1182
+ case "setStyle":
1183
+ originals.set(el, { type: "setStyle", value: htmlEl.style.cssText });
1184
+ break;
1185
+ case "addClass":
1186
+ originals.set(el, { type: "addClass", value: mod.value });
1187
+ break;
1188
+ case "removeClass":
1189
+ originals.set(el, { type: "removeClass", value: mod.value });
1190
+ break;
1191
+ }
1192
+ }
1193
+ switch (mod.type) {
1194
+ case "setText": {
1195
+ const walker = document.createTreeWalker(htmlEl, NodeFilter.SHOW_TEXT);
1196
+ const firstTextNode = walker.nextNode();
1197
+ if (firstTextNode) {
1198
+ firstTextNode.nodeValue = mod.value;
1199
+ let extra;
1200
+ while (extra = walker.nextNode()) {
1201
+ extra.nodeValue = "";
1202
+ }
1203
+ }
1204
+ break;
1205
+ }
1206
+ case "setAttribute": {
1207
+ const { attr, value } = mod.value;
1208
+ htmlEl.setAttribute(attr, value);
1209
+ break;
1210
+ }
1211
+ case "setStyle":
1212
+ Object.assign(htmlEl.style, mod.value);
1213
+ break;
1214
+ case "addClass":
1215
+ htmlEl.classList.add(mod.value);
1216
+ break;
1217
+ case "removeClass":
1218
+ htmlEl.classList.remove(mod.value);
1219
+ break;
1220
+ }
1221
+ htmlEl.setAttribute("data-sidekick-dom-mod", "true");
1222
+ });
1223
+ }
1224
+ }
1225
+ applyModifications();
1226
+ const observer = new MutationObserver(() => {
1227
+ applyModifications();
1228
+ });
1229
+ if (document.body) {
1230
+ observer.observe(document.body, { childList: true, subtree: true });
1231
+ }
1232
+ return () => {
1233
+ observer.disconnect();
1234
+ originals.forEach((original, el) => {
1235
+ const htmlEl = el;
1236
+ switch (original.type) {
1237
+ case "setText": {
1238
+ const textNodes = original.value;
1239
+ for (const { node, value } of textNodes) {
1240
+ try {
1241
+ node.nodeValue = value;
1242
+ } catch {
1243
+ }
1244
+ }
1245
+ break;
1246
+ }
1247
+ case "setAttribute": {
1248
+ const { attr, value } = original.value;
1249
+ if (value === null) htmlEl.removeAttribute(attr);
1250
+ else htmlEl.setAttribute(attr, value);
1251
+ break;
1252
+ }
1253
+ case "setStyle":
1254
+ htmlEl.style.cssText = original.value;
1255
+ break;
1256
+ case "addClass":
1257
+ htmlEl.classList.remove(original.value);
1258
+ break;
1259
+ case "removeClass":
1260
+ htmlEl.classList.add(original.value);
1261
+ break;
1262
+ }
1263
+ htmlEl.removeAttribute("data-sidekick-dom-mod");
1264
+ });
1265
+ };
1266
+ }, [state.domModifications, isReady]);
1267
+ (0, import_react5.useEffect)(() => {
1268
+ if (!isReady || typeof document === "undefined" || state.keyboardShortcuts.length === 0) return;
1269
+ function matchesKeys(event, keys) {
1270
+ const parts = keys.toLowerCase().split("+").map((s) => s.trim());
1271
+ const keyName = parts[parts.length - 1];
1272
+ const modifiers = new Set(parts.slice(0, -1));
1273
+ const needsCtrl = modifiers.has("ctrl") || modifiers.has("cmd") || modifiers.has("meta");
1274
+ const needsShift = modifiers.has("shift");
1275
+ const needsAlt = modifiers.has("alt");
1276
+ if (needsCtrl !== (event.ctrlKey || event.metaKey)) return false;
1277
+ if (needsShift !== event.shiftKey) return false;
1278
+ if (needsAlt !== event.altKey) return false;
1279
+ return event.key.toLowerCase() === keyName || event.code.toLowerCase() === keyName;
1280
+ }
1281
+ function handleKeydown(event) {
1282
+ for (const shortcut of state.keyboardShortcuts) {
1283
+ if (matchesKeys(event, shortcut.keys)) {
1284
+ event.preventDefault();
1285
+ try {
1286
+ shortcut.action();
1287
+ } catch (error) {
1288
+ console.error(`[Sidekick] Keyboard shortcut error for "${shortcut.keys}":`, error);
1289
+ }
1290
+ return;
1291
+ }
1292
+ }
1293
+ }
1294
+ document.addEventListener("keydown", handleKeydown);
1295
+ return () => {
1296
+ document.removeEventListener("keydown", handleKeydown);
1297
+ };
1298
+ }, [state.keyboardShortcuts, isReady]);
1299
+ (0, import_react5.useEffect)(() => {
1300
+ if (!isReady || typeof window === "undefined" || state.interceptors.length === 0) return;
1301
+ const originalFetch = window.fetch;
1302
+ window.fetch = async function sidekickFetch(input, init) {
1303
+ const response = await originalFetch.call(window, input, init);
1304
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
1305
+ const method = init?.method || "GET";
1306
+ for (const interceptor of stateRef.current.interceptors) {
1307
+ const pattern = interceptor.pathPattern;
1308
+ const matches = typeof pattern === "string" ? url.includes(pattern) : pattern.test(url);
1309
+ if (matches) {
1310
+ try {
1311
+ const cloned = response.clone();
1312
+ const json = await cloned.json();
1313
+ const modified = interceptor.handler(json, { path: url, method });
1314
+ return new Response(JSON.stringify(modified), {
1315
+ status: response.status,
1316
+ statusText: response.statusText,
1317
+ headers: response.headers
1318
+ });
1319
+ } catch {
1320
+ return response;
1321
+ }
1322
+ }
1323
+ }
1324
+ return response;
1325
+ };
1326
+ return () => {
1327
+ window.fetch = originalFetch;
1328
+ };
1329
+ }, [state.interceptors, isReady]);
1330
+ const [injectionContainers, setInjectionContainers] = (0, import_react5.useState)([]);
1331
+ (0, import_react5.useEffect)(() => {
1332
+ if (!isReady || typeof document === "undefined" || state.injections.length === 0) return;
1333
+ const containers = [];
1334
+ function createContainers() {
1335
+ document.querySelectorAll("[data-sidekick-injection]").forEach((el) => el.remove());
1336
+ containers.length = 0;
1337
+ for (const injection of state.injections) {
1338
+ let target;
1339
+ try {
1340
+ target = document.querySelector(injection.selector);
1341
+ } catch {
1342
+ console.warn(`[Sidekick] Invalid CSS selector: "${injection.selector}"`);
1343
+ continue;
1344
+ }
1345
+ if (!target) continue;
1346
+ const container = document.createElement("div");
1347
+ container.setAttribute("data-sidekick-injection", injection.id);
1348
+ switch (injection.position) {
1349
+ case "before":
1350
+ target.parentNode?.insertBefore(container, target);
1351
+ break;
1352
+ case "after":
1353
+ target.parentNode?.insertBefore(container, target.nextSibling);
1354
+ break;
1355
+ case "prepend":
1356
+ target.insertBefore(container, target.firstChild);
1357
+ break;
1358
+ case "append":
1359
+ target.appendChild(container);
1360
+ break;
1361
+ }
1362
+ containers.push({ injection, container });
1363
+ }
1364
+ setInjectionContainers([...containers]);
1365
+ }
1366
+ createContainers();
1367
+ const observer = new MutationObserver(() => {
1368
+ const needsUpdate = state.injections.some((inj) => {
1369
+ try {
1370
+ const existing = document.querySelector(`[data-sidekick-injection="${inj.id}"]`);
1371
+ if (existing) return false;
1372
+ const target = document.querySelector(inj.selector);
1373
+ return !!target;
1374
+ } catch {
1375
+ return false;
1376
+ }
1377
+ });
1378
+ if (needsUpdate) createContainers();
1379
+ });
1380
+ if (document.body) {
1381
+ observer.observe(document.body, { childList: true, subtree: true });
1382
+ }
1383
+ return () => {
1384
+ observer.disconnect();
1385
+ document.querySelectorAll("[data-sidekick-injection]").forEach((el) => el.remove());
1386
+ setInjectionContainers([]);
1387
+ };
1388
+ }, [state.injections, isReady]);
1389
+ (0, import_react5.useEffect)(() => {
1390
+ if (!isReady || typeof document === "undefined" || state.domEventListeners.length === 0) return;
1391
+ const cleanups = [];
1392
+ for (const listener of state.domEventListeners) {
1393
+ const handler = (event) => {
1394
+ const target = event.target;
1395
+ if (!target) return;
1396
+ let matched;
1397
+ try {
1398
+ matched = target.matches(listener.selector) ? target : target.closest(listener.selector);
1399
+ } catch {
1400
+ return;
1401
+ }
1402
+ if (matched) {
1403
+ try {
1404
+ listener.handler(event, matched);
1405
+ } catch (error) {
1406
+ console.error(`[Sidekick] DOM event handler error for "${listener.selector}" ${listener.eventType}:`, error);
1407
+ }
1408
+ }
1409
+ };
1410
+ document.addEventListener(listener.eventType, handler);
1411
+ cleanups.push(() => document.removeEventListener(listener.eventType, handler));
1412
+ }
1413
+ return () => {
1414
+ cleanups.forEach((cleanup) => cleanup());
1415
+ };
1416
+ }, [state.domEventListeners, isReady]);
1417
+ (0, import_react5.useEffect)(() => {
1418
+ if (!isReady || typeof window === "undefined" || state.routeModifiers.length === 0) return;
1419
+ const originalPushState = history.pushState.bind(history);
1420
+ const originalReplaceState = history.replaceState.bind(history);
1421
+ function interceptNavigation(original, data, unused, url) {
1422
+ let finalUrl = url;
1423
+ if (url) {
1424
+ const urlStr = url.toString();
1425
+ for (const modifier of stateRef.current.routeModifiers) {
1426
+ const pattern = modifier.pathPattern;
1427
+ const matches = typeof pattern === "string" ? urlStr.includes(pattern) : pattern.test(urlStr);
1428
+ if (matches) {
1429
+ try {
1430
+ const result = modifier.handler({ path: urlStr, params: {} });
1431
+ if (typeof result === "string") {
1432
+ finalUrl = result;
1433
+ }
1434
+ } catch (error) {
1435
+ console.error(`[Sidekick] Route modifier error:`, error);
1436
+ }
1437
+ }
1438
+ }
1439
+ }
1440
+ original(data, unused, finalUrl);
1441
+ }
1442
+ history.pushState = function(data, unused, url) {
1443
+ interceptNavigation(originalPushState, data, unused, url);
1444
+ };
1445
+ history.replaceState = function(data, unused, url) {
1446
+ interceptNavigation(originalReplaceState, data, unused, url);
1447
+ };
1448
+ const handlePopState = () => {
1449
+ const currentPath = window.location.pathname;
1450
+ for (const modifier of stateRef.current.routeModifiers) {
1451
+ const pattern = modifier.pathPattern;
1452
+ const matches = typeof pattern === "string" ? currentPath.includes(pattern) : pattern.test(currentPath);
1453
+ if (matches) {
1454
+ try {
1455
+ modifier.handler({ path: currentPath, params: {} });
1456
+ } catch (error) {
1457
+ console.error(`[Sidekick] Route modifier error on popstate:`, error);
1458
+ }
1459
+ }
1460
+ }
1461
+ };
1462
+ window.addEventListener("popstate", handlePopState);
1463
+ return () => {
1464
+ history.pushState = originalPushState;
1465
+ history.replaceState = originalReplaceState;
1466
+ window.removeEventListener("popstate", handlePopState);
1467
+ };
1468
+ }, [state.routeModifiers, isReady]);
1469
+ const isOverrideEnabled = (0, import_react5.useCallback)(
1470
+ (id) => {
1471
+ const override = overrides.find((o) => o.id === id);
1472
+ if (override) return override.enabled;
1473
+ return getFlag(id);
1474
+ },
1475
+ [overrides]
1476
+ );
1477
+ const toggleOverride = (0, import_react5.useCallback)(
1478
+ (id) => {
1479
+ const currentEnabled = getFlag(id);
1480
+ setFlag(id, !currentEnabled);
1481
+ window.location.reload();
1482
+ },
1483
+ []
1484
+ );
1485
+ const getColumns = (0, import_react5.useCallback)(
1486
+ (tableId) => {
1487
+ return state.columns.get(tableId) ?? [];
1488
+ },
1489
+ [state.columns]
1490
+ );
1491
+ const getColumnRenames = (0, import_react5.useCallback)(
1492
+ (tableId) => {
1493
+ return state.columnRenames.get(tableId) ?? [];
1494
+ },
1495
+ [state.columnRenames]
1496
+ );
1497
+ const getHiddenColumns = (0, import_react5.useCallback)(
1498
+ (tableId) => {
1499
+ return state.hiddenColumns.get(tableId) ?? [];
1500
+ },
1501
+ [state.hiddenColumns]
1502
+ );
1503
+ const getColumnOrder = (0, import_react5.useCallback)(
1504
+ (tableId) => {
1505
+ return state.columnOrders.get(tableId);
1506
+ },
1507
+ [state.columnOrders]
1508
+ );
1509
+ const getMenuItems = (0, import_react5.useCallback)(
1510
+ (menuId) => {
1511
+ return state.menuItems.get(menuId) ?? [];
1512
+ },
1513
+ [state.menuItems]
1514
+ );
1515
+ const getTabs = (0, import_react5.useCallback)(
1516
+ (tabGroupId) => {
1517
+ return state.tabs.get(tabGroupId) ?? [];
1518
+ },
1519
+ [state.tabs]
1520
+ );
1521
+ const getActions = (0, import_react5.useCallback)(
1522
+ (actionBarId) => {
1523
+ return state.actions.get(actionBarId) ?? [];
1524
+ },
1525
+ [state.actions]
1526
+ );
1527
+ const getValidations = (0, import_react5.useCallback)(
1528
+ (formId) => {
1529
+ return state.validations.get(formId) ?? [];
1530
+ },
1531
+ [state.validations]
1532
+ );
1533
+ const applyPropsModifiers = (0, import_react5.useCallback)(
1534
+ (componentId, props) => {
1535
+ const modifiers = state.propsModifiers.get(componentId) ?? [];
1536
+ return modifiers.reduce((acc, { modifier }) => modifier(acc), props);
1537
+ },
1538
+ [state.propsModifiers]
1539
+ );
1540
+ const getComputedValue = (0, import_react5.useCallback)(
1541
+ (fieldName, data) => {
1542
+ const field = state.computedFields.get(fieldName);
1543
+ if (!field) return void 0;
1544
+ return field.compute(data);
1545
+ },
1546
+ [state.computedFields]
1547
+ );
1548
+ const applyFilters = (0, import_react5.useCallback)(
1549
+ (filterName, items) => {
1550
+ const filter = state.filters.get(filterName);
1551
+ if (!filter) return items;
1552
+ return filter.filter(items);
1553
+ },
1554
+ [state.filters]
1555
+ );
1556
+ const applyTransform = (0, import_react5.useCallback)(
1557
+ (dataKey, data) => {
1558
+ const transform2 = state.transforms.get(dataKey);
1559
+ if (!transform2) return data;
1560
+ return transform2.transform(data);
1561
+ },
1562
+ [state.transforms]
1563
+ );
1564
+ const getSortOptions = (0, import_react5.useCallback)(
1565
+ (tableId) => {
1566
+ return state.sortOptions.get(tableId) ?? [];
1567
+ },
1568
+ [state.sortOptions]
1569
+ );
1570
+ const getGroupByOptions = (0, import_react5.useCallback)(
1571
+ (tableId) => {
1572
+ return state.groupByOptions.get(tableId) ?? [];
1573
+ },
1574
+ [state.groupByOptions]
1575
+ );
1576
+ const getKeyboardShortcuts = (0, import_react5.useCallback)(
1577
+ () => {
1578
+ return state.keyboardShortcuts;
1579
+ },
1580
+ [state.keyboardShortcuts]
1581
+ );
1582
+ const emitEvent = (0, import_react5.useCallback)(
1583
+ (eventName, payload) => {
1584
+ const handlers = state.eventHandlers.get(eventName) ?? [];
1585
+ for (const handler of handlers) {
1586
+ try {
1587
+ handler.handler(payload);
1588
+ } catch (error) {
1589
+ console.error(`[Sidekick] Event handler error for ${eventName}:`, error);
1590
+ }
1591
+ }
1592
+ },
1593
+ [state.eventHandlers]
1594
+ );
1595
+ const getWrapper = (0, import_react5.useCallback)(
1596
+ (componentName) => {
1597
+ const wrappers = state.wrappers.get(componentName);
1598
+ if (!wrappers || wrappers.length === 0) return void 0;
1599
+ return (Component) => {
1600
+ return wrappers.reduce(
1601
+ (wrapped, { wrapper }) => wrapper(wrapped),
1602
+ Component
1603
+ );
1604
+ };
1605
+ },
1606
+ [state.wrappers]
1607
+ );
1608
+ const getReplacement = (0, import_react5.useCallback)(
1609
+ (componentName) => {
1610
+ return state.replacements.get(componentName);
1611
+ },
1612
+ [state.replacements]
1613
+ );
1614
+ const contextValue = (0, import_react5.useMemo)(
1615
+ () => ({
1616
+ state,
1617
+ overrides,
1618
+ isOverrideEnabled,
1619
+ toggleOverride,
1620
+ // UI
1621
+ getColumns,
1622
+ getColumnRenames,
1623
+ getHiddenColumns,
1624
+ getColumnOrder,
1625
+ getMenuItems,
1626
+ getTabs,
1627
+ getActions,
1628
+ getValidations,
1629
+ getWrapper,
1630
+ getReplacement,
1631
+ applyPropsModifiers,
1632
+ // Data
1633
+ getComputedValue,
1634
+ applyFilters,
1635
+ applyTransform,
1636
+ getSortOptions,
1637
+ getGroupByOptions,
1638
+ // Behavior
1639
+ getKeyboardShortcuts,
1640
+ emitEvent
1641
+ }),
1642
+ [
1643
+ state,
1644
+ overrides,
1645
+ isOverrideEnabled,
1646
+ toggleOverride,
1647
+ getColumns,
1648
+ getColumnRenames,
1649
+ getHiddenColumns,
1650
+ getColumnOrder,
1651
+ getMenuItems,
1652
+ getTabs,
1653
+ getActions,
1654
+ getValidations,
1655
+ getWrapper,
1656
+ getReplacement,
1657
+ applyPropsModifiers,
1658
+ getComputedValue,
1659
+ applyFilters,
1660
+ applyTransform,
1661
+ getSortOptions,
1662
+ getGroupByOptions,
1663
+ getKeyboardShortcuts,
1664
+ emitEvent
1665
+ ]
1666
+ );
1667
+ const wrapCacheRef = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
1668
+ const transformedChildren = (0, import_react5.useMemo)(() => {
1669
+ if (!isReady) return null;
1670
+ if (state.wrappers.size === 0 && state.replacements.size === 0) return children;
1671
+ return transformElementTree(children, state.wrappers, state.replacements, wrapCacheRef.current);
1672
+ }, [children, isReady, state.wrappers, state.replacements]);
1673
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(SidekickContext.Provider, { value: contextValue, children: [
1674
+ isReady ? transformedChildren : null,
1675
+ injectionContainers.map(
1676
+ ({ injection, container }) => (0, import_react_dom.createPortal)(
1677
+ import_react5.default.createElement(injection.component, {}),
1678
+ container,
1679
+ `sidekick-injection-${injection.id}`
1680
+ )
1681
+ )
1682
+ ] });
1683
+ }
1684
+
1685
+ // src/components/SidekickPanel.tsx
1686
+ var import_react6 = require("react");
1687
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1688
+ function SidekickPanel({ apiEndpoint, deleteEndpoint, toggleEndpoint, onGenerate, onDelete, onToggle }) {
1689
+ const [isOpen, setIsOpen] = (0, import_react6.useState)(() => {
1690
+ if (typeof window === "undefined") return false;
1691
+ return sessionStorage.getItem("sidekick_panel_open") === "true";
1692
+ });
1693
+ const [activeTab, setActiveTab] = (0, import_react6.useState)(() => {
1694
+ if (typeof window === "undefined") return "chat";
1695
+ return sessionStorage.getItem("sidekick_panel_tab") || "chat";
1696
+ });
1697
+ const [messages, setMessages] = (0, import_react6.useState)([]);
1698
+ const [input, setInput] = (0, import_react6.useState)("");
1699
+ const [isGenerating, setIsGenerating] = (0, import_react6.useState)(false);
1700
+ const [deletingId, setDeletingId] = (0, import_react6.useState)(null);
1701
+ const [togglingId, setTogglingId] = (0, import_react6.useState)(null);
1702
+ const [editingOverrideId, setEditingOverrideId] = (0, import_react6.useState)(null);
1703
+ const context = useSidekickSafe();
1704
+ const overrides = context?.overrides ?? [];
1705
+ const effectiveDeleteEndpoint = deleteEndpoint || (apiEndpoint ? apiEndpoint.replace("/generate", "/delete") : void 0);
1706
+ const effectiveToggleEndpoint = toggleEndpoint || (apiEndpoint ? apiEndpoint.replace("/generate", "/toggle") : void 0);
1707
+ (0, import_react6.useEffect)(() => {
1708
+ if (typeof window === "undefined") return;
1709
+ sessionStorage.setItem("sidekick_panel_open", isOpen ? "true" : "false");
1710
+ }, [isOpen]);
1711
+ (0, import_react6.useEffect)(() => {
1712
+ if (typeof window === "undefined") return;
1713
+ sessionStorage.setItem("sidekick_panel_tab", activeTab);
1714
+ }, [activeTab]);
1715
+ const messagesStorageKey = editingOverrideId ? `sidekick_edit_messages_${editingOverrideId}` : "sidekick_messages";
1716
+ (0, import_react6.useEffect)(() => {
1717
+ if (typeof window === "undefined") return;
1718
+ const stored = sessionStorage.getItem(messagesStorageKey);
1719
+ if (stored) {
1720
+ try {
1721
+ const parsed = JSON.parse(stored);
1722
+ setMessages(parsed.map((m) => ({ ...m, timestamp: new Date(m.timestamp) })));
1723
+ } catch {
1724
+ setMessages([]);
1725
+ }
1726
+ } else {
1727
+ setMessages([]);
1728
+ }
1729
+ }, [messagesStorageKey]);
1730
+ (0, import_react6.useEffect)(() => {
1731
+ if (typeof window === "undefined" || messages.length === 0) return;
1732
+ sessionStorage.setItem(messagesStorageKey, JSON.stringify(messages));
1733
+ }, [messages, messagesStorageKey]);
1734
+ const handleSubmit = (0, import_react6.useCallback)(async (e) => {
1735
+ e.preventDefault();
1736
+ if (!input.trim() || isGenerating) return;
1737
+ const userMessage = {
1738
+ id: generateId4(),
1739
+ role: "user",
1740
+ content: input.trim(),
1741
+ timestamp: /* @__PURE__ */ new Date()
1742
+ };
1743
+ const assistantMessage = {
1744
+ id: generateId4(),
1745
+ role: "assistant",
1746
+ content: "Generating your customization...",
1747
+ timestamp: /* @__PURE__ */ new Date(),
1748
+ status: "generating"
1749
+ };
1750
+ setMessages((prev) => [...prev, userMessage, assistantMessage]);
1751
+ setInput("");
1752
+ setIsGenerating(true);
1753
+ try {
1754
+ let result;
1755
+ const requestBody = { request: userMessage.content };
1756
+ if (editingOverrideId) {
1757
+ requestBody.overrideId = editingOverrideId;
1758
+ }
1759
+ if (onGenerate) {
1760
+ result = await onGenerate(userMessage.content);
1761
+ } else if (apiEndpoint) {
1762
+ const response = await fetch(apiEndpoint, {
1763
+ method: "POST",
1764
+ headers: { "Content-Type": "application/json" },
1765
+ body: JSON.stringify(requestBody)
1766
+ });
1767
+ result = await response.json();
1768
+ } else {
1769
+ result = {
1770
+ success: false,
1771
+ error: "No API endpoint or onGenerate handler configured"
1772
+ };
1773
+ }
1774
+ const verb = editingOverrideId ? "Updated" : "Created";
1775
+ const successMessage = result.success ? `${verb} "${result.name || result.overrideId}"!
1776
+
1777
+ ${result.description || ""}
1778
+
1779
+ Reload the page to apply changes.` : `Failed to generate: ${result.error}`;
1780
+ setMessages(
1781
+ (prev) => prev.map(
1782
+ (m) => m.id === assistantMessage.id ? {
1783
+ ...m,
1784
+ content: successMessage,
1785
+ status: result.success ? "success" : "error",
1786
+ overrideId: result.overrideId
1787
+ } : m
1788
+ )
1789
+ );
1790
+ } catch (error) {
1791
+ setMessages(
1792
+ (prev) => prev.map(
1793
+ (m) => m.id === assistantMessage.id ? {
1794
+ ...m,
1795
+ content: `Error: ${error instanceof Error ? error.message : "Unknown error"}`,
1796
+ status: "error"
1797
+ } : m
1798
+ )
1799
+ );
1800
+ } finally {
1801
+ setIsGenerating(false);
1802
+ }
1803
+ }, [input, isGenerating, onGenerate, apiEndpoint, editingOverrideId]);
1804
+ const handleToggleOverride = (0, import_react6.useCallback)(async (overrideId, enabled) => {
1805
+ setTogglingId(overrideId);
1806
+ try {
1807
+ if (onToggle) {
1808
+ await onToggle(overrideId, enabled);
1809
+ } else if (effectiveToggleEndpoint) {
1810
+ const response = await fetch(effectiveToggleEndpoint, {
1811
+ method: "POST",
1812
+ headers: { "Content-Type": "application/json" },
1813
+ body: JSON.stringify({ overrideId, enabled })
1814
+ });
1815
+ const result = await response.json();
1816
+ if (!result.success) {
1817
+ throw new Error(result.error || "Toggle failed");
1818
+ }
1819
+ } else {
1820
+ setFlag(overrideId, enabled);
1821
+ }
1822
+ window.location.reload();
1823
+ } catch (error) {
1824
+ alert(`Failed to toggle: ${error instanceof Error ? error.message : "Unknown error"}`);
1825
+ setTogglingId(null);
1826
+ }
1827
+ }, [onToggle, effectiveToggleEndpoint]);
1828
+ const handleDeleteOverride = (0, import_react6.useCallback)(async (overrideId) => {
1829
+ if (!confirm(`Are you sure you want to delete this override? This cannot be undone.`)) {
1830
+ return;
1831
+ }
1832
+ setDeletingId(overrideId);
1833
+ try {
1834
+ let result;
1835
+ if (onDelete) {
1836
+ result = await onDelete(overrideId);
1837
+ } else if (effectiveDeleteEndpoint) {
1838
+ const response = await fetch(effectiveDeleteEndpoint, {
1839
+ method: "POST",
1840
+ headers: { "Content-Type": "application/json" },
1841
+ body: JSON.stringify({ overrideId })
1842
+ });
1843
+ result = await response.json();
1844
+ } else {
1845
+ result = { success: false, error: "No delete endpoint configured" };
1846
+ }
1847
+ if (result.success) {
1848
+ setFlag(overrideId, false);
1849
+ window.location.reload();
1850
+ } else {
1851
+ alert(`Failed to delete: ${result.error}`);
1852
+ }
1853
+ } catch (error) {
1854
+ alert(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
1855
+ } finally {
1856
+ setDeletingId(null);
1857
+ }
1858
+ }, [onDelete, effectiveDeleteEndpoint]);
1859
+ const handleRegenerateOverride = (0, import_react6.useCallback)((overrideId) => {
1860
+ setEditingOverrideId(overrideId);
1861
+ setActiveTab("chat");
1862
+ setInput("");
1863
+ }, []);
1864
+ const handleEditOverride = (0, import_react6.useCallback)((overrideId) => {
1865
+ setEditingOverrideId(overrideId);
1866
+ setActiveTab("chat");
1867
+ setInput("");
1868
+ }, []);
1869
+ const handleExitEditMode = (0, import_react6.useCallback)(() => {
1870
+ setEditingOverrideId(null);
1871
+ setInput("");
1872
+ }, []);
1873
+ const handleClearHistory = (0, import_react6.useCallback)(() => {
1874
+ setMessages([]);
1875
+ sessionStorage.removeItem(messagesStorageKey);
1876
+ }, [messagesStorageKey]);
1877
+ if (!isOpen) {
1878
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1879
+ "button",
1880
+ {
1881
+ onClick: () => setIsOpen(true),
1882
+ style: styles.trigger,
1883
+ "aria-label": "Open Sidekick Panel",
1884
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SidekickIcon, {})
1885
+ }
1886
+ );
1887
+ }
1888
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.overlay, onWheel: (e) => e.stopPropagation(), onTouchMove: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.panel, children: [
1889
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.header, children: [
1890
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { style: styles.title, children: "Sidekick" }),
1891
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => setIsOpen(false), style: styles.closeButton, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, {}) })
1892
+ ] }),
1893
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.tabs, children: [
1894
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1895
+ "button",
1896
+ {
1897
+ onClick: () => setActiveTab("chat"),
1898
+ style: {
1899
+ ...styles.tab,
1900
+ ...activeTab === "chat" ? styles.tabActive : {}
1901
+ },
1902
+ children: "Customize"
1903
+ }
1904
+ ),
1905
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1906
+ "button",
1907
+ {
1908
+ onClick: () => setActiveTab("overrides"),
1909
+ style: {
1910
+ ...styles.tab,
1911
+ ...activeTab === "overrides" ? styles.tabActive : {}
1912
+ },
1913
+ children: [
1914
+ "Overrides (",
1915
+ overrides.length,
1916
+ ")"
1917
+ ]
1918
+ }
1919
+ )
1920
+ ] }),
1921
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.content, children: activeTab === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1922
+ ChatTab,
1923
+ {
1924
+ messages,
1925
+ input,
1926
+ isGenerating,
1927
+ onInputChange: setInput,
1928
+ onSubmit: handleSubmit,
1929
+ onClearHistory: handleClearHistory,
1930
+ editingOverride: editingOverrideId ? overrides.find((o) => o.id === editingOverrideId) : void 0,
1931
+ onExitEditMode: handleExitEditMode
1932
+ }
1933
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1934
+ OverridesTab,
1935
+ {
1936
+ overrides,
1937
+ onToggle: handleToggleOverride,
1938
+ onDelete: handleDeleteOverride,
1939
+ onRegenerate: handleRegenerateOverride,
1940
+ onEdit: handleEditOverride,
1941
+ deletingId,
1942
+ togglingId
1943
+ }
1944
+ ) })
1945
+ ] }) });
1946
+ }
1947
+ function ChatTab({
1948
+ messages,
1949
+ input,
1950
+ isGenerating,
1951
+ onInputChange,
1952
+ onSubmit,
1953
+ onClearHistory,
1954
+ editingOverride,
1955
+ onExitEditMode
1956
+ }) {
1957
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.chatContainer, children: [
1958
+ editingOverride && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.editHeader, children: [
1959
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: styles.editHeaderText, children: [
1960
+ "Editing: ",
1961
+ editingOverride.name
1962
+ ] }),
1963
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: onExitEditMode, style: styles.editHeaderClose, children: "\u2715" })
1964
+ ] }),
1965
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.messages, children: messages.length === 0 ? editingOverride ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.emptyState, children: [
1966
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { style: styles.emptyTitle, children: [
1967
+ 'Edit "',
1968
+ editingOverride.name,
1969
+ '"'
1970
+ ] }),
1971
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.emptyDescription, children: "Describe what you want to change about this override, and I'll modify the existing code." }),
1972
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.examples, children: [
1973
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.examplesTitle, children: "Try saying:" }),
1974
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { style: styles.examplesList, children: [
1975
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Change the color to red"' }),
1976
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Make it only apply to high priority items"' }),
1977
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Add a hover effect"' })
1978
+ ] })
1979
+ ] })
1980
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.emptyState, children: [
1981
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.emptyTitle, children: "Customize your app" }),
1982
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.emptyDescription, children: "Describe what you want to change in natural language, and I'll generate the code." }),
1983
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.examples, children: [
1984
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.examplesTitle, children: "Try saying:" }),
1985
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { style: styles.examplesList, children: [
1986
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Add a column showing days until due date"' }),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Add a banner at the top of the sidebar"' }),
1988
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: '"Highlight overdue tasks in red"' })
1989
+ ] })
1990
+ ] })
1991
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1992
+ messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1993
+ "div",
1994
+ {
1995
+ style: {
1996
+ ...styles.message,
1997
+ ...message.role === "user" ? styles.userMessage : styles.assistantMessage
1998
+ },
1999
+ children: [
2000
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.messageContent, children: [
2001
+ message.content,
2002
+ message.status === "generating" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles.spinner, children: "\u27F3" })
2003
+ ] }),
2004
+ message.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.successContainer, children: [
2005
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.successBadge, children: [
2006
+ "\u2713 ",
2007
+ editingOverride ? "Updated" : "Created"
2008
+ ] }),
2009
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2010
+ "button",
2011
+ {
2012
+ onClick: () => window.location.reload(),
2013
+ style: styles.reloadButton,
2014
+ children: "Reload to Apply"
2015
+ }
2016
+ )
2017
+ ] }),
2018
+ message.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.errorBadge, children: "\u2715 Failed" })
2019
+ ]
2020
+ },
2021
+ message.id
2022
+ )),
2023
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: onClearHistory, style: styles.clearButton, children: "Clear history" })
2024
+ ] }) }),
2025
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { onSubmit, style: styles.inputForm, children: [
2026
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2027
+ "input",
2028
+ {
2029
+ type: "text",
2030
+ value: input,
2031
+ onChange: (e) => onInputChange(e.target.value),
2032
+ placeholder: "Describe your customization...",
2033
+ disabled: isGenerating,
2034
+ style: styles.input
2035
+ }
2036
+ ),
2037
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2038
+ "button",
2039
+ {
2040
+ type: "submit",
2041
+ disabled: !input.trim() || isGenerating,
2042
+ style: {
2043
+ ...styles.submitButton,
2044
+ ...!input.trim() || isGenerating ? styles.submitButtonDisabled : {}
2045
+ },
2046
+ children: isGenerating ? "..." : "\u2192"
2047
+ }
2048
+ )
2049
+ ] })
2050
+ ] });
2051
+ }
2052
+ function OverridesTab({ overrides, onToggle, onDelete, onRegenerate, onEdit, deletingId, togglingId }) {
2053
+ const handleToggle = (override) => {
2054
+ onToggle(override.id, !override.enabled);
2055
+ };
2056
+ if (overrides.length === 0) {
2057
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.emptyState, children: [
2058
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.emptyTitle, children: "No overrides yet" }),
2059
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.emptyDescription, children: "Use the Customize tab to create your first customization." })
2060
+ ] });
2061
+ }
2062
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles.overridesList, children: overrides.map((override) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.overrideItem, children: [
2063
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.overrideInfo, children: [
2064
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { style: styles.overrideName, children: override.name }),
2065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: styles.overrideDescription, children: override.description }),
2066
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles.overrideActions, children: [
2067
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2068
+ "button",
2069
+ {
2070
+ onClick: () => onEdit(override.id),
2071
+ style: styles.actionButton,
2072
+ children: "Edit"
2073
+ }
2074
+ ),
2075
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2076
+ "button",
2077
+ {
2078
+ onClick: () => onRegenerate(override.id),
2079
+ style: styles.actionButton,
2080
+ children: "Regenerate"
2081
+ }
2082
+ ),
2083
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2084
+ "button",
2085
+ {
2086
+ onClick: () => onDelete(override.id),
2087
+ disabled: deletingId === override.id,
2088
+ style: {
2089
+ ...styles.actionButton,
2090
+ ...styles.deleteButton,
2091
+ ...deletingId === override.id ? styles.actionButtonDisabled : {}
2092
+ },
2093
+ children: deletingId === override.id ? "Deleting..." : "Delete"
2094
+ }
2095
+ )
2096
+ ] })
2097
+ ] }),
2098
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2099
+ "button",
2100
+ {
2101
+ onClick: () => handleToggle(override),
2102
+ disabled: togglingId === override.id,
2103
+ style: {
2104
+ ...styles.toggle,
2105
+ ...override.enabled ? styles.toggleOn : styles.toggleOff,
2106
+ ...togglingId === override.id ? styles.toggleDisabled : {}
2107
+ },
2108
+ children: togglingId === override.id ? "..." : override.enabled ? "ON" : "OFF"
2109
+ }
2110
+ )
2111
+ ] }, override.id)) });
2112
+ }
2113
+ function SidekickIcon() {
2114
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
2115
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
2116
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M2 17l10 5 10-5" }),
2117
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M2 12l10 5 10-5" })
2118
+ ] });
2119
+ }
2120
+ function CloseIcon() {
2121
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) });
2122
+ }
2123
+ function generateId4() {
2124
+ return Math.random().toString(36).substring(2, 11);
2125
+ }
2126
+ var styles = {
2127
+ trigger: {
2128
+ position: "fixed",
2129
+ bottom: "24px",
2130
+ right: "24px",
2131
+ width: "56px",
2132
+ height: "56px",
2133
+ borderRadius: "50%",
2134
+ backgroundColor: "#3B82F6",
2135
+ color: "white",
2136
+ border: "none",
2137
+ cursor: "pointer",
2138
+ display: "flex",
2139
+ alignItems: "center",
2140
+ justifyContent: "center",
2141
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
2142
+ zIndex: 9999
2143
+ },
2144
+ overlay: {
2145
+ position: "fixed",
2146
+ top: 0,
2147
+ right: 0,
2148
+ bottom: 0,
2149
+ width: "400px",
2150
+ zIndex: 9999,
2151
+ boxShadow: "-4px 0 24px rgba(0, 0, 0, 0.15)",
2152
+ overscrollBehavior: "contain"
2153
+ },
2154
+ panel: {
2155
+ height: "100%",
2156
+ backgroundColor: "white",
2157
+ display: "flex",
2158
+ flexDirection: "column"
2159
+ },
2160
+ header: {
2161
+ display: "flex",
2162
+ alignItems: "center",
2163
+ justifyContent: "space-between",
2164
+ padding: "16px 20px",
2165
+ borderBottom: "1px solid #E5E7EB"
2166
+ },
2167
+ title: {
2168
+ margin: 0,
2169
+ fontSize: "18px",
2170
+ fontWeight: 600,
2171
+ color: "#111827"
2172
+ },
2173
+ closeButton: {
2174
+ background: "none",
2175
+ border: "none",
2176
+ cursor: "pointer",
2177
+ padding: "4px",
2178
+ color: "#6B7280"
2179
+ },
2180
+ tabs: {
2181
+ display: "flex",
2182
+ borderBottom: "1px solid #E5E7EB"
2183
+ },
2184
+ tab: {
2185
+ flex: 1,
2186
+ padding: "12px 16px",
2187
+ background: "none",
2188
+ border: "none",
2189
+ cursor: "pointer",
2190
+ fontSize: "14px",
2191
+ fontWeight: 500,
2192
+ color: "#6B7280",
2193
+ borderBottom: "2px solid transparent"
2194
+ },
2195
+ tabActive: {
2196
+ color: "#3B82F6",
2197
+ borderBottomColor: "#3B82F6"
2198
+ },
2199
+ content: {
2200
+ flex: 1,
2201
+ overflow: "hidden",
2202
+ display: "flex",
2203
+ flexDirection: "column"
2204
+ },
2205
+ chatContainer: {
2206
+ flex: 1,
2207
+ display: "flex",
2208
+ flexDirection: "column",
2209
+ overflow: "hidden"
2210
+ },
2211
+ messages: {
2212
+ flex: 1,
2213
+ overflowY: "auto",
2214
+ padding: "16px",
2215
+ overscrollBehavior: "contain"
2216
+ },
2217
+ emptyState: {
2218
+ textAlign: "center",
2219
+ padding: "40px 20px"
2220
+ },
2221
+ emptyTitle: {
2222
+ margin: "0 0 8px 0",
2223
+ fontSize: "16px",
2224
+ fontWeight: 600,
2225
+ color: "#111827"
2226
+ },
2227
+ emptyDescription: {
2228
+ margin: "0 0 24px 0",
2229
+ fontSize: "14px",
2230
+ color: "#6B7280"
2231
+ },
2232
+ examples: {
2233
+ textAlign: "left",
2234
+ backgroundColor: "#F9FAFB",
2235
+ borderRadius: "8px",
2236
+ padding: "16px"
2237
+ },
2238
+ examplesTitle: {
2239
+ margin: "0 0 8px 0",
2240
+ fontSize: "13px",
2241
+ fontWeight: 500,
2242
+ color: "#374151"
2243
+ },
2244
+ examplesList: {
2245
+ margin: 0,
2246
+ padding: "0 0 0 20px",
2247
+ fontSize: "13px",
2248
+ color: "#6B7280",
2249
+ lineHeight: 1.8
2250
+ },
2251
+ message: {
2252
+ marginBottom: "12px",
2253
+ padding: "12px 16px",
2254
+ borderRadius: "12px",
2255
+ fontSize: "14px",
2256
+ lineHeight: 1.5
2257
+ },
2258
+ userMessage: {
2259
+ backgroundColor: "#3B82F6",
2260
+ color: "white",
2261
+ marginLeft: "40px"
2262
+ },
2263
+ assistantMessage: {
2264
+ backgroundColor: "#F3F4F6",
2265
+ color: "#111827",
2266
+ marginRight: "40px"
2267
+ },
2268
+ messageContent: {
2269
+ whiteSpace: "pre-wrap"
2270
+ },
2271
+ spinner: {
2272
+ display: "inline-block",
2273
+ animation: "spin 1s linear infinite"
2274
+ },
2275
+ successContainer: {
2276
+ marginTop: "12px",
2277
+ display: "flex",
2278
+ flexDirection: "column",
2279
+ gap: "8px"
2280
+ },
2281
+ successBadge: {
2282
+ fontSize: "12px",
2283
+ color: "#059669",
2284
+ fontWeight: 500
2285
+ },
2286
+ reloadButton: {
2287
+ padding: "8px 16px",
2288
+ backgroundColor: "#059669",
2289
+ color: "white",
2290
+ border: "none",
2291
+ borderRadius: "6px",
2292
+ fontSize: "13px",
2293
+ fontWeight: 500,
2294
+ cursor: "pointer"
2295
+ },
2296
+ errorBadge: {
2297
+ marginTop: "8px",
2298
+ fontSize: "12px",
2299
+ color: "#DC2626",
2300
+ fontWeight: 500
2301
+ },
2302
+ clearButton: {
2303
+ background: "none",
2304
+ border: "none",
2305
+ color: "#6B7280",
2306
+ fontSize: "12px",
2307
+ cursor: "pointer",
2308
+ padding: "8px",
2309
+ textAlign: "center",
2310
+ width: "100%"
2311
+ },
2312
+ inputForm: {
2313
+ display: "flex",
2314
+ gap: "8px",
2315
+ padding: "16px",
2316
+ borderTop: "1px solid #E5E7EB"
2317
+ },
2318
+ input: {
2319
+ flex: 1,
2320
+ padding: "12px 16px",
2321
+ border: "1px solid #E5E7EB",
2322
+ borderRadius: "8px",
2323
+ fontSize: "14px",
2324
+ outline: "none"
2325
+ },
2326
+ submitButton: {
2327
+ padding: "12px 20px",
2328
+ backgroundColor: "#3B82F6",
2329
+ color: "white",
2330
+ border: "none",
2331
+ borderRadius: "8px",
2332
+ fontSize: "16px",
2333
+ cursor: "pointer",
2334
+ fontWeight: 600
2335
+ },
2336
+ submitButtonDisabled: {
2337
+ backgroundColor: "#93C5FD",
2338
+ cursor: "not-allowed"
2339
+ },
2340
+ overridesList: {
2341
+ padding: "16px",
2342
+ flex: 1,
2343
+ overflowY: "auto",
2344
+ overscrollBehavior: "contain"
2345
+ },
2346
+ overrideItem: {
2347
+ display: "flex",
2348
+ alignItems: "center",
2349
+ justifyContent: "space-between",
2350
+ padding: "16px",
2351
+ backgroundColor: "#F9FAFB",
2352
+ borderRadius: "8px",
2353
+ marginBottom: "12px"
2354
+ },
2355
+ overrideInfo: {
2356
+ flex: 1,
2357
+ marginRight: "16px"
2358
+ },
2359
+ overrideName: {
2360
+ margin: "0 0 4px 0",
2361
+ fontSize: "14px",
2362
+ fontWeight: 600,
2363
+ color: "#111827"
2364
+ },
2365
+ overrideDescription: {
2366
+ margin: 0,
2367
+ fontSize: "13px",
2368
+ color: "#6B7280"
2369
+ },
2370
+ toggle: {
2371
+ padding: "6px 12px",
2372
+ borderRadius: "4px",
2373
+ border: "none",
2374
+ fontSize: "12px",
2375
+ fontWeight: 600,
2376
+ cursor: "pointer"
2377
+ },
2378
+ toggleOn: {
2379
+ backgroundColor: "#059669",
2380
+ color: "white"
2381
+ },
2382
+ toggleOff: {
2383
+ backgroundColor: "#E5E7EB",
2384
+ color: "#6B7280"
2385
+ },
2386
+ toggleDisabled: {
2387
+ opacity: 0.5,
2388
+ cursor: "not-allowed"
2389
+ },
2390
+ overrideActions: {
2391
+ display: "flex",
2392
+ gap: "8px",
2393
+ marginTop: "8px"
2394
+ },
2395
+ actionButton: {
2396
+ padding: "4px 8px",
2397
+ fontSize: "11px",
2398
+ fontWeight: 500,
2399
+ border: "1px solid #E5E7EB",
2400
+ borderRadius: "4px",
2401
+ backgroundColor: "white",
2402
+ color: "#6B7280",
2403
+ cursor: "pointer"
2404
+ },
2405
+ actionButtonDisabled: {
2406
+ opacity: 0.5,
2407
+ cursor: "not-allowed"
2408
+ },
2409
+ deleteButton: {
2410
+ color: "#DC2626",
2411
+ borderColor: "#FCA5A5"
2412
+ },
2413
+ editHeader: {
2414
+ display: "flex",
2415
+ alignItems: "center",
2416
+ justifyContent: "space-between",
2417
+ padding: "8px 16px",
2418
+ backgroundColor: "#EFF6FF",
2419
+ borderBottom: "1px solid #BFDBFE"
2420
+ },
2421
+ editHeaderText: {
2422
+ fontSize: "13px",
2423
+ fontWeight: 600,
2424
+ color: "#1D4ED8"
2425
+ },
2426
+ editHeaderClose: {
2427
+ background: "none",
2428
+ border: "none",
2429
+ cursor: "pointer",
2430
+ fontSize: "14px",
2431
+ color: "#1D4ED8",
2432
+ padding: "2px 6px",
2433
+ borderRadius: "4px"
2434
+ }
2435
+ };
2436
+ // Annotate the CommonJS export names for ESM import in node:
2437
+ 0 && (module.exports = {
2438
+ SidekickPanel,
2439
+ SidekickProvider,
2440
+ configureJsxRuntime,
2441
+ createOverride,
2442
+ getFlag,
2443
+ getRegisteredOverrides,
2444
+ getSeenComponentsFromJsx,
2445
+ isJsxRuntimeConfigured,
2446
+ loadFlags,
2447
+ onConfigChange,
2448
+ registerOverride,
2449
+ saveFlags,
2450
+ setFlag,
2451
+ toggleFlag,
2452
+ useActions,
2453
+ useAddedColumns,
2454
+ useColumnOrder,
2455
+ useColumnRenames,
2456
+ useComputedField,
2457
+ useEventEmitter,
2458
+ useFilter,
2459
+ useGroupByOptions,
2460
+ useHiddenColumns,
2461
+ useKeyboardShortcuts,
2462
+ useMenuItems,
2463
+ usePropsModifier,
2464
+ useSidekick,
2465
+ useSidekickSafe,
2466
+ useSortOptions,
2467
+ useTabs,
2468
+ useValidations
2469
+ });
2470
+ //# sourceMappingURL=index.js.map