@mrpatronz/nexusflow 0.2.13 → 0.2.18

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 (228) hide show
  1. package/.agents/skills/ccc/SKILL.md +71 -0
  2. package/.agents/skills/ccc/references/management.md +110 -0
  3. package/.agents/skills/ccc/references/settings.md +126 -0
  4. package/.github/workflows/ci.yml +44 -0
  5. package/.github/workflows/dependabot-merge.yml +53 -0
  6. package/.github/workflows/release-desktop.yml +67 -0
  7. package/.github/workflows/release-npm.yml +65 -0
  8. package/.github/workflows/release-vscode.yml +61 -0
  9. package/GETTING_STARTED.md +5 -0
  10. package/README.md +53 -0
  11. package/desktop/build-installer.js +228 -0
  12. package/desktop/build.js +118 -0
  13. package/desktop/installer/nexusflow.iss +35 -0
  14. package/desktop/neutralino.config.json +39 -0
  15. package/desktop/package-lock.json +1060 -0
  16. package/desktop/package.json +14 -0
  17. package/dist/commands/adapter.d.ts +27 -0
  18. package/dist/commands/adapter.d.ts.map +1 -0
  19. package/dist/commands/adapter.js +318 -0
  20. package/dist/commands/adapter.js.map +1 -0
  21. package/dist/commands/add-repo.d.ts.map +1 -1
  22. package/dist/commands/add-repo.js +0 -1
  23. package/dist/commands/add-repo.js.map +1 -1
  24. package/dist/commands/commands.test.js +2 -2
  25. package/dist/commands/commands.test.js.map +1 -1
  26. package/dist/commands/config.d.ts +22 -0
  27. package/dist/commands/config.d.ts.map +1 -0
  28. package/dist/commands/config.js +50 -0
  29. package/dist/commands/config.js.map +1 -0
  30. package/dist/commands/create.d.ts.map +1 -1
  31. package/dist/commands/create.js +14 -17
  32. package/dist/commands/create.js.map +1 -1
  33. package/dist/commands/desktop.d.ts +12 -0
  34. package/dist/commands/desktop.d.ts.map +1 -0
  35. package/dist/commands/desktop.js +119 -0
  36. package/dist/commands/desktop.js.map +1 -0
  37. package/dist/commands/doctor.d.ts.map +1 -1
  38. package/dist/commands/doctor.js +11 -0
  39. package/dist/commands/doctor.js.map +1 -1
  40. package/dist/commands/refresh.d.ts +1 -0
  41. package/dist/commands/refresh.d.ts.map +1 -1
  42. package/dist/commands/refresh.js +2 -14
  43. package/dist/commands/refresh.js.map +1 -1
  44. package/dist/commands/sync.d.ts.map +1 -1
  45. package/dist/commands/sync.js +1 -8
  46. package/dist/commands/sync.js.map +1 -1
  47. package/dist/commands/tui.d.ts +8 -0
  48. package/dist/commands/tui.d.ts.map +1 -0
  49. package/dist/commands/tui.js +439 -0
  50. package/dist/commands/tui.js.map +1 -0
  51. package/dist/commands/ui.d.ts +3 -1
  52. package/dist/commands/ui.d.ts.map +1 -1
  53. package/dist/commands/ui.js +76 -19
  54. package/dist/commands/ui.js.map +1 -1
  55. package/dist/core/adapters/local-storage.d.ts +14 -0
  56. package/dist/core/adapters/local-storage.d.ts.map +1 -0
  57. package/dist/core/adapters/local-storage.js +58 -0
  58. package/dist/core/adapters/local-storage.js.map +1 -0
  59. package/dist/core/adapters/obsidian-storage.d.ts +28 -0
  60. package/dist/core/adapters/obsidian-storage.d.ts.map +1 -0
  61. package/dist/core/adapters/obsidian-storage.js +135 -0
  62. package/dist/core/adapters/obsidian-storage.js.map +1 -0
  63. package/dist/core/adapters/registry.d.ts +8 -0
  64. package/dist/core/adapters/registry.d.ts.map +1 -0
  65. package/dist/core/adapters/registry.js +37 -0
  66. package/dist/core/adapters/registry.js.map +1 -0
  67. package/dist/core/adapters/storage.test.d.ts +2 -0
  68. package/dist/core/adapters/storage.test.d.ts.map +1 -0
  69. package/dist/core/adapters/storage.test.js +106 -0
  70. package/dist/core/adapters/storage.test.js.map +1 -0
  71. package/dist/core/adapters/vault-storage.d.ts +16 -0
  72. package/dist/core/adapters/vault-storage.d.ts.map +1 -0
  73. package/dist/core/adapters/vault-storage.js +77 -0
  74. package/dist/core/adapters/vault-storage.js.map +1 -0
  75. package/dist/core/config.d.ts.map +1 -1
  76. package/dist/core/config.js +28 -4
  77. package/dist/core/config.js.map +1 -1
  78. package/dist/core/plugins/index.d.ts +14 -0
  79. package/dist/core/plugins/index.d.ts.map +1 -0
  80. package/dist/core/plugins/index.js +2 -0
  81. package/dist/core/plugins/index.js.map +1 -0
  82. package/dist/core/plugins/loader.d.ts +2 -0
  83. package/dist/core/plugins/loader.d.ts.map +1 -0
  84. package/dist/core/plugins/loader.js +34 -0
  85. package/dist/core/plugins/loader.js.map +1 -0
  86. package/dist/core/ports/storage.d.ts +59 -0
  87. package/dist/core/ports/storage.d.ts.map +1 -0
  88. package/dist/core/ports/storage.js +10 -0
  89. package/dist/core/ports/storage.js.map +1 -0
  90. package/dist/core/storage.d.ts +10 -0
  91. package/dist/core/storage.d.ts.map +1 -0
  92. package/dist/core/storage.js +29 -0
  93. package/dist/core/storage.js.map +1 -0
  94. package/dist/core/workspace.d.ts.map +1 -1
  95. package/dist/core/workspace.js +110 -16
  96. package/dist/core/workspace.js.map +1 -1
  97. package/dist/generators/base.d.ts.map +1 -1
  98. package/dist/generators/base.js +19 -6
  99. package/dist/generators/base.js.map +1 -1
  100. package/dist/generators/diff-context.d.ts +6 -0
  101. package/dist/generators/diff-context.d.ts.map +1 -0
  102. package/dist/generators/diff-context.js +68 -0
  103. package/dist/generators/diff-context.js.map +1 -0
  104. package/dist/generators/index.d.ts +1 -1
  105. package/dist/generators/index.d.ts.map +1 -1
  106. package/dist/generators/index.js +75 -18
  107. package/dist/generators/index.js.map +1 -1
  108. package/dist/generators/map-generator.d.ts.map +1 -1
  109. package/dist/generators/map-generator.js +7 -11
  110. package/dist/generators/map-generator.js.map +1 -1
  111. package/dist/generators/plan-generator.d.ts.map +1 -1
  112. package/dist/generators/plan-generator.js +3 -5
  113. package/dist/generators/plan-generator.js.map +1 -1
  114. package/dist/gui/app_logo.png +0 -0
  115. package/dist/gui/assets/index-CB-jWded.css +1 -0
  116. package/dist/gui/assets/index-DDXpZZu3.js +25 -0
  117. package/dist/gui/index.html +2 -2
  118. package/dist/index.js +174 -20
  119. package/dist/index.js.map +1 -1
  120. package/dist/server.d.ts.map +1 -1
  121. package/dist/server.js +212 -28
  122. package/dist/server.js.map +1 -1
  123. package/dist/server.test.js +173 -38
  124. package/dist/server.test.js.map +1 -1
  125. package/dist/types.d.ts +11 -2
  126. package/dist/types.d.ts.map +1 -1
  127. package/dist/utils/git.d.ts +16 -0
  128. package/dist/utils/git.d.ts.map +1 -1
  129. package/dist/utils/git.js +52 -0
  130. package/dist/utils/git.js.map +1 -1
  131. package/dist/utils/local-ai.d.ts.map +1 -1
  132. package/dist/utils/local-ai.js +7 -3
  133. package/dist/utils/local-ai.js.map +1 -1
  134. package/dist/utils/multi-git.d.ts +2 -0
  135. package/dist/utils/multi-git.d.ts.map +1 -1
  136. package/dist/utils/multi-git.js +5 -2
  137. package/dist/utils/multi-git.js.map +1 -1
  138. package/dist/utils/update-check.d.ts +3 -1
  139. package/dist/utils/update-check.d.ts.map +1 -1
  140. package/dist/utils/update-check.js +23 -34
  141. package/dist/utils/update-check.js.map +1 -1
  142. package/dist/utils/workflow-advisor.d.ts +16 -0
  143. package/dist/utils/workflow-advisor.d.ts.map +1 -0
  144. package/dist/utils/workflow-advisor.js +100 -0
  145. package/dist/utils/workflow-advisor.js.map +1 -0
  146. package/dist/utils/workflows.d.ts +11 -0
  147. package/dist/utils/workflows.d.ts.map +1 -0
  148. package/dist/utils/workflows.js +156 -0
  149. package/dist/utils/workflows.js.map +1 -0
  150. package/dist/utils/workflows.test.d.ts +2 -0
  151. package/dist/utils/workflows.test.d.ts.map +1 -0
  152. package/dist/utils/workflows.test.js +86 -0
  153. package/dist/utils/workflows.test.js.map +1 -0
  154. package/extension/media/icon.svg +1 -0
  155. package/extension/package-lock.json +4893 -1660
  156. package/extension/package.json +58 -11
  157. package/extension/src/extension.ts +476 -27
  158. package/extension/tsconfig.json +4 -2
  159. package/gui/e2e/wizard.spec.ts +19 -0
  160. package/gui/package-lock.json +342 -381
  161. package/gui/package.json +12 -12
  162. package/gui/public/app_logo.png +0 -0
  163. package/gui/src/App.tsx +991 -81
  164. package/gui/src/features/workspace/WorkspaceList.tsx +30 -30
  165. package/gui/src/index.css +64 -22
  166. package/gui/src/main.tsx +89 -5
  167. package/package.json +11 -12
  168. package/resources/workflows/plan-implement-review.md +8 -0
  169. package/resources/workflows/research-verify.md +6 -0
  170. package/resources/workflows/solo-developer.md +3 -0
  171. package/skills-lock.json +11 -0
  172. package/src/commands/adapter.ts +348 -0
  173. package/src/commands/add-repo.ts +0 -1
  174. package/src/commands/commands.test.ts +3 -2
  175. package/src/commands/config.ts +52 -0
  176. package/src/commands/create.ts +14 -17
  177. package/src/commands/desktop.ts +128 -0
  178. package/src/commands/doctor.ts +13 -0
  179. package/src/commands/mcp.ts +2 -0
  180. package/src/commands/refresh.ts +4 -14
  181. package/src/commands/sync.ts +2 -8
  182. package/src/commands/tui.ts +484 -0
  183. package/src/commands/ui.ts +83 -19
  184. package/src/core/adapters/local-storage.ts +66 -0
  185. package/src/core/adapters/obsidian-storage.ts +151 -0
  186. package/src/core/adapters/registry.ts +44 -0
  187. package/src/core/adapters/storage.test.ts +174 -0
  188. package/src/core/adapters/vault-storage.ts +86 -0
  189. package/src/core/config.ts +29 -4
  190. package/src/core/plugins/index.ts +17 -0
  191. package/src/core/plugins/loader.ts +36 -0
  192. package/src/core/ports/storage.ts +71 -0
  193. package/src/core/storage.ts +37 -0
  194. package/src/core/workspace.ts +122 -15
  195. package/src/generators/base.ts +21 -5
  196. package/src/generators/diff-context.ts +75 -0
  197. package/src/generators/index.ts +93 -21
  198. package/src/generators/map-generator.ts +7 -10
  199. package/src/generators/plan-generator.ts +6 -4
  200. package/src/index.ts +178 -21
  201. package/src/server.test.ts +193 -39
  202. package/src/server.ts +238 -28
  203. package/src/types.ts +14 -2
  204. package/src/utils/git.ts +56 -0
  205. package/src/utils/local-ai.ts +8 -3
  206. package/src/utils/multi-git.ts +16 -9
  207. package/src/utils/update-check.ts +42 -31
  208. package/src/utils/workflow-advisor.ts +118 -0
  209. package/src/utils/workflows.test.ts +114 -0
  210. package/src/utils/workflows.ts +178 -0
  211. package/.github/workflows/release.yml +0 -100
  212. package/dist/commands/pack.d.ts +0 -7
  213. package/dist/commands/pack.d.ts.map +0 -1
  214. package/dist/commands/pack.js +0 -64
  215. package/dist/commands/pack.js.map +0 -1
  216. package/dist/core/packer.d.ts +0 -14
  217. package/dist/core/packer.d.ts.map +0 -1
  218. package/dist/core/packer.js +0 -87
  219. package/dist/core/packer.js.map +0 -1
  220. package/dist/core/packer.test.d.ts +0 -2
  221. package/dist/core/packer.test.d.ts.map +0 -1
  222. package/dist/core/packer.test.js +0 -82
  223. package/dist/core/packer.test.js.map +0 -1
  224. package/dist/gui/assets/index-CFWwqFux.js +0 -23
  225. package/dist/gui/assets/index-Dvc9QMvl.css +0 -2
  226. package/src/commands/pack.ts +0 -73
  227. package/src/core/packer.test.ts +0 -99
  228. package/src/core/packer.ts +0 -107
