ghostykit 0.9.1 → 0.10.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.
- package/README.md +1 -0
- package/dist/chunks/{chunk-VFCROLFF.js → chunk-6PYYF4XU.js} +14 -823
- package/dist/chunks/chunk-AQBQ3QZH.js +852 -0
- package/dist/plugins/index.js +2 -1
- package/dist/react/index.js +35 -33
- package/dist/split/index.d.ts +30 -0
- package/dist/split/index.js +83 -1
- package/dist/split.css +12 -0
- package/package.json +1 -1
package/dist/plugins/index.js
CHANGED
|
@@ -3,9 +3,10 @@ import {
|
|
|
3
3
|
definePlugin,
|
|
4
4
|
pluginPoints,
|
|
5
5
|
pluginRequires
|
|
6
|
-
} from "../chunks/chunk-
|
|
6
|
+
} from "../chunks/chunk-6PYYF4XU.js";
|
|
7
7
|
import "../chunks/chunk-UUH37KXA.js";
|
|
8
8
|
import "../chunks/chunk-6U545WJG.js";
|
|
9
|
+
import "../chunks/chunk-AQBQ3QZH.js";
|
|
9
10
|
|
|
10
11
|
// src/plugins/index.tsx
|
|
11
12
|
import { useEffect, useState, useSyncExternalStore } from "react";
|
package/dist/react/index.js
CHANGED
|
@@ -31,47 +31,15 @@ import {
|
|
|
31
31
|
readSse
|
|
32
32
|
} from "../chunks/chunk-KG23PQI2.js";
|
|
33
33
|
import {
|
|
34
|
-
Activity,
|
|
35
|
-
AppWindow,
|
|
36
|
-
ArrowDown,
|
|
37
|
-
ArrowUpRight,
|
|
38
34
|
BUILTIN_CUSTOM,
|
|
39
|
-
BookOpen,
|
|
40
|
-
Check,
|
|
41
|
-
ChevronRight,
|
|
42
|
-
CircleCheck,
|
|
43
|
-
CircleSlash,
|
|
44
|
-
CircleX,
|
|
45
|
-
Clock,
|
|
46
|
-
Coins,
|
|
47
35
|
Composer,
|
|
48
|
-
Copy,
|
|
49
|
-
ExternalLink,
|
|
50
|
-
FilePenLine,
|
|
51
|
-
FileSpreadsheet,
|
|
52
|
-
FileText,
|
|
53
|
-
Folder,
|
|
54
|
-
Gauge,
|
|
55
|
-
Globe,
|
|
56
|
-
Image,
|
|
57
|
-
Inbox,
|
|
58
|
-
ListChecks,
|
|
59
|
-
LoaderCircle,
|
|
60
36
|
ModelPicker,
|
|
61
|
-
OctagonX,
|
|
62
37
|
PilotoContext,
|
|
63
38
|
ReferenceChips,
|
|
64
|
-
RotateCcw,
|
|
65
39
|
STRINGS_EN,
|
|
66
40
|
STRINGS_ES,
|
|
67
|
-
Search,
|
|
68
|
-
Send,
|
|
69
|
-
ShieldAlert,
|
|
70
41
|
Suggestions,
|
|
71
42
|
TurnContext,
|
|
72
|
-
UsersRound,
|
|
73
|
-
Wrench,
|
|
74
|
-
X,
|
|
75
43
|
definePlugin,
|
|
76
44
|
isDev,
|
|
77
45
|
mimeOf,
|
|
@@ -80,7 +48,7 @@ import {
|
|
|
80
48
|
resolvePlugins,
|
|
81
49
|
rootProps,
|
|
82
50
|
usePiloto
|
|
83
|
-
} from "../chunks/chunk-
|
|
51
|
+
} from "../chunks/chunk-6PYYF4XU.js";
|
|
84
52
|
import {
|
|
85
53
|
TOOL_VERBS_EN,
|
|
86
54
|
TOOL_VERBS_ES,
|
|
@@ -97,6 +65,40 @@ import {
|
|
|
97
65
|
formatDuration,
|
|
98
66
|
systemNoteOf
|
|
99
67
|
} from "../chunks/chunk-6U545WJG.js";
|
|
68
|
+
import {
|
|
69
|
+
Activity,
|
|
70
|
+
AppWindow,
|
|
71
|
+
ArrowDown,
|
|
72
|
+
ArrowUpRight,
|
|
73
|
+
BookOpen,
|
|
74
|
+
Check,
|
|
75
|
+
ChevronRight,
|
|
76
|
+
CircleCheck,
|
|
77
|
+
CircleSlash,
|
|
78
|
+
CircleX,
|
|
79
|
+
Clock,
|
|
80
|
+
Coins,
|
|
81
|
+
Copy,
|
|
82
|
+
ExternalLink,
|
|
83
|
+
FilePenLine,
|
|
84
|
+
FileSpreadsheet,
|
|
85
|
+
FileText,
|
|
86
|
+
Folder,
|
|
87
|
+
Gauge,
|
|
88
|
+
Globe,
|
|
89
|
+
Image,
|
|
90
|
+
Inbox,
|
|
91
|
+
ListChecks,
|
|
92
|
+
LoaderCircle,
|
|
93
|
+
OctagonX,
|
|
94
|
+
RotateCcw,
|
|
95
|
+
Search,
|
|
96
|
+
Send,
|
|
97
|
+
ShieldAlert,
|
|
98
|
+
UsersRound,
|
|
99
|
+
Wrench,
|
|
100
|
+
X
|
|
101
|
+
} from "../chunks/chunk-AQBQ3QZH.js";
|
|
100
102
|
|
|
101
103
|
// src/react/Piloto.tsx
|
|
102
104
|
import {
|
package/dist/split/index.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ export type PilotoSplitOptions = {
|
|
|
9
9
|
desktopMinWidth?: number;
|
|
10
10
|
/** Se llama cada vez que se abre o se cierra (p. ej. para contraer el menú lateral de la app). */
|
|
11
11
|
onOpenChange?: (open: boolean) => void;
|
|
12
|
+
/** Atajo para abrir/cerrar con ⌘/Ctrl + esta tecla (default "i"; `false` lo apaga). */
|
|
13
|
+
shortcut?: string | false;
|
|
14
|
+
/** Esc cierra el panel de escritorio (default true; en la hoja lo maneja vaul). */
|
|
15
|
+
escapeToClose?: boolean;
|
|
12
16
|
};
|
|
13
17
|
export declare function usePilotoSplit(options: PilotoSplitOptions | string): {
|
|
14
18
|
isDesktop: boolean;
|
|
@@ -71,3 +75,29 @@ export declare function PilotoLauncher({ split, label, avatarSrc, className, sty
|
|
|
71
75
|
className?: string;
|
|
72
76
|
style?: CSSProperties;
|
|
73
77
|
}): import("react").JSX.Element;
|
|
78
|
+
/**
|
|
79
|
+
* La conversación visible: una llave que se guarda en el navegador y cambia con «Nueva conversación».
|
|
80
|
+
* La app arma con ella el `threadId` (p. ej. `${base}-${key}`); el hilo anterior NO se borra (sigue en
|
|
81
|
+
* el servidor), sólo deja de verse. Sin almacenamiento, arranca en "1".
|
|
82
|
+
*/
|
|
83
|
+
export declare function useConversationKey(storageKey: string): readonly [string, () => void];
|
|
84
|
+
/**
|
|
85
|
+
* La carcasa estándar del piloto en el panel o la hoja: encabezado (avatar, nombre y acciones:
|
|
86
|
+
* «Nueva conversación» y cerrar) y el chat debajo. En el panel queda pegado a la ventana aunque la
|
|
87
|
+
* página tenga scroll (el composer siempre a la vista). Va dentro de `PilotoSplit` (`piloto={(v) => …}`).
|
|
88
|
+
*/
|
|
89
|
+
export declare function PilotoPanel({ variant, title, avatar, onClose, onNewConversation, canStartNew, actions, locale, className, children, }: {
|
|
90
|
+
variant: PilotoSplitVariant;
|
|
91
|
+
title: ReactNode;
|
|
92
|
+
avatar?: ReactNode;
|
|
93
|
+
onClose?: () => void;
|
|
94
|
+
/** Sin esto no sale el botón. Normalmente `rotate` de `useConversationKey`. */
|
|
95
|
+
onNewConversation?: () => void;
|
|
96
|
+
/** Ocultar «Nueva conversación» (p. ej. con el hilo vacío). */
|
|
97
|
+
canStartNew?: boolean;
|
|
98
|
+
/** Más botones a la derecha del encabezado, antes de los estándar. */
|
|
99
|
+
actions?: ReactNode;
|
|
100
|
+
locale?: "es" | "en";
|
|
101
|
+
className?: string;
|
|
102
|
+
children: ReactNode;
|
|
103
|
+
}): import("react").JSX.Element;
|
package/dist/split/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SquarePen,
|
|
3
|
+
X
|
|
4
|
+
} from "../chunks/chunk-AQBQ3QZH.js";
|
|
5
|
+
|
|
1
6
|
// src/split/index.tsx
|
|
2
7
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
3
8
|
import { Group, Panel, Separator, usePanelRef } from "react-resizable-panels";
|
|
@@ -7,7 +12,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
7
12
|
var SHEET_SNAPS = [0.6, 0.94];
|
|
8
13
|
var OPEN_MS = 320;
|
|
9
14
|
function usePilotoSplit(options) {
|
|
10
|
-
const { widthKey, defaultWidth = 420, desktopMinWidth = 1024, onOpenChange } = typeof options === "string" ? { widthKey: options } : options;
|
|
15
|
+
const { widthKey, defaultWidth = 420, desktopMinWidth = 1024, onOpenChange, shortcut = "i", escapeToClose = true } = typeof options === "string" ? { widthKey: options } : options;
|
|
11
16
|
const isDesktop = useIsDesktop(desktopMinWidth);
|
|
12
17
|
const panelRef = usePanelRef();
|
|
13
18
|
const [panelOpen, setPanelOpen] = useState(false);
|
|
@@ -47,6 +52,21 @@ function usePilotoSplit(options) {
|
|
|
47
52
|
useEffect(() => {
|
|
48
53
|
notify.current?.(isOpen);
|
|
49
54
|
}, [isOpen]);
|
|
55
|
+
const toggleRef = useRef(() => {
|
|
56
|
+
});
|
|
57
|
+
toggleRef.current = isOpen ? close : open;
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const onKey = (e) => {
|
|
60
|
+
if (shortcut && (e.metaKey || e.ctrlKey) && !e.altKey && e.key.toLowerCase() === shortcut.toLowerCase()) {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
toggleRef.current();
|
|
63
|
+
} else if (escapeToClose && e.key === "Escape" && !e.defaultPrevented && isDesktop && isOpen) {
|
|
64
|
+
close();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
window.addEventListener("keydown", onKey);
|
|
68
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
69
|
+
}, [shortcut, escapeToClose, isDesktop, isOpen, close]);
|
|
50
70
|
return {
|
|
51
71
|
isDesktop,
|
|
52
72
|
panelRef,
|
|
@@ -230,9 +250,71 @@ function PilotoLauncher({
|
|
|
230
250
|
"gk-launcher"
|
|
231
251
|
) });
|
|
232
252
|
}
|
|
253
|
+
function useConversationKey(storageKey) {
|
|
254
|
+
const [key, setKey] = useState(() => {
|
|
255
|
+
try {
|
|
256
|
+
return localStorage.getItem(storageKey) || "1";
|
|
257
|
+
} catch {
|
|
258
|
+
return "1";
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
const rotate = useCallback(() => {
|
|
262
|
+
const next = Date.now().toString(36);
|
|
263
|
+
try {
|
|
264
|
+
localStorage.setItem(storageKey, next);
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
setKey(next);
|
|
268
|
+
}, [storageKey]);
|
|
269
|
+
return [key, rotate];
|
|
270
|
+
}
|
|
271
|
+
var PANEL_LABELS = {
|
|
272
|
+
es: { newConversation: "Nueva conversaci\xF3n", close: "Cerrar" },
|
|
273
|
+
en: { newConversation: "New conversation", close: "Close" }
|
|
274
|
+
};
|
|
275
|
+
function PilotoPanel({
|
|
276
|
+
variant,
|
|
277
|
+
title,
|
|
278
|
+
avatar,
|
|
279
|
+
onClose,
|
|
280
|
+
onNewConversation,
|
|
281
|
+
canStartNew = true,
|
|
282
|
+
actions,
|
|
283
|
+
locale = "es",
|
|
284
|
+
className = "",
|
|
285
|
+
children
|
|
286
|
+
}) {
|
|
287
|
+
const sticky = useStickyPanelHeight(variant === "panel");
|
|
288
|
+
const t = PANEL_LABELS[locale];
|
|
289
|
+
return /* @__PURE__ */ jsxs(
|
|
290
|
+
"aside",
|
|
291
|
+
{
|
|
292
|
+
ref: sticky.ref,
|
|
293
|
+
"aria-label": typeof title === "string" ? title : void 0,
|
|
294
|
+
style: sticky.style,
|
|
295
|
+
className: `gk-panel ${variant === "panel" ? "gk-panel-side" : ""} ${className}`,
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ jsxs("header", { className: "gk-panel-header", children: [
|
|
298
|
+
/* @__PURE__ */ jsxs("div", { className: "gk-panel-title", children: [
|
|
299
|
+
avatar,
|
|
300
|
+
/* @__PURE__ */ jsx("span", { children: title })
|
|
301
|
+
] }),
|
|
302
|
+
/* @__PURE__ */ jsxs("div", { className: "gk-panel-actions", children: [
|
|
303
|
+
actions,
|
|
304
|
+
onNewConversation && canStartNew && /* @__PURE__ */ jsx("button", { type: "button", className: "gk-panel-btn", onClick: onNewConversation, title: t.newConversation, "aria-label": t.newConversation, children: /* @__PURE__ */ jsx(SquarePen, { size: 17, strokeWidth: 1.8 }) }),
|
|
305
|
+
onClose && variant === "panel" && /* @__PURE__ */ jsx("button", { type: "button", className: "gk-panel-btn", onClick: onClose, title: t.close, "aria-label": t.close, children: /* @__PURE__ */ jsx(X, { size: 18, strokeWidth: 1.8 }) })
|
|
306
|
+
] })
|
|
307
|
+
] }),
|
|
308
|
+
/* @__PURE__ */ jsx("div", { className: "gk-panel-body", children })
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
);
|
|
312
|
+
}
|
|
233
313
|
export {
|
|
234
314
|
PilotoLauncher,
|
|
315
|
+
PilotoPanel,
|
|
235
316
|
PilotoSplit,
|
|
317
|
+
useConversationKey,
|
|
236
318
|
useIsDesktop,
|
|
237
319
|
usePilotoSplit,
|
|
238
320
|
useStickyPanelHeight
|
package/dist/split.css
CHANGED
|
@@ -69,3 +69,15 @@
|
|
|
69
69
|
}
|
|
70
70
|
.gk-launcher img { width: 32px; height: 32px; object-fit: contain; }
|
|
71
71
|
.gk-launcher-icon { padding: 8px; }
|
|
72
|
+
|
|
73
|
+
/* Carcasa estándar del piloto (PilotoPanel). Colores: --gk-panel-bg, --gk-panel-border, --gk-panel-fg, --gk-panel-muted, --gk-panel-hover. */
|
|
74
|
+
.gk-panel { display: flex; width: 100%; flex-direction: column; overflow: hidden; background: var(--gk-panel-bg, #fff); }
|
|
75
|
+
.gk-panel-side { border-left: 1px solid var(--gk-panel-border, #e5e7eb); }
|
|
76
|
+
.gk-panel-header { display: flex; flex-shrink: 0; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px 10px 16px; border-bottom: 1px solid var(--gk-panel-border, #eceef2); }
|
|
77
|
+
.gk-panel-title { display: flex; min-width: 0; align-items: center; gap: 8px; color: var(--gk-panel-fg, #111827); font-size: 14px; font-weight: 600; }
|
|
78
|
+
.gk-panel-title > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
79
|
+
.gk-panel-title img { width: 24px; height: 24px; object-fit: contain; flex-shrink: 0; }
|
|
80
|
+
.gk-panel-actions { display: flex; align-items: center; gap: 2px; }
|
|
81
|
+
.gk-panel-btn { display: inline-flex; width: 32px; height: 32px; align-items: center; justify-content: center; border: 0; border-radius: 9999px; background: transparent; color: var(--gk-panel-muted, #6b7280); cursor: pointer; }
|
|
82
|
+
.gk-panel-btn:hover { background: var(--gk-panel-hover, rgb(17 24 39 / 0.06)); color: var(--gk-panel-fg, #111827); }
|
|
83
|
+
.gk-panel-body { display: flex; min-height: 0; flex: 1; flex-direction: column; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghostykit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Ghosty Autopilot — the autopilot chat for your React app, on AG-UI: works with LangGraph, Mastra, CrewAI or any AG-UI agent. Streaming text, agent steps, human approval cards (interrupt/resume), attachments and voice.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/core/index.js",
|