@mrpatronz/nexusflow 0.2.17 → 0.2.19

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 (320) 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/dependabot.yml +52 -52
  5. package/.github/workflows/ci.yml +44 -0
  6. package/.github/workflows/dependabot-merge.yml +53 -53
  7. package/.github/workflows/release-desktop.yml +67 -0
  8. package/.github/workflows/release-npm.yml +65 -0
  9. package/.github/workflows/release-vscode.yml +61 -0
  10. package/.vscode/launch.json +17 -17
  11. package/.vscode/tasks.json +17 -17
  12. package/GETTING_STARTED.md +114 -114
  13. package/README.md +364 -336
  14. package/desktop/build-installer.js +228 -228
  15. package/desktop/build.js +118 -118
  16. package/desktop/installer/nexusflow.iss +35 -35
  17. package/desktop/neutralino.config.json +38 -38
  18. package/desktop/package-lock.json +1060 -1060
  19. package/desktop/package.json +14 -14
  20. package/dist/commands/adapter.d.ts +27 -0
  21. package/dist/commands/adapter.d.ts.map +1 -0
  22. package/dist/commands/adapter.js +318 -0
  23. package/dist/commands/adapter.js.map +1 -0
  24. package/dist/commands/add-repo.d.ts.map +1 -1
  25. package/dist/commands/add-repo.js +0 -1
  26. package/dist/commands/add-repo.js.map +1 -1
  27. package/dist/commands/commands.test.js +2 -2
  28. package/dist/commands/commands.test.js.map +1 -1
  29. package/dist/commands/config.d.ts +22 -0
  30. package/dist/commands/config.d.ts.map +1 -0
  31. package/dist/commands/config.js +50 -0
  32. package/dist/commands/config.js.map +1 -0
  33. package/dist/commands/create.d.ts.map +1 -1
  34. package/dist/commands/create.js +14 -17
  35. package/dist/commands/create.js.map +1 -1
  36. package/dist/commands/doctor.d.ts.map +1 -1
  37. package/dist/commands/doctor.js +11 -0
  38. package/dist/commands/doctor.js.map +1 -1
  39. package/dist/commands/refresh.d.ts +1 -0
  40. package/dist/commands/refresh.d.ts.map +1 -1
  41. package/dist/commands/refresh.js +2 -14
  42. package/dist/commands/refresh.js.map +1 -1
  43. package/dist/commands/sync.d.ts.map +1 -1
  44. package/dist/commands/sync.js +36 -54
  45. package/dist/commands/sync.js.map +1 -1
  46. package/dist/commands/tui.d.ts.map +1 -1
  47. package/dist/commands/tui.js +63 -10
  48. package/dist/commands/tui.js.map +1 -1
  49. package/dist/core/adapters/local-storage.d.ts +14 -0
  50. package/dist/core/adapters/local-storage.d.ts.map +1 -0
  51. package/dist/core/adapters/local-storage.js +58 -0
  52. package/dist/core/adapters/local-storage.js.map +1 -0
  53. package/dist/core/adapters/obsidian-storage.d.ts +28 -0
  54. package/dist/core/adapters/obsidian-storage.d.ts.map +1 -0
  55. package/dist/core/adapters/obsidian-storage.js +135 -0
  56. package/dist/core/adapters/obsidian-storage.js.map +1 -0
  57. package/dist/core/adapters/registry.d.ts +8 -0
  58. package/dist/core/adapters/registry.d.ts.map +1 -0
  59. package/dist/core/adapters/registry.js +37 -0
  60. package/dist/core/adapters/registry.js.map +1 -0
  61. package/dist/core/adapters/storage.test.d.ts +2 -0
  62. package/dist/core/adapters/storage.test.d.ts.map +1 -0
  63. package/dist/core/adapters/storage.test.js +106 -0
  64. package/dist/core/adapters/storage.test.js.map +1 -0
  65. package/dist/core/adapters/vault-storage.d.ts +16 -0
  66. package/dist/core/adapters/vault-storage.d.ts.map +1 -0
  67. package/dist/core/adapters/vault-storage.js +77 -0
  68. package/dist/core/adapters/vault-storage.js.map +1 -0
  69. package/dist/core/config.d.ts.map +1 -1
  70. package/dist/core/config.js +28 -4
  71. package/dist/core/config.js.map +1 -1
  72. package/dist/core/plugins/index.d.ts +14 -0
  73. package/dist/core/plugins/index.d.ts.map +1 -0
  74. package/dist/core/plugins/index.js +2 -0
  75. package/dist/core/plugins/index.js.map +1 -0
  76. package/dist/core/plugins/loader.d.ts +2 -0
  77. package/dist/core/plugins/loader.d.ts.map +1 -0
  78. package/dist/core/plugins/loader.js +34 -0
  79. package/dist/core/plugins/loader.js.map +1 -0
  80. package/dist/core/ports/storage.d.ts +59 -0
  81. package/dist/core/ports/storage.d.ts.map +1 -0
  82. package/dist/core/ports/storage.js +10 -0
  83. package/dist/core/ports/storage.js.map +1 -0
  84. package/dist/core/storage.d.ts +10 -0
  85. package/dist/core/storage.d.ts.map +1 -0
  86. package/dist/core/storage.js +29 -0
  87. package/dist/core/storage.js.map +1 -0
  88. package/dist/core/sync.d.ts +44 -0
  89. package/dist/core/sync.d.ts.map +1 -0
  90. package/dist/core/sync.js +82 -0
  91. package/dist/core/sync.js.map +1 -0
  92. package/dist/core/workspace-state.d.ts +51 -0
  93. package/dist/core/workspace-state.d.ts.map +1 -0
  94. package/dist/core/workspace-state.js +108 -0
  95. package/dist/core/workspace-state.js.map +1 -0
  96. package/dist/core/workspace-state.test.d.ts +2 -0
  97. package/dist/core/workspace-state.test.d.ts.map +1 -0
  98. package/dist/core/workspace-state.test.js +84 -0
  99. package/dist/core/workspace-state.test.js.map +1 -0
  100. package/dist/core/workspace.d.ts.map +1 -1
  101. package/dist/core/workspace.js +110 -16
  102. package/dist/core/workspace.js.map +1 -1
  103. package/dist/generators/base.d.ts.map +1 -1
  104. package/dist/generators/base.js +80 -79
  105. package/dist/generators/base.js.map +1 -1
  106. package/dist/generators/codex.js +11 -11
  107. package/dist/generators/copilot.js +17 -17
  108. package/dist/generators/cursor.js +5 -5
  109. package/dist/generators/diff-context.d.ts +6 -0
  110. package/dist/generators/diff-context.d.ts.map +1 -0
  111. package/dist/generators/diff-context.js +68 -0
  112. package/dist/generators/diff-context.js.map +1 -0
  113. package/dist/generators/index.d.ts +1 -1
  114. package/dist/generators/index.d.ts.map +1 -1
  115. package/dist/generators/index.js +125 -68
  116. package/dist/generators/index.js.map +1 -1
  117. package/dist/generators/map-generator.d.ts.map +1 -1
  118. package/dist/generators/map-generator.js +21 -25
  119. package/dist/generators/map-generator.js.map +1 -1
  120. package/dist/generators/plan-generator.d.ts.map +1 -1
  121. package/dist/generators/plan-generator.js +3 -5
  122. package/dist/generators/plan-generator.js.map +1 -1
  123. package/dist/generators/skills-generator.js +28 -28
  124. package/dist/gui/assets/index-Bdbld6yY.css +1 -0
  125. package/dist/gui/assets/index-D8iJPvnk.js +26 -0
  126. package/dist/gui/icons.svg +24 -24
  127. package/dist/gui/index.html +18 -18
  128. package/dist/index.js +131 -20
  129. package/dist/index.js.map +1 -1
  130. package/dist/mcp/server.d.ts.map +1 -1
  131. package/dist/mcp/server.js +42 -0
  132. package/dist/mcp/server.js.map +1 -1
  133. package/dist/server.d.ts.map +1 -1
  134. package/dist/server.js +140 -56
  135. package/dist/server.js.map +1 -1
  136. package/dist/server.test.js +105 -48
  137. package/dist/server.test.js.map +1 -1
  138. package/dist/types.d.ts +38 -2
  139. package/dist/types.d.ts.map +1 -1
  140. package/dist/utils/local-ai.d.ts.map +1 -1
  141. package/dist/utils/local-ai.js +7 -3
  142. package/dist/utils/local-ai.js.map +1 -1
  143. package/dist/utils/multi-git.d.ts +33 -8
  144. package/dist/utils/multi-git.d.ts.map +1 -1
  145. package/dist/utils/multi-git.js +91 -19
  146. package/dist/utils/multi-git.js.map +1 -1
  147. package/dist/utils/multi-git.test.d.ts +2 -0
  148. package/dist/utils/multi-git.test.d.ts.map +1 -0
  149. package/dist/utils/multi-git.test.js +125 -0
  150. package/dist/utils/multi-git.test.js.map +1 -0
  151. package/dist/utils/update-check.d.ts.map +1 -1
  152. package/dist/utils/update-check.js +0 -28
  153. package/dist/utils/update-check.js.map +1 -1
  154. package/dist/utils/workflow-advisor.d.ts +16 -0
  155. package/dist/utils/workflow-advisor.d.ts.map +1 -0
  156. package/dist/utils/workflow-advisor.js +100 -0
  157. package/dist/utils/workflow-advisor.js.map +1 -0
  158. package/extension/package-lock.json +6044 -2673
  159. package/extension/package.json +117 -108
  160. package/extension/src/extension.ts +653 -631
  161. package/extension/tsconfig.json +21 -21
  162. package/gui/README.md +73 -73
  163. package/gui/e2e/dashboard.spec.ts +61 -0
  164. package/gui/e2e/wizard.spec.ts +346 -346
  165. package/gui/eslint.config.js +26 -26
  166. package/gui/index.html +17 -17
  167. package/gui/package-lock.json +3137 -3079
  168. package/gui/package.json +37 -36
  169. package/gui/playwright.config.ts +41 -41
  170. package/gui/public/icons.svg +24 -24
  171. package/gui/src/App.css +1 -1
  172. package/gui/src/App.tsx +3573 -3407
  173. package/gui/src/app/AppSidebar.tsx +69 -0
  174. package/gui/src/assets/vite.svg +1 -1
  175. package/gui/src/components/AddRepoPicker.tsx +81 -0
  176. package/gui/src/components/ui/Button.tsx +40 -0
  177. package/gui/src/components/ui/Card.tsx +6 -0
  178. package/gui/src/components/ui/EmptyState.tsx +22 -0
  179. package/gui/src/components/ui/Input.tsx +21 -0
  180. package/gui/src/components/ui/Menu.tsx +71 -0
  181. package/gui/src/components/ui/Modal.tsx +39 -0
  182. package/gui/src/components/ui/PageHeader.tsx +21 -0
  183. package/gui/src/components/ui/RepoStatusStrip.tsx +33 -0
  184. package/gui/src/components/ui/Skeleton.tsx +5 -0
  185. package/gui/src/components/ui/StatusPill.tsx +36 -0
  186. package/gui/src/components/ui/Tabs.tsx +40 -0
  187. package/gui/src/components/ui/cn.ts +4 -0
  188. package/gui/src/components/ui/index.ts +16 -0
  189. package/gui/src/features/changes/ChangesViewer.tsx +388 -388
  190. package/gui/src/features/knowledge/KnowledgeBase.tsx +84 -84
  191. package/gui/src/features/onboarding/OnboardingWizard.tsx +230 -230
  192. package/gui/src/features/plan/ImplementationPlan.tsx +32 -32
  193. package/gui/src/features/services/ServiceConsole.tsx +215 -250
  194. package/gui/src/features/sessions/SessionHistory.tsx +195 -195
  195. package/gui/src/index.css +167 -152
  196. package/gui/src/lib/status.ts +24 -0
  197. package/gui/src/main.tsx +94 -94
  198. package/gui/src/pages/DashboardPage.tsx +129 -0
  199. package/gui/src/pages/WorkspacesPage.tsx +352 -0
  200. package/gui/src/types.ts +81 -62
  201. package/gui/tsconfig.app.json +25 -25
  202. package/gui/tsconfig.json +7 -7
  203. package/gui/tsconfig.node.json +24 -24
  204. package/gui/vite.config.ts +12 -12
  205. package/package.json +55 -56
  206. package/resources/workflows/plan-implement-review.md +8 -8
  207. package/resources/workflows/research-verify.md +6 -6
  208. package/resources/workflows/solo-developer.md +3 -3
  209. package/scripts/simulate-workspaces.ts +55 -55
  210. package/skills-lock.json +11 -0
  211. package/src/analyzers/detect-apis.ts +290 -290
  212. package/src/analyzers/detect-deps.ts +315 -315
  213. package/src/analyzers/detect-existing.ts +74 -74
  214. package/src/analyzers/detect-ports.ts +110 -110
  215. package/src/analyzers/index.ts +97 -97
  216. package/src/analyzers/messaging-analyzer.ts +254 -254
  217. package/src/analyzers/readme-summarizer.ts +102 -102
  218. package/src/analyzers/run-analyzer.ts +269 -269
  219. package/src/analyzers/tech-stack.ts +283 -283
  220. package/src/commands/adapter.ts +348 -0
  221. package/src/commands/add-repo.ts +156 -157
  222. package/src/commands/commands.test.ts +156 -155
  223. package/src/commands/commit.ts +131 -131
  224. package/src/commands/config.ts +52 -0
  225. package/src/commands/create.ts +204 -207
  226. package/src/commands/desktop.ts +128 -128
  227. package/src/commands/diff.ts +125 -125
  228. package/src/commands/doctor.ts +370 -357
  229. package/src/commands/handoff.ts +266 -266
  230. package/src/commands/init.ts +134 -134
  231. package/src/commands/list.ts +46 -46
  232. package/src/commands/logs.ts +63 -63
  233. package/src/commands/mcp.ts +94 -92
  234. package/src/commands/open.ts +129 -129
  235. package/src/commands/refresh.ts +137 -147
  236. package/src/commands/remove.ts +98 -98
  237. package/src/commands/start.ts +117 -117
  238. package/src/commands/status.ts +54 -54
  239. package/src/commands/stop.ts +55 -55
  240. package/src/commands/sync.ts +125 -151
  241. package/src/commands/tui.ts +484 -424
  242. package/src/commands/ui.ts +111 -111
  243. package/src/core/adapters/local-storage.ts +66 -0
  244. package/src/core/adapters/obsidian-storage.ts +151 -0
  245. package/src/core/adapters/registry.ts +44 -0
  246. package/src/core/adapters/storage.test.ts +174 -0
  247. package/src/core/adapters/vault-storage.ts +86 -0
  248. package/src/core/config.test.ts +96 -96
  249. package/src/core/config.ts +140 -115
  250. package/src/core/graph.ts +344 -344
  251. package/src/core/plugins/index.ts +17 -0
  252. package/src/core/plugins/loader.ts +36 -0
  253. package/src/core/ports/storage.ts +71 -0
  254. package/src/core/scanner.test.ts +61 -61
  255. package/src/core/scanner.ts +91 -91
  256. package/src/core/storage.ts +37 -0
  257. package/src/core/sync.ts +121 -0
  258. package/src/core/workspace-state.test.ts +108 -0
  259. package/src/core/workspace-state.ts +130 -0
  260. package/src/core/workspace.ts +487 -380
  261. package/src/core/worktree.ts +120 -120
  262. package/src/generators/antigravity.ts +32 -32
  263. package/src/generators/base.ts +243 -240
  264. package/src/generators/claude.ts +34 -34
  265. package/src/generators/codex.ts +48 -48
  266. package/src/generators/copilot.ts +56 -56
  267. package/src/generators/cursor.ts +44 -44
  268. package/src/generators/diff-context.ts +75 -0
  269. package/src/generators/index.ts +322 -250
  270. package/src/generators/map-generator.test.ts +159 -159
  271. package/src/generators/map-generator.ts +539 -542
  272. package/src/generators/plan-generator.ts +483 -481
  273. package/src/generators/skills-generator.ts +259 -259
  274. package/src/index.ts +539 -426
  275. package/src/mcp/server.ts +338 -294
  276. package/src/orchestration/detect.ts +313 -313
  277. package/src/orchestration/index.ts +7 -7
  278. package/src/orchestration/runner.ts +283 -283
  279. package/src/server.test.ts +618 -555
  280. package/src/server.ts +1402 -1308
  281. package/src/types.ts +451 -408
  282. package/src/utils/detect-ai.test.ts +44 -44
  283. package/src/utils/detect-ai.ts +84 -84
  284. package/src/utils/detect-editors.test.ts +48 -48
  285. package/src/utils/detect-editors.ts +57 -57
  286. package/src/utils/git.test.ts +74 -74
  287. package/src/utils/git.ts +117 -117
  288. package/src/utils/local-ai.test.ts +130 -130
  289. package/src/utils/local-ai.ts +116 -111
  290. package/src/utils/multi-git.test.ts +158 -0
  291. package/src/utils/multi-git.ts +405 -313
  292. package/src/utils/prompts.ts +209 -209
  293. package/src/utils/session-finder.ts +483 -483
  294. package/src/utils/system-scanner.test.ts +89 -89
  295. package/src/utils/system-scanner.ts +96 -96
  296. package/src/utils/update-check.ts +286 -309
  297. package/src/utils/workflow-advisor.ts +118 -0
  298. package/src/utils/workflows.test.ts +114 -114
  299. package/src/utils/workflows.ts +178 -178
  300. package/tsconfig.json +19 -19
  301. package/vitest.config.ts +14 -14
  302. package/.github/workflows/release.yml +0 -112
  303. package/dist/commands/pack.d.ts +0 -7
  304. package/dist/commands/pack.d.ts.map +0 -1
  305. package/dist/commands/pack.js +0 -64
  306. package/dist/commands/pack.js.map +0 -1
  307. package/dist/core/packer.d.ts +0 -14
  308. package/dist/core/packer.d.ts.map +0 -1
  309. package/dist/core/packer.js +0 -87
  310. package/dist/core/packer.js.map +0 -1
  311. package/dist/core/packer.test.d.ts +0 -2
  312. package/dist/core/packer.test.d.ts.map +0 -1
  313. package/dist/core/packer.test.js +0 -82
  314. package/dist/core/packer.test.js.map +0 -1
  315. package/dist/gui/assets/index-Ct3qq-X4.js +0 -25
  316. package/dist/gui/assets/index-P_ZrgHXg.css +0 -1
  317. package/gui/src/features/workspace/WorkspaceList.tsx +0 -666
  318. package/src/commands/pack.ts +0 -73
  319. package/src/core/packer.test.ts +0 -99
  320. package/src/core/packer.ts +0 -107
