neural-loom 0.1.2 → 0.2.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.
Files changed (54) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/cache/.previewinfo +1 -1
  4. package/.next/cache/.rscinfo +1 -1
  5. package/.next/cache/.tsbuildinfo +1 -1
  6. package/.next/diagnostics/route-bundle-stats.json +1 -1
  7. package/.next/fallback-build-manifest.json +3 -3
  8. package/.next/prerender-manifest.json +3 -3
  9. package/.next/server/app/_global-error.html +1 -1
  10. package/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  24. package/.next/server/app/index.html +1 -1
  25. package/.next/server/app/index.rsc +2 -2
  26. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  27. package/.next/server/app/index.segments/_full.segment.rsc +2 -2
  28. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  29. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  30. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  31. package/.next/server/app/page/react-loadable-manifest.json +2 -2
  32. package/.next/server/app/page_client-reference-manifest.js +1 -1
  33. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ev3h.z.js +1 -1
  34. package/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ev3h.z.js.map +1 -1
  35. package/.next/server/middleware-build-manifest.js +3 -3
  36. package/.next/server/pages/404.html +1 -1
  37. package/.next/server/pages/500.html +1 -1
  38. package/.next/server/server-reference-manifest.js +1 -1
  39. package/.next/server/server-reference-manifest.json +1 -1
  40. package/.next/static/chunks/03wk6d_hkj.x2.js +1 -0
  41. package/.next/static/chunks/095uz52in_39t.js +1 -0
  42. package/.next/static/chunks/{0f4at4_v-tkgj.js → 0di.tbc4b33wc.js} +1 -1
  43. package/.next/trace +1 -1
  44. package/.next/trace-build +1 -1
  45. package/package.json +1 -1
  46. package/src/app/api/files/route.ts +42 -0
  47. package/src/app/components/AiderWizard.tsx +55 -7
  48. package/src/app/components/ClaudeWizard.tsx +55 -7
  49. package/src/app/components/DirectoryBrowserModal.tsx +362 -0
  50. package/.next/static/chunks/0ewdhgxsa_h.q.js +0 -1
  51. package/.next/static/chunks/0mej.ad_ddvf1.js +0 -1
  52. /package/.next/static/{LKAGJKkoLEWqiDjSp26mp → 7dOnbX1c746E1bCz_44Q2}/_buildManifest.js +0 -0
  53. /package/.next/static/{LKAGJKkoLEWqiDjSp26mp → 7dOnbX1c746E1bCz_44Q2}/_clientMiddlewareManifest.js +0 -0
  54. /package/.next/static/{LKAGJKkoLEWqiDjSp26mp → 7dOnbX1c746E1bCz_44Q2}/_ssgManifest.js +0 -0
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import { useEffect, useState } from "react";
4
+ import DirectoryBrowserModal from "./DirectoryBrowserModal";
4
5
 
