@mrpatronz/nexusflow 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GETTING_STARTED.md +109 -0
- package/README.md +310 -0
- package/dist/analyzers/detect-apis.d.ts +19 -0
- package/dist/analyzers/detect-apis.d.ts.map +1 -0
- package/dist/analyzers/detect-apis.js +121 -0
- package/dist/analyzers/detect-apis.js.map +1 -0
- package/dist/analyzers/detect-deps.d.ts +30 -0
- package/dist/analyzers/detect-deps.d.ts.map +1 -0
- package/dist/analyzers/detect-deps.js +121 -0
- package/dist/analyzers/detect-deps.js.map +1 -0
- package/dist/analyzers/detect-existing.d.ts +15 -0
- package/dist/analyzers/detect-existing.d.ts.map +1 -0
- package/dist/analyzers/detect-existing.js +65 -0
- package/dist/analyzers/detect-existing.js.map +1 -0
- package/dist/analyzers/detect-ports.d.ts +20 -0
- package/dist/analyzers/detect-ports.d.ts.map +1 -0
- package/dist/analyzers/detect-ports.js +103 -0
- package/dist/analyzers/detect-ports.js.map +1 -0
- package/dist/analyzers/index.d.ts +29 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +74 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/readme-summarizer.d.ts +13 -0
- package/dist/analyzers/readme-summarizer.d.ts.map +1 -0
- package/dist/analyzers/readme-summarizer.js +59 -0
- package/dist/analyzers/readme-summarizer.js.map +1 -0
- package/dist/analyzers/tech-stack.d.ts +15 -0
- package/dist/analyzers/tech-stack.d.ts.map +1 -0
- package/dist/analyzers/tech-stack.js +284 -0
- package/dist/analyzers/tech-stack.js.map +1 -0
- package/dist/commands/create.d.ts +17 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +111 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +50 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +9 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +32 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/logs.d.ts +12 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +54 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/open.d.ts +9 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +49 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +97 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +47 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +47 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/ui.d.ts +13 -0
- package/dist/commands/ui.d.ts.map +1 -0
- package/dist/commands/ui.js +44 -0
- package/dist/commands/ui.js.map +1 -0
- package/dist/core/config.d.ts +32 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +68 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/scanner.d.ts +18 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +73 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/workspace.d.ts +53 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +114 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/core/worktree.d.ts +27 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +35 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/generators/base.d.ts +15 -0
- package/dist/generators/base.d.ts.map +1 -0
- package/dist/generators/base.js +175 -0
- package/dist/generators/base.js.map +1 -0
- package/dist/generators/claude.d.ts +17 -0
- package/dist/generators/claude.d.ts.map +1 -0
- package/dist/generators/claude.js +29 -0
- package/dist/generators/claude.js.map +1 -0
- package/dist/generators/codex.d.ts +16 -0
- package/dist/generators/codex.d.ts.map +1 -0
- package/dist/generators/codex.js +41 -0
- package/dist/generators/codex.js.map +1 -0
- package/dist/generators/copilot.d.ts +16 -0
- package/dist/generators/copilot.d.ts.map +1 -0
- package/dist/generators/copilot.js +49 -0
- package/dist/generators/copilot.js.map +1 -0
- package/dist/generators/cursor.d.ts +17 -0
- package/dist/generators/cursor.d.ts.map +1 -0
- package/dist/generators/cursor.js +37 -0
- package/dist/generators/cursor.js.map +1 -0
- package/dist/generators/index.d.ts +18 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +95 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/gui/assets/index-Cq9V485S.js +21 -0
- package/dist/gui/assets/index-Dh1b5gSZ.css +2 -0
- package/dist/gui/favicon.svg +1 -0
- package/dist/gui/icons.svg +24 -0
- package/dist/gui/index.html +18 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +169 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestration/detect.d.ts +29 -0
- package/dist/orchestration/detect.d.ts.map +1 -0
- package/dist/orchestration/detect.js +292 -0
- package/dist/orchestration/detect.js.map +1 -0
- package/dist/orchestration/index.d.ts +7 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +7 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/runner.d.ts +40 -0
- package/dist/orchestration/runner.d.ts.map +1 -0
- package/dist/orchestration/runner.js +242 -0
- package/dist/orchestration/runner.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +419 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +210 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/detect-ai.d.ts +21 -0
- package/dist/utils/detect-ai.d.ts.map +1 -0
- package/dist/utils/detect-ai.js +76 -0
- package/dist/utils/detect-ai.js.map +1 -0
- package/dist/utils/detect-editors.d.ts +19 -0
- package/dist/utils/detect-editors.d.ts.map +1 -0
- package/dist/utils/detect-editors.js +49 -0
- package/dist/utils/detect-editors.js.map +1 -0
- package/dist/utils/git.d.ts +27 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +57 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/prompts.d.ts +27 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +119 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/session-finder.d.ts +29 -0
- package/dist/utils/session-finder.d.ts.map +1 -0
- package/dist/utils/session-finder.js +462 -0
- package/dist/utils/session-finder.js.map +1 -0
- package/gui/README.md +73 -0
- package/gui/eslint.config.js +22 -0
- package/gui/index.html +17 -0
- package/gui/package-lock.json +3054 -0
- package/gui/package.json +33 -0
- package/gui/public/favicon.svg +1 -0
- package/gui/public/icons.svg +24 -0
- package/gui/src/App.css +1 -0
- package/gui/src/App.tsx +1949 -0
- package/gui/src/assets/hero.png +0 -0
- package/gui/src/assets/react.svg +1 -0
- package/gui/src/assets/vite.svg +1 -0
- package/gui/src/index.css +1 -0
- package/gui/src/main.tsx +10 -0
- package/gui/tsconfig.app.json +25 -0
- package/gui/tsconfig.json +7 -0
- package/gui/tsconfig.node.json +24 -0
- package/gui/vite.config.ts +12 -0
- package/package.json +48 -0
- package/src/analyzers/detect-apis.ts +138 -0
- package/src/analyzers/detect-deps.ts +138 -0
- package/src/analyzers/detect-existing.ts +74 -0
- package/src/analyzers/detect-ports.ts +110 -0
- package/src/analyzers/index.ts +85 -0
- package/src/analyzers/readme-summarizer.ts +68 -0
- package/src/analyzers/tech-stack.ts +255 -0
- package/src/commands/create.ts +142 -0
- package/src/commands/init.ts +58 -0
- package/src/commands/list.ts +46 -0
- package/src/commands/logs.ts +63 -0
- package/src/commands/open.ts +54 -0
- package/src/commands/start.ts +117 -0
- package/src/commands/status.ts +54 -0
- package/src/commands/stop.ts +55 -0
- package/src/commands/ui.ts +47 -0
- package/src/core/config.ts +79 -0
- package/src/core/scanner.ts +91 -0
- package/src/core/workspace.ts +149 -0
- package/src/core/worktree.ts +50 -0
- package/src/generators/base.ts +187 -0
- package/src/generators/claude.ts +34 -0
- package/src/generators/codex.ts +48 -0
- package/src/generators/copilot.ts +56 -0
- package/src/generators/cursor.ts +44 -0
- package/src/generators/index.ts +122 -0
- package/src/index.ts +178 -0
- package/src/orchestration/detect.ts +313 -0
- package/src/orchestration/index.ts +7 -0
- package/src/orchestration/runner.ts +279 -0
- package/src/server.ts +466 -0
- package/src/types.ts +294 -0
- package/src/utils/detect-ai.ts +81 -0
- package/src/utils/detect-editors.ts +54 -0
- package/src/utils/git.ts +61 -0
- package/src/utils/prompts.ts +135 -0
- package/src/utils/session-finder.ts +483 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module analyzers/tech-stack
|
|
3
|
+
* Detects the language, framework, build tools, and project type
|
|
4
|
+
* of a repository by inspecting manifest files.
|
|
5
|
+
*/
|
|
6
|
+
import * as fs from 'node:fs/promises';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
/** Check if a file exists in a directory. */
|
|
9
|
+
async function fileExists(dir, filename) {
|
|
10
|
+
try {
|
|
11
|
+
await fs.access(path.join(dir, filename));
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Safely read and parse a JSON file. Returns null on failure. */
|
|
19
|
+
async function readJson(filePath) {
|
|
20
|
+
try {
|
|
21
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
22
|
+
return JSON.parse(raw);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Check if any file matching a glob-like pattern exists. */
|
|
29
|
+
async function hasFileWithExtension(dir, ext) {
|
|
30
|
+
try {
|
|
31
|
+
const entries = await fs.readdir(dir);
|
|
32
|
+
return entries.some((e) => e.endsWith(ext));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Detects the tech stack of a repository by inspecting its root directory
|
|
40
|
+
* for manifest files, config files, and project structures.
|
|
41
|
+
*
|
|
42
|
+
* @param repoPath - Absolute path to the repository root.
|
|
43
|
+
* @returns A {@link TechStack} object describing the detected stack.
|
|
44
|
+
*/
|
|
45
|
+
export async function detectTechStack(repoPath) {
|
|
46
|
+
const languages = [];
|
|
47
|
+
const frameworks = [];
|
|
48
|
+
const buildTools = [];
|
|
49
|
+
let projectType = 'other';
|
|
50
|
+
// āā Node.js / JavaScript / TypeScript āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
51
|
+
const hasPackageJson = await fileExists(repoPath, 'package.json');
|
|
52
|
+
if (hasPackageJson) {
|
|
53
|
+
const pkg = await readJson(path.join(repoPath, 'package.json'));
|
|
54
|
+
// Detect TypeScript vs JavaScript
|
|
55
|
+
const hasTsConfig = await fileExists(repoPath, 'tsconfig.json');
|
|
56
|
+
if (hasTsConfig) {
|
|
57
|
+
languages.push('typescript');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
languages.push('javascript');
|
|
61
|
+
}
|
|
62
|
+
if (pkg) {
|
|
63
|
+
const allDeps = {
|
|
64
|
+
...pkg.dependencies,
|
|
65
|
+
...pkg.devDependencies,
|
|
66
|
+
};
|
|
67
|
+
// Frameworks
|
|
68
|
+
if (allDeps['next']) {
|
|
69
|
+
frameworks.push('nextjs');
|
|
70
|
+
projectType = 'fullstack';
|
|
71
|
+
}
|
|
72
|
+
if (allDeps['react'] && !allDeps['next']) {
|
|
73
|
+
frameworks.push('react');
|
|
74
|
+
projectType = 'frontend';
|
|
75
|
+
}
|
|
76
|
+
if (allDeps['@angular/core']) {
|
|
77
|
+
frameworks.push('angular');
|
|
78
|
+
projectType = 'frontend';
|
|
79
|
+
}
|
|
80
|
+
if (allDeps['vue']) {
|
|
81
|
+
frameworks.push('vue');
|
|
82
|
+
projectType = 'frontend';
|
|
83
|
+
}
|
|
84
|
+
if (allDeps['svelte']) {
|
|
85
|
+
frameworks.push('svelte');
|
|
86
|
+
projectType = 'frontend';
|
|
87
|
+
}
|
|
88
|
+
if (allDeps['express']) {
|
|
89
|
+
frameworks.push('express');
|
|
90
|
+
projectType = 'backend';
|
|
91
|
+
}
|
|
92
|
+
if (allDeps['@nestjs/core']) {
|
|
93
|
+
frameworks.push('nestjs');
|
|
94
|
+
projectType = 'backend';
|
|
95
|
+
}
|
|
96
|
+
if (allDeps['fastify']) {
|
|
97
|
+
frameworks.push('fastify');
|
|
98
|
+
projectType = 'backend';
|
|
99
|
+
}
|
|
100
|
+
if (allDeps['hono']) {
|
|
101
|
+
frameworks.push('hono');
|
|
102
|
+
projectType = 'backend';
|
|
103
|
+
}
|
|
104
|
+
// Build tools
|
|
105
|
+
if (allDeps['vite'] || allDeps['@vitejs/plugin-react'])
|
|
106
|
+
buildTools.push('vite');
|
|
107
|
+
if (allDeps['webpack'])
|
|
108
|
+
buildTools.push('webpack');
|
|
109
|
+
if (allDeps['esbuild'])
|
|
110
|
+
buildTools.push('esbuild');
|
|
111
|
+
if (allDeps['rollup'])
|
|
112
|
+
buildTools.push('rollup');
|
|
113
|
+
if (allDeps['turbo'])
|
|
114
|
+
buildTools.push('turborepo');
|
|
115
|
+
if (allDeps['nx'])
|
|
116
|
+
buildTools.push('nx');
|
|
117
|
+
// Project type heuristics
|
|
118
|
+
if (pkg.bin)
|
|
119
|
+
projectType = 'cli';
|
|
120
|
+
if (pkg.main && !pkg.bin && frameworks.length === 0)
|
|
121
|
+
projectType = 'library';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// āā .NET / C# āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
125
|
+
const hasCsproj = await hasFileWithExtension(repoPath, '.csproj');
|
|
126
|
+
const hasSln = await hasFileWithExtension(repoPath, '.sln');
|
|
127
|
+
if (hasCsproj || hasSln) {
|
|
128
|
+
languages.push('csharp');
|
|
129
|
+
// Try to detect ASP.NET or Blazor from csproj content
|
|
130
|
+
try {
|
|
131
|
+
const entries = await fs.readdir(repoPath);
|
|
132
|
+
const csprojFile = entries.find((e) => e.endsWith('.csproj'));
|
|
133
|
+
if (csprojFile) {
|
|
134
|
+
const content = await fs.readFile(path.join(repoPath, csprojFile), 'utf-8');
|
|
135
|
+
if (content.includes('Microsoft.NET.Sdk.Web')) {
|
|
136
|
+
frameworks.push('aspnet');
|
|
137
|
+
projectType = 'backend';
|
|
138
|
+
}
|
|
139
|
+
if (content.includes('Microsoft.NET.Sdk.BlazorWebAssembly') || content.includes('Blazor')) {
|
|
140
|
+
frameworks.push('blazor');
|
|
141
|
+
projectType = 'frontend';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Ignore read errors
|
|
147
|
+
}
|
|
148
|
+
buildTools.push('dotnet');
|
|
149
|
+
}
|
|
150
|
+
// āā Python āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
151
|
+
const hasPyproject = await fileExists(repoPath, 'pyproject.toml');
|
|
152
|
+
const hasRequirements = await fileExists(repoPath, 'requirements.txt');
|
|
153
|
+
const hasSetupPy = await fileExists(repoPath, 'setup.py');
|
|
154
|
+
if (hasPyproject || hasRequirements || hasSetupPy) {
|
|
155
|
+
languages.push('python');
|
|
156
|
+
// Try to detect frameworks from requirements
|
|
157
|
+
try {
|
|
158
|
+
let content = '';
|
|
159
|
+
if (hasRequirements) {
|
|
160
|
+
content = await fs.readFile(path.join(repoPath, 'requirements.txt'), 'utf-8');
|
|
161
|
+
}
|
|
162
|
+
else if (hasPyproject) {
|
|
163
|
+
content = await fs.readFile(path.join(repoPath, 'pyproject.toml'), 'utf-8');
|
|
164
|
+
}
|
|
165
|
+
const lower = content.toLowerCase();
|
|
166
|
+
if (lower.includes('django')) {
|
|
167
|
+
frameworks.push('django');
|
|
168
|
+
projectType = 'backend';
|
|
169
|
+
}
|
|
170
|
+
if (lower.includes('flask')) {
|
|
171
|
+
frameworks.push('flask');
|
|
172
|
+
projectType = 'backend';
|
|
173
|
+
}
|
|
174
|
+
if (lower.includes('fastapi')) {
|
|
175
|
+
frameworks.push('fastapi');
|
|
176
|
+
projectType = 'backend';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Ignore
|
|
181
|
+
}
|
|
182
|
+
if (hasPyproject)
|
|
183
|
+
buildTools.push('pyproject');
|
|
184
|
+
if (hasSetupPy)
|
|
185
|
+
buildTools.push('setuptools');
|
|
186
|
+
}
|
|
187
|
+
// āā Go āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
188
|
+
const hasGoMod = await fileExists(repoPath, 'go.mod');
|
|
189
|
+
if (hasGoMod) {
|
|
190
|
+
languages.push('go');
|
|
191
|
+
buildTools.push('go');
|
|
192
|
+
try {
|
|
193
|
+
const content = await fs.readFile(path.join(repoPath, 'go.mod'), 'utf-8');
|
|
194
|
+
if (content.includes('github.com/gin-gonic/gin')) {
|
|
195
|
+
frameworks.push('gin');
|
|
196
|
+
projectType = 'backend';
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Ignore
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// āā Java āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
204
|
+
const hasPom = await fileExists(repoPath, 'pom.xml');
|
|
205
|
+
const hasGradle = await fileExists(repoPath, 'build.gradle');
|
|
206
|
+
const hasGradleKts = await fileExists(repoPath, 'build.gradle.kts');
|
|
207
|
+
if (hasPom || hasGradle || hasGradleKts) {
|
|
208
|
+
languages.push('java');
|
|
209
|
+
if (hasPom)
|
|
210
|
+
buildTools.push('maven');
|
|
211
|
+
if (hasGradle || hasGradleKts)
|
|
212
|
+
buildTools.push('gradle');
|
|
213
|
+
try {
|
|
214
|
+
let content = '';
|
|
215
|
+
if (hasPom) {
|
|
216
|
+
content = await fs.readFile(path.join(repoPath, 'pom.xml'), 'utf-8');
|
|
217
|
+
}
|
|
218
|
+
else if (hasGradle) {
|
|
219
|
+
content = await fs.readFile(path.join(repoPath, 'build.gradle'), 'utf-8');
|
|
220
|
+
}
|
|
221
|
+
if (content.includes('spring')) {
|
|
222
|
+
frameworks.push('spring');
|
|
223
|
+
projectType = 'backend';
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Ignore
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// āā Rust āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
231
|
+
const hasCargo = await fileExists(repoPath, 'Cargo.toml');
|
|
232
|
+
if (hasCargo) {
|
|
233
|
+
languages.push('rust');
|
|
234
|
+
buildTools.push('cargo');
|
|
235
|
+
}
|
|
236
|
+
// āā Ruby āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
237
|
+
const hasGemfile = await fileExists(repoPath, 'Gemfile');
|
|
238
|
+
if (hasGemfile) {
|
|
239
|
+
languages.push('ruby');
|
|
240
|
+
buildTools.push('bundler');
|
|
241
|
+
try {
|
|
242
|
+
const content = await fs.readFile(path.join(repoPath, 'Gemfile'), 'utf-8');
|
|
243
|
+
if (content.includes('rails')) {
|
|
244
|
+
frameworks.push('rails');
|
|
245
|
+
projectType = 'backend';
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// Ignore
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// āā PHP āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
253
|
+
const hasComposer = await fileExists(repoPath, 'composer.json');
|
|
254
|
+
if (hasComposer) {
|
|
255
|
+
languages.push('php');
|
|
256
|
+
buildTools.push('composer');
|
|
257
|
+
const composer = await readJson(path.join(repoPath, 'composer.json'));
|
|
258
|
+
if (composer) {
|
|
259
|
+
const req = composer.require;
|
|
260
|
+
if (req?.['laravel/framework']) {
|
|
261
|
+
frameworks.push('laravel');
|
|
262
|
+
projectType = 'backend';
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// āā Docker āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
267
|
+
if (await fileExists(repoPath, 'Dockerfile')) {
|
|
268
|
+
buildTools.push('docker');
|
|
269
|
+
}
|
|
270
|
+
if (await fileExists(repoPath, 'docker-compose.yml') || await fileExists(repoPath, 'compose.yaml')) {
|
|
271
|
+
buildTools.push('docker-compose');
|
|
272
|
+
}
|
|
273
|
+
// Fallback
|
|
274
|
+
if (languages.length === 0) {
|
|
275
|
+
languages.push('other');
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
languages,
|
|
279
|
+
frameworks,
|
|
280
|
+
buildTools,
|
|
281
|
+
projectType,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=tech-stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tech-stack.js","sourceRoot":"","sources":["../../src/analyzers/tech-stack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/create
|
|
3
|
+
* The main "create workspace" command ā the core NexusFlow workflow.
|
|
4
|
+
* Mirrors and enhances the user's existing Create-Workspace.ps1 script.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Executes the full "create workspace" flow:
|
|
8
|
+
* 1. Prompt for branch name
|
|
9
|
+
* 2. Prompt for feature description
|
|
10
|
+
* 3. Scan for repos and let user pick
|
|
11
|
+
* 4. Detect AI assistants and let user pick
|
|
12
|
+
* 5. Create workspace with git worktrees
|
|
13
|
+
* 6. Generate AI context files
|
|
14
|
+
* 7. Optionally open in editor
|
|
15
|
+
*/
|
|
16
|
+
export declare function createCommand(): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH;;;;;;;;;GASG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAwGnD"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/create
|
|
3
|
+
* The main "create workspace" command ā the core NexusFlow workflow.
|
|
4
|
+
* Mirrors and enhances the user's existing Create-Workspace.ps1 script.
|
|
5
|
+
*/
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { execa } from 'execa';
|
|
10
|
+
import { loadConfig } from '../core/config.js';
|
|
11
|
+
import { scanForRepos } from '../core/scanner.js';
|
|
12
|
+
import { createWorkspace } from '../core/workspace.js';
|
|
13
|
+
import { generateContextFiles } from '../generators/index.js';
|
|
14
|
+
import { analyzeAllRepos } from '../analyzers/index.js';
|
|
15
|
+
import { detectAIAssistants } from '../utils/detect-ai.js';
|
|
16
|
+
import { detectEditors } from '../utils/detect-editors.js';
|
|
17
|
+
import { promptBranchName, promptDescription, promptSelectRepos, promptSelectAI, promptSelectEditor, } from '../utils/prompts.js';
|
|
18
|
+
/**
|
|
19
|
+
* Executes the full "create workspace" flow:
|
|
20
|
+
* 1. Prompt for branch name
|
|
21
|
+
* 2. Prompt for feature description
|
|
22
|
+
* 3. Scan for repos and let user pick
|
|
23
|
+
* 4. Detect AI assistants and let user pick
|
|
24
|
+
* 5. Create workspace with git worktrees
|
|
25
|
+
* 6. Generate AI context files
|
|
26
|
+
* 7. Optionally open in editor
|
|
27
|
+
*/
|
|
28
|
+
export async function createCommand() {
|
|
29
|
+
console.log(chalk.bold.cyan('\nš NexusFlow ā Create Feature Workspace\n'));
|
|
30
|
+
// āā 1. Branch name āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
31
|
+
const branchName = await promptBranchName();
|
|
32
|
+
// āā 2. Feature description āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
33
|
+
const description = await promptDescription();
|
|
34
|
+
// āā 3. Scan for repos āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
35
|
+
const config = await loadConfig();
|
|
36
|
+
const spinner = ora('Scanning for projects...').start();
|
|
37
|
+
let repos;
|
|
38
|
+
try {
|
|
39
|
+
repos = await scanForRepos(config.devDir, config.scanDepth);
|
|
40
|
+
spinner.succeed(`Found ${chalk.bold(repos.length)} projects in ${config.devDir}`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
spinner.fail('Failed to scan for projects');
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
if (repos.length === 0) {
|
|
47
|
+
console.log(chalk.yellow('No git projects found. Check your devDir setting.'));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// āā 4. Select repos āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
51
|
+
const selectedRepos = await promptSelectRepos(repos);
|
|
52
|
+
if (selectedRepos.length === 0) {
|
|
53
|
+
console.log(chalk.yellow('No projects selected. Exiting.'));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log(chalk.dim(` Selected: ${selectedRepos.map((r) => r.name).join(', ')}`));
|
|
57
|
+
// āā 5. Detect and select AI assistants āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
58
|
+
const detectedAI = await detectAIAssistants();
|
|
59
|
+
const selectedAI = await promptSelectAI(detectedAI);
|
|
60
|
+
// āā 6. Create workspace āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
61
|
+
const workspacePath = path.join(config.workspacesDir, branchName);
|
|
62
|
+
const feature = {
|
|
63
|
+
id: branchName,
|
|
64
|
+
branchName,
|
|
65
|
+
description,
|
|
66
|
+
repos: selectedRepos.map((r) => r.path),
|
|
67
|
+
assistants: selectedAI,
|
|
68
|
+
workspacePath,
|
|
69
|
+
createdAt: new Date().toISOString(),
|
|
70
|
+
};
|
|
71
|
+
const wsSpinner = ora('Creating workspace with git worktrees...').start();
|
|
72
|
+
try {
|
|
73
|
+
await createWorkspace(feature, selectedRepos);
|
|
74
|
+
wsSpinner.succeed(`Workspace created at ${chalk.bold(workspacePath)}`);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
wsSpinner.fail('Failed to create workspace');
|
|
78
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
79
|
+
console.error(chalk.red(` ${message}`));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// āā 7. Analyze projects āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
83
|
+
console.log(chalk.cyan('\nAnalyzing projects...'));
|
|
84
|
+
const analysis = await analyzeAllRepos(selectedRepos);
|
|
85
|
+
// āā 8. Generate AI context files āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
86
|
+
const ctx = { feature, repos: selectedRepos, analysis };
|
|
87
|
+
console.log(chalk.cyan('\nGenerating AI context files...'));
|
|
88
|
+
await generateContextFiles(ctx, selectedAI, workspacePath);
|
|
89
|
+
// āā 8. Open in editor āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
90
|
+
const detectedEditors = await detectEditors();
|
|
91
|
+
const editor = await promptSelectEditor(detectedEditors);
|
|
92
|
+
if (editor) {
|
|
93
|
+
const editorSpinner = ora(`Opening in ${editor.name}...`).start();
|
|
94
|
+
try {
|
|
95
|
+
await execa(editor.command, [workspacePath], { stdio: 'ignore' });
|
|
96
|
+
editorSpinner.succeed(`Opened in ${editor.name}`);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
editorSpinner.warn(`Could not open ${editor.name}. Open manually:\n ${chalk.dim(`cd "${workspacePath}"`)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// āā Done āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
103
|
+
console.log(chalk.bold.green('\nā
Workspace ready!\n'));
|
|
104
|
+
console.log(` ${chalk.dim('Path:')} ${workspacePath}`);
|
|
105
|
+
console.log(` ${chalk.dim('Branch:')} ${branchName}`);
|
|
106
|
+
console.log(` ${chalk.dim('Repos:')} ${selectedRepos.map((r) => r.name).join(', ')}`);
|
|
107
|
+
console.log(` ${chalk.dim('AI:')} ${selectedAI.join(', ')}`);
|
|
108
|
+
console.log(`\n ${chalk.dim('To navigate:')} cd "${workspacePath}"`);
|
|
109
|
+
console.log();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/init
|
|
3
|
+
* Initializes the NexusFlow configuration.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Initializes NexusFlow configuration interactively.
|
|
7
|
+
* Creates ~/.nexusflow/config.json with user preferences.
|
|
8
|
+
*/
|
|
9
|
+
export declare function initCommand(): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;GAGG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyCjD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/init
|
|
3
|
+
* Initializes the NexusFlow configuration.
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { input } from '@inquirer/prompts';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import os from 'node:os';
|
|
9
|
+
import { loadConfig, saveConfig, ensureConfigDir } from '../core/config.js';
|
|
10
|
+
/**
|
|
11
|
+
* Initializes NexusFlow configuration interactively.
|
|
12
|
+
* Creates ~/.nexusflow/config.json with user preferences.
|
|
13
|
+
*/
|
|
14
|
+
export async function initCommand() {
|
|
15
|
+
console.log(chalk.bold.cyan('\nāļø NexusFlow ā Initialize\n'));
|
|
16
|
+
await ensureConfigDir();
|
|
17
|
+
const existing = await loadConfig();
|
|
18
|
+
const devDir = await input({
|
|
19
|
+
message: 'Development directory (where your repos live):',
|
|
20
|
+
default: existing.devDir || path.join(os.homedir(), 'dev'),
|
|
21
|
+
});
|
|
22
|
+
const workspacesDir = await input({
|
|
23
|
+
message: 'Workspaces directory (where feature workspaces are created):',
|
|
24
|
+
default: existing.workspacesDir || path.join(devDir, 'workspaces'),
|
|
25
|
+
});
|
|
26
|
+
const scanDepth = await input({
|
|
27
|
+
message: 'How deep to scan for repos (directory levels):',
|
|
28
|
+
default: String(existing.scanDepth || 2),
|
|
29
|
+
validate: (value) => {
|
|
30
|
+
const num = parseInt(value, 10);
|
|
31
|
+
if (isNaN(num) || num < 1 || num > 10)
|
|
32
|
+
return 'Enter a number between 1 and 10';
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const config = {
|
|
37
|
+
...existing,
|
|
38
|
+
devDir: devDir.trim(),
|
|
39
|
+
workspacesDir: workspacesDir.trim(),
|
|
40
|
+
scanDepth: parseInt(scanDepth, 10),
|
|
41
|
+
};
|
|
42
|
+
await saveConfig(config);
|
|
43
|
+
console.log(chalk.green('\nā
Configuration saved!\n'));
|
|
44
|
+
console.log(chalk.dim(' Config file: ~/.nexusflow/config.json'));
|
|
45
|
+
console.log(chalk.dim(` Dev dir: ${config.devDir}`));
|
|
46
|
+
console.log(chalk.dim(` Workspaces: ${config.workspacesDir}`));
|
|
47
|
+
console.log(chalk.dim(` Scan depth: ${config.scanDepth}`));
|
|
48
|
+
console.log(chalk.dim('\n Run "nexusflow create" to create your first workspace.\n'));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE5E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAE/D,MAAM,eAAe,EAAE,CAAC;IACxB,MAAM,QAAQ,GAAG,MAAM,UAAU,EAAE,CAAC;IAEpC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;QACzB,OAAO,EAAE,gDAAgD;QACzD,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC;KAC3D,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC;QAChC,OAAO,EAAE,8DAA8D;QACvE,OAAO,EAAE,QAAQ,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;KACnE,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC;QAC5B,OAAO,EAAE,gDAAgD;QACzD,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAC;QACxC,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;YAC1B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,EAAE;gBAAE,OAAO,iCAAiC,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG;QACb,GAAG,QAAQ;QACX,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;QACrB,aAAa,EAAE,aAAa,CAAC,IAAI,EAAE;QACnC,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;KACnC,CAAC;IAEF,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IAEzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAgCjD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/list
|
|
3
|
+
* Lists all existing NexusFlow workspaces.
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { loadConfig } from '../core/config.js';
|
|
7
|
+
import { listWorkspaces } from '../core/workspace.js';
|
|
8
|
+
/**
|
|
9
|
+
* Lists all existing workspaces, showing feature name, repos, and status.
|
|
10
|
+
*/
|
|
11
|
+
export async function listCommand() {
|
|
12
|
+
const config = await loadConfig();
|
|
13
|
+
const workspaces = await listWorkspaces(config.workspacesDir);
|
|
14
|
+
if (workspaces.length === 0) {
|
|
15
|
+
console.log(chalk.yellow('\nNo workspaces found.'));
|
|
16
|
+
console.log(chalk.dim(` Workspaces directory: ${config.workspacesDir}`));
|
|
17
|
+
console.log(chalk.dim(' Run "nexusflow create" to create your first workspace.\n'));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(chalk.bold.cyan(`\nš NexusFlow Workspaces (${workspaces.length})\n`));
|
|
21
|
+
for (const ws of workspaces) {
|
|
22
|
+
const repoCount = ws.repos.length;
|
|
23
|
+
const aiList = ws.assistants.join(', ');
|
|
24
|
+
const date = new Date(ws.createdAt).toLocaleDateString();
|
|
25
|
+
console.log(` ${chalk.bold(ws.branchName)} ${chalk.dim(`(${date})`)}`);
|
|
26
|
+
console.log(` ${chalk.dim('Repos:')} ${repoCount} project${repoCount !== 1 ? 's' : ''}`);
|
|
27
|
+
console.log(` ${chalk.dim('AI:')} ${aiList || 'none'}`);
|
|
28
|
+
console.log(` ${chalk.dim('Path:')} ${ws.workspacePath}`);
|
|
29
|
+
console.log();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAE9D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC,CAAC;QACrF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAEnF,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;QAClC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,CAAC;QAEzD,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAC3D,CAAC;QACF,OAAO,CAAC,GAAG,CACT,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS,WAAW,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAChF,CAAC;QACF,OAAO,CAAC,GAAG,CACT,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,MAAM,IAAI,MAAM,EAAE,CAClD,CAAC;QACF,OAAO,CAAC,GAAG,CACT,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,CAClD,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/logs
|
|
3
|
+
* Shows aggregated logs from all services in a workspace.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Shows logs and status for services in a workspace.
|
|
7
|
+
*
|
|
8
|
+
* @param workspaceArg - Optional workspace path from CLI.
|
|
9
|
+
* @param lines - Number of log lines to show per service.
|
|
10
|
+
*/
|
|
11
|
+
export declare function logsCommand(workspaceArg?: string, lines?: number): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAe1F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module commands/logs
|
|
3
|
+
* Shows aggregated logs from all services in a workspace.
|
|
4
|
+
*/
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { select } from '@inquirer/prompts';
|
|
8
|
+
import { loadConfig } from '../core/config.js';
|
|
9
|
+
import { listWorkspaces, loadFeatureConfig } from '../core/workspace.js';
|
|
10
|
+
import { showLogs, getServiceStatus } from '../orchestration/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Shows logs and status for services in a workspace.
|
|
13
|
+
*
|
|
14
|
+
* @param workspaceArg - Optional workspace path from CLI.
|
|
15
|
+
* @param lines - Number of log lines to show per service.
|
|
16
|
+
*/
|
|
17
|
+
export async function logsCommand(workspaceArg, lines = 30) {
|
|
18
|
+
console.log(chalk.bold.cyan('\nš NexusFlow ā Service Logs\n'));
|
|
19
|
+
const workspacePath = await resolveWorkspace(workspaceArg);
|
|
20
|
+
if (!workspacePath)
|
|
21
|
+
return;
|
|
22
|
+
// Show service status first
|
|
23
|
+
console.log(chalk.cyan('Service Status:'));
|
|
24
|
+
await getServiceStatus(workspacePath);
|
|
25
|
+
// Show logs
|
|
26
|
+
const logDir = path.join(workspacePath, '.nexusflow-logs');
|
|
27
|
+
await showLogs(workspacePath, logDir, lines);
|
|
28
|
+
console.log();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolves a workspace path from argument, cwd, or user prompt.
|
|
32
|
+
*/
|
|
33
|
+
async function resolveWorkspace(workspaceArg) {
|
|
34
|
+
if (workspaceArg)
|
|
35
|
+
return workspaceArg;
|
|
36
|
+
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
37
|
+
if (cwdFeature)
|
|
38
|
+
return process.cwd();
|
|
39
|
+
const config = await loadConfig();
|
|
40
|
+
const workspaces = await listWorkspaces(config.workspacesDir);
|
|
41
|
+
if (workspaces.length === 0) {
|
|
42
|
+
console.log(chalk.yellow('No workspaces found.\n'));
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const selected = await select({
|
|
46
|
+
message: 'Select a workspace to view logs for:',
|
|
47
|
+
choices: workspaces.map((ws) => ({
|
|
48
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
|
|
49
|
+
value: ws.workspacePath,
|
|
50
|
+
})),
|
|
51
|
+
});
|
|
52
|
+
return selected;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,YAAqB,EAAE,QAAgB,EAAE;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAEhE,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC,aAAa;QAAE,OAAO;IAE3B,4BAA4B;IAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC3C,MAAM,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAEtC,YAAY;IACZ,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAC3D,MAAM,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAE7C,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,YAAqB;IACnD,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IAEtC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1D,IAAI,UAAU;QAAE,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAE9D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,sCAAsC;QAC/C,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/B,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,SAAS,CAAC,EAAE;YACnE,KAAK,EAAE,EAAE,CAAC,aAAa;SACxB,CAAC,CAAC;KACJ,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|