neural-loom 0.2.60 → 0.2.62
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +3 -0
- package/.next/build-manifest.json +3 -3
- package/.next/cache/.previewinfo +1 -1
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/diagnostics/route-bundle-stats.json +2 -2
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +18 -0
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/configs/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/configs/route/build-manifest.json +9 -0
- package/.next/server/app/api/configs/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/configs/route.js +6 -0
- package/.next/server/app/api/configs/route.js.map +5 -0
- package/.next/server/app/api/configs/route.js.nft.json +1 -0
- package/.next/server/app/api/configs/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/context/aider/route.js.nft.json +1 -1
- package/.next/server/app/api/context/claude/route.js.nft.json +1 -1
- package/.next/server/app/api/context/route.js.nft.json +1 -1
- package/.next/server/app/api/context/ssh/route.js.nft.json +1 -1
- package/.next/server/app/api/recents/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/inject/route.js +2 -2
- package/.next/server/app/api/sessions/inject/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/input/route.js +2 -2
- package/.next/server/app/api/sessions/input/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/launch/route.js +2 -2
- package/.next/server/app/api/sessions/launch/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/route.js +2 -2
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/scope/route.js +2 -2
- package/.next/server/app/api/sessions/scope/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/start/route.js +2 -2
- package/.next/server/app/api/sessions/start/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/stats/route.js +2 -2
- package/.next/server/app/api/sessions/stats/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/stop/route.js +2 -2
- package/.next/server/app/api/sessions/stop/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/upload-image/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/sessions/upload-image/route/build-manifest.json +9 -0
- package/.next/server/app/api/sessions/upload-image/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/sessions/upload-image/route.js +7 -0
- package/.next/server/app/api/sessions/upload-image/route.js.map +5 -0
- package/.next/server/app/api/sessions/upload-image/route.js.nft.json +1 -0
- package/.next/server/app/api/sessions/upload-image/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/sql/connections/route.js.nft.json +1 -1
- package/.next/server/app/api/sql/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/sql/query/route.js.nft.json +1 -1
- package/.next/server/app/api/sql/schema/route.js.nft.json +1 -1
- package/.next/server/app/api/telemetry/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/telemetry/route/build-manifest.json +9 -0
- package/.next/server/app/api/telemetry/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/telemetry/route.js +6 -0
- package/.next/server/app/api/telemetry/route.js.map +5 -0
- package/.next/server/app/api/telemetry/route.js.nft.json +1 -0
- package/.next/server/app/api/telemetry/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/page/react-loadable-manifest.json +5 -5
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +3 -0
- package/.next/server/chunks/[root-of-the-server]__0.ptwor._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0.ptwor._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__00-sqou._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__0thsozo._.js.map → [root-of-the-server]__00-sqou._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__00l5btc._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__00l5btc._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__01621nz._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__01621nz._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__06men8g._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__06men8g._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__08r0s-s._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__08r0s-s._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__097vtn1._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__0em6a~~._.js.map → [root-of-the-server]__097vtn1._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0_v2.a8._.js +15 -0
- package/.next/server/chunks/[root-of-the-server]__0_v2.a8._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0co.g5k._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0co.g5k._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0e03ite._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__10wwca8._.js.map → [root-of-the-server]__0e03ite._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0fxtx7z._.js +15 -0
- package/.next/server/chunks/[root-of-the-server]__0fxtx7z._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0h.~hv6._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__0s0is_9._.js.map → [root-of-the-server]__0h.~hv6._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0li1h1u._.js +33 -0
- package/.next/server/chunks/[root-of-the-server]__0li1h1u._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0s1axek._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__0i~01cv._.js.map → [root-of-the-server]__0s1axek._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tq0maq._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__0_o7_jj._.js.map → [root-of-the-server]__0tq0maq._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0viil6b._.js +15 -0
- package/.next/server/chunks/{[root-of-the-server]__07zx04e._.js.map → [root-of-the-server]__0viil6b._.js.map} +1 -1
- package/.next/server/chunks/_next-internal_server_app_api_configs_route_actions_087k_4j.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_configs_route_actions_087k_4j.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_sessions_upload-image_route_actions_09tfn3a.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_sessions_upload-image_route_actions_09tfn3a.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_telemetry_route_actions_0.yo5qr.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_telemetry_route_actions_0.yo5qr.js.map +1 -0
- package/.next/server/chunks/ssr/_0t7oqy6._.js +3 -3
- package/.next/server/chunks/ssr/_0t7oqy6._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/0qu1p~ny_bvko.css +1 -0
- package/.next/static/chunks/0sr3d9iqny2rf.js +4 -0
- package/.next/static/chunks/0xhaghhxllgzs.js +1 -0
- package/.next/static/chunks/{0y~7jjqbr14.5.js → 15_baizhaiq8c.js} +10 -7
- package/.next/static/chunks/15sigqif_v.mu.js +1 -0
- package/.next/static/chunks/16rky3981raz5.js +11 -0
- package/.next/trace +1 -1
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +4 -1
- package/.next/types/validator.ts +27 -0
- package/bin/cli.js +4 -4
- package/bin/fix-pwa-ubuntu.sh +50 -0
- package/package.json +1 -1
- package/src/app/api/configs/route.ts +40 -0
- package/src/app/api/sessions/launch/route.ts +3 -3
- package/src/app/api/sessions/route.ts +2 -2
- package/src/app/api/sessions/start/route.ts +2 -2
- package/src/app/api/sessions/upload-image/route.ts +57 -0
- package/src/app/api/sql/connections/route.ts +9 -6
- package/src/app/api/sql/mcp/route.ts +3 -2
- package/src/app/api/sql/query/route.ts +3 -2
- package/src/app/api/sql/schema/route.ts +3 -2
- package/src/app/api/telemetry/route.ts +18 -0
- package/src/app/components/AiderWizard.tsx +46 -2
- package/src/app/components/ClaudeWizard.tsx +30 -0
- package/src/app/components/DbExplorer.tsx +37 -4
- package/src/app/components/IdeLayout.tsx +577 -72
- package/src/app/components/TerminalConsole.tsx +54 -0
- package/src/app/page.module.css +12 -5
- package/src/app/page.tsx +534 -401
- package/src/lib/agents/AgentRunner.ts +98 -12
- package/src/lib/agents/AiderRunner.ts +4 -18
- package/src/lib/agents/ClaudeRunner.ts +16 -26
- package/src/lib/agents/DockerRunner.ts +16 -26
- package/src/lib/agents/MockRunner.ts +4 -16
- package/src/lib/agents/SSHRunner.ts +16 -26
- package/src/lib/agents/SessionConfig.ts +79 -0
- package/src/lib/agents/SessionManager.ts +16 -16
- package/src/lib/agents/SessionPersister.ts +13 -9
- package/src/lib/agents/ShellRunner.ts +14 -21
- package/src/lib/agents/WebSocketServer.ts +2 -2
- package/.next/server/chunks/[root-of-the-server]__01.zh3b._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__01.zh3b._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__07zx04e._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__0_o7_jj._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__0d0pykb._.js +0 -33
- package/.next/server/chunks/[root-of-the-server]__0d0pykb._.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__0em6a~~._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__0i~01cv._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__0s0is_9._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__0thsozo._.js +0 -15
- package/.next/server/chunks/[root-of-the-server]__10wwca8._.js +0 -15
- package/.next/static/chunks/076_b43_kienv.js +0 -1
- package/.next/static/chunks/07r_au7dcyu8l.js +0 -11
- package/.next/static/chunks/0hoyc~vbuqe0t.css +0 -1
- package/.next/static/chunks/0k2co3uj4w81_.js +0 -1
- package/.next/static/chunks/0sqeixl35qoac.js +0 -1
- /package/.next/static/{PdRX_M_W5hqhNmHxYt-oH → K1_el6-FnhIqHfvSMHXCm}/_buildManifest.js +0 -0
- /package/.next/static/{PdRX_M_W5hqhNmHxYt-oH → K1_el6-FnhIqHfvSMHXCm}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{PdRX_M_W5hqhNmHxYt-oH → K1_el6-FnhIqHfvSMHXCm}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { SessionManager } from "@/lib/agents/SessionManager";
|
|
5
|
+
|
|
6
|
+
export async function POST(request: Request) {
|
|
7
|
+
try {
|
|
8
|
+
const { sessionId, base64Data, fileName } = await request.json();
|
|
9
|
+
|
|
10
|
+
if (!sessionId) {
|
|
11
|
+
return NextResponse.json({ error: "Missing parameter 'sessionId'" }, { status: 400 });
|
|
12
|
+
}
|
|
13
|
+
if (!base64Data) {
|
|
14
|
+
return NextResponse.json({ error: "Missing parameter 'base64Data'" }, { status: 400 });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const manager = SessionManager.getInstance();
|
|
18
|
+
const session = manager.getSession(sessionId);
|
|
19
|
+
if (!session) {
|
|
20
|
+
return NextResponse.json({ error: "Session not found" }, { status: 404 });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const root = session.workspaceRoot || process.env.ORIGINAL_CWD || process.cwd();
|
|
24
|
+
|
|
25
|
+
// Create pasted-images folder inside workspace root under .ai/neural-loom
|
|
26
|
+
const destDir = path.join(root, ".ai", "neural-loom", "pasted-images");
|
|
27
|
+
if (!fs.existsSync(destDir)) {
|
|
28
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Parse base64 data URL
|
|
32
|
+
let buffer: Buffer;
|
|
33
|
+
let ext = "png";
|
|
34
|
+
const matches = base64Data.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
|
|
35
|
+
|
|
36
|
+
if (matches && matches.length === 3) {
|
|
37
|
+
buffer = Buffer.from(matches[2], 'base64');
|
|
38
|
+
const mimeType = matches[1];
|
|
39
|
+
ext = mimeType.split("/")[1] || "png";
|
|
40
|
+
} else {
|
|
41
|
+
buffer = Buffer.from(base64Data, 'base64');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const name = fileName || `image_${Date.now()}.${ext}`;
|
|
45
|
+
const destPath = path.join(destDir, name);
|
|
46
|
+
|
|
47
|
+
fs.writeFileSync(destPath, buffer);
|
|
48
|
+
|
|
49
|
+
// Return relative path from workspace root
|
|
50
|
+
const relativePath = `./.ai/neural-loom/pasted-images/${name}`;
|
|
51
|
+
|
|
52
|
+
return NextResponse.json({ success: true, path: relativePath });
|
|
53
|
+
} catch (error) {
|
|
54
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
55
|
+
return NextResponse.json({ error: msg }, { status: 500 });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -7,8 +7,9 @@ export async function GET(request: Request) {
|
|
|
7
7
|
const root = searchParams.get("root") || undefined;
|
|
8
8
|
const data = await ConnectionManager.getProfiles(root);
|
|
9
9
|
return NextResponse.json({ success: true, ...data });
|
|
10
|
-
} catch (error
|
|
11
|
-
|
|
10
|
+
} catch (error) {
|
|
11
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
12
|
+
return NextResponse.json({ error: msg }, { status: 500 });
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -48,13 +49,15 @@ export async function POST(request: Request) {
|
|
|
48
49
|
await adapter.listTables(); // Quick verify
|
|
49
50
|
await adapter.disconnect();
|
|
50
51
|
return NextResponse.json({ success: true, message: "Connection test successful!" });
|
|
51
|
-
} catch (err
|
|
52
|
-
|
|
52
|
+
} catch (err) {
|
|
53
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
54
|
+
return NextResponse.json({ success: false, error: msg });
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
return NextResponse.json({ error: "Invalid action" }, { status: 400 });
|
|
57
|
-
} catch (error
|
|
58
|
-
|
|
59
|
+
} catch (error) {
|
|
60
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
61
|
+
return NextResponse.json({ error: msg }, { status: 500 });
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -14,13 +14,14 @@ export async function POST(request: Request) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
return NextResponse.json(response);
|
|
17
|
-
} catch (error
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
18
19
|
return NextResponse.json({
|
|
19
20
|
jsonrpc: "2.0",
|
|
20
21
|
id: null,
|
|
21
22
|
error: {
|
|
22
23
|
code: -32603,
|
|
23
|
-
message: "Internal server error: " +
|
|
24
|
+
message: "Internal server error: " + msg
|
|
24
25
|
}
|
|
25
26
|
}, { status: 500 });
|
|
26
27
|
}
|
|
@@ -50,7 +50,8 @@ export async function POST(request: Request) {
|
|
|
50
50
|
affectedRows: result.affectedRows,
|
|
51
51
|
durationMs
|
|
52
52
|
});
|
|
53
|
-
} catch (error
|
|
54
|
-
|
|
53
|
+
} catch (error) {
|
|
54
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
55
|
+
return NextResponse.json({ error: msg }, { status: 500 });
|
|
55
56
|
}
|
|
56
57
|
}
|
|
@@ -36,7 +36,8 @@ export async function GET(request: Request) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
return NextResponse.json({ error: "Invalid action. Must be 'list_tables', 'describe_table', or 'summary'" }, { status: 400 });
|
|
39
|
-
} catch (error
|
|
40
|
-
|
|
39
|
+
} catch (error) {
|
|
40
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
41
|
+
return NextResponse.json({ error: msg }, { status: 500 });
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
export async function GET() {
|
|
6
|
+
try {
|
|
7
|
+
const historyFile = path.join(process.cwd(), ".ai", "neural-loom", "token-history.json");
|
|
8
|
+
if (!fs.existsSync(historyFile)) {
|
|
9
|
+
return NextResponse.json({ success: true, history: [] });
|
|
10
|
+
}
|
|
11
|
+
const raw = fs.readFileSync(historyFile, "utf8");
|
|
12
|
+
const history = JSON.parse(raw) || [];
|
|
13
|
+
return NextResponse.json({ success: true, history });
|
|
14
|
+
} catch (error) {
|
|
15
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
16
|
+
return NextResponse.json({ error: errorMessage }, { status: 500 });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -4,6 +4,7 @@ import { useEffect, useState } from "react";
|
|
|
4
4
|
import DirectoryBrowserModal from "./DirectoryBrowserModal";
|
|
5
5
|
|
|
6
6
|
interface AiderConfig {
|
|
7
|
+
name: string;
|
|
7
8
|
openaiApiKey: string;
|
|
8
9
|
anthropicApiKey: string;
|
|
9
10
|
geminiApiKey: string;
|
|
@@ -16,12 +17,13 @@ interface AiderConfig {
|
|
|
16
17
|
|
|
17
18
|
interface AiderWizardProps {
|
|
18
19
|
onClose: () => void;
|
|
19
|
-
onConfirmLaunch: () => void;
|
|
20
|
+
onConfirmLaunch: (name: string, workspaceRoot: string, scopedDirs: string[]) => void;
|
|
20
21
|
isDocker: boolean;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: AiderWizardProps) {
|
|
24
25
|
const [config, setConfig] = useState<AiderConfig>({
|
|
26
|
+
name: isDocker ? "Aider Docker" : "Aider Local",
|
|
25
27
|
openaiApiKey: "",
|
|
26
28
|
anthropicApiKey: "",
|
|
27
29
|
geminiApiKey: "",
|
|
@@ -33,6 +35,7 @@ export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: Aide
|
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
const [newScopePath, setNewScopePath] = useState("");
|
|
38
|
+
const [saveAsTemplate, setSaveAsTemplate] = useState(false);
|
|
36
39
|
const [isLoading, setIsLoading] = useState(true);
|
|
37
40
|
const [isSaving, setIsSaving] = useState(false);
|
|
38
41
|
const [errorMessage, setErrorMessage] = useState("");
|
|
@@ -49,6 +52,7 @@ export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: Aide
|
|
|
49
52
|
const data = await res.json();
|
|
50
53
|
if (data.success && data.config) {
|
|
51
54
|
setConfig({
|
|
55
|
+
name: data.config.name || (isDocker ? "Aider Docker" : "Aider Local"),
|
|
52
56
|
openaiApiKey: data.config.openaiApiKey || "",
|
|
53
57
|
anthropicApiKey: data.config.anthropicApiKey || "",
|
|
54
58
|
geminiApiKey: data.config.geminiApiKey || "",
|
|
@@ -90,8 +94,24 @@ export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: Aide
|
|
|
90
94
|
});
|
|
91
95
|
|
|
92
96
|
if (res.ok) {
|
|
97
|
+
if (saveAsTemplate) {
|
|
98
|
+
await fetch("/api/configs", {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: { "Content-Type": "application/json" },
|
|
101
|
+
body: JSON.stringify({
|
|
102
|
+
action: "save",
|
|
103
|
+
config: {
|
|
104
|
+
name: config.name,
|
|
105
|
+
type: isDocker ? "aider-docker" : "aider",
|
|
106
|
+
workspaceRoot: config.workspaceRoot,
|
|
107
|
+
scopedDirs: config.scopedDirs,
|
|
108
|
+
extraFlags: config.extraFlags
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
}
|
|
93
113
|
setIsSaving(false);
|
|
94
|
-
onConfirmLaunch();
|
|
114
|
+
onConfirmLaunch(config.name, config.workspaceRoot, config.scopedDirs);
|
|
95
115
|
} else {
|
|
96
116
|
const data = await res.json();
|
|
97
117
|
setErrorMessage(data.error || "Failed to save settings.");
|
|
@@ -133,6 +153,17 @@ export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: Aide
|
|
|
133
153
|
Configure model and environment variables for the Aider session. API keys are saved locally in `.ai/neural-loom/aider.json` and are ignored by git.
|
|
134
154
|
</p>
|
|
135
155
|
|
|
156
|
+
<div style={formGroupStyle}>
|
|
157
|
+
<label style={labelStyle}>Session Display Name</label>
|
|
158
|
+
<input
|
|
159
|
+
type="text"
|
|
160
|
+
value={config.name}
|
|
161
|
+
onChange={(e) => setConfig({ ...config, name: e.target.value })}
|
|
162
|
+
placeholder={isDocker ? "Aider Docker" : "Aider Local"}
|
|
163
|
+
style={inputStyle}
|
|
164
|
+
/>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
136
167
|
<div style={formGroupStyle}>
|
|
137
168
|
<label style={labelStyle}>Anthropic API Key</label>
|
|
138
169
|
<input
|
|
@@ -355,6 +386,19 @@ export default function AiderWizard({ onClose, onConfirmLaunch, isDocker }: Aide
|
|
|
355
386
|
</label>
|
|
356
387
|
</div>
|
|
357
388
|
|
|
389
|
+
<div style={{ ...formGroupStyle, flexDirection: "row", alignItems: "center", gap: "0.5rem", marginTop: "1rem", marginBottom: "0.5rem" }}>
|
|
390
|
+
<input
|
|
391
|
+
type="checkbox"
|
|
392
|
+
id="saveAsTemplate"
|
|
393
|
+
checked={saveAsTemplate}
|
|
394
|
+
onChange={(e) => setSaveAsTemplate(e.target.checked)}
|
|
395
|
+
style={{ width: "16px", height: "16px", cursor: "pointer", accentColor: "var(--accent)" }}
|
|
396
|
+
/>
|
|
397
|
+
<label htmlFor="saveAsTemplate" style={{ fontSize: "0.8rem", color: "var(--foreground)", cursor: "pointer", userSelect: "none" }}>
|
|
398
|
+
Save configuration template
|
|
399
|
+
</label>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
358
402
|
{errorMessage && (
|
|
359
403
|
<div style={errorBoxStyle}>
|
|
360
404
|
✗ {errorMessage}
|
|
@@ -25,6 +25,7 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
const [newScopePath, setNewScopePath] = useState("");
|
|
28
|
+
const [saveAsTemplate, setSaveAsTemplate] = useState(false);
|
|
28
29
|
const [isLoading, setIsLoading] = useState(true);
|
|
29
30
|
const [isSaving, setIsSaving] = useState(false);
|
|
30
31
|
const [errorMessage, setErrorMessage] = useState("");
|
|
@@ -78,6 +79,22 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
|
|
|
78
79
|
});
|
|
79
80
|
|
|
80
81
|
if (res.ok) {
|
|
82
|
+
if (saveAsTemplate) {
|
|
83
|
+
await fetch("/api/configs", {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: { "Content-Type": "application/json" },
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
action: "save",
|
|
88
|
+
config: {
|
|
89
|
+
name: config.name,
|
|
90
|
+
type: isDocker ? "claude-docker" : "claude",
|
|
91
|
+
workspaceRoot: config.workspaceRoot,
|
|
92
|
+
scopedDirs: config.scopedDirs,
|
|
93
|
+
extraFlags: config.extraFlags
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
});
|
|
97
|
+
}
|
|
81
98
|
setIsSaving(false);
|
|
82
99
|
onConfirmLaunch(config.name, config.workspaceRoot, config.scopedDirs);
|
|
83
100
|
} else {
|
|
@@ -289,6 +306,19 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
|
|
|
289
306
|
)}
|
|
290
307
|
</div>
|
|
291
308
|
|
|
309
|
+
<div style={{ ...formGroupStyle, flexDirection: "row", alignItems: "center", gap: "0.5rem", marginTop: "1rem", marginBottom: "0.5rem" }}>
|
|
310
|
+
<input
|
|
311
|
+
type="checkbox"
|
|
312
|
+
id="saveAsTemplate"
|
|
313
|
+
checked={saveAsTemplate}
|
|
314
|
+
onChange={(e) => setSaveAsTemplate(e.target.checked)}
|
|
315
|
+
style={{ width: "16px", height: "16px", cursor: "pointer", accentColor: "var(--accent)" }}
|
|
316
|
+
/>
|
|
317
|
+
<label htmlFor="saveAsTemplate" style={{ fontSize: "0.8rem", color: "var(--foreground)", cursor: "pointer", userSelect: "none" }}>
|
|
318
|
+
Save configuration template
|
|
319
|
+
</label>
|
|
320
|
+
</div>
|
|
321
|
+
|
|
292
322
|
{errorMessage && (
|
|
293
323
|
<div style={errorBoxStyle}>
|
|
294
324
|
✗ {errorMessage}
|
|
@@ -46,6 +46,7 @@ export default function DbExplorer({ workspaceRoot }: DbExplorerProps) {
|
|
|
46
46
|
});
|
|
47
47
|
const [activeId, setActiveId] = useState<string | null>(null);
|
|
48
48
|
const [isActiveGlobal, setIsActiveGlobal] = useState<boolean>(true);
|
|
49
|
+
const [sidebarOpen, setSidebarOpen] = useState(true);
|
|
49
50
|
|
|
50
51
|
// Schema state
|
|
51
52
|
const [tables, setTables] = useState<TableSchema[]>([]);
|
|
@@ -523,8 +524,18 @@ export default function DbExplorer({ workspaceRoot }: DbExplorerProps) {
|
|
|
523
524
|
return (
|
|
524
525
|
<div style={styles.container}>
|
|
525
526
|
{/* Sidebar: Connections & Schemas */}
|
|
526
|
-
<div
|
|
527
|
-
{
|
|
527
|
+
<div
|
|
528
|
+
style={{
|
|
529
|
+
...styles.sidebar,
|
|
530
|
+
width: sidebarOpen ? "220px" : "0px",
|
|
531
|
+
borderRight: sidebarOpen ? "1px solid var(--border)" : "none",
|
|
532
|
+
overflow: "hidden",
|
|
533
|
+
transition: "all 0.25s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
534
|
+
}}
|
|
535
|
+
>
|
|
536
|
+
{sidebarOpen && (
|
|
537
|
+
<div style={{ display: "flex", flexDirection: "column", height: "100%", minWidth: "220px", minHeight: 0 }}>
|
|
538
|
+
{/* Connection Profiles section */}
|
|
528
539
|
<div style={styles.section}>
|
|
529
540
|
<div style={styles.sectionHeader}>
|
|
530
541
|
<span style={styles.sectionTitle}>Connections</span>
|
|
@@ -663,13 +674,35 @@ export default function DbExplorer({ workspaceRoot }: DbExplorerProps) {
|
|
|
663
674
|
))}
|
|
664
675
|
</div>
|
|
665
676
|
</div>
|
|
677
|
+
</div>
|
|
678
|
+
)}
|
|
666
679
|
</div>
|
|
667
680
|
|
|
668
681
|
{/* Main Panel: Query Editor & Data Results */}
|
|
669
682
|
<div style={styles.mainContent}>
|
|
670
683
|
{/* Connection status header */}
|
|
671
684
|
<div style={styles.statusBar}>
|
|
672
|
-
<div style={{ display: "flex", alignItems: "center", gap: "0.
|
|
685
|
+
<div style={{ display: "flex", alignItems: "center", gap: "0.75rem" }}>
|
|
686
|
+
<button
|
|
687
|
+
type="button"
|
|
688
|
+
onClick={() => setSidebarOpen(!sidebarOpen)}
|
|
689
|
+
style={{
|
|
690
|
+
background: "rgba(255, 255, 255, 0.05)",
|
|
691
|
+
border: "1px solid var(--border)",
|
|
692
|
+
borderRadius: "6px",
|
|
693
|
+
color: "var(--muted)",
|
|
694
|
+
cursor: "pointer",
|
|
695
|
+
padding: "0.25rem 0.5rem",
|
|
696
|
+
fontSize: "0.75rem",
|
|
697
|
+
display: "flex",
|
|
698
|
+
alignItems: "center",
|
|
699
|
+
justifyContent: "center",
|
|
700
|
+
transition: "all 0.15s ease",
|
|
701
|
+
}}
|
|
702
|
+
title={sidebarOpen ? "Collapse Connections List" : "Expand Connections List"}
|
|
703
|
+
>
|
|
704
|
+
{sidebarOpen ? "◀ Collapse" : "📂 Schema Connections"}
|
|
705
|
+
</button>
|
|
673
706
|
<span style={styles.statusLabel}>Active Connection:</span>
|
|
674
707
|
{activeProfile ? (
|
|
675
708
|
<span style={styles.statusValue}>
|
|
@@ -1080,7 +1113,7 @@ const styles: { [key: string]: React.CSSProperties } = {
|
|
|
1080
1113
|
minHeight: 0,
|
|
1081
1114
|
},
|
|
1082
1115
|
sidebar: {
|
|
1083
|
-
width: "
|
|
1116
|
+
width: "220px",
|
|
1084
1117
|
borderRight: "1px solid var(--border)",
|
|
1085
1118
|
display: "flex",
|
|
1086
1119
|
flexDirection: "column",
|