@exposify/next 0.0.0-stage → 0.0.1

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.
@@ -0,0 +1,196 @@
1
+ import { ProposedField, LoginField, DocSource, RouteMarker, AgentReadyOptions } from '@exposify/core';
2
+ export { HostedAuthResolverConfig, completeMcpLogin, createHostedAuthResolver, describe, exposed, hidden, hostedBroker } from '@exposify/core';
3
+ import { A as ActionField } from './fields-olvyFnxj.cjs';
4
+
5
+ interface AppRouteEntry {
6
+ router: "app";
7
+ /** `/api/orders/:id`; catch-alls as `:slug*`, optional ones as `:slug*?`. */
8
+ path: string;
9
+ params: string[];
10
+ /** Project-relative, for messages. */
11
+ file: string;
12
+ /** Exported methods when generated; the loaded module's exports win at runtime. */
13
+ methods: string[];
14
+ /** Loads the route module to read exposed()/hidden()/describe() off its exports. Absent for edge routes. */
15
+ load?: () => Promise<Record<string, unknown>>;
16
+ /** `export const runtime = "edge"`: not loaded into the Node MCP route, so markers there aren't read. */
17
+ edge?: boolean;
18
+ }
19
+ interface PagesRouteEntry {
20
+ router: "pages";
21
+ path: string;
22
+ params: string[];
23
+ file: string;
24
+ }
25
+ type ManifestRoute = AppRouteEntry | PagesRouteEntry;
26
+ /** An exported function of a `"use server"` module. */
27
+ interface ManifestAction {
28
+ /** Unique among actions: the default tool name, and the URL segment under `<mcpPath>/actions/`. */
29
+ key: string;
30
+ file: string;
31
+ export: string;
32
+ /** How each parameter is filled on a call, in order: see `ActionParamRole` in parse.ts. */
33
+ params: Array<{
34
+ name: string;
35
+ role: "formData" | "prev" | "input" | "object";
36
+ }>;
37
+ /** It sets or deletes a cookie, which would land on exposify's internal call rather than the agent's client. */
38
+ setsCookies?: boolean;
39
+ /** What it takes, worked out from its code (fields.ts): its tool schema when the app doesn't write one. */
40
+ fields: ActionField[];
41
+ /** It reads every form field, so its code doesn't say which exist. */
42
+ readsAll?: boolean;
43
+ /** What the analysis couldn't work out ("line N: …"): with any, the app writes the schema. */
44
+ unresolved?: string[];
45
+ /** The forms that submit to it (pass 3), where they are. */
46
+ forms?: Array<{
47
+ file: string;
48
+ line: number;
49
+ }>;
50
+ /** An input `describe` proposed and a person accepted, current with the code: used when `fields` can't be the schema. */
51
+ proposed?: ProposedField[];
52
+ /**
53
+ * A page that uses it (`/checkout`, `/admin/orders/:id`): tool calls are
54
+ * sent there as a real Server Action request. Absent when no page uses it;
55
+ * it's then called in-process by the MCP route.
56
+ */
57
+ host?: string;
58
+ /**
59
+ * The app's own checks it runs first (`lib/auth.ts#requireAdmin`): a
60
+ * user who doesn't pass one doesn't see the tool (guards.ts).
61
+ */
62
+ guards?: string[];
63
+ load: () => Promise<Record<string, unknown>>;
64
+ }
65
+ /** An App Router page: a read tool that fetches it like a browser (pages.ts). */
66
+ interface ManifestPage {
67
+ /** Tool name, e.g. `view_product_slug`. */
68
+ name: string;
69
+ /** `/product/:slug`, as routes are written. */
70
+ path: string;
71
+ params: string[];
72
+ file: string;
73
+ /** Search params its code reads: optional tool arguments, sent as the query. */
74
+ search?: string[];
75
+ /** From its static `metadata`. */
76
+ title?: string;
77
+ description?: string;
78
+ /** Just a form posting to a Server Action: not a tool unless `pages` lists it. */
79
+ formOnly?: boolean;
80
+ /** The app's own checks it runs (`lib/auth.ts#requireAdmin`), see ManifestAction.guards. */
81
+ guards?: string[];
82
+ }
83
+ /**
84
+ * The app's own login (login.ts): a sign-in form under the MCP route makes
85
+ * this request, for Connect with no code. `host` is the page with the
86
+ * action's form, which tool calls redirected to mean "signed out".
87
+ */
88
+ type ManifestLogin = {
89
+ kind: "action";
90
+ key: string;
91
+ fields: LoginField[];
92
+ host?: string;
93
+ } | {
94
+ kind: "route";
95
+ path: string;
96
+ fields: LoginField[];
97
+ body: "json" | "form";
98
+ };
99
+ interface ExposifyManifest {
100
+ info: {
101
+ name: string;
102
+ version: string;
103
+ };
104
+ /** next.config's basePath, prefixed to every tool call's path. */
105
+ basePath?: string;
106
+ /** next.config's trailingSlash: tool calls add one, so they aren't redirected. */
107
+ trailingSlash?: boolean;
108
+ routes: ManifestRoute[];
109
+ /** The MCP route's URL without its catch-all segment, e.g. `/mcp`: Server Actions are served under `<mcpPath>/actions/`. */
110
+ mcpPath?: string;
111
+ actions?: ManifestAction[];
112
+ pages?: ManifestPage[];
113
+ login?: ManifestLogin;
114
+ /** Docs for search_docs, embedded so they work without a file system. */
115
+ docs: DocSource[];
116
+ /** exposify.descriptions.json's texts, "METHOD /path" -> text. */
117
+ descriptions?: Record<string, string>;
118
+ }
119
+
120
+ /** Set on every tool call; the MCP route refuses requests carrying it, so a tool can never call the MCP endpoint. */
121
+ declare const DISPATCH_HEADER = "x-exposify-dispatch";
122
+ type InputShape = NonNullable<Extract<RouteMarker, {
123
+ kind: "described";
124
+ }>["input"]>;
125
+ interface NextActionOptions {
126
+ /** Tool name. Default: the action's export name, snake_cased (`placeOrder` -> `place_order`). */
127
+ name?: string;
128
+ description?: string;
129
+ /**
130
+ * The action's input, as a zod shape: its form's field names (`true` is
131
+ * sent as a checked checkbox, "on"; arrays as repeated fields; objects as
132
+ * JSON), and the names of any parameters it takes before the FormData
133
+ * (`.bind` arguments). Required for any action that takes input.
134
+ */
135
+ input?: InputShape;
136
+ }
137
+ interface NextAiReadyOptions extends Omit<AgentReadyOptions, "docs"> {
138
+ /**
139
+ * Where tool calls are sent. Default: the origin the MCP request came in on
140
+ * (else the EXPOSIFY_BASE_URL environment variable). Set it when that
141
+ * origin isn't reachable from the server itself, e.g. behind a proxy that
142
+ * only the outside world can resolve.
143
+ */
144
+ baseUrl?: string;
145
+ /**
146
+ * The app's OpenAPI document (import the JSON): matching operations give
147
+ * tools input schemas and descriptions (below describe() and
148
+ * exposify.descriptions.json).
149
+ */
150
+ openapi?: object;
151
+ /**
152
+ * Server Actions to expose as tools, by export name (or by tool name when
153
+ * two files export the same name). Actions are writes, so none is exposed
154
+ * unless listed here or wrapped in exposed()/describe() in its module.
155
+ * `true` is enough for an action that takes no input.
156
+ */
157
+ actions?: Record<string, NextActionOptions | true>;
158
+ /**
159
+ * App Router pages are read tools by default: a call fetches the page like
160
+ * a browser (with the agent's credentials) and returns its main content as
161
+ * text, plus the data it was rendered with. `false` turns them off; by
162
+ * path (`"/product/:slug"`), `false` hides one, `true` brings back one
163
+ * that's just a form, and an object names or describes one. `exclude`
164
+ * globs apply to pages too.
165
+ */
166
+ pages?: false | Record<string, NextPageOptions | boolean>;
167
+ /**
168
+ * MCP requests allowed per client address per window (default 60 per
169
+ * 60 s). In-memory and per instance: best effort, as for the other web
170
+ * adapters; real limits belong to your platform's gateway.
171
+ */
172
+ rateLimit?: number;
173
+ rateWindowMs?: number;
174
+ /**
175
+ * The app's own login, for Connect with the hosted broker: AI assistants
176
+ * sign in on a form this route serves at `<MCP path>/login`, which makes
177
+ * this login request inside the app. Found by `withExposify` (a Server
178
+ * Action or a POST route that takes a password and sets a session). Name
179
+ * another Server Action (by export name), a route (`{ path, fields }`),
180
+ * or `false` to not offer it.
181
+ */
182
+ login?: false | string | {
183
+ path: string;
184
+ fields: string[];
185
+ body?: "json" | "form";
186
+ };
187
+ }
188
+ interface NextPageOptions {
189
+ /** Tool name. Default: `view_` and the path, snake_cased. */
190
+ name?: string;
191
+ description?: string;
192
+ }
193
+ type NextMcpHandler = (req: Request) => Promise<Response>;
194
+ declare function aiReady(manifest: ExposifyManifest, options?: NextAiReadyOptions): NextMcpHandler;
195
+
196
+ export { type AppRouteEntry, DISPATCH_HEADER, type ExposifyManifest, type ManifestAction, type ManifestLogin, type ManifestPage, type ManifestRoute, type NextActionOptions, type NextAiReadyOptions, type NextMcpHandler, type NextPageOptions, type PagesRouteEntry, aiReady };
@@ -0,0 +1,196 @@
1
+ import { ProposedField, LoginField, DocSource, RouteMarker, AgentReadyOptions } from '@exposify/core';
2
+ export { HostedAuthResolverConfig, completeMcpLogin, createHostedAuthResolver, describe, exposed, hidden, hostedBroker } from '@exposify/core';
3
+ import { A as ActionField } from './fields-olvyFnxj.js';
4
+
5
+ interface AppRouteEntry {
6
+ router: "app";
7
+ /** `/api/orders/:id`; catch-alls as `:slug*`, optional ones as `:slug*?`. */
8
+ path: string;
9
+ params: string[];
10
+ /** Project-relative, for messages. */
11
+ file: string;
12
+ /** Exported methods when generated; the loaded module's exports win at runtime. */
13
+ methods: string[];
14
+ /** Loads the route module to read exposed()/hidden()/describe() off its exports. Absent for edge routes. */
15
+ load?: () => Promise<Record<string, unknown>>;
16
+ /** `export const runtime = "edge"`: not loaded into the Node MCP route, so markers there aren't read. */
17
+ edge?: boolean;
18
+ }
19
+ interface PagesRouteEntry {
20
+ router: "pages";
21
+ path: string;
22
+ params: string[];
23
+ file: string;
24
+ }
25
+ type ManifestRoute = AppRouteEntry | PagesRouteEntry;
26
+ /** An exported function of a `"use server"` module. */
27
+ interface ManifestAction {
28
+ /** Unique among actions: the default tool name, and the URL segment under `<mcpPath>/actions/`. */
29
+ key: string;
30
+ file: string;
31
+ export: string;
32
+ /** How each parameter is filled on a call, in order: see `ActionParamRole` in parse.ts. */
33
+ params: Array<{
34
+ name: string;
35
+ role: "formData" | "prev" | "input" | "object";
36
+ }>;
37
+ /** It sets or deletes a cookie, which would land on exposify's internal call rather than the agent's client. */
38
+ setsCookies?: boolean;
39
+ /** What it takes, worked out from its code (fields.ts): its tool schema when the app doesn't write one. */
40
+ fields: ActionField[];
41
+ /** It reads every form field, so its code doesn't say which exist. */
42
+ readsAll?: boolean;
43
+ /** What the analysis couldn't work out ("line N: …"): with any, the app writes the schema. */
44
+ unresolved?: string[];
45
+ /** The forms that submit to it (pass 3), where they are. */
46
+ forms?: Array<{
47
+ file: string;
48
+ line: number;
49
+ }>;
50
+ /** An input `describe` proposed and a person accepted, current with the code: used when `fields` can't be the schema. */
51
+ proposed?: ProposedField[];
52
+ /**
53
+ * A page that uses it (`/checkout`, `/admin/orders/:id`): tool calls are
54
+ * sent there as a real Server Action request. Absent when no page uses it;
55
+ * it's then called in-process by the MCP route.
56
+ */
57
+ host?: string;
58
+ /**
59
+ * The app's own checks it runs first (`lib/auth.ts#requireAdmin`): a
60
+ * user who doesn't pass one doesn't see the tool (guards.ts).
61
+ */
62
+ guards?: string[];
63
+ load: () => Promise<Record<string, unknown>>;
64
+ }
65
+ /** An App Router page: a read tool that fetches it like a browser (pages.ts). */
66
+ interface ManifestPage {
67
+ /** Tool name, e.g. `view_product_slug`. */
68
+ name: string;
69
+ /** `/product/:slug`, as routes are written. */
70
+ path: string;
71
+ params: string[];
72
+ file: string;
73
+ /** Search params its code reads: optional tool arguments, sent as the query. */
74
+ search?: string[];
75
+ /** From its static `metadata`. */
76
+ title?: string;
77
+ description?: string;
78
+ /** Just a form posting to a Server Action: not a tool unless `pages` lists it. */
79
+ formOnly?: boolean;
80
+ /** The app's own checks it runs (`lib/auth.ts#requireAdmin`), see ManifestAction.guards. */
81
+ guards?: string[];
82
+ }
83
+ /**
84
+ * The app's own login (login.ts): a sign-in form under the MCP route makes
85
+ * this request, for Connect with no code. `host` is the page with the
86
+ * action's form, which tool calls redirected to mean "signed out".
87
+ */
88
+ type ManifestLogin = {
89
+ kind: "action";
90
+ key: string;
91
+ fields: LoginField[];
92
+ host?: string;
93
+ } | {
94
+ kind: "route";
95
+ path: string;
96
+ fields: LoginField[];
97
+ body: "json" | "form";
98
+ };
99
+ interface ExposifyManifest {
100
+ info: {
101
+ name: string;
102
+ version: string;
103
+ };
104
+ /** next.config's basePath, prefixed to every tool call's path. */
105
+ basePath?: string;
106
+ /** next.config's trailingSlash: tool calls add one, so they aren't redirected. */
107
+ trailingSlash?: boolean;
108
+ routes: ManifestRoute[];
109
+ /** The MCP route's URL without its catch-all segment, e.g. `/mcp`: Server Actions are served under `<mcpPath>/actions/`. */
110
+ mcpPath?: string;
111
+ actions?: ManifestAction[];
112
+ pages?: ManifestPage[];
113
+ login?: ManifestLogin;
114
+ /** Docs for search_docs, embedded so they work without a file system. */
115
+ docs: DocSource[];
116
+ /** exposify.descriptions.json's texts, "METHOD /path" -> text. */
117
+ descriptions?: Record<string, string>;
118
+ }
119
+
120
+ /** Set on every tool call; the MCP route refuses requests carrying it, so a tool can never call the MCP endpoint. */
121
+ declare const DISPATCH_HEADER = "x-exposify-dispatch";
122
+ type InputShape = NonNullable<Extract<RouteMarker, {
123
+ kind: "described";
124
+ }>["input"]>;
125
+ interface NextActionOptions {
126
+ /** Tool name. Default: the action's export name, snake_cased (`placeOrder` -> `place_order`). */
127
+ name?: string;
128
+ description?: string;
129
+ /**
130
+ * The action's input, as a zod shape: its form's field names (`true` is
131
+ * sent as a checked checkbox, "on"; arrays as repeated fields; objects as
132
+ * JSON), and the names of any parameters it takes before the FormData
133
+ * (`.bind` arguments). Required for any action that takes input.
134
+ */
135
+ input?: InputShape;
136
+ }
137
+ interface NextAiReadyOptions extends Omit<AgentReadyOptions, "docs"> {
138
+ /**
139
+ * Where tool calls are sent. Default: the origin the MCP request came in on
140
+ * (else the EXPOSIFY_BASE_URL environment variable). Set it when that
141
+ * origin isn't reachable from the server itself, e.g. behind a proxy that
142
+ * only the outside world can resolve.
143
+ */
144
+ baseUrl?: string;
145
+ /**
146
+ * The app's OpenAPI document (import the JSON): matching operations give
147
+ * tools input schemas and descriptions (below describe() and
148
+ * exposify.descriptions.json).
149
+ */
150
+ openapi?: object;
151
+ /**
152
+ * Server Actions to expose as tools, by export name (or by tool name when
153
+ * two files export the same name). Actions are writes, so none is exposed
154
+ * unless listed here or wrapped in exposed()/describe() in its module.
155
+ * `true` is enough for an action that takes no input.
156
+ */
157
+ actions?: Record<string, NextActionOptions | true>;
158
+ /**
159
+ * App Router pages are read tools by default: a call fetches the page like
160
+ * a browser (with the agent's credentials) and returns its main content as
161
+ * text, plus the data it was rendered with. `false` turns them off; by
162
+ * path (`"/product/:slug"`), `false` hides one, `true` brings back one
163
+ * that's just a form, and an object names or describes one. `exclude`
164
+ * globs apply to pages too.
165
+ */
166
+ pages?: false | Record<string, NextPageOptions | boolean>;
167
+ /**
168
+ * MCP requests allowed per client address per window (default 60 per
169
+ * 60 s). In-memory and per instance: best effort, as for the other web
170
+ * adapters; real limits belong to your platform's gateway.
171
+ */
172
+ rateLimit?: number;
173
+ rateWindowMs?: number;
174
+ /**
175
+ * The app's own login, for Connect with the hosted broker: AI assistants
176
+ * sign in on a form this route serves at `<MCP path>/login`, which makes
177
+ * this login request inside the app. Found by `withExposify` (a Server
178
+ * Action or a POST route that takes a password and sets a session). Name
179
+ * another Server Action (by export name), a route (`{ path, fields }`),
180
+ * or `false` to not offer it.
181
+ */
182
+ login?: false | string | {
183
+ path: string;
184
+ fields: string[];
185
+ body?: "json" | "form";
186
+ };
187
+ }
188
+ interface NextPageOptions {
189
+ /** Tool name. Default: `view_` and the path, snake_cased. */
190
+ name?: string;
191
+ description?: string;
192
+ }
193
+ type NextMcpHandler = (req: Request) => Promise<Response>;
194
+ declare function aiReady(manifest: ExposifyManifest, options?: NextAiReadyOptions): NextMcpHandler;
195
+
196
+ export { type AppRouteEntry, DISPATCH_HEADER, type ExposifyManifest, type ManifestAction, type ManifestLogin, type ManifestPage, type ManifestRoute, type NextActionOptions, type NextAiReadyOptions, type NextMcpHandler, type NextPageOptions, type PagesRouteEntry, aiReady };