skybridge 0.0.0-dev.b10ac04 → 0.0.0-dev.b25e54f

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 (120) hide show
  1. package/dist/src/server/server.d.ts +1 -0
  2. package/dist/src/server/server.js +19 -7
  3. package/dist/src/server/server.js.map +1 -1
  4. package/dist/src/server/templateHelper.d.ts +9 -8
  5. package/dist/src/server/templateHelper.js +0 -8
  6. package/dist/src/server/templateHelper.js.map +1 -1
  7. package/dist/src/server/templates/development.hbs +1 -0
  8. package/dist/src/server/templates/production.hbs +3 -2
  9. package/dist/src/test/widget.test.js +23 -2
  10. package/dist/src/test/widget.test.js.map +1 -1
  11. package/dist/src/web/hooks/index.d.ts +13 -0
  12. package/dist/src/web/hooks/index.js +14 -0
  13. package/dist/src/web/hooks/index.js.map +1 -0
  14. package/dist/src/web/hooks/use-call-tool.d.ts +62 -0
  15. package/dist/src/web/{use-call-tool.js → hooks/use-call-tool.js} +28 -4
  16. package/dist/src/web/hooks/use-call-tool.js.map +1 -0
  17. package/dist/src/web/hooks/use-call-tool.test.js +163 -0
  18. package/dist/src/web/hooks/use-call-tool.test.js.map +1 -0
  19. package/dist/src/web/hooks/use-display-mode.d.ts +4 -0
  20. package/dist/src/web/hooks/use-display-mode.js +7 -0
  21. package/dist/src/web/hooks/use-display-mode.js.map +1 -0
  22. package/dist/src/web/hooks/use-display-mode.test.js +40 -0
  23. package/dist/src/web/hooks/use-display-mode.test.js.map +1 -0
  24. package/dist/src/web/hooks/use-locale.d.ts +1 -0
  25. package/dist/src/web/hooks/use-locale.js +5 -0
  26. package/dist/src/web/hooks/use-locale.js.map +1 -0
  27. package/dist/src/web/hooks/use-locale.test.d.ts +1 -0
  28. package/dist/src/web/hooks/use-locale.test.js +21 -0
  29. package/dist/src/web/hooks/use-locale.test.js.map +1 -0
  30. package/dist/src/web/hooks/use-open-external.d.ts +1 -0
  31. package/dist/src/web/hooks/use-open-external.js +6 -0
  32. package/dist/src/web/hooks/use-open-external.js.map +1 -0
  33. package/dist/src/web/hooks/use-open-external.test.d.ts +1 -0
  34. package/dist/src/web/hooks/use-open-external.test.js +24 -0
  35. package/dist/src/web/hooks/use-open-external.test.js.map +1 -0
  36. package/dist/src/web/{use-openai-global.d.ts → hooks/use-openai-global.d.ts} +1 -1
  37. package/dist/src/web/{use-openai-global.js → hooks/use-openai-global.js} +4 -2
  38. package/dist/src/web/hooks/use-openai-global.js.map +1 -0
  39. package/dist/src/web/hooks/use-request-modal.d.ts +5 -0
  40. package/dist/src/web/hooks/use-request-modal.js +9 -0
  41. package/dist/src/web/hooks/use-request-modal.js.map +1 -0
  42. package/dist/src/web/hooks/use-request-modal.test.d.ts +1 -0
  43. package/dist/src/web/hooks/use-request-modal.test.js +24 -0
  44. package/dist/src/web/hooks/use-request-modal.test.js.map +1 -0
  45. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +1 -0
  46. package/dist/src/web/hooks/use-send-follow-up-message.js +11 -0
  47. package/dist/src/web/hooks/use-send-follow-up-message.js.map +1 -0
  48. package/dist/src/web/hooks/use-theme.d.ts +1 -0
  49. package/dist/src/web/hooks/use-theme.js +5 -0
  50. package/dist/src/web/hooks/use-theme.js.map +1 -0
  51. package/dist/src/web/hooks/use-theme.test.d.ts +1 -0
  52. package/dist/src/web/hooks/use-theme.test.js +26 -0
  53. package/dist/src/web/hooks/use-theme.test.js.map +1 -0
  54. package/dist/src/web/hooks/use-tool-info.d.ts +25 -0
  55. package/dist/src/web/hooks/use-tool-info.js +22 -0
  56. package/dist/src/web/hooks/use-tool-info.js.map +1 -0
  57. package/dist/src/web/hooks/use-tool-info.test-d.d.ts +1 -0
  58. package/dist/src/web/hooks/use-tool-info.test-d.js +74 -0
  59. package/dist/src/web/hooks/use-tool-info.test-d.js.map +1 -0
  60. package/dist/src/web/hooks/use-tool-info.test.d.ts +1 -0
  61. package/dist/src/web/hooks/use-tool-info.test.js +59 -0
  62. package/dist/src/web/hooks/use-tool-info.test.js.map +1 -0
  63. package/dist/src/web/hooks/use-tool-output.d.ts +4 -0
  64. package/dist/src/web/hooks/use-tool-output.js +9 -0
  65. package/dist/src/web/hooks/use-tool-output.js.map +1 -0
  66. package/dist/src/web/hooks/use-tool-response-metadata.d.ts +4 -0
  67. package/dist/src/web/hooks/use-tool-response-metadata.js +8 -0
  68. package/dist/src/web/hooks/use-tool-response-metadata.js.map +1 -0
  69. package/dist/src/web/hooks/use-user-agent.d.ts +1 -0
  70. package/dist/src/web/hooks/use-user-agent.js +5 -0
  71. package/dist/src/web/hooks/use-user-agent.js.map +1 -0
  72. package/dist/src/web/hooks/use-user-agent.test.d.ts +1 -0
  73. package/dist/src/web/hooks/use-user-agent.test.js +31 -0
  74. package/dist/src/web/hooks/use-user-agent.test.js.map +1 -0
  75. package/dist/src/web/hooks/use-widget-state.d.ts +4 -0
  76. package/dist/src/web/hooks/use-widget-state.js +54 -0
  77. package/dist/src/web/hooks/use-widget-state.js.map +1 -0
  78. package/dist/src/web/hooks/use-widget-state.test.d.ts +1 -0
  79. package/dist/src/web/hooks/use-widget-state.test.js +60 -0
  80. package/dist/src/web/hooks/use-widget-state.test.js.map +1 -0
  81. package/dist/src/web/index.d.ts +3 -5
  82. package/dist/src/web/index.js +3 -5
  83. package/dist/src/web/index.js.map +1 -1
  84. package/dist/src/web/llm-describe.d.ts +13 -0
  85. package/dist/src/web/llm-describe.js +62 -0
  86. package/dist/src/web/llm-describe.js.map +1 -0
  87. package/dist/src/web/llm-describe.test.d.ts +1 -0
  88. package/dist/src/web/llm-describe.test.js +76 -0
  89. package/dist/src/web/llm-describe.test.js.map +1 -0
  90. package/dist/src/web/plugin/data-llm.d.ts +12 -0
  91. package/dist/src/web/plugin/data-llm.js +96 -0
  92. package/dist/src/web/plugin/data-llm.js.map +1 -0
  93. package/dist/src/web/plugin/data-llm.test.d.ts +1 -0
  94. package/dist/src/web/plugin/data-llm.test.js +81 -0
  95. package/dist/src/web/plugin/data-llm.test.js.map +1 -0
  96. package/dist/src/web/{plugin.js → plugin/plugin.js} +7 -4
  97. package/dist/src/web/plugin/plugin.js.map +1 -0
  98. package/dist/src/web/types.d.ts +17 -3
  99. package/dist/src/web/types.js +1 -0
  100. package/dist/src/web/types.js.map +1 -1
  101. package/dist/vitest.config.js +0 -1
  102. package/dist/vitest.config.js.map +1 -1
  103. package/package.json +6 -2
  104. package/dist/src/test/setup.js +0 -9
  105. package/dist/src/test/setup.js.map +0 -1
  106. package/dist/src/web/plugin.js.map +0 -1
  107. package/dist/src/web/use-call-tool.d.ts +0 -54
  108. package/dist/src/web/use-call-tool.js.map +0 -1
  109. package/dist/src/web/use-call-tool.test.js +0 -66
  110. package/dist/src/web/use-call-tool.test.js.map +0 -1
  111. package/dist/src/web/use-openai-global.js.map +0 -1
  112. package/dist/src/web/use-tool-output.d.ts +0 -3
  113. package/dist/src/web/use-tool-output.js +0 -5
  114. package/dist/src/web/use-tool-output.js.map +0 -1
  115. package/dist/src/web/use-tool-response-metadata.d.ts +0 -3
  116. package/dist/src/web/use-tool-response-metadata.js +0 -5
  117. package/dist/src/web/use-tool-response-metadata.js.map +0 -1
  118. /package/dist/src/web/{use-call-tool.test.d.ts → hooks/use-call-tool.test.d.ts} +0 -0
  119. /package/dist/src/{test/setup.d.ts → web/hooks/use-display-mode.test.d.ts} +0 -0
  120. /package/dist/src/web/{plugin.d.ts → plugin/plugin.d.ts} +0 -0
