@mrpatronz/nexusflow 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +25 -0
- package/.github/workflows/release.yml +90 -0
- package/.vscode/launch.json +17 -0
- package/.vscode/tasks.json +17 -0
- package/README.md +1 -1
- package/dist/commands/commit.d.ts +18 -0
- package/dist/commands/commit.d.ts.map +1 -0
- package/dist/commands/commit.js +105 -0
- package/dist/commands/commit.js.map +1 -0
- package/dist/commands/diff.d.ts +11 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +101 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/sync.d.ts +11 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +96 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/generators/base.d.ts.map +1 -1
- package/dist/generators/base.js +3 -0
- package/dist/generators/base.js.map +1 -1
- package/dist/generators/index.d.ts +5 -2
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +88 -38
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/plan-generator.d.ts +40 -0
- package/dist/generators/plan-generator.d.ts.map +1 -0
- package/dist/generators/plan-generator.js +312 -0
- package/dist/generators/plan-generator.js.map +1 -0
- package/dist/gui/assets/index-B9Ph2bHH.css +2 -0
- package/dist/gui/assets/index-s4nRkpqY.js +21 -0
- package/dist/gui/index.html +2 -2
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +141 -1
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/multi-git.d.ts +108 -0
- package/dist/utils/multi-git.d.ts.map +1 -0
- package/dist/utils/multi-git.js +206 -0
- package/dist/utils/multi-git.js.map +1 -0
- package/extension/package-lock.json +2811 -0
- package/extension/package.json +61 -0
- package/extension/src/extension.ts +168 -0
- package/extension/tsconfig.json +19 -0
- package/gui/src/App.tsx +377 -24
- package/gui/src/features/changes/ChangesViewer.tsx +212 -0
- package/gui/src/features/knowledge/KnowledgeBase.tsx +84 -0
- package/gui/src/features/onboarding/OnboardingWizard.tsx +230 -0
- package/gui/src/features/plan/ImplementationPlan.tsx +32 -0
- package/gui/src/features/services/ServiceConsole.tsx +159 -0
- package/gui/src/features/sessions/SessionHistory.tsx +195 -0
- package/gui/src/features/workspace/WorkspaceBuilder.tsx +414 -0
- package/gui/src/features/workspace/WorkspaceList.tsx +382 -0
- package/gui/src/types.ts +61 -0
- package/package.json +6 -4
- package/src/commands/commit.ts +131 -0
- package/src/commands/diff.ts +125 -0
- package/src/commands/sync.ts +110 -0
- package/src/generators/base.ts +3 -0
- package/src/generators/index.ts +95 -40
- package/src/generators/plan-generator.ts +390 -0
- package/src/index.ts +59 -0
- package/src/server.ts +152 -1
- package/src/types.ts +17 -0
- package/src/utils/multi-git.ts +306 -0
- package/dist/gui/assets/index-Cq9V485S.js +0 -21
- package/dist/gui/assets/index-Dh1b5gSZ.css +0 -2
package/dist/generators/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { generateCodexConfig } from './codex.js';
|
|
|
6
6
|
import { generateCopilotConfig } from './copilot.js';
|
|
7
7
|
import { generateCursorConfig } from './cursor.js';
|
|
8
8
|
import { buildContextContent } from './base.js';
|
|
9
|
+
import { generateImplementationPlan } from './plan-generator.js';
|
|
9
10
|
/** Maps each assistant to its generator function and the file it produces. */
|
|
10
11
|
const GENERATORS = {
|
|
11
12
|
claude: { generate: generateClaudeConfig, outputFile: 'CLAUDE.md' },
|
|
@@ -14,11 +15,79 @@ const GENERATORS = {
|
|
|
14
15
|
copilot: { generate: generateCopilotConfig, outputFile: '.github/copilot-instructions.md' },
|
|
15
16
|
cursor: { generate: generateCursorConfig, outputFile: '.cursor/rules/nexusflow.mdc' },
|
|
16
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Builds the nexusflow-knowledge.md content — a persistent AI memory file.
|
|
20
|
+
*/
|
|
21
|
+
function buildKnowledgeContent(ctx) {
|
|
22
|
+
const { feature, repos, analysis } = ctx;
|
|
23
|
+
// Build repo list with tech stack info if available
|
|
24
|
+
const repoList = repos.map((r) => {
|
|
25
|
+
if (analysis && analysis.has(r.path)) {
|
|
26
|
+
const a = analysis.get(r.path);
|
|
27
|
+
const tech = a.techStack.frameworks.length > 0
|
|
28
|
+
? ` (${a.techStack.languages.join(', ')} — ${a.techStack.frameworks.join(', ')})`
|
|
29
|
+
: a.techStack.languages[0] !== 'other'
|
|
30
|
+
? ` (${a.techStack.languages.join(', ')})`
|
|
31
|
+
: '';
|
|
32
|
+
return `- **${r.name}**${tech}`;
|
|
33
|
+
}
|
|
34
|
+
return `- **${r.name}**`;
|
|
35
|
+
}).join('\n');
|
|
36
|
+
// Build initial progress checklist
|
|
37
|
+
const progressItems = repos.map((r) => `- [ ] ${r.name} — changes implemented and tested`).join('\n');
|
|
38
|
+
return `# Workspace Knowledge — ${feature.id}
|
|
39
|
+
|
|
40
|
+
> **This file is a living document.** AI assistants should read this at the
|
|
41
|
+
> start of each session and append new learnings at the end.
|
|
42
|
+
> It preserves context across sessions so decisions aren't lost or repeated.
|
|
43
|
+
|
|
44
|
+
## Feature Goal
|
|
45
|
+
|
|
46
|
+
${feature.description}
|
|
47
|
+
|
|
48
|
+
**Branch:** \`${feature.branchName}\`
|
|
49
|
+
**Created:** ${feature.createdAt}
|
|
50
|
+
|
|
51
|
+
## Repos in This Workspace
|
|
52
|
+
|
|
53
|
+
${repoList}
|
|
54
|
+
|
|
55
|
+
## Architecture Decisions
|
|
56
|
+
|
|
57
|
+
<!-- AI assistants: append decisions here as they are made during development.
|
|
58
|
+
Format: ### YYYY-MM-DD — Decision Title
|
|
59
|
+
**Decision:** What was decided
|
|
60
|
+
**Alternatives considered:** What else was evaluated
|
|
61
|
+
**Reasoning:** Why this choice was made -->
|
|
62
|
+
|
|
63
|
+
_(No decisions recorded yet.)_
|
|
64
|
+
|
|
65
|
+
## Implementation Progress
|
|
66
|
+
|
|
67
|
+
${progressItems}
|
|
68
|
+
|
|
69
|
+
## Known Gotchas
|
|
70
|
+
|
|
71
|
+
<!-- AI assistants: append any gotchas, workarounds, or "watch out for" items
|
|
72
|
+
discovered during development. These help future sessions avoid repeating
|
|
73
|
+
the same debugging. -->
|
|
74
|
+
|
|
75
|
+
_(No gotchas recorded yet.)_
|
|
76
|
+
|
|
77
|
+
## Open Questions
|
|
78
|
+
|
|
79
|
+
<!-- Add questions that need human input before the AI can proceed. -->
|
|
80
|
+
|
|
81
|
+
_(No open questions.)_
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
17
84
|
/**
|
|
18
85
|
* Generates AI context files for each of the selected assistants.
|
|
19
86
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
87
|
+
* Also generates:
|
|
88
|
+
* - WORKSPACE.md — universal context file
|
|
89
|
+
* - nexusflow-knowledge.md — persistent AI memory across sessions
|
|
90
|
+
* - nexusflow-plan.md — implementation order based on dependency analysis
|
|
22
91
|
*
|
|
23
92
|
* @param ctx - The workspace context (feature + repos).
|
|
24
93
|
* @param assistants - Which AI assistants to generate context files for.
|
|
@@ -31,43 +100,15 @@ export async function generateContextFiles(ctx, assistants, workspacePath) {
|
|
|
31
100
|
const filePath = path.join(workspacePath, 'WORKSPACE.md');
|
|
32
101
|
await fse.writeFile(filePath, content, 'utf-8');
|
|
33
102
|
console.log(chalk.green(' ✔'), `Generated universal ${chalk.bold('WORKSPACE.md')}`);
|
|
34
|
-
// Generate
|
|
35
|
-
const
|
|
36
|
-
if (!(await fse.pathExists(
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- **Session Started**: ${new Date().toLocaleDateString()}
|
|
41
|
-
- **Last Modified Files**: None (Start of session)
|
|
42
|
-
|
|
43
|
-
## Summary of Accomplished Work
|
|
44
|
-
- Setup workspace with ${ctx.repos.length} mapped repositories.
|
|
45
|
-
|
|
46
|
-
## Active State & Blockers
|
|
47
|
-
- No active blockers.
|
|
48
|
-
|
|
49
|
-
## Next Steps
|
|
50
|
-
1. Open this workspace in your selected editor.
|
|
51
|
-
2. Ask the assistant to read \`WORKSPACE.md\` and \`session.md\` to get started.
|
|
52
|
-
`;
|
|
53
|
-
await fse.writeFile(sessionPath, sessionContent, 'utf-8');
|
|
54
|
-
console.log(chalk.green(' ✔'), `Generated initial session.md`);
|
|
103
|
+
// Generate nexusflow-knowledge.md if it does not exist
|
|
104
|
+
const knowledgePath = path.join(workspacePath, 'nexusflow-knowledge.md');
|
|
105
|
+
if (!(await fse.pathExists(knowledgePath))) {
|
|
106
|
+
const knowledgeContent = buildKnowledgeContent(ctx);
|
|
107
|
+
await fse.writeFile(knowledgePath, knowledgeContent, 'utf-8');
|
|
108
|
+
console.log(chalk.green(' ✔'), `Generated ${chalk.bold('nexusflow-knowledge.md')} (persistent AI memory)`);
|
|
55
109
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!(await fse.pathExists(planPath))) {
|
|
59
|
-
const planContent = `# Feature Development Plan
|
|
60
|
-
|
|
61
|
-
## Checklist
|
|
62
|
-
- [ ] Read \`WORKSPACE.md\` and analyze the codebase structure.
|
|
63
|
-
- [ ] Initialize context by creating \`nexusflow-overview.md\` outlining assumptions and raising clarifying questions.
|
|
64
|
-
- [ ] Review user's responses to clarifying questions.
|
|
65
|
-
- [ ] Implement feature logic.
|
|
66
|
-
- [ ] Verify build and run tests.
|
|
67
|
-
- [ ] Compile final changes in the session handover memo.
|
|
68
|
-
`;
|
|
69
|
-
await fse.writeFile(planPath, planContent, 'utf-8');
|
|
70
|
-
console.log(chalk.green(' ✔'), `Generated initial plan.md`);
|
|
110
|
+
else {
|
|
111
|
+
console.log(chalk.gray(' ○'), `nexusflow-knowledge.md already exists — preserving existing content`);
|
|
71
112
|
}
|
|
72
113
|
}
|
|
73
114
|
catch (error) {
|
|
@@ -85,6 +126,14 @@ export async function generateContextFiles(ctx, assistants, workspacePath) {
|
|
|
85
126
|
console.error(chalk.red(' ✖'), `Failed to generate ${entry.outputFile} for ${assistant}: ${message}`);
|
|
86
127
|
}
|
|
87
128
|
}
|
|
129
|
+
// Generate implementation plan from dependency analysis (if analysis data available)
|
|
130
|
+
try {
|
|
131
|
+
await generateImplementationPlan(ctx, workspacePath);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
135
|
+
console.error(chalk.red(' ✖'), `Failed to generate implementation plan: ${message}`);
|
|
136
|
+
}
|
|
88
137
|
}
|
|
89
138
|
// Re-export individual generators for direct use
|
|
90
139
|
export { generateClaudeConfig } from './claude.js';
|
|
@@ -92,4 +141,5 @@ export { generateCodexConfig } from './codex.js';
|
|
|
92
141
|
export { generateCopilotConfig } from './copilot.js';
|
|
93
142
|
export { generateCursorConfig } from './cursor.js';
|
|
94
143
|
export { buildContextContent } from './base.js';
|
|
144
|
+
export { generateImplementationPlan } from './plan-generator.js';
|
|
95
145
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plan-generator
|
|
3
|
+
* Analyzes inter-repo dependencies within a workspace and generates a
|
|
4
|
+
* `nexusflow-plan.md` implementation plan with build-order phases.
|
|
5
|
+
*/
|
|
6
|
+
import type { WorkspaceContext, ProjectAnalysis, RepoInfo, DependencyGraph } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build a dependency graph by analysing package dependencies, API
|
|
9
|
+
* relationships and shared-package conventions across the workspace repos.
|
|
10
|
+
*
|
|
11
|
+
* @param analysis Per-repo analysis results, keyed by repo path.
|
|
12
|
+
* @param repos Metadata for every repo in the workspace.
|
|
13
|
+
* @returns A map of repo name → {@link DependencyNode}.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildDependencyGraph(analysis: Map<string, ProjectAnalysis>, repos: RepoInfo[]): DependencyGraph;
|
|
16
|
+
/**
|
|
17
|
+
* Topologically sort the dependency graph into build phases.
|
|
18
|
+
* Each phase is a group of repos that can be built in parallel
|
|
19
|
+
* because all of their dependencies appear in earlier phases.
|
|
20
|
+
*
|
|
21
|
+
* If a cycle is detected, the remaining nodes are placed in a final phase
|
|
22
|
+
* with a warning logged to the console.
|
|
23
|
+
*
|
|
24
|
+
* @param graph The workspace dependency graph.
|
|
25
|
+
* @returns An array of phases, where each phase is an array of repo names.
|
|
26
|
+
*/
|
|
27
|
+
export declare function topologicalSort(graph: DependencyGraph): string[][];
|
|
28
|
+
/**
|
|
29
|
+
* Generate a `nexusflow-plan.md` implementation plan for the workspace.
|
|
30
|
+
*
|
|
31
|
+
* The plan includes:
|
|
32
|
+
* - A Mermaid dependency diagram
|
|
33
|
+
* - Phased implementation order derived from topological sort
|
|
34
|
+
* - A dependency cross-reference table
|
|
35
|
+
*
|
|
36
|
+
* @param ctx The current workspace context (feature + repos + analysis).
|
|
37
|
+
* @param workspacePath Absolute path to the workspace root directory.
|
|
38
|
+
*/
|
|
39
|
+
export declare function generateImplementationPlan(ctx: WorkspaceContext, workspacePath: string): Promise<void>;
|
|
40
|
+
//# sourceMappingURL=plan-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-generator.d.ts","sourceRoot":"","sources":["../../src/generators/plan-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,QAAQ,EAER,eAAe,EAChB,MAAM,aAAa,CAAC;AAerB;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACtC,KAAK,EAAE,QAAQ,EAAE,GAChB,eAAe,CAkFjB;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,EAAE,CA4ClE;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,gBAAgB,EACrB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA6If"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plan-generator
|
|
3
|
+
* Analyzes inter-repo dependencies within a workspace and generates a
|
|
4
|
+
* `nexusflow-plan.md` implementation plan with build-order phases.
|
|
5
|
+
*/
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import fse from 'fs-extra';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
// ─── Constants ────────────────────────────────────────────────────────────
|
|
10
|
+
/** Repo-name substrings that signal a shared/foundation package. */
|
|
11
|
+
const SHARED_PACKAGE_KEYWORDS = ['shared', 'common', 'contracts', 'types'];
|
|
12
|
+
/** Project types that act as backend producers. */
|
|
13
|
+
const BACKEND_TYPES = ['api', 'backend', 'service'];
|
|
14
|
+
/** Project types that act as frontend consumers. */
|
|
15
|
+
const FRONTEND_TYPES = ['frontend', 'webapp', 'app'];
|
|
16
|
+
// ─── Dependency Graph Builder ─────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Build a dependency graph by analysing package dependencies, API
|
|
19
|
+
* relationships and shared-package conventions across the workspace repos.
|
|
20
|
+
*
|
|
21
|
+
* @param analysis Per-repo analysis results, keyed by repo path.
|
|
22
|
+
* @param repos Metadata for every repo in the workspace.
|
|
23
|
+
* @returns A map of repo name → {@link DependencyNode}.
|
|
24
|
+
*/
|
|
25
|
+
export function buildDependencyGraph(analysis, repos) {
|
|
26
|
+
const graph = new Map();
|
|
27
|
+
// ── Initialise a node for each repo ──────────────────────────────────
|
|
28
|
+
for (const repo of repos) {
|
|
29
|
+
graph.set(repo.name, {
|
|
30
|
+
repoName: repo.name,
|
|
31
|
+
repoPath: repo.path,
|
|
32
|
+
dependsOn: [],
|
|
33
|
+
dependedOnBy: [],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Build a quick lookup: repo name → ProjectAnalysis
|
|
37
|
+
const analysisByName = new Map();
|
|
38
|
+
for (const repo of repos) {
|
|
39
|
+
const a = analysis.get(repo.path);
|
|
40
|
+
if (a)
|
|
41
|
+
analysisByName.set(repo.name, a);
|
|
42
|
+
}
|
|
43
|
+
const repoNames = new Set(repos.map((r) => r.name));
|
|
44
|
+
// ── 1. Shared-package dependencies ───────────────────────────────────
|
|
45
|
+
for (const repo of repos) {
|
|
46
|
+
const a = analysisByName.get(repo.name);
|
|
47
|
+
if (!a)
|
|
48
|
+
continue;
|
|
49
|
+
for (const dep of a.dependencies) {
|
|
50
|
+
// Direct name match — e.g. "@acme/shared-contracts" contains "shared-contracts"
|
|
51
|
+
for (const otherName of repoNames) {
|
|
52
|
+
if (otherName === repo.name)
|
|
53
|
+
continue;
|
|
54
|
+
if (dep.name === otherName || dep.name.includes(otherName)) {
|
|
55
|
+
addEdge(graph, repo.name, otherName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ── 2. API relationships (frontend → backend heuristic) ─────────────
|
|
61
|
+
for (const repoA of repos) {
|
|
62
|
+
const analysisA = analysisByName.get(repoA.name);
|
|
63
|
+
if (!analysisA)
|
|
64
|
+
continue;
|
|
65
|
+
const typeA = analysisA.techStack.projectType;
|
|
66
|
+
if (!BACKEND_TYPES.includes(typeA))
|
|
67
|
+
continue;
|
|
68
|
+
for (const repoB of repos) {
|
|
69
|
+
if (repoB.name === repoA.name)
|
|
70
|
+
continue;
|
|
71
|
+
const analysisB = analysisByName.get(repoB.name);
|
|
72
|
+
if (!analysisB)
|
|
73
|
+
continue;
|
|
74
|
+
const typeB = analysisB.techStack.projectType;
|
|
75
|
+
if (FRONTEND_TYPES.includes(typeB)) {
|
|
76
|
+
// B (frontend) depends on A (backend)
|
|
77
|
+
addEdge(graph, repoB.name, repoA.name);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ── 3. Shared-type packages are always foundation ───────────────────
|
|
82
|
+
for (const repo of repos) {
|
|
83
|
+
const isShared = SHARED_PACKAGE_KEYWORDS.some((kw) => repo.name.toLowerCase().includes(kw));
|
|
84
|
+
if (!isShared)
|
|
85
|
+
continue;
|
|
86
|
+
const node = graph.get(repo.name);
|
|
87
|
+
if (!node)
|
|
88
|
+
continue;
|
|
89
|
+
// Ensure no outgoing deps (it's a leaf producer)
|
|
90
|
+
node.dependsOn = [];
|
|
91
|
+
// Every other repo that doesn't already depend on it — add edge
|
|
92
|
+
for (const other of repos) {
|
|
93
|
+
if (other.name === repo.name)
|
|
94
|
+
continue;
|
|
95
|
+
addEdge(graph, other.name, repo.name);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return graph;
|
|
99
|
+
}
|
|
100
|
+
// ─── Topological Sort ─────────────────────────────────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* Topologically sort the dependency graph into build phases.
|
|
103
|
+
* Each phase is a group of repos that can be built in parallel
|
|
104
|
+
* because all of their dependencies appear in earlier phases.
|
|
105
|
+
*
|
|
106
|
+
* If a cycle is detected, the remaining nodes are placed in a final phase
|
|
107
|
+
* with a warning logged to the console.
|
|
108
|
+
*
|
|
109
|
+
* @param graph The workspace dependency graph.
|
|
110
|
+
* @returns An array of phases, where each phase is an array of repo names.
|
|
111
|
+
*/
|
|
112
|
+
export function topologicalSort(graph) {
|
|
113
|
+
// Calculate in-degrees
|
|
114
|
+
const inDegree = new Map();
|
|
115
|
+
for (const [name, node] of graph) {
|
|
116
|
+
inDegree.set(name, node.dependsOn.length);
|
|
117
|
+
}
|
|
118
|
+
const phases = [];
|
|
119
|
+
const placed = new Set();
|
|
120
|
+
while (placed.size < graph.size) {
|
|
121
|
+
// Collect nodes whose in-degree is 0 and haven't been placed yet
|
|
122
|
+
const phase = [];
|
|
123
|
+
for (const [name, degree] of inDegree) {
|
|
124
|
+
if (degree === 0 && !placed.has(name)) {
|
|
125
|
+
phase.push(name);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Cycle detection — no zero-in-degree nodes remain
|
|
129
|
+
if (phase.length === 0) {
|
|
130
|
+
const remaining = [...graph.keys()].filter((n) => !placed.has(n));
|
|
131
|
+
console.log(chalk.yellow(' ⚠'), `Dependency cycle detected among: ${remaining.join(', ')}`);
|
|
132
|
+
phases.push(remaining);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
phase.sort(); // Deterministic ordering within a phase
|
|
136
|
+
phases.push(phase);
|
|
137
|
+
// "Remove" placed nodes and decrement dependents' in-degrees
|
|
138
|
+
for (const name of phase) {
|
|
139
|
+
placed.add(name);
|
|
140
|
+
const node = graph.get(name);
|
|
141
|
+
for (const dependent of node.dependedOnBy) {
|
|
142
|
+
inDegree.set(dependent, (inDegree.get(dependent) ?? 1) - 1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return phases;
|
|
147
|
+
}
|
|
148
|
+
// ─── Plan Generator ───────────────────────────────────────────────────────
|
|
149
|
+
/**
|
|
150
|
+
* Generate a `nexusflow-plan.md` implementation plan for the workspace.
|
|
151
|
+
*
|
|
152
|
+
* The plan includes:
|
|
153
|
+
* - A Mermaid dependency diagram
|
|
154
|
+
* - Phased implementation order derived from topological sort
|
|
155
|
+
* - A dependency cross-reference table
|
|
156
|
+
*
|
|
157
|
+
* @param ctx The current workspace context (feature + repos + analysis).
|
|
158
|
+
* @param workspacePath Absolute path to the workspace root directory.
|
|
159
|
+
*/
|
|
160
|
+
export async function generateImplementationPlan(ctx, workspacePath) {
|
|
161
|
+
try {
|
|
162
|
+
const { feature, repos, analysis } = ctx;
|
|
163
|
+
// ── Fallback: no analysis available ─────────────────────────────────
|
|
164
|
+
if (!analysis || analysis.size === 0) {
|
|
165
|
+
const lines = [
|
|
166
|
+
`# Implementation Plan — ${feature.id}`,
|
|
167
|
+
'',
|
|
168
|
+
'> Auto-generated by NexusFlow.',
|
|
169
|
+
'> No project analysis data was available, so repos are listed alphabetically.',
|
|
170
|
+
'',
|
|
171
|
+
'## Repos',
|
|
172
|
+
'',
|
|
173
|
+
...repos
|
|
174
|
+
.map((r) => r.name)
|
|
175
|
+
.sort()
|
|
176
|
+
.map((n) => `- ${n}`),
|
|
177
|
+
'',
|
|
178
|
+
];
|
|
179
|
+
await fse.outputFile(path.join(workspacePath, 'nexusflow-plan.md'), lines.join('\n'));
|
|
180
|
+
console.log(chalk.green(' ✔'), 'Generated nexusflow-plan.md');
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
// ── Build graph & sort ──────────────────────────────────────────────
|
|
184
|
+
const graph = buildDependencyGraph(analysis, repos);
|
|
185
|
+
const phases = topologicalSort(graph);
|
|
186
|
+
// ── Render markdown ─────────────────────────────────────────────────
|
|
187
|
+
const md = [];
|
|
188
|
+
md.push(`# Implementation Plan — ${feature.id}`);
|
|
189
|
+
md.push('');
|
|
190
|
+
md.push('> Auto-generated by NexusFlow based on dependency analysis between repos.');
|
|
191
|
+
md.push('> Follow the phase order to avoid blocking yourself on cross-repo dependencies.');
|
|
192
|
+
md.push('');
|
|
193
|
+
// ── Mermaid diagram ─────────────────────────────────────────────────
|
|
194
|
+
md.push('## Dependency Diagram');
|
|
195
|
+
md.push('');
|
|
196
|
+
md.push('```mermaid');
|
|
197
|
+
md.push('graph TD');
|
|
198
|
+
const alias = buildAliasMap(graph);
|
|
199
|
+
for (const [name, node] of graph) {
|
|
200
|
+
if (node.dependsOn.length === 0 && node.dependedOnBy.length === 0) {
|
|
201
|
+
// Isolated node — still show it
|
|
202
|
+
md.push(` ${alias.get(name)}["${name}"]`);
|
|
203
|
+
}
|
|
204
|
+
for (const dep of node.dependsOn) {
|
|
205
|
+
// Arrow: dependency → dependent (dep is built first)
|
|
206
|
+
md.push(` ${alias.get(dep)}["${dep}"] --> ${alias.get(name)}["${name}"]`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
md.push('```');
|
|
210
|
+
md.push('');
|
|
211
|
+
// ── Phase descriptions ──────────────────────────────────────────────
|
|
212
|
+
md.push('## Suggested Implementation Order');
|
|
213
|
+
md.push('');
|
|
214
|
+
const phaseLabels = [
|
|
215
|
+
'Foundation',
|
|
216
|
+
'Core Services',
|
|
217
|
+
'Integration Layer',
|
|
218
|
+
'Consumers',
|
|
219
|
+
'Final',
|
|
220
|
+
];
|
|
221
|
+
for (let i = 0; i < phases.length; i++) {
|
|
222
|
+
const phase = phases[i];
|
|
223
|
+
const label = phaseLabels[Math.min(i, phaseLabels.length - 1)];
|
|
224
|
+
const ordinal = ordinalWord(i + 1);
|
|
225
|
+
md.push(`### Phase ${i + 1}: ${label}`);
|
|
226
|
+
md.push('');
|
|
227
|
+
md.push(`**Repos:** ${phase.join(', ')}`);
|
|
228
|
+
md.push('');
|
|
229
|
+
if (i === 0) {
|
|
230
|
+
md.push(`**Why first:** These repos have no dependencies on other workspace repos. Other repos depend on them.`);
|
|
231
|
+
}
|
|
232
|
+
else if (i === phases.length - 1) {
|
|
233
|
+
md.push(`**Why ${ordinal}:** Depends on APIs and types from earlier phases.`);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
const prevPhases = phases
|
|
237
|
+
.slice(0, i)
|
|
238
|
+
.flat()
|
|
239
|
+
.join(', ');
|
|
240
|
+
md.push(`**Why ${ordinal}:** Depends on Phase ${i === 1 ? '1' : `1–${i}`} repos (${prevPhases}). Build these before the consumers.`);
|
|
241
|
+
}
|
|
242
|
+
md.push('');
|
|
243
|
+
}
|
|
244
|
+
// ── Dependency table ────────────────────────────────────────────────
|
|
245
|
+
md.push('## Dependency Table');
|
|
246
|
+
md.push('');
|
|
247
|
+
md.push('| Repo | Depends On | Depended On By |');
|
|
248
|
+
md.push('|:---|:---|:---|');
|
|
249
|
+
// Sort repos by phase order for a natural reading experience
|
|
250
|
+
const orderedNames = phases.flat();
|
|
251
|
+
for (const name of orderedNames) {
|
|
252
|
+
const node = graph.get(name);
|
|
253
|
+
const deps = node.dependsOn.length > 0 ? node.dependsOn.join(', ') : '—';
|
|
254
|
+
const rdeps = node.dependedOnBy.length > 0 ? node.dependedOnBy.join(', ') : '—';
|
|
255
|
+
md.push(`| ${name} | ${deps} | ${rdeps} |`);
|
|
256
|
+
}
|
|
257
|
+
md.push('');
|
|
258
|
+
// ── Write file ──────────────────────────────────────────────────────
|
|
259
|
+
const outPath = path.join(workspacePath, 'nexusflow-plan.md');
|
|
260
|
+
await fse.outputFile(outPath, md.join('\n'));
|
|
261
|
+
console.log(chalk.green(' ✔'), 'Generated nexusflow-plan.md');
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
265
|
+
console.error(chalk.red(' ✖'), `Failed to generate implementation plan: ${message}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
269
|
+
/**
|
|
270
|
+
* Add a directed edge: `from` depends on `to`.
|
|
271
|
+
* Idempotent — duplicate edges are ignored.
|
|
272
|
+
*/
|
|
273
|
+
function addEdge(graph, from, to) {
|
|
274
|
+
const fromNode = graph.get(from);
|
|
275
|
+
const toNode = graph.get(to);
|
|
276
|
+
if (!fromNode || !toNode)
|
|
277
|
+
return;
|
|
278
|
+
if (!fromNode.dependsOn.includes(to)) {
|
|
279
|
+
fromNode.dependsOn.push(to);
|
|
280
|
+
}
|
|
281
|
+
if (!toNode.dependedOnBy.includes(from)) {
|
|
282
|
+
toNode.dependedOnBy.push(from);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Build a short single-letter alias map for Mermaid node IDs.
|
|
287
|
+
* Falls back to sanitised names when there are more than 26 repos.
|
|
288
|
+
*/
|
|
289
|
+
function buildAliasMap(graph) {
|
|
290
|
+
const map = new Map();
|
|
291
|
+
const names = [...graph.keys()].sort();
|
|
292
|
+
if (names.length <= 26) {
|
|
293
|
+
let code = 65; // 'A'
|
|
294
|
+
for (const name of names) {
|
|
295
|
+
map.set(name, String.fromCharCode(code++));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
for (const name of names) {
|
|
300
|
+
map.set(name, name.replace(/[^a-zA-Z0-9]/g, '_'));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return map;
|
|
304
|
+
}
|
|
305
|
+
/** Return an ordinal word for small numbers, or "nth" for larger ones. */
|
|
306
|
+
function ordinalWord(n) {
|
|
307
|
+
const words = ['first', 'second', 'third', 'fourth', 'fifth'];
|
|
308
|
+
if (n >= 1 && n <= words.length)
|
|
309
|
+
return words[n - 1];
|
|
310
|
+
return `${n}th`;
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=plan-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-generator.js","sourceRoot":"","sources":["../../src/generators/plan-generator.ts"],"names":[],"mappings":"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"}
|