@wabot-dev/framework 0.9.27 → 2.0.0-beta.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 (94) hide show
  1. package/README.md +27 -0
  2. package/bin/skills.mjs +151 -0
  3. package/bin/wabot-skills.mjs +120 -0
  4. package/dist/build/build.js +1031 -8
  5. package/dist/src/addon/chat-bot/in-memory/InMemoryChatMemory.js +1 -3
  6. package/dist/src/addon/chat-bot/xai/XAIChatAdapter.js +180 -0
  7. package/dist/src/addon/chat-controller/cmd/cmdChannelSocketPath.js +1 -5
  8. package/dist/src/addon/chat-controller/hubspot/@hubspot.js +28 -0
  9. package/dist/src/addon/chat-controller/hubspot/HubSpotChannel.js +81 -0
  10. package/dist/src/addon/chat-controller/hubspot/HubSpotChannelConfig.js +20 -0
  11. package/dist/src/addon/chat-controller/hubspot/HubSpotReceiver.js +42 -0
  12. package/dist/src/addon/chat-controller/hubspot/HubSpotSender.js +118 -0
  13. package/dist/src/addon/chat-controller/hubspot/HubSpotWebhookController.js +122 -0
  14. package/dist/src/addon/chat-controller/hubspot/downloadHubSpotAttachments.js +45 -0
  15. package/dist/src/addon/chat-controller/hubspot/hubspotChannelName.js +3 -0
  16. package/dist/src/addon/chat-controller/hubspot/verifyHubSpotSignatureV3.js +28 -0
  17. package/dist/src/addon/chat-controller/{telegram/markdownToTelegramHtml.js → markdown/markdownToChatHtml.js} +5 -8
  18. package/dist/src/addon/chat-controller/slack/@slack.js +22 -0
  19. package/dist/src/addon/chat-controller/slack/SlackChannel.js +187 -0
  20. package/dist/src/addon/chat-controller/slack/SlackChannelConfig.js +12 -0
  21. package/dist/src/addon/chat-controller/slack/markdownToSlackMrkdwn.js +38 -0
  22. package/dist/src/addon/chat-controller/slack/slackChannelName.js +3 -0
  23. package/dist/src/addon/chat-controller/telegram/TelegramChannel.js +2 -2
  24. package/dist/src/addon/ui/preact/PreactRenderer.js +86 -0
  25. package/dist/src/addon/ui/preact/outlet.js +22 -0
  26. package/dist/src/addon/ui/preact/preactClientRuntime.js +67 -0
  27. package/dist/src/core/repository/CrudRepository.js +7 -7
  28. package/dist/src/feature/async/computeDedupKey.js +1 -1
  29. package/dist/src/feature/chat-controller/runChatControllers.js +4 -1
  30. package/dist/src/feature/pg/@pgExtension.js +2 -4
  31. package/dist/src/feature/project-runner/ProjectRunner.js +62 -10
  32. package/dist/src/feature/project-runner/scanner.js +1 -1
  33. package/dist/src/feature/repository/@memExtension.js +1 -2
  34. package/dist/src/feature/rest-controller/runRestControllers.js +11 -6
  35. package/dist/src/feature/ui-controller/actions.js +35 -0
  36. package/dist/src/feature/ui-controller/bundler/UiBundler.js +191 -0
  37. package/dist/src/feature/ui-controller/bundler/devMiddleware.js +41 -0
  38. package/dist/src/feature/ui-controller/bundler/index.js +4 -0
  39. package/dist/src/feature/ui-controller/bundler/manifest.js +34 -0
  40. package/dist/src/feature/ui-controller/bundler/navRuntime.js +236 -0
  41. package/dist/src/feature/ui-controller/bundler/pageAssets.js +30 -0
  42. package/dist/src/feature/ui-controller/document/escape.js +17 -0
  43. package/dist/src/feature/ui-controller/document/helpers.js +13 -0
  44. package/dist/src/feature/ui-controller/document/renderDocument.js +43 -0
  45. package/dist/src/feature/ui-controller/island/IslandRegistry.js +68 -0
  46. package/dist/src/feature/ui-controller/island/island.js +40 -0
  47. package/dist/src/feature/ui-controller/island/serialize.js +35 -0
  48. package/dist/src/feature/ui-controller/metadata/@action.js +18 -0
  49. package/dist/src/feature/ui-controller/metadata/@uiController.js +19 -0
  50. package/dist/src/feature/ui-controller/metadata/@uiMiddleware.js +20 -0
  51. package/dist/src/feature/ui-controller/metadata/@view.js +18 -0
  52. package/dist/src/feature/ui-controller/metadata/UiControllerMetadataStore.js +107 -0
  53. package/dist/src/feature/ui-controller/renderer/UiRendererRegistry.js +42 -0
  54. package/dist/src/feature/ui-controller/runUiControllers.js +285 -0
  55. package/dist/src/index.d.ts +640 -3
  56. package/dist/src/index.js +32 -3
  57. package/dist/src/testing/LlmJudge.js +93 -0
  58. package/dist/src/testing/MockChatAdapter.js +68 -0
  59. package/dist/src/testing/TestChatMemory.js +73 -0
  60. package/dist/src/testing/asyncHarness.js +66 -0
  61. package/dist/src/testing/auth.js +114 -0
  62. package/dist/src/testing/chatBotHarness.js +88 -0
  63. package/dist/src/testing/chatControllerHarness.js +94 -0
  64. package/dist/src/testing/conformance/chatAdapterConformanceCases.js +656 -0
  65. package/dist/src/testing/fixtures.js +53 -0
  66. package/dist/src/testing/helpers.js +42 -0
  67. package/dist/src/testing/index.d.ts +818 -0
  68. package/dist/src/testing/index.js +14 -0
  69. package/dist/src/testing/repositories.js +34 -0
  70. package/dist/src/testing/restHarness.js +127 -0
  71. package/dist/src/testing/testImageBase64.js +5 -0
  72. package/dist/src/testing/uiHarness.js +102 -0
  73. package/dist/src/testing/validation.js +66 -0
  74. package/dist/src/ui/client.js +6 -0
  75. package/dist/src/ui/index.d.ts +427 -0
  76. package/dist/src/ui/index.js +29 -0
  77. package/dist/src/ui/jsx-dev-runtime.d.ts +1 -0
  78. package/dist/src/ui/jsx-dev-runtime.js +1 -0
  79. package/dist/src/ui/jsx-runtime.d.ts +1 -0
  80. package/dist/src/ui/jsx-runtime.js +1 -0
  81. package/package.json +48 -11
  82. package/skills/wabot-async/SKILL.md +143 -0
  83. package/skills/wabot-auth/SKILL.md +153 -0
  84. package/skills/wabot-chat/SKILL.md +140 -0
  85. package/skills/wabot-di-config/SKILL.md +117 -0
  86. package/skills/wabot-framework/SKILL.md +81 -0
  87. package/skills/wabot-framework/references/quickstart.md +85 -0
  88. package/skills/wabot-mindset/SKILL.md +159 -0
  89. package/skills/wabot-ops/SKILL.md +151 -0
  90. package/skills/wabot-persistence/SKILL.md +159 -0
  91. package/skills/wabot-rest-socket/SKILL.md +167 -0
  92. package/skills/wabot-testing/SKILL.md +214 -0
  93. package/skills/wabot-ui/SKILL.md +201 -0
  94. package/skills/wabot-validation/SKILL.md +108 -0