@@ -0,0 +1,60 @@
1
+ import { useWidgetState } from "./use-widget-state.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach, } from "vitest";
3
+ import { renderHook, act } from "@testing-library/react";
4
+ describe("useWidgetState", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ widgetState: null,
9
+ setWidgetState: vi.fn().mockResolvedValue(undefined),
10
+ };
11
+ vi.stubGlobal("openai", OpenaiMock);
12
+ });
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ vi.resetAllMocks();
16
+ });
17
+ const defaultState = { count: 0, name: "test" };
18
+ const windowState = { count: 5, name: "window" };
19
+ it("should initialize with default state when window.openai.widgetState is null", () => {
20
+ OpenaiMock.widgetState = null;
21
+ const { result } = renderHook(() => useWidgetState(defaultState));
22
+ expect(result.current[0]).toEqual(defaultState);
23
+ });
24
+ it("should initialize with window.openai.widgetState when available", () => {
25
+ OpenaiMock.widgetState = windowState;
26
+ const { result } = renderHook(() => useWidgetState(defaultState));
27
+ expect(result.current[0]).toEqual(windowState);
28
+ });
29
+ it("should call window.openai.setWidgetState when setWidgetState is called with a new state", async () => {
30
+ const { result } = renderHook(() => useWidgetState(defaultState));
31
+ const newState = { count: 10, name: "updated" };
32
+ act(() => {
33
+ result.current[1](newState);
34
+ });
35
+ expect(OpenaiMock.setWidgetState).toHaveBeenCalledWith(newState);
36
+ expect(result.current[0]).toEqual(newState);
37
+ });
38
+ it("should call window.openai.setWidgetState when setWidgetState is called with a function updater", async () => {
39
+ const { result } = renderHook(() => useWidgetState(defaultState));
40
+ act(() => {
41
+ result.current[1]((prev) => ({ ...prev, count: prev.count + 1 }));
42
+ });
43
+ expect(OpenaiMock.setWidgetState).toHaveBeenCalledWith({
44
+ count: 1,
45
+ name: "test",
46
+ });
47
+ expect(result.current[0]).toEqual({ count: 1, name: "test" });
48
+ });
49
+ it("should update state when window.openai.widgetState changes", () => {
50
+ OpenaiMock.widgetState = defaultState;
51
+ const { result, rerender } = renderHook(() => useWidgetState(defaultState));
52
+ expect(result.current[0]).toEqual(defaultState);
53
+ // Simulate window.openai.widgetState changing
54
+ OpenaiMock.widgetState = windowState;
55
+ // Trigger re-render to simulate the useEffect running
56
+ rerender();
57
+ expect(result.current[0]).toEqual(windowState);
58
+ });
59
+ });
60
+ //# sourceMappingURL=use-widget-state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-widget-state.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-widget-state.test.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,5 @@
1
- export { useOpenAiGlobal } from "./use-openai-global.js";
2
- export { useToolOutput } from "./use-tool-output.js";
3
- export { useToolResponseMetadata } from "./use-tool-response-metadata.js";
4
- export { useCallTool } from "./use-call-tool.js";
5
1
  export * from "./types.js";
