@mrpatronz/nexusflow 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/add-repo.d.ts +12 -0
- package/dist/commands/add-repo.d.ts.map +1 -0
- package/dist/commands/add-repo.js +126 -0
- package/dist/commands/add-repo.js.map +1 -0
- package/dist/commands/remove.d.ts +11 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +82 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/core/workspace.d.ts +20 -0
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +127 -1
- package/dist/core/workspace.js.map +1 -1
- package/dist/core/worktree.d.ts +3 -2
- package/dist/core/worktree.d.ts.map +1 -1
- package/dist/core/worktree.js +9 -3
- package/dist/core/worktree.js.map +1 -1
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +9 -0
- package/dist/generators/base.js.map +1 -1
- package/dist/gui/assets/index-C8W6FoPa.js +21 -0
- package/dist/gui/assets/index-CJn2LW8K.css +2 -0
- package/dist/gui/index.html +2 -2
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +70 -2
- package/dist/server.js.map +1 -1
- package/dist/utils/update-check.d.ts +11 -0
- package/dist/utils/update-check.d.ts.map +1 -1
- package/dist/utils/update-check.js +105 -0
- package/dist/utils/update-check.js.map +1 -1
- package/extension/package-lock.json +8 -8
- package/extension/package.json +1 -1
- package/gui/src/App.tsx +268 -6
- package/gui/src/features/workspace/WorkspaceList.tsx +58 -8
- package/package.json +1 -1
- package/src/commands/add-repo.ts +141 -0
- package/src/commands/remove.ts +90 -0
- package/src/core/workspace.ts +142 -2
- package/src/core/worktree.ts +10 -2
- package/src/generators/base.ts +9 -0
- package/src/index.ts +39 -0
- package/src/server.ts +73 -2
- package/src/utils/update-check.ts +116 -0
- package/dist/gui/assets/index-7IR7ZrSG.css +0 -2
- package/dist/gui/assets/index-BfNp4LNj.js +0 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/utils/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@types/glob": "^8.1.0",
|
|
12
12
|
"@types/mocha": "^10.0.1",
|
|
13
|
-
"@types/node": "
|
|
13
|
+
"@types/node": "25.x",
|
|
14
14
|
"@types/vscode": "^1.80.0",
|
|
15
15
|
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
|
16
16
|
"@typescript-eslint/parser": "^5.59.8",
|
|
@@ -196,13 +196,13 @@
|
|
|
196
196
|
"license": "MIT"
|
|
197
197
|
},
|
|
198
198
|
"node_modules/@types/node": {
|
|
199
|
-
"version": "
|
|
200
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-
|
|
201
|
-
"integrity": "sha512-
|
|
199
|
+
"version": "25.9.1",
|
|
200
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
|
|
201
|
+
"integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
|
|
202
202
|
"dev": true,
|
|
203
203
|
"license": "MIT",
|
|
204
204
|
"dependencies": {
|
|
205
|
-
"undici-types": "
|
|
205
|
+
"undici-types": ">=7.24.0 <7.24.7"
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
208
|
"node_modules/@types/semver": {
|
|
@@ -2614,9 +2614,9 @@
|
|
|
2614
2614
|
}
|
|
2615
2615
|
},
|
|
2616
2616
|
"node_modules/undici-types": {
|
|
2617
|
-
"version": "
|
|
2618
|
-
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-
|
|
2619
|
-
"integrity": "sha512-
|
|
2617
|
+
"version": "7.24.6",
|
|
2618
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
|
2619
|
+
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
|
2620
2620
|
"dev": true,
|
|
2621
2621
|
"license": "MIT"
|
|
2622
2622
|
},
|
package/extension/package.json
CHANGED
package/gui/src/App.tsx
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
Save,
|
|
26
26
|
Edit,
|
|
27
27
|
Download,
|
|
28
|
+
Trash2,
|
|
28
29
|
} from 'lucide-react';
|
|
29
30
|
import './App.css';
|
|
30
31
|
|
|
@@ -135,6 +136,10 @@ export default function App() {
|
|
|
135
136
|
{ id: 'pack', name: 'Pack Codebase Context', status: 'pending', message: 'Waiting...' },
|
|
136
137
|
]);
|
|
137
138
|
|
|
139
|
+
const [toolsStatus, setToolsStatus] = useState<any[]>([]);
|
|
140
|
+
const [toolsLoading, setToolsLoading] = useState(false);
|
|
141
|
+
const [updatingToolId, setUpdatingToolId] = useState<string | null>(null);
|
|
142
|
+
|
|
138
143
|
// Resumption Commands State
|
|
139
144
|
const [testCommand, setTestCommand] = useState('npm run test');
|
|
140
145
|
const [mockCommand, setMockCommand] = useState('');
|
|
@@ -187,6 +192,8 @@ export default function App() {
|
|
|
187
192
|
const [showCommitModal, setShowCommitModal] = useState<boolean>(false);
|
|
188
193
|
const [commitLoading, setCommitLoading] = useState<boolean>(false);
|
|
189
194
|
const [commitResults, setCommitResults] = useState<any[] | null>(null);
|
|
195
|
+
const [deleteWsLoading, setDeleteWsLoading] = useState<string | null>(null);
|
|
196
|
+
const [addRepoLoading, setAddRepoLoading] = useState<boolean>(false);
|
|
190
197
|
|
|
191
198
|
|
|
192
199
|
// Log Viewer
|
|
@@ -203,6 +210,13 @@ export default function App() {
|
|
|
203
210
|
fetchUpdateStatus();
|
|
204
211
|
}, []);
|
|
205
212
|
|
|
213
|
+
// Load tool updates status when settings view is open
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (view === 'settings') {
|
|
216
|
+
fetchToolsStatus();
|
|
217
|
+
}
|
|
218
|
+
}, [view]);
|
|
219
|
+
|
|
206
220
|
// Poll logs and services status when active workspace is open
|
|
207
221
|
useEffect(() => {
|
|
208
222
|
let interval: any = null;
|
|
@@ -285,6 +299,45 @@ export default function App() {
|
|
|
285
299
|
}
|
|
286
300
|
};
|
|
287
301
|
|
|
302
|
+
const fetchToolsStatus = async (force = false) => {
|
|
303
|
+
setToolsLoading(true);
|
|
304
|
+
try {
|
|
305
|
+
const res = await fetch(`${API_BASE}/api/updates/tools${force ? '?force=true' : ''}`);
|
|
306
|
+
if (res.ok) {
|
|
307
|
+
const data = await res.json();
|
|
308
|
+
setToolsStatus(data);
|
|
309
|
+
}
|
|
310
|
+
} catch (e) {
|
|
311
|
+
console.error('Failed to fetch tools status:', e);
|
|
312
|
+
} finally {
|
|
313
|
+
setToolsLoading(false);
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const handleUpdateTool = async (toolId: string) => {
|
|
318
|
+
setUpdatingToolId(toolId);
|
|
319
|
+
try {
|
|
320
|
+
const res = await fetch(`${API_BASE}/api/updates/install`, {
|
|
321
|
+
method: 'POST',
|
|
322
|
+
headers: { 'Content-Type': 'application/json' },
|
|
323
|
+
body: JSON.stringify({ toolId }),
|
|
324
|
+
});
|
|
325
|
+
const data = await res.json();
|
|
326
|
+
if (res.ok && data.success) {
|
|
327
|
+
alert(`${toolId} updated successfully!\n\nOutput:\n${data.output}`);
|
|
328
|
+
fetchToolsStatus(true);
|
|
329
|
+
fetchUpdateStatus();
|
|
330
|
+
} else {
|
|
331
|
+
alert(`Error: ${data.error || 'Failed to update tool'}`);
|
|
332
|
+
}
|
|
333
|
+
} catch (e) {
|
|
334
|
+
console.error(e);
|
|
335
|
+
alert('Network error when updating tool.');
|
|
336
|
+
} finally {
|
|
337
|
+
setUpdatingToolId(null);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
288
341
|
const fetchConfig = async () => {
|
|
289
342
|
try {
|
|
290
343
|
const res = await fetch(`${API_BASE}/api/config`);
|
|
@@ -778,6 +831,63 @@ Core Instructions:
|
|
|
778
831
|
alert('Universal AI briefing prompt copied to clipboard!');
|
|
779
832
|
};
|
|
780
833
|
|
|
834
|
+
const handleDeleteWorkspace = async (wsName: string) => {
|
|
835
|
+
if (!window.confirm(`Are you sure you want to delete the workspace "${wsName}"?\nThis will force remove all git worktrees inside it and delete all files in the folder.`)) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
setDeleteWsLoading(wsName);
|
|
839
|
+
try {
|
|
840
|
+
const encodedId = encodeURIComponent(wsName);
|
|
841
|
+
const res = await fetch(`${API_BASE}/api/workspace/${encodedId}`, {
|
|
842
|
+
method: 'DELETE',
|
|
843
|
+
});
|
|
844
|
+
const data = await res.json();
|
|
845
|
+
if (res.ok && data.success) {
|
|
846
|
+
if (activeWsId === wsName) {
|
|
847
|
+
setActiveWsId(null);
|
|
848
|
+
}
|
|
849
|
+
await fetchWorkspaces();
|
|
850
|
+
alert(`Workspace ${wsName} successfully deleted.`);
|
|
851
|
+
} else {
|
|
852
|
+
alert(`Failed to delete workspace: ${data.error || 'Unknown error'}`);
|
|
853
|
+
}
|
|
854
|
+
} catch (e) {
|
|
855
|
+
console.error(e);
|
|
856
|
+
alert('Network error while deleting workspace.');
|
|
857
|
+
} finally {
|
|
858
|
+
setDeleteWsLoading(null);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
const handleAddRepo = async (wsName: string, repoPath: string) => {
|
|
863
|
+
setAddRepoLoading(true);
|
|
864
|
+
try {
|
|
865
|
+
const encodedId = encodeURIComponent(wsName);
|
|
866
|
+
const res = await fetch(`${API_BASE}/api/workspace/${encodedId}/repo`, {
|
|
867
|
+
method: 'POST',
|
|
868
|
+
headers: { 'Content-Type': 'application/json' },
|
|
869
|
+
body: JSON.stringify({ repoPath }),
|
|
870
|
+
});
|
|
871
|
+
const data = await res.json();
|
|
872
|
+
if (res.ok && data.success) {
|
|
873
|
+
await fetchWorkspaces();
|
|
874
|
+
if (activeWsId === wsName) {
|
|
875
|
+
fetchWorkspaceServices(wsName, true);
|
|
876
|
+
fetchGitChanges(wsName);
|
|
877
|
+
fetchWorkspaceSessions(wsName);
|
|
878
|
+
}
|
|
879
|
+
alert('Repository successfully added. Configurations and Repomix packing updated.');
|
|
880
|
+
} else {
|
|
881
|
+
alert(`Failed to add repository: ${data.error || 'Unknown error'}`);
|
|
882
|
+
}
|
|
883
|
+
} catch (e) {
|
|
884
|
+
console.error(e);
|
|
885
|
+
alert('Network error while adding repository.');
|
|
886
|
+
} finally {
|
|
887
|
+
setAddRepoLoading(false);
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
|
|
781
891
|
const filteredRepos = repos.filter((r) =>
|
|
782
892
|
r.name.toLowerCase().includes(repoSearch.toLowerCase())
|
|
783
893
|
);
|
|
@@ -1177,6 +1287,18 @@ Core Instructions:
|
|
|
1177
1287
|
</p>
|
|
1178
1288
|
</div>
|
|
1179
1289
|
</div>
|
|
1290
|
+
|
|
1291
|
+
<div className="flex gap-4">
|
|
1292
|
+
<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">
|
|
1293
|
+
4
|
|
1294
|
+
</div>
|
|
1295
|
+
<div>
|
|
1296
|
+
<h3 className="text-sm font-semibold text-white">Repomix Packing</h3>
|
|
1297
|
+
<p className="text-xs text-gray-400 mt-1">
|
|
1298
|
+
NexusFlow aggregates the entire multi-repo codebase using <code>Repomix</code> into a token-efficient XML file <code>nexusflow-context.xml</code>, giving AI immediate access to the full codebase state.
|
|
1299
|
+
</p>
|
|
1300
|
+
</div>
|
|
1301
|
+
</div>
|
|
1180
1302
|
</div>
|
|
1181
1303
|
|
|
1182
1304
|
{/* Right: Quick actions and Telemetry info */}
|
|
@@ -1783,6 +1905,14 @@ Core Instructions:
|
|
|
1783
1905
|
>
|
|
1784
1906
|
{isExpanded ? 'Hide Runner' : 'Orchestrate'}
|
|
1785
1907
|
</button>
|
|
1908
|
+
<button
|
|
1909
|
+
className="inline-flex items-center justify-center gap-1.5 px-3.5 py-2 bg-red-950/40 border border-red-900/60 hover:bg-red-900/60 hover:border-red-800 rounded-lg text-xs font-semibold text-red-200 transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed animate-fade-in"
|
|
1910
|
+
onClick={() => handleDeleteWorkspace(ws.branchName)}
|
|
1911
|
+
disabled={deleteWsLoading === ws.branchName}
|
|
1912
|
+
>
|
|
1913
|
+
<Trash2 size={12} className={deleteWsLoading === ws.branchName ? 'animate-spin' : ''} />
|
|
1914
|
+
{deleteWsLoading === ws.branchName ? 'Deleting...' : 'Delete'}
|
|
1915
|
+
</button>
|
|
1786
1916
|
</div>
|
|
1787
1917
|
</div>
|
|
1788
1918
|
|
|
@@ -1790,12 +1920,42 @@ Core Instructions:
|
|
|
1790
1920
|
{ws.description}
|
|
1791
1921
|
</p>
|
|
1792
1922
|
|
|
1793
|
-
<div className="flex
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
{repoPath
|
|
1797
|
-
|
|
1798
|
-
|
|
1923
|
+
<div className="flex items-center gap-3 mb-4">
|
|
1924
|
+
<div className="flex flex-wrap gap-2">
|
|
1925
|
+
{ws.repos.map((repoPath) => (
|
|
1926
|
+
<span key={repoPath} className="text-[10px] px-2.5 py-1 bg-gray-900 border border-gray-800 text-gray-300 rounded-md font-semibold">
|
|
1927
|
+
{repoPath.split(/[\\/]/).pop()}
|
|
1928
|
+
</span>
|
|
1929
|
+
))}
|
|
1930
|
+
</div>
|
|
1931
|
+
|
|
1932
|
+
{repos.filter((r) => !ws.repos.includes(r.path)).length > 0 && (
|
|
1933
|
+
<div className="flex items-center gap-1.5 ml-auto">
|
|
1934
|
+
<select
|
|
1935
|
+
id={`add-repo-select-${ws.branchName}`}
|
|
1936
|
+
className="bg-gray-900 border border-gray-800 text-gray-300 rounded-md text-[10px] px-2 py-1 font-semibold outline-none focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
|
|
1937
|
+
defaultValue=""
|
|
1938
|
+
onChange={async (e) => {
|
|
1939
|
+
const val = e.target.value;
|
|
1940
|
+
if (val) {
|
|
1941
|
+
if (window.confirm(`Are you sure you want to add repository "${val.split(/[\\/]/).pop()}" to this workspace?\nThis will create a new git worktree and re-run analysis.`)) {
|
|
1942
|
+
await handleAddRepo(ws.branchName, val);
|
|
1943
|
+
}
|
|
1944
|
+
e.target.value = "";
|
|
1945
|
+
}
|
|
1946
|
+
}}
|
|
1947
|
+
disabled={addRepoLoading}
|
|
1948
|
+
>
|
|
1949
|
+
<option value="" disabled>+ Add Repository</option>
|
|
1950
|
+
{repos
|
|
1951
|
+
.filter((r) => !ws.repos.includes(r.path))
|
|
1952
|
+
.map((r) => (
|
|
1953
|
+
<option key={r.path} value={r.path}>{r.name}</option>
|
|
1954
|
+
))
|
|
1955
|
+
}
|
|
1956
|
+
</select>
|
|
1957
|
+
</div>
|
|
1958
|
+
)}
|
|
1799
1959
|
</div>
|
|
1800
1960
|
|
|
1801
1961
|
{/* Expansion: Process management console */}
|
|
@@ -2407,6 +2567,108 @@ Core Instructions:
|
|
|
2407
2567
|
Save Configuration
|
|
2408
2568
|
</button>
|
|
2409
2569
|
</div>
|
|
2570
|
+
|
|
2571
|
+
{/* Toolchain Updates Section */}
|
|
2572
|
+
<div className="bg-[#111827]/40 border border-gray-800/80 rounded-xl p-8 shadow-xl backdrop-blur-sm mt-6">
|
|
2573
|
+
<div className="flex justify-between items-center mb-6">
|
|
2574
|
+
<div>
|
|
2575
|
+
<h3 className="text-lg font-bold text-white mb-1">AI Toolchain Updates</h3>
|
|
2576
|
+
<p className="text-xs text-gray-555">Monitor and update CLI packages and assistants in your workflow.</p>
|
|
2577
|
+
</div>
|
|
2578
|
+
<button
|
|
2579
|
+
onClick={() => fetchToolsStatus(true)}
|
|
2580
|
+
disabled={toolsLoading}
|
|
2581
|
+
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-gray-800 hover:border-gray-700 bg-gray-950/20 text-xs font-semibold text-white transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
|
|
2582
|
+
>
|
|
2583
|
+
<RefreshCw size={13} className={toolsLoading ? 'animate-spin' : ''} />
|
|
2584
|
+
{toolsLoading ? 'Checking...' : 'Check Now'}
|
|
2585
|
+
</button>
|
|
2586
|
+
</div>
|
|
2587
|
+
|
|
2588
|
+
{toolsLoading && toolsStatus.length === 0 ? (
|
|
2589
|
+
<div className="flex flex-col items-center justify-center py-8 gap-2 text-gray-400">
|
|
2590
|
+
<RefreshCw className="animate-spin text-indigo-400" size={24} />
|
|
2591
|
+
<span className="text-xs">Fetching registry version details...</span>
|
|
2592
|
+
</div>
|
|
2593
|
+
) : (
|
|
2594
|
+
<div className="space-y-4">
|
|
2595
|
+
{toolsStatus.map((tool) => (
|
|
2596
|
+
<div key={tool.id} className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 p-4 border border-gray-800/60 rounded-xl bg-gray-950/10">
|
|
2597
|
+
<div className="min-w-0">
|
|
2598
|
+
<h4 className="text-sm font-bold text-white flex items-center gap-2">
|
|
2599
|
+
{tool.name}
|
|
2600
|
+
<span className={`text-[9px] px-2 py-0.5 rounded font-semibold uppercase ${
|
|
2601
|
+
tool.installed ? 'bg-emerald-500/10 text-emerald-400' : 'bg-gray-800 text-gray-500'
|
|
2602
|
+
}`}>
|
|
2603
|
+
{tool.installed ? 'Installed' : 'Not Installed'}
|
|
2604
|
+
</span>
|
|
2605
|
+
</h4>
|
|
2606
|
+
<div className="flex items-center gap-4 mt-1.5 text-xs text-gray-500">
|
|
2607
|
+
<span>Installed version: <code className="text-gray-300 font-mono text-[10px]">{tool.currentVersion}</code></span>
|
|
2608
|
+
{tool.installed && (
|
|
2609
|
+
<span>Latest: <code className="text-gray-300 font-mono text-[10px]">{tool.latestVersion}</code></span>
|
|
2610
|
+
)}
|
|
2611
|
+
</div>
|
|
2612
|
+
<p className="text-[10px] text-gray-600 mt-1 font-mono">{tool.updateCmd}</p>
|
|
2613
|
+
</div>
|
|
2614
|
+
|
|
2615
|
+
<div className="shrink-0 flex items-center gap-3">
|
|
2616
|
+
{tool.updateAvailable ? (
|
|
2617
|
+
<button
|
|
2618
|
+
onClick={() => handleUpdateTool(tool.id)}
|
|
2619
|
+
disabled={updatingToolId !== null}
|
|
2620
|
+
className="px-3.5 py-2 bg-gradient-to-r from-amber-500 to-amber-600 hover:from-amber-600 hover:to-amber-700 text-[#060813] font-bold text-xs rounded-lg transition-all shadow-md shadow-amber-500/10 cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed flex items-center gap-1.5"
|
|
2621
|
+
>
|
|
2622
|
+
{updatingToolId === tool.id ? (
|
|
2623
|
+
<>
|
|
2624
|
+
<RefreshCw className="animate-spin" size={12} /> Updating...
|
|
2625
|
+
</>
|
|
2626
|
+
) : (
|
|
2627
|
+
<>
|
|
2628
|
+
<Sparkles size={12} /> Update Tool
|
|
2629
|
+
</>
|
|
2630
|
+
)}
|
|
2631
|
+
</button>
|
|
2632
|
+
) : tool.installed ? (
|
|
2633
|
+
<div className="flex items-center gap-2">
|
|
2634
|
+
<span className="text-xs font-semibold text-emerald-400 flex items-center gap-1.5 bg-emerald-500/5 px-2.5 py-1.5 rounded-lg border border-emerald-500/10">
|
|
2635
|
+
<Check size={12} /> Up to Date
|
|
2636
|
+
</span>
|
|
2637
|
+
<button
|
|
2638
|
+
onClick={() => handleUpdateTool(tool.id)}
|
|
2639
|
+
disabled={updatingToolId !== null}
|
|
2640
|
+
className="px-3.5 py-2 bg-gray-900 border border-gray-800 hover:bg-gray-800 hover:border-gray-750 text-gray-300 font-bold text-xs rounded-lg transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed flex items-center gap-1.5"
|
|
2641
|
+
>
|
|
2642
|
+
{updatingToolId === tool.id ? (
|
|
2643
|
+
<>
|
|
2644
|
+
<RefreshCw className="animate-spin" size={12} /> Reinstalling...
|
|
2645
|
+
</>
|
|
2646
|
+
) : (
|
|
2647
|
+
'Reinstall'
|
|
2648
|
+
)}
|
|
2649
|
+
</button>
|
|
2650
|
+
</div>
|
|
2651
|
+
) : (
|
|
2652
|
+
<button
|
|
2653
|
+
onClick={() => handleUpdateTool(tool.id)}
|
|
2654
|
+
disabled={updatingToolId !== null}
|
|
2655
|
+
className="px-3.5 py-2 bg-gray-900 border border-gray-800 hover:bg-gray-800 hover:border-gray-700 text-white font-bold text-xs rounded-lg transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
|
|
2656
|
+
>
|
|
2657
|
+
{updatingToolId === tool.id ? (
|
|
2658
|
+
<>
|
|
2659
|
+
<RefreshCw className="animate-spin" size={12} /> Installing...
|
|
2660
|
+
</>
|
|
2661
|
+
) : (
|
|
2662
|
+
'Install CLI'
|
|
2663
|
+
)}
|
|
2664
|
+
</button>
|
|
2665
|
+
)}
|
|
2666
|
+
</div>
|
|
2667
|
+
</div>
|
|
2668
|
+
))}
|
|
2669
|
+
</div>
|
|
2670
|
+
)}
|
|
2671
|
+
</div>
|
|
2410
2672
|
</div>
|
|
2411
2673
|
)}
|
|
2412
2674
|
</>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Play, RefreshCw, FolderGit2, Sparkles, ExternalLink } from 'lucide-react';
|
|
3
|
-
import type { Feature, RunningService, ServiceConfig, OrchestrationDetection } from '../../types.js';
|
|
2
|
+
import { Play, RefreshCw, FolderGit2, Sparkles, ExternalLink, Trash2 } from 'lucide-react';
|
|
3
|
+
import type { Feature, RunningService, ServiceConfig, OrchestrationDetection, RepoInfo } from '../../types.js';
|
|
4
4
|
|
|
5
5
|
// Feature subcomponents
|
|
6
6
|
import { SessionHistory } from '../sessions/SessionHistory.js';
|
|
@@ -20,6 +20,13 @@ interface WorkspaceListProps {
|
|
|
20
20
|
handleOpenInEditor: (workspacePath: string) => Promise<void>;
|
|
21
21
|
fetchWorkspaces: () => Promise<void>;
|
|
22
22
|
|
|
23
|
+
// Deletion and repo addition props
|
|
24
|
+
repos: RepoInfo[];
|
|
25
|
+
deleteWsLoading: string | null;
|
|
26
|
+
addRepoLoading: boolean;
|
|
27
|
+
handleDeleteWorkspace: (wsName: string) => Promise<void>;
|
|
28
|
+
handleAddRepo: (wsName: string, repoPath: string) => Promise<void>;
|
|
29
|
+
|
|
23
30
|
// ServiceConsole props
|
|
24
31
|
services: ServiceConfig[];
|
|
25
32
|
runningServices: RunningService[];
|
|
@@ -89,6 +96,11 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
|
|
|
89
96
|
handleCopyPrompt,
|
|
90
97
|
handleOpenInEditor,
|
|
91
98
|
fetchWorkspaces,
|
|
99
|
+
repos,
|
|
100
|
+
deleteWsLoading,
|
|
101
|
+
addRepoLoading,
|
|
102
|
+
handleDeleteWorkspace,
|
|
103
|
+
handleAddRepo,
|
|
92
104
|
|
|
93
105
|
// ServiceConsole
|
|
94
106
|
services,
|
|
@@ -225,6 +237,14 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
|
|
|
225
237
|
>
|
|
226
238
|
{isExpanded ? 'Hide Runner' : 'Orchestrate'}
|
|
227
239
|
</button>
|
|
240
|
+
<button
|
|
241
|
+
className="inline-flex items-center justify-center gap-1.5 px-3.5 py-2 bg-red-950/40 border border-red-900/60 hover:bg-red-900/60 hover:border-red-800 rounded-lg text-xs font-semibold text-red-200 transition-all cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed animate-fade-in"
|
|
242
|
+
onClick={() => handleDeleteWorkspace(ws.branchName)}
|
|
243
|
+
disabled={deleteWsLoading === ws.branchName}
|
|
244
|
+
>
|
|
245
|
+
<Trash2 size={12} className={deleteWsLoading === ws.branchName ? 'animate-spin' : ''} />
|
|
246
|
+
{deleteWsLoading === ws.branchName ? 'Deleting...' : 'Delete'}
|
|
247
|
+
</button>
|
|
228
248
|
</div>
|
|
229
249
|
</div>
|
|
230
250
|
|
|
@@ -232,12 +252,42 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
|
|
|
232
252
|
{ws.description}
|
|
233
253
|
</p>
|
|
234
254
|
|
|
235
|
-
<div className="flex
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
{repoPath
|
|
239
|
-
|
|
240
|
-
|
|
255
|
+
<div className="flex items-center gap-3 mb-4">
|
|
256
|
+
<div className="flex flex-wrap gap-2">
|
|
257
|
+
{ws.repos.map((repoPath) => (
|
|
258
|
+
<span key={repoPath} className="text-[10px] px-2.5 py-1 bg-gray-900 border border-gray-800 text-gray-300 rounded-md font-semibold">
|
|
259
|
+
{repoPath.split(/[\\/]/).pop()}
|
|
260
|
+
</span>
|
|
261
|
+
))}
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
{repos.filter((r) => !ws.repos.includes(r.path)).length > 0 && (
|
|
265
|
+
<div className="flex items-center gap-1.5 ml-auto">
|
|
266
|
+
<select
|
|
267
|
+
id={`add-repo-select-feature-${ws.branchName}`}
|
|
268
|
+
className="bg-gray-900 border border-gray-800 text-gray-300 rounded-md text-[10px] px-2 py-1 font-semibold outline-none focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
|
|
269
|
+
defaultValue=""
|
|
270
|
+
onChange={async (e) => {
|
|
271
|
+
const val = e.target.value;
|
|
272
|
+
if (val) {
|
|
273
|
+
if (window.confirm(`Are you sure you want to add repository "${val.split(/[\\/]/).pop()}" to this workspace?\nThis will create a new git worktree and re-run analysis.`)) {
|
|
274
|
+
await handleAddRepo(ws.branchName, val);
|
|
275
|
+
}
|
|
276
|
+
e.target.value = "";
|
|
277
|
+
}
|
|
278
|
+
}}
|
|
279
|
+
disabled={addRepoLoading}
|
|
280
|
+
>
|
|
281
|
+
<option value="" disabled>+ Add Repository</option>
|
|
282
|
+
{repos
|
|
283
|
+
.filter((r) => !ws.repos.includes(r.path))
|
|
284
|
+
.map((r) => (
|
|
285
|
+
<option key={r.path} value={r.path}>{r.name}</option>
|
|
286
|
+
))
|
|
287
|
+
}
|
|
288
|
+
</select>
|
|
289
|
+
</div>
|
|
290
|
+
)}
|
|
241
291
|
</div>
|
|
242
292
|
|
|
243
293
|
{/* Expansion: Process management console */}
|
package/package.json
CHANGED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/add-repo
|
|
3
|
+
* Adds a repository to an existing NexusFlow workspace.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import { select } from '@inquirer/prompts';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
|
|
11
|
+
import { loadConfig } from '../core/config.js';
|
|
12
|
+
import { scanForRepos } from '../core/scanner.js';
|
|
13
|
+
import { listWorkspaces, loadFeatureConfig, addRepoToWorkspace } from '../core/workspace.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Executes the add-repo command.
|
|
17
|
+
*
|
|
18
|
+
* @param repoPathArg - Optional repository path to add.
|
|
19
|
+
* @param workspaceArg - Optional workspace path or name.
|
|
20
|
+
*/
|
|
21
|
+
export async function addRepoCommand(
|
|
22
|
+
repoPathArg?: string,
|
|
23
|
+
workspaceArg?: string,
|
|
24
|
+
): Promise<void> {
|
|
25
|
+
console.log(chalk.bold.cyan('\n➕ NexusFlow — Adding Repository to Workspace\n'));
|
|
26
|
+
|
|
27
|
+
const config = await loadConfig();
|
|
28
|
+
|
|
29
|
+
// 1. Resolve workspace
|
|
30
|
+
let workspacePath: string | null = null;
|
|
31
|
+
let workspaceName = '';
|
|
32
|
+
|
|
33
|
+
if (workspaceArg) {
|
|
34
|
+
const resolvedPath = path.isAbsolute(workspaceArg)
|
|
35
|
+
? workspaceArg
|
|
36
|
+
: path.resolve(config.workspacesDir, workspaceArg);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const manifest = await loadFeatureConfig(resolvedPath);
|
|
40
|
+
if (manifest) {
|
|
41
|
+
workspacePath = resolvedPath;
|
|
42
|
+
workspaceName = manifest.branchName;
|
|
43
|
+
}
|
|
44
|
+
} catch {}
|
|
45
|
+
|
|
46
|
+
if (!workspacePath) {
|
|
47
|
+
const directPath = path.join(config.workspacesDir, workspaceArg);
|
|
48
|
+
const manifest = await loadFeatureConfig(directPath);
|
|
49
|
+
if (manifest) {
|
|
50
|
+
workspacePath = directPath;
|
|
51
|
+
workspaceName = manifest.branchName;
|
|
52
|
+
} else {
|
|
53
|
+
console.error(chalk.red(`✖ Invalid workspace: No nexusflow.json found at ${workspaceArg}`));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
59
|
+
if (cwdFeature) {
|
|
60
|
+
workspacePath = process.cwd();
|
|
61
|
+
workspaceName = cwdFeature.branchName;
|
|
62
|
+
} else {
|
|
63
|
+
const workspaces = await listWorkspaces(config.workspacesDir);
|
|
64
|
+
if (workspaces.length === 0) {
|
|
65
|
+
console.log(chalk.yellow('No workspaces found.\n'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const selected = await select({
|
|
70
|
+
message: 'Select a workspace to add a repository to:',
|
|
71
|
+
choices: workspaces.map((ws) => ({
|
|
72
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
|
|
73
|
+
value: ws,
|
|
74
|
+
})),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
workspacePath = selected.workspacePath;
|
|
78
|
+
workspaceName = selected.branchName;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!workspacePath) return;
|
|
83
|
+
|
|
84
|
+
const feature = await loadFeatureConfig(workspacePath);
|
|
85
|
+
if (!feature) {
|
|
86
|
+
console.error(chalk.red('✖ Failed to load workspace configuration.'));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 2. Resolve repository to add
|
|
91
|
+
let repoPathToAdd = '';
|
|
92
|
+
|
|
93
|
+
if (repoPathArg) {
|
|
94
|
+
repoPathToAdd = path.resolve(repoPathArg);
|
|
95
|
+
} else {
|
|
96
|
+
const scanSpinner = ora('Scanning for projects...').start();
|
|
97
|
+
let repos = [];
|
|
98
|
+
try {
|
|
99
|
+
repos = await scanForRepos(config.devDir, config.scanDepth);
|
|
100
|
+
scanSpinner.succeed(`Found ${chalk.bold(repos.length)} projects in ${config.devDir}`);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
scanSpinner.fail('Failed to scan for projects');
|
|
103
|
+
console.error(error);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const availableRepos = repos.filter(
|
|
108
|
+
(r) => !feature.repos.includes(r.path)
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (availableRepos.length === 0) {
|
|
112
|
+
console.log(chalk.yellow('All scanned repositories are already in the workspace.\n'));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
repoPathToAdd = await select({
|
|
117
|
+
message: 'Select a repository to add:',
|
|
118
|
+
choices: availableRepos.map((r) => ({
|
|
119
|
+
name: `${r.name} ${chalk.dim(`(${r.path})`)}`,
|
|
120
|
+
value: r.path,
|
|
121
|
+
})),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const repoName = path.basename(repoPathToAdd);
|
|
126
|
+
const spinner = ora(`Adding ${repoName} to workspace ${workspaceName}...`).start();
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
await addRepoToWorkspace(workspacePath, repoPathToAdd);
|
|
130
|
+
spinner.succeed(`Successfully added ${chalk.bold(repoName)} to workspace ${chalk.bold(workspaceName)}`);
|
|
131
|
+
console.log(chalk.dim(' - Checked out git worktree'));
|
|
132
|
+
console.log(chalk.dim(' - Updated nexusflow.json and .gitignore'));
|
|
133
|
+
console.log(chalk.dim(' - Re-analyzed workspace codebases'));
|
|
134
|
+
console.log(chalk.dim(' - Regenerated LLM instruction context files'));
|
|
135
|
+
console.log(chalk.dim(' - Repacked codebase context using Repomix'));
|
|
136
|
+
console.log();
|
|
137
|
+
} catch (error) {
|
|
138
|
+
spinner.fail(`Failed to add repository: ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
console.log();
|
|
140
|
+
}
|
|
141
|
+
}
|