@@ -0,0 +1,427 @@
1
+ import { DependencyContainer } from 'tsyringe';
2
+ import { Request, Response, Express } from 'express';
3
+ import { Server } from 'node:http';
4
+ import * as preact from 'preact';
5
+ export { ComponentChild, ComponentChildren, Fragment, RefObject, VNode, cloneElement, createContext, h as createElement, createRef, h, isValidElement, toChildArray } from 'preact';
6
+ export * from 'preact/hooks';
7
+ export { Model, ModelConstructor, ReadonlySignal, Signal, batch, computed, createModel, effect, signal, action as signalAction, untracked, useComputed, useModel, useSignal, useSignalEffect } from '@preact/signals';
8
+
9
+ type IConstructor<T> = new (...args: any[]) => T;
10
+
11
+ interface IMiddleware {
12
+ handle(req: Request, res: Response, container: DependencyContainer): Promise<void>;
13
+ }
14
+
15
+ declare class HttpServerProvider {
16
+ server: Server | null;
17
+ private listening;
18
+ private logger;
19
+ getHttpServer(): Server;
20
+ listen(): void;
21
+ }
22
+
23
+ declare class ExpressProvider {
24
+ private httpServerProvider;
25
+ private expressApp;
26
+ private logger;
27
+ constructor(httpServerProvider: HttpServerProvider);
28
+ getExpress(): Express;
29
+ listen(): void;
30
+ private createExpress;
31
+ }
32
+
33
+ /** A resource to `<link rel="preload">` (font, critical image, …). */
34
+ interface IPreloadLink {
35
+ href: string;
36
+ /** Destination: 'font' | 'image' | 'style' | 'script' | 'fetch' | … */
37
+ as: string;
38
+ /** MIME type, e.g. 'font/woff2'. Recommended so the preload matches the request. */
39
+ type?: string;
40
+ /**
41
+ * CORS mode. Fonts are always fetched cross-origin, so `as: 'font'` defaults to
42
+ * `true` (a bare `crossorigin`) — omitting it would fetch the font twice.
43
+ */
44
+ crossorigin?: boolean | 'anonymous' | 'use-credentials';
45
+ media?: string;
46
+ }
47
+ /** An origin to `<link rel="preconnect">` (e.g. a font CDN). */
48
+ type IPreconnect = string | {
49
+ href: string;
50
+ crossorigin?: boolean;
51
+ };
52
+ /** Extra `<head>` resource hints rendered on full document loads. */
53
+ interface IControllerHead {
54
+ /** Origins to open a connection to early (TLS handshake), e.g. a font host. */
55
+ preconnect?: IPreconnect[];
56
+ /** Resources to fetch early in parallel (fonts, hero image, …). */
57
+ preload?: IPreloadLink[];
58
+ }
59
+ interface IUiControllerConfig {
60
+ /** Base path every view/action of the controller is mounted under. */
61
+ path: string;
62
+ /** Middlewares (e.g. auth guards) applied to every view and action. */
63
+ middlewares?: IConstructor<IMiddleware>[];
64
+ /**
65
+ * Opt into client-side ("boosted") navigation between this controller's
66
+ * views: links within the controller's `path` are intercepted and swapped in
67
+ * without a full browser reload, backed by a stale-while-revalidate cache.
68
+ * Views still SSR normally and keep working without JS. Defaults to false.
69
+ */
70
+ app?: boolean;
71
+ /**
72
+ * Persistent app shell rendered once around every view of the controller. The
73
+ * layout renders an `<Outlet/>` where the current view goes; during boosted
74
+ * navigation only the outlet swaps, so the shell (and its islands) keep their
75
+ * state. A renderer component (e.g. a Preact function component).
76
+ */
77
+ layout?: unknown;
78
+ /**
79
+ * `<head>` resource hints (preconnect/preload) rendered on full document
80
+ * loads — the natural home for app-wide fonts, since the head persists across
81
+ * boosted navigation and is cached for the whole session.
82
+ */
83
+ head?: IControllerHead;
84
+ }
85
+
86
+ declare function uiController(config: string | IUiControllerConfig): (target: IConstructor<any>) => void;
87
+
88
+ interface IViewConfig {
89
+ /** Sub-path appended to the controller path. Empty/omitted = controller index. */
90
+ path?: string;
91
+ /** Document <title> for this page. */
92
+ title?: string;
93
+ /** Extra <meta> tags rendered into the document head: name -> content. */
94
+ meta?: Record<string, string>;
95
+ /**
96
+ * Stale-while-revalidate hints for boosted navigation (`app: true`
97
+ * controllers). Only meaningful for the soft-nav client cache.
98
+ */
99
+ swr?: {
100
+ /**
101
+ * Seconds a cached fragment is considered fresh: within this window a
102
+ * revisit renders from cache without a background revalidation. Default 0
103
+ * (always revalidate in the background).
104
+ */
105
+ maxAge?: number;
106
+ /**
107
+ * Cheap revalidation tag (the SWR key). When provided, boosted-nav
108
+ * revalidation compares this against `If-None-Match` and can answer 304
109
+ * *without* running the view handler or SSR. Receives the request with
110
+ * body+query+params merged, so parameterized routes can (and should) key off
111
+ * their route params — e.g. `version: ({ id }) => docRevision(id)`.
112
+ * Return a short, deterministic string (a data timestamp or revision).
113
+ */
114
+ version?: (request: any) => string | Promise<string>;
115
+ };
116
+ }
117
+
118
+ declare function view(config?: string | IViewConfig): (target: object, propertyKey: string | symbol) => void;
119
+
120
+ interface IActionConfig {
121
+ /** Sub-path of the action. Defaults to the method name. Mounted under `<controller>/_action/<path>`. */
122
+ path?: string;
123
+ }
124
+
125
+ declare function action(config?: string | IActionConfig): (target: object, propertyKey: string | symbol) => void;
126
+
127
+ /**
128
+ * Attach a middleware (e.g. an auth guard) to a single @view or @action.
129
+ * Controller-wide middlewares can instead be declared on @uiController({ middlewares }).
130
+ */
131
+ declare function uiMiddleware(middlewareConstructor: IConstructor<IMiddleware>): (target: object, propertyKey: string | symbol) => void;
132
+
133
+ interface IUiControllerMetadata {
134
+ controllerConstructor: IConstructor<any>;
135
+ path: string;
136
+ middlewares: IConstructor<IMiddleware>[];
137
+ /** Whether this controller opts into client-side ("boosted") navigation. */
138
+ app?: boolean;
139
+ /** Persistent app-shell component rendered around every view (with an `<Outlet/>`). */
140
+ layout?: unknown;
141
+ /** `<head>` resource hints (preconnect/preload) for full document loads. */
142
+ head?: IControllerHead;
143
+ }
144
+
145
+ interface IViewMetadata {
146
+ controllerConstructor: IConstructor<any>;
147
+ functionName: string;
148
+ config?: IViewConfig;
149
+ paramsTypes: any[];
150
+ }
151
+
152
+ interface IActionMetadata {
153
+ controllerConstructor: IConstructor<any>;
154
+ functionName: string;
155
+ config?: IActionConfig;
156
+ paramsTypes: any[];
157
+ }
158
+
159
+ interface IUiMiddlewareMetadata {
160
+ controllerConstructor: IConstructor<any>;
161
+ functionName: string;
162
+ middlewareConstructor: IConstructor<IMiddleware>;
163
+ }
164
+
165
+ declare class UiControllerMetadataStore {
166
+ private controllers;
167
+ private views;
168
+ private actions;
169
+ private middlewares;
170
+ saveControllerMetadata(metadata: IUiControllerMetadata): void;
171
+ saveViewMetadata(metadata: IViewMetadata): void;
172
+ saveActionMetadata(metadata: IActionMetadata): void;
173
+ saveMiddlewareMetadata(metadata: IUiMiddlewareMetadata): void;
174
+ getAllUiControllerConstructors(): IConstructor<any>[];
175
+ private getController;
176
+ private collectMethodMiddlewares;
177
+ getControllerViewsInfo(controllerConstructor: IConstructor<any>): {
178
+ controllerConstructor: IConstructor<any>;
179
+ controller: IUiControllerMetadata;
180
+ middlewares: IUiMiddlewareMetadata[];
181
+ functionName: string;
182
+ config?: IViewConfig;
183
+ paramsTypes: any[];
184
+ }[];
185
+ getControllerActionsInfo(controllerConstructor: IConstructor<any>): {
186
+ controllerConstructor: IConstructor<any>;
187
+ controller: IUiControllerMetadata;
188
+ middlewares: IUiMiddlewareMetadata[];
189
+ functionName: string;
190
+ config?: IActionConfig;
191
+ paramsTypes: any[];
192
+ }[];
193
+ }
194
+
195
+ interface IRenderContext {
196
+ /** True while running under the dev server (enables hydration in dev, etc.). */
197
+ dev?: boolean;
198
+ /**
199
+ * Optional layout component to wrap the view in (the persistent app shell).
200
+ * The renderer places the view where the layout renders its `<Outlet/>`.
201
+ * Passed only for full-document loads; omitted for boosted-nav fragments so
202
+ * only the view (the outlet's content) is rendered.
203
+ */
204
+ layout?: unknown;
205
+ }
206
+ interface IRenderedIsland {
207
+ /** Stable island id (module-derived), used to load its client bundle. */
208
+ id: string;
209
+ /** Serializable props the island was rendered with, for client hydration. */
210
+ props: unknown;
211
+ }
212
+ interface IRenderResult {
213
+ /** Server-rendered HTML for the view body. */
214
+ html: string;
215
+ /** Islands encountered while rendering, in document order. */
216
+ islands: IRenderedIsland[];
217
+ /** Style hrefs (or inline CSS ids) the page depends on, if any. */
218
+ styles: string[];
219
+ }
220
+ interface IIslandEntryArgs {
221
+ /** Stable island id (also the client bundle's output name). */
222
+ id: string;
223
+ /** Absolute path to the island's source module (default export = island). */
224
+ importPath: string;
225
+ }
226
+ /** Renderer-specific knobs the island bundler needs to build client bundles. */
227
+ interface IUiClientConfig {
228
+ /** Module the generated island entry imports its hydration `registerIsland` from. */
229
+ runtimeModule: string;
230
+ /** esbuild JSX settings for compiling islands on the client. */
231
+ esbuildJsx?: {
232
+ jsx?: 'automatic' | 'transform' | 'preserve';
233
+ jsxImportSource?: string;
234
+ jsxFactory?: string;
235
+ jsxFragmentFactory?: string;
236
+ };
237
+ /** Source of the client entry that registers one island for hydration. */
238
+ islandEntrySource(args: IIslandEntryArgs): string;
239
+ }
240
+ /**
241
+ * A pluggable UI rendering engine. The default implementation is Preact
242
+ * (`@wabot-dev/framework/ui`), but any framework can be adapted by implementing
243
+ * this interface and registering it in {@link UiRendererRegistry}.
244
+ */
245
+ interface UiRenderer {
246
+ /** Unique id, e.g. "preact" or "react". */
247
+ readonly id: string;
248
+ /** Render a view's returned node tree to HTML, collecting island usage. */
249
+ renderToString(node: unknown, context?: IRenderContext): IRenderResult | Promise<IRenderResult>;
250
+ /** Bundling/hydration config. Required to ship interactive islands. */
251
+ readonly client?: IUiClientConfig;
252
+ }
253
+
254
+ declare class UiRendererRegistry {
255
+ private renderers;
256
+ private defaultRenderer;
257
+ /** Register a renderer. The first one registered becomes the default. */
258
+ register(renderer: UiRenderer): void;
259
+ /** Register a renderer and make it the default. */
260
+ setDefault(renderer: UiRenderer): void;
261
+ has(id: string): boolean;
262
+ hasDefault(): boolean;
263
+ get(id?: string): UiRenderer;
264
+ }
265
+
266
+ /**
267
+ * Marker attached to components wrapped with {@link island}. The UI renderer
268
+ * uses it to decide which components must hydrate on the client; the bundler
269
+ * uses {@link IslandMeta.id} (assigned from the `*.island.tsx` file location) to
270
+ * emit a per-island client bundle.
271
+ */
272
+ declare const ISLAND_MARKER: unique symbol;
273
+ interface IslandMeta {
274
+ /** The original component, rendered for SSR and hydrated on the client. */
275
+ component: (props: any) => any;
276
+ /** Human-readable name (component name unless overridden). */
277
+ name: string;
278
+ /** Stable bundle id, assigned during island discovery. Undefined until then. */
279
+ id?: string;
280
+ }
281
+ interface IslandComponent<P = any> {
282
+ (props: P): any;
283
+ [ISLAND_MARKER]: IslandMeta;
284
+ }
285
+ /**
286
+ * Mark a component as an interactive client "island". The component still
287
+ * renders on the server, but only islands ship JavaScript and hydrate in the
288
+ * browser. Islands must be the export of a `*.island.tsx` file so the bundler
289
+ * can give them a stable id.
290
+ *
291
+ * // Counter.island.tsx
292
+ * function Counter() { ... }
293
+ * export default island(Counter)
294
+ */
295
+ declare function island<P>(component: (props: P) => any, name?: string): IslandComponent<P>;
296
+ declare function getIslandMeta(component: unknown): IslandMeta | undefined;
297
+ declare function isIsland(component: unknown): boolean;
298
+ /** Assign the stable bundle id to an island, done during island discovery. */
299
+ declare function setIslandId(component: unknown, id: string): void;
300
+
301
+ /**
302
+ * Serialize the props an island was rendered with so the client can hydrate it
303
+ * with the same data. Drops `children`/`ref`/`key` and any function-valued
304
+ * props (event handlers belong inside the island, not in its serialized props).
305
+ */
306
+ declare function serializeProps(props: Record<string, unknown>): string;
307
+ declare function deserializeProps(raw: string | undefined | null): Record<string, unknown>;
308
+
309
+ interface IDiscoveredIsland {
310
+ /** Stable id derived from the file's project-relative path. */
311
+ id: string;
312
+ /** Absolute path to the island source module. */
313
+ importPath: string;
314
+ /** Project-relative posix path (the basis of the id). */
315
+ relPath: string;
316
+ }
317
+ /** Files matching this are treated as islands (default export wrapped with island()). */
318
+ declare const ISLAND_FILE_PATTERN: RegExp;
319
+ /** Deterministic, readable, collision-resistant id from a project-relative path. */
320
+ declare function toIslandId(relPath: string): string;
321
+ declare function isIslandFile(file: string): boolean;
322
+ /**
323
+ * Discovers `*.island.tsx` modules, assigns each a stable id, and stamps that
324
+ * id onto the imported island component (ESM module singletons mean the view
325
+ * renders the same instance, so the renderer can read the id during SSR).
326
+ */
327
+ declare class IslandRegistry {
328
+ private islands;
329
+ private logger;
330
+ discover(files: string[], cwd?: string): Promise<IDiscoveredIsland[]>;
331
+ register(island: IDiscoveredIsland): void;
332
+ list(): IDiscoveredIsland[];
333
+ get(id: string): IDiscoveredIsland | undefined;
334
+ get size(): number;
335
+ }
336
+
337
+ interface IDocumentOptions {
338
+ /** Server-rendered HTML placed inside <body>. */
339
+ bodyHtml: string;
340
+ /** Document title. */
341
+ title?: string;
342
+ /** <meta name=.. content=..> tags. */
343
+ meta?: Record<string, string>;
344
+ /** Stylesheet hrefs rendered as <link rel="stylesheet">. */
345
+ styles?: string[];
346
+ /** Extra <link> tags (preload/preconnect/…) as attribute maps. `true` => bare attribute. */
347
+ links?: Array<Record<string, string | boolean>>;
348
+ /** Module script srcs rendered as <script type="module">. */
349
+ scripts?: string[];
350
+ /** Raw HTML appended to <head> (e.g. inline bootstrap data). */
351
+ headHtml?: string;
352
+ /** Raw HTML appended to the end of <body> (e.g. dev live-reload snippet). */
353
+ bodyEndHtml?: string;
354
+ /** <html lang>. Defaults to "en". */
355
+ lang?: string;
356
+ }
357
+ /**
358
+ * Render the default HTML document shell around a view's body. Kept
359
+ * renderer-agnostic (plain string templating) so it works with any UiRenderer.
360
+ */
361
+ declare function renderDocument(options: IDocumentOptions): string;
362
+
363
+ declare const REDIRECT_MARKER: unique symbol;
364
+ interface UiRedirect {
365
+ readonly [REDIRECT_MARKER]: true;
366
+ location: string;
367
+ status: number;
368
+ }
369
+ /**
370
+ * Return this from a @view or @action to send an HTTP redirect instead of
371
+ * rendering. Used for the post/redirect/get pattern after form actions.
372
+ */
373
+ declare function redirect(location: string, status?: number): UiRedirect;
374
+ declare function isRedirect(value: unknown): value is UiRedirect;
375
+
376
+ /** Escape text for safe interpolation into HTML element content. */
377
+ declare function escapeHtml(value: string): string;
378
+ /** Escape a value for safe interpolation into a double-quoted HTML attribute. */
379
+ declare function escapeAttr(value: string): string;
380
+
381
+ /** Build the URL of an @action: `<controllerPath>/_action/<actionName>`. */
382
+ declare function actionUrl(controllerPath: string, actionName: string): string;
383
+ interface ICallActionOptions {
384
+ headers?: Record<string, string>;
385
+ signal?: AbortSignal;
386
+ }
387
+ /**
388
+ * POST JSON to an @action and return its JSON result. Throws on non-2xx with
389
+ * the server-provided error message. Intended for use from islands; plain
390
+ * <form action=…> posts also work for progressive enhancement.
391
+ */
392
+ declare function callAction<T = unknown>(url: string, data?: unknown, options?: ICallActionOptions): Promise<T>;
393
+
394
+ /** Page-level assets (scripts/styles) to inject, computed from the islands a view rendered. */
395
+ interface IPageAssets {
396
+ scripts?: string[];
397
+ styles?: string[];
398
+ headHtml?: string;
399
+ bodyEndHtml?: string;
400
+ /** URL of the boosted-navigation runtime; injected on `app: true` pages. */
401
+ navScript?: string;
402
+ }
403
+ interface IRegisterUiControllersOptions {
404
+ baseContainer?: DependencyContainer;
405
+ expressProvider?: ExpressProvider;
406
+ /** Hook used by the bundler/dev server to inject island client bundles + CSS. */
407
+ pageAssets?: (islands: IRenderedIsland[]) => IPageAssets;
408
+ }
409
+ declare function registerUiControllers(controllers: IConstructor<any>[], options?: IRegisterUiControllersOptions): ExpressProvider;
410
+ declare function runUiControllers(controllers: IConstructor<any>[], options?: IRegisterUiControllersOptions): void;
411
+
412
+ /**
413
+ * Placeholder a controller `layout` renders where the current view goes. Emits a
414
+ * `<wabot-outlet>` host wrapping the view's server HTML; during boosted
415
+ * navigation only this element's content is swapped, so the surrounding shell
416
+ * (and its islands) keep their state.
417
+ *
418
+ * function Layout() {
419
+ * return <div class="app"><Nav /><main><Outlet /></main></div>
420
+ * }
421
+ * @uiController({ path: '/panel', app: true, layout: Layout })
422
+ */
423
+ declare function Outlet(): preact.VNode<preact.Attributes & {
424
+ 'data-wabot-outlet': string;
425
+ }>;
426
+
427
+ export { type IActionConfig, type IActionMetadata, type ICallActionOptions, type IControllerHead, type IDiscoveredIsland, type IDocumentOptions, type IIslandEntryArgs, type IPageAssets, type IPreconnect, type IPreloadLink, type IRegisterUiControllersOptions, type IRenderContext, type IRenderResult, type IRenderedIsland, ISLAND_FILE_PATTERN, ISLAND_MARKER, type IUiClientConfig, type IUiControllerConfig, type IUiControllerMetadata, type IUiMiddlewareMetadata, type IViewConfig, type IViewMetadata, type IslandComponent, type IslandMeta, IslandRegistry, Outlet, REDIRECT_MARKER, UiControllerMetadataStore, type UiRedirect, type UiRenderer, UiRendererRegistry, action, actionUrl, callAction, deserializeProps, escapeAttr, escapeHtml, getIslandMeta, isIsland, isIslandFile, isRedirect, island, redirect, registerUiControllers, renderDocument, runUiControllers, serializeProps, setIslandId, toIslandId, uiController, uiMiddleware, view };
@@ -0,0 +1,29 @@
1
+ import { container } from '../core/injection/index.js';
2
+ export { uiController } from '../feature/ui-controller/metadata/@uiController.js';
3
+ export { view } from '../feature/ui-controller/metadata/@view.js';
4
+ export { action } from '../feature/ui-controller/metadata/@action.js';
5
+ export { uiMiddleware } from '../feature/ui-controller/metadata/@uiMiddleware.js';
6
+ export { UiControllerMetadataStore } from '../feature/ui-controller/metadata/UiControllerMetadataStore.js';
7
+ import { UiRendererRegistry } from '../feature/ui-controller/renderer/UiRendererRegistry.js';
8
+ export { ISLAND_MARKER, getIslandMeta, isIsland, island, setIslandId } from '../feature/ui-controller/island/island.js';
9
+ export { deserializeProps, serializeProps } from '../feature/ui-controller/island/serialize.js';
10
+ export { ISLAND_FILE_PATTERN, IslandRegistry, isIslandFile, toIslandId } from '../feature/ui-controller/island/IslandRegistry.js';
11
+ export { renderDocument } from '../feature/ui-controller/document/renderDocument.js';
12
+ export { REDIRECT_MARKER, isRedirect, redirect } from '../feature/ui-controller/document/helpers.js';
13
+ export { escapeAttr, escapeHtml } from '../feature/ui-controller/document/escape.js';
14
+ export { actionUrl, callAction } from '../feature/ui-controller/actions.js';
15
+ export { registerUiControllers, runUiControllers } from '../feature/ui-controller/runUiControllers.js';
16
+ import { PreactRenderer } from '../addon/ui/preact/PreactRenderer.js';
17
+ export { Outlet } from '../addon/ui/preact/outlet.js';
18
+ export { Fragment, cloneElement, createContext, h as createElement, createRef, h, isValidElement, toChildArray } from 'preact';
19
+ export * from 'preact/hooks';
20
+ export { Signal, batch, computed, createModel, effect, signal, action as signalAction, untracked, useComputed, useModel, useSignal, useSignalEffect } from '@preact/signals';
21
+
22
+ // UI entrypoint: import from '@wabot-dev/framework/ui'.
23
+ //
24
+ // Importing this module registers Preact + @preact/signals as the default UI
25
+ // renderer. Configure your tsconfig with:
26
+ // "jsx": "react-jsx", "jsxImportSource": "@wabot-dev/framework/ui"
27
+ container.resolve(UiRendererRegistry).setDefault(new PreactRenderer());
28
+
29
+ export { UiRendererRegistry };
@@ -0,0 +1 @@
1
+ export * from 'preact/jsx-dev-runtime';
@@ -0,0 +1 @@
1
+ export * from 'preact/jsx-dev-runtime';
@@ -0,0 +1 @@
1
+ export * from 'preact/jsx-runtime';
@@ -0,0 +1 @@
1
+ export * from 'preact/jsx-runtime';
package/package.json CHANGED
@@ -1,11 +1,37 @@
1
1
  {
2
2
  "name": "@wabot-dev/framework",
3
- "version": "0.9.27",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "Framework for IA Chat Bots",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "types": "dist/src/index.d.ts",
9
+ "bin": {
10
+ "wabot-skills": "./bin/wabot-skills.mjs"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/src/index.d.ts",
15
+ "import": "./dist/src/index.js"
16
+ },
17
+ "./testing": {
18
+ "types": "./dist/src/testing/index.d.ts",
19
+ "import": "./dist/src/testing/index.js"
20
+ },
21
+ "./ui": {
22
+ "types": "./dist/src/ui/index.d.ts",
23
+ "browser": "./dist/src/ui/client.js",
24
+ "import": "./dist/src/ui/index.js"
25
+ },
26
+ "./ui/jsx-runtime": {
27
+ "types": "./dist/src/ui/jsx-runtime.d.ts",
28
+ "import": "./dist/src/ui/jsx-runtime.js"
29
+ },
30
+ "./ui/jsx-dev-runtime": {
31
+ "types": "./dist/src/ui/jsx-dev-runtime.d.ts",
32
+ "import": "./dist/src/ui/jsx-dev-runtime.js"
33
+ }
34
+ },
9
35
  "license": "MIT",
