@mrpatronz/nexusflow 1.3.3 → 1.6.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/README.md +50 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +85 -44
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +16 -73
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +58 -318
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/finish.d.ts +17 -0
- package/dist/commands/finish.d.ts.map +1 -0
- package/dist/commands/finish.js +173 -0
- package/dist/commands/finish.js.map +1 -0
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +11 -6
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/knowledge.d.ts +36 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +184 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +2 -4
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/refresh.d.ts +2 -1
- package/dist/commands/refresh.d.ts.map +1 -1
- package/dist/commands/refresh.js +35 -2
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/strategy.d.ts +37 -0
- package/dist/commands/strategy.d.ts.map +1 -0
- package/dist/commands/strategy.js +198 -0
- package/dist/commands/strategy.js.map +1 -0
- package/dist/core/commit.d.ts +41 -0
- package/dist/core/commit.d.ts.map +1 -0
- package/dist/core/commit.js +53 -0
- package/dist/core/commit.js.map +1 -0
- package/dist/core/config.d.ts +3 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +60 -32
- package/dist/core/config.js.map +1 -1
- package/dist/core/config.test.js +24 -0
- package/dist/core/config.test.js.map +1 -1
- package/dist/core/diff.d.ts +27 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/diff.js +50 -0
- package/dist/core/diff.js.map +1 -0
- package/dist/core/doctor.d.ts +34 -0
- package/dist/core/doctor.d.ts.map +1 -0
- package/dist/core/doctor.js +276 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/finish.d.ts +56 -0
- package/dist/core/finish.d.ts.map +1 -0
- package/dist/core/finish.js +121 -0
- package/dist/core/finish.js.map +1 -0
- package/dist/core/finish.test.d.ts +2 -0
- package/dist/core/finish.test.d.ts.map +1 -0
- package/dist/core/finish.test.js +110 -0
- package/dist/core/finish.test.js.map +1 -0
- package/dist/core/knowledge.d.ts +96 -0
- package/dist/core/knowledge.d.ts.map +1 -0
- package/dist/core/knowledge.js +299 -0
- package/dist/core/knowledge.js.map +1 -0
- package/dist/core/knowledge.test.d.ts +2 -0
- package/dist/core/knowledge.test.d.ts.map +1 -0
- package/dist/core/knowledge.test.js +157 -0
- package/dist/core/knowledge.test.js.map +1 -0
- package/dist/core/refresh.test.d.ts +2 -0
- package/dist/core/refresh.test.d.ts.map +1 -0
- package/dist/core/refresh.test.js +67 -0
- package/dist/core/refresh.test.js.map +1 -0
- package/dist/core/status.d.ts +45 -0
- package/dist/core/status.d.ts.map +1 -0
- package/dist/core/status.js +45 -0
- package/dist/core/status.js.map +1 -0
- package/dist/core/sync.test.d.ts +2 -0
- package/dist/core/sync.test.d.ts.map +1 -0
- package/dist/core/sync.test.js +86 -0
- package/dist/core/sync.test.js.map +1 -0
- package/dist/core/workspace.create.test.d.ts +2 -0
- package/dist/core/workspace.create.test.d.ts.map +1 -0
- package/dist/core/workspace.create.test.js +95 -0
- package/dist/core/workspace.create.test.js.map +1 -0
- package/dist/core/workspace.d.ts +9 -3
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +91 -13
- package/dist/core/workspace.js.map +1 -1
- package/dist/core/worktree.d.ts +11 -1
- package/dist/core/worktree.d.ts.map +1 -1
- package/dist/core/worktree.js +2 -0
- package/dist/core/worktree.js.map +1 -1
- package/dist/core/worktree.test.d.ts +2 -0
- package/dist/core/worktree.test.d.ts.map +1 -0
- package/dist/core/worktree.test.js +111 -0
- package/dist/core/worktree.test.js.map +1 -0
- package/dist/generators/base.js +1 -1
- package/dist/generators/index.d.ts +7 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +4 -1
- package/dist/generators/index.js.map +1 -1
- package/dist/index.js +205 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +51 -282
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +45 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +413 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +43 -26
- package/dist/server.js.map +1 -1
- package/dist/utils/debug.d.ts +17 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +25 -0
- package/dist/utils/debug.js.map +1 -0
- package/dist/utils/detect-ai.d.ts +14 -6
- package/dist/utils/detect-ai.d.ts.map +1 -1
- package/dist/utils/detect-ai.js +22 -9
- package/dist/utils/detect-ai.js.map +1 -1
- package/dist/utils/detect-ai.test.js +33 -0
- package/dist/utils/detect-ai.test.js.map +1 -1
- package/dist/utils/git.d.ts +13 -2
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +64 -5
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/git.test.js +46 -8
- package/dist/utils/git.test.js.map +1 -1
- package/dist/utils/multi-git.d.ts +40 -0
- package/dist/utils/multi-git.d.ts.map +1 -1
- package/dist/utils/multi-git.js +80 -0
- package/dist/utils/multi-git.js.map +1 -1
- package/dist/utils/multi-git.test.js +54 -1
- package/dist/utils/multi-git.test.js.map +1 -1
- package/dist/utils/open-editor.d.ts +20 -0
- package/dist/utils/open-editor.d.ts.map +1 -0
- package/dist/utils/open-editor.js +44 -0
- package/dist/utils/open-editor.js.map +1 -0
- package/dist/utils/pr.d.ts +50 -0
- package/dist/utils/pr.d.ts.map +1 -0
- package/dist/utils/pr.js +144 -0
- package/dist/utils/pr.js.map +1 -0
- package/dist/utils/pr.test.d.ts +2 -0
- package/dist/utils/pr.test.d.ts.map +1 -0
- package/dist/utils/pr.test.js +47 -0
- package/dist/utils/pr.test.js.map +1 -0
- package/dist/utils/prompts.d.ts +22 -1
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +145 -24
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/resolve-workspace.d.ts +30 -0
- package/dist/utils/resolve-workspace.d.ts.map +1 -0
- package/dist/utils/resolve-workspace.js +77 -0
- package/dist/utils/resolve-workspace.js.map +1 -0
- package/dist/utils/workflow-advisor.d.ts +2 -0
- package/dist/utils/workflow-advisor.d.ts.map +1 -1
- package/dist/utils/workflow-advisor.js +27 -4
- package/dist/utils/workflow-advisor.js.map +1 -1
- package/package.json +11 -11
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/doctor
|
|
3
|
+
* Headless workspace diagnostics. Produces a structured {@link DoctorReport}
|
|
4
|
+
* shared by the CLI `doctor` renderer and the MCP `run_doctor` tool. The local
|
|
5
|
+
* AI connectivity probe uses fetch + AbortController, so this is safe to run
|
|
6
|
+
* outside a TTY.
|
|
7
|
+
*/
|
|
8
|
+
export type DoctorCheckStatus = 'pass' | 'warn' | 'fail' | 'info';
|
|
9
|
+
/** A single diagnostic result. */
|
|
10
|
+
export interface DoctorCheck {
|
|
11
|
+
category: string;
|
|
12
|
+
name: string;
|
|
13
|
+
status: DoctorCheckStatus;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
/** Full diagnostic report for a workspace. */
|
|
17
|
+
export interface DoctorReport {
|
|
18
|
+
workspacePath: string;
|
|
19
|
+
branchName: string;
|
|
20
|
+
checks: DoctorCheck[];
|
|
21
|
+
errors: string[];
|
|
22
|
+
warnings: string[];
|
|
23
|
+
healthy: boolean;
|
|
24
|
+
/** True when worktree-path errors aborted the deeper checks. */
|
|
25
|
+
aborted: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Runs all workspace diagnostics and returns a structured report.
|
|
29
|
+
*
|
|
30
|
+
* @param workspacePath - Absolute path to the workspace directory.
|
|
31
|
+
* @throws If the workspace manifest cannot be loaded.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runDoctor(workspacePath: string): Promise<DoctorReport>;
|
|
34
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAElE,kCAAkC;AAClC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;CAClB;AAWD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6O5E"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/doctor
|
|
3
|
+
* Headless workspace diagnostics. Produces a structured {@link DoctorReport}
|
|
4
|
+
* shared by the CLI `doctor` renderer and the MCP `run_doctor` tool. The local
|
|
5
|
+
* AI connectivity probe uses fetch + AbortController, so this is safe to run
|
|
6
|
+
* outside a TTY.
|
|
7
|
+
*/
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import * as fs from 'node:fs/promises';
|
|
10
|
+
import { execa } from 'execa';
|
|
11
|
+
import { globby } from 'globby';
|
|
12
|
+
import { loadConfig } from './config.js';
|
|
13
|
+
import { loadFeatureConfig, resolveRepoInfos } from './workspace.js';
|
|
14
|
+
import { getRepoStatus } from '../utils/multi-git.js';
|
|
15
|
+
import { workspaceFileExists, baseFileExists } from './storage.js';
|
|
16
|
+
import { analyzeAllReposCached } from '../analyzers/index.js';
|
|
17
|
+
import { isOllamaModelAvailable, getOpenAiCompatibleUrl } from '../utils/local-ai.js';
|
|
18
|
+
/** Resolves the conventional test command for a repo's tech stack. */
|
|
19
|
+
function getTestCommand(analysis) {
|
|
20
|
+
if (analysis.techStack.languages.includes('csharp'))
|
|
21
|
+
return 'dotnet test';
|
|
22
|
+
if (analysis.techStack.languages.includes('typescript') || analysis.techStack.languages.includes('javascript'))
|
|
23
|
+
return 'npm test';
|
|
24
|
+
if (analysis.techStack.languages.includes('python'))
|
|
25
|
+
return 'pytest';
|
|
26
|
+
if (analysis.techStack.languages.includes('go'))
|
|
27
|
+
return 'go test ./...';
|
|
28
|
+
return 'npm test';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Runs all workspace diagnostics and returns a structured report.
|
|
32
|
+
*
|
|
33
|
+
* @param workspacePath - Absolute path to the workspace directory.
|
|
34
|
+
* @throws If the workspace manifest cannot be loaded.
|
|
35
|
+
*/
|
|
36
|
+
export async function runDoctor(workspacePath) {
|
|
37
|
+
const feature = await loadFeatureConfig(workspacePath);
|
|
38
|
+
if (!feature) {
|
|
39
|
+
throw new Error('Failed to load workspace configuration. Ensure nexusflow.json exists.');
|
|
40
|
+
}
|
|
41
|
+
const allRepos = await resolveRepoInfos(feature.repos);
|
|
42
|
+
const checks = [];
|
|
43
|
+
const warnings = [];
|
|
44
|
+
const errors = [];
|
|
45
|
+
const report = () => ({
|
|
46
|
+
workspacePath,
|
|
47
|
+
branchName: feature.branchName,
|
|
48
|
+
checks,
|
|
49
|
+
errors,
|
|
50
|
+
warnings,
|
|
51
|
+
healthy: errors.length === 0 && warnings.length === 0,
|
|
52
|
+
aborted: false,
|
|
53
|
+
});
|
|
54
|
+
// ── 1. Worktree Paths ──────────────────────────────────────────────────
|
|
55
|
+
let worktreeErrors = false;
|
|
56
|
+
for (const repo of allRepos) {
|
|
57
|
+
try {
|
|
58
|
+
const stat = await fs.stat(repo.path);
|
|
59
|
+
if (!stat.isDirectory()) {
|
|
60
|
+
errors.push(`Worktree path for "${repo.name}" is not a directory.`);
|
|
61
|
+
checks.push({ category: 'Worktree Paths', name: repo.name, status: 'fail', message: 'Path is not a directory' });
|
|
62
|
+
worktreeErrors = true;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
checks.push({ category: 'Worktree Paths', name: repo.name, status: 'pass', message: 'Directory exists' });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
errors.push(`Worktree path for "${repo.name}" does not exist: ${repo.path}`);
|
|
70
|
+
checks.push({ category: 'Worktree Paths', name: repo.name, status: 'fail', message: 'Path does not exist' });
|
|
71
|
+
worktreeErrors = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (worktreeErrors) {
|
|
75
|
+
return { ...report(), aborted: true };
|
|
76
|
+
}
|
|
77
|
+
// ── 2. Analysis (feeds later checks) ───────────────────────────────────
|
|
78
|
+
const { analysis } = await analyzeAllReposCached(allRepos, workspacePath);
|
|
79
|
+
// ── 3. Branch Alignment & Git Status ───────────────────────────────────
|
|
80
|
+
for (const repo of allRepos) {
|
|
81
|
+
let branch = 'unknown';
|
|
82
|
+
try {
|
|
83
|
+
const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: repo.path });
|
|
84
|
+
branch = stdout.trim();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Detached HEAD or git failure — leave as 'unknown'.
|
|
88
|
+
}
|
|
89
|
+
if (branch !== feature.branchName) {
|
|
90
|
+
warnings.push(`Repository "${repo.name}" is checked out on branch "${branch}", but workspace branch is "${feature.branchName}".`);
|
|
91
|
+
checks.push({ category: 'Branch Alignment & Git Status', name: repo.name, status: 'warn', message: `Branch mismatch (${branch} vs expected ${feature.branchName})` });
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
checks.push({ category: 'Branch Alignment & Git Status', name: repo.name, status: 'pass', message: `Aligned on branch "${branch}"` });
|
|
95
|
+
}
|
|
96
|
+
const status = await getRepoStatus(repo.path);
|
|
97
|
+
if (status.hasChanges) {
|
|
98
|
+
warnings.push(`Repository "${repo.name}" has uncommitted changes.`);
|
|
99
|
+
checks.push({ category: 'Branch Alignment & Git Status', name: repo.name, status: 'warn', message: `Has uncommitted changes (${status.summary})` });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// ── 4. Local Package Setup & Reference Versioning ──────────────────────
|
|
103
|
+
let hasCsharp = false;
|
|
104
|
+
let hasNode = false;
|
|
105
|
+
for (const repo of allRepos) {
|
|
106
|
+
const a = analysis.get(repo.path);
|
|
107
|
+
if (!a)
|
|
108
|
+
continue;
|
|
109
|
+
if (a.techStack.languages.includes('csharp'))
|
|
110
|
+
hasCsharp = true;
|
|
111
|
+
if (a.techStack.languages.includes('typescript') || a.techStack.languages.includes('javascript'))
|
|
112
|
+
hasNode = true;
|
|
113
|
+
if (a.techStack.languages.includes('csharp')) {
|
|
114
|
+
try {
|
|
115
|
+
const csprojs = await globby('**/*.csproj', {
|
|
116
|
+
cwd: repo.path,
|
|
117
|
+
absolute: true,
|
|
118
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', '**/dist/**', '**/out/**', '**/.git/**'],
|
|
119
|
+
});
|
|
120
|
+
for (const csproj of csprojs) {
|
|
121
|
+
const content = await fs.readFile(csproj, 'utf-8');
|
|
122
|
+
if (content.toLowerCase().includes('-local') || content.toLowerCase().includes('-dev')) {
|
|
123
|
+
warnings.push(`Temporary package version (e.g. ending in "-local" or "-dev") found in "${path.basename(csproj)}".`);
|
|
124
|
+
checks.push({ category: 'Local Package Setup', name: repo.name, status: 'warn', message: `Temporary local package version in "${path.basename(csproj)}"` });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch { }
|
|
129
|
+
if (a.nugetFeeds && a.nugetFeeds.length === 0) {
|
|
130
|
+
try {
|
|
131
|
+
const nugetConfigs = await globby('**/NuGet.config', {
|
|
132
|
+
cwd: repo.path,
|
|
133
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', '**/dist/**', '**/out/**', '**/.git/**'],
|
|
134
|
+
});
|
|
135
|
+
if (nugetConfigs.length === 0) {
|
|
136
|
+
warnings.push(`Repository "${repo.name}" does not have a NuGet.config. It might not resolve local package dependencies.`);
|
|
137
|
+
checks.push({ category: 'Local Package Setup', name: repo.name, status: 'warn', message: 'No NuGet.config found (needed for local package feeds)' });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch { }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (a.techStack.languages.includes('typescript') || a.techStack.languages.includes('javascript')) {
|
|
144
|
+
try {
|
|
145
|
+
const pjs = await globby('**/package.json', {
|
|
146
|
+
cwd: repo.path,
|
|
147
|
+
absolute: true,
|
|
148
|
+
ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', '**/dist/**', '**/out/**', '**/.git/**'],
|
|
149
|
+
});
|
|
150
|
+
for (const pj of pjs) {
|
|
151
|
+
const content = await fs.readFile(pj, 'utf-8');
|
|
152
|
+
if (content.includes('"file:') || content.includes('"link:')) {
|
|
153
|
+
warnings.push(`Temporary package link/file reference (e.g., "file:../") found in "${path.basename(pj)}".`);
|
|
154
|
+
checks.push({ category: 'Local Package Setup', name: repo.name, status: 'warn', message: `Temporary local dependency reference ("file:" or "link:") in "${path.basename(pj)}"` });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch { }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (hasCsharp || hasNode) {
|
|
162
|
+
checks.push({ category: 'Local Package Setup', name: 'validation', status: 'pass', message: 'Local registry feeds/link validation completed.' });
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
checks.push({ category: 'Local Package Setup', name: 'validation', status: 'info', message: 'No C# or Node.js repositories to validate.' });
|
|
166
|
+
}
|
|
167
|
+
// ── 5. Test Commands ───────────────────────────────────────────────────
|
|
168
|
+
for (const repo of allRepos) {
|
|
169
|
+
const a = analysis.get(repo.path);
|
|
170
|
+
if (!a)
|
|
171
|
+
continue;
|
|
172
|
+
const testCommand = getTestCommand(a);
|
|
173
|
+
if (testCommand === 'npm test' && !a.techStack.languages.includes('typescript') && !a.techStack.languages.includes('javascript')) {
|
|
174
|
+
warnings.push(`Repository "${repo.name}" fell back to default test command "npm test".`);
|
|
175
|
+
checks.push({ category: 'Test Commands', name: repo.name, status: 'warn', message: 'Using default fallback test command "npm test"' });
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
checks.push({ category: 'Test Commands', name: repo.name, status: 'pass', message: `Test command is "${testCommand}"` });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// ── 6. Core Artifacts ──────────────────────────────────────────────────
|
|
182
|
+
const featureId = path.basename(workspacePath);
|
|
183
|
+
const coreFiles = [
|
|
184
|
+
{ name: 'WORKSPACE.md', exists: () => workspaceFileExists(workspacePath, featureId, 'WORKSPACE.md') },
|
|
185
|
+
{ name: 'nexusflow-knowledge.md', exists: () => workspaceFileExists(workspacePath, featureId, 'nexusflow-knowledge.md') },
|
|
186
|
+
{ name: 'nexusflow-plan.md', exists: () => workspaceFileExists(workspacePath, featureId, 'nexusflow-plan.md') },
|
|
187
|
+
];
|
|
188
|
+
for (const repo of allRepos) {
|
|
189
|
+
const name = `nexusflow-map-${repo.name}.md`;
|
|
190
|
+
coreFiles.push({ name, exists: () => baseFileExists(workspacePath, repo.name, name) });
|
|
191
|
+
}
|
|
192
|
+
for (const file of coreFiles) {
|
|
193
|
+
if (await file.exists()) {
|
|
194
|
+
checks.push({ category: 'Core Artifacts', name: file.name, status: 'pass', message: 'exists' });
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
warnings.push(`Missing core workspace artifact: "${file.name}".`);
|
|
198
|
+
checks.push({ category: 'Core Artifacts', name: file.name, status: 'warn', message: 'is missing' });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const workspaceName = path.basename(workspacePath);
|
|
202
|
+
const codeWorkspacePath = path.join(workspacePath, `${workspaceName}.code-workspace`);
|
|
203
|
+
try {
|
|
204
|
+
await fs.access(codeWorkspacePath);
|
|
205
|
+
checks.push({ category: 'Core Artifacts', name: `${workspaceName}.code-workspace`, status: 'pass', message: 'exists' });
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
warnings.push(`Missing ${workspaceName}.code-workspace. VS Code SCM will not show changes inside repo sub-folders. Run \`nexusflow refresh\` to regenerate it.`);
|
|
209
|
+
checks.push({ category: 'Core Artifacts', name: `${workspaceName}.code-workspace`, status: 'warn', message: 'is missing' });
|
|
210
|
+
}
|
|
211
|
+
const vscodeSettingsPath = path.join(workspacePath, '.vscode', 'settings.json');
|
|
212
|
+
try {
|
|
213
|
+
const content = await fs.readFile(vscodeSettingsPath, 'utf-8');
|
|
214
|
+
const parsed = JSON.parse(content);
|
|
215
|
+
if (parsed['search.useIgnoreFiles'] === false) {
|
|
216
|
+
checks.push({ category: 'Core Artifacts', name: '.vscode/settings.json', status: 'pass', message: 'configured correctly (search.useIgnoreFiles: false)' });
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
warnings.push('.vscode/settings.json search.useIgnoreFiles is not set to false. VS Code global search may ignore repository files.');
|
|
220
|
+
checks.push({ category: 'Core Artifacts', name: '.vscode/settings.json', status: 'warn', message: 'search.useIgnoreFiles is not set to false' });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
warnings.push('Missing .vscode/settings.json. VS Code search might not work properly inside sub-repos.');
|
|
225
|
+
checks.push({ category: 'Core Artifacts', name: '.vscode/settings.json', status: 'warn', message: 'is missing or invalid' });
|
|
226
|
+
}
|
|
227
|
+
// ── 7. Local AI Agent Connection ───────────────────────────────────────
|
|
228
|
+
const config = await loadConfig();
|
|
229
|
+
if (config.localLlm?.enabled) {
|
|
230
|
+
const { provider, endpoint, model } = config.localLlm;
|
|
231
|
+
try {
|
|
232
|
+
const cleanEndpoint = endpoint.replace(/\/$/, '');
|
|
233
|
+
const controller = new AbortController();
|
|
234
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
235
|
+
try {
|
|
236
|
+
if (provider === 'ollama') {
|
|
237
|
+
const res = await fetch(`${cleanEndpoint}/api/tags`, { signal: controller.signal });
|
|
238
|
+
if (!res.ok)
|
|
239
|
+
throw new Error(`Ollama responded with status ${res.status}`);
|
|
240
|
+
const data = await res.json();
|
|
241
|
+
const models = data?.models || [];
|
|
242
|
+
if (isOllamaModelAvailable(models, model)) {
|
|
243
|
+
checks.push({ category: 'Local AI Agent', name: provider, status: 'pass', message: `Ollama active and model "${model}" is ready` });
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
const availableList = models.map((m) => m.name).join(', ') || 'none';
|
|
247
|
+
warnings.push(`Local model "${model}" is not pulled in Ollama. Available: [${availableList}]. Run "ollama pull ${model}" to install it.`);
|
|
248
|
+
checks.push({ category: 'Local AI Agent', name: provider, status: 'warn', message: `Ollama active, but model "${model}" is not pulled` });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
const testUrl = getOpenAiCompatibleUrl(cleanEndpoint, '/v1/models');
|
|
253
|
+
const res = await fetch(testUrl, { signal: controller.signal });
|
|
254
|
+
if (!res.ok)
|
|
255
|
+
throw new Error(`OpenAI-compatible server responded with status ${res.status}`);
|
|
256
|
+
checks.push({ category: 'Local AI Agent', name: provider, status: 'pass', message: `OpenAI-compatible server at "${endpoint}" is active` });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
260
|
+
throw new Error(e.name === 'AbortError' ? 'Request timed out after 5 seconds' : e.message);
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
clearTimeout(timeout);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (e) {
|
|
267
|
+
warnings.push(`Local LLM server at "${endpoint}" is offline or unreachable: ${e.message}`);
|
|
268
|
+
checks.push({ category: 'Local AI Agent', name: 'connection', status: 'warn', message: `Local LLM server is offline or unreachable (${e.message})` });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
checks.push({ category: 'Local AI Agent', name: 'status', status: 'info', message: 'Local AI agent is disabled in config.' });
|
|
273
|
+
}
|
|
274
|
+
return report();
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/core/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/finish
|
|
3
|
+
* Headless "finish a feature" engine shared by the CLI `finish` command and the
|
|
4
|
+
* MCP `finish_workspace` tool. Commits remaining changes, pushes branches, and
|
|
5
|
+
* surfaces a way to open a PR for each repo (via `gh` when available, otherwise
|
|
6
|
+
* a compare URL). It never promotes knowledge or deletes anything — those are
|
|
7
|
+
* interactive concerns owned by the command.
|
|
8
|
+
*/
|
|
9
|
+
import { type WorkspaceStatusReport } from './status.js';
|
|
10
|
+
/** Options for {@link finishWorkspace}. */
|
|
11
|
+
export interface FinishOptions {
|
|
12
|
+
/** Commit message for any remaining dirty changes. */
|
|
13
|
+
message?: string;
|
|
14
|
+
/** Do not push after committing. */
|
|
15
|
+
skipPush?: boolean;
|
|
16
|
+
/** Attempt `gh pr create` when the GitHub CLI is installed and authenticated. */
|
|
17
|
+
createPrs?: boolean;
|
|
18
|
+
prTitle?: string;
|
|
19
|
+
prBody?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Per-repo finish outcome. */
|
|
22
|
+
export interface RepoFinishReport {
|
|
23
|
+
name: string;
|
|
24
|
+
committed: boolean;
|
|
25
|
+
commitHash?: string;
|
|
26
|
+
pushed: boolean;
|
|
27
|
+
/** PR URL created via `gh`, when available. */
|
|
28
|
+
prUrl?: string;
|
|
29
|
+
/** Compare/create-PR URL to open in a browser (fallback and default path). */
|
|
30
|
+
compareUrl?: string;
|
|
31
|
+
/** Set when the repo was intentionally skipped (wrong branch, no remote, …). */
|
|
32
|
+
skipped?: string;
|
|
33
|
+
/** Set when an operation failed for this repo. */
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
/** Aggregate finish report. */
|
|
37
|
+
export interface FinishReport {
|
|
38
|
+
workspacePath: string;
|
|
39
|
+
branchName: string;
|
|
40
|
+
preflight: WorkspaceStatusReport;
|
|
41
|
+
repos: RepoFinishReport[];
|
|
42
|
+
/** True when `gh` was used to create PRs. */
|
|
43
|
+
ghUsed: boolean;
|
|
44
|
+
/** True when, after finishing, every repo is clean and pushed. */
|
|
45
|
+
safeToCleanup: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Runs the finish sequence: preflight → commit dirty repos → push → PR links →
|
|
49
|
+
* recheck. Repos on the wrong branch or in a detached-HEAD state are skipped
|
|
50
|
+
* (never committed) so a stray checkout can't push to the wrong branch.
|
|
51
|
+
*
|
|
52
|
+
* @param workspacePath - Absolute path to the workspace directory.
|
|
53
|
+
* @param options - Finish options.
|
|
54
|
+
*/
|
|
55
|
+
export declare function finishWorkspace(workspacePath: string, options?: FinishOptions): Promise<FinishReport>;
|
|
56
|
+
//# sourceMappingURL=finish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finish.d.ts","sourceRoot":"","sources":["../../src/core/finish.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAA4B,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAKnF,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,+BAA+B;AAC/B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,+BAA+B;AAC/B,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,qBAAqB,CAAC;IACjC,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAmGvB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/finish
|
|
3
|
+
* Headless "finish a feature" engine shared by the CLI `finish` command and the
|
|
4
|
+
* MCP `finish_workspace` tool. Commits remaining changes, pushes branches, and
|
|
5
|
+
* surfaces a way to open a PR for each repo (via `gh` when available, otherwise
|
|
6
|
+
* a compare URL). It never promotes knowledge or deletes anything — those are
|
|
7
|
+
* interactive concerns owned by the command.
|
|
8
|
+
*/
|
|
9
|
+
import { getWorkspaceStatusReport } from './status.js';
|
|
10
|
+
import { commitWorkspace } from './commit.js';
|
|
11
|
+
import { pushRepo } from '../utils/multi-git.js';
|
|
12
|
+
import { detectGh, createPrWithGh, parseRemoteUrl, buildCompareUrl } from '../utils/pr.js';
|
|
13
|
+
/**
|
|
14
|
+
* Runs the finish sequence: preflight → commit dirty repos → push → PR links →
|
|
15
|
+
* recheck. Repos on the wrong branch or in a detached-HEAD state are skipped
|
|
16
|
+
* (never committed) so a stray checkout can't push to the wrong branch.
|
|
17
|
+
*
|
|
18
|
+
* @param workspacePath - Absolute path to the workspace directory.
|
|
19
|
+
* @param options - Finish options.
|
|
20
|
+
*/
|
|
21
|
+
export async function finishWorkspace(workspacePath, options = {}) {
|
|
22
|
+
const preflight = await getWorkspaceStatusReport(workspacePath);
|
|
23
|
+
const reports = new Map();
|
|
24
|
+
for (const repo of preflight.repos) {
|
|
25
|
+
reports.set(repo.name, { name: repo.name, committed: false, pushed: false });
|
|
26
|
+
}
|
|
27
|
+
// Repos we are allowed to act on: on the expected branch, not detached.
|
|
28
|
+
const actionable = preflight.repos.filter((r) => r.onExpectedBranch && r.branch);
|
|
29
|
+
for (const repo of preflight.repos) {
|
|
30
|
+
if (!r_isActionable(repo.name, actionable)) {
|
|
31
|
+
const rep = reports.get(repo.name);
|
|
32
|
+
rep.skipped = repo.branch
|
|
33
|
+
? `on branch "${repo.branch}", not the feature branch "${repo.expectedBranch}"`
|
|
34
|
+
: 'detached HEAD';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// ── Commit dirty, actionable repos ──────────────────────────────────────
|
|
38
|
+
const dirtyActionable = actionable.filter((r) => r.dirty);
|
|
39
|
+
if (dirtyActionable.length > 0) {
|
|
40
|
+
if (!options.message || !options.message.trim()) {
|
|
41
|
+
for (const r of dirtyActionable) {
|
|
42
|
+
reports.get(r.name).error = 'uncommitted changes and no commit message provided';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const commitReport = await commitWorkspace(workspacePath, options.message, {
|
|
47
|
+
noPush: true, // push is handled uniformly below
|
|
48
|
+
repos: dirtyActionable.map((r) => r.name),
|
|
49
|
+
});
|
|
50
|
+
for (const c of commitReport.repos) {
|
|
51
|
+
const rep = reports.get(c.name);
|
|
52
|
+
rep.committed = c.success;
|
|
53
|
+
rep.commitHash = c.commitHash || undefined;
|
|
54
|
+
if (!c.success)
|
|
55
|
+
rep.error = c.message;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ── Push actionable repos with a remote ─────────────────────────────────
|
|
60
|
+
for (const repo of actionable) {
|
|
61
|
+
const rep = reports.get(repo.name);
|
|
62
|
+
if (rep.error)
|
|
63
|
+
continue;
|
|
64
|
+
if (!repo.remoteUrl) {
|
|
65
|
+
rep.skipped = rep.skipped ?? 'no remote configured';
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (options.skipPush)
|
|
69
|
+
continue;
|
|
70
|
+
// Push when we committed, when the branch is ahead, or when it was never pushed.
|
|
71
|
+
const needsPush = rep.committed || repo.ahead === null || (repo.ahead ?? 0) > 0;
|
|
72
|
+
if (needsPush) {
|
|
73
|
+
const result = await pushRepo(repo.path, repo.expectedBranch);
|
|
74
|
+
rep.pushed = result.success;
|
|
75
|
+
if (!result.success)
|
|
76
|
+
rep.error = result.message;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// ── PR links ────────────────────────────────────────────────────────────
|
|
80
|
+
const gh = options.createPrs ? await detectGh() : { installed: false, authenticated: false };
|
|
81
|
+
const ghUsed = Boolean(options.createPrs && gh.installed && gh.authenticated);
|
|
82
|
+
for (const repo of actionable) {
|
|
83
|
+
const rep = reports.get(repo.name);
|
|
84
|
+
if (!repo.remoteUrl || rep.error)
|
|
85
|
+
continue;
|
|
86
|
+
const remote = parseRemoteUrl(repo.remoteUrl);
|
|
87
|
+
if (remote) {
|
|
88
|
+
rep.compareUrl = buildCompareUrl(remote, repo.defaultBranch, repo.expectedBranch) ?? undefined;
|
|
89
|
+
}
|
|
90
|
+
if (ghUsed && rep.pushed) {
|
|
91
|
+
const title = options.prTitle?.trim() || repo.expectedBranch;
|
|
92
|
+
const body = options.prBody ?? '';
|
|
93
|
+
const pr = await createPrWithGh(repo.path, {
|
|
94
|
+
base: repo.defaultBranch,
|
|
95
|
+
head: repo.expectedBranch,
|
|
96
|
+
title,
|
|
97
|
+
body,
|
|
98
|
+
});
|
|
99
|
+
if (pr.url) {
|
|
100
|
+
rep.prUrl = pr.url;
|
|
101
|
+
}
|
|
102
|
+
// On gh failure we silently keep compareUrl (already populated above).
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// ── Recheck to decide whether cleanup is safe ───────────────────────────
|
|
106
|
+
const after = await getWorkspaceStatusReport(workspacePath);
|
|
107
|
+
const safeToCleanup = after.allClean && after.allPushed;
|
|
108
|
+
return {
|
|
109
|
+
workspacePath,
|
|
110
|
+
branchName: preflight.branchName,
|
|
111
|
+
preflight,
|
|
112
|
+
repos: preflight.repos.map((r) => reports.get(r.name)),
|
|
113
|
+
ghUsed,
|
|
114
|
+
safeToCleanup,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/** Whether a repo name is in the actionable set. */
|
|
118
|
+
function r_isActionable(name, actionable) {
|
|
119
|
+
return actionable.some((r) => r.name === name);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=finish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finish.js","sourceRoot":"","sources":["../../src/core/finish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finish.test.d.ts","sourceRoot":"","sources":["../../src/core/finish.test.ts"],"names":[],"mappings":""}
|