@mrpatronz/nexusflow 0.2.12 → 0.2.13

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 (88) hide show
  1. package/dist/commands/add-repo.d.ts.map +1 -1
  2. package/dist/commands/add-repo.js +24 -14
  3. package/dist/commands/add-repo.js.map +1 -1
  4. package/dist/commands/commit.js +1 -1
  5. package/dist/commands/commit.js.map +1 -1
  6. package/dist/commands/diff.js +1 -1
  7. package/dist/commands/diff.js.map +1 -1
  8. package/dist/commands/doctor.js +1 -1
  9. package/dist/commands/doctor.js.map +1 -1
  10. package/dist/commands/handoff.js +1 -1
  11. package/dist/commands/handoff.js.map +1 -1
  12. package/dist/commands/logs.js +1 -1
  13. package/dist/commands/logs.js.map +1 -1
  14. package/dist/commands/open.d.ts.map +1 -1
  15. package/dist/commands/open.js +12 -7
  16. package/dist/commands/open.js.map +1 -1
  17. package/dist/commands/pack.js +1 -1
  18. package/dist/commands/pack.js.map +1 -1
  19. package/dist/commands/refresh.js +13 -8
  20. package/dist/commands/refresh.js.map +1 -1
  21. package/dist/commands/remove.d.ts.map +1 -1
  22. package/dist/commands/remove.js +12 -7
  23. package/dist/commands/remove.js.map +1 -1
  24. package/dist/commands/start.js +1 -1
  25. package/dist/commands/start.js.map +1 -1
  26. package/dist/commands/status.js +1 -1
  27. package/dist/commands/status.js.map +1 -1
  28. package/dist/commands/stop.js +1 -1
  29. package/dist/commands/stop.js.map +1 -1
  30. package/dist/commands/sync.js +13 -8
  31. package/dist/commands/sync.js.map +1 -1
  32. package/dist/core/workspace.d.ts +7 -0
  33. package/dist/core/workspace.d.ts.map +1 -1
  34. package/dist/core/workspace.js +45 -1
  35. package/dist/core/workspace.js.map +1 -1
  36. package/dist/generators/index.d.ts.map +1 -1
  37. package/dist/generators/index.js +14 -0
  38. package/dist/generators/index.js.map +1 -1
  39. package/dist/gui/assets/index-CFWwqFux.js +23 -0
  40. package/dist/gui/assets/index-Dvc9QMvl.css +2 -0
  41. package/dist/gui/index.html +2 -2
  42. package/dist/orchestration/runner.d.ts +5 -6
  43. package/dist/orchestration/runner.d.ts.map +1 -1
  44. package/dist/orchestration/runner.js +105 -102
  45. package/dist/orchestration/runner.js.map +1 -1
  46. package/dist/server.d.ts.map +1 -1
  47. package/dist/server.js +53 -1
  48. package/dist/server.js.map +1 -1
  49. package/dist/utils/detect-editors.js +1 -1
  50. package/dist/utils/detect-editors.js.map +1 -1
  51. package/dist/utils/detect-editors.test.js +3 -3
  52. package/dist/utils/detect-editors.test.js.map +1 -1
  53. package/dist/utils/prompts.d.ts +1 -0
  54. package/dist/utils/prompts.d.ts.map +1 -1
  55. package/dist/utils/prompts.js +77 -15
  56. package/dist/utils/prompts.js.map +1 -1
  57. package/extension/package.json +9 -0
  58. package/extension/src/extension.ts +37 -1
  59. package/gui/eslint.config.js +4 -0
  60. package/gui/src/App.tsx +375 -151
  61. package/gui/src/features/changes/ChangesViewer.tsx +246 -70
  62. package/gui/src/features/services/ServiceConsole.tsx +162 -71
  63. package/gui/src/features/workspace/WorkspaceList.tsx +184 -32
  64. package/gui/src/index.css +95 -2
  65. package/package.json +2 -1
  66. package/src/commands/add-repo.ts +30 -14
  67. package/src/commands/commit.ts +1 -1
  68. package/src/commands/diff.ts +1 -1
  69. package/src/commands/doctor.ts +1 -1
  70. package/src/commands/handoff.ts +1 -1
  71. package/src/commands/logs.ts +1 -1
  72. package/src/commands/open.ts +15 -7
  73. package/src/commands/pack.ts +1 -1
  74. package/src/commands/refresh.ts +16 -8
  75. package/src/commands/remove.ts +15 -7
  76. package/src/commands/start.ts +1 -1
  77. package/src/commands/status.ts +1 -1
  78. package/src/commands/stop.ts +1 -1
  79. package/src/commands/sync.ts +16 -8
  80. package/src/core/workspace.ts +48 -1
  81. package/src/generators/index.ts +20 -0
  82. package/src/orchestration/runner.ts +112 -108
  83. package/src/server.ts +58 -1
  84. package/src/utils/detect-editors.test.ts +3 -3
  85. package/src/utils/detect-editors.ts +1 -1
  86. package/src/utils/prompts.ts +88 -14
  87. package/dist/gui/assets/index-Ca2VRMrQ.js +0 -22
  88. package/dist/gui/assets/index-fj0RJiOb.css +0 -2