5
6
  interface ClaudeConfig {
6
7
  name: string;
@@ -25,6 +26,8 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
25
26
  const [isLoading, setIsLoading] = useState(true);
26
27
  const [isSaving, setIsSaving] = useState(false);
27
28
  const [errorMessage, setErrorMessage] = useState("");
29
+ const [isBrowsingWorkspace, setIsBrowsingWorkspace] = useState(false);
30
+ const [isBrowsingScope, setIsBrowsingScope] = useState(false);
28
31
 
29
32
  // Load config on mount
30
33
  useEffect(() => {
@@ -119,13 +122,22 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
119
122
 
120
123
  <div style={formGroupStyle}>
121
124
  <label style={labelStyle}>Workspace Directory (Root)</label>
122
- <input
123
- type="text"
124
- value={config.workspaceRoot}
125
- onChange={(e) => setConfig({ ...config, workspaceRoot: e.target.value })}
126
- placeholder="e.g. C:\Users\Dave\OneDrive\Projects\JS\wingman"
127
- style={inputStyle}
128
- />
125
+ <div style={{ display: "flex", gap: "0.5rem" }}>
126
+ <input
127
+ type="text"
128
+ value={config.workspaceRoot}
129
+ onChange={(e) => setConfig({ ...config, workspaceRoot: e.target.value })}
130
+ placeholder="e.g. C:\Users\Dave\OneDrive\Projects\JS\wingman"
131
+ style={{ ...inputStyle, flex: 1 }}
132
+ />
133
+ <button
134
+ type="button"
135
+ onClick={() => setIsBrowsingWorkspace(true)}
136
+ style={browseButtonStyle}
137
+ >
138
+ Browse...
139
+ </button>
140
+ </div>
129
141
  <span style={{ fontSize: "0.7rem", color: "var(--muted)", marginTop: "0.25rem" }}>
130
142
  The active folder Claude Code will run in. Leave blank to run in the current orchestrator directory.
131
143
  </span>
@@ -160,6 +172,13 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
160
172
  placeholder="e.g. C:\Users\Dave\OneDrive\Projects\JS\other-repo"
161
173
  style={{ ...inputStyle, flex: 1 }}
162
174
  />
175
+ <button
176
+ type="button"
177
+ onClick={() => setIsBrowsingScope(true)}
178
+ style={browseButtonStyle}
179
+ >
180
+ Browse...
181
+ </button>
163
182
  <button
164
183
  type="button"
165
184
  onClick={() => {
@@ -207,6 +226,23 @@ export default function ClaudeWizard({ onClose, onConfirmLaunch, isDocker }: Cla
207
226
  {isSaving ? "Saving..." : "Launch Session"}
208
227
  </button>
209
228
  </div>
229
+ {isBrowsingWorkspace && (
230
+ <DirectoryBrowserModal
231
+ title="Select Workspace Root"
232
+ initialPath={config.workspaceRoot}
233
+ onClose={() => setIsBrowsingWorkspace(false)}
234
+ onSelect={(selectedPath) => setConfig({ ...config, workspaceRoot: selectedPath })}
235
+ />
236
+ )}
237
+
238
+ {isBrowsingScope && (
239
+ <DirectoryBrowserModal
240
+ title="Add Scoped Directory"
241
+ initialPath={newScopePath}
242
+ onClose={() => setIsBrowsingScope(false)}
243
+ onSelect={(selectedPath) => setNewScopePath(selectedPath)}
244
+ />
245
+ )}
210
246
  </div>
211
247
  </div>
212
248
  );
@@ -333,3 +369,15 @@ const secondaryButtonStyle: React.CSSProperties = {
333
369
  fontWeight: 600,
334
370
  cursor: "pointer",
335
371
  };
372
+
373
+ const browseButtonStyle: React.CSSProperties = {
374
+ padding: "0.35rem 0.75rem",
375
+ borderRadius: "6px",
376
+ border: "1px solid var(--border)",
377
+ backgroundColor: "rgba(255, 255, 255, 0.05)",
378
+ color: "var(--foreground)",
379
+ fontSize: "0.75rem",
380
+ fontWeight: 600,
381
+ cursor: "pointer",
382
+ transition: "all 0.15s ease",
383
+ };
@@ -0,0 +1,362 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+
5
+ interface DirectoryItem {
6
+ name: string;
7
+ path: string;
8
+ }
9
+
10
+ interface DirectoryBrowserModalProps {
11
+ title: string;
12
+ initialPath: string;
13
+ onClose: () => void;
14
+ onSelect: (selectedPath: string) => void;
15
+ }
16
+
17
+ export default function DirectoryBrowserModal({
18
+ title,
19
+ initialPath,
20
+ onClose,
21
+ onSelect,
22
+ }: DirectoryBrowserModalProps) {
23
+ const [currentPath, setCurrentPath] = useState(initialPath || "");
24
+ const [parentPath, setParentPath] = useState<string | null>(null);
25
+ const [directories, setDirectories] = useState<DirectoryItem[]>([]);
26
+ const [highlightedPath, setHighlightedPath] = useState<string | null>(null);
27
+ const [typedPath, setTypedPath] = useState("");
28
+ const [isLoading, setIsLoading] = useState(false);
29
+ const [error, setError] = useState("");
30
+
31
+ const fetchDirectories = async (pathTarget: string) => {
32
+ setIsLoading(true);
33
+ setError("");
34
+ try {
35
+ const url = `/api/files?action=browse_dirs&path=${encodeURIComponent(pathTarget)}`;
36
+ const res = await fetch(url);
37
+ const data = await res.json();
38
+ if (res.ok && data.success) {
39
+ setCurrentPath(data.currentPath);
40
+ setTypedPath(data.currentPath);
41
+ setParentPath(data.parentPath);
42
+ setDirectories(data.directories);
43
+ setHighlightedPath(null); // Reset highlight when entering a new folder
44
+ } else {
45
+ setError(data.error || "Failed to load directory content.");
46
+ }
47
+ } catch (err) {
48
+ console.error("Error browsing directories:", err);
49
+ setError("Failed to fetch directory contents.");
50
+ } finally {
51
+ setIsLoading(false);
52
+ }
53
+ };
54
+
55
+ // Load initial path on mount
56
+ useEffect(() => {
57
+ // eslint-disable-next-line react-hooks/set-state-in-effect
58
+ fetchDirectories(initialPath);
59
+ }, [initialPath]);
60
+
61
+ const handleNavigate = (pathTarget: string) => {
62
+ fetchDirectories(pathTarget);
63
+ };
64
+
65
+ const handleGoClick = () => {
66
+ if (typedPath.trim()) {
67
+ fetchDirectories(typedPath.trim());
68
+ }
69
+ };
70
+
71
+ const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
72
+ if (e.key === "Enter") {
73
+ handleGoClick();
74
+ }
75
+ };
76
+
77
+ const handleSelectClick = () => {
78
+ const finalSelection = highlightedPath || currentPath;
79
+ onSelect(finalSelection);
80
+ onClose();
81
+ };
82
+
83
+ return (
84
+ <div style={modalOverlayStyle}>
85
+ <div style={modalContainerStyle}>
86
+ {/* Header */}
87
+ <div style={headerStyle}>
88
+ <h3 style={{ fontSize: "1rem", fontWeight: 700, margin: 0, color: "var(--foreground)" }}>
89
+ 📁 {title}
90
+ </h3>
91
+ <button onClick={onClose} style={closeButtonStyle} aria-label="Close browser">✖</button>
92
+ </div>
93
+
94
+ {/* Path Bar */}
95
+ <div style={pathBarContainerStyle}>
96
+ <input
97
+ type="text"
98
+ value={typedPath}
99
+ onChange={(e) => setTypedPath(e.target.value)}
100
+ onKeyDown={handleKeyPress}
101
+ style={pathInputStyle}
102
+ placeholder="Absolute folder path..."
103
+ />
104
+ <button onClick={handleGoClick} style={goButtonStyle} disabled={isLoading}>
105
+ Go
106
+ </button>
107
+ </div>
108
+
109
+ {/* Directory List Container */}
110
+ <div style={listContainerStyle}>
111
+ {isLoading ? (
112
+ <div style={statusMessageStyle}>Loading directories...</div>
113
+ ) : error ? (
114
+ <div style={{ ...statusMessageStyle, color: "var(--danger)" }}>
115
+ {error}
116
+ <button
117
+ onClick={() => fetchDirectories(currentPath || ".")}
118
+ style={{ ...goButtonStyle, display: "block", margin: "0.75rem auto 0" }}
119
+ >
120
+ Retry
121
+ </button>
122
+ </div>
123
+ ) : (
124
+ <div style={listStyle}>
125
+ {/* Up directory item */}
126
+ {parentPath && (
127
+ <div
128
+ onClick={() => handleNavigate(parentPath)}
129
+ onDoubleClick={() => handleNavigate(parentPath)}
130
+ style={listItemStyle}
131
+ title="Go up to parent directory"
132
+ >
133
+ <span style={{ fontSize: "1.1rem" }}>⬆️</span>
134
+ <span style={{ fontWeight: 600 }}>.. (Up)</span>
135
+ </div>
136
+ )}
137
+
138
+ {/* Child directories */}
139
+ {directories.length === 0 ? (
140
+ <div style={{ ...statusMessageStyle, color: "var(--muted)" }}>
141
+ No subdirectories found
142
+ </div>
143
+ ) : (
144
+ directories.map((dir) => {
145
+ const isHighlighted = highlightedPath === dir.path;
146
+ return (
147
+ <div
148
+ key={dir.path}
149
+ onClick={() => setHighlightedPath(dir.path)}
150
+ onDoubleClick={() => handleNavigate(dir.path)}
151
+ style={{
152
+ ...listItemStyle,
153
+ backgroundColor: isHighlighted ? "rgba(109, 40, 217, 0.25)" : "transparent",
154
+ borderColor: isHighlighted ? "var(--border-focus)" : "transparent",
155
+ }}
156
+ title="Single click to highlight, double click to enter"
157
+ >
158
+ <span style={{ fontSize: "1.1rem" }}>📁</span>
159
+ <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
160
+ {dir.name}
161
+ </span>
162
+ {isHighlighted && (
163
+ <button
164
+ type="button"
165
+ onClick={(e) => {
166
+ e.stopPropagation();
167
+ handleNavigate(dir.path);
168
+ }}
169
+ style={enterFolderButtonStyle}
170
+ >
171
+ Enter ➜
172
+ </button>
173
+ )}
174
+ </div>
175
+ );
176
+ })
177
+ )}
178
+ </div>
179
+ )}
180
+ </div>
181
+
182
+ {/* Footer */}
183
+ <div style={footerStyle}>
184
+ <span style={selectionPreviewStyle}>
185
+ Selection: <span style={{ color: "var(--foreground)", fontFamily: "var(--font-mono), monospace" }}>
186
+ {highlightedPath || currentPath || "(None)"}
187
+ </span>
188
+ </span>
189
+ <div style={{ display: "flex", gap: "0.5rem" }}>
190
+ <button onClick={onClose} style={secondaryButtonStyle}>
191
+ Cancel
192
+ </button>
193
+ <button onClick={handleSelectClick} style={primaryButtonStyle} disabled={isLoading}>
194
+ Select Folder
195
+ </button>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ );
201
+ }
202
+
203
+ // Styling for Directory Browser
204
+ const modalOverlayStyle: React.CSSProperties = {
205
+ position: "fixed",
206
+ top: 0,
207
+ left: 0,
208
+ right: 0,
209
+ bottom: 0,
210
+ backgroundColor: "rgba(5, 7, 10, 0.85)",
211
+ backdropFilter: "blur(12px)",
212
+ zIndex: 1100, // Higher than regular wizard overlays
213
+ display: "flex",
214
+ alignItems: "center",
215
+ justifyContent: "center",
216
+ };
217
+
218
+ const modalContainerStyle: React.CSSProperties = {
219
+ width: "90%",
220
+ maxWidth: "550px",
221
+ height: "480px",
222
+ backgroundColor: "var(--card)",
223
+ border: "1px solid var(--border-focus)",
224
+ borderRadius: "12px",
225
+ boxShadow: "0 20px 25px -5px rgba(0,0,0,0.7), 0 10px 10px -5px rgba(0,0,0,0.7)",
226
+ display: "flex",
227
+ flexDirection: "column",
228
+ overflow: "hidden",
229
+ };
230
+
231
+ const headerStyle: React.CSSProperties = {
232
+ display: "flex",
233
+ alignItems: "center",
234
+ justifyContent: "space-between",
235
+ padding: "0.85rem 1.25rem",
236
+ borderBottom: "1px solid var(--border)",
237
+ background: "hsla(var(--border-hsl), 0.2)",
238
+ };
239
+
240
+ const closeButtonStyle: React.CSSProperties = {
241
+ background: "none",
242
+ border: "none",
243
+ color: "var(--muted)",
244
+ fontSize: "0.9rem",
245
+ cursor: "pointer",
246
+ padding: "0.25rem",
247
+ };
248
+
249
+ const pathBarContainerStyle: React.CSSProperties = {
250
+ display: "flex",
251
+ padding: "0.75rem 1.25rem",
252
+ gap: "0.5rem",
253
+ backgroundColor: "rgba(10, 15, 25, 0.5)",
254
+ borderBottom: "1px solid var(--border)",
255
+ };
256
+
257
+ const pathInputStyle: React.CSSProperties = {
258
+ flex: 1,
259
+ padding: "0.45rem 0.75rem",
260
+ backgroundColor: "#05070a",
261
+ border: "1px solid var(--border)",
262
+ borderRadius: "6px",
263
+ color: "var(--foreground)",
264
+ fontFamily: "var(--font-mono), monospace",
265
+ fontSize: "0.8rem",
266
+ outline: "none",
267
+ };
268
+
269
+ const goButtonStyle: React.CSSProperties = {
270
+ padding: "0.45rem 0.85rem",
271
+ backgroundColor: "var(--border)",
272
+ border: "1px solid var(--border-focus)",
273
+ borderRadius: "6px",
274
+ color: "var(--foreground)",
275
+ fontSize: "0.75rem",
276
+ fontWeight: 600,
277
+ cursor: "pointer",
278
+ };
279
+
280
+ const enterFolderButtonStyle: React.CSSProperties = {
281
+ padding: "0.15rem 0.45rem",
282
+ backgroundColor: "rgba(255, 255, 255, 0.15)",
283
+ border: "none",
284
+ borderRadius: "4px",
285
+ color: "var(--foreground)",
286
+ fontSize: "0.7rem",
287
+ cursor: "pointer",
288
+ fontWeight: 600,
289
+ };
290
+
291
+ const listContainerStyle: React.CSSProperties = {
292
+ flex: 1,
293
+ padding: "0.5rem 1.25rem",
294
+ overflowY: "auto",
295
+ backgroundColor: "#070a0f",
296
+ };
297
+
298
+ const listStyle: React.CSSProperties = {
299
+ display: "flex",
300
+ flexDirection: "column",
301
+ gap: "0.25rem",
302
+ };
303
+
304
+ const listItemStyle: React.CSSProperties = {
305
+ display: "flex",
306
+ alignItems: "center",
307
+ gap: "0.6rem",
308
+ padding: "0.45rem 0.65rem",
309
+ borderRadius: "6px",
310
+ cursor: "pointer",
311
+ fontSize: "0.825rem",
312
+ border: "1px solid transparent",
313
+ userSelect: "none",
314
+ transition: "all 0.15s ease",
315
+ };
316
+
317
+ const statusMessageStyle: React.CSSProperties = {
318
+ textAlign: "center",
319
+ padding: "2rem",
320
+ fontSize: "0.85rem",
321
+ color: "var(--muted)",
322
+ };
323
+
324
+ const footerStyle: React.CSSProperties = {
325
+ display: "flex",
326
+ alignItems: "center",
327
+ justifyContent: "space-between",
328
+ padding: "0.85rem 1.25rem",
329
+ borderTop: "1px solid var(--border)",
330
+ background: "hsla(var(--border-hsl), 0.2)",
331
+ };
332
+
333
+ const selectionPreviewStyle: React.CSSProperties = {
334
+ fontSize: "0.75rem",
335
+ color: "var(--muted)",
336
+ maxWidth: "240px",
337
+ overflow: "hidden",
338
+ textOverflow: "ellipsis",
339
+ whiteSpace: "nowrap",
340
+ };
341
+
342
+ const primaryButtonStyle: React.CSSProperties = {
343
+ padding: "0.45rem 0.9rem",
344
+ borderRadius: "6px",
345
+ border: "none",
346
+ background: "linear-gradient(135deg, hsl(262, 83%, 60%) 0%, hsl(195, 100%, 45%) 100%)",
347
+ color: "#fff",
348
+ fontSize: "0.75rem",
349
+ fontWeight: 600,
350
+ cursor: "pointer",
351
+ };
352
+
353
+ const secondaryButtonStyle: React.CSSProperties = {
354
+ padding: "0.45rem 0.9rem",
355
+ borderRadius: "6px",
356
+ border: "1px solid var(--border)",
357
+ backgroundColor: "transparent",
358
+ color: "var(--foreground)",
359
+ fontSize: "0.75rem",
360
+ fontWeight: 600,
361
+ cursor: "pointer",
362
+ };
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,44837,e=>{"use strict";var r=e.i(43476),o=e.i(71645);let t={position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(5, 7, 10, 0.8)",backdropFilter:"blur(8px)",zIndex:1e3,display:"flex",alignItems:"center",justifyContent:"center",animation:"fadeIn 0.2s ease-out"},n={width:"90%",maxWidth:"500px",backgroundColor:"var(--card)",border:"1px solid var(--border-focus)",borderRadius:"12px",boxShadow:"0 10px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.5)",overflow:"hidden",display:"flex",flexDirection:"column"},a={display:"flex",alignItems:"center",justifyContent:"space-between",padding:"1rem 1.25rem",borderBottom:"1px solid var(--border)",background:"hsla(var(--border-hsl), 0.2)"},i={background:"none",border:"none",color:"var(--muted)",fontSize:"0.9rem",cursor:"pointer",padding:"0.25rem"},l={padding:"1.25rem",display:"flex",flexDirection:"column"},s={display:"flex",flexDirection:"column",marginBottom:"1rem"},d={fontSize:"0.75rem",fontWeight:600,color:"var(--foreground)",marginBottom:"0.375rem",textTransform:"uppercase",letterSpacing:"0.05em"},c={width:"100%",padding:"0.5rem 0.75rem",backgroundColor:"#080c14",border:"1px solid var(--border)",borderRadius:"6px",color:"var(--foreground)",fontFamily:"var(--font-mono), monospace",fontSize:"0.825rem",outline:"none",transition:"border-color 0.15s ease"},p={marginTop:"0.75rem",padding:"0.75rem",borderRadius:"6px",border:"1px solid var(--danger)",backgroundColor:"rgba(239, 68, 68, 0.05)",color:"var(--danger)",fontSize:"0.8rem",lineHeight:1.4},u={display:"flex",justifyContent:"flex-end",gap:"0.75rem",padding:"1rem 1.25rem",borderTop:"1px solid var(--border)",background:"hsla(var(--border-hsl), 0.2)"},m={padding:"0.5rem 1rem",borderRadius:"6px",border:"none",background:"linear-gradient(135deg, hsl(262, 83%, 60%) 0%, hsl(195, 100%, 45%) 100%)",color:"#fff",fontSize:"0.8rem",fontWeight:600,cursor:"pointer"},g={padding:"0.5rem 1rem",borderRadius:"6px",border:"1px solid var(--border)",backgroundColor:"transparent",color:"var(--foreground)",fontSize:"0.8rem",fontWeight:600,cursor:"pointer"};e.s(["default",0,function({onClose:e,onConfirmLaunch:x,isDocker:f}){let[h,b]=(0,o.useState)({name:f?"Claude Docker":"Claude Local",workspaceRoot:"",scopedDirs:[]}),[y,v]=(0,o.useState)(""),[j,C]=(0,o.useState)(!0),[k,S]=(0,o.useState)(!1),[D,w]=(0,o.useState)("");(0,o.useEffect)(()=>{(async()=>{try{let e=await fetch("/api/context/claude");if(e.ok){let r=await e.json();r.success&&r.config&&b({name:r.config.name||(f?"Claude Docker":"Claude Local"),workspaceRoot:r.config.workspaceRoot||"",scopedDirs:r.config.scopedDirs||[]})}}catch(e){console.error("Failed to load Claude configuration:",e)}finally{C(!1)}})()},[f]);let R=async()=>{S(!0),w("");try{let e=await fetch("/api/context/claude",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)});if(e.ok)S(!1),x(h.name,h.workspaceRoot,h.scopedDirs);else{let r=await e.json();w(r.error||"Failed to save settings."),S(!1)}}catch(e){console.error(e),w("Network error: failed to connect to NeuralLoom dashboard API."),S(!1)}};return j?(0,r.jsx)("div",{style:t,children:(0,r.jsx)("div",{style:n,children:(0,r.jsx)("div",{style:{textAlign:"center",padding:"2rem"},children:(0,r.jsx)("span",{style:{color:"var(--muted)"},children:"Loading Claude Configuration..."})})})}):(0,r.jsx)("div",{style:t,children:(0,r.jsxs)("div",{style:n,children:[(0,r.jsxs)("div",{style:a,children:[(0,r.jsxs)("h3",{style:{fontSize:"1.1rem",fontWeight:700,margin:0,display:"flex",alignItems:"center",gap:"0.5rem"},children:[f?"🐳":"🤖"," Claude PTY Launch Wizard ",f?"(Docker)":"(Local)"]}),(0,r.jsx)("button",{onClick:e,style:i,"aria-label":"Close wizard",children:"✖"})]}),(0,r.jsxs)("div",{style:l,children:[(0,r.jsx)("p",{style:{fontSize:"0.825rem",color:"var(--muted)",marginBottom:"1.25rem",lineHeight:1.4},children:"Configure the local workspace path and access parameters for the Claude Code session. Settings are saved in `.ai/neural-loom/claude.json`."}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Session Display Name"}),(0,r.jsx)("input",{type:"text",value:h.name,onChange:e=>b({...h,name:e.target.value}),placeholder:f?"Claude Docker":"Claude Local",style:c})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Workspace Directory (Root)"}),(0,r.jsx)("input",{type:"text",value:h.workspaceRoot,onChange:e=>b({...h,workspaceRoot:e.target.value}),placeholder:"e.g. C:\\Users\\Dave\\OneDrive\\Projects\\JS\\wingman",style:c}),(0,r.jsx)("span",{style:{fontSize:"0.7rem",color:"var(--muted)",marginTop:"0.25rem"},children:"The active folder Claude Code will run in. Leave blank to run in the current orchestrator directory."})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Scoped Directories (Additional Access)"}),h.scopedDirs.length>0&&(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",marginBottom:"0.5rem"},children:h.scopedDirs.map((e,o)=>(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",backgroundColor:"#080c14",padding:"0.35rem 0.5rem",borderRadius:"4px",border:"1px solid var(--border)"},children:[(0,r.jsx)("span",{style:{fontSize:"0.8rem",fontFamily:"var(--font-mono), monospace",wordBreak:"break-all"},children:e}),(0,r.jsx)("button",{type:"button",onClick:()=>{let e=h.scopedDirs.filter((e,r)=>r!==o);b({...h,scopedDirs:e})},style:{background:"none",border:"none",color:"var(--danger)",cursor:"pointer",fontSize:"0.8rem",padding:"0 0.25rem"},children:"Remove"})]},o))}),(0,r.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,r.jsx)("input",{type:"text",value:y,onChange:e=>v(e.target.value),placeholder:"e.g. C:\\Users\\Dave\\OneDrive\\Projects\\JS\\other-repo",style:{...c,flex:1}}),(0,r.jsx)("button",{type:"button",onClick:()=>{y.trim()&&!h.scopedDirs.includes(y.trim())&&(b({...h,scopedDirs:[...h.scopedDirs,y.trim()]}),v(""))},style:{padding:"0.35rem 0.75rem",borderRadius:"6px",border:"1px solid var(--border-focus)",backgroundColor:"rgba(109, 40, 217, 0.1)",color:"var(--foreground)",fontSize:"0.75rem",fontWeight:600,cursor:"pointer"},children:"Add"})]})]}),D&&(0,r.jsxs)("div",{style:p,children:["✗ ",D]})]}),(0,r.jsxs)("div",{style:u,children:[(0,r.jsx)("button",{onClick:e,style:g,disabled:k,children:"Cancel"}),(0,r.jsx)("button",{onClick:R,style:m,disabled:k,children:k?"Saving...":"Launch Session"})]})]})})}])},20032,e=>{e.n(e.i(44837))}]);
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,1663,e=>{"use strict";var r=e.i(43476),o=e.i(71645);let i={position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(5, 7, 10, 0.8)",backdropFilter:"blur(8px)",zIndex:1e3,display:"flex",alignItems:"center",justifyContent:"center",animation:"fadeIn 0.2s ease-out"},n={width:"90%",maxWidth:"500px",backgroundColor:"var(--card)",border:"1px solid var(--border-focus)",borderRadius:"12px",boxShadow:"0 10px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.5)",overflow:"hidden",display:"flex",flexDirection:"column"},t={display:"flex",alignItems:"center",justifyContent:"space-between",padding:"1rem 1.25rem",borderBottom:"1px solid var(--border)",background:"hsla(var(--border-hsl), 0.2)"},l={background:"none",border:"none",color:"var(--muted)",fontSize:"0.9rem",cursor:"pointer",padding:"0.25rem"},a={padding:"1.25rem",display:"flex",flexDirection:"column"},s={display:"flex",flexDirection:"column",marginBottom:"1rem"},d={fontSize:"0.75rem",fontWeight:600,color:"var(--foreground)",marginBottom:"0.375rem",textTransform:"uppercase",letterSpacing:"0.05em"},c={width:"100%",padding:"0.5rem 0.75rem",backgroundColor:"#080c14",border:"1px solid var(--border)",borderRadius:"6px",color:"var(--foreground)",fontFamily:"var(--font-mono), monospace",fontSize:"0.825rem",outline:"none",transition:"border-color 0.15s ease"},p={width:"100%",padding:"0.5rem 0.75rem",backgroundColor:"#080c14",border:"1px solid var(--border)",borderRadius:"6px",color:"var(--foreground)",fontSize:"0.825rem",outline:"none",cursor:"pointer"},g={marginTop:"0.75rem",padding:"0.75rem",borderRadius:"6px",border:"1px solid var(--danger)",backgroundColor:"rgba(239, 68, 68, 0.05)",color:"var(--danger)",fontSize:"0.8rem",lineHeight:1.4},m={display:"flex",justifyContent:"flex-end",gap:"0.75rem",padding:"1rem 1.25rem",borderTop:"1px solid var(--border)",background:"hsla(var(--border-hsl), 0.2)"},u={padding:"0.5rem 1rem",borderRadius:"6px",border:"none",background:"linear-gradient(135deg, hsl(210, 80%, 45%) 0%, hsl(262, 80%, 55%) 100%)",color:"#fff",fontSize:"0.8rem",fontWeight:600,cursor:"pointer"},x={padding:"0.5rem 1rem",borderRadius:"6px",border:"1px solid var(--border)",backgroundColor:"transparent",color:"var(--foreground)",fontSize:"0.8rem",fontWeight:600,cursor:"pointer"};e.s(["default",0,function({onClose:e,onConfirmLaunch:h,isDocker:y}){let[f,b]=(0,o.useState)({openaiApiKey:"",anthropicApiKey:"",geminiApiKey:"",model:"claude-3-5-sonnet",extraFlags:"",workspaceRoot:"",scopedDirs:[]}),[v,j]=(0,o.useState)(""),[k,A]=(0,o.useState)(!0),[C,S]=(0,o.useState)(!1),[w,K]=(0,o.useState)("");(0,o.useEffect)(()=>{(async()=>{try{let e=await fetch("/api/context/aider");if(e.ok){let r=await e.json();r.success&&r.config&&b({openaiApiKey:r.config.openaiApiKey||"",anthropicApiKey:r.config.anthropicApiKey||"",geminiApiKey:r.config.geminiApiKey||"",model:r.config.model||"claude-3-5-sonnet",extraFlags:r.config.extraFlags||"",workspaceRoot:r.config.workspaceRoot||"",scopedDirs:r.config.scopedDirs||[]})}}catch(e){console.error("Failed to load Aider configuration:",e)}finally{A(!1)}})()},[]);let D=async()=>{S(!0),K("");try{let e=await fetch("/api/context/aider",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f)});if(e.ok)S(!1),h();else{let r=await e.json();K(r.error||"Failed to save settings."),S(!1)}}catch(e){console.error(e),K("Network error: failed to connect to NeuralLoom dashboard API."),S(!1)}};return k?(0,r.jsx)("div",{style:i,children:(0,r.jsx)("div",{style:n,children:(0,r.jsx)("div",{style:{textAlign:"center",padding:"2rem"},children:(0,r.jsx)("span",{style:{color:"var(--muted)"},children:"Loading Aider Configuration..."})})})}):(0,r.jsx)("div",{style:i,children:(0,r.jsxs)("div",{style:n,children:[(0,r.jsxs)("div",{style:t,children:[(0,r.jsxs)("h3",{style:{fontSize:"1.1rem",fontWeight:700,margin:0,display:"flex",alignItems:"center",gap:"0.5rem"},children:["🐍 Aider Launch Panel ",y?"(Docker)":""]}),(0,r.jsx)("button",{onClick:e,style:l,"aria-label":"Close wizard",children:"✖"})]}),(0,r.jsxs)("div",{style:a,children:[(0,r.jsx)("p",{style:{fontSize:"0.825rem",color:"var(--muted)",marginBottom:"1.25rem",lineHeight:1.4},children:"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."}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Anthropic API Key"}),(0,r.jsx)("input",{type:"password",value:f.anthropicApiKey,onChange:e=>b({...f,anthropicApiKey:e.target.value}),placeholder:f.anthropicApiKey?"••••••••••••••••":"sk-ant-...",style:c})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"OpenAI API Key"}),(0,r.jsx)("input",{type:"password",value:f.openaiApiKey,onChange:e=>b({...f,openaiApiKey:e.target.value}),placeholder:f.openaiApiKey?"••••••••••••••••":"sk-...",style:c})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Gemini API Key"}),(0,r.jsx)("input",{type:"password",value:f.geminiApiKey,onChange:e=>b({...f,geminiApiKey:e.target.value}),placeholder:f.geminiApiKey?"••••••••••••••••":"AIzaSy...",style:c})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Workspace Directory (Root)"}),(0,r.jsx)("input",{type:"text",value:f.workspaceRoot,onChange:e=>b({...f,workspaceRoot:e.target.value}),placeholder:"e.g. C:\\Users\\Dave\\OneDrive\\Projects\\JS\\neural-loom",style:c}),(0,r.jsx)("span",{style:{fontSize:"0.7rem",color:"var(--muted)",marginTop:"0.25rem"},children:"Leave blank to default to the current orchestrator directory."})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Scoped Directories (Additional Access)"}),f.scopedDirs.length>0&&(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",marginBottom:"0.5rem"},children:f.scopedDirs.map((e,o)=>(0,r.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",backgroundColor:"#080c14",padding:"0.35rem 0.5rem",borderRadius:"4px",border:"1px solid var(--border)"},children:[(0,r.jsx)("span",{style:{fontSize:"0.8rem",fontFamily:"var(--font-mono), monospace",wordBreak:"break-all"},children:e}),(0,r.jsx)("button",{type:"button",onClick:()=>{let e=f.scopedDirs.filter((e,r)=>r!==o);b({...f,scopedDirs:e})},style:{background:"none",border:"none",color:"var(--danger)",cursor:"pointer",fontSize:"0.8rem",padding:"0 0.25rem"},children:"Remove"})]},o))}),(0,r.jsxs)("div",{style:{display:"flex",gap:"0.5rem"},children:[(0,r.jsx)("input",{type:"text",value:v,onChange:e=>j(e.target.value),placeholder:"e.g. C:\\Users\\Dave\\OneDrive\\Projects\\JS\\wingman",style:{...c,flex:1}}),(0,r.jsx)("button",{type:"button",onClick:()=>{v.trim()&&!f.scopedDirs.includes(v.trim())&&(b({...f,scopedDirs:[...f.scopedDirs,v.trim()]}),j(""))},style:{padding:"0.35rem 0.75rem",borderRadius:"6px",border:"1px solid var(--border-focus)",backgroundColor:"rgba(109, 40, 217, 0.1)",color:"var(--foreground)",fontSize:"0.75rem",fontWeight:600,cursor:"pointer"},children:"Add"})]})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"AI Model Selection"}),(0,r.jsxs)("select",{value:f.model,onChange:e=>b({...f,model:e.target.value}),style:p,children:[(0,r.jsx)("option",{value:"claude-3-5-sonnet",children:"Claude 3.5 Sonnet (Recommended)"}),(0,r.jsx)("option",{value:"gemini/gemini-1.5-pro",children:"Gemini 1.5 Pro"}),(0,r.jsx)("option",{value:"gemini/gemini-1.5-flash",children:"Gemini 1.5 Flash"}),(0,r.jsx)("option",{value:"gemini/gemini-2.0-flash-exp",children:"Gemini 2.0 Flash Exp"}),(0,r.jsx)("option",{value:"gpt-4o",children:"GPT-4o"}),(0,r.jsx)("option",{value:"deepseek/deepseek-coder",children:"DeepSeek Coder"}),(0,r.jsx)("option",{value:"gpt-4-turbo",children:"GPT-4 Turbo"})]})]}),(0,r.jsxs)("div",{style:s,children:[(0,r.jsx)("label",{style:d,children:"Extra CLI Flags (Optional)"}),(0,r.jsx)("input",{type:"text",value:f.extraFlags,onChange:e=>b({...f,extraFlags:e.target.value}),placeholder:"e.g. --no-git --auto-commits",style:c}),(0,r.jsx)("span",{style:{fontSize:"0.7rem",color:"var(--muted)",marginTop:"0.25rem"},children:"Appended directly to the startup shell command."})]}),w&&(0,r.jsxs)("div",{style:g,children:["✗ ",w]})]}),(0,r.jsxs)("div",{style:m,children:[(0,r.jsx)("button",{onClick:e,style:x,disabled:C,children:"Cancel"}),(0,r.jsx)("button",{onClick:D,style:u,disabled:C,children:C?"Saving...":"Save & Launch Session"})]})]})})}])},9949,e=>{e.n(e.i(1663))}]);