@@ -1,240 +1,243 @@
1
- /**
2
- * @module generators/base
3
- * Builds the shared markdown context content that all AI assistant generators
4
- * use as their foundation. Now includes rich project analysis data when available.
5
- */
6
-
7
- import * as path from 'node:path';
8
- import * as fs from 'node:fs';
9
- import * as os from 'node:os';
10
- import type { WorkspaceContext, ProjectAnalysis } from '../types.js';
11
-
12
- /**
13
- * Formats a ProjectAnalysis into a readable markdown section.
14
- */
15
- function formatProjectSection(analysis: ProjectAnalysis, workspacePath: string): string {
16
- const lines: string[] = [];
17
-
18
- lines.push(`### ${analysis.name}`);
19
-
20
- const mapPath = path.join(workspacePath, `nexusflow-map-${analysis.name}.md`).replace(/\\/g, '/');
21
- lines.push(`- **Architecture Map**: [nexusflow-map-${analysis.name}.md](file:///${mapPath}) — **Instruction**: Before modifying this repository, read its architecture map. For exploration, consult the map's section index on demand.`);
22
-
23
- // Tech stack
24
- const { techStack } = analysis;
25
- if (techStack.languages.length > 0 && techStack.languages[0] !== 'other') {
26
- const langStr = techStack.languages.join(', ');
27
- const fwStr = techStack.frameworks.length > 0 ? techStack.frameworks.join(', ') : 'none detected';
28
- const buildStr = techStack.buildTools.length > 0 ? techStack.buildTools.join(', ') : 'none detected';
29
-
30
- lines.push(`- **Type**: ${techStack.projectType}`);
31
- lines.push(`- **Languages**: ${langStr}`);
32
- lines.push(`- **Frameworks**: ${fwStr}`);
33
- lines.push(`- **Build tools**: ${buildStr}`);
34
- }
35
-
36
- // README summary
37
- if (analysis.readmeSummary) {
38
- // Take first 200 chars of README summary as purpose
39
- const purpose = analysis.readmeSummary
40
- .replace(/^#\s+.+\n?/, '') // Remove h1 title
41
- .trim()
42
- .slice(0, 200)
43
- .trim();
44
- if (purpose) {
45
- lines.push(`- **Purpose**: ${purpose}`);
46
- }
47
- }
48
-
49
- // API endpoints
50
- if (analysis.endpoints.length > 0) {
51
- lines.push(`- **API surface**: ${analysis.endpoints.length} endpoints — see architecture map for details`);
52
- }
53
-
54
- // Ports
55
- if (analysis.ports.length > 0) {
56
- const portStr = analysis.ports.map((p) => `${p.port} (${p.protocol}, from ${p.source})`).join(', ');
57
- lines.push(`- **Ports**: ${portStr}`);
58
- }
59
-
60
- // Path
61
- lines.push(`- **Path**: \`${analysis.path}\``);
62
-
63
- return lines.join('\n');
64
- }
65
-
66
- /**
67
- * Builds the shared markdown context content that all AI assistant generators
68
- * use as their foundation. Includes analysis data if available.
69
- *
70
- * @param ctx - The workspace context containing feature metadata, repo list, and optional analysis.
71
- * @returns A markdown string with feature details, repo listing, and task instructions.
72
- */
73
- export function buildContextContent(ctx: WorkspaceContext): string {
74
- const { feature, repos, analysis } = ctx;
75
- const workspacePath = feature.workspacePath;
76
- const localLlmEnabled = feature.localLlmEnabled ?? false;
77
-
78
- // Build project sections — rich if analysis is available, simple if not
79
- let projectSections: string;
80
-
81
- if (analysis && analysis.size > 0) {
82
- const sections = repos.map((r) => {
83
- const a = analysis.get(r.path);
84
- if (a) return formatProjectSection(a, workspacePath);
85
- return `### ${r.name}\n- **Path**: \`${r.path}\``;
86
- });
87
- projectSections = sections.join('\n\n');
88
- } else {
89
- projectSections = repos
90
- .map((r) => `- **${r.name}** — \`${r.path}\` (default branch: \`${r.defaultBranch}\`)`)
91
- .join('\n');
92
- }
93
-
94
- // Build existing AI configs section
95
- let existingConfigsSection = '';
96
- if (analysis && analysis.size > 0) {
97
- const allConfigs: string[] = [];
98
- for (const [, a] of analysis) {
99
- for (const config of a.existingAIConfigs) {
100
- allConfigs.push(`- **${a.name}** has \`${config.relativePath}\` (${config.assistant})`);
101
- }
102
- }
103
- if (allConfigs.length > 0) {
104
- existingConfigsSection = `
105
- ---
106
-
107
- ## Existing AI Configurations
108
-
109
- The following repos already have AI assistant configuration files.
110
- Incorporate their instructions when working in those repos:
111
-
112
- ${allConfigs.join('\n')}
113
- `;
114
- }
115
- }
116
-
117
- // Resumption commands section
118
- let resumptionSection = '';
119
- if (feature.resumption) {
120
- let { testCommand, mockCommand, startCommand } = feature.resumption;
121
- const parts: string[] = [];
122
- if (mockCommand) parts.push(`- **Setup/Mock Command**: \`${mockCommand}\``);
123
- if (startCommand) parts.push(`- **Start/Run Command**: \`${startCommand}\``);
124
-
125
- const standardCommands = [
126
- 'npm run test', 'npm test', 'npm t', 'yarn test', 'yarn t', 'pnpm test', 'pnpm t', 'bun test',
127
- 'dotnet test',
128
- 'pytest', 'python -m unittest', 'python -m pytest',
129
- 'go test', 'go test ./...',
130
- 'cargo test',
131
- ];
132
-
133
- if (testCommand) {
134
- const normalizedCmd = testCommand.trim().toLowerCase();
135
- const isStandard = standardCommands.some(cmd => normalizedCmd === cmd || normalizedCmd.startsWith(cmd + ' '));
136
- if (!isStandard) {
137
- parts.push(`- **Verification/Test Command**: \`${testCommand}\``);
138
- }
139
- }
140
-
141
- if (parts.length > 0) {
142
- resumptionSection = `
143
- ---
144
-
145
- ## Workspace Resumption & Verification Commands
146
-
147
- Use these pre-configured commands to spin up mocks, run background services, and verify your changes:
148
-
149
- ${parts.join('\n')}
150
- `;
151
- }
152
- }
153
-
154
- const knowledgePath = path.join(workspacePath, 'nexusflow-knowledge.md').replace(/\\/g, '/');
155
-
156
- let setupDone = false;
157
- try {
158
- const realKnowledgePath = path.join(workspacePath, 'nexusflow-knowledge.md');
159
- if (fs.existsSync(realKnowledgePath)) {
160
- const content = fs.readFileSync(realKnowledgePath, 'utf-8');
161
- if (!content.includes('No assumptions recorded yet') && !content.includes('AI assistant to populate')) {
162
- setupDone = true;
163
- }
164
- }
165
- } catch {}
166
-
167
- // Teamwork strategy section
168
- let teamworkSection = '';
169
- if (feature.teamworkInstructions) {
170
- teamworkSection = `
171
- ---
172
-
173
- ## Team Collaboration Strategy
174
-
175
- ${feature.teamworkInstructions}
176
- `;
177
- }
178
-
179
- const taskSection = setupDone
180
- ? `## Setup Status\n\n✅ **Setup Completed**: Project assumptions and initial questions have been addressed. Refer to [nexusflow-knowledge.md](file:///${knowledgePath}) for persistent session details.`
181
- : `## First Steps\n\nYour very first task upon entering this workspace is to explore the codebase and align with the user:\n\n1. **Verify Assumptions**: Open [nexusflow-knowledge.md](file:///${knowledgePath}) and fill in the **Project Assumptions** section with a brief description of what each project does, its tech stack, and responsibilities.\n2. **Raise Questions**: Document any outstanding uncertainties or architectural questions in the **Clarifying Questions for the User** section.\n3. **Obtain Approval**: Ask the user to confirm your assumptions and answer your questions before writing any code.`;
182
-
183
- return `# Multi-Repo Workspace Context
184
-
185
- ## Feature: ${feature.id}
186
-
187
- **Description:** ${feature.description}
188
-
189
- > For the detailed feature specification, architecture decisions, and session memory, see [nexusflow-knowledge.md](file:///${knowledgePath}).
190
-
191
- ---
192
-
193
- ## Projects
194
-
195
- This workspace contains the following projects, each checked out as a
196
- git worktree on the feature branch:
197
-
198
- ${projectSections}
199
- ${existingConfigsSection}
200
- ${resumptionSection}
201
- ---
202
-
203
- ${taskSection}
204
- ${teamworkSection}
205
- ---
206
-
207
- ## Guidelines
208
-
209
- - **Multi-Repo Workspace Structure**: This workspace is a multi-repository developer environment where each project subdirectory (e.g. \`my-api\`, \`my-frontend\`) is a separate Git worktree checked out on the feature branch \`${feature.branchName}\`.
210
- - **All code changes** must be made within the appropriate project subdirectories.
211
- - **Worktree Isolation**: Under no circumstances should you edit files, read code, or run commands in the original/main repository directories outside of this workspace folder. All development must be strictly contained within the checked-out worktree subdirectories of this workspace.
212
- - **Git commands** (like \`git status\`, \`git add\`, \`git commit\`, \`git push\`) must be run inside the specific project subdirectories (e.g. \`cd my-api && git commit -m "..."\`), NOT in the workspace root.
213
- - **Project commands** (like \`npm install\`, \`npm run build\`, \`npm run test\`) must be run inside the project subdirectories.
214
- - **Global helpers**: Alternatively, you can run NexusFlow CLI commands from the workspace root:
215
- - \`nexusflow diff\` view changes across all sub-repositories.
216
- - \`nexusflow commit\` commit and push changes across modified repositories.
217
- - \`nexusflow sync\` rebase all repositories with their default base branches.
218
- - \`nexusflow refresh\` — regenerate maps, context files and plans without rebasing.
219
- - \`nexusflow doctor\` — run diagnostics to verify workspace health.
220
- - **Workspace Knowledge**: Read \`nexusflow-knowledge.md\` at the start of every session. It serves as the persistent memory for this feature. Before ending your session, append significant architecture decisions, discovered gotchas, and checklist progress to \`nexusflow-knowledge.md\`. Never delete or overwrite existing knowledge/decisions only append.
221
- - **Implementation Plan**: Refer to \`nexusflow-plan.md\` for the suggested implementation order based on dependency analysis. Follow the phased implementation order to avoid blocking yourself on cross-repo dependencies.
222
- ${localLlmEnabled ? `- **Local AI Agent Delegation (Token Optimizer)**: You have access to a local Small Language Model (SLM) on the developer's machine via the MCP tool \`delegate_to_local_agent\`.${
223
- ctx.localLlm ? `\n - **Model Capacity**: The local agent is running \`${ctx.localLlm.model}\`. ${
224
- ctx.localLlm.model.match(/70b|72b|32b|14b/i)
225
- ? 'This is a highly capable model; you can delegate complex reasoning and larger code generation tasks.'
226
- : 'This is a smaller model; it is best suited for targeted search, log parsing, summarization, and simple boilerplate.'
227
- }` : ''
228
- }
229
- - **Usage rule**: Whenever you need to perform high-token tasks (like searching large chunks of code, analyzing raw service logs to debug, or generating repetitive boilerplate), **always use \`delegate_to_local_agent\`** first.
230
- - The local model is free and fast. Pass the instruction and any logs/source files in \`filesToRead\` (relative paths). Use the distilled summary returned to formulate your final output, saving up to 90% in remote context tokens.
231
- ` : ''}- Read each project's existing \`README.md\` and any doc files before proposing changes.
232
- - When modifying a shared library, check every downstream consumer for breakage.
233
- - Prefer small, focused commits that touch one repo at a time when possible.
234
- - If a change must span repos, describe the ordering and any migration steps.
235
-
236
-
237
-
238
-
239
- `;
240
- }
1
+ /**
2
+ * @module generators/base
3
+ * Builds the shared markdown context content that all AI assistant generators
4
+ * use as their foundation. Now includes rich project analysis data when available.
5
+ */
6
+
7
+ import * as path from 'node:path';
8
+ import * as fs from 'node:fs';
9
+ import * as os from 'node:os';
10
+ import type { WorkspaceContext, ProjectAnalysis } from '../types.js';
11
+ import { resolveBaseFileUrl, resolveWorkspaceFileUrl } from '../core/storage.js';
12
+
13
+ /**
14
+ * Formats a ProjectAnalysis into a readable markdown section.
15
+ */
16
+ function formatProjectSection(analysis: ProjectAnalysis, workspacePath: string): string {
17
+ const lines: string[] = [];
18
+
19
+ lines.push(`### ${analysis.name}`);
20
+
21
+ const mapPath = resolveBaseFileUrl(workspacePath, analysis.name, `nexusflow-map-${analysis.name}.md`);
22
+ lines.push(`- **Architecture Map**: [nexusflow-map-${analysis.name}.md](file:///${mapPath}) — **Instruction**: Before modifying this repository, read its architecture map. For exploration, consult the map's section index on demand.`);
23
+
24
+ const baseKnowledgePath = resolveBaseFileUrl(workspacePath, analysis.name, 'nexusflow-knowledge.md');
25
+ lines.push(`- **Base Knowledge & Decisions**: [nexusflow-knowledge.md](file:///${baseKnowledgePath}) **Instruction**: Read this for persistent codebase learnings, decisions, and conventions.`);
26
+
27
+ // Tech stack
28
+ const { techStack } = analysis;
29
+ if (techStack.languages.length > 0 && techStack.languages[0] !== 'other') {
30
+ const langStr = techStack.languages.join(', ');
31
+ const fwStr = techStack.frameworks.length > 0 ? techStack.frameworks.join(', ') : 'none detected';
32
+ const buildStr = techStack.buildTools.length > 0 ? techStack.buildTools.join(', ') : 'none detected';
33
+
34
+ lines.push(`- **Type**: ${techStack.projectType}`);
35
+ lines.push(`- **Languages**: ${langStr}`);
36
+ lines.push(`- **Frameworks**: ${fwStr}`);
37
+ lines.push(`- **Build tools**: ${buildStr}`);
38
+ }
39
+
40
+ // README summary
41
+ if (analysis.readmeSummary) {
42
+ // Take first 200 chars of README summary as purpose
43
+ const purpose = analysis.readmeSummary
44
+ .replace(/^#\s+.+\n?/, '') // Remove h1 title
45
+ .trim()
46
+ .slice(0, 200)
47
+ .trim();
48
+ if (purpose) {
49
+ lines.push(`- **Purpose**: ${purpose}`);
50
+ }
51
+ }
52
+
53
+ // API endpoints
54
+ if (analysis.endpoints.length > 0) {
55
+ lines.push(`- **API surface**: ${analysis.endpoints.length} endpoints — see architecture map for details`);
56
+ }
57
+
58
+ // Ports
59
+ if (analysis.ports.length > 0) {
60
+ const portStr = analysis.ports.map((p) => `${p.port} (${p.protocol}, from ${p.source})`).join(', ');
61
+ lines.push(`- **Ports**: ${portStr}`);
62
+ }
63
+
64
+ // Path
65
+ lines.push(`- **Path**: \`${analysis.path}\``);
66
+
67
+ return lines.join('\n');
68
+ }
69
+
70
+ /**
71
+ * Builds the shared markdown context content that all AI assistant generators
72
+ * use as their foundation. Includes analysis data if available.
73
+ *
74
+ * @param ctx - The workspace context containing feature metadata, repo list, and optional analysis.
75
+ * @returns A markdown string with feature details, repo listing, and task instructions.
76
+ */
77
+ export function buildContextContent(ctx: WorkspaceContext): string {
78
+ const { feature, repos, analysis } = ctx;
79
+ const workspacePath = feature.workspacePath;
80
+ const localLlmEnabled = feature.localLlmEnabled ?? false;
81
+
82
+ // Build project sections rich if analysis is available, simple if not
83
+ let projectSections: string;
84
+
85
+ if (analysis && analysis.size > 0) {
86
+ const sections = repos.map((r) => {
87
+ const a = analysis.get(r.path);
88
+ if (a) return formatProjectSection(a, workspacePath);
89
+ return `### ${r.name}\n- **Path**: \`${r.path}\``;
90
+ });
91
+ projectSections = sections.join('\n\n');
92
+ } else {
93
+ projectSections = repos
94
+ .map((r) => `- **${r.name}** \`${r.path}\` (default branch: \`${r.defaultBranch}\`)`)
95
+ .join('\n');
96
+ }
97
+
98
+ // Build existing AI configs section
99
+ let existingConfigsSection = '';
100
+ if (analysis && analysis.size > 0) {
101
+ const allConfigs: string[] = [];
102
+ for (const [, a] of analysis) {
103
+ for (const config of a.existingAIConfigs) {
104
+ allConfigs.push(`- **${a.name}** has \`${config.relativePath}\` (${config.assistant})`);
105
+ }
106
+ }
107
+ if (allConfigs.length > 0) {
108
+ existingConfigsSection = `
109
+ ---
110
+
111
+ ## Existing AI Configurations
112
+
113
+ The following repos already have AI assistant configuration files.
114
+ Incorporate their instructions when working in those repos:
115
+
116
+ ${allConfigs.join('\n')}
117
+ `;
118
+ }
119
+ }
120
+
121
+ // Resumption commands section
122
+ let resumptionSection = '';
123
+ if (feature.resumption) {
124
+ let { testCommand, mockCommand, startCommand } = feature.resumption;
125
+ const parts: string[] = [];
126
+ if (mockCommand) parts.push(`- **Setup/Mock Command**: \`${mockCommand}\``);
127
+ if (startCommand) parts.push(`- **Start/Run Command**: \`${startCommand}\``);
128
+
129
+ const standardCommands = [
130
+ 'npm run test', 'npm test', 'npm t', 'yarn test', 'yarn t', 'pnpm test', 'pnpm t', 'bun test',
131
+ 'dotnet test',
132
+ 'pytest', 'python -m unittest', 'python -m pytest',
133
+ 'go test', 'go test ./...',
134
+ 'cargo test',
135
+ ];
136
+
137
+ if (testCommand) {
138
+ const normalizedCmd = testCommand.trim().toLowerCase();
139
+ const isStandard = standardCommands.some(cmd => normalizedCmd === cmd || normalizedCmd.startsWith(cmd + ' '));
140
+ if (!isStandard) {
141
+ parts.push(`- **Verification/Test Command**: \`${testCommand}\``);
142
+ }
143
+ }
144
+
145
+ if (parts.length > 0) {
146
+ resumptionSection = `
147
+ ---
148
+
149
+ ## Workspace Resumption & Verification Commands
150
+
151
+ Use these pre-configured commands to spin up mocks, run background services, and verify your changes:
152
+
153
+ ${parts.join('\n')}
154
+ `;
155
+ }
156
+ }
157
+
158
+ const knowledgePath = resolveWorkspaceFileUrl(workspacePath, feature.id, 'nexusflow-knowledge.md').replace(/\\/g, '/');
159
+
160
+ let setupDone = false;
161
+ try {
162
+ if (fs.existsSync(knowledgePath)) {
163
+ const content = fs.readFileSync(knowledgePath, 'utf-8');
164
+ if (!content.includes('No assumptions recorded yet') && !content.includes('AI assistant to populate')) {
165
+ setupDone = true;
166
+ }
167
+ }
168
+ } catch {}
169
+
170
+ // Teamwork strategy section
171
+ let teamworkSection = '';
172
+ if (feature.teamworkInstructions) {
173
+ teamworkSection = `
174
+ ---
175
+
176
+ ## Team Collaboration Strategy
177
+
178
+ ${feature.teamworkInstructions}
179
+ `;
180
+ }
181
+
182
+ const taskSection = setupDone
183
+ ? `## Setup Status\n\n✅ **Setup Completed**: Project assumptions and initial questions have been addressed. Refer to [nexusflow-knowledge.md](file:///${knowledgePath}) for persistent session details.`
184
+ : `## First Steps\n\nYour very first task upon entering this workspace is to explore the codebase and align with the user:\n\n1. **Verify Assumptions**: Open [nexusflow-knowledge.md](file:///${knowledgePath}) and fill in the **Project Assumptions** section with a brief description of what each project does, its tech stack, and responsibilities.\n2. **Raise Questions**: Document any outstanding uncertainties or architectural questions in the **Clarifying Questions for the User** section.\n3. **Obtain Approval**: Ask the user to confirm your assumptions and answer your questions before writing any code.`;
185
+
186
+ return `# Multi-Repo Workspace Context
187
+
188
+ ## Feature: ${feature.id}
189
+
190
+ **Description:** ${feature.description}
191
+
192
+ > For the detailed feature specification, architecture decisions, and session memory, see [nexusflow-knowledge.md](file:///${knowledgePath}).
193
+
194
+ ---
195
+
196
+ ## Projects
197
+
198
+ This workspace contains the following projects, each checked out as a
199
+ git worktree on the feature branch:
200
+
201
+ ${projectSections}
202
+ ${existingConfigsSection}
203
+ ${resumptionSection}
204
+ ---
205
+
206
+ ${taskSection}
207
+ ${teamworkSection}
208
+ ---
209
+
210
+ ## Guidelines
211
+
212
+ - **Multi-Repo Workspace Structure**: This workspace is a multi-repository developer environment where each project subdirectory (e.g. \`my-api\`, \`my-frontend\`) is a separate Git worktree checked out on the feature branch \`${feature.branchName}\`.
213
+ - **All code changes** must be made within the appropriate project subdirectories.
214
+ - **Worktree Isolation**: Under no circumstances should you edit files, read code, or run commands in the original/main repository directories outside of this workspace folder. All development must be strictly contained within the checked-out worktree subdirectories of this workspace.
215
+ - **Git commands** (like \`git status\`, \`git add\`, \`git commit\`, \`git push\`) must be run inside the specific project subdirectories (e.g. \`cd my-api && git commit -m "..."\`), NOT in the workspace root.
216
+ - **Project commands** (like \`npm install\`, \`npm run build\`, \`npm run test\`) must be run inside the project subdirectories.
217
+ - **Global helpers**: Alternatively, you can run NexusFlow CLI commands from the workspace root:
218
+ - \`nexusflow diff\` — view changes across all sub-repositories.
219
+ - \`nexusflow commit\` — commit and push changes across modified repositories.
220
+ - \`nexusflow sync\` rebase all repositories with their default base branches.
221
+ - \`nexusflow refresh\` regenerate maps, context files and plans without rebasing.
222
+ - \`nexusflow doctor\` run diagnostics to verify workspace health.
223
+ - **Workspace Knowledge**: Read \`nexusflow-knowledge.md\` at the start of every session. It serves as the persistent memory for this feature. Before ending your session, append significant architecture decisions, discovered gotchas, and checklist progress to \`nexusflow-knowledge.md\`. Never delete or overwrite existing knowledge/decisions — only append.
224
+ - **Implementation Plan**: Refer to \`nexusflow-plan.md\` for the suggested implementation order based on dependency analysis. Follow the phased implementation order to avoid blocking yourself on cross-repo dependencies.
225
+ ${localLlmEnabled ? `- **Local AI Agent Delegation (Token Optimizer)**: You have access to a local Small Language Model (SLM) on the developer's machine via the MCP tool \`delegate_to_local_agent\`.${
226
+ ctx.localLlm ? `\n - **Model Capacity**: The local agent is running \`${ctx.localLlm.model}\`. ${
227
+ ctx.localLlm.model.match(/70b|72b|32b|14b/i)
228
+ ? 'This is a highly capable model; you can delegate complex reasoning and larger code generation tasks.'
229
+ : 'This is a smaller model; it is best suited for targeted search, log parsing, summarization, and simple boilerplate.'
230
+ }` : ''
231
+ }
232
+ - **Usage rule**: Whenever you need to perform high-token tasks (like searching large chunks of code, analyzing raw service logs to debug, or generating repetitive boilerplate), **always use \`delegate_to_local_agent\`** first.
233
+ - The local model is free and fast. Pass the instruction and any logs/source files in \`filesToRead\` (relative paths). Use the distilled summary returned to formulate your final output, saving up to 90% in remote context tokens.
234
+ ` : ''}- Read each project's existing \`README.md\` and any doc files before proposing changes.
235
+ - When modifying a shared library, check every downstream consumer for breakage.
236
+ - Prefer small, focused commits that touch one repo at a time when possible.
237
+ - If a change must span repos, describe the ordering and any migration steps.
238
+
239
+
240
+
241
+
242
+ `;
243
+ }
@@ -1,34 +1,34 @@
1
- /**
2
- * @module generators/claude
3
- * Generates a CLAUDE.md file for Claude Code / Antigravity.
4
- * Now uses the shared base content builder which includes analysis data.
5
- */
6
-
7
- import path from 'node:path';
8
- import fse from 'fs-extra';
9
- import type { WorkspaceContext } from '../types.js';
10
- import { buildContextContent } from './base.js';
11
-
12
- /**
13
- * Generates a `CLAUDE.md` file at the workspace root.
14
- *
15
- * Claude Code reads this file automatically when opened in a directory,
16
- * so it is the primary way to give Claude long-lived project context.
17
- *
18
- * @param ctx - The workspace context (feature + repos + analysis).
19
- * @param workspacePath - Absolute path to the workspace root directory.
20
- */
21
- export async function generateClaudeConfig(
22
- ctx: WorkspaceContext,
23
- workspacePath: string,
24
- ): Promise<void> {
25
- const content = buildContextContent(ctx);
26
- const filePath = path.join(workspacePath, 'CLAUDE.md');
27
-
28
- try {
29
- await fse.writeFile(filePath, content, 'utf-8');
30
- } catch (error) {
31
- const message = error instanceof Error ? error.message : String(error);
32
- throw new Error(`Failed to write CLAUDE.md: ${message}`);
33
- }
34
- }
1
+ /**
2
+ * @module generators/claude
3
+ * Generates a CLAUDE.md file for Claude Code / Antigravity.
4
+ * Now uses the shared base content builder which includes analysis data.
5
+ */
6
+
7
+ import path from 'node:path';
8
+ import fse from 'fs-extra';
9
+ import type { WorkspaceContext } from '../types.js';
10
+ import { buildContextContent } from './base.js';
11
+
12
+ /**
13
+ * Generates a `CLAUDE.md` file at the workspace root.
14
+ *
15
+ * Claude Code reads this file automatically when opened in a directory,
16
+ * so it is the primary way to give Claude long-lived project context.
17
+ *
18
+ * @param ctx - The workspace context (feature + repos + analysis).
19
+ * @param workspacePath - Absolute path to the workspace root directory.
20
+ */
21
+ export async function generateClaudeConfig(
22
+ ctx: WorkspaceContext,
23
+ workspacePath: string,
24
+ ): Promise<void> {
25
+ const content = buildContextContent(ctx);
26
+ const filePath = path.join(workspacePath, 'CLAUDE.md');
27
+
28
+ try {
29
+ await fse.writeFile(filePath, content, 'utf-8');
30
+ } catch (error) {
31
+ const message = error instanceof Error ? error.message : String(error);
32
+ throw new Error(`Failed to write CLAUDE.md: ${message}`);
33
+ }
34
+ }