@exposify/next 0.0.0-stage → 0.0.2

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,201 @@
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
+ /** Where it is, for the startup log and the dashboard: "signIn in app/actions/auth.ts". */
100
+ where?: string;
101
+ };
102
+ interface ExposifyManifest {
103
+ info: {
104
+ name: string;
105
+ version: string;
106
+ };
107
+ /** next.config's basePath, prefixed to every tool call's path. */
108
+ basePath?: string;
109
+ /** next.config's trailingSlash: tool calls add one, so they aren't redirected. */
110
+ trailingSlash?: boolean;
111
+ routes: ManifestRoute[];
112
+ /** The MCP route's URL without its catch-all segment, e.g. `/mcp`: Server Actions are served under `<mcpPath>/actions/`. */
113
+ mcpPath?: string;
114
+ actions?: ManifestAction[];
115
+ pages?: ManifestPage[];
116
+ login?: ManifestLogin;
117
+ /** Auth libraries in package.json ("next-auth", "@supabase/ssr", ...), reported with the login. */
118
+ authStacks?: string[];
119
+ /** Docs for search_docs, embedded so they work without a file system. */
120
+ docs: DocSource[];
121
+ /** exposify.descriptions.json's texts, "METHOD /path" -> text. */
122
+ descriptions?: Record<string, string>;
123
+ }
124
+
125
+ /** Set on every tool call; the MCP route refuses requests carrying it, so a tool can never call the MCP endpoint. */
126
+ declare const DISPATCH_HEADER = "x-exposify-dispatch";
127
+ type InputShape = NonNullable<Extract<RouteMarker, {
128
+ kind: "described";
129
+ }>["input"]>;
130
+ interface NextActionOptions {
131
+ /** Tool name. Default: the action's export name, snake_cased (`placeOrder` -> `place_order`). */
132
+ name?: string;
133
+ description?: string;
134
+ /**
135
+ * The action's input, as a zod shape: its form's field names (`true` is
136
+ * sent as a checked checkbox, "on"; arrays as repeated fields; objects as
137
+ * JSON), and the names of any parameters it takes before the FormData
138
+ * (`.bind` arguments). Required for any action that takes input.
139
+ */
140
+ input?: InputShape;
141
+ }
142
+ interface NextAiReadyOptions extends Omit<AgentReadyOptions, "docs"> {
143
+ /**
144
+ * Where tool calls are sent. Default: the origin the MCP request came in on
145
+ * (else the EXPOSIFY_BASE_URL environment variable). Set it when that
146
+ * origin isn't reachable from the server itself, e.g. behind a proxy that
147
+ * only the outside world can resolve.
148
+ */
149
+ baseUrl?: string;
150
+ /**
151
+ * The app's OpenAPI document (import the JSON): matching operations give
152
+ * tools input schemas and descriptions (below describe() and
153
+ * exposify.descriptions.json).
154
+ */
155
+ openapi?: object;
156
+ /**
157
+ * Server Actions to expose as tools, by export name (or by tool name when
158
+ * two files export the same name). Actions are writes, so none is exposed
159
+ * unless listed here or wrapped in exposed()/describe() in its module.
160
+ * `true` is enough for an action that takes no input.
161
+ */
162
+ actions?: Record<string, NextActionOptions | true>;
163
+ /**
164
+ * App Router pages are read tools by default: a call fetches the page like
165
+ * a browser (with the agent's credentials) and returns its main content as
166
+ * text, plus the data it was rendered with. `false` turns them off; by
167
+ * path (`"/product/:slug"`), `false` hides one, `true` brings back one
168
+ * that's just a form, and an object names or describes one. `exclude`
169
+ * globs apply to pages too.
170
+ */
171
+ pages?: false | Record<string, NextPageOptions | boolean>;
172
+ /**
173
+ * MCP requests allowed per client address per window (default 60 per
174
+ * 60 s). In-memory and per instance: best effort, as for the other web
175
+ * adapters; real limits belong to your platform's gateway.
176
+ */
177
+ rateLimit?: number;
178
+ rateWindowMs?: number;
179
+ /**
180
+ * The app's own login, for Connect with the hosted broker: AI assistants
181
+ * sign in on a form this route serves at `<MCP path>/login`, which makes
182
+ * this login request inside the app. Found by `withExposify` (a Server
183
+ * Action or a POST route that takes a password and sets a session). Name
184
+ * another Server Action (by export name), a route (`{ path, fields }`),
185
+ * or `false` to not offer it.
186
+ */
187
+ login?: false | string | {
188
+ path: string;
189
+ fields: string[];
190
+ body?: "json" | "form";
191
+ };
192
+ }
193
+ interface NextPageOptions {
194
+ /** Tool name. Default: `view_` and the path, snake_cased. */
195
+ name?: string;
196
+ description?: string;
197
+ }
198
+ type NextMcpHandler = (req: Request) => Promise<Response>;
199
+ declare function aiReady(manifest: ExposifyManifest, options?: NextAiReadyOptions): NextMcpHandler;
200
+
201
+ 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,201 @@
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
+ /** Where it is, for the startup log and the dashboard: "signIn in app/actions/auth.ts". */
100
+ where?: string;
101
+ };
102
+ interface ExposifyManifest {
103
+ info: {
104
+ name: string;
105
+ version: string;
106
+ };
107
+ /** next.config's basePath, prefixed to every tool call's path. */
108
+ basePath?: string;
109
+ /** next.config's trailingSlash: tool calls add one, so they aren't redirected. */
110
+ trailingSlash?: boolean;
111
+ routes: ManifestRoute[];
112
+ /** The MCP route's URL without its catch-all segment, e.g. `/mcp`: Server Actions are served under `<mcpPath>/actions/`. */
113
+ mcpPath?: string;
114
+ actions?: ManifestAction[];
115
+ pages?: ManifestPage[];
116
+ login?: ManifestLogin;
117
+ /** Auth libraries in package.json ("next-auth", "@supabase/ssr", ...), reported with the login. */
118
+ authStacks?: string[];
119
+ /** Docs for search_docs, embedded so they work without a file system. */
120
+ docs: DocSource[];
121
+ /** exposify.descriptions.json's texts, "METHOD /path" -> text. */
122
+ descriptions?: Record<string, string>;
123
+ }
124
+
125
+ /** Set on every tool call; the MCP route refuses requests carrying it, so a tool can never call the MCP endpoint. */
126
+ declare const DISPATCH_HEADER = "x-exposify-dispatch";
127
+ type InputShape = NonNullable<Extract<RouteMarker, {
128
+ kind: "described";
129
+ }>["input"]>;
130
+ interface NextActionOptions {
131
+ /** Tool name. Default: the action's export name, snake_cased (`placeOrder` -> `place_order`). */
132
+ name?: string;
133
+ description?: string;
134
+ /**
135
+ * The action's input, as a zod shape: its form's field names (`true` is
136
+ * sent as a checked checkbox, "on"; arrays as repeated fields; objects as
137
+ * JSON), and the names of any parameters it takes before the FormData
138
+ * (`.bind` arguments). Required for any action that takes input.
139
+ */
140
+ input?: InputShape;
141
+ }
142
+ interface NextAiReadyOptions extends Omit<AgentReadyOptions, "docs"> {
143
+ /**
144
+ * Where tool calls are sent. Default: the origin the MCP request came in on
145
+ * (else the EXPOSIFY_BASE_URL environment variable). Set it when that
146
+ * origin isn't reachable from the server itself, e.g. behind a proxy that
147
+ * only the outside world can resolve.
148
+ */
149
+ baseUrl?: string;
150
+ /**
151
+ * The app's OpenAPI document (import the JSON): matching operations give
152
+ * tools input schemas and descriptions (below describe() and
153
+ * exposify.descriptions.json).
154
+ */
155
+ openapi?: object;
156
+ /**
157
+ * Server Actions to expose as tools, by export name (or by tool name when
158
+ * two files export the same name). Actions are writes, so none is exposed
159
+ * unless listed here or wrapped in exposed()/describe() in its module.
160
+ * `true` is enough for an action that takes no input.
161
+ */
162
+ actions?: Record<string, NextActionOptions | true>;
163
+ /**
164
+ * App Router pages are read tools by default: a call fetches the page like
165
+ * a browser (with the agent's credentials) and returns its main content as
166
+ * text, plus the data it was rendered with. `false` turns them off; by
167
+ * path (`"/product/:slug"`), `false` hides one, `true` brings back one
168
+ * that's just a form, and an object names or describes one. `exclude`
169
+ * globs apply to pages too.
170
+ */
171
+ pages?: false | Record<string, NextPageOptions | boolean>;
172
+ /**
173
+ * MCP requests allowed per client address per window (default 60 per
174
+ * 60 s). In-memory and per instance: best effort, as for the other web
175
+ * adapters; real limits belong to your platform's gateway.
176
+ */
177
+ rateLimit?: number;
178
+ rateWindowMs?: number;
179
+ /**
180
+ * The app's own login, for Connect with the hosted broker: AI assistants
181
+ * sign in on a form this route serves at `<MCP path>/login`, which makes
182
+ * this login request inside the app. Found by `withExposify` (a Server
183
+ * Action or a POST route that takes a password and sets a session). Name
184
+ * another Server Action (by export name), a route (`{ path, fields }`),
185
+ * or `false` to not offer it.
186
+ */
187
+ login?: false | string | {
188
+ path: string;
189
+ fields: string[];
190
+ body?: "json" | "form";
191
+ };
192
+ }
193
+ interface NextPageOptions {
194
+ /** Tool name. Default: `view_` and the path, snake_cased. */
195
+ name?: string;
196
+ description?: string;
197
+ }
198
+ type NextMcpHandler = (req: Request) => Promise<Response>;
199
+ declare function aiReady(manifest: ExposifyManifest, options?: NextAiReadyOptions): NextMcpHandler;
200
+
201
+ 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 };