@neurosquad/card-sdk 1.0.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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +431 -0
  3. package/dist/card-sdk.js +5266 -0
  4. package/dist/cli.js +2838 -0
  5. package/dist/react.js +257 -0
  6. package/dist/testing.js +1150 -0
  7. package/dist/types/client/base64.d.ts +7 -0
  8. package/dist/types/client/card.d.ts +653 -0
  9. package/dist/types/client/channel.d.ts +49 -0
  10. package/dist/types/client/coalesce.d.ts +14 -0
  11. package/dist/types/client/connect.d.ts +39 -0
  12. package/dist/types/client/errors.d.ts +46 -0
  13. package/dist/types/client/helpers.d.ts +25 -0
  14. package/dist/types/client/net.d.ts +111 -0
  15. package/dist/types/client/theme.d.ts +31 -0
  16. package/dist/types/client/toolResult.d.ts +16 -0
  17. package/dist/types/contract/api.d.ts +812 -0
  18. package/dist/types/contract/index.d.ts +11 -0
  19. package/dist/types/contract/jsonSchema.d.ts +88 -0
  20. package/dist/types/contract/localized.d.ts +10 -0
  21. package/dist/types/contract/manifest.d.ts +179 -0
  22. package/dist/types/contract/network.d.ts +48 -0
  23. package/dist/types/contract/permissions.d.ts +180 -0
  24. package/dist/types/contract/ports.d.ts +237 -0
  25. package/dist/types/contract/protocol.d.ts +74 -0
  26. package/dist/types/contract/source.d.ts +111 -0
  27. package/dist/types/contract/theme.d.ts +21 -0
  28. package/dist/types/contract/version.d.ts +126 -0
  29. package/dist/types/i18n.d.ts +50 -0
  30. package/dist/types/index.d.ts +28 -0
  31. package/dist/types/react/index.d.ts +132 -0
  32. package/dist/types/testing/index.d.ts +7 -0
  33. package/dist/types/testing/mockHost.d.ts +315 -0
  34. package/dist/types/version.d.ts +2 -0
  35. package/dist/ui.css +581 -0
  36. package/package.json +77 -0
  37. package/schema/neurosquad-card.v1.json +434 -0
  38. package/templates/react/README.md +34 -0
  39. package/templates/react/_gitignore +10 -0
  40. package/templates/react/icon.png +0 -0
  41. package/templates/react/index.html +12 -0
  42. package/templates/react/neurosquad-card.json +94 -0
  43. package/templates/react/package.json +25 -0
  44. package/templates/react/src/App.tsx +131 -0
  45. package/templates/react/src/i18n.ts +61 -0
  46. package/templates/react/src/main.tsx +77 -0
  47. package/templates/react/src/styles.css +42 -0
  48. package/templates/react/tsconfig.json +18 -0
  49. package/templates/react/vite.config.ts +19 -0
  50. package/templates/vanilla/README.md +37 -0
  51. package/templates/vanilla/_gitignore +6 -0
  52. package/templates/vanilla/icon.png +0 -0
  53. package/templates/vanilla/index.html +41 -0
  54. package/templates/vanilla/main.js +256 -0
  55. package/templates/vanilla/neurosquad-card.json +94 -0
  56. package/templates/vanilla/style.css +41 -0