@@ -96,7 +96,7 @@ const parseInlineStyles = (text: string): React.ReactNode => {
96
96
  return <strong key={index} className="font-bold text-gray-200">{part.slice(2, -2)}</strong>;
97
97
  }
98
98
  if (part.startsWith('`') && part.endsWith('`')) {
99
- return <code key={index} className="px-1.5 py-0.5 bg-gray-900 border border-gray-800 text-indigo-300 rounded font-mono text-[10px]">{part.slice(1, -1)}</code>;
99
+ return <code key={index} className="px-1.5 py-0.5 bg-gray-900 border border-gray-800 text-cyan-400 rounded font-mono text-[10px]">{part.slice(1, -1)}</code>;
100
100
  }
101
101
  if (part.startsWith('*') && part.endsWith('*')) {
102
102
  return <em key={index} className="italic text-gray-300">{part.slice(1, -1)}</em>;
@@ -263,13 +263,13 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
263
263
  onClick={fetchWorkspaces}
264
264
  disabled={workspacesLoading}
265
265
  >
266
- <RefreshCw size={14} className={workspacesLoading ? 'animate-spin text-indigo-400' : ''} /> Refresh
266
+ <RefreshCw size={14} className={workspacesLoading ? 'animate-spin text-cyan-400' : ''} /> Refresh
267
267
  </button>
268
268
  </header>
269
269
 
270
270
  {workspacesLoading ? (
271
271
  <div className="flex flex-col items-center py-40 gap-4 text-gray-400">
272
- <RefreshCw className="animate-spin text-indigo-400" size={32} />
272
+ <RefreshCw className="animate-spin text-cyan-400" size={32} />
273
273
  <span className="text-sm">Fetching workspace details...</span>
274
274
  </div>
275
275
  ) : workspaces.length === 0 ? (
@@ -285,10 +285,10 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
285
285
  {workspaces.map((ws) => {
286
286
  const isExpanded = activeWsId === ws.branchName;
287
287
  return (
288
- <div key={ws.id} className="glass-card p-8 rounded-2xl shadow-xl hover:shadow-2xl border border-slate-800/40 relative overflow-hidden transition-all duration-300 before:absolute before:inset-x-0 before:top-0 before:h-[1px] before:bg-gradient-to-r before:from-indigo-500/10 via-purple-500/10 to-transparent">
288
+ <div key={ws.id} className="glass-card p-8 rounded-2xl shadow-xl hover:shadow-2xl border border-slate-800/40 relative overflow-hidden transition-all duration-300 before:absolute before:inset-x-0 before:top-0 before:h-[1px] before:bg-gradient-to-r before:from-cyan-500/10 via-violet-500/10 to-transparent">
289
289
  <div className="flex justify-between items-start gap-4 mb-4">
290
290
  <div>
291
- <h3 className="text-lg font-bold text-white hover:text-indigo-400 transition-colors">{ws.branchName}</h3>
291
+ <h3 className="text-lg font-bold text-white hover:text-cyan-400 transition-colors">{ws.branchName}</h3>
292
292
  <div className="flex items-center gap-3 text-xs text-slate-500 mt-1">
293
293
  <span>Created: {new Date(ws.createdAt).toLocaleDateString()}</span>
294
294
  <span className="h-1 w-1 rounded-full bg-slate-850"></span>
@@ -317,7 +317,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
317
317
  <ExternalLink size={12} /> Open
318
318
  </button>
319
319
  <button
320
- className="inline-flex items-center justify-center gap-1.5 px-3.5 py-2.5 bg-indigo-500 hover:bg-indigo-600 text-white rounded-xl text-xs font-semibold transition-all cursor-pointer shadow-md shadow-indigo-500/10"
320
+ className="inline-flex items-center justify-center gap-1.5 px-3.5 py-2.5 bg-cyan-600 hover:bg-cyan-500 text-white rounded-xl text-xs font-semibold transition-all cursor-pointer shadow-md shadow-cyan-650/10"
321
321
  onClick={() => {
322
322
  if (isExpanded) {
323
323
  setActiveWsId(null);
@@ -339,7 +339,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
339
339
  </div>
340
340
  </div>
341
341
 
342
- <div className="text-xs text-slate-350 bg-slate-950/60 border-l-2 border-indigo-500/80 rounded-r-xl px-5 py-3.5 mb-5 font-normal leading-relaxed relative overflow-hidden before:absolute before:inset-y-0 before:right-0 before:w-12 before:bg-gradient-to-r before:from-transparent before:to-indigo-500/2">
342
+ <div className="text-xs text-slate-350 bg-slate-950/60 border-l-2 border-cyan-500/80 rounded-r-xl px-5 py-3.5 mb-5 font-normal leading-relaxed relative overflow-hidden before:absolute before:inset-y-0 before:right-0 before:w-12 before:bg-gradient-to-r before:from-transparent before:to-cyan-500/2">
343
343
  {renderFormattedDescription(ws.description)}
344
344
  </div>
345
345
 
@@ -356,7 +356,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
356
356
  <div className="flex items-center gap-1.5 ml-auto">
357
357
  <select
358
358
  id={`add-repo-select-feature-${ws.branchName}`}
359
- className="bg-slate-905 border border-slate-800 text-slate-300 rounded-lg text-[10px] px-3 py-1.5 font-semibold outline-none focus:border-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer transition-all hover:border-slate-700"
359
+ className="bg-slate-905 border border-slate-800 text-slate-300 rounded-lg text-[10px] px-3 py-1.5 font-semibold outline-none focus:border-cyan-500 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer transition-all hover:border-slate-700"
360
360
  defaultValue=""
361
361
  onChange={async (e) => {
362
362
  const val = e.target.value;
@@ -389,8 +389,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
389
389
  <button
390
390
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
391
391
  subTab === 'overview'
392
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
393
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
392
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
393
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
394
394
  }`}
395
395
  onClick={() => setSubTab('overview')}
396
396
  >
@@ -399,8 +399,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
399
399
  <button
400
400
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
401
401
  subTab === 'sessions'
402
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
403
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
402
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
403
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
404
404
  }`}
405
405
  onClick={() => setSubTab('sessions')}
406
406
  >
@@ -409,8 +409,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
409
409
  <button
410
410
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
411
411
  subTab === 'services'
412
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
413
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
412
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
413
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
414
414
  }`}
415
415
  onClick={() => setSubTab('services')}
416
416
  >
@@ -419,8 +419,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
419
419
  <button
420
420
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
421
421
  subTab === 'changes'
422
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
423
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
422
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
423
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
424
424
  }`}
425
425
  onClick={() => setSubTab('changes')}
426
426
  >
@@ -429,8 +429,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
429
429
  <button
430
430
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
431
431
  subTab === 'knowledge'
432
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
433
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
432
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
433
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
434
434
  }`}
435
435
  onClick={() => setSubTab('knowledge')}
436
436
  >
@@ -439,8 +439,8 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
439
439
  <button
440
440
  className={`px-4 py-2 rounded-lg text-xs font-bold transition-all cursor-pointer select-none ${
441
441
  subTab === 'plan'
442
- ? 'bg-indigo-500/15 border border-indigo-500/35 text-indigo-300 shadow-[0_0_15px_rgba(99,102,241,0.05)]'
443
- : 'text-slate-500 hover:text-slate-350 hover:bg-slate-900/30 border border-transparent'
442
+ ? 'bg-cyan-950/30 border border-cyan-900/60 text-cyan-400 shadow-[0_0_15px_rgba(6,182,212,0.1)]'
443
+ : 'text-slate-500 hover:text-slate-300 hover:bg-slate-900/40 border border-transparent'
444
444
  }`}
445
445
  onClick={() => setSubTab('plan')}
446
446
  >
@@ -453,7 +453,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
453
453
  {/* Section 1: AI Assistant Harnesses */}
454
454
  <div className="bg-gray-950/20 border border-gray-800/80 rounded-xl p-5">
455
455
  <div className="flex items-center gap-2 mb-4 border-b border-gray-800/80 pb-3">
456
- <Cpu size={18} className="text-indigo-400" />
456
+ <Cpu size={18} className="text-cyan-400" />
457
457
  <h4 className="font-bold text-white">AI Assistant Harnesses</h4>
458
458
  </div>
459
459
  <p className="text-xs text-gray-400 mb-4">
@@ -479,11 +479,11 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
479
479
  <div key={name} className="flex flex-col p-3 bg-gray-900/40 border border-gray-800/60 rounded-lg">
480
480
  <div className="flex items-center justify-between gap-2">
481
481
  <div className="flex items-center gap-2">
482
- <span className={`h-2 w-2 rounded-full ${isConfigured ? 'bg-indigo-500 shadow-sm' : 'bg-gray-700'}`}></span>
482
+ <span className={`h-2 w-2 rounded-full ${isConfigured ? 'bg-cyan-500 shadow-sm' : 'bg-gray-700'}`}></span>
483
483
  <span className="font-semibold text-xs text-gray-200">{displayName}</span>
484
484
  </div>
485
485
  <div className="flex items-center gap-1.5 text-[10px] font-medium">
486
- {isConfigured && <span className="text-indigo-400 bg-indigo-500/10 px-2 py-0.5 rounded border border-indigo-500/20 text-[9px] font-bold uppercase tracking-wider">Active</span>}
486
+ {isConfigured && <span className="text-cyan-400 bg-cyan-950/20 px-2 py-0.5 rounded border border-cyan-900/40 text-[9px] font-bold uppercase tracking-wider">Active</span>}
487
487
  {isDetected ? (
488
488
  <span className="text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded border border-emerald-500/20 text-[9px] font-bold uppercase tracking-wider">Installed</span>
489
489
  ) : (
@@ -493,7 +493,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
493
493
  </div>
494
494
  {isConfigured && resumeCmd && (
495
495
  <div className="mt-2.5 flex items-center justify-between gap-2 bg-gray-950/80 px-2.5 py-1.5 rounded border border-gray-800/60 font-mono text-[10px]">
496
- <span className="text-indigo-300 truncate">{resumeCmd}</span>
496
+ <span className="text-cyan-400 truncate">{resumeCmd}</span>
497
497
  <button
498
498
  onClick={() => handleCopy(resumeCmd)}
499
499
  className="text-gray-400 hover:text-white transition-colors cursor-pointer"
@@ -513,7 +513,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
513
513
  <div className="flex flex-col gap-6">
514
514
  <div className="bg-gray-950/20 border border-gray-800/80 rounded-xl p-5">
515
515
  <div className="flex items-center gap-2 mb-4 border-b border-gray-800/80 pb-3">
516
- <Layers size={18} className="text-indigo-400" />
516
+ <Layers size={18} className="text-cyan-400" />
517
517
  <h4 className="font-bold text-white">Local MCP Server (Tools)</h4>
518
518
  </div>
519
519
  <p className="text-xs text-gray-400 mb-4">
@@ -521,7 +521,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
521
521
  </p>
522
522
  <div className="flex flex-col gap-3.5">
523
523
  <div className="flex flex-col gap-1">
524
- <div className="flex items-center gap-2 text-xs font-semibold text-indigo-300">
524
+ <div className="flex items-center gap-2 text-xs font-semibold text-cyan-455">
525
525
  <code>search_workspace</code>
526
526
  </div>
527
527
  <span className="text-[11px] text-gray-400">
@@ -529,7 +529,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
529
529
  </span>
530
530
  </div>
531
531
  <div className="flex flex-col gap-1 border-t border-gray-800/40 pt-2.5">
532
- <div className="flex items-center gap-2 text-xs font-semibold text-indigo-300">
532
+ <div className="flex items-center gap-2 text-xs font-semibold text-cyan-455">
533
533
  <code>get_service_logs</code>
534
534
  </div>
535
535
  <span className="text-[11px] text-gray-400">
@@ -537,7 +537,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
537
537
  </span>
538
538
  </div>
539
539
  <div className="flex flex-col gap-1 border-t border-gray-800/40 pt-2.5">
540
- <div className="flex items-center gap-2 text-xs font-semibold text-indigo-300">
540
+ <div className="flex items-center gap-2 text-xs font-semibold text-cyan-455">
541
541
  <code>delegate_to_local_agent</code>
542
542
  </div>
543
543
  <span className="text-[11px] text-gray-400">
@@ -550,7 +550,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
550
550
  {/* CLI shortcuts */}
551
551
  <div className="bg-gray-950/20 border border-gray-800/80 rounded-xl p-5">
552
552
  <div className="flex items-center gap-2 mb-4 border-b border-gray-800/80 pb-3">
553
- <Terminal size={18} className="text-indigo-400" />
553
+ <Terminal size={18} className="text-cyan-400" />
554
554
  <h4 className="font-bold text-white">Workspace CLI Shortcuts</h4>
555
555
  </div>
556
556
  <div className="flex flex-col gap-2.5">
@@ -563,7 +563,7 @@ export const WorkspaceList: React.FC<WorkspaceListProps> = ({
563
563
  ].map(({ cmd, desc }) => (
564
564
  <div key={cmd} className="flex flex-col gap-1">
565
565
  <div className="flex items-center justify-between gap-2">
566
- <code className="text-xs text-indigo-300">{cmd}</code>
566
+ <code className="text-xs text-cyan-400">{cmd}</code>
567
567
  <button
568
568
  onClick={() => handleCopy(cmd)}
569
569
  className="text-gray-400 hover:text-white transition-colors cursor-pointer"
package/gui/src/index.css CHANGED
@@ -1,37 +1,80 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Space+Grotesk:wght@300..700&display=swap');
1
2
  @import "tailwindcss";
2
3
 
4
+ /* Global Font Overrides to Monospace */
5
+ body {
6
+ font-family: 'JetBrains Mono', monospace !important;
7
+ background-color: #030408 !important;
8
+ background-image:
9
+ radial-gradient(at 50% 0%, rgba(139, 92, 246, 0.06) 0px, transparent 50%),
10
+ radial-gradient(at 0% 100%, rgba(6, 182, 212, 0.04) 0px, transparent 50%) !important;
11
+ }
12
+
13
+ h1, h2, h3, h4, h5, h6, button, input, select, textarea, code, pre {
14
+ font-family: 'JetBrains Mono', monospace !important;
15
+ }
16
+
3
17
  /* Custom Sleek Scrollbars */
4
18
  ::-webkit-scrollbar {
5
19
  width: 6px;
6
20
  height: 6px;
7
21
  }
8
22
  ::-webkit-scrollbar-track {
9
- background: transparent;
23
+ background: #05070c;
10
24
  }
11
25
  ::-webkit-scrollbar-thumb {
12
- background: rgba(99, 102, 241, 0.15);
13
- border-radius: 8px;
26
+ background: #1f2937;
27
+ border-radius: 3px;
14
28
  border: 1px solid rgba(255, 255, 255, 0.03);
15
29
  }
16
30
  ::-webkit-scrollbar-thumb:hover {
17
- background: rgba(99, 102, 241, 0.3);
31
+ background: #374151;
18
32
  }
19
33
 
20
- /* Glassmorphism and Modern UI Helpers */
34
+ /* Glassmorphism and Terminal UI Helpers */
21
35
  @utility glass-card {
22
- background: rgba(17, 24, 39, 0.45);
23
- backdrop-filter: blur(16px);
24
- -webkit-backdrop-filter: blur(16px);
25
- border: 1px solid rgba(255, 255, 255, 0.05);
26
- box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
36
+ background: rgba(5, 7, 12, 0.6) !important;
37
+ backdrop-filter: blur(12px);
38
+ -webkit-backdrop-filter: blur(12px);
39
+ border: 1px solid rgba(255, 255, 255, 0.04) !important;
40
+ box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.5) !important;
27
41
  }
28
42
 
29
43
  @utility glass-card-glow {
30
- box-shadow: 0 0 15px rgba(99, 102, 241, 0.1), inset 0 0 1px 1px rgba(255, 255, 255, 0.05);
44
+ box-shadow: 0 0 15px rgba(6, 182, 212, 0.05), inset 0 0 1px 1px rgba(255, 255, 255, 0.03);
45
+ }
46
+
47
+ @utility text-glow-cyan {
48
+ text-shadow: 0 0 8px rgba(6, 182, 212, 0.4);
49
+ }
50
+
51
+ @utility text-glow-green {
52
+ text-shadow: 0 0 8px rgba(16, 185, 129, 0.4);
31
53
  }
32
54
 
33
- @utility text-glow-indigo {
34
- text-shadow: 0 0 12px rgba(99, 102, 241, 0.4);
55
+ @utility neon-border {
56
+ box-shadow: 0 0 10px rgba(6, 182, 212, 0.1);
57
+ }
58
+
59
+ @utility neon-border-green {
60
+ box-shadow: 0 0 10px rgba(16, 185, 129, 0.1);
61
+ }
62
+
63
+ /* CRT Scanline effect */
64
+ .crt-screen {
65
+ position: relative;
66
+ }
67
+
68
+ .crt-screen::after {
69
+ content: " ";
70
+ display: block;
71
+ position: absolute;
72
+ top: 0; left: 0; bottom: 0; right: 0;
73
+ background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.2) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.04), rgba(0, 255, 0, 0.01), rgba(0, 255, 0, 0.04));
74
+ z-index: 10;
75
+ background-size: 100% 4px, 6px 100%;
76
+ pointer-events: none;
77
+ opacity: 0.35;
35
78
  }
36
79
 
37
80
  @utility animate-slide-in {
@@ -50,13 +93,13 @@
50
93
  animation: pulse-glow-green 2s infinite ease-in-out;
51
94
  }
52
95
 
53
- @utility animate-pulse-glow-indigo {
54
- animation: pulse-glow-indigo 2.5s infinite ease-in-out;
96
+ @utility animate-pulse-glow-cyan {
97
+ animation: pulse-glow-cyan 2.5s infinite ease-in-out;
55
98
  }
56
99
 
57
100
  @keyframes slide-in {
58
101
  from {
59
- transform: translateY(0.75rem);
102
+ transform: translateY(0.5rem);
60
103
  opacity: 0;
61
104
  }
62
105
  to {
@@ -76,21 +119,21 @@
76
119
 
77
120
  @keyframes pulse-glow-green {
78
121
  0%, 100% {
79
- box-shadow: 0 0 4px rgba(52, 211, 153, 0.2);
122
+ box-shadow: 0 0 4px rgba(52, 211, 153, 0.15);
80
123
  opacity: 0.8;
81
124
  }
82
125
  50% {
83
- box-shadow: 0 0 12px rgba(52, 211, 153, 0.6);
126
+ box-shadow: 0 0 10px rgba(52, 211, 153, 0.4);
84
127
  opacity: 1;
85
128
  }
86
129
  }
87
130
 
88
- @keyframes pulse-glow-indigo {
131
+ @keyframes pulse-glow-cyan {
89
132
  0%, 100% {
90
- box-shadow: 0 0 4px rgba(99, 102, 241, 0.2);
133
+ box-shadow: 0 0 4px rgba(6, 182, 212, 0.15);
91
134
  }
92
135
  50% {
93
- box-shadow: 0 0 14px rgba(99, 102, 241, 0.5);
136
+ box-shadow: 0 0 12px rgba(6, 182, 212, 0.4);
94
137
  }
95
138
  }
96
139
 
@@ -107,4 +150,3 @@
107
150
  color: #e5e7eb;
108
151
  background-color: #0b0f19;
109
152
  }
110
-
package/gui/src/main.tsx CHANGED
@@ -3,8 +3,92 @@ import { createRoot } from 'react-dom/client'
3
3
  import './index.css'
4
4
  import App from './App.tsx'
5
5
 
6
- createRoot(document.getElementById('root')!).render(
7
- <StrictMode>
8
- <App />
9
- </StrictMode>,
10
- )
6
+ declare global {
7
+ interface Window {
8
+ Neutralino?: any;
9
+ NL_PATH?: string;
10
+ }
11
+ }
12
+
13
+ async function waitForBackend(url: string, maxRetries = 25, delay = 200): Promise<boolean> {
14
+ for (let i = 0; i < maxRetries; i++) {
15
+ try {
16
+ const res = await fetch(url);
17
+ if (res.ok) {
18
+ console.log(`Backend connection established on attempt ${i + 1}`);
19
+ return true;
20
+ }
21
+ } catch {
22
+ // Ignored, retry
23
+ }
24
+ await new Promise((resolve) => setTimeout(resolve, delay));
25
+ }
26
+ console.warn(`Backend connection timed out after ${maxRetries} attempts`);
27
+ return false;
28
+ }
29
+
30
+ function renderApp() {
31
+ createRoot(document.getElementById('root')!).render(
32
+ <StrictMode>
33
+ <App />
34
+ </StrictMode>,
35
+ );
36
+ }
37
+
38
+ if (typeof window !== 'undefined' && window.Neutralino) {
39
+ window.Neutralino.init();
40
+ window.Neutralino.events.on('windowClose', () => {
41
+ window.Neutralino.app.exit();
42
+ });
43
+
44
+ (async () => {
45
+ const backendUrl = 'http://localhost:3000/api/config';
46
+ try {
47
+ const res = await fetch(backendUrl);
48
+ if (res.ok) {
49
+ console.log('NexusFlow Hono backend is already running.');
50
+ renderApp();
51
+ return;
52
+ }
53
+ } catch {
54
+ console.log('NexusFlow Hono backend not detected. Launching...');
55
+ try {
56
+ const isWin = navigator.platform.includes('Win') || navigator.userAgent.includes('Windows');
57
+ const nlPath = window.NL_PATH || '.';
58
+
59
+ // Construct paths for packaged mode
60
+ const nodeBinary = isWin ? `${nlPath}/node/node.exe` : `${nlPath}/node/bin/node`;
61
+ const serverScript = `${nlPath}/server/dist/index.js`;
62
+
63
+ // Check if we are running in packaged mode by testing if the embedded node exists
64
+ let isPackaged = false;
65
+ try {
66
+ await window.Neutralino.filesystem.getStats(nodeBinary);
67
+ isPackaged = true;
68
+ } catch {
69
+ // File doesn't exist or filesystem API failed, meaning dev mode
70
+ }
71
+
72
+ let cmd: string;
73
+ if (isPackaged) {
74
+ console.log('Running in packaged mode, using embedded node and server...');
75
+ cmd = `"${nodeBinary}" "${serverScript}" ui --server-only --port 3000`;
76
+ } else {
77
+ console.log('Running in development mode, using global node and relative path...');
78
+ cmd = 'node ../NexusFlow/dist/index.js ui --server-only --port 3000';
79
+ }
80
+
81
+ console.log('Spawning backend command:', cmd);
82
+ await window.Neutralino.os.execCommand(cmd, { background: true });
83
+ console.log('Hono backend successfully spawned. Waiting for port 3000...');
84
+ await waitForBackend(backendUrl);
85
+ } catch (err) {
86
+ console.error('Failed to spawn Hono backend:', err);
87
+ } finally {
88
+ renderApp();
89
+ }
90
+ }
91
+ })();
92
+ } else {
93
+ renderApp();
94
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrpatronz/nexusflow",
3
- "version": "0.2.13",
3
+ "version": "0.2.18",
4
4
  "description": "Combine multiple repos into a workspace with rich AI assistant context",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -8,7 +8,7 @@
8
8
  "nexusflow": "dist/index.js"
9
9
  },
10
10
  "scripts": {
11
- "build": "tsc && npm run build --prefix gui && npm run extension:compile",
11
+ "build": "tsc && npm run build --prefix gui",
12
12
  "dev": "tsc --watch",
13
13
  "start": "node dist/index.js",
14
14
  "ui": "node dist/index.js ui",
@@ -34,23 +34,22 @@
34
34
  "license": "MIT",
35
35
  "dependencies": {
36
36
  "@hono/node-server": "^2.0.4",
37
- "@inquirer/prompts": "^7.0.0",
37
+ "@inquirer/prompts": "^8.5.2",
38
38
  "@modelcontextprotocol/sdk": "^1.29.0",
39
39
  "chalk": "^5.3.0",
40
- "commander": "^13.0.0",
40
+ "commander": "^15.0.0",
41
41
  "execa": "^9.5.0",
42
42
  "fs-extra": "^11.2.0",
43
- "globby": "^14.1.0",
44
- "hono": "^4.12.23",
45
- "ora": "^8.1.0",
46
- "pm2": "^7.0.1",
47
- "repomix": "^1.14.1"
43
+ "globby": "^16.2.0",
44
+ "hono": "^4.12.25",
45
+ "ora": "^9.4.0",
46
+ "pm2": "^7.0.1"
48
47
  },
49
48
  "devDependencies": {
50
49
  "@types/fs-extra": "^11.0.4",
51
- "@types/node": "^22.0.0",
50
+ "@types/node": "^25.9.3",
52
51
  "rimraf": "^6.0.0",
53
- "typescript": "^5.7.0",
54
- "vitest": "^3.0.0"
52
+ "typescript": "^6.0.3",
53
+ "vitest": "^4.1.8"
55
54
  }
56
55
  }
@@ -0,0 +1,8 @@
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.
@@ -0,0 +1,6 @@
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.
@@ -0,0 +1,3 @@
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.
@@ -0,0 +1,11 @@
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
+ }