2
+ export * from "./llm-describe.js";
6
3
  export { mountWidget } from "./mount-widget.js";
7
- export { skybridge } from "./plugin.js";
4
+ export { skybridge } from "./plugin/plugin.js";
5
+ export * from "./hooks/index.js";
@@ -1,8 +1,6 @@
1
- export { useOpenAiGlobal } from "./use-openai-global.js";
2
- export { useToolOutput } from "./use-tool-output.js";
3
- export { useToolResponseMetadata } from "./use-tool-response-metadata.js";
4
- export { useCallTool } from "./use-call-tool.js";
5
1
  export * from "./types.js";
2
+ export * from "./llm-describe.js";
6
3
  export { mountWidget } from "./mount-widget.js";
7
- export { skybridge } from "./plugin.js";
4
+ export { skybridge } from "./plugin/plugin.js";
5
+ export * from "./hooks/index.js";
8
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/web/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type ReactNode } from "react";
2
+ export type LLMDescribeContent = string;
3
+ export interface LLMDescribeNode {
4
+ id: string;
5
+ parentId: string | null;
6
+ content: string | null;
7
+ }
8
+ interface LLMDescribeProps {
9
+ content: LLMDescribeContent | null | undefined;
10
+ children?: ReactNode;
11
+ }
12
+ export declare function LLMDescribe({ content, children }: LLMDescribeProps): import("react/jsx-runtime").JSX.Element;
13
+ export {};
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useId, } from "react";
3
+ const nodes = new Map();
4
+ function setNode(node) {
5
+ nodes.set(node.id, node);
6
+ onChange();
7
+ }
8
+ function removeNode(id) {
9
+ nodes.delete(id);
10
+ onChange();
11
+ }
12
+ function onChange() {
13
+ const description = getLLMDescriptionString();
14
+ window.openai.setWidgetState({
15
+ ...window.openai.widgetState,
16
+ __widget_context: description,
17
+ });
18
+ }
19
+ const ParentIdContext = createContext(null);
20
+ export function LLMDescribe({ content, children }) {
21
+ const parentId = useContext(ParentIdContext);
22
+ const id = useId();
23
+ useEffect(() => {
24
+ setNode({
25
+ id,
26
+ parentId,
27
+ content: content ?? null,
28
+ });
29
+ return () => {
30
+ removeNode(id);
31
+ };
32
+ }, [id, parentId, content]);
33
+ return (_jsx(ParentIdContext.Provider, { value: id, children: children }));
34
+ }
35
+ function getLLMDescriptionString() {
36
+ const byParent = new Map();
37
+ for (const node of Array.from(nodes.values())) {
38
+ const key = node.parentId ?? null;
39
+ if (!byParent.has(key))
40
+ byParent.set(key, []);
41
+ byParent.get(key).push(node);
42
+ }
43
+ for (const list of byParent.values()) {
44
+ list.sort((a, b) => a.id.localeCompare(b.id));
45
+ }
46
+ const lines = [];
47
+ function traverseTree(parentId, depth) {
48
+ const children = byParent.get(parentId);
49
+ if (!children)
50
+ return;
51
+ for (const child of children) {
52
+ if (child.content && child.content.trim()) {
53
+ const indent = " ".repeat(depth);
54
+ lines.push(`${indent}- ${child.content.trim()}`);
55
+ }
56
+ traverseTree(child.id, depth + 1);
57
+ }
58
+ }
59
+ traverseTree(null, 0);
60
+ return lines.join("\n");
61
+ }
62
+ //# sourceMappingURL=llm-describe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-describe.js","sourceRoot":"","sources":["../../../src/web/llm-describe.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { render } from "@testing-library/react";
3
+ import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
4
+ import { LLMDescribe } from "./llm-describe.js";
5
+ describe("LLMDescribe", () => {
6
+ let OpenaiMock;
7
+ beforeEach(() => {
8
+ OpenaiMock = {
9
+ widgetState: {},
10
+ setWidgetState: vi.fn(),
11
+ };
12
+ // Use Object.defineProperty to ensure it persists
13
+ Object.defineProperty(globalThis, "openai", {
14
+ value: OpenaiMock,
15
+ writable: true,
16
+ configurable: true,
17
+ });
18
+ // Also set on window for browser-like environment
19
+ if (typeof window !== "undefined") {
20
+ Object.defineProperty(window, "openai", {
21
+ value: OpenaiMock,
22
+ writable: true,
23
+ configurable: true,
24
+ });
25
+ }
26
+ vi.stubGlobal("openai", OpenaiMock);
27
+ });
28
+ afterEach(() => {
29
+ vi.resetAllMocks();
30
+ // Keep the mock available for React cleanup, but reset it
31
+ if (typeof window !== "undefined" && window.openai) {
32
+ window.openai.setWidgetState = vi.fn();
33
+ window.openai.widgetState = {};
34
+ }
35
+ });
36
+ it("should register a node with content and call setWidgetState", () => {
37
+ render(_jsx(LLMDescribe, { content: "Test content", children: _jsx("div", { children: "Child" }) }));
38
+ expect(OpenaiMock.setWidgetState).toHaveBeenCalled();
39
+ const callArgs = OpenaiMock.setWidgetState.mock.calls[0]?.[0];
40
+ expect(callArgs).toHaveProperty("__widget_context");
41
+ expect(callArgs?.__widget_context).toContain("- Test content");
42
+ });
43
+ it("should preserve existing widgetState when updating context", () => {
44
+ OpenaiMock.widgetState = { existingKey: "existingValue" };
45
+ render(_jsx(LLMDescribe, { content: "Test content", children: _jsx("div", { children: "Child" }) }));
46
+ const callArgs = OpenaiMock.setWidgetState.mock.calls[0]?.[0];
47
+ expect(callArgs).toHaveProperty("existingKey", "existingValue");
48
+ expect(callArgs).toHaveProperty("__widget_context");
49
+ });
50
+ it("should handle deeply nested LLMDescribe components", () => {
51
+ render(_jsxs(LLMDescribe, { content: "Level 1", children: [_jsx(LLMDescribe, { content: "Level 2A" }), _jsx(LLMDescribe, { content: "Level 2B", children: _jsx(LLMDescribe, { content: "Level 3", children: _jsx("div", { children: "Content" }) }) })] }));
52
+ const callArgs = OpenaiMock.setWidgetState.mock.calls[OpenaiMock.setWidgetState.mock.calls.length - 1]?.[0];
53
+ const context = callArgs?.__widget_context;
54
+ expect(context).toContain("- Level 1");
55
+ expect(context).toContain(" - Level 2A");
56
+ expect(context).toContain(" - Level 2B");
57
+ expect(context).toContain(" - Level 3");
58
+ });
59
+ it("should update context when content changes", () => {
60
+ const { rerender } = render(_jsx(LLMDescribe, { content: "Initial content", children: _jsx("div", { children: "Child" }) }));
61
+ const initialCalls = OpenaiMock.setWidgetState.mock.calls.length;
62
+ rerender(_jsx(LLMDescribe, { content: "Updated content", children: _jsx("div", { children: "Child" }) }));
63
+ expect(OpenaiMock.setWidgetState.mock.calls.length).toBeGreaterThan(initialCalls);
64
+ const lastCallArgs = OpenaiMock.setWidgetState.mock.calls[OpenaiMock.setWidgetState.mock.calls.length - 1]?.[0];
65
+ expect(lastCallArgs?.__widget_context).toContain("- Updated content");
66
+ });
67
+ it("should remove node and update context when component unmounts", () => {
68
+ const { unmount } = render(_jsx(LLMDescribe, { content: "Content to remove", children: _jsx("div", { children: "Child" }) }));
69
+ const callsBeforeUnmount = OpenaiMock.setWidgetState.mock.calls.length;
70
+ unmount();
71
+ expect(OpenaiMock.setWidgetState.mock.calls.length).toBeGreaterThan(callsBeforeUnmount);
72
+ const lastCallArgs = OpenaiMock.setWidgetState.mock.calls[OpenaiMock.setWidgetState.mock.calls.length - 1]?.[0];
73
+ expect(lastCallArgs?.__widget_context).not.toContain("Content to remove");
74
+ });
75
+ });
76
+ //# sourceMappingURL=llm-describe.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-describe.test.js","sourceRoot":"","sources":["../../../src/web/llm-describe.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const transform: (code: string, id: string) => Promise<{
2
+ code: string;
3
+ map: {
4
+ version: number;
5
+ sources: string[];
6
+ names: string[];
7
+ sourceRoot?: string | undefined;
8
+ sourcesContent?: string[] | undefined;
9
+ mappings: string;
10
+ file: string;
11
+ } | null;
12
+ } | null>;
@@ -0,0 +1,96 @@
1
+ const LLM_IMPORT_SOURCE = "skybridge/web";
2
+ function createBabelPlugin(t) {
3
+ return {
4
+ name: "data-llm-babel",
5
+ visitor: {
6
+ Program: {
7
+ enter(path, state) {
8
+ state.hasLLMDescribeImport = false;
9
+ state.needsLLMDescribeImport = false;
10
+ for (const node of path.node.body) {
11
+ if (!t.isImportDeclaration(node))
12
+ continue;
13
+ if (node.source.value !== LLM_IMPORT_SOURCE)
14
+ continue;
15
+ const hasSpecifier = node.specifiers.some((s) => t.isImportSpecifier(s) &&
16
+ t.isIdentifier(s.imported, { name: "LLMDescribe" }));
17
+ if (hasSpecifier) {
18
+ state.hasLLMDescribeImport = true;
19
+ break;
20
+ }
21
+ }
22
+ },
23
+ exit(path, state) {
24
+ if (state.needsLLMDescribeImport && !state.hasLLMDescribeImport) {
25
+ const importDecl = t.importDeclaration([
26
+ t.importSpecifier(t.identifier("LLMDescribe"), t.identifier("LLMDescribe")),
27
+ ], t.stringLiteral(LLM_IMPORT_SOURCE));
28
+ path.node.body.unshift(importDecl);
29
+ }
30
+ },
31
+ },
32
+ JSXElement(path, state) {
33
+ const opening = path.node.openingElement;
34
+ const attrs = opening.attributes;
35
+ const llmAttrIndex = attrs.findIndex((attr) => t.isJSXAttribute(attr) &&
36
+ t.isJSXIdentifier(attr.name, { name: "data-llm" }));
37
+ if (llmAttrIndex === -1)
38
+ return;
39
+ const llmAttr = attrs[llmAttrIndex];
40
+ const newAttrs = [...attrs];
41
+ newAttrs.splice(llmAttrIndex, 1);
42
+ opening.attributes = newAttrs;
43
+ let contentExpression;
44
+ if (!llmAttr.value) {
45
+ contentExpression = t.stringLiteral("");
46
+ }
47
+ else if (t.isStringLiteral(llmAttr.value)) {
48
+ contentExpression = llmAttr.value;
49
+ }
50
+ else if (t.isJSXExpressionContainer(llmAttr.value)) {
51
+ contentExpression = llmAttr.value.expression;
52
+ }
53
+ else {
54
+ return;
55
+ }
56
+ const contentAttr = t.jsxAttribute(t.jsxIdentifier("content"), t.isStringLiteral(contentExpression)
57
+ ? contentExpression
58
+ : t.jsxExpressionContainer(contentExpression));
59
+ const llmOpening = t.jsxOpeningElement(t.jsxIdentifier("LLMDescribe"), [
60
+ contentAttr,
61
+ ]);
62
+ const llmClosing = t.jsxClosingElement(t.jsxIdentifier("LLMDescribe"));
63
+ const wrapped = t.jsxElement(llmOpening, llmClosing, [path.node], false);
64
+ state.needsLLMDescribeImport = true;
65
+ path.replaceWith(wrapped);
66
+ },
67
+ },
68
+ };
69
+ }
70
+ export const transform = async (code, id) => {
71
+ if (!/\.(jsx|tsx)$/.test(id)) {
72
+ return null;
73
+ }
74
+ if (id.includes("node_modules")) {
75
+ return null;
76
+ }
77
+ // Dynamic import to ensure @babel/core is only loaded in Node.js context
78
+ const { types: t, transformSync } = await import("@babel/core");
79
+ const babelOptions = {
80
+ plugins: [createBabelPlugin(t)],
81
+ parserOpts: {
82
+ plugins: ["jsx", "typescript"],
83
+ },
84
+ filename: id,
85
+ sourceFileName: id,
86
+ };
87
+ const result = transformSync(code, babelOptions);
88
+ if (!result || !result.code) {
89
+ return null;
90
+ }
91
+ return {
92
+ code: result.code,
93
+ map: result.map || null,
94
+ };
95
+ };
96
+ //# sourceMappingURL=data-llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-llm.js","sourceRoot":"","sources":["../../../../src/web/plugin/data-llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { transform } from "./data-llm.js";
3
+ describe("data-llm plugin", () => {
4
+ it("should transform JSX element with data-llm string attribute", async () => {
5
+ const code = `
6
+ function Component() {
7
+ return <div data-llm="Test description">Content</div>;
8
+ }
9
+ `;
10
+ const result = await transform(code, "test.tsx");
11
+ expect(result).not.toBeNull();
12
+ expect(result?.code).toContain("LLMDescribe");
13
+ expect(result?.code).toContain('content="Test description"');
14
+ expect(result?.code).not.toContain("data-llm");
15
+ });
16
+ it("should transform JSX element with data-llm expression attribute", async () => {
17
+ const code = `
18
+ function Component() {
19
+ const desc = "Dynamic description";
20
+ return <div data-llm={desc}>Content</div>;
21
+ }
22
+ `;
23
+ const result = await transform(code, "test.tsx");
24
+ expect(result).not.toBeNull();
25
+ expect(result?.code).toContain("LLMDescribe");
26
+ expect(result?.code).toContain("content={desc}");
27
+ expect(result?.code).not.toContain("data-llm");
28
+ });
29
+ it("should add import for LLMDescribe when not present", async () => {
30
+ const code = `
31
+ function Component() {
32
+ return <div data-llm="Test">Content</div>;
33
+ }
34
+ `;
35
+ const result = await transform(code, "test.tsx");
36
+ expect(result).not.toBeNull();
37
+ expect(result?.code).toContain('import { LLMDescribe } from "skybridge/web"');
38
+ });
39
+ it("should handle LLMDescribe imports correctly", async () => {
40
+ // No duplicate import
41
+ const codeWithImport = `
42
+ import { LLMDescribe } from "skybridge/web";
43
+ function Component() {
44
+ return <div data-llm="Test">Content</div>;
45
+ }
46
+ `;
47
+ const result1 = await transform(codeWithImport, "test.tsx");
48
+ expect(result1?.code.match(/import.*LLMDescribe.*from.*skybridge\/web/g)).toHaveLength(1);
49
+ // Preserve other imports and add missing LLMDescribe
50
+ const codeWithOthers = `
51
+ import React from "react";
52
+ import { useState } from "react";
53
+ function Component() {
54
+ return <div data-llm="Test">Content</div>;
55
+ }
56
+ `;
57
+ const result2 = await transform(codeWithOthers, "test.tsx");
58
+ expect(result2?.code).toContain('import React from "react"');
59
+ expect(result2?.code).toContain('import { useState } from "react"');
60
+ expect(result2?.code).toContain('import { LLMDescribe } from "skybridge/web"');
61
+ });
62
+ it("should handle complex JSX with multiple data-llm attributes", async () => {
63
+ const code = `
64
+ function Component() {
65
+ return (
66
+ <div>
67
+ <section data-llm="Section 1">
68
+ <p>Content 1</p>
69
+ </section>
70
+ <section data-llm="Section 2">
71
+ <p>Content 2</p>
72
+ </section>
73
+ </div>
74
+ );
75
+ }
76
+ `;
77
+ const result = await transform(code, "test.tsx");
78
+ expect(result).toMatchSnapshot();
79
+ });
80
+ });
81
+ //# sourceMappingURL=data-llm.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-llm.test.js","sourceRoot":"","sources":["../../../../src/web/plugin/data-llm.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,IAAI,GAAG;;;;KAIZ,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,IAAI,GAAG;;;;;KAKZ,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,IAAI,GAAG;;;;KAIZ,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAC5B,6CAA6C,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,sBAAsB;QACtB,MAAM,cAAc,GAAG;;;;;KAKtB,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,CACJ,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAClE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAElB,qDAAqD;QACrD,MAAM,cAAc,GAAG;;;;;;KAMtB,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QACpE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,SAAS,CAC7B,6CAA6C,CAC9C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,IAAI,GAAG;;;;;;;;;;;;;KAaZ,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { transform as dataLlmTransform } from "./data-llm.js";
1
2
  export function skybridge() {
2
3
  return {
3
4
  name: "skybridge",
@@ -12,19 +13,21 @@ export function skybridge() {
12
13
  file,
13
14
  ]));
