@mrpatronz/nexusflow 0.2.19 → 1.3.1

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 (294) hide show
  1. package/README.md +37 -7
  2. package/dist/analyzers/index.d.ts +23 -0
  3. package/dist/analyzers/index.d.ts.map +1 -1
  4. package/dist/analyzers/index.js +62 -0
  5. package/dist/analyzers/index.js.map +1 -1
  6. package/dist/commands/add-repo.d.ts +9 -0
  7. package/dist/commands/add-repo.d.ts.map +1 -1
  8. package/dist/commands/add-repo.js +12 -1
  9. package/dist/commands/add-repo.js.map +1 -1
  10. package/dist/commands/add-repo.test.d.ts +2 -0
  11. package/dist/commands/add-repo.test.d.ts.map +1 -0
  12. package/dist/commands/add-repo.test.js +30 -0
  13. package/dist/commands/add-repo.test.js.map +1 -0
  14. package/dist/commands/commands.test.js +26 -6
  15. package/dist/commands/commands.test.js.map +1 -1
  16. package/dist/commands/commit.d.ts +7 -1
  17. package/dist/commands/commit.d.ts.map +1 -1
  18. package/dist/commands/commit.js +31 -8
  19. package/dist/commands/commit.js.map +1 -1
  20. package/dist/commands/commit.test.d.ts +2 -0
  21. package/dist/commands/commit.test.d.ts.map +1 -0
  22. package/dist/commands/commit.test.js +54 -0
  23. package/dist/commands/commit.test.js.map +1 -0
  24. package/dist/commands/diff.d.ts +9 -2
  25. package/dist/commands/diff.d.ts.map +1 -1
  26. package/dist/commands/diff.js +36 -12
  27. package/dist/commands/diff.js.map +1 -1
  28. package/dist/commands/doctor.d.ts.map +1 -1
  29. package/dist/commands/doctor.js +16 -20
  30. package/dist/commands/doctor.js.map +1 -1
  31. package/dist/commands/handoff.d.ts.map +1 -1
  32. package/dist/commands/handoff.js +11 -15
  33. package/dist/commands/handoff.js.map +1 -1
  34. package/dist/commands/refresh.d.ts +4 -2
  35. package/dist/commands/refresh.d.ts.map +1 -1
  36. package/dist/commands/refresh.js +20 -36
  37. package/dist/commands/refresh.js.map +1 -1
  38. package/dist/commands/schedule.d.ts +35 -0
  39. package/dist/commands/schedule.d.ts.map +1 -0
  40. package/dist/commands/schedule.js +151 -0
  41. package/dist/commands/schedule.js.map +1 -0
  42. package/dist/commands/sync.d.ts.map +1 -1
  43. package/dist/commands/sync.js +28 -7
  44. package/dist/commands/sync.js.map +1 -1
  45. package/dist/commands/tui.js +1 -1
  46. package/dist/commands/tui.js.map +1 -1
  47. package/dist/commands/ui.d.ts +1 -0
  48. package/dist/commands/ui.d.ts.map +1 -1
  49. package/dist/commands/ui.js +5 -2
  50. package/dist/commands/ui.js.map +1 -1
  51. package/dist/core/adapters/local-storage.d.ts +7 -0
  52. package/dist/core/adapters/local-storage.d.ts.map +1 -1
  53. package/dist/core/adapters/local-storage.js +13 -4
  54. package/dist/core/adapters/local-storage.js.map +1 -1
  55. package/dist/core/adapters/storage.test.js +18 -0
  56. package/dist/core/adapters/storage.test.js.map +1 -1
  57. package/dist/core/analysis-cache.d.ts +58 -0
  58. package/dist/core/analysis-cache.d.ts.map +1 -0
  59. package/dist/core/analysis-cache.js +116 -0
  60. package/dist/core/analysis-cache.js.map +1 -0
  61. package/dist/core/analysis-cache.test.d.ts +2 -0
  62. package/dist/core/analysis-cache.test.d.ts.map +1 -0
  63. package/dist/core/analysis-cache.test.js +108 -0
  64. package/dist/core/analysis-cache.test.js.map +1 -0
  65. package/dist/core/refresh.d.ts +41 -0
  66. package/dist/core/refresh.d.ts.map +1 -0
  67. package/dist/core/refresh.js +56 -0
  68. package/dist/core/refresh.js.map +1 -0
  69. package/dist/core/scheduler.d.ts +117 -0
  70. package/dist/core/scheduler.d.ts.map +1 -0
  71. package/dist/core/scheduler.js +361 -0
  72. package/dist/core/scheduler.js.map +1 -0
  73. package/dist/core/scheduler.test.d.ts +2 -0
  74. package/dist/core/scheduler.test.d.ts.map +1 -0
  75. package/dist/core/scheduler.test.js +163 -0
  76. package/dist/core/scheduler.test.js.map +1 -0
  77. package/dist/core/sync.d.ts +6 -0
  78. package/dist/core/sync.d.ts.map +1 -1
  79. package/dist/core/sync.js +17 -12
  80. package/dist/core/sync.js.map +1 -1
  81. package/dist/core/workspace.d.ts +6 -0
  82. package/dist/core/workspace.d.ts.map +1 -1
  83. package/dist/core/workspace.js +32 -15
  84. package/dist/core/workspace.js.map +1 -1
  85. package/dist/core/workspace.test.d.ts +2 -0
  86. package/dist/core/workspace.test.d.ts.map +1 -0
  87. package/dist/core/workspace.test.js +42 -0
  88. package/dist/core/workspace.test.js.map +1 -0
  89. package/dist/generators/index.d.ts +7 -1
  90. package/dist/generators/index.d.ts.map +1 -1
  91. package/dist/generators/index.js +14 -1
  92. package/dist/generators/index.js.map +1 -1
  93. package/dist/generators/map-generator.d.ts.map +1 -1
  94. package/dist/generators/map-generator.js +4 -3
  95. package/dist/generators/map-generator.js.map +1 -1
  96. package/dist/generators/map-generator.test.js +4 -2
  97. package/dist/generators/map-generator.test.js.map +1 -1
  98. package/dist/gui/assets/index-ElroPpSP.js +26 -0
  99. package/dist/gui/index.html +1 -1
  100. package/dist/index.js +108 -4
  101. package/dist/index.js.map +1 -1
  102. package/dist/orchestration/index.d.ts +1 -1
  103. package/dist/orchestration/index.d.ts.map +1 -1
  104. package/dist/orchestration/index.js +1 -1
  105. package/dist/orchestration/index.js.map +1 -1
  106. package/dist/orchestration/runner.d.ts +16 -1
  107. package/dist/orchestration/runner.d.ts.map +1 -1
  108. package/dist/orchestration/runner.js +41 -5
  109. package/dist/orchestration/runner.js.map +1 -1
  110. package/dist/orchestration/runner.test.d.ts +2 -0
  111. package/dist/orchestration/runner.test.d.ts.map +1 -0
  112. package/dist/orchestration/runner.test.js +71 -0
  113. package/dist/orchestration/runner.test.js.map +1 -0
  114. package/dist/server.d.ts +17 -1
  115. package/dist/server.d.ts.map +1 -1
  116. package/dist/server.js +275 -114
  117. package/dist/server.js.map +1 -1
  118. package/dist/server.test.js +158 -1
  119. package/dist/server.test.js.map +1 -1
  120. package/dist/utils/multi-git.d.ts +21 -0
  121. package/dist/utils/multi-git.d.ts.map +1 -1
  122. package/dist/utils/multi-git.js +40 -4
  123. package/dist/utils/multi-git.js.map +1 -1
  124. package/dist/utils/prompts.d.ts.map +1 -1
  125. package/dist/utils/prompts.js +8 -2
  126. package/dist/utils/prompts.js.map +1 -1
  127. package/package.json +13 -1
  128. package/.agents/skills/ccc/SKILL.md +0 -71
  129. package/.agents/skills/ccc/references/management.md +0 -110
  130. package/.agents/skills/ccc/references/settings.md +0 -126
  131. package/.github/dependabot.yml +0 -52
  132. package/.github/workflows/ci.yml +0 -44
  133. package/.github/workflows/dependabot-merge.yml +0 -53
  134. package/.github/workflows/release-desktop.yml +0 -67
  135. package/.github/workflows/release-npm.yml +0 -65
  136. package/.github/workflows/release-vscode.yml +0 -61
  137. package/.vscode/launch.json +0 -17
  138. package/.vscode/tasks.json +0 -17
  139. package/GETTING_STARTED.md +0 -114
  140. package/desktop/build-installer.js +0 -228
  141. package/desktop/build.js +0 -118
  142. package/desktop/installer/nexusflow.iss +0 -35
  143. package/desktop/neutralino.config.json +0 -39
  144. package/desktop/package-lock.json +0 -1060
  145. package/desktop/package.json +0 -14
  146. package/dist/gui/assets/index-D8iJPvnk.js +0 -26
  147. package/extension/media/icon.svg +0 -1
  148. package/extension/package-lock.json +0 -6044
  149. package/extension/package.json +0 -117
  150. package/extension/src/extension.ts +0 -653
  151. package/extension/tsconfig.json +0 -21
  152. package/gui/README.md +0 -73
  153. package/gui/e2e/dashboard.spec.ts +0 -61
  154. package/gui/e2e/wizard.spec.ts +0 -346
  155. package/gui/eslint.config.js +0 -26
  156. package/gui/index.html +0 -17
  157. package/gui/package-lock.json +0 -3137
  158. package/gui/package.json +0 -37
  159. package/gui/playwright.config.ts +0 -41
  160. package/gui/public/app_logo.png +0 -0
  161. package/gui/public/favicon.svg +0 -1
  162. package/gui/public/icons.svg +0 -24
  163. package/gui/src/App.css +0 -1
  164. package/gui/src/App.tsx +0 -3573
  165. package/gui/src/app/AppSidebar.tsx +0 -69
  166. package/gui/src/assets/hero.png +0 -0
  167. package/gui/src/assets/react.svg +0 -1
  168. package/gui/src/assets/vite.svg +0 -1
  169. package/gui/src/components/AddRepoPicker.tsx +0 -81
  170. package/gui/src/components/ui/Button.tsx +0 -40
  171. package/gui/src/components/ui/Card.tsx +0 -6
  172. package/gui/src/components/ui/EmptyState.tsx +0 -22
  173. package/gui/src/components/ui/Input.tsx +0 -21
  174. package/gui/src/components/ui/Menu.tsx +0 -71
  175. package/gui/src/components/ui/Modal.tsx +0 -39
  176. package/gui/src/components/ui/PageHeader.tsx +0 -21
  177. package/gui/src/components/ui/RepoStatusStrip.tsx +0 -33
  178. package/gui/src/components/ui/Skeleton.tsx +0 -5
  179. package/gui/src/components/ui/StatusPill.tsx +0 -36
  180. package/gui/src/components/ui/Tabs.tsx +0 -40
  181. package/gui/src/components/ui/cn.ts +0 -4
  182. package/gui/src/components/ui/index.ts +0 -16
  183. package/gui/src/features/changes/ChangesViewer.tsx +0 -388
  184. package/gui/src/features/knowledge/KnowledgeBase.tsx +0 -84
  185. package/gui/src/features/onboarding/OnboardingWizard.tsx +0 -230
  186. package/gui/src/features/plan/ImplementationPlan.tsx +0 -32
  187. package/gui/src/features/services/ServiceConsole.tsx +0 -215
  188. package/gui/src/features/sessions/SessionHistory.tsx +0 -195
  189. package/gui/src/index.css +0 -167
  190. package/gui/src/lib/status.ts +0 -24
  191. package/gui/src/main.tsx +0 -94
  192. package/gui/src/pages/DashboardPage.tsx +0 -129
  193. package/gui/src/pages/WorkspacesPage.tsx +0 -352
  194. package/gui/src/types.ts +0 -81
  195. package/gui/tsconfig.app.json +0 -25
  196. package/gui/tsconfig.json +0 -7
  197. package/gui/tsconfig.node.json +0 -24
  198. package/gui/vite.config.ts +0 -12
  199. package/resources/workflows/plan-implement-review.md +0 -8
  200. package/resources/workflows/research-verify.md +0 -6
  201. package/resources/workflows/solo-developer.md +0 -3
  202. package/scripts/simulate-workspaces.ts +0 -55
  203. package/skills-lock.json +0 -11
  204. package/src/analyzers/detect-apis.ts +0 -290
  205. package/src/analyzers/detect-deps.ts +0 -315
  206. package/src/analyzers/detect-existing.ts +0 -74
  207. package/src/analyzers/detect-ports.ts +0 -110
  208. package/src/analyzers/index.ts +0 -97
  209. package/src/analyzers/messaging-analyzer.ts +0 -254
  210. package/src/analyzers/readme-summarizer.ts +0 -102
  211. package/src/analyzers/run-analyzer.ts +0 -269
  212. package/src/analyzers/tech-stack.ts +0 -283
  213. package/src/commands/adapter.ts +0 -348
  214. package/src/commands/add-repo.ts +0 -156
  215. package/src/commands/commands.test.ts +0 -156
  216. package/src/commands/commit.ts +0 -131
  217. package/src/commands/config.ts +0 -52
  218. package/src/commands/create.ts +0 -204
  219. package/src/commands/desktop.ts +0 -128
  220. package/src/commands/diff.ts +0 -125
  221. package/src/commands/doctor.ts +0 -370
  222. package/src/commands/handoff.ts +0 -266
  223. package/src/commands/init.ts +0 -134
  224. package/src/commands/list.ts +0 -46
  225. package/src/commands/logs.ts +0 -63
  226. package/src/commands/mcp.ts +0 -94
  227. package/src/commands/open.ts +0 -129
  228. package/src/commands/refresh.ts +0 -137
  229. package/src/commands/remove.ts +0 -98
  230. package/src/commands/start.ts +0 -117
  231. package/src/commands/status.ts +0 -54
  232. package/src/commands/stop.ts +0 -55
  233. package/src/commands/sync.ts +0 -125
  234. package/src/commands/tui.ts +0 -484
  235. package/src/commands/ui.ts +0 -111
  236. package/src/core/adapters/local-storage.ts +0 -66
  237. package/src/core/adapters/obsidian-storage.ts +0 -151
  238. package/src/core/adapters/registry.ts +0 -44
  239. package/src/core/adapters/storage.test.ts +0 -174
  240. package/src/core/adapters/vault-storage.ts +0 -86
  241. package/src/core/config.test.ts +0 -96
  242. package/src/core/config.ts +0 -140
  243. package/src/core/graph.ts +0 -344
  244. package/src/core/plugins/index.ts +0 -17
  245. package/src/core/plugins/loader.ts +0 -36
  246. package/src/core/ports/storage.ts +0 -71
  247. package/src/core/scanner.test.ts +0 -61
  248. package/src/core/scanner.ts +0 -91
  249. package/src/core/storage.ts +0 -37
  250. package/src/core/sync.ts +0 -121
  251. package/src/core/workspace-state.test.ts +0 -108
  252. package/src/core/workspace-state.ts +0 -130
  253. package/src/core/workspace.ts +0 -487
  254. package/src/core/worktree.ts +0 -120
  255. package/src/generators/antigravity.ts +0 -32
  256. package/src/generators/base.ts +0 -243
  257. package/src/generators/claude.ts +0 -34
  258. package/src/generators/codex.ts +0 -48
  259. package/src/generators/copilot.ts +0 -56
  260. package/src/generators/cursor.ts +0 -44
  261. package/src/generators/diff-context.ts +0 -75
  262. package/src/generators/index.ts +0 -322
  263. package/src/generators/map-generator.test.ts +0 -159
  264. package/src/generators/map-generator.ts +0 -539
  265. package/src/generators/plan-generator.ts +0 -483
  266. package/src/generators/skills-generator.ts +0 -259
  267. package/src/index.ts +0 -539
  268. package/src/mcp/server.ts +0 -338
  269. package/src/orchestration/detect.ts +0 -313
  270. package/src/orchestration/index.ts +0 -7
  271. package/src/orchestration/runner.ts +0 -283
  272. package/src/server.test.ts +0 -618
  273. package/src/server.ts +0 -1402
  274. package/src/types.ts +0 -451
  275. package/src/utils/detect-ai.test.ts +0 -44
  276. package/src/utils/detect-ai.ts +0 -84
  277. package/src/utils/detect-editors.test.ts +0 -48
  278. package/src/utils/detect-editors.ts +0 -57
  279. package/src/utils/git.test.ts +0 -74
  280. package/src/utils/git.ts +0 -117
  281. package/src/utils/local-ai.test.ts +0 -130
  282. package/src/utils/local-ai.ts +0 -116
  283. package/src/utils/multi-git.test.ts +0 -158
  284. package/src/utils/multi-git.ts +0 -405
  285. package/src/utils/prompts.ts +0 -209
  286. package/src/utils/session-finder.ts +0 -483
  287. package/src/utils/system-scanner.test.ts +0 -89
  288. package/src/utils/system-scanner.ts +0 -96
  289. package/src/utils/update-check.ts +0 -286
  290. package/src/utils/workflow-advisor.ts +0 -118
  291. package/src/utils/workflows.test.ts +0 -114
  292. package/src/utils/workflows.ts +0 -178
  293. package/tsconfig.json +0 -19
  294. package/vitest.config.ts +0 -14