10
36
  "repository": {
11
37
  "type": "git",
@@ -34,25 +60,25 @@
34
60
  "async-jobs",
35
61
  "cron",
36
62
  "messaging-platforms",
63
+ "slack",
37
64
  "bot-framework",
38
65
  "conversational-ai"
39
66
  ],
40
67
  "files": [
41
68
  "dist/src",
42
69
  "dist/build",
70
+ "bin",
71
+ "skills",
43
72
  "LICENSE.md"
44
73
  ],
45
74
  "scripts": {
46
- "build": "rollup --config rollup.config.ts --configPlugin typescript && tsup --dts-only --format esm --out-dir dist/src src/index.ts",
75
+ "build": "rollup --config rollup.config.ts --configPlugin typescript && tsup --dts-only --format esm --out-dir dist/src src/index.ts && tsup --dts-only --format esm --out-dir dist/src/testing src/testing/index.ts && tsup --dts-only --format esm --out-dir dist/src/ui src/ui/index.ts && tsup --dts-only --format esm --out-dir dist/src/ui src/ui/jsx-runtime.ts && tsup --dts-only --format esm --out-dir dist/src/ui src/ui/jsx-dev-runtime.ts",
47
76
  "test:units": "node --import @yucacodes/ts --test './src/**/*.unit.test.ts'",
48
77
  "test:integration": "node --import @yucacodes/ts --import ./env.mjs --test './src/**/*.integration.test.ts'",
49
78
  "test:multiprocess": "node --import @yucacodes/ts --import ./env.mjs --test './src/**/*.multiprocess.test.ts'",
50
79
  "fmt": "prettier --write .",
51
80
  "fmt:check": "prettier --check .",
52
- "types:check": "tsc --noEmit",
53
- "elia:dev": "node --import @yucacodes/ts --import ./env.mjs ./test/elia/_run_.ts",
54
- "elia:watch": "node --watch --import @yucacodes/ts --import ./env.mjs ./test/elia/_run_.ts",
55
- "elia:cmd": "node --import @yucacodes/ts ./test/elia/_cmd_.ts"
81
+ "types:check": "tsc --noEmit"
56
82
  },