14
15
  return {
16
+ base: "/assets",
15
17
  build: {
18
+ manifest: true,
16
19
  minify: true,
17
20
  cssCodeSplit: false,
18
21
  rollupOptions: {
19
22
  input,
20
- output: {
21
- entryFileNames: "[name].js",
22
- assetFileNames: "[name][extname]",
23
- },
24
23
  },
25
24
  },
26
25
  };
27
26
  },
27
+ enforce: "pre",
28
+ async transform(code, id) {
29
+ return await dataLlmTransform(code, id);
30
+ },
28
31
  };
29
32
  }
30
33
  //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../../src/web/plugin/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,UAAU,SAAS;IACvB,OAAO;QACL,IAAI,EAAE,WAAW;QAEjB,KAAK,CAAC,MAAM,CAAC,MAAM;YACjB,4EAA4E;YAC5E,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;YAE9C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YACjD,MAAM,cAAc,GAAG,OAAO,CAC5B,WAAW,EACX,oCAAoC,CACrC,CAAC;YAEF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAC9B,QAAQ,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACrC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC3C,IAAI;aACL,CAAC,CACH,CAAC;YAEF,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE;oBACL,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,IAAI;oBACZ,YAAY,EAAE,KAAK;oBACnB,aAAa,EAAE;wBACb,KAAK;qBACN;iBACF;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,KAAK;QACd,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE;YACtB,OAAO,MAAM,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,4 +1,10 @@