package/dist/react.js ADDED
@@ -0,0 +1,257 @@
1
+ /*! @neurosquad/card-sdk 1.0.0 | MIT */
2
+
3
+ // src/react/index.tsx
4
+ import {
5
+ createContext,
6
+ useCallback,
7
+ useContext,
8
+ useEffect,
9
+ useMemo,
10
+ useRef,
11
+ useState,
12
+ useSyncExternalStore
13
+ } from "react";
14
+ import {
15
+ connect,
16
+ createTranslator
17
+ } from "./card-sdk.js";
18
+ import { jsx } from "react/jsx-runtime";
19
+ var CardContext = createContext(null);
20
+ function CardProvider({
21
+ card,
22
+ connectOptions,
23
+ fallback = null,
24
+ errorFallback,
25
+ children
26
+ }) {
27
+ const [state, setState] = useState({
28
+ card: card ?? null,
29
+ error: null
30
+ });
31
+ const options = useRef(connectOptions);
32
+ useEffect(() => {
33
+ if (card) {
34
+ setState({ card, error: null });
35
+ return;
36
+ }
37
+ let cancelled = false;
38
+ connect(options.current).then(
39
+ (connected) => !cancelled && setState({ card: connected, error: null }),
40
+ (error) => !cancelled && setState({ card: null, error: error instanceof Error ? error : new Error(String(error)) })
41
+ );
42
+ return () => {
43
+ cancelled = true;
44
+ };
45
+ }, [card]);
46
+ const current = card ?? state.card;
47
+ if (state.error && !current) {
48
+ return errorFallback ? errorFallback(state.error) : /* @__PURE__ */ jsx("pre", { style: { whiteSpace: "pre-wrap", padding: 12 }, children: state.error.message });
49
+ }
50
+ if (!current) return fallback;
51
+ return /* @__PURE__ */ jsx(CardContext.Provider, { value: current, children });
52
+ }
53
+ function useCard() {
54
+ const card = useContext(CardContext);
55
+ if (!card) throw new Error("useCard() must be used inside <CardProvider>");
56
+ return card;
57
+ }
58
+ function useCardContext() {
59
+ const card = useCard();
60
+ return useCardSelector(card, (context) => context);
61
+ }
62
+ function useCardSelector(card, select) {
63
+ const subscribe = useCallback((onChange) => card.onContextChange(onChange), [card]);
64
+ const snapshot = useCallback(() => select(card.context), [card, select]);
65
+ return useSyncExternalStore(subscribe, snapshot, snapshot);
66
+ }
67
+ var selectSettings = (context) => context.settings;
68
+ var selectTheme = (context) => context.theme;
69
+ var selectI18n = (context) => context.i18n;
70
+ var selectVisibility = (context) => context.visibility;
71
+ var selectPeers = (context) => context.peers;
72
+ var selectExpanded = (context) => context.expanded;
73
+ function useSettings() {
74
+ const card = useCard();
75
+ const settings = useCardSelector(card, selectSettings);
76
+ const set = useCallback(
77
+ async (values) => {
78
+ await card.settings.set(values);
79
+ },
80
+ [card]
81
+ );
82
+ return [settings, set];
83
+ }
84
+ function useStorage(key, initial, options = {}) {
85
+ const card = useCard();
86
+ const scope = options.scope ?? "instance";
87
+ const [state, setState] = useState({
88
+ value: initial,
89
+ loading: true,
90
+ error: null
91
+ });
92
+ const latest = useRef(state.value);
93
+ latest.current = state.value;
94
+ const initialRef = useRef(initial);
95
+ const writes = useRef(0);
96
+ useEffect(() => {
97
+ let cancelled = false;
98
+ const store = scope === "package" ? card.storage.package : card.storage;
99
+ const load = () => {
100
+ const started = writes.current;
101
+ store.get(key, initialRef.current).then(
102
+ (value) => {
103
+ if (!cancelled && writes.current === started)
104
+ setState({ value, loading: false, error: null });
105
+ },
106
+ (error) => {
107
+ if (!cancelled) setState((s) => ({ ...s, loading: false, error }));
108
+ }
109
+ );
110
+ };
111
+ load();
112
+ const off = scope === "package" ? card.storage.onChange((change) => change.key === key && load()) : void 0;
113
+ return () => {
114
+ cancelled = true;
115
+ off?.();
116
+ };
117
+ }, [card, key, scope]);
118
+ const set = useCallback(
119
+ (next) => {
120
+ const value = typeof next === "function" ? next(latest.current) : next;
121
+ latest.current = value;
122
+ writes.current++;
123
+ setState((s) => ({ ...s, value, loading: false }));
124
+ const store = scope === "package" ? card.storage.package : card.storage;
125
+ store.set(key, value).catch((error) => setState((s) => ({ ...s, error })));
126
+ },
127
+ [card, key, scope]
128
+ );
129
+ return [state.value, set, { loading: state.loading, error: state.error }];
130
+ }
131
+ function useAgents() {
132
+ const card = useCard();
133
+ const [state, setState] = useState({
134
+ agents: [],
135
+ loading: true,
136
+ error: null
137
+ });
138
+ const [tick, setTick] = useState(0);
139
+ useEffect(() => {
140
+ let cancelled = false;
141
+ card.agents.list().then(
142
+ (agents) => !cancelled && setState({ agents, loading: false, error: null }),
143
+ (error) => !cancelled && setState((s) => ({ ...s, loading: false, error }))
144
+ );
145
+ const offChanged = card.agents.onChanged(
146
+ (agents) => setState({ agents, loading: false, error: null })
147
+ );
148
+ const offStatus = card.agents.onStatus(
149
+ (event) => setState((s) => ({
150
+ ...s,
151
+ agents: s.agents.map(
152
+ (agent) => agent.id === event.agentId ? { ...agent, status: event.status } : agent
153
+ )
154
+ }))
155
+ );
156
+ return () => {
157
+ cancelled = true;
158
+ offChanged();
159
+ offStatus();
160
+ };
161
+ }, [card, tick]);
162
+ const refresh = useCallback(() => setTick((n) => n + 1), []);
163
+ return { ...state, refresh };
164
+ }
165
+ function useAgentStatus(agentId) {
166
+ const { agents } = useAgents();
167
+ return agentId ? agents.find((agent) => agent.id === agentId)?.status : void 0;
168
+ }
169
+ function usePort(input) {
170
+ const card = useCard();
171
+ const [message, setMessage] = useState(void 0);
172
+ useEffect(
173
+ () => card.ports.onMessage((_data, event) => setMessage(event), input ? { input } : {}),
174
+ [card, input]
175
+ );
176
+ return { data: message?.data, message };
177
+ }
178
+ function useEmit(output) {
179
+ const card = useCard();
180
+ return useCallback((data) => card.ports.emit(output, data), [card, output]);
181
+ }
182
+ function usePeers() {
183
+ return useCardSelector(useCard(), selectPeers);
184
+ }
185
+ function useTheme() {
186
+ return useCardSelector(useCard(), selectTheme);
187
+ }
188
+ function useLanguage() {
189
+ return useCardSelector(useCard(), selectI18n);
190
+ }
191
+ function useVisibility() {
192
+ return useCardSelector(useCard(), selectVisibility);
193
+ }
194
+ function useExpanded() {
195
+ return useCardSelector(useCard(), selectExpanded);
196
+ }
197
+ function usePaused() {
198
+ return useVisibility() !== "visible";
199
+ }
200
+ function useTool(name, handler) {
201
+ const card = useCard();
202
+ const ref = useRef(handler);
203
+ ref.current = handler;
204
+ useEffect(() => card.tools.handle(name, (args, call) => ref.current(args, call)), [card, name]);
205
+ }
206
+ function usePortRequest(input, handler) {
207
+ const card = useCard();
208
+ const ref = useRef(handler);
209
+ ref.current = handler;
210
+ useEffect(
211
+ () => card.ports.onRequest(input, (data, request) => ref.current(data, request)),
212
+ [card, input]
213
+ );
214
+ }
215
+ function useCardEvent(event, handler) {
216
+ const card = useCard();
217
+ const ref = useRef(handler);
218
+ ref.current = handler;
219
+ useEffect(() => card.on(event, (data) => ref.current(data)), [card, event]);
220
+ }
221
+ function useTranslator(catalog) {
222
+ const card = useCard();
223
+ const translator = useMemo(() => createTranslator(catalog, card), [catalog, card]);
224
+ const language = useLanguage().language;
225
+ useEffect(() => () => translator.dispose(), [translator]);
226
+ return useMemo(() => {
227
+ const t = ((key, values) => translator(key, values));
228
+ return Object.assign(t, {
229
+ language,
230
+ locale: translator.locale,
231
+ setLanguage: translator.setLanguage,
232
+ onChange: translator.onChange,
233
+ dispose: translator.dispose
234
+ });
235
+ }, [translator, language]);
236
+ }
237
+ export {
238
+ CardProvider,
239
+ useAgentStatus,
240
+ useAgents,
241
+ useCard,
242
+ useCardContext,
243
+ useCardEvent,
244
+ useEmit,
245
+ useExpanded,
246
+ useLanguage,
247
+ usePaused,
248
+ usePeers,
249
+ usePort,
250
+ usePortRequest,
251
+ useSettings,
252
+ useStorage,
253
+ useTheme,
254
+ useTool,
255
+ useTranslator,
256
+ useVisibility
257
+ };