@yak-io/nextjs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +36 -0
  2. package/README.md +223 -0
  3. package/dist/cli/generate-manifest.d.ts +16 -0
  4. package/dist/cli/generate-manifest.d.ts.map +1 -0
  5. package/dist/cli/generate-manifest.js +216 -0
  6. package/dist/client/YakProvider.d.ts +15 -0
  7. package/dist/client/YakProvider.d.ts.map +1 -0
  8. package/dist/client/YakProvider.js +57 -0
  9. package/dist/client/useYak.d.ts +4 -0
  10. package/dist/client/useYak.d.ts.map +1 -0
  11. package/dist/client/useYak.js +4 -0
  12. package/dist/index.client.d.ts +6 -0
  13. package/dist/index.client.d.ts.map +1 -0
  14. package/dist/index.client.js +4 -0
  15. package/dist/index.server.d.ts +2 -0
  16. package/dist/index.server.d.ts.map +1 -0
  17. package/dist/index.server.js +2 -0
  18. package/dist/internal/logger.d.ts +11 -0
  19. package/dist/internal/logger.d.ts.map +1 -0
  20. package/dist/internal/logger.js +23 -0
  21. package/dist/server/createNextYakConfigHandler.d.ts +3 -0
  22. package/dist/server/createNextYakConfigHandler.d.ts.map +1 -0
  23. package/dist/server/createNextYakConfigHandler.js +1 -0
  24. package/dist/server/createNextYakHandler.d.ts +38 -0
  25. package/dist/server/createNextYakHandler.d.ts.map +1 -0
  26. package/dist/server/createNextYakHandler.js +71 -0
  27. package/dist/server/createNextYakToolsHandler.d.ts +3 -0
  28. package/dist/server/createNextYakToolsHandler.d.ts.map +1 -0
  29. package/dist/server/createNextYakToolsHandler.js +1 -0
  30. package/dist/server/index.d.ts +6 -0
  31. package/dist/server/index.d.ts.map +1 -0
  32. package/dist/server/index.js +2 -0
  33. package/dist/server/scan-routes.d.ts +9 -0
  34. package/dist/server/scan-routes.d.ts.map +1 -0
  35. package/dist/server/scan-routes.js +197 -0
  36. package/dist/types/config.d.ts +12 -0
  37. package/dist/types/config.d.ts.map +1 -0
  38. package/dist/types/config.js +1 -0
  39. package/dist/types/messaging.d.ts +71 -0
  40. package/dist/types/messaging.d.ts.map +1 -0
  41. package/dist/types/messaging.js +1 -0
  42. package/dist/types/routes.d.ts +21 -0
  43. package/dist/types/routes.d.ts.map +1 -0
  44. package/dist/types/routes.js +1 -0
  45. package/dist/types/tools.d.ts +52 -0
  46. package/dist/types/tools.d.ts.map +1 -0
  47. package/dist/types/tools.js +1 -0
  48. package/package.json +71 -0
