@ai-ins/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.
package/dist/index.js ADDED
@@ -0,0 +1,202 @@
1
+ // ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.12_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ var getFilename = () => fileURLToPath(import.meta.url);
5
+ var getDirname = () => path.dirname(getFilename());
6
+ var __dirname = /* @__PURE__ */ getDirname();
7
+
8
+ // src/index.ts
9
+ import { createServer } from "http";
10
+ import { existsSync } from "fs";
11
+ import { join } from "path";
12
+ import { createAiInsMiddlewares, getAiInsClientCode, normalizeProxy } from "@ai-ins/core";
13
+ var packageDirectory = __dirname;
14
+ var developmentPhase = "phase-development-server";
15
+ var aiInsServers = /* @__PURE__ */ new Map();
16
+ function getBundledAssetPath(fileName) {
17
+ const sourcePath = join(packageDirectory, "..", "src", fileName);
18
+ return existsSync(sourcePath) ? sourcePath : join(packageDirectory, fileName);
19
+ }
20
+ var clientEntryPath = getBundledAssetPath("client-entry.js");
21
+ var sourceLoaderPath = getBundledAssetPath("source-loader.cjs");
22
+ function hasEntryValue(entry, value) {
23
+ if (entry === value) return true;
24
+ if (Array.isArray(entry)) return entry.some((item) => hasEntryValue(item, value));
25
+ if (entry && typeof entry === "object") return Object.values(entry).some((item) => hasEntryValue(item, value));
26
+ return false;
27
+ }
28
+ function prependEntry(entry, value) {
29
+ if (hasEntryValue(entry, value)) return entry;
30
+ if (!entry) return [value];
31
+ if (typeof entry === "string") return [value, entry];
32
+ if (Array.isArray(entry)) return [value, ...entry];
33
+ if (typeof entry === "function") {
34
+ return async (...args) => prependEntry(await entry(...args), value);
35
+ }
36
+ if (entry && typeof entry === "object") {
37
+ if ("import" in entry) {
38
+ return { ...entry, import: prependEntry(entry.import, value) };
39
+ }
40
+ return Object.fromEntries(Object.entries(entry).map(([key, childEntry]) => [key, prependEntry(childEntry, value)]));
41
+ }
42
+ return entry;
43
+ }
44
+ function normalizeRoot(root) {
45
+ return root || process.cwd();
46
+ }
47
+ function getServerKey(root, options) {
48
+ return `${root}:${options.middlewarePort ?? 0}`;
49
+ }
50
+ function dispatch(routes, req, res) {
51
+ const pathname = req.url ? new URL(req.url, "http://localhost").pathname : "/";
52
+ const route = routes.find((candidate) => pathname === candidate.path || pathname.startsWith(`${candidate.path}/`));
53
+ if (!route) {
54
+ res.statusCode = 404;
55
+ res.end("AI Ins route not found");
56
+ return;
57
+ }
58
+ route.middleware(req, res);
59
+ }
60
+ function startAiInsServer(root, options) {
61
+ const key = getServerKey(root, options);
62
+ const existing = aiInsServers.get(key);
63
+ if (existing) {
64
+ return existing;
65
+ }
66
+ const promise = new Promise((resolve, reject) => {
67
+ const pluginProxy = normalizeProxy(options.codex?.proxy ?? options.proxy);
68
+ const routes = [
69
+ {
70
+ path: "/__ai-ins/client.js",
71
+ middleware: (_req, res) => {
72
+ res.setHeader("Content-Type", "application/javascript; charset=utf-8");
73
+ res.end(getAiInsClientCode({ base: "/", defaultProvider: options.agents?.defaultProvider, options, pluginProxy, root }));
74
+ }
75
+ },
76
+ ...createAiInsMiddlewares(root, options)
77
+ ].sort((left, right) => right.path.length - left.path.length);
78
+ const server = createServer((req, res) => dispatch(routes, req, res));
79
+ server.once("error", reject);
80
+ server.listen(options.middlewarePort ?? 0, "127.0.0.1", () => {
81
+ server.off("error", reject);
82
+ const address = server.address();
83
+ if (!address || typeof address === "string") {
84
+ reject(new Error("failed to start AI Ins middleware server"));
85
+ return;
86
+ }
87
+ resolve({ port: address.port, server });
88
+ });
89
+ });
90
+ aiInsServers.set(key, promise);
91
+ return promise;
92
+ }
93
+ function appendWebpackRule(config) {
94
+ if (!config.module) config.module = {};
95
+ const rules = config.module.rules ?? [];
96
+ config.module.rules = [
97
+ ...rules,
98
+ {
99
+ enforce: "pre",
100
+ exclude: /node_modules/u,
101
+ test: /\.[cm]?[jt]sx$/u,
102
+ use: sourceLoaderPath
103
+ }
104
+ ];
105
+ }
106
+ function withWebpackConfig(config, options) {
107
+ const previousWebpack = config.webpack;
108
+ return {
109
+ ...config,
110
+ webpack(webpackConfig, context) {
111
+ const nextWebpackConfig = previousWebpack ? previousWebpack(webpackConfig, context) : webpackConfig;
112
+ if (context.dev && !context.isServer) {
113
+ nextWebpackConfig.entry = prependEntry(nextWebpackConfig.entry, clientEntryPath);
114
+ }
115
+ if (context.dev && !options.disableSourceAttributes) {
116
+ appendWebpackRule(nextWebpackConfig);
117
+ }
118
+ return nextWebpackConfig;
119
+ }
120
+ };
121
+ }
122
+ function withTurbopackConfig(config, options) {
123
+ if (options.disableSourceAttributes) {
124
+ return config;
125
+ }
126
+ const turbopack = config.turbopack ?? {};
127
+ const rules = turbopack.rules ?? {};
128
+ return {
129
+ ...config,
130
+ turbopack: {
131
+ ...turbopack,
132
+ rules: {
133
+ ...rules,
134
+ "*.{jsx,tsx}": {
135
+ as: "*.js",
136
+ loaders: [sourceLoaderPath]
137
+ }
138
+ }
139
+ }
140
+ };
141
+ }
142
+ async function resolveRewrites(rewrites) {
143
+ const value = typeof rewrites === "function" ? await rewrites() : rewrites;
144
+ if (!value) {
145
+ return [];
146
+ }
147
+ return value;
148
+ }
149
+ async function mergeRewrites(rewrites, middlewarePort) {
150
+ const aiInsRewrites = [
151
+ {
152
+ source: "/__ai-ins/:path*",
153
+ destination: `http://127.0.0.1:${middlewarePort}/__ai-ins/:path*`
154
+ },
155
+ {
156
+ source: "/__ai-ins-agent/:path*",
157
+ destination: `http://127.0.0.1:${middlewarePort}/__ai-ins-agent/:path*`
158
+ },
159
+ {
160
+ source: "/__open-in-editor",
161
+ destination: `http://127.0.0.1:${middlewarePort}/__open-in-editor`
162
+ },
163
+ {
164
+ source: "/__reveal-in-folder",
165
+ destination: `http://127.0.0.1:${middlewarePort}/__reveal-in-folder`
166
+ }
167
+ ];
168
+ const existing = await resolveRewrites(rewrites);
169
+ if (Array.isArray(existing)) {
170
+ return [...aiInsRewrites, ...existing];
171
+ }
172
+ return {
173
+ ...existing,
174
+ beforeFiles: [...aiInsRewrites, ...existing.beforeFiles ?? []]
175
+ };
176
+ }
177
+ function withAiIns(nextConfig = {}, options = {}) {
178
+ return async (phase, context) => {
179
+ const resolvedConfig = typeof nextConfig === "function" ? await nextConfig(phase, context) : nextConfig;
180
+ const root = normalizeRoot(typeof context === "object" && context && "dir" in context ? String(context.dir ?? "") : void 0);
181
+ const config = withTurbopackConfig(withWebpackConfig(resolvedConfig, options), options);
182
+ if (phase !== developmentPhase) {
183
+ return config;
184
+ }
185
+ const { port } = await startAiInsServer(root, options);
186
+ const previousRewrites = config.rewrites;
187
+ return {
188
+ ...config,
189
+ async rewrites() {
190
+ return mergeRewrites(previousRewrites, port);
191
+ }
192
+ };
193
+ };
194
+ }
195
+ var aiIns = withAiIns;
196
+ var index_default = withAiIns;
197
+ export {
198
+ aiIns,
199
+ index_default as default,
200
+ withAiIns
201
+ };
202
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.12_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js","../src/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createAiInsMiddlewares, getAiInsClientCode, normalizeProxy } from '@ai-ins/core'\nimport type { AiInsMiddleware, AiInsPluginOptions } from '@ai-ins/core'\n\nexport type { AiInsPluginOptions }\n\nexport type AiInsNextPluginOptions = AiInsPluginOptions & {\n middlewarePort?: number\n}\n\ntype NextConfig = import('next').NextConfig & {\n rewrites?: NextRewrites\n turbopack?: {\n rules?: Record<string, unknown>\n } & import('next').NextConfig['turbopack']\n}\n\ntype NextConfigExport = NextConfig | ((phase: string, context?: unknown) => NextConfig | Promise<NextConfig>)\n\ntype NextRewrites =\n | (() => Promise<Rewrite[] | { afterFiles?: Rewrite[]; beforeFiles?: Rewrite[]; fallback?: Rewrite[] }>)\n | Rewrite[]\n | { afterFiles?: Rewrite[]; beforeFiles?: Rewrite[]; fallback?: Rewrite[] }\n\ntype Rewrite = {\n destination: string\n source: string\n}\n\ntype WebpackConfig = {\n entry?: unknown\n module?: {\n rules?: unknown[]\n }\n}\n\ntype WebpackContext = {\n dev?: boolean\n dir?: string\n isServer?: boolean\n}\n\ntype AiInsServerState = {\n port: number\n server: Server\n}\n\nconst packageDirectory = __dirname\nconst developmentPhase = 'phase-development-server'\nconst aiInsServers = new Map<string, Promise<AiInsServerState>>()\n\nfunction getBundledAssetPath(fileName: string) {\n const sourcePath = join(packageDirectory, '..', 'src', fileName)\n return existsSync(sourcePath) ? sourcePath : join(packageDirectory, fileName)\n}\n\nconst clientEntryPath = getBundledAssetPath('client-entry.js')\nconst sourceLoaderPath = getBundledAssetPath('source-loader.cjs')\n\nfunction hasEntryValue(entry: unknown, value: string): boolean {\n if (entry === value) return true\n if (Array.isArray(entry)) return entry.some((item) => hasEntryValue(item, value))\n if (entry && typeof entry === 'object') return Object.values(entry).some((item) => hasEntryValue(item, value))\n return false\n}\n\nfunction prependEntry(entry: unknown, value: string): unknown {\n if (hasEntryValue(entry, value)) return entry\n if (!entry) return [value]\n if (typeof entry === 'string') return [value, entry]\n if (Array.isArray(entry)) return [value, ...entry]\n if (typeof entry === 'function') {\n return async (...args: unknown[]) => prependEntry(await entry(...args), value)\n }\n if (entry && typeof entry === 'object') {\n if ('import' in entry) {\n return { ...entry, import: prependEntry((entry as { import?: unknown }).import, value) }\n }\n\n return Object.fromEntries(Object.entries(entry).map(([key, childEntry]) => [key, prependEntry(childEntry, value)]))\n }\n\n return entry\n}\n\nfunction normalizeRoot(root: string | undefined) {\n return root || process.cwd()\n}\n\nfunction getServerKey(root: string, options: AiInsNextPluginOptions) {\n return `${root}:${options.middlewarePort ?? 0}`\n}\n\nfunction dispatch(routes: Array<{ middleware: AiInsMiddleware; path: string }>, req: IncomingMessage, res: ServerResponse) {\n const pathname = req.url ? new URL(req.url, 'http://localhost').pathname : '/'\n const route = routes.find((candidate) => pathname === candidate.path || pathname.startsWith(`${candidate.path}/`))\n\n if (!route) {\n res.statusCode = 404\n res.end('AI Ins route not found')\n return\n }\n\n route.middleware(req, res)\n}\n\nfunction startAiInsServer(root: string, options: AiInsNextPluginOptions) {\n const key = getServerKey(root, options)\n const existing = aiInsServers.get(key)\n if (existing) {\n return existing\n }\n\n const promise = new Promise<AiInsServerState>((resolve, reject) => {\n const pluginProxy = normalizeProxy(options.codex?.proxy ?? options.proxy)\n const routes = [\n {\n path: '/__ai-ins/client.js',\n middleware: (_req: IncomingMessage, res: ServerResponse) => {\n res.setHeader('Content-Type', 'application/javascript; charset=utf-8')\n res.end(getAiInsClientCode({ base: '/', defaultProvider: options.agents?.defaultProvider, options, pluginProxy, root }))\n },\n },\n ...createAiInsMiddlewares(root, options),\n ].sort((left, right) => right.path.length - left.path.length)\n\n const server = createServer((req, res) => dispatch(routes, req, res))\n server.once('error', reject)\n server.listen(options.middlewarePort ?? 0, '127.0.0.1', () => {\n server.off('error', reject)\n const address = server.address()\n if (!address || typeof address === 'string') {\n reject(new Error('failed to start AI Ins middleware server'))\n return\n }\n\n resolve({ port: address.port, server })\n })\n })\n\n aiInsServers.set(key, promise)\n return promise\n}\n\nfunction appendWebpackRule(config: WebpackConfig) {\n if (!config.module) config.module = {}\n const rules = config.module.rules ?? []\n config.module.rules = [\n ...rules,\n {\n enforce: 'pre',\n exclude: /node_modules/u,\n test: /\\.[cm]?[jt]sx$/u,\n use: sourceLoaderPath,\n },\n ]\n}\n\nfunction withWebpackConfig(config: NextConfig, options: AiInsNextPluginOptions): NextConfig {\n const previousWebpack = config.webpack as ((config: WebpackConfig, context: WebpackContext) => WebpackConfig) | null | undefined\n\n return {\n ...config,\n webpack(webpackConfig: WebpackConfig, context: WebpackContext) {\n const nextWebpackConfig = previousWebpack ? previousWebpack(webpackConfig, context) : webpackConfig\n if (context.dev && !context.isServer) {\n nextWebpackConfig.entry = prependEntry(nextWebpackConfig.entry, clientEntryPath)\n }\n if (context.dev && !options.disableSourceAttributes) {\n appendWebpackRule(nextWebpackConfig)\n }\n return nextWebpackConfig\n },\n }\n}\n\nfunction withTurbopackConfig(config: NextConfig, options: AiInsNextPluginOptions): NextConfig {\n if (options.disableSourceAttributes) {\n return config\n }\n\n const turbopack = config.turbopack ?? {}\n const rules = turbopack.rules ?? {}\n\n return {\n ...config,\n turbopack: {\n ...turbopack,\n rules: {\n ...rules,\n '*.{jsx,tsx}': {\n as: '*.js',\n loaders: [sourceLoaderPath],\n },\n },\n },\n }\n}\n\nasync function resolveRewrites(rewrites: NextRewrites | undefined) {\n const value = typeof rewrites === 'function' ? await rewrites() : rewrites\n if (!value) {\n return []\n }\n\n return value\n}\n\nasync function mergeRewrites(rewrites: NextRewrites | undefined, middlewarePort: number) {\n const aiInsRewrites: Rewrite[] = [\n {\n source: '/__ai-ins/:path*',\n destination: `http://127.0.0.1:${middlewarePort}/__ai-ins/:path*`,\n },\n {\n source: '/__ai-ins-agent/:path*',\n destination: `http://127.0.0.1:${middlewarePort}/__ai-ins-agent/:path*`,\n },\n {\n source: '/__open-in-editor',\n destination: `http://127.0.0.1:${middlewarePort}/__open-in-editor`,\n },\n {\n source: '/__reveal-in-folder',\n destination: `http://127.0.0.1:${middlewarePort}/__reveal-in-folder`,\n },\n ]\n const existing = await resolveRewrites(rewrites)\n\n if (Array.isArray(existing)) {\n return [...aiInsRewrites, ...existing]\n }\n\n return {\n ...existing,\n beforeFiles: [...aiInsRewrites, ...(existing.beforeFiles ?? [])],\n }\n}\n\nexport function withAiIns(nextConfig: NextConfigExport = {}, options: AiInsNextPluginOptions = {}) {\n return async (phase: string, context?: unknown) => {\n const resolvedConfig = typeof nextConfig === 'function' ? await nextConfig(phase, context) : nextConfig\n const root = normalizeRoot(typeof context === 'object' && context && 'dir' in context ? String((context as { dir?: unknown }).dir ?? '') : undefined)\n const config = withTurbopackConfig(withWebpackConfig(resolvedConfig, options), options)\n\n if (phase !== developmentPhase) {\n return config\n }\n\n const { port } = await startAiInsServer(root, options)\n const previousRewrites = config.rewrites\n\n return {\n ...config,\n async rewrites() {\n return mergeRewrites(previousRewrites, port)\n },\n }\n }\n}\n\nexport const aiIns = withAiIns\nexport default withAiIns\n"],"mappings":"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","names":[]}
@@ -0,0 +1,90 @@
1
+ const { transformSync } = require('@babel/core')
2
+ const transformReactJsx = require('@babel/plugin-transform-react-jsx')
3
+ const transformTypeScript = require('@babel/plugin-transform-typescript')
4
+
5
+ const sourceAttribute = 'data-ai-ins-source'
6
+ const sourceRangeAttribute = 'data-ai-ins-source-range'
7
+
8
+ function isNativeJsxElementName(name) {
9
+ return Boolean(name && name.type === 'JSXIdentifier' && typeof name.name === 'string' && /^[a-z]/u.test(name.name))
10
+ }
11
+
12
+ function hasSourceAttribute(attributes) {
13
+ return attributes.some((attribute) => {
14
+ return Boolean(
15
+ attribute &&
16
+ attribute.type === 'JSXAttribute' &&
17
+ attribute.name &&
18
+ attribute.name.type === 'JSXIdentifier' &&
19
+ (attribute.name.name === sourceAttribute || attribute.name.name === sourceRangeAttribute),
20
+ )
21
+ })
22
+ }
23
+
24
+ function createAgentSourcePlugin(fileName) {
25
+ return {
26
+ name: 'ai-ins-source-attribute',
27
+ visitor: {
28
+ JSXOpeningElement(path) {
29
+ const { node } = path
30
+ if (!isNativeJsxElementName(node.name) || hasSourceAttribute(node.attributes) || !node.loc) {
31
+ return
32
+ }
33
+
34
+ const elementLocation = path.parentPath.isJSXElement() && path.parentPath.node.loc ? path.parentPath.node.loc : node.loc
35
+ node.attributes.push(
36
+ {
37
+ name: { name: sourceAttribute, type: 'JSXIdentifier' },
38
+ type: 'JSXAttribute',
39
+ value: {
40
+ type: 'StringLiteral',
41
+ value: `${fileName}:${node.loc.start.line}:${node.loc.start.column + 1}`,
42
+ },
43
+ },
44
+ {
45
+ name: { name: sourceRangeAttribute, type: 'JSXIdentifier' },
46
+ type: 'JSXAttribute',
47
+ value: {
48
+ type: 'StringLiteral',
49
+ value: `${fileName}:${elementLocation.start.line}:${elementLocation.start.column + 1}-${elementLocation.end.line}:${elementLocation.end.column + 1}`,
50
+ },
51
+ },
52
+ )
53
+ },
54
+ },
55
+ }
56
+ }
57
+
58
+ module.exports = function aiInsNextSourceLoader(code, inputMap) {
59
+ const callback = this.async()
60
+ const fileName = this.resourcePath
61
+
62
+ if (!/\.[cm]?[jt]sx$/u.test(fileName) || fileName.includes('/node_modules/') || fileName.includes('\\node_modules\\')) {
63
+ callback(null, code, inputMap)
64
+ return
65
+ }
66
+
67
+ try {
68
+ const result = transformSync(code, {
69
+ babelrc: false,
70
+ code: true,
71
+ configFile: false,
72
+ filename: fileName,
73
+ inputSourceMap: inputMap || undefined,
74
+ parserOpts: {
75
+ plugins: ['jsx', 'typescript'],
76
+ sourceType: 'module',
77
+ },
78
+ plugins: [
79
+ createAgentSourcePlugin(fileName),
80
+ [transformTypeScript, { allowDeclareFields: true, allExtensions: true, isTSX: true }],
81
+ [transformReactJsx, { runtime: 'automatic' }],
82
+ ],
83
+ sourceMaps: true,
84
+ })
85
+
86
+ callback(null, result && result.code ? result.code : code, result ? result.map : inputMap)
87
+ } catch (error) {
88
+ callback(error)
89
+ }
90
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@ai-ins/nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Next.js plugin for AI Ins.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./client": {
16
+ "import": "./dist/client-entry.js",
17
+ "require": "./dist/client-entry.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^22.15.3",
28
+ "next": "^16.0.10",
29
+ "tsup": "^8.4.0",
30
+ "typescript": "^5.8.3",
31
+ "webpack": "^5.99.0"
32
+ },
33
+ "peerDependencies": {
34
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0"
35
+ },
36
+ "dependencies": {
37
+ "@babel/core": "^7.29.0",
38
+ "@babel/plugin-transform-react-jsx": "^7.28.6",
39
+ "@babel/plugin-transform-typescript": "^7.28.6",
40
+ "@ai-ins/core": "0.3.4"
41
+ },
42
+ "scripts": {
43
+ "copy-build": "node scripts/copy-build.mjs",
44
+ "build": "tsup src/index.ts --format esm,cjs --dts --sourcemap --clean --shims && pnpm copy-build",
45
+ "dev": "tsup src/index.ts --format esm,cjs --dts --sourcemap --shims --watch --onSuccess \"pnpm copy-build\"",
46
+ "typecheck": "tsc --noEmit",
47
+ "clean": "rm -rf dist"
48
+ }
49
+ }