agenauto-nextjs 1.0.1 → 1.3.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @agenauto/nextjs
2
2
 
3
- Official Next.js SDK for [AgenAuto](https://agenauto.dev) — your autonomous AI agent.
3
+ Official Next.js SDK for [AgenAuto](https://agenauto.lat) — your autonomous AI agent.
4
4
 
5
5
  ## Installation
6
6
 
@@ -63,7 +63,7 @@ function MyComponent() {
63
63
  | Prop | Type | Default | Description |
64
64
  |:---|:---|:---|:---|
65
65
  | `agentKey` | `string` | **required** | Your Agent Key from the AgenAuto dashboard |
66
- | `apiUrl` | `string` | `https://app.agenauto.dev` | Your AgenAuto instance URL |
66
+ | `apiUrl` | `string` | `https://agenauto.lat` | Your AgenAuto instance URL |
67
67
  | `showBadge` | `boolean` | `false` | Show status badge on the page |
68
68
 
69
69
  ### `useAgenAuto()`
@@ -0,0 +1,220 @@
1
+ /**
2
+ * AgenAuto SDK — Next.js Bridge Route
3
+ *
4
+ * Install in your Next.js project:
5
+ * 1. Copy this file to: src/app/api/agenauto/route.ts
6
+ * 2. Set AGENAUTO_KEY in your .env (get it from agenauto.lat dashboard)
7
+ * 3. Deploy your app — the agent will connect automatically
8
+ *
9
+ * The agent can then read/write files, run lints, and improve your project autonomously.
10
+ */
11
+
12
+ import { NextResponse } from "next/server";
13
+ import { readdir, readFile, writeFile, stat } from "fs/promises";
14
+ import { execSync } from "child_process";
15
+ import { join, extname } from "path";
16
+ import { existsSync } from "fs";
17
+
18
+ const AGENAUTO_KEY = process.env.AGENAUTO_KEY || "";
19
+ const PROJECT_ROOT = process.cwd();
20
+
21
+ // Auth check
22
+ function checkAuth(req: Request): boolean {
23
+ const key = req.headers.get("X-AgenAuto-Key") || "";
24
+ return AGENAUTO_KEY.length > 0 && key === AGENAUTO_KEY;
25
+ }
26
+
27
+ function unauthorized() {
28
+ return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
29
+ }
30
+
31
+ // GET /api/agenauto/site-info
32
+ async function getSiteInfo() {
33
+ const pkgPath = join(PROJECT_ROOT, "package.json");
34
+ let pkg: any = {};
35
+
36
+ try {
37
+ const pkgContent = await readFile(pkgPath, "utf-8");
38
+ pkg = JSON.parse(pkgContent);
39
+ } catch { }
40
+
41
+ const nextVersion = pkg.dependencies?.next || pkg.devDependencies?.next || "unknown";
42
+ const deps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
43
+
44
+ // Count pages
45
+ let pageCount = 0;
46
+ let componentCount = 0;
47
+ let apiRouteCount = 0;
48
+
49
+ const countFiles = async (dir: string, ext: string[]): Promise<number> => {
50
+ let count = 0;
51
+ try {
52
+ const entries = await readdir(dir, { withFileTypes: true });
53
+ for (const entry of entries) {
54
+ if (entry.isDirectory() && !["node_modules", ".next", ".git"].includes(entry.name)) {
55
+ count += await countFiles(join(dir, entry.name), ext);
56
+ } else if (ext.some(e => entry.name.endsWith(e))) {
57
+ count++;
58
+ }
59
+ }
60
+ } catch { }
61
+ return count;
62
+ };
63
+
64
+ const appDir = join(PROJECT_ROOT, "src/app");
65
+ const pagesDir = join(PROJECT_ROOT, "pages");
66
+ const componentsDir = join(PROJECT_ROOT, "src/components");
67
+
68
+ if (existsSync(appDir)) pageCount = await countFiles(appDir, ["page.tsx", "page.ts", "page.jsx"]);
69
+ else if (existsSync(pagesDir)) pageCount = await countFiles(pagesDir, [".tsx", ".ts", ".jsx", ".js"]);
70
+ if (existsSync(componentsDir)) componentCount = await countFiles(componentsDir, [".tsx", ".ts"]);
71
+ apiRouteCount = await countFiles(join(PROJECT_ROOT, "src/app/api"), ["route.ts", "route.js"]);
72
+
73
+ return NextResponse.json({
74
+ name: pkg.name || "unknown",
75
+ nextVersion,
76
+ pageCount,
77
+ componentCount,
78
+ apiRouteCount,
79
+ deps: deps.slice(0, 20),
80
+ hasTailwind: deps.some(d => d.includes("tailwind")),
81
+ hasTypeScript: existsSync(join(PROJECT_ROOT, "tsconfig.json")),
82
+ hasTests: existsSync(join(PROJECT_ROOT, "jest.config.js")) || existsSync(join(PROJECT_ROOT, "jest.config.ts")),
83
+ });
84
+ }
85
+
86
+ // GET /api/agenauto/files?path=src/components&extensions=tsx,ts
87
+ async function getFiles(req: Request) {
88
+ const url = new URL(req.url);
89
+ const path = url.searchParams.get("path") || "/";
90
+ const extensions = url.searchParams.get("extensions")?.split(",") || [];
91
+ const fullPath = join(PROJECT_ROOT, path.replace(/^\//, ""));
92
+
93
+ try {
94
+ const entries = await readdir(fullPath, { withFileTypes: true });
95
+ const files = await Promise.all(
96
+ entries
97
+ .filter(e => {
98
+ if (["node_modules", ".next", ".git", "__pycache__"].includes(e.name)) return false;
99
+ if (extensions.length > 0 && !e.isDirectory()) {
100
+ return extensions.some(ext => e.name.endsWith(`.${ext}`));
101
+ }
102
+ return true;
103
+ })
104
+ .map(async (e) => {
105
+ let size = "";
106
+ if (!e.isDirectory()) {
107
+ try {
108
+ const s = await stat(join(fullPath, e.name));
109
+ size = `${Math.round(s.size / 1024)}KB`;
110
+ } catch { }
111
+ }
112
+ return {
113
+ name: e.name,
114
+ isDir: e.isDirectory(),
115
+ size,
116
+ };
117
+ })
118
+ );
119
+ return NextResponse.json({ files, path });
120
+ } catch (e) {
121
+ return NextResponse.json({ error: String(e) }, { status: 404 });
122
+ }
123
+ }
124
+
125
+ // GET /api/agenauto/file?path=src/app/page.tsx
126
+ async function getFile(req: Request) {
127
+ const url = new URL(req.url);
128
+ const path = url.searchParams.get("path") || "";
129
+ if (!path) return NextResponse.json({ error: "path required" }, { status: 400 });
130
+
131
+ const fullPath = join(PROJECT_ROOT, path.replace(/^\//, ""));
132
+ // Security: only allow text files
133
+ const ALLOWED_EXT = [".ts", ".tsx", ".js", ".jsx", ".css", ".json", ".md", ".env.example", ".yaml", ".yml", ".html", ".svg"];
134
+ if (!ALLOWED_EXT.some(ext => fullPath.endsWith(ext))) {
135
+ return NextResponse.json({ error: "File type not allowed" }, { status: 403 });
136
+ }
137
+
138
+ try {
139
+ const content = await readFile(fullPath, "utf-8");
140
+ return NextResponse.json({ path, content });
141
+ } catch (e) {
142
+ return NextResponse.json({ error: String(e) }, { status: 404 });
143
+ }
144
+ }
145
+
146
+ // PUT /api/agenauto/file body: { path, content, reason }
147
+ async function putFile(req: Request) {
148
+ const { path, content, reason } = await req.json();
149
+ if (!path || !content) return NextResponse.json({ error: "path and content required" }, { status: 400 });
150
+
151
+ const fullPath = join(PROJECT_ROOT, path.replace(/^\//, ""));
152
+ const ALLOWED_EXT = [".ts", ".tsx", ".js", ".jsx", ".css", ".json", ".md", ".html"];
153
+ if (!ALLOWED_EXT.some(ext => fullPath.endsWith(ext))) {
154
+ return NextResponse.json({ error: "File type not allowed" }, { status: 403 });
155
+ }
156
+ // Never allow writing outside project root
157
+ if (!fullPath.startsWith(PROJECT_ROOT)) {
158
+ return NextResponse.json({ error: "Path traversal not allowed" }, { status: 403 });
159
+ }
160
+
161
+ try {
162
+ await writeFile(fullPath, content, "utf-8");
163
+ console.log(`[AgenAuto] Updated ${path}: ${reason || "autonomous improvement"}`);
164
+ return NextResponse.json({ success: true, path });
165
+ } catch (e) {
166
+ return NextResponse.json({ error: String(e) }, { status: 500 });
167
+ }
168
+ }
169
+
170
+ // POST /api/agenauto/run body: { command }
171
+ async function runCommand(req: Request) {
172
+ const { command } = await req.json();
173
+ const ALLOWED_COMMANDS = [
174
+ "npm run lint", "npm run build", "npm test",
175
+ "npx tsc --noEmit", "npm run type-check",
176
+ ];
177
+ if (!ALLOWED_COMMANDS.includes(command)) {
178
+ return NextResponse.json({ error: "Command not allowed" }, { status: 403 });
179
+ }
180
+
181
+ try {
182
+ const stdout = execSync(command, { cwd: PROJECT_ROOT, timeout: 60000 }).toString();
183
+ return NextResponse.json({ stdout, stderr: "", exitCode: 0 });
184
+ } catch (e: any) {
185
+ return NextResponse.json({
186
+ stdout: e.stdout?.toString() || "",
187
+ stderr: e.stderr?.toString() || String(e),
188
+ exitCode: e.status || 1,
189
+ });
190
+ }
191
+ }
192
+
193
+ // Main route handler — dispatch by endpoint
194
+ export async function GET(req: Request) {
195
+ if (!checkAuth(req)) return unauthorized();
196
+ const url = new URL(req.url);
197
+ const segments = url.pathname.split("/api/agenauto/")[1];
198
+
199
+ if (segments === "site-info") return getSiteInfo();
200
+ if (segments === "files") return getFiles(req);
201
+ if (segments === "file") return getFile(req);
202
+
203
+ return NextResponse.json({ error: "Unknown endpoint" }, { status: 404 });
204
+ }
205
+
206
+ export async function PUT(req: Request) {
207
+ if (!checkAuth(req)) return unauthorized();
208
+ const url = new URL(req.url);
209
+ const segments = url.pathname.split("/api/agenauto/")[1];
210
+ if (segments === "file") return putFile(req);
211
+ return NextResponse.json({ error: "Unknown endpoint" }, { status: 404 });
212
+ }
213
+
214
+ export async function POST(req: Request) {
215
+ if (!checkAuth(req)) return unauthorized();
216
+ const url = new URL(req.url);
217
+ const segments = url.pathname.split("/api/agenauto/")[1];
218
+ if (segments === "run") return runCommand(req);
219
+ return NextResponse.json({ error: "Unknown endpoint" }, { status: 404 });
220
+ }
package/dist/index.js CHANGED
@@ -51,7 +51,22 @@ function AgenAutoProvider({ agentKey, apiUrl = "https://agenauto.lat", showBadge
51
51
  agentName: data.agent.name,
52
52
  model: data.agent.model
53
53
  });
54
- console.log(`AgenAuto: Connected \u2713 (Agent: ${data.agent.name})`);
54
+ console.log(`AgenAuto: Connected (Agent: ${data.agent.name})`);
55
+ fetch(`${apiUrl}/api/v1/register`, {
56
+ method: "POST",
57
+ headers: { "Content-Type": "application/json" },
58
+ body: JSON.stringify({
59
+ agentKey,
60
+ platform: "nextjs",
61
+ siteUrl: typeof window !== "undefined" ? window.location.origin : "",
62
+ version: "1.3.0",
63
+ extra: {
64
+ framework: "nextjs",
65
+ sdk: "agenauto-nextjs"
66
+ }
67
+ })
68
+ }).catch(() => {
69
+ });
55
70
  }
56
71
  }).catch(() => {
57
72
  console.warn("AgenAuto: Connection failed. Check your agent key.");
package/dist/index.mjs CHANGED
@@ -17,7 +17,22 @@ function AgenAutoProvider({ agentKey, apiUrl = "https://agenauto.lat", showBadge
17
17
  agentName: data.agent.name,
18
18
  model: data.agent.model
19
19
  });
20
- console.log(`AgenAuto: Connected \u2713 (Agent: ${data.agent.name})`);
20
+ console.log(`AgenAuto: Connected (Agent: ${data.agent.name})`);
21
+ fetch(`${apiUrl}/api/v1/register`, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/json" },
24
+ body: JSON.stringify({
25
+ agentKey,
26
+ platform: "nextjs",
27
+ siteUrl: typeof window !== "undefined" ? window.location.origin : "",
28
+ version: "1.3.0",
29
+ extra: {
30
+ framework: "nextjs",
31
+ sdk: "agenauto-nextjs"
32
+ }
33
+ })
34
+ }).catch(() => {
35
+ });
21
36
  }
22
37
  }).catch(() => {
23
38
  console.warn("AgenAuto: Connection failed. Check your agent key.");
package/package.json CHANGED
@@ -1,20 +1,34 @@
1
1
  {
2
2
  "name": "agenauto-nextjs",
3
- "version": "1.0.1",
4
- "description": "AgenAuto SDK for Next.js — connect your React app to your autonomous AI agent",
3
+ "version": "1.3.0",
4
+ "description": "AgenAuto SDK for Next.js — autonomous AI agent for your React/Next.js project",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./bridge": {
15
+ "import": "./bridge/route.ts"
16
+ }
17
+ },
8
18
  "files": [
9
- "dist"
19
+ "dist",
20
+ "bridge",
21
+ "README.md"
10
22
  ],
11
23
  "scripts": {
12
24
  "build": "tsup src/index.ts --format cjs,esm --dts",
13
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch"
25
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
26
+ "prepublishOnly": "npm run build"
14
27
  },
15
28
  "peerDependencies": {
16
29
  "react": ">=18.0.0",
17
- "react-dom": ">=18.0.0"
30
+ "react-dom": ">=18.0.0",
31
+ "next": ">=13.0.0"
18
32
  },
19
33
  "devDependencies": {
20
34
  "react": "^19.0.0",
@@ -26,15 +40,18 @@
26
40
  "agenauto",
27
41
  "ai",
28
42
  "agent",
43
+ "autonomous",
29
44
  "nextjs",
30
45
  "react",
31
46
  "seo",
32
- "optimization"
47
+ "optimization",
48
+ "wordpress"
33
49
  ],
34
50
  "author": "AgenAuto <hello@agenauto.lat>",
35
51
  "license": "MIT",
36
52
  "repository": {
37
53
  "type": "git",
38
54
  "url": "https://github.com/agenauto/nextjs-sdk"
39
- }
55
+ },
56
+ "homepage": "https://agenauto.lat"
40
57
  }