1
- type UnknownObject = Record<string, unknown>;
1
+ import "react";
2
+ declare module "react" {
3
+ interface HTMLAttributes<T extends Element = HTMLElement> {
4
+ "data-llm"?: string;
5
+ }
6
+ }
7
+ export type UnknownObject = Record<string, unknown>;
2
8
  export type WidgetState = UnknownObject;
3
9
  export type SetWidgetState = (state: WidgetState) => Promise<void>;
4
10
  export type SendFollowUpMessage = (args: {
@@ -9,6 +15,10 @@ export type RequestDisplayMode = (args: {
9
15
  }) => Promise<{
10
16
  mode: DisplayMode;
11
17
  }>;
18
+ export type RequestModal = (options: RequestModalOptions) => Promise<void>;
19
+ export type RequestModalOptions = {
20
+ title: string;
21
+ };
12
22
  export declare const TOOL_RESPONSE_EVENT_TYPE = "openai:tool_response";
13
23
  export declare class ToolResponseEvent extends CustomEvent<{
14
24
  tool: {
@@ -26,7 +36,7 @@ declare global {
26
36
  [SET_GLOBALS_EVENT_TYPE]: SetGlobalsEvent;
27
37
  }
28
38
  }
29
- export type OpenAiGlobals<ToolInput extends UnknownObject = UnknownObject, ToolOutput extends UnknownObject = UnknownObject, ToolResponseMetadata extends UnknownObject = UnknownObject, WidgetState extends UnknownObject = UnknownObject> = {
39
+ export type OpenAiGlobals<ToolInput extends UnknownObject = {}, ToolOutput extends UnknownObject = UnknownObject, ToolResponseMetadata extends UnknownObject = UnknownObject, WidgetState extends UnknownObject = UnknownObject> = {
30
40
  theme: Theme;
31
41
  userAgent: UserAgent;
32
42
  locale: string;
@@ -34,9 +44,13 @@ export type OpenAiGlobals<ToolInput extends UnknownObject = UnknownObject, ToolO
34
44
  displayMode: DisplayMode;
35
45
  safeArea: SafeArea;
36
46
  toolInput: ToolInput;
37
- toolOutput: ToolOutput | null;
47
+ toolOutput: ToolOutput | {
48
+ text: string;
49
+ } | null;
38
50
  toolResponseMetadata: ToolResponseMetadata | null;
39
51
  widgetState: WidgetState | null;
52
+ requestDisplayMode: RequestDisplayMode;
53
+ requestModal: RequestModal;
40
54
  };
41
55
  export type CallToolArgs = Record<string, unknown> | null;
42
56
  export type CallToolResponse = {
@@ -1,3 +1,4 @@
1
+ import "react";
1
2
  export const TOOL_RESPONSE_EVENT_TYPE = "openai:tool_response";
2
3
  export class ToolResponseEvent extends CustomEvent {
3
4
  type = TOOL_RESPONSE_EVENT_TYPE;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/types.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAC/D,MAAM,OAAO,iBAAkB,SAAQ,WAErC;IACkB,IAAI,GAAG,wBAAwB,CAAC;CACnD;AA2ED,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAC3D,MAAM,OAAO,eAAgB,SAAQ,WAEnC;IACkB,IAAI,GAAG,sBAAsB,CAAC;CACjD"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/types.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,CAAC;AA0Bf,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AAC/D,MAAM,OAAO,iBAAkB,SAAQ,WAErC;IACkB,IAAI,GAAG,wBAAwB,CAAC;CACnD;AA6ED,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAC3D,MAAM,OAAO,eAAgB,SAAQ,WAEnC;IACkB,IAAI,GAAG,sBAAsB,CAAC;CACjD"}
@@ -3,7 +3,6 @@ export default defineConfig({
3
3
  test: {
4
4
  environment: "jsdom",
5
5
  globals: true,
6
- setupFiles: ["./src/test/setup.ts"],
7
6
  },
8
7
  });
9
8
  //# sourceMappingURL=vitest.config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.config.js","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE;QACJ,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,CAAC,qBAAqB,CAAC;KACpC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"vitest.config.js","sourceRoot":"","sources":["../vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE;QACJ,WAAW,EAAE,OAAO;QACpB,OAAO,EAAE,IAAI;KACd;CACF,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skybridge",
3
- "version": "0.0.0-dev.b10ac04",
3
+ "version": "0.0.0-dev.b25e54f",
4
4
  "description": "Skybridge is a framework for building ChatGPT apps",
5
5
  "type": "module",
6
6
  "files": [
@@ -19,7 +19,9 @@
19
19
  "scripts": {
20
20
  "build": "tsc && pnpm run build:templates",
21
21
  "build:templates": "cp -r src/server/templates dist/src/server/",
22
- "test": "vitest run --silent",
22
+ "test": "pnpm run test:unit && pnpm run test:type",
23
+ "test:unit": "vitest run --silent",
24
+ "test:type": "tsc --noEmit",
23
25
  "docs:dev": "pnpm --filter @skybridge/docs start",
24
26
  "docs:build": "pnpm --filter @skybridge/docs build",
25
27
  "docs:serve": "pnpm --filter @skybridge/docs serve"
@@ -37,6 +39,7 @@
37
39
  "react-dom": ">=18.0.0"
38
40
  },
39
41
  "dependencies": {
42
+ "@babel/core": "^7.28.5",
40
43
  "@modelcontextprotocol/sdk": "^1.20.0",
41
44
  "cors": "^2.8.5",
42
45
  "express": "^5.1.0",
@@ -48,6 +51,7 @@
48
51
  "@testing-library/dom": "^10.4.1",
49
52
  "@testing-library/react": "^16.3.0",
50
53
  "@total-typescript/tsconfig": "^1.0.4",
54
+ "@types/babel__core": "^7.20.5",
51
55
  "@types/cors": "^2.8.19",
52
56
  "@types/express": "^5.0.3",
53
57
  "@types/jsdom": "^21.1.6",
@@ -1,9 +0,0 @@
1
- import { vi } from "vitest";
2
- // Mock console methods to avoid noise in tests
3
- global.console = {
4
- ...console,
5
- error: vi.fn(),
6
- warn: vi.fn(),
7
- log: vi.fn(),
8
- };
9
- //# sourceMappingURL=setup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/test/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,+CAA+C;AAC/C,MAAM,CAAC,OAAO,GAAG;IACf,GAAG,OAAO;IACV,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;CACb,CAAC"}