57
83
  "devDependencies": {
58
84
  "@rollup/plugin-alias": "5.1.1",
@@ -62,10 +88,17 @@
62
88
  "@rollup/plugin-typescript": "12.1.2",
63
89
  "rollup": "^4.60.0"
64
90
  },
91
+ "overrides": {
92
+ "gaxios": {
93
+ "uuid": "^11.1.1"
94
+ }
95
+ },
65
96
  "peerDependencies": {
66
97
  "@anthropic-ai/sdk": "^0.60.0",
98
+ "@slack/bolt": "^3.17.0",
67
99
  "@google/genai": "^1.16.0",
68
100
  "@openrouter/sdk": "^0.12.2",
101
+ "@preact/signals": "^2.9.2",
69
102
  "@types/big.js": "^6.2.2",
70
103
  "@types/debug": "^4.1.12",
71
104
  "@types/express": "^5.0.1",
@@ -73,28 +106,32 @@
73
106
  "@types/jsonwebtoken": "^9.0.10",
74
107
  "@types/node": "22.14.1",
75
108
  "@types/pg": "^8.11.14",
76
- "@yucacodes/ts": "0.0.8",
109
+ "@yucacodes/ts": "^0.1.0",
77
110
  "big.js": "^7.0.1",
78
111
  "body-parser": "^2.2.0",
79
112
  "cron-parser": "^5.4.0",
80
113
  "debug": "^4.4.0",
81
114
  "dotenv": "^16.5.0",
115
+ "esbuild": "^0.25.12",
82
116
  "express": "^5.1.0",
83
117
  "grammy": "^1.36.0",
84
118
  "html-to-text": "^9.0.5",
85
119
  "jsonwebtoken": "^9.0.2",
86
120
  "openai": "^6.10.0",
87
121
  "pg": "^8.15.6",
122
+ "preact": "^10.29.3",
123
+ "preact-render-to-string": "^6.7.0",
124
+ "prettier": "^3.5.3",
88
125
  "reflect-metadata": "^0.2.2",
89
126
  "short-uuid": "^6.0.3",
90
127
  "socket.io": "^4.8.1",
91
128
  "socket.io-client": "^4.8.1",
92
129
  "tslib": "^2.8.1",
93
- "tsyringe": "^4.9.1",
94
- "uuid": "^14.0.0",
95
- "wasenderapi": "^0.1.5",
130
+ "@hubspot/api-client": "^13.5.0",
96
131
  "tsup": "^8.4.0",
132
+ "tsyringe": "^4.9.1",
97
133
  "typescript": "^6.0.3",
98
- "prettier": "^3.5.3"
134
+ "uuid": "^14.0.0",
135
+ "wasenderapi": "^0.1.5"
99
136
  }
100
137
  }