@@ -0,0 +1,38 @@
1
+ import type { RouteSourceInput, ToolSourceInput, RouteInfo, ToolManifest, ToolExecutor } from "@yak-io/javascript/server";
2
+ export type NextYakRouteFilter = {
3
+ include?: RegExp[];
4
+ exclude?: RegExp[];
5
+ };
6
+ export type NextYakHandlerConfig = {
7
+ appDir?: string;
8
+ routeFilter?: NextYakRouteFilter;
9
+ routes?: RouteSourceInput;
10
+ getRoutes?: () => Promise<RouteInfo[]>;
11
+ tools?: ToolSourceInput;
12
+ pagesDir?: string | false;
13
+ getTools?: () => Promise<ToolManifest>;
14
+ executeTool?: ToolExecutor;
15
+ };
16
+ /**
17
+ * Create a unified Next.js App Router handler backed by the core primitives
18
+ */
19
+ export declare function createNextYakHandler(config: NextYakHandlerConfig): {
20
+ GET: (_req: Request) => Promise<Response>;
21
+ POST: (req: Request) => Promise<Response>;
22
+ };
23
+ export type NextYakConfigHandlerConfig = {
24
+ appDir?: string;
25
+ routeFilter?: NextYakRouteFilter;
26
+ routes?: RouteSourceInput;
27
+ getRoutes?: () => Promise<RouteInfo[]>;
28
+ tools?: ToolSourceInput;
29
+ getTools?: () => Promise<ToolManifest>;
30
+ };
31
+ export declare function createNextYakConfigHandler(config: NextYakConfigHandlerConfig): (_req: Request) => Promise<Response>;
32
+ export type NextYakToolsHandlerConfig = {
33
+ tools?: ToolSourceInput;
34
+ getTools?: () => Promise<ToolManifest>;
35
+ executeTool: ToolExecutor;
36
+ };
37
+ export declare function createNextYakToolsHandler(config: NextYakToolsHandlerConfig): (req: Request) => Promise<Response>;
38
+ //# sourceMappingURL=createNextYakHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createNextYakHandler.d.ts","sourceRoot":"","sources":["../../src/server/createNextYakHandler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,YAAY,EACZ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAGnC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB;;;EAKhE;AA2DD,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,wCAK5E;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,WAAW,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,uCAW1E"}
@@ -0,0 +1,71 @@
1
+ import { createYakHandler, createYakConfigHandler, createYakToolsHandler, } from "@yak-io/javascript/server";
2
+ import { scanRoutes } from "./scan-routes.js";
3
+ /**
4
+ * Create a unified Next.js App Router handler backed by the core primitives
5
+ */
6
+ export function createNextYakHandler(config) {
7
+ return createYakHandler({
8
+ routes: resolveRouteSources(config),
9
+ tools: resolveToolSources(config),
10
+ });
11
+ }
12
+ function resolveRouteSources(config) {
13
+ if (config.routes) {
14
+ return config.routes;
15
+ }
16
+ if (config.getRoutes) {
17
+ return config.getRoutes;
18
+ }
19
+ return async () => applyRouteFilters(scanRoutes(config.appDir ?? "./src/app"), config.routeFilter);
20
+ }
21
+ function applyRouteFilters(routes, filter) {
22
+ if (!filter) {
23
+ return routes;
24
+ }
25
+ const { include = [], exclude = [] } = filter;
26
+ return routes.filter(route => {
27
+ const path = route.path;
28
+ if (include.length > 0 && !include.some(pattern => matches(pattern, path))) {
29
+ return false;
30
+ }
31
+ if (exclude.some(pattern => matches(pattern, path))) {
32
+ return false;
33
+ }
34
+ return true;
35
+ });
36
+ }
37
+ function matches(pattern, value) {
38
+ pattern.lastIndex = 0;
39
+ return pattern.test(value);
40
+ }
41
+ function resolveToolSources(config) {
42
+ if (config.tools) {
43
+ return config.tools;
44
+ }
45
+ if (config.getTools) {
46
+ return {
47
+ getTools: config.getTools,
48
+ executeTool: config.executeTool,
49
+ };
50
+ }
51
+ if (config.executeTool) {
52
+ throw new Error("'executeTool' was provided without a matching tool manifest source");
53
+ }
54
+ return undefined;
55
+ }
56
+ export function createNextYakConfigHandler(config) {
57
+ return createYakConfigHandler({
58
+ routes: resolveRouteSources(config),
59
+ tools: config.tools ?? (config.getTools ? { getTools: config.getTools } : undefined),
60
+ });
61
+ }
62
+ export function createNextYakToolsHandler(config) {
63
+ if (!config.tools && !config.getTools) {
64
+ throw new Error("createNextYakToolsHandler requires either 'tools' or 'getTools'");
65
+ }
66
+ const toolSource = config.tools ?? {
67
+ getTools: config.getTools,
68
+ executeTool: config.executeTool,
69
+ };
70
+ return createYakToolsHandler({ tools: toolSource });
71
+ }
@@ -0,0 +1,3 @@
1
+ export { createNextYakToolsHandler } from "./createNextYakHandler.js";
2
+ export type { NextYakToolsHandlerConfig } from "./createNextYakHandler.js";
3
+ //# sourceMappingURL=createNextYakToolsHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createNextYakToolsHandler.d.ts","sourceRoot":"","sources":["../../src/server/createNextYakToolsHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,YAAY,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1 @@
1
+ export { createNextYakToolsHandler } from "./createNextYakHandler.js";
@@ -0,0 +1,6 @@
1
+ export { scanRoutes } from "./scan-routes.js";
2
+ export type { ScanRoutesOptions } from "./scan-routes.js";
3
+ export { createNextYakHandler, createNextYakConfigHandler, createNextYakToolsHandler, } from "./createNextYakHandler.js";
4
+ export type { NextYakHandlerConfig, NextYakConfigHandlerConfig, NextYakToolsHandlerConfig, NextYakRouteFilter, } from "./createNextYakHandler.js";
5
+ export type { ToolExecutor, ToolCallPayload, ToolCallResult, ToolDefinition, ToolManifest, RouteInfo, RouteManifest, ChatConfig, } from "@yak-io/javascript/server";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACN,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,GACzB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACV,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { scanRoutes } from "./scan-routes.js";
2
+ export { createNextYakHandler, createNextYakConfigHandler, createNextYakToolsHandler, } from "./createNextYakHandler.js";
@@ -0,0 +1,9 @@
1
+ import type { RouteInfo } from "@yak-io/javascript/server";
2
+ export type ScanRoutesOptions = {
3
+ directoryType?: "app" | "pages";
4
+ };
5
+ /**
6
+ * Scan a Next.js app or pages directory and return page route information
7
+ */
8
+ export declare function scanRoutes(directory: string, options?: ScanRoutesOptions): RouteInfo[];
9
+ //# sourceMappingURL=scan-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-routes.d.ts","sourceRoot":"","sources":["../../src/server/scan-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CACjC,CAAC;AA8NF;;GAEG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,SAAS,EAAE,CAcb"}
@@ -0,0 +1,197 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ /**
4
+ * Extract static metadata (title and description) from a Next.js page file.
5
+ * Parses `export const metadata = { title: "...", description: "..." }` patterns.
6
+ * Does not support dynamic generateMetadata functions.
7
+ */
8
+ function extractMetadata(filePath) {
9
+ try {
10
+ const content = fs.readFileSync(filePath, "utf-8");
11
+ // Match `export const metadata` object
12
+ const metadataMatch = content.match(/export\s+const\s+metadata\s*(?::\s*Metadata\s*)?=\s*\{([^}]*(?:\{[^}]*\}[^}]*)*)\}/s);
13
+ if (!metadataMatch) {
14
+ return {};
15
+ }
16
+ const metadataBlock = metadataMatch[1];
17
+ const result = {};
18
+ // Extract title - handle both single and double quotes
19
+ const titleMatch = metadataBlock?.match(/title\s*:\s*["'`]([^"'`]+)["'`]/);
20
+ if (titleMatch?.[1]) {
21
+ result.title = titleMatch[1];
22
+ }
23
+ // Extract description - handle both single and double quotes
24
+ const descMatch = metadataBlock?.match(/description\s*:\s*["'`]([^"'`]+)["'`]/);
25
+ if (descMatch?.[1]) {
26
+ result.description = descMatch[1];
27
+ }
28
+ return result;
29
+ }
30
+ catch {
31
+ return {};
32
+ }
33
+ }
34
+ /**
35
+ * Check if a path segment is a route group (organizational only, not part of URL)
36
+ */
37
+ function isRouteGroup(segment) {
38
+ return segment.startsWith("(") && segment.endsWith(")");
39
+ }
40
+ /**
41
+ * Check if a path segment is an optional catch-all (e.g., [[...slug]])
42
+ * These segments match the base path without any additional segments
43
+ */
44
+ function isOptionalCatchAll(segment) {
45
+ return segment.startsWith("[[...") && segment.endsWith("]]");
46
+ }
47
+ /**
48
+ * Check if a path segment is a required catch-all (e.g., [...slug])
49
+ * These segments require at least one additional path segment
50
+ */
51
+ function isRequiredCatchAll(segment) {
52
+ return segment.startsWith("[...") && segment.endsWith("]") && !segment.startsWith("[[");
53
+ }
54
+ /**
55
+ * Check if a path segment is a dynamic segment (e.g., [id])
56
+ */
57
+ function isDynamicSegment(segment) {
58
+ return segment.startsWith("[") && segment.endsWith("]") && !isOptionalCatchAll(segment) && !isRequiredCatchAll(segment);
59
+ }
60
+ /**
61
+ * Normalize a dynamic segment for display
62
+ * e.g., [id] → :id, [postId] → :postId
63
+ */
64
+ function normalizeDynamicSegment(segment) {
65
+ // Extract the parameter name from [name] format
66
+ const paramName = segment.slice(1, -1);
67
+ return `:${paramName}`;
68
+ }
69
+ /**
70
+ * Normalize a route path for display (excludes route groups and handles dynamic segments)
71
+ */
72
+ function normalizeRoutePath(segments) {
73
+ // Filter out route groups - they don't appear in URLs
74
+ // Filter out optional catch-all segments - they match the base path
75
+ const urlSegments = segments
76
+ .filter(seg => !isRouteGroup(seg) && !isOptionalCatchAll(seg))
77
+ .map(seg => {
78
+ if (isDynamicSegment(seg)) {
79
+ return normalizeDynamicSegment(seg);
80
+ }
81
+ if (isRequiredCatchAll(seg)) {
82
+ // For required catch-all, extract the name: [...slug] → :slug+
83
+ const paramName = seg.slice(4, -1);
84
+ return `:${paramName}+`;
85
+ }
86
+ return seg;
87
+ });
88
+ if (urlSegments.length === 0)
89
+ return "/";
90
+ return "/" + urlSegments.join("/");
91
+ }
92
+ /**
93
+ * Check if file is a page file
94
+ */
95
+ function isPageFile(filename) {
96
+ return filename === "page.tsx" || filename === "page.js";
97
+ }
98
+ /**
99
+ * Recursively scan a directory for Next.js page routes
100
+ */
101
+ function scanAppDirectory(dirPath, segments = []) {
102
+ const routes = [];
103
+ try {
104
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
105
+ for (const entry of entries) {
106
+ const fullPath = path.join(dirPath, entry.name);
107
+ if (entry.isDirectory()) {
108
+ // Skip special Next.js directories and api routes
109
+ if (entry.name.startsWith("_") || entry.name === "api") {
110
+ continue;
111
+ }
112
+ // Recursively scan subdirectories
113
+ routes.push(...scanAppDirectory(fullPath, [...segments, entry.name]));
114
+ }
115
+ else if (entry.isFile() && isPageFile(entry.name)) {
116
+ const metadata = extractMetadata(fullPath);
117
+ routes.push({
118
+ path: normalizeRoutePath(segments),
119
+ title: metadata.title,
120
+ description: metadata.description,
121
+ });
122
+ }
123
+ }
124
+ }
125
+ catch (error) {
126
+ console.error(`Error scanning directory ${dirPath}:`, error);
127
+ }
128
+ return routes;
129
+ }
130
+ /**
131
+ * File discovery helpers for legacy `pages/` directories
132
+ */
133
+ const VALID_PAGE_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx", ".md", ".mdx"]);
134
+ const SPECIAL_PAGE_FILENAMES = new Set(["_app", "_document", "_error", "404", "500", "middleware", "_middleware"]);
135
+ function scanPagesDirectory(dirPath, segments = []) {
136
+ const routes = [];
137
+ try {
138
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
139
+ for (const entry of entries) {
140
+ const fullPath = path.join(dirPath, entry.name);
141
+ if (entry.isDirectory()) {
142
+ // Skip special directories and api routes
143
+ if (entry.name.startsWith("_") || entry.name === "api") {
144
+ continue;
145
+ }
146
+ routes.push(...scanPagesDirectory(fullPath, [...segments, entry.name]));
147
+ }
148
+ else if (entry.isFile()) {
149
+ const extension = path.extname(entry.name);
150
+ if (!VALID_PAGE_EXTENSIONS.has(extension)) {
151
+ continue;
152
+ }
153
+ const baseName = entry.name.slice(0, -extension.length);
154
+ if (!baseName || SPECIAL_PAGE_FILENAMES.has(baseName) || baseName.startsWith("_")) {
155
+ continue;
156
+ }
157
+ const routeSegments = buildPagesSegments(segments, baseName);
158
+ const metadata = extractMetadata(fullPath);
159
+ routes.push({
160
+ path: normalizeRoutePath(routeSegments),
161
+ title: metadata.title,
162
+ description: metadata.description,
163
+ });
164
+ }
165
+ }
166
+ }
167
+ catch (error) {
168
+ console.error(`Error scanning directory ${dirPath}:`, error);
169
+ }
170
+ return routes;
171
+ }
172
+ function buildPagesSegments(segments, baseName) {
173
+ const routeSegments = [...segments];
174
+ if (baseName !== "index") {
175
+ routeSegments.push(baseName);
176
+ }
177
+ return routeSegments;
178
+ }
179
+ function normalizeScanOptions(options) {
180
+ return {
181
+ directoryType: options?.directoryType ?? "app",
182
+ };
183
+ }
184
+ /**
185
+ * Scan a Next.js app or pages directory and return page route information
186
+ */
187
+ export function scanRoutes(directory, options) {
188
+ const normalizedOptions = normalizeScanOptions(options);
189
+ const targetDir = path.resolve(process.cwd(), directory);
190
+ if (!fs.existsSync(targetDir)) {
191
+ throw new Error(`App directory not found: ${targetDir}`);
192
+ }
193
+ const routes = normalizedOptions.directoryType === "pages"
194
+ ? scanPagesDirectory(targetDir, [])
195
+ : scanAppDirectory(targetDir, []);
196
+ return routes.sort((a, b) => a.path.localeCompare(b.path));
197
+ }
@@ -0,0 +1,12 @@
1
+ import type { ToolManifest } from "./tools.js";
2
+ import type { RouteManifest } from "./routes.js";
3
+ /**
4
+ * Combined configuration for the chatbot including routes and optionally tools
5
+ */
6
+ export type ChatConfig = {
7
+ /** Route manifest with Next.js routes */
8
+ routes: RouteManifest;
9
+ /** Optional tool manifest (e.g., tRPC procedures) */
10
+ tools?: ToolManifest;
11
+ };
12
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,yCAAyC;IACzC,MAAM,EAAE,aAAa,CAAC;IACtB,qDAAqD;IACrD,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
1
+ import type { ToolManifest } from "./tools";
2
+ import type { RouteManifest } from "./routes";
3
+ /**
4
+ * Theme configuration for the chatbot widget
5
+ */
6
+ export type Theme = {
7
+ position?: "bottom-right" | "bottom-left";
8
+ };
9
+ /**
10
+ * Page context information from the host page
11
+ */
12
+ export type PageContext = {
13
+ url: string;
14
+ title: string;
15
+ text: string;
16
+ timestamp: number;
17
+ };
18
+ /**
19
+ * Messages sent FROM the host application TO the iframe
20
+ */
21
+ export type IframeMessageFromHost = {
22
+ type: "yak:config";
23
+ payload: {
24
+ appId: string;
25
+ theme?: Theme;
26
+ toolManifest?: ToolManifest;
27
+ routeManifest?: RouteManifest;
28
+ };
29
+ } | {
30
+ type: "yak:tool_result";
31
+ payload: {
32
+ id: string;
33
+ ok: true;
34
+ result: unknown;
35
+ };
36
+ } | {
37
+ type: "yak:tool_result";
38
+ payload: {
39
+ id: string;
40
+ ok: false;
41
+ error: string;
42
+ };
43
+ } | {
44
+ type: "yak:page_context";
45
+ payload: PageContext;
46
+ };
47
+ /**
48
+ * Messages sent FROM the iframe TO the host application
49
+ */
50
+ export type IframeMessageToHost = {
51
+ type: "yak:ready";
52
+ } | {
53
+ type: "yak:tool_call";
54
+ payload: {
55
+ id: string;
56
+ name: string;
57
+ args: unknown;
58
+ };
59
+ } | {
60
+ type: "yak:redirect";
61
+ payload: {
62
+ path: string;
63
+ };
64
+ } | {
65
+ type: "yak:close";
66
+ };
67
+ /**
68
+ * Union of all message types (for type guards)
69
+ */
70
+ export type IframeMessage = IframeMessageFromHost | IframeMessageToHost;
71
+ //# sourceMappingURL=messaging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../../src/types/messaging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC;CAC3C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,YAAY,CAAC,EAAE,YAAY,CAAC;QAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;KAC/B,CAAC;CACH,GACD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAEvD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1B;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,qBAAqB,GAAG,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Information about a single route in the Next.js application
3
+ */
4
+ export type RouteInfo = {
5
+ /** The route path, e.g., "/dashboard" or "/posts/[id]" */
6
+ path: string;
7
+ /** Human-readable title extracted from page metadata */
8
+ title?: string;
9
+ /** Description extracted from page metadata */
10
+ description?: string;
11
+ };
12
+ /**
13
+ * Manifest of all routes in the Next.js application
14
+ */
15
+ export type RouteManifest = {
16
+ /** List of all discovered routes */
17
+ routes: RouteInfo[];
18
+ /** ISO timestamp when the manifest was generated */
19
+ generated_at: string;
20
+ };
21
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/types/routes.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,oCAAoC;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Generic JSON Schema type
3
+ */
4
+ export type JSONSchema = Record<string, unknown>;
5
+ /**
6
+ * Payload for a tool call request from the iframe
7
+ */
8
+ export type ToolCallPayload = {
9
+ id: string;
10
+ name: string;
11
+ args: unknown;
12
+ };
13
+ /**
14
+ * Successful tool call result
15
+ */
16
+ export type ToolCallSuccess = {
17
+ ok: true;
18
+ result: unknown;
19
+ };
20
+ /**
21
+ * Failed tool call result
22
+ */
23
+ export type ToolCallError = {
24
+ ok: false;
25
+ error: string;
26
+ };
27
+ /**
28
+ * Union type for tool call responses
29
+ */
30
+ export type ToolCallResult = ToolCallSuccess | ToolCallError;
31
+ /**
32
+ * Definition of a single tool (tRPC procedure) available to the LLM
33
+ */
34
+ export type ToolDefinition = {
35
+ /** Fully qualified procedure name, e.g. "orders.list" */
36
+ name: string;
37
+ /** Human friendly label */
38
+ displayName?: string;
39
+ /** Description shown to the LLM as a tool description */
40
+ description?: string;
41
+ /** Optional JSON Schema for input args */
42
+ inputSchema?: JSONSchema;
43
+ /** Optional JSON Schema for output shape (not required in v1) */
44
+ outputSchema?: JSONSchema;
45
+ };
46
+ /**
47
+ * Manifest of all tools (tRPC procedures) available to the chatbot
48
+ */
49
+ export type ToolManifest = {
50
+ tools: ToolDefinition[];
51
+ };
52
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,aAAa,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IAEb,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,UAAU,CAAC;IAEzB,iEAAiE;IACjE,YAAY,CAAC,EAAE,UAAU,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@yak-io/nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Next.js SDK for embedding yak chatbot with route manifest generation",
5
+ "type": "module",
6
+ "license": "SEE LICENSE IN LICENSE",
7
+ "author": "Yak <support@yak.io>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/9f-au/yak.git",
11
+ "directory": "packages/nextjs"
12
+ },
13
+ "publishConfig": {
14
+ "access": "public",
15
+ "provenance": false
16
+ },
17
+ "keywords": [
18
+ "yak",
19
+ "chatbot",
20
+ "ai",
21
+ "widget",
22
+ "chat",
23
+ "nextjs",
24
+ "react"
25
+ ],
26
+ "engines": {
27
+ "node": ">=18"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "LICENSE"
32
+ ],
33
+ "sideEffects": false,
34
+ "exports": {
35
+ "./client": {
36
+ "types": "./dist/index.client.d.ts",
37
+ "import": "./dist/index.client.js"
38
+ },
39
+ "./server": {
40
+ "types": "./dist/index.server.d.ts",
41
+ "import": "./dist/index.server.js"
42
+ },
43
+ "./package.json": "./package.json"
44
+ },
45
+ "bin": {
46
+ "yak-nextjs": "./dist/cli/generate-manifest.js"
47
+ },
48
+ "dependencies": {
49
+ "@yak-io/javascript": "0.1.0",
50
+ "@yak-io/react": "0.1.0"
51
+ },
52
+ "peerDependencies": {
53
+ "next": "^14.0.0 || ^15.0.0",
54
+ "react": "^18.0.0 || ^19.0.0",
55
+ "react-dom": "^18.0.0 || ^19.0.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/node": "^24.10.2",
59
+ "@types/react": "^19.2.7",
60
+ "@types/react-dom": "^19.2.0",
61
+ "next": "^16.0.10",
62
+ "react": "^19.2.3",
63
+ "react-dom": "^19.2.3",
64
+ "typescript": "^5.3.0",
65
+ "@repo/typescript-config": "0.0.0"
66
+ },
67
+ "scripts": {
68
+ "build": "tsc",
69
+ "check-types": "tsc --noEmit"
70
+ }
71
+ }