@@ -1,352 +0,0 @@
1
- import { useMemo, useState, type ComponentProps } from 'react';
2
- import { RefreshCw, Play, MoreVertical, ExternalLink, Sparkles, Trash2, Search, FolderGit2 } from 'lucide-react';
3
- import type { Feature, WorkspaceStatus, RepoInfo } from '../types.js';
4
- import { Button, Card, EmptyState, Menu, PageHeader, StatusPill, Tabs, Input, Skeleton, cn } from '../components/ui/index.js';
5
- import type { TabItem } from '../components/ui/index.js';
6
- import { AddRepoPicker } from '../components/AddRepoPicker.js';
7
- import { syncMeta, repoName } from '../lib/status.js';
8
- import { SessionHistory } from '../features/sessions/SessionHistory.js';
9
- import { ServiceConsole } from '../features/services/ServiceConsole.js';
10
- import { ChangesViewer } from '../features/changes/ChangesViewer.js';
11
- import { KnowledgeBase } from '../features/knowledge/KnowledgeBase.js';
12
- import { ImplementationPlan } from '../features/plan/ImplementationPlan.js';
13
-
14
- type SubTab = 'overview' | 'sessions' | 'services' | 'changes' | 'knowledge' | 'plan';
15
-
16
- const TABS: TabItem[] = [
17
- { value: 'overview', label: 'Overview' },
18
- { value: 'changes', label: 'Changes' },
19
- { value: 'services', label: 'Services' },
20
- { value: 'sessions', label: 'Sessions' },
21
- { value: 'knowledge', label: 'Knowledge' },
22
- { value: 'plan', label: 'Plan' },
23
- ];
24
-
25
- const FILTERS = ['all', 'changes', 'running'] as const;
26
- type Filter = (typeof FILTERS)[number];
27
-
28
- interface WorkspacesPageProps {
29
- workspaces: Feature[];
30
- workspaceStatuses: Record<string, WorkspaceStatus>;
31
- statusesLoading: boolean;
32
- workspacesLoading: boolean;
33
- fetchWorkspaces: () => Promise<void>;
34
- selectedId: string | null;
35
- subTab: SubTab;
36
- onSelect: (id: string) => void;
37
- onSelectTab: (id: string, tab: SubTab) => void;
38
- resumingWs: string | null;
39
- handleResumeSession: (ws: Feature, sessionId?: string, assistant?: string) => Promise<void>;
40
- handleCopyPrompt: (ws: Feature) => void;
41
- handleOpenInEditor: (workspacePath: string) => Promise<void>;
42
- handleDeleteWorkspace: (wsName: string) => Promise<void>;
43
- deleteWsLoading: string | null;
44
- repos: RepoInfo[];
45
- addRepoLoading: boolean;
46
- handleAddRepo: (wsName: string, repoPath: string) => Promise<void>;
47
- sessionProps: Omit<ComponentProps<typeof SessionHistory>, 'ws'>;
48
- serviceProps: Omit<ComponentProps<typeof ServiceConsole>, 'ws'>;
49
- changesProps: Omit<ComponentProps<typeof ChangesViewer>, 'ws'>;
50
- knowledgeProps: Omit<ComponentProps<typeof KnowledgeBase>, 'ws'>;
51
- planProps: ComponentProps<typeof ImplementationPlan>;
52
- }
53
-
54
- export function WorkspacesPage(props: WorkspacesPageProps) {
55
- const {
56
- workspaces,
57
- workspaceStatuses,
58
- workspacesLoading,
59
- fetchWorkspaces,
60
- selectedId,
61
- subTab,
62
- onSelect,
63
- onSelectTab,
64
- resumingWs,
65
- handleResumeSession,
66
- handleCopyPrompt,
67
- handleOpenInEditor,
68
- handleDeleteWorkspace,
69
- deleteWsLoading,
70
- repos,
71
- addRepoLoading,
72
- handleAddRepo,
73
- sessionProps,
74
- serviceProps,
75
- changesProps,
76
- knowledgeProps,
77
- planProps,
78
- } = props;
79
-
80
- const [query, setQuery] = useState('');
81
- const [filter, setFilter] = useState<Filter>('all');
82
-
83
- const selected = workspaces.find((w) => w.branchName === selectedId) ?? null;
84
-
85
- const filtered = useMemo(() => {
86
- const q = query.trim().toLowerCase();
87
- return workspaces.filter((w) => {
88
- const st = workspaceStatuses[w.branchName];
89
- if (q && !`${w.branchName} ${w.description}`.toLowerCase().includes(q)) return false;
90
- if (filter === 'changes' && !(st && st.changedFiles > 0)) return false;
91
- if (filter === 'running' && !(st && st.runningServices > 0)) return false;
92
- return true;
93
- });
94
- }, [workspaces, workspaceStatuses, query, filter]);
95
-
96
- const repoRows = selected
97
- ? selected.repos.map((rp) => {
98
- const name = repoName(rp);
99
- const change = changesProps.gitChanges?.find((c: { repoName: string; files?: unknown[] }) => c.repoName === name);
100
- const changedCount: number | null = change ? change.files?.length ?? 0 : null;
101
- const svcs = (serviceProps.services ?? []).filter((s) => (s.cwd ?? '').split(/[\\/]/).includes(name));
102
- const ports = Array.from(new Set(svcs.map((s) => s.port).filter((p): p is number => typeof p === 'number')));
103
- return { name, changedCount, ports, serviceCount: svcs.length };
104
- })
105
- : [];
106
-
107
- const availableRepos = selected ? repos.filter((r) => !selected.repos.includes(r.path)) : [];
108
-
109
- return (
110
- <div className="mx-auto max-w-7xl animate-fade-in">
111
- <PageHeader
112
- title="Workspaces"
113
- subtitle="Select a workspace to inspect its changes, services, sessions and context."
114
- actions={
115
- <Button
116
- variant="secondary"
117
- icon={<RefreshCw size={14} className={workspacesLoading ? 'animate-spin text-accent' : ''} />}
118
- onClick={fetchWorkspaces}
119
- disabled={workspacesLoading}
120
- >
121
- Refresh
122
- </Button>
123
- }
124
- />
125
-
126
- <div className="flex flex-col gap-5 lg:flex-row">
127
- {/* ── List pane ─────────────────────────────────────────── */}
128
- <div className="lg:w-80 lg:shrink-0">
129
- <div className="relative mb-3">
130
- <Search size={14} className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-content-faint" />
131
- <Input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search workspaces" className="pl-8" />
132
- </div>
133
- <div className="mb-3 flex items-center gap-1">
134
- {FILTERS.map((f) => (
135
- <button
136
- key={f}
137
- onClick={() => setFilter(f)}
138
- className={cn(
139
- 'rounded-md px-2.5 py-1 text-xs font-medium capitalize transition-colors cursor-pointer',
140
- filter === f ? 'bg-accent-soft text-accent' : 'text-content-faint hover:text-content',
141
- )}
142
- >
143
- {f}
144
- </button>
145
- ))}
146
- </div>
147
-
148
- {workspacesLoading ? (
149
- <div className="flex flex-col gap-1.5">
150
- {[0, 1, 2, 3].map((i) => (
151
- <Skeleton key={i} className="h-14" />
152
- ))}
153
- </div>
154
- ) : filtered.length === 0 ? (
155
- <Card className="p-6 text-center text-sm text-content-muted">No workspaces match.</Card>
156
- ) : (
157
- <div className="flex flex-col gap-1.5">
158
- {filtered.map((w) => {
159
- const st = workspaceStatuses[w.branchName];
160
- const active = w.branchName === selectedId;
161
- const sync = st ? syncMeta(st.syncStatus) : null;
162
- return (
163
- <button
164
- key={w.id}
165
- onClick={() => onSelect(w.branchName)}
166
- className={cn(
167
- 'rounded-lg border p-3 text-left transition-colors cursor-pointer',
168
- active ? 'border-accent/50 bg-accent-soft' : 'border-hairline bg-surface hover:border-hairline-strong hover:bg-raised',
169
- )}
170
- >
171
- <div className="flex items-center justify-between gap-2">
172
- <span className="truncate font-mono text-sm font-semibold text-content">{w.branchName}</span>
173
- <span className="shrink-0 text-[11px] text-content-faint">{w.repos.length} repos</span>
174
- </div>
175
- <div className="mt-1.5 flex items-center gap-2">
176
- <span
177
- className={cn('h-1.5 w-1.5 rounded-full', st?.changedFiles ? 'bg-warning' : 'bg-success')}
178
- title={st?.changedFiles ? `${st.changedFiles} uncommitted` : 'Clean'}
179
- />
180
- {st?.runningServices ? <span className="h-1.5 w-1.5 rounded-full bg-running" title="Running services" /> : null}
181
- {sync && <span className="text-[11px] text-content-faint">{sync.label}</span>}
182
- </div>
183
- </button>
184
- );
185
- })}
186
- </div>
187
- )}
188
- </div>
189
-
190
- {/* ── Detail pane ───────────────────────────────────────── */}
191
- <div className="min-w-0 flex-1">
192
- {!selected ? (
193
- <Card>
194
- <EmptyState
195
- icon={<FolderGit2 size={40} />}
196
- title="No workspace selected"
197
- description="Pick a workspace from the list to see its status, repositories, changes, services and sessions."
198
- />
199
- </Card>
200
- ) : (
201
- <div>
202
- <Card className="mb-4 p-5">
203
- <div className="flex items-start justify-between gap-4">
204
- <div className="min-w-0">
205
- <h2 className="font-display text-xl font-bold text-content">{selected.branchName}</h2>
206
- <div className="mt-1 flex items-center gap-2 text-xs text-content-faint">
207
- <span>Created {new Date(selected.createdAt).toLocaleDateString()}</span>
208
- <span>·</span>
209
- <span>{selected.repos.length} repos</span>
210
- </div>
211
- </div>
212
- <div className="flex shrink-0 items-center gap-2">
213
- <Button
214
- variant="primary"
215
- icon={<Play size={13} className={resumingWs === selected.branchName ? 'animate-spin' : ''} />}
216
- disabled={resumingWs === selected.branchName}
217
- onClick={() => handleResumeSession(selected)}
218
- >
219
- {resumingWs === selected.branchName ? 'Resuming…' : 'Resume in Editor'}
220
- </Button>
221
- <Menu
222
- label="More actions"
223
- trigger={
224
- <span className="grid h-9 w-9 place-items-center rounded-md border border-hairline bg-surface text-content-muted hover:bg-raised hover:text-content">
225
- <MoreVertical size={16} />
226
- </span>
227
- }
228
- items={[
229
- { label: 'Open Folder', icon: <ExternalLink size={14} />, onClick: () => void handleOpenInEditor(selected.workspacePath) },
230
- { label: 'Copy AI Context', icon: <Sparkles size={14} className="text-accent" />, onClick: () => handleCopyPrompt(selected) },
231
- {
232
- label: deleteWsLoading === selected.branchName ? 'Deleting…' : 'Delete Workspace',
233
- icon: <Trash2 size={14} />,
234
- danger: true,
235
- disabled: deleteWsLoading === selected.branchName,
236
- onClick: () => void handleDeleteWorkspace(selected.branchName),
237
- },
238
- ]}
239
- />
240
- </div>
241
- </div>
242
-
243
- <div className="mt-3 flex flex-wrap items-center gap-2">
244
- {(() => {
245
- const st = workspaceStatuses[selected.branchName];
246
- if (!st) return null;
247
- const sync = syncMeta(st.syncStatus);
248
- return (
249
- <>
250
- {st.changedFiles > 0 ? (
251
- <StatusPill tone="warning" dot>
252
- {st.changedFiles} uncommitted
253
- </StatusPill>
254
- ) : (
255
- <StatusPill tone="idle" dot>
256
- Clean
257
- </StatusPill>
258
- )}
259
- {st.runningServices > 0 ? (
260
- <StatusPill tone="running" dot>
261
- {st.runningServices} running
262
- </StatusPill>
263
- ) : (
264
- <StatusPill tone="idle" dot>
265
- No services
266
- </StatusPill>
267
- )}
268
- <StatusPill tone={sync.tone}>
269
- <RefreshCw size={11} /> {sync.label}
270
- </StatusPill>
271
- {st.pendingValidation && <StatusPill tone="warning">Needs validation</StatusPill>}
272
- </>
273
- );
274
- })()}
275
- </div>
276
- </Card>
277
-
278
- <Tabs items={TABS} value={subTab} onChange={(v) => onSelectTab(selected.branchName, v as SubTab)} className="mb-4" />
279
-
280
- <div className="animate-fade-in">
281
- {subTab === 'overview' && (
282
- <div className="flex flex-col gap-4">
283
- <Card className="p-5">
284
- <h3 className="mb-2 font-display text-sm font-semibold text-content">Description</h3>
285
- {selected.description ? (
286
- <p className="whitespace-pre-line text-sm leading-relaxed text-content-muted">{selected.description}</p>
287
- ) : (
288
- <p className="text-sm text-content-faint">No description provided.</p>
289
- )}
290
- </Card>
291
- <Card className="p-5">
292
- <div className="mb-4 flex items-center justify-between gap-3">
293
- <h3 className="font-display text-sm font-semibold text-content">
294
- Repositories <span className="text-content-faint">({selected.repos.length})</span>
295
- </h3>
296
- {availableRepos.length > 0 && (
297
- <AddRepoPicker
298
- repos={availableRepos}
299
- disabled={addRepoLoading}
300
- onAdd={(path) => {
301
- if (
302
- window.confirm(
303
- `Add repository "${repoName(path)}" to this workspace?\nThis creates a new git worktree and re-runs analysis.`,
304
- )
305
- ) {
306
- void handleAddRepo(selected.branchName, path);
307
- }
308
- }}
309
- />
310
- )}
311
- </div>
312
- <div className="divide-y divide-hairline">
313
- {repoRows.map((r) => (
314
- <div key={r.name} className="flex items-center gap-3 py-2.5 first:pt-0 last:pb-0">
315
- <span
316
- className={cn(
317
- 'h-2 w-2 shrink-0 rounded-full',
318
- r.changedCount === null ? 'bg-idle' : r.changedCount > 0 ? 'bg-warning' : 'bg-success',
319
- )}
320
- title={r.changedCount === null ? 'Status unknown' : r.changedCount > 0 ? 'Uncommitted changes' : 'Clean'}
321
- />
322
- <span className="min-w-0 flex-1 truncate font-mono text-sm text-content">{r.name}</span>
323
- <div className="flex shrink-0 items-center gap-2">
324
- {r.ports.map((p) => (
325
- <span key={p} className="rounded border border-hairline bg-base px-1.5 py-0.5 font-mono text-[11px] text-running">
326
- :{p}
327
- </span>
328
- ))}
329
- <span className="w-24 text-right text-xs text-content-faint">
330
- {r.changedCount === null ? '—' : r.changedCount > 0 ? `${r.changedCount} changed` : 'clean'}
331
- </span>
332
- </div>
333
- </div>
334
- ))}
335
- </div>
336
- <p className="mt-3 text-[11px] text-content-faint">Per-repo git state and detected service ports.</p>
337
- </Card>
338
- </div>
339
- )}
340
- {subTab === 'sessions' && <SessionHistory ws={selected} {...sessionProps} />}
341
- {subTab === 'services' && <ServiceConsole ws={selected} {...serviceProps} />}
342
- {subTab === 'changes' && <ChangesViewer ws={selected} {...changesProps} />}
343
- {subTab === 'knowledge' && <KnowledgeBase ws={selected} {...knowledgeProps} />}
344
- {subTab === 'plan' && <ImplementationPlan {...planProps} />}
345
- </div>
346
- </div>
347
- )}
348
- </div>
349
- </div>
350
- </div>
351
- );
352
- }
package/gui/src/types.ts DELETED
@@ -1,81 +0,0 @@
1
- // Types matched with src/types.ts
2
-
3
- export interface NexusFlowConfig {
4
- version: string;
5
- devDir: string;
6
- workspacesDir: string;
7
- defaultAssistant: string | null;
8
- defaultEditor?: string | null;
9
- scanDepth: number;
10
- }
11
-
12
- export interface DetectedAI {
13
- name: string;
14
- displayName: string;
15
- detected: boolean;
16
- command?: string;
17
- }
18
-
19
- export interface DetectedEditor {
20
- name: string;
21
- command: string;
22
- detected: boolean;
23
- }
24
-
25
- export interface RepoInfo {
26
- name: string;
27
- path: string;
28
- defaultBranch: string;
29
- }
30
-
31
- export interface Feature {
32
- id: string;
33
- branchName: string;
34
- description: string;
35
- repos: string[];
36
- assistants: string[];
37
- workspacePath: string;
38
- createdAt: string;
39
- }
40
-
41
- /** Classified outcome of a sync/rebase attempt for a repo (mirrors src/types.ts). */
42
- export type SyncStatus = 'up-to-date' | 'rebased' | 'conflict' | 'stash-conflict' | 'error';
43
-
44
- /** At-a-glance status for one workspace, from GET /api/workspaces/status. */
45
- export interface WorkspaceStatus {
46
- id: string;
47
- branchName: string;
48
- /** Total uncommitted files across all repo worktrees. */
49
- changedFiles: number;
50
- /** Number of repos with uncommitted changes. */
51
- dirtyRepos: number;
52
- /** Number of currently running orchestrated services. */
53
- runningServices: number;
54
- /** Worst-case sync classification across repos, or 'unknown' if never synced. */
55
- syncStatus: SyncStatus | 'unknown';
56
- /** True when any repo pulled in new commits and awaits re-validation. */
57
- pendingValidation: boolean;
58
- }
59
-
60
- export interface ServiceConfig {
61
- name: string;
62
- cwd: string;
63
- command: string;
64
- args: string[];
65
- port?: number;
66
- source: string;
67
- }
68
-
69
- export interface OrchestrationDetection {
70
- tool: string;
71
- configPath: string;
72
- startCommand: string;
73
- stopCommand: string;
74
- }
75
-
76
- export interface RunningService {
77
- name: string;
78
- pid: number;
79
- config: ServiceConfig;
80
- startedAt: string;
81
- }
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
- "target": "es2023",
5
- "lib": ["ES2023", "DOM"],
6
- "module": "esnext",
7
- "types": ["vite/client"],
8
- "skipLibCheck": true,
9
-
10
- /* Bundler mode */
11
- "moduleResolution": "bundler",
12
- "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "moduleDetection": "force",
15
- "noEmit": true,
16
- "jsx": "react-jsx",
17
-
18
- /* Linting */
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "erasableSyntaxOnly": true,
22
- "noFallthroughCasesInSwitch": true
23
- },
24
- "include": ["src"]
25
- }
package/gui/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ]
7
- }
@@ -1,24 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
- "target": "es2023",
5
- "lib": ["ES2023"],
6
- "module": "esnext",
7
- "types": ["node"],
8
- "skipLibCheck": true,
9
-
10
- /* Bundler mode */
11
- "moduleResolution": "bundler",
12
- "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "moduleDetection": "force",
15
- "noEmit": true,
16
-
17
- /* Linting */
18
- "noUnusedLocals": true,
19
- "noUnusedParameters": true,
20
- "erasableSyntaxOnly": true,
21
- "noFallthroughCasesInSwitch": true
22
- },
23
- "include": ["vite.config.ts"]
24
- }
@@ -1,12 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
- import tailwindcss from '@tailwindcss/vite'
4
-
5
- // https://vite.dev/config/
6
- export default defineConfig({
7
- plugins: [react(), tailwindcss()],
8
- build: {
9
- outDir: '../dist/gui',
10
- emptyOutDir: true,
11
- },
12
- })
@@ -1,8 +0,0 @@
1
- # Team Cooperation Guidelines
2
-
3
- You are the lead developer. You must coordinate a Plan-Implement-Review loop to complete the task:
4
-
5
- 1. **Research & Plan**: Research the requirements and codebase first. Create a plan (`implementation_plan.md`) describing the proposed changes.
6
- 2. **Implement**: Define a `Code_Implementer` subagent equipped with code editing and terminal tools. Send them the plan and instruct them to write the changes.
7
- 3. **Review**: Once implemented, define a `Code_Reviewer` subagent to run verification tests and review the changes for correctness.
8
- 4. **Loop**: If the reviewer finds bugs or test failures, send the feedback back to the implementer and repeat the cycle until the changes are approved.
@@ -1,6 +0,0 @@
1
- # Team Cooperation Guidelines
2
-
3
- You are the lead investigator. You must coordinate a research-heavy cycle:
4
-
5
- 1. **Deep Research**: Define a `Research_Specialist` subagent to scan the codebase, find dependencies, and write a thorough context guide outlining how the system works.
6
- 2. **Test-Driven Implement**: Write test suites first based on the research findings, then spawn a developer subagent to code until all tests pass successfully.
@@ -1,3 +0,0 @@
1
- # Direct Execution Guidelines
2
-
3
- You are a solo developer. Do not spawn subagents. Research, plan, edit, and verify all code changes yourself. Focus on delivering direct, simple edits to target files.
@@ -1,55 +0,0 @@
1
- import * as path from 'node:path';
2
- import * as os from 'node:os';
3
- import { loadConfig } from '../src/core/config.js';
4
- import { createWorkspace } from '../src/core/workspace.js';
5
- import { analyzeAllRepos } from '../src/analyzers/index.js';
6
- import { generateContextFiles } from '../src/generators/index.js';
7
-
8
- async function main() {
9
- const config = await loadConfig();
10
- const repoPath = 'C:\\Users\\patro\\dev\\easyagent_container';
11
-
12
- console.log('Creating Workspace 1: feat/rate-limiting-standard (Local LLM DISABLED)');
13
- const ws1Path = path.join(config.workspacesDir, 'feat/rate-limiting-standard');
14
- const feature1 = {
15
- id: 'feat/rate-limiting-standard',
16
- branchName: 'feat/rate-limiting-standard',
17
- description: 'Implement rate limiting and connection pooling',
18
- repos: [repoPath],
19
- assistants: ['claude'],
20
- workspacePath: ws1Path,
21
- createdAt: new Date().toISOString(),
22
- localLlmEnabled: false,
23
- };
24
- const repos1 = [{ name: 'easyagent_container', path: path.join(ws1Path, 'easyagent_container'), isGitRepo: true, defaultBranch: 'master' }];
25
-
26
- await createWorkspace(feature1, [{ name: 'easyagent_container', path: repoPath, isGitRepo: true, defaultBranch: 'master' }]);
27
- const analysis1 = await analyzeAllRepos(repos1);
28
- const ctx1 = { feature: feature1, repos: repos1, analysis: analysis1 };
29
- await generateContextFiles(ctx1, ['claude'], ws1Path);
30
- console.log('✅ Workspace 1 created at:', ws1Path);
31
-
32
- console.log('\nCreating Workspace 2: feat/rate-limiting-local-llm (Local LLM ENABLED)');
33
- const ws2Path = path.join(config.workspacesDir, 'feat/rate-limiting-local-llm');
34
- const feature2 = {
35
- id: 'feat/rate-limiting-local-llm',
36
- branchName: 'feat/rate-limiting-local-llm',
37
- description: 'Implement rate limiting and connection pooling',
38
- repos: [repoPath],
39
- assistants: ['claude'],
40
- workspacePath: ws2Path,
41
- createdAt: new Date().toISOString(),
42
- localLlmEnabled: true,
43
- };
44
- const repos2 = [{ name: 'easyagent_container', path: path.join(ws2Path, 'easyagent_container'), isGitRepo: true, defaultBranch: 'master' }];
45
-
46
- await createWorkspace(feature2, [{ name: 'easyagent_container', path: repoPath, isGitRepo: true, defaultBranch: 'master' }]);
47
- const analysis2 = await analyzeAllRepos(repos2);
48
- const ctx2 = { feature: feature2, repos: repos2, analysis: analysis2, localLlm: config.localLlm };
49
- await generateContextFiles(ctx2, ['claude'], ws2Path);
50
- console.log('✅ Workspace 2 created at:', ws2Path);
51
-
52
- console.log('\nBoth test workspaces are ready!');
53
- }
54
-
55
- main().catch(console.error);
package/skills-lock.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "version": 1,
3
- "skills": {
4
- "ccc": {
5
- "source": "cocoindex-io/cocoindex-code",
6
- "sourceType": "github",
7
- "skillPath": "skills/ccc/SKILL.md",
8
- "computedHash": "ad5f1c8501fd81d45e20501cbfa2b13699a6bbb4fd218c1b1034fec7b9659eff"
9
- }
10
- }
11
- }