@mrpatronz/nexusflow 0.2.19 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/README.md +27 -3
  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/commands.test.js +20 -6
  7. package/dist/commands/commands.test.js.map +1 -1
  8. package/dist/commands/commit.d.ts +2 -0
  9. package/dist/commands/commit.d.ts.map +1 -1
  10. package/dist/commands/commit.js +27 -5
  11. package/dist/commands/commit.js.map +1 -1
  12. package/dist/commands/diff.d.ts +9 -2
  13. package/dist/commands/diff.d.ts.map +1 -1
  14. package/dist/commands/diff.js +36 -12
  15. package/dist/commands/diff.js.map +1 -1
  16. package/dist/commands/doctor.js +2 -2
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/commands/handoff.js +2 -2
  19. package/dist/commands/handoff.js.map +1 -1
  20. package/dist/commands/refresh.d.ts +4 -2
  21. package/dist/commands/refresh.d.ts.map +1 -1
  22. package/dist/commands/refresh.js +20 -36
  23. package/dist/commands/refresh.js.map +1 -1
  24. package/dist/commands/schedule.d.ts +35 -0
  25. package/dist/commands/schedule.d.ts.map +1 -0
  26. package/dist/commands/schedule.js +151 -0
  27. package/dist/commands/schedule.js.map +1 -0
  28. package/dist/commands/sync.d.ts.map +1 -1
  29. package/dist/commands/sync.js +28 -7
  30. package/dist/commands/sync.js.map +1 -1
  31. package/dist/core/analysis-cache.d.ts +58 -0
  32. package/dist/core/analysis-cache.d.ts.map +1 -0
  33. package/dist/core/analysis-cache.js +116 -0
  34. package/dist/core/analysis-cache.js.map +1 -0
  35. package/dist/core/analysis-cache.test.d.ts +2 -0
  36. package/dist/core/analysis-cache.test.d.ts.map +1 -0
  37. package/dist/core/analysis-cache.test.js +108 -0
  38. package/dist/core/analysis-cache.test.js.map +1 -0
  39. package/dist/core/refresh.d.ts +41 -0
  40. package/dist/core/refresh.d.ts.map +1 -0
  41. package/dist/core/refresh.js +60 -0
  42. package/dist/core/refresh.js.map +1 -0
  43. package/dist/core/scheduler.d.ts +117 -0
  44. package/dist/core/scheduler.d.ts.map +1 -0
  45. package/dist/core/scheduler.js +247 -0
  46. package/dist/core/scheduler.js.map +1 -0
  47. package/dist/core/scheduler.test.d.ts +2 -0
  48. package/dist/core/scheduler.test.d.ts.map +1 -0
  49. package/dist/core/scheduler.test.js +111 -0
  50. package/dist/core/scheduler.test.js.map +1 -0
  51. package/dist/core/sync.d.ts +6 -0
  52. package/dist/core/sync.d.ts.map +1 -1
  53. package/dist/core/sync.js +15 -5
  54. package/dist/core/sync.js.map +1 -1
  55. package/dist/generators/index.d.ts +7 -1
  56. package/dist/generators/index.d.ts.map +1 -1
  57. package/dist/generators/index.js +14 -1
  58. package/dist/generators/index.js.map +1 -1
  59. package/dist/index.js +107 -4
  60. package/dist/index.js.map +1 -1
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +81 -0
  63. package/dist/server.js.map +1 -1
  64. package/dist/server.test.js +66 -0
  65. package/dist/server.test.js.map +1 -1
  66. package/dist/utils/multi-git.d.ts +21 -0
  67. package/dist/utils/multi-git.d.ts.map +1 -1
  68. package/dist/utils/multi-git.js +40 -4
  69. package/dist/utils/multi-git.js.map +1 -1
  70. package/package.json +13 -1
  71. package/.agents/skills/ccc/SKILL.md +0 -71
  72. package/.agents/skills/ccc/references/management.md +0 -110
  73. package/.agents/skills/ccc/references/settings.md +0 -126
  74. package/.github/dependabot.yml +0 -52
  75. package/.github/workflows/ci.yml +0 -44
  76. package/.github/workflows/dependabot-merge.yml +0 -53
  77. package/.github/workflows/release-desktop.yml +0 -67
  78. package/.github/workflows/release-npm.yml +0 -65
  79. package/.github/workflows/release-vscode.yml +0 -61
  80. package/.vscode/launch.json +0 -17
  81. package/.vscode/tasks.json +0 -17
  82. package/GETTING_STARTED.md +0 -114
  83. package/desktop/build-installer.js +0 -228
  84. package/desktop/build.js +0 -118
  85. package/desktop/installer/nexusflow.iss +0 -35
  86. package/desktop/neutralino.config.json +0 -39
  87. package/desktop/package-lock.json +0 -1060
  88. package/desktop/package.json +0 -14
  89. package/extension/media/icon.svg +0 -1
  90. package/extension/package-lock.json +0 -6044
  91. package/extension/package.json +0 -117
  92. package/extension/src/extension.ts +0 -653
  93. package/extension/tsconfig.json +0 -21
  94. package/gui/README.md +0 -73
  95. package/gui/e2e/dashboard.spec.ts +0 -61
  96. package/gui/e2e/wizard.spec.ts +0 -346
  97. package/gui/eslint.config.js +0 -26
  98. package/gui/index.html +0 -17
  99. package/gui/package-lock.json +0 -3137
  100. package/gui/package.json +0 -37
  101. package/gui/playwright.config.ts +0 -41
  102. package/gui/public/app_logo.png +0 -0
  103. package/gui/public/favicon.svg +0 -1
  104. package/gui/public/icons.svg +0 -24
  105. package/gui/src/App.css +0 -1
  106. package/gui/src/App.tsx +0 -3573
  107. package/gui/src/app/AppSidebar.tsx +0 -69
  108. package/gui/src/assets/hero.png +0 -0
  109. package/gui/src/assets/react.svg +0 -1
  110. package/gui/src/assets/vite.svg +0 -1
  111. package/gui/src/components/AddRepoPicker.tsx +0 -81
  112. package/gui/src/components/ui/Button.tsx +0 -40
  113. package/gui/src/components/ui/Card.tsx +0 -6
  114. package/gui/src/components/ui/EmptyState.tsx +0 -22
  115. package/gui/src/components/ui/Input.tsx +0 -21
  116. package/gui/src/components/ui/Menu.tsx +0 -71
  117. package/gui/src/components/ui/Modal.tsx +0 -39
  118. package/gui/src/components/ui/PageHeader.tsx +0 -21
  119. package/gui/src/components/ui/RepoStatusStrip.tsx +0 -33
  120. package/gui/src/components/ui/Skeleton.tsx +0 -5
  121. package/gui/src/components/ui/StatusPill.tsx +0 -36
  122. package/gui/src/components/ui/Tabs.tsx +0 -40
  123. package/gui/src/components/ui/cn.ts +0 -4
  124. package/gui/src/components/ui/index.ts +0 -16
  125. package/gui/src/features/changes/ChangesViewer.tsx +0 -388
  126. package/gui/src/features/knowledge/KnowledgeBase.tsx +0 -84
  127. package/gui/src/features/onboarding/OnboardingWizard.tsx +0 -230
  128. package/gui/src/features/plan/ImplementationPlan.tsx +0 -32
  129. package/gui/src/features/services/ServiceConsole.tsx +0 -215
  130. package/gui/src/features/sessions/SessionHistory.tsx +0 -195
  131. package/gui/src/index.css +0 -167
  132. package/gui/src/lib/status.ts +0 -24
  133. package/gui/src/main.tsx +0 -94
  134. package/gui/src/pages/DashboardPage.tsx +0 -129
  135. package/gui/src/pages/WorkspacesPage.tsx +0 -352
  136. package/gui/src/types.ts +0 -81
  137. package/gui/tsconfig.app.json +0 -25
  138. package/gui/tsconfig.json +0 -7
  139. package/gui/tsconfig.node.json +0 -24
  140. package/gui/vite.config.ts +0 -12
  141. package/resources/workflows/plan-implement-review.md +0 -8
  142. package/resources/workflows/research-verify.md +0 -6
  143. package/resources/workflows/solo-developer.md +0 -3
  144. package/scripts/simulate-workspaces.ts +0 -55
  145. package/skills-lock.json +0 -11
  146. package/src/analyzers/detect-apis.ts +0 -290
  147. package/src/analyzers/detect-deps.ts +0 -315
  148. package/src/analyzers/detect-existing.ts +0 -74
  149. package/src/analyzers/detect-ports.ts +0 -110
  150. package/src/analyzers/index.ts +0 -97
  151. package/src/analyzers/messaging-analyzer.ts +0 -254
  152. package/src/analyzers/readme-summarizer.ts +0 -102
  153. package/src/analyzers/run-analyzer.ts +0 -269
  154. package/src/analyzers/tech-stack.ts +0 -283
  155. package/src/commands/adapter.ts +0 -348
  156. package/src/commands/add-repo.ts +0 -156
  157. package/src/commands/commands.test.ts +0 -156
  158. package/src/commands/commit.ts +0 -131
  159. package/src/commands/config.ts +0 -52
  160. package/src/commands/create.ts +0 -204
  161. package/src/commands/desktop.ts +0 -128
  162. package/src/commands/diff.ts +0 -125
  163. package/src/commands/doctor.ts +0 -370
  164. package/src/commands/handoff.ts +0 -266
  165. package/src/commands/init.ts +0 -134
  166. package/src/commands/list.ts +0 -46
  167. package/src/commands/logs.ts +0 -63
  168. package/src/commands/mcp.ts +0 -94
  169. package/src/commands/open.ts +0 -129
  170. package/src/commands/refresh.ts +0 -137
  171. package/src/commands/remove.ts +0 -98
  172. package/src/commands/start.ts +0 -117
  173. package/src/commands/status.ts +0 -54
  174. package/src/commands/stop.ts +0 -55
  175. package/src/commands/sync.ts +0 -125
  176. package/src/commands/tui.ts +0 -484
  177. package/src/commands/ui.ts +0 -111
  178. package/src/core/adapters/local-storage.ts +0 -66
  179. package/src/core/adapters/obsidian-storage.ts +0 -151
  180. package/src/core/adapters/registry.ts +0 -44
  181. package/src/core/adapters/storage.test.ts +0 -174
  182. package/src/core/adapters/vault-storage.ts +0 -86
  183. package/src/core/config.test.ts +0 -96
  184. package/src/core/config.ts +0 -140
  185. package/src/core/graph.ts +0 -344
  186. package/src/core/plugins/index.ts +0 -17
  187. package/src/core/plugins/loader.ts +0 -36
  188. package/src/core/ports/storage.ts +0 -71
  189. package/src/core/scanner.test.ts +0 -61
  190. package/src/core/scanner.ts +0 -91
  191. package/src/core/storage.ts +0 -37
  192. package/src/core/sync.ts +0 -121
  193. package/src/core/workspace-state.test.ts +0 -108
  194. package/src/core/workspace-state.ts +0 -130
  195. package/src/core/workspace.ts +0 -487
  196. package/src/core/worktree.ts +0 -120
  197. package/src/generators/antigravity.ts +0 -32
  198. package/src/generators/base.ts +0 -243
  199. package/src/generators/claude.ts +0 -34
  200. package/src/generators/codex.ts +0 -48
  201. package/src/generators/copilot.ts +0 -56
  202. package/src/generators/cursor.ts +0 -44
  203. package/src/generators/diff-context.ts +0 -75
  204. package/src/generators/index.ts +0 -322
  205. package/src/generators/map-generator.test.ts +0 -159
  206. package/src/generators/map-generator.ts +0 -539
  207. package/src/generators/plan-generator.ts +0 -483
  208. package/src/generators/skills-generator.ts +0 -259
  209. package/src/index.ts +0 -539
  210. package/src/mcp/server.ts +0 -338
  211. package/src/orchestration/detect.ts +0 -313
  212. package/src/orchestration/index.ts +0 -7
  213. package/src/orchestration/runner.ts +0 -283
  214. package/src/server.test.ts +0 -618
  215. package/src/server.ts +0 -1402
  216. package/src/types.ts +0 -451
  217. package/src/utils/detect-ai.test.ts +0 -44
  218. package/src/utils/detect-ai.ts +0 -84
  219. package/src/utils/detect-editors.test.ts +0 -48
  220. package/src/utils/detect-editors.ts +0 -57
  221. package/src/utils/git.test.ts +0 -74
  222. package/src/utils/git.ts +0 -117
  223. package/src/utils/local-ai.test.ts +0 -130
  224. package/src/utils/local-ai.ts +0 -116
  225. package/src/utils/multi-git.test.ts +0 -158
  226. package/src/utils/multi-git.ts +0 -405
  227. package/src/utils/prompts.ts +0 -209
  228. package/src/utils/session-finder.ts +0 -483
  229. package/src/utils/system-scanner.test.ts +0 -89
  230. package/src/utils/system-scanner.ts +0 -96
  231. package/src/utils/update-check.ts +0 -286
  232. package/src/utils/workflow-advisor.ts +0 -118
  233. package/src/utils/workflows.test.ts +0 -114
  234. package/src/utils/workflows.ts +0 -178
  235. package/tsconfig.json +0 -19
  236. 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
- }