package/gui/src/App.tsx CHANGED
@@ -95,6 +95,7 @@ interface RunningService {
95
95
 
96
96
  const API_BASE = import.meta.env.DEV ? 'http://localhost:3000' : '';
97
97
  const isVsCode = new URLSearchParams(window.location.search).get('env') === 'vscode';
98
+ let toastIdCounter = 0;
98
99
 
99
100
  export default function App() {
100
101
  const [view, setView] = useState<'guide' | 'create' | 'workspaces' | 'settings'>('guide');
@@ -108,7 +109,7 @@ export default function App() {
108
109
  }
109
110
  const [toasts, setToasts] = useState<Toast[]>([]);
110
111
  const showToast = (message: string, type: 'success' | 'error' | 'info' = 'info', duration = 5000) => {
111
- const id = Math.random().toString(36).substring(2, 9);
112
+ const id = `toast-${++toastIdCounter}`;
112
113
  setToasts((prev) => [...prev, { id, message, type, duration }]);
113
114
  setTimeout(() => {
114
115
  setToasts((prev) => prev.filter((t) => t.id !== id));
@@ -190,7 +191,7 @@ export default function App() {
190
191
  const [orchTools, setOrchTools] = useState<OrchestrationDetection[]>([]);
191
192
  const [runningServices, setRunningServices] = useState<RunningService[]>([]);
192
193
  const [servicesLoading, setServicesLoading] = useState(false);
193
- const [subTab, setSubTab] = useState<'services' | 'changes' | 'sessions' | 'knowledge' | 'plan'>('sessions');
194
+ const [subTab, setSubTab] = useState<'overview' | 'services' | 'changes' | 'sessions' | 'knowledge' | 'plan'>('overview');
194
195
  const [sessions, setSessions] = useState<any[]>([]);
195
196
  const [sessionsLoading, setSessionsLoading] = useState(false);
196
197
  const [activeSession, setActiveSession] = useState<any | null>(null);
@@ -237,86 +238,7 @@ export default function App() {
237
238
  return true;
238
239
  })();
239
240
 
240
- // Initial loads
241
- useEffect(() => {
242
- fetchConfig();
243
- fetchAIAssistants();
244
- fetchWorkspaces();
245
- fetchUpdateStatus();
246
- }, []);
247
-
248
- // Load tool updates status and LLM recommendations when settings view is open
249
- useEffect(() => {
250
- if (view === 'settings') {
251
- fetchToolsStatus();
252
- fetchLlmRecommendation();
253
- }
254
- }, [view]);
255
-
256
- // Poll logs and services status when active workspace is open
257
- useEffect(() => {
258
- let interval: any = null;
259
- if (activeWsId) {
260
- fetchWorkspaceServices(activeWsId);
261
- interval = setInterval(() => {
262
- fetchWorkspaceServices(activeWsId, true);
263
- }, 3000);
264
- }
265
- return () => {
266
- if (interval) clearInterval(interval);
267
- };
268
- }, [activeWsId]);
269
-
270
- // Load git changes when tab switches to 'changes' or active workspace changes
271
- useEffect(() => {
272
- if (activeWsId && subTab === 'changes') {
273
- fetchGitChanges(activeWsId);
274
- }
275
- }, [activeWsId, subTab]);
276
-
277
- // Load sessions when active workspace changes or subTab switches to 'sessions'
278
- useEffect(() => {
279
- if (activeWsId && subTab === 'sessions') {
280
- fetchWorkspaceSessions(activeWsId);
281
- }
282
- }, [activeWsId, subTab]);
283
-
284
- // Load knowledge when subTab switches to 'knowledge' or active workspace changes
285
- useEffect(() => {
286
- if (activeWsId && subTab === 'knowledge') {
287
- fetchKnowledge(activeWsId);
288
- }
289
- }, [activeWsId, subTab]);
290
-
291
- // Load plan when subTab switches to 'plan' or active workspace changes
292
- useEffect(() => {
293
- if (activeWsId && subTab === 'plan') {
294
- fetchPlan(activeWsId);
295
- }
296
- }, [activeWsId, subTab]);
297
-
298
-
299
-
300
- // Poll logs for active service logs
301
- useEffect(() => {
302
- let interval: any = null;
303
- if (activeWsId && selectedLogService) {
304
- fetchLogs(activeWsId, selectedLogService);
305
- interval = setInterval(() => {
306
- fetchLogs(activeWsId, selectedLogService);
307
- }, 2000);
308
- }
309
- return () => {
310
- if (interval) clearInterval(interval);
311
- };
312
- }, [activeWsId, selectedLogService]);
313
-
314
- // Scroll to bottom of logs when log content changes
315
- useEffect(() => {
316
- if (logsEndRef.current) {
317
- logsEndRef.current.scrollIntoView({ behavior: 'smooth' });
318
- }
319
- }, [serviceLogs]);
241
+ // Effects moved below helper functions to resolve lexical declaration order
320
242
 
321
243
  // ─── API Fetches ────────────────────────────────────────────────────────
322
244
 
@@ -892,7 +814,106 @@ export default function App() {
892
814
  }
893
815
  };
894
816
 
817
+ const executeTerminal = (command: string) => {
818
+ if (!activeWsId) return;
819
+ const ws = workspaces.find(w => w.branchName === activeWsId);
820
+ if (ws) {
821
+ window.parent.postMessage({
822
+ type: 'executeTerminalCommand',
823
+ command,
824
+ cwd: ws.workspacePath
825
+ }, '*');
826
+ }
827
+ };
828
+
829
+
895
830
 
831
+ // Initial loads
832
+ useEffect(() => {
833
+ fetchConfig();
834
+ fetchAIAssistants();
835
+ fetchWorkspaces();
836
+ fetchUpdateStatus();
837
+
838
+ // Support auto-loading workspace from VS Code or URL params
839
+ const queryParams = new URLSearchParams(window.location.search);
840
+ const queryWsId = queryParams.get('workspaceId');
841
+ if (queryWsId) {
842
+ setActiveWsId(queryWsId);
843
+ setView('workspaces');
844
+ }
845
+ }, []);
846
+
847
+ // Load tool updates status and LLM recommendations when settings view is open
848
+ useEffect(() => {
849
+ if (view === 'settings') {
850
+ fetchToolsStatus();
851
+ fetchLlmRecommendation();
852
+ }
853
+ }, [view]);
854
+
855
+ // Poll logs and services status when active workspace is open
856
+ useEffect(() => {
857
+ let interval: any = null;
858
+ if (activeWsId) {
859
+ fetchWorkspaceServices(activeWsId);
860
+ interval = setInterval(() => {
861
+ fetchWorkspaceServices(activeWsId, true);
862
+ }, 3000);
863
+ }
864
+ return () => {
865
+ if (interval) clearInterval(interval);
866
+ };
867
+ }, [activeWsId]);
868
+
869
+ // Load git changes when tab switches to 'changes' or active workspace changes
870
+ useEffect(() => {
871
+ if (activeWsId && subTab === 'changes') {
872
+ fetchGitChanges(activeWsId);
873
+ }
874
+ }, [activeWsId, subTab]);
875
+
876
+ // Load sessions when active workspace changes or subTab switches to 'sessions'
877
+ useEffect(() => {
878
+ if (activeWsId && subTab === 'sessions') {
879
+ fetchWorkspaceSessions(activeWsId);
880
+ }
881
+ }, [activeWsId, subTab]);
882
+
883
+ // Load knowledge when subTab switches to 'knowledge' or active workspace changes
884
+ useEffect(() => {
885
+ if (activeWsId && subTab === 'knowledge') {
886
+ fetchKnowledge(activeWsId);
887
+ }
888
+ }, [activeWsId, subTab]);
889
+
890
+ // Load plan when subTab switches to 'plan' or active workspace changes
891
+ useEffect(() => {
892
+ if (activeWsId && subTab === 'plan') {
893
+ fetchPlan(activeWsId);
894
+ }
895
+ }, [activeWsId, subTab]);
896
+
897
+ // Poll logs for active service logs
898
+ useEffect(() => {
899
+ let interval: any = null;
900
+ if (activeWsId && selectedLogService) {
901
+ fetchLogs(activeWsId, selectedLogService);
902
+ interval = setInterval(() => {
903
+ fetchLogs(activeWsId, selectedLogService);
904
+ }, 2000);
905
+ }
906
+ return () => {
907
+ if (interval) clearInterval(interval);
908
+ };
909
+ }, [activeWsId, selectedLogService]);
910
+
911
+ // Scroll to bottom of logs when log content changes
912
+ useEffect(() => {
913
+ if (logsEndRef.current) {
914
+ logsEndRef.current.scrollIntoView({ behavior: 'smooth' });
915
+ }
916
+ }, [serviceLogs]);
896
917
 
897
918
  const handleCopyPrompt = (ws: Feature) => {
898
919
  const repoNames = ws.repos.map((r) => r.split(/[\\/]/).pop()).join(', ');
@@ -978,68 +999,68 @@ Core Instructions:
978
999
  const isFormValid = config.devDir.trim() !== '' && config.workspacesDir.trim() !== '';
979
1000
 
980
1001
  return (
981
- <div className="flex min-h-screen bg-[#070913] text-gray-100 font-sans items-center justify-center p-6 bg-gradient-to-br from-[#0c0f24] via-[#070913] to-[#04050b]">
1002
+ <div className="flex min-h-screen bg-[#060813] text-gray-100 font-sans items-center justify-center p-6 bg-gradient-to-br from-[#0b0e24] via-[#060813] to-[#030409]">
982
1003
  {/* Onboarding Box */}
983
- <div className="max-w-6xl w-full bg-[#111827]/40 border border-gray-800/80 rounded-2xl p-8 backdrop-blur-md shadow-2xl grid grid-cols-1 lg:grid-cols-12 gap-10">
1004
+ <div className="max-w-6xl w-full glass-card border border-slate-800/60 rounded-3xl p-10 shadow-2xl glass-card-glow grid grid-cols-1 lg:grid-cols-12 gap-12 animate-slide-in">
984
1005
 
985
1006
  {/* Left Column: Onboarding Guide & Concepts */}
986
1007
  <div className="lg:col-span-7 flex flex-col justify-between">
987
1008
  <div>
988
- <div className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full bg-indigo-500/10 text-indigo-400 border border-indigo-500/20 text-xs font-semibold uppercase tracking-wider mb-4">
1009
+ <div className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full bg-indigo-500/10 text-indigo-400 border border-indigo-500/20 text-xs font-semibold uppercase tracking-wider mb-5">
989
1010
  <Sparkles size={12} className="text-cyan-400 animate-pulse" /> Onboarding Guide
990
1011
  </div>
991
- <h1 className="text-3xl font-extrabold tracking-tight text-white mb-2 bg-gradient-to-r from-white via-gray-200 to-indigo-300 bg-clip-text text-transparent">
1012
+ <h1 className="text-3xl font-extrabold tracking-tight text-white mb-2 bg-gradient-to-r from-white via-slate-200 to-indigo-300 bg-clip-text text-transparent">
992
1013
  Welcome to NexusFlow
993
1014
  </h1>
994
- <p className="text-sm text-gray-400 mb-8 max-w-xl">
1015
+ <p className="text-sm text-slate-400 mb-8 max-w-xl leading-relaxed">
995
1016
  NexusFlow orchestrates multi-repository developer environments. It combines isolated Git worktrees, automatic code analyzer sweeps, and background process running into a single dashboard.
996
1017
  </p>
997
1018
 
998
1019
  {/* Onboarding Steps */}
999
1020
  <div className="space-y-6">
1000
- <div className="flex gap-4">
1001
- <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0">
1021
+ <div className="flex gap-4 group">
1022
+ <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0 group-hover:bg-indigo-500/20 group-hover:text-indigo-300 transition-colors">
1002
1023
  1
1003
1024
  </div>
1004
1025
  <div>
1005
- <h3 className="text-sm font-semibold text-white">Configure Development Folders</h3>
1006
- <p className="text-xs text-gray-400 mt-1">
1026
+ <h3 className="text-sm font-semibold text-white group-hover:text-indigo-300 transition-colors">Configure Development Folders</h3>
1027
+ <p className="text-xs text-slate-400 mt-1 leading-relaxed">
1007
1028
  Specify your local code path and target workspaces path. For the first setup, these paths start empty so you can explicitly configure them.
1008
1029
  </p>
1009
1030
  </div>
1010
1031
  </div>
1011
1032
 
1012
- <div className="flex gap-4">
1013
- <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0">
1033
+ <div className="flex gap-4 group">
1034
+ <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0 group-hover:bg-indigo-500/20 group-hover:text-indigo-300 transition-colors">
1014
1035
  2
1015
1036
  </div>
1016
1037
  <div>
1017
- <h3 className="text-sm font-semibold text-white">Build Isolated Branch Workspaces</h3>
1018
- <p className="text-xs text-gray-400 mt-1">
1038
+ <h3 className="text-sm font-semibold text-white group-hover:text-indigo-300 transition-colors">Build Isolated Branch Workspaces</h3>
1039
+ <p className="text-xs text-slate-400 mt-1 leading-relaxed">
1019
1040
  Choose repositories and input your feature branch. NexusFlow runs <code>git worktree</code> to checkout dependencies under a unified folder structure, leaving your primary repository directories clean.
1020
1041
  </p>
1021
1042
  </div>
1022
1043
  </div>
1023
1044
 
1024
- <div className="flex gap-4">
1025
- <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0">
1045
+ <div className="flex gap-4 group">
1046
+ <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0 group-hover:bg-indigo-500/20 group-hover:text-indigo-300 transition-colors">
1026
1047
  3
1027
1048
  </div>
1028
1049
  <div>
1029
- <h3 className="text-sm font-semibold text-white">Align AI Coding Contexts</h3>
1030
- <p className="text-xs text-gray-400 mt-1">
1050
+ <h3 className="text-sm font-semibold text-white group-hover:text-indigo-300 transition-colors">Align AI Coding Contexts</h3>
1051
+ <p className="text-xs text-slate-400 mt-1 leading-relaxed">
1031
1052
  NexusFlow automatically generates configuration files (<code>CLAUDE.md</code>, <code>.cursorrules</code>, <code>AGENTS.md</code>) that instruct the AI assistant to analyze project inter-dependencies, document its assumptions in <code>nexusflow-overview.md</code>, and highlight clarifying questions.
1032
1053
  </p>
1033
1054
  </div>
1034
1055
  </div>
1035
1056
 
1036
- <div className="flex gap-4">
1037
- <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0">
1057
+ <div className="flex gap-4 group">
1058
+ <div className="w-8 h-8 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 flex items-center justify-center font-bold text-sm shrink-0 group-hover:bg-indigo-500/20 group-hover:text-indigo-300 transition-colors">
1038
1059
  4
1039
1060
  </div>
1040
1061
  <div>
1041
- <h3 className="text-sm font-semibold text-white">Orchestrate Background Services</h3>
1042
- <p className="text-xs text-gray-400 mt-1">
1062
+ <h3 className="text-sm font-semibold text-white group-hover:text-indigo-300 transition-colors">Orchestrate Background Services</h3>
1063
+ <p className="text-xs text-slate-400 mt-1 leading-relaxed">
1043
1064
  Run APIs, database scripts, and frontend watch tasks concurrently from the web portal. Monitor real-time logs inside a unified terminal pane.
1044
1065
  </p>
1045
1066
  </div>
@@ -1048,12 +1069,12 @@ Core Instructions:
1048
1069
  </div>
1049
1070
 
1050
1071
  {/* Comparison Dashboard */}
1051
- <div className="mt-8 pt-6 border-t border-gray-800/80">
1052
- <h4 className="text-xs font-semibold uppercase tracking-wider text-gray-500 mb-3">Industry Comparison</h4>
1072
+ <div className="mt-8 pt-6 border-t border-slate-800/80">
1073
+ <h4 className="text-xs font-semibold uppercase tracking-wider text-slate-500 mb-3">Industry Comparison</h4>
1053
1074
  <div className="overflow-x-auto font-sans">
1054
- <table className="w-full text-[10px] text-gray-400 text-left border-collapse">
1075
+ <table className="w-full text-[10px] text-slate-400 text-left border-collapse">
1055
1076
  <thead>
1056
- <tr className="border-b border-gray-800 text-gray-500">
1077
+ <tr className="border-b border-slate-800 text-slate-500">
1057
1078
  <th className="py-2 pr-4 font-semibold">Orchestrator</th>
1058
1079
  <th className="py-2 px-4 font-semibold">Multi-Repo</th>
1059
1080
  <th className="py-2 px-4 font-semibold">AI Rules Integration</th>
@@ -1061,29 +1082,29 @@ Core Instructions:
1061
1082
  </tr>
1062
1083
  </thead>
1063
1084
  <tbody>
1064
- <tr className="border-b border-gray-800/40">
1085
+ <tr className="border-b border-slate-850">
1065
1086
  <td className="py-2 pr-4 font-semibold text-white">Docker Compose</td>
1066
1087
  <td className="py-2 px-4">Yes (Containers only)</td>
1067
1088
  <td className="py-2 px-4">No</td>
1068
1089
  <td className="py-2 pl-4">Medium (VM overhead)</td>
1069
1090
  </tr>
1070
- <tr className="border-b border-gray-800/40">
1091
+ <tr className="border-b border-slate-850">
1071
1092
  <td className="py-2 pr-4 font-semibold text-white">Lerna / Turborepo</td>
1072
1093
  <td className="py-2 px-4">Monorepo only</td>
1073
1094
  <td className="py-2 px-4">No</td>
1074
1095
  <td className="py-2 pl-4">Light</td>
1075
1096
  </tr>
1076
- <tr className="border-b border-gray-800/40">
1097
+ <tr className="border-b border-slate-850">
1077
1098
  <td className="py-2 pr-4 font-semibold text-white">DevPod / Gitpod</td>
1078
1099
  <td className="py-2 px-4">Yes (Complex config)</td>
1079
1100
  <td className="py-2 px-4">No</td>
1080
1101
  <td className="py-2 pl-4">Heavy (Full virtual VM)</td>
1081
1102
  </tr>
1082
1103
  <tr>
1083
- <td className="py-2 pr-4 font-semibold text-indigo-400">NexusFlow</td>
1084
- <td className="py-2 px-4 text-indigo-300">Yes (Native Worktrees)</td>
1085
- <td className="py-2 px-4 text-indigo-300">Yes (CLAUDE.md/MDC rules)</td>
1086
- <td className="py-2 pl-4 text-indigo-300">Extremely Light (Native processes)</td>
1104
+ <td className="py-2 pr-4 font-semibold text-indigo-400 text-glow-indigo">NexusFlow</td>
1105
+ <td className="py-2 px-4 text-indigo-300 font-medium">Yes (Native Worktrees)</td>
1106
+ <td className="py-2 px-4 text-indigo-300 font-medium">Yes (CLAUDE.md/MDC rules)</td>
1107
+ <td className="py-2 pl-4 text-indigo-300 font-medium">Extremely Light (Native processes)</td>
1087
1108
  </tr>
1088
1109
  </tbody>
1089
1110
  </table>
@@ -1093,44 +1114,44 @@ Core Instructions:
1093
1114
 
1094
1115
  {/* Right Column: Configuration Form */}
1095
1116
  <div className="lg:col-span-5 flex flex-col justify-center">
1096
- <div className="bg-gray-950/40 border border-gray-800/80 rounded-2xl p-6 shadow-lg">
1117
+ <div className="bg-slate-950/50 border border-slate-850 rounded-2xl p-8 shadow-xl relative overflow-hidden before:absolute before:inset-0 before:bg-gradient-to-b before:from-indigo-500/5 before:to-transparent before:pointer-events-none">
1097
1118
  <h2 className="text-xl font-bold text-white mb-1 flex items-center gap-2">
1098
1119
  <SettingsIcon className="text-indigo-400 animate-spin-slow" size={20} /> Initialize Config
1099
1120
  </h2>
1100
- <p className="text-xs text-gray-500 mb-6">
1121
+ <p className="text-xs text-slate-500 mb-6">
1101
1122
  Define the directories on your machine. The fields are empty so you can provide your paths.
1102
1123
  </p>
1103
1124
 
1104
1125
  {/* Form Input fields */}
1105
1126
  <div className="space-y-5">
1106
1127
  <div>
1107
- <label className="block text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-2">Development Directory</label>
1128
+ <label className="block text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-2">Development Directory</label>
1108
1129
  <input
1109
1130
  type="text"
1110
- className="w-full bg-[#111827] border border-gray-800 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 rounded-lg px-4 py-3 text-white placeholder-gray-600 transition-all outline-none text-xs shadow-inner"
1131
+ className="w-full bg-slate-950/60 border border-slate-800 focus:border-indigo-500/80 focus:ring-1 focus:ring-indigo-500/35 rounded-xl px-4 py-3 text-white placeholder-slate-600 transition-all outline-none text-xs shadow-inner"
1111
1132
  placeholder="e.g. C:\Users\username\dev"
1112
1133
  value={config.devDir}
1113
1134
  onChange={(e) => setConfig({ ...config, devDir: e.target.value })}
1114
1135
  />
1115
1136
  {defaultPaths && (
1116
- <div className="text-[10px] text-gray-500 mt-1.5 flex justify-between items-center">
1117
- <span>Suggested: <code>{defaultPaths.devDir}</code></span>
1137
+ <div className="text-[10px] text-slate-500 mt-1.5 flex justify-between items-center">
1138
+ <span>Suggested: <code className="text-indigo-300">{defaultPaths.devDir}</code></span>
1118
1139
  </div>
1119
1140
  )}
1120
1141
  </div>
1121
1142
 
1122
1143
  <div>
1123
- <label className="block text-[11px] font-semibold text-gray-400 uppercase tracking-wider mb-2">Workspaces Directory</label>
1144
+ <label className="block text-[10px] font-semibold text-slate-400 uppercase tracking-wider mb-2">Workspaces Directory</label>
1124
1145
  <input
1125
1146
  type="text"
1126
- className="w-full bg-[#111827] border border-gray-800 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 rounded-lg px-4 py-3 text-white placeholder-gray-600 transition-all outline-none text-xs shadow-inner"
1147
+ className="w-full bg-slate-950/60 border border-slate-800 focus:border-indigo-500/80 focus:ring-1 focus:ring-indigo-500/35 rounded-xl px-4 py-3 text-white placeholder-slate-600 transition-all outline-none text-xs shadow-inner"
1127
1148
  placeholder="e.g. C:\Users\username\dev\workspaces"
1128
1149
  value={config.workspacesDir}
1129
1150
  onChange={(e) => setConfig({ ...config, workspacesDir: e.target.value })}
1130
1151
  />
1131
1152
  {defaultPaths && (
1132
- <div className="text-[10px] text-gray-500 mt-1.5 flex justify-between items-center">
1133
- <span>Suggested: <code>{defaultPaths.workspacesDir}</code></span>
1153
+ <div className="text-[10px] text-slate-500 mt-1.5 flex justify-between items-center">
1154
+ <span>Suggested: <code className="text-indigo-300">{defaultPaths.workspacesDir}</code></span>
1134
1155
  </div>
1135
1156
  )}
1136
1157
  </div>
@@ -1140,15 +1161,15 @@ Core Instructions:
1140
1161
  <input
1141
1162
  type="checkbox"
1142
1163
  id="onboardingPackContextXml"
1143
- className="w-4 h-4 rounded border-gray-800 bg-[#111827] text-indigo-600 focus:ring-indigo-500 cursor-pointer"
1164
+ className="w-4 h-4 rounded border-slate-800 bg-slate-950/60 text-indigo-650 focus:ring-indigo-500/50 cursor-pointer"
1144
1165
  checked={config.packContextXml || false}
1145
1166
  onChange={(e) => setConfig({ ...config, packContextXml: e.target.checked })}
1146
1167
  />
1147
- <label htmlFor="onboardingPackContextXml" className="text-xs font-semibold text-white cursor-pointer select-none">
1168
+ <label htmlFor="onboardingPackContextXml" className="text-xs font-semibold text-slate-200 cursor-pointer select-none">
1148
1169
  Pack Codebase Context with Repomix (XML)
1149
1170
  </label>
1150
1171
  </div>
1151
- <span className="text-[10px] text-gray-500 mt-1 block">
1172
+ <span className="text-[10px] text-slate-500 mt-1.5 block leading-normal">
1152
1173
  Aggregates all repository files into a single token-efficient XML file (<code>nexusflow-context.xml</code>) at the workspace root, giving AI assistants immediate access to the full codebase state.
1153
1174
  </span>
1154
1175
  </div>
@@ -1157,7 +1178,7 @@ Core Instructions:
1157
1178
  <div className="flex gap-2 pt-2">
1158
1179
  <button
1159
1180
  type="button"
1160
- className="flex-1 inline-flex items-center justify-center gap-1.5 px-3 py-2 bg-gray-900 border border-gray-800 hover:bg-gray-800 hover:border-gray-700 rounded-lg text-xs font-semibold transition-all cursor-pointer"
1181
+ className="flex-1 inline-flex items-center justify-center gap-1.5 px-3 py-2.5 bg-slate-900 border border-slate-800/80 hover:bg-indigo-500/5 hover:border-indigo-500/30 rounded-xl text-xs font-semibold transition-all cursor-pointer text-slate-300 hover:text-white"
1161
1182
  onClick={() => {
1162
1183
  if (defaultPaths) {
1163
1184
  setConfig({
@@ -1172,7 +1193,7 @@ Core Instructions:
1172
1193
  </button>
1173
1194
  <button
1174
1195
  type="button"
1175
- className="px-3 py-2 bg-gray-900 border border-gray-800 hover:bg-gray-800 hover:border-rose-900/60 hover:text-rose-400 rounded-lg text-xs font-semibold transition-all cursor-pointer"
1196
+ className="px-3 py-2.5 bg-slate-900 border border-slate-800/80 hover:bg-rose-500/5 hover:border-rose-500/30 hover:text-rose-400 rounded-xl text-xs font-semibold transition-all cursor-pointer text-slate-400"
1176
1197
  onClick={() => {
1177
1198
  setConfig({
1178
1199
  ...config,
@@ -1189,7 +1210,7 @@ Core Instructions:
1189
1210
  <div className="pt-4">
1190
1211
  <button
1191
1212
  type="button"
1192
- className="w-full inline-flex items-center justify-center gap-2 px-5 py-3 rounded-lg text-sm font-semibold bg-gradient-to-r from-indigo-500 to-indigo-600 hover:from-indigo-600 hover:to-indigo-700 text-white shadow-lg shadow-indigo-500/20 hover:-translate-y-0.5 active:translate-y-0 disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:translate-y-0 transition-all cursor-pointer"
1213
+ className="w-full inline-flex items-center justify-center gap-2 px-5 py-3.5 rounded-xl text-sm font-bold bg-gradient-to-r from-indigo-500 via-indigo-600 to-purple-650 hover:from-indigo-600 hover:to-purple-700 text-white shadow-lg shadow-indigo-500/20 hover:-translate-y-0.5 active:translate-y-0 disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:translate-y-0 transition-all cursor-pointer"
1193
1214
  disabled={!isFormValid}
1194
1215
  onClick={() => saveAppConfig(config)}
1195
1216
  >
@@ -1204,41 +1225,243 @@ Core Instructions:
1204
1225
  );
1205
1226
  }
1206
1227
 
1228
+ if (isVsCode) {
1229
+ return (
1230
+ <div className="flex flex-col h-screen w-full bg-[#060813] text-[#d1d5db] font-mono text-[11px] overflow-hidden select-none border-t border-gray-800">
1231
+ {/* Terminal Header */}
1232
+ <div className="flex items-center justify-between px-3 py-2 bg-[#0b0f19] border-b border-gray-800 shrink-0 text-[10px]">
1233
+ <div className="flex items-center gap-2">
1234
+ <span className="font-bold text-indigo-400">NEXUSFLOW_SHELL</span>
1235
+ <span className="text-gray-700">|</span>
1236
+ <span className="text-gray-300">ws: {activeWsId || 'none'}</span>
1237
+ </div>
1238
+ <div className="flex items-center gap-2">
1239
+ {activeWsId && (
1240
+ <button
1241
+ onClick={() => {
1242
+ setActiveWsId(null);
1243
+ setSelectedLogService(null);
1244
+ setServiceLogs('');
1245
+ }}
1246
+ className="text-indigo-400 hover:text-indigo-350 hover:underline transition-colors cursor-pointer bg-transparent border-none p-0 outline-none"
1247
+ >
1248
+ [Change WS]
1249
+ </button>
1250
+ )}
1251
+ <span className="text-[10px] text-gray-500">v{appVersion}</span>
1252
+ </div>
1253
+ </div>
1254
+
1255
+ {!activeWsId ? (
1256
+ /* CLI Workspace Selection Menu */
1257
+ <div className="flex-1 flex flex-col items-center justify-center p-6 text-center overflow-y-auto">
1258
+ <div className="text-indigo-400 font-bold mb-4 text-[12px] uppercase">
1259
+ === Select Active Workspace ===
1260
+ </div>
1261
+ <div className="flex flex-col gap-2 w-full max-w-xs">
1262
+ {workspaces.map((ws) => (
1263
+ <button
1264
+ key={ws.branchName}
1265
+ onClick={() => {
1266
+ setActiveWsId(ws.branchName);
1267
+ fetchWorkspaceServices(ws.branchName);
1268
+ }}
1269
+ className="w-full text-left p-2.5 bg-gray-950 border border-gray-800 hover:border-indigo-500 rounded hover:bg-indigo-500/5 text-gray-300 hover:text-white transition-all text-[11px] cursor-pointer"
1270
+ >
1271
+ &gt; {ws.branchName}
1272
+ </button>
1273
+ ))}
1274
+ {workspaces.length === 0 && (
1275
+ <div className="text-gray-550 italic">No workspaces found. Initialize one via the CLI.</div>
1276
+ )}
1277
+ </div>
1278
+ </div>
1279
+ ) : (
1280
+ /* Active Workspace Panel */
1281
+ <div className="flex-1 flex flex-col min-h-0">
1282
+ {/* Top Config / Control Panel */}
1283
+ <div className="p-3 border-b border-gray-800 shrink-0 bg-gray-950/30">
1284
+ {/* Service Control Buttons */}
1285
+ <div className="flex gap-2 mb-3">
1286
+ <button
1287
+ onClick={() => handleStartServices(activeWsId)}
1288
+ className="flex-1 inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded border border-emerald-500/20 bg-emerald-500/5 hover:bg-emerald-500/10 text-emerald-400 font-bold transition-all cursor-pointer text-[10px]"
1289
+ >
1290
+ <Play size={10} /> [START SERVICES]
1291
+ </button>
1292
+ <button
1293
+ onClick={() => handleStopServices(activeWsId)}
1294
+ className="flex-1 inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded border border-rose-500/20 bg-rose-500/5 hover:bg-rose-500/10 text-rose-400 font-bold transition-all cursor-pointer text-[10px]"
1295
+ >
1296
+ <X size={10} /> [STOP SERVICES]
1297
+ </button>
1298
+ </div>
1299
+
1300
+ {/* Service List */}
1301
+ <div className="mb-3">
1302
+ <div className="text-[10px] text-gray-400 uppercase font-bold tracking-wider mb-1 px-1">
1303
+ Background Services ({runningServices.filter(rs => rs.pid > 0).length}/{services.length})
1304
+ </div>
1305
+ {services.length === 0 ? (
1306
+ <div className="text-gray-600 italic px-1 text-[10px]">No services detected in workspace.</div>
1307
+ ) : (
1308
+ <div className="flex flex-col gap-1 max-h-[120px] overflow-y-auto pr-1">
1309
+ {services.map((service) => {
1310
+ const isRunning = runningServices.some((rs) => rs.name === service.name && rs.pid > 0);
1311
+ const isSelected = selectedLogService === service.name;
1312
+ return (
1313
+ <div
1314
+ key={service.name}
1315
+ onClick={() => setSelectedLogService(service.name)}
1316
+ className={`flex items-center justify-between p-1.5 border rounded cursor-pointer transition-all ${
1317
+ isSelected
1318
+ ? 'bg-indigo-950/40 border-indigo-500/50 text-white'
1319
+ : 'bg-gray-950/20 border-gray-800 hover:border-gray-700 text-gray-300'
1320
+ }`}
1321
+ >
1322
+ <div className="flex items-center gap-2 truncate">
1323
+ <span className={`h-1.5 w-1.5 rounded-full ${isRunning ? 'bg-emerald-400 animate-pulse' : 'bg-rose-500'}`}></span>
1324
+ <span className="font-bold truncate">{service.name}</span>
1325
+ </div>
1326
+ <span className="text-[10px] font-mono shrink-0">
1327
+ {isRunning ? (
1328
+ <span className="text-emerald-400 bg-emerald-500/10 px-1 py-0.2 rounded border border-emerald-500/20 text-[8px] font-bold uppercase">on</span>
1329
+ ) : (
1330
+ <span className="text-gray-500 bg-gray-900 px-1 py-0.2 rounded border border-gray-800 text-[8px] font-bold uppercase">off</span>
1331
+ )}
1332
+ </span>
1333
+ </div>
1334
+ );
1335
+ })}
1336
+ </div>
1337
+ )}
1338
+ </div>
1339
+
1340
+ {/* MCP Status Check */}
1341
+ <div className="mb-3 border-t border-gray-800 pt-2.5">
1342
+ <div className="text-[10px] text-gray-400 font-bold uppercase mb-1 px-1">
1343
+ Active Local MCP Tools
1344
+ </div>
1345
+ <div className="flex flex-col gap-1 px-1 text-[10px] text-gray-450 font-mono">
1346
+ <div className="flex justify-between">
1347
+ <span>• search_workspace</span>
1348
+ <span className="text-indigo-400 font-bold">READY</span>
1349
+ </div>
1350
+ <div className="flex justify-between">
1351
+ <span>• get_service_logs</span>
1352
+ <span className="text-indigo-400 font-bold">READY</span>
1353
+ </div>
1354
+ <div className="flex justify-between">
1355
+ <span>• delegate_to_local_agent</span>
1356
+ <span className={config?.localLlm?.enabled ? "text-indigo-400 font-bold" : "text-gray-600 font-bold"}>
1357
+ {config?.localLlm?.enabled ? 'READY' : 'DISABLED'}
1358
+ </span>
1359
+ </div>
1360
+ </div>
1361
+ </div>
1362
+
1363
+ {/* Interactive CLI Buttons */}
1364
+ <div className="border-t border-gray-800 pt-2.5">
1365
+ <div className="text-[10px] text-gray-400 font-bold uppercase mb-1.5 px-1">
1366
+ Terminal Commands (Click to Run)
1367
+ </div>
1368
+ <div className="grid grid-cols-2 gap-1.5">
1369
+ <button
1370
+ onClick={() => executeTerminal('nexusflow sync')}
1371
+ className="px-2 py-1.5 text-left border border-gray-850 hover:border-indigo-500 bg-gray-950/40 rounded text-gray-300 hover:text-white hover:bg-indigo-950/20 transition-all font-mono text-[9px] cursor-pointer"
1372
+ >
1373
+ $ nexusflow sync
1374
+ </button>
1375
+ <button
1376
+ onClick={() => executeTerminal('nexusflow diff')}
1377
+ className="px-2 py-1.5 text-left border border-gray-850 hover:border-indigo-500 bg-gray-950/40 rounded text-gray-300 hover:text-white hover:bg-indigo-950/20 transition-all font-mono text-[9px] cursor-pointer"
1378
+ >
1379
+ $ nexusflow diff
1380
+ </button>
1381
+ <button
1382
+ onClick={() => executeTerminal('nexusflow handoff')}
1383
+ className="px-2 py-1.5 text-left border border-gray-850 hover:border-indigo-500 bg-gray-950/40 rounded text-gray-300 hover:text-white hover:bg-indigo-950/20 transition-all font-mono text-[9px] cursor-pointer"
1384
+ >
1385
+ $ nexusflow handoff
1386
+ </button>
1387
+ <button
1388
+ onClick={() => executeTerminal('nexusflow status')}
1389
+ className="px-2 py-1.5 text-left border border-gray-850 hover:border-indigo-500 bg-gray-950/40 rounded text-gray-300 hover:text-white hover:bg-indigo-950/20 transition-all font-mono text-[9px] cursor-pointer"
1390
+ >
1391
+ $ nexusflow status
1392
+ </button>
1393
+ </div>
1394
+ </div>
1395
+ </div>
1396
+
1397
+ {/* Bottom Log Pane */}
1398
+ <div className="flex-1 flex flex-col min-h-0 bg-[#04060d]">
1399
+ <div className="flex items-center justify-between px-3 py-1.5 bg-[#090d1a] border-b border-gray-800/80 shrink-0 text-[9px] text-gray-400 uppercase tracking-wider font-bold">
1400
+ <div className="flex items-center gap-1.5">
1401
+ <span className="h-1.5 w-1.5 rounded-full bg-indigo-500 animate-pulse"></span>
1402
+ <span>log_stream: {selectedLogService || 'none'}</span>
1403
+ </div>
1404
+ <button
1405
+ onClick={() => {
1406
+ if (activeWsId && selectedLogService) {
1407
+ fetchLogs(activeWsId, selectedLogService);
1408
+ }
1409
+ }}
1410
+ className="text-gray-500 hover:text-white font-mono hover:underline cursor-pointer bg-transparent border-none p-0 outline-none"
1411
+ >
1412
+ [refresh]
1413
+ </button>
1414
+ </div>
1415
+ <div className="flex-1 p-3 overflow-y-auto font-mono text-[10px] leading-relaxed whitespace-pre-wrap select-text selection:bg-indigo-500/30 text-gray-300">
1416
+ {serviceLogs.trim() ? (
1417
+ serviceLogs
1418
+ ) : (
1419
+ <span className="text-gray-600 italic font-mono">(no logs recorded yet)</span>
1420
+ )}
1421
+ <div ref={logsEndRef} />
1422
+ </div>
1423
+ </div>
1424
+ </div>
1425
+ )}
1426
+ </div>
1427
+ );
1428
+ }
1429
+
1207
1430
  return (
1208
1431
  <div className="flex min-h-screen bg-[#060813] bg-gradient-to-br from-[#0c0f24] via-[#060813] to-[#04050a] text-gray-100 font-sans">
1209
1432
  {/* Sidebar Navigation */}
1210
- <aside className="w-64 bg-[#090d1a]/85 border-r border-gray-800/80 flex flex-col p-6 shrink-0 shadow-2xl backdrop-blur-md">
1433
+ <aside className="w-64 bg-slate-950/40 border-r border-slate-900 flex flex-col p-6 shrink-0 shadow-[0_0_50px_rgba(0,0,0,0.8)] backdrop-blur-xl relative z-10">
1211
1434
  <div className="flex items-center gap-3 mb-10 px-2">
1212
- <div className="w-9 h-9 bg-gradient-to-tr from-cyan-400 via-indigo-500 to-purple-600 rounded-lg flex items-center justify-center font-bold text-white shadow-lg shadow-indigo-500/25 text-lg">
1435
+ <div className="w-9 h-9 bg-gradient-to-tr from-cyan-400 via-indigo-500 to-purple-650 rounded-lg flex items-center justify-center font-extrabold text-white shadow-lg shadow-indigo-500/25 text-lg select-none">
1213
1436
  N
1214
1437
  </div>
1215
- <span className="text-xl font-bold tracking-tight bg-gradient-to-r from-white via-gray-200 to-gray-400 bg-clip-text text-transparent">
1438
+ <span className="text-xl font-bold tracking-tight bg-gradient-to-r from-white via-slate-200 to-slate-400 bg-clip-text text-transparent">
1216
1439
  NexusFlow
1217
1440
  </span>
1218
1441
  </div>
1219
1442
  <nav className="flex-1">
1220
- <ul className="flex flex-col gap-2">
1443
+ <ul className="flex flex-col gap-2.5">
1221
1444
  <li>
1222
1445
  <button
1223
- className={`w-full flex items-center gap-3 p-3 rounded-lg text-sm font-semibold transition-all cursor-pointer border ${
1446
+ className={`w-full flex items-center gap-3 p-3 rounded-xl text-sm font-semibold transition-all cursor-pointer border relative overflow-hidden group ${
1224
1447
  view === 'guide'
1225
- ? 'text-white bg-indigo-500/10 border-indigo-500/20 shadow-sm'
1226
- : 'text-gray-400 border-transparent hover:text-white hover:bg-gray-800/40'
1448
+ ? 'text-white bg-indigo-500/10 border-indigo-500/25 shadow-[0_0_20px_rgba(99,102,241,0.08)] before:absolute before:left-0 before:top-2 before:bottom-2 before:w-[3.5px] before:bg-indigo-500 before:rounded-r'
1449
+ : 'text-slate-400 border-transparent hover:text-white hover:bg-slate-900/40 hover:-translate-x-0.5'
1227
1450
  }`}
1228
1451
  onClick={() => {
1229
1452
  setView('guide');
1230
1453
  }}
1231
1454
  >
1232
- <Sparkles size={18} className="text-indigo-400" />
1455
+ <Sparkles size={18} className="text-indigo-400 group-hover:scale-110 transition-transform" />
1233
1456
  Getting Started
1234
1457
  </button>
1235
1458
  </li>
1236
1459
  <li>
1237
1460
  <button
1238
- className={`w-full flex items-center gap-3 p-3 rounded-lg text-sm font-semibold transition-all cursor-pointer border ${
1461
+ className={`w-full flex items-center gap-3 p-3 rounded-xl text-sm font-semibold transition-all cursor-pointer border relative overflow-hidden group ${
1239
1462
  view === 'create'
1240
- ? 'text-white bg-indigo-500/10 border-indigo-500/20 shadow-sm'
1241
- : 'text-gray-400 border-transparent hover:text-white hover:bg-gray-800/40'
1463
+ ? 'text-white bg-indigo-500/10 border-indigo-500/25 shadow-[0_0_20px_rgba(99,102,241,0.08)] before:absolute before:left-0 before:top-2 before:bottom-2 before:w-[3.5px] before:bg-indigo-500 before:rounded-r'
1464
+ : 'text-slate-400 border-transparent hover:text-white hover:bg-slate-900/40 hover:-translate-x-0.5'
1242
1465
  }`}
1243
1466
  onClick={() => {
1244
1467
  setView('create');
@@ -1250,45 +1473,45 @@ Core Instructions:
1250
1473
  setLocalLlmEnabled(config?.localLlm?.enabled || false);
1251
1474
  }}
1252
1475
  >
1253
- <PlusCircle size={18} className="text-indigo-400" />
1476
+ <PlusCircle size={18} className="text-indigo-400 group-hover:scale-110 transition-transform" />
1254
1477
  New Workspace
1255
1478
  </button>
1256
1479
  </li>
1257
1480
  <li>
1258
1481
  <button
1259
- className={`w-full flex items-center gap-3 p-3 rounded-lg text-sm font-semibold transition-all cursor-pointer border ${
1482
+ className={`w-full flex items-center gap-3 p-3 rounded-xl text-sm font-semibold transition-all cursor-pointer border relative overflow-hidden group ${
1260
1483
  view === 'workspaces'
1261
- ? 'text-white bg-indigo-500/10 border-indigo-500/20 shadow-sm'
1262
- : 'text-gray-400 border-transparent hover:text-white hover:bg-gray-800/40'
1484
+ ? 'text-white bg-indigo-500/10 border-indigo-500/25 shadow-[0_0_20px_rgba(99,102,241,0.08)] before:absolute before:left-0 before:top-2 before:bottom-2 before:w-[3.5px] before:bg-indigo-500 before:rounded-r'
1485
+ : 'text-slate-400 border-transparent hover:text-white hover:bg-slate-900/40 hover:-translate-x-0.5'
1263
1486
  }`}
1264
1487
  onClick={() => {
1265
1488
  setView('workspaces');
1266
1489
  fetchWorkspaces();
1267
1490
  }}
1268
1491
  >
1269
- <FolderGit2 size={18} className="text-indigo-400" />
1492
+ <FolderGit2 size={18} className="text-indigo-400 group-hover:scale-110 transition-transform" />
1270
1493
  Active Workspaces
1271
1494
  </button>
1272
1495
  </li>
1273
1496
  <li>
1274
1497
  <button
1275
- className={`w-full flex items-center gap-3 p-3 rounded-lg text-sm font-semibold transition-all cursor-pointer border ${
1498
+ className={`w-full flex items-center gap-3 p-3 rounded-xl text-sm font-semibold transition-all cursor-pointer border relative overflow-hidden group ${
1276
1499
  view === 'settings'
1277
- ? 'text-white bg-indigo-500/10 border-indigo-500/20 shadow-sm'
1278
- : 'text-gray-400 border-transparent hover:text-white hover:bg-gray-800/40'
1500
+ ? 'text-white bg-indigo-500/10 border-indigo-500/25 shadow-[0_0_20px_rgba(99,102,241,0.08)] before:absolute before:left-0 before:top-2 before:bottom-2 before:w-[3.5px] before:bg-indigo-500 before:rounded-r'
1501
+ : 'text-slate-400 border-transparent hover:text-white hover:bg-slate-900/40 hover:-translate-x-0.5'
1279
1502
  }`}
1280
1503
  onClick={() => {
1281
1504
  setView('settings');
1282
1505
  fetchConfig();
1283
1506
  }}
1284
1507
  >
1285
- <SettingsIcon size={18} className="text-indigo-400" />
1508
+ <SettingsIcon size={18} className="text-indigo-400 group-hover:scale-110 transition-transform" />
1286
1509
  Settings
1287
1510
  </button>
1288
1511
  </li>
1289
1512
  </ul>
1290
1513
  </nav>
1291
- <div className="pt-6 border-t border-gray-800/60 text-[11px] text-gray-500 text-center">
1514
+ <div className="pt-6 border-t border-slate-900 text-[10px] text-slate-500 text-center tracking-wider font-semibold uppercase">
1292
1515
  NexusFlow Engine v{appVersion}
1293
1516
  </div>
1294
1517
  </aside>
@@ -1975,6 +2198,7 @@ Core Instructions:
1975
2198
  handleCopyPrompt={handleCopyPrompt}
1976
2199
  handleOpenInEditor={handleOpenInEditor}
1977
2200
  fetchWorkspaces={fetchWorkspaces}
2201
+ aiAssistants={aiAssistants}
1978
2202
  repos={repos}
1979
2203
  deleteWsLoading={deleteWsLoading}
1980
2204
  addRepoLoading={addRepoLoading}