@mrpatronz/nexusflow 1.3.2 → 1.5.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.
Files changed (143) hide show
  1. package/README.md +50 -0
  2. package/dist/commands/create.d.ts.map +1 -1
  3. package/dist/commands/create.js +54 -37
  4. package/dist/commands/create.js.map +1 -1
  5. package/dist/commands/diff.d.ts.map +1 -1
  6. package/dist/commands/diff.js +16 -73
  7. package/dist/commands/diff.js.map +1 -1
  8. package/dist/commands/doctor.d.ts +4 -0
  9. package/dist/commands/doctor.d.ts.map +1 -1
  10. package/dist/commands/doctor.js +58 -318
  11. package/dist/commands/doctor.js.map +1 -1
  12. package/dist/commands/finish.d.ts +17 -0
  13. package/dist/commands/finish.d.ts.map +1 -0
  14. package/dist/commands/finish.js +172 -0
  15. package/dist/commands/finish.js.map +1 -0
  16. package/dist/commands/handoff.d.ts.map +1 -1
  17. package/dist/commands/handoff.js +11 -6
  18. package/dist/commands/handoff.js.map +1 -1
  19. package/dist/commands/knowledge.d.ts +36 -0
  20. package/dist/commands/knowledge.d.ts.map +1 -0
  21. package/dist/commands/knowledge.js +184 -0
  22. package/dist/commands/knowledge.js.map +1 -0
  23. package/dist/commands/open.d.ts.map +1 -1
  24. package/dist/commands/open.js +2 -4
  25. package/dist/commands/open.js.map +1 -1
  26. package/dist/core/commit.d.ts +41 -0
  27. package/dist/core/commit.d.ts.map +1 -0
  28. package/dist/core/commit.js +53 -0
  29. package/dist/core/commit.js.map +1 -0
  30. package/dist/core/config.d.ts +3 -1
  31. package/dist/core/config.d.ts.map +1 -1
  32. package/dist/core/config.js +60 -32
  33. package/dist/core/config.js.map +1 -1
  34. package/dist/core/config.test.js +24 -0
  35. package/dist/core/config.test.js.map +1 -1
  36. package/dist/core/diff.d.ts +27 -0
  37. package/dist/core/diff.d.ts.map +1 -0
  38. package/dist/core/diff.js +50 -0
  39. package/dist/core/diff.js.map +1 -0
  40. package/dist/core/doctor.d.ts +34 -0
  41. package/dist/core/doctor.d.ts.map +1 -0
  42. package/dist/core/doctor.js +276 -0
  43. package/dist/core/doctor.js.map +1 -0
  44. package/dist/core/finish.d.ts +56 -0
  45. package/dist/core/finish.d.ts.map +1 -0
  46. package/dist/core/finish.js +121 -0
  47. package/dist/core/finish.js.map +1 -0
  48. package/dist/core/finish.test.d.ts +2 -0
  49. package/dist/core/finish.test.d.ts.map +1 -0
  50. package/dist/core/finish.test.js +110 -0
  51. package/dist/core/finish.test.js.map +1 -0
  52. package/dist/core/knowledge.d.ts +96 -0
  53. package/dist/core/knowledge.d.ts.map +1 -0
  54. package/dist/core/knowledge.js +299 -0
  55. package/dist/core/knowledge.js.map +1 -0
  56. package/dist/core/knowledge.test.d.ts +2 -0
  57. package/dist/core/knowledge.test.d.ts.map +1 -0
  58. package/dist/core/knowledge.test.js +157 -0
  59. package/dist/core/knowledge.test.js.map +1 -0
  60. package/dist/core/refresh.test.d.ts +2 -0
  61. package/dist/core/refresh.test.d.ts.map +1 -0
  62. package/dist/core/refresh.test.js +67 -0
  63. package/dist/core/refresh.test.js.map +1 -0
  64. package/dist/core/status.d.ts +45 -0
  65. package/dist/core/status.d.ts.map +1 -0
  66. package/dist/core/status.js +45 -0
  67. package/dist/core/status.js.map +1 -0
  68. package/dist/core/sync.test.d.ts +2 -0
  69. package/dist/core/sync.test.d.ts.map +1 -0
  70. package/dist/core/sync.test.js +86 -0
  71. package/dist/core/sync.test.js.map +1 -0
  72. package/dist/core/workspace.create.test.d.ts +2 -0
  73. package/dist/core/workspace.create.test.d.ts.map +1 -0
  74. package/dist/core/workspace.create.test.js +95 -0
  75. package/dist/core/workspace.create.test.js.map +1 -0
  76. package/dist/core/workspace.d.ts +9 -3
  77. package/dist/core/workspace.d.ts.map +1 -1
  78. package/dist/core/workspace.js +91 -13
  79. package/dist/core/workspace.js.map +1 -1
  80. package/dist/core/worktree.d.ts +11 -1
  81. package/dist/core/worktree.d.ts.map +1 -1
  82. package/dist/core/worktree.js +2 -0
  83. package/dist/core/worktree.js.map +1 -1
  84. package/dist/core/worktree.test.d.ts +2 -0
  85. package/dist/core/worktree.test.d.ts.map +1 -0
  86. package/dist/core/worktree.test.js +111 -0
  87. package/dist/core/worktree.test.js.map +1 -0
  88. package/dist/generators/base.js +1 -1
  89. package/dist/generators/index.d.ts +7 -0
  90. package/dist/generators/index.d.ts.map +1 -1
  91. package/dist/generators/index.js +4 -1
  92. package/dist/generators/index.js.map +1 -1
  93. package/dist/index.js +110 -3
  94. package/dist/index.js.map +1 -1
  95. package/dist/mcp/server.d.ts.map +1 -1
  96. package/dist/mcp/server.js +51 -282
  97. package/dist/mcp/server.js.map +1 -1
  98. package/dist/mcp/tools.d.ts +45 -0
  99. package/dist/mcp/tools.d.ts.map +1 -0
  100. package/dist/mcp/tools.js +413 -0
  101. package/dist/mcp/tools.js.map +1 -0
  102. package/dist/server.d.ts.map +1 -1
  103. package/dist/server.js +43 -26
  104. package/dist/server.js.map +1 -1
  105. package/dist/utils/debug.d.ts +17 -0
  106. package/dist/utils/debug.d.ts.map +1 -0
  107. package/dist/utils/debug.js +25 -0
  108. package/dist/utils/debug.js.map +1 -0
  109. package/dist/utils/detect-ai.d.ts +14 -6
  110. package/dist/utils/detect-ai.d.ts.map +1 -1
  111. package/dist/utils/detect-ai.js +22 -9
  112. package/dist/utils/detect-ai.js.map +1 -1
  113. package/dist/utils/detect-ai.test.js +33 -0
  114. package/dist/utils/detect-ai.test.js.map +1 -1
  115. package/dist/utils/git.d.ts +13 -2
  116. package/dist/utils/git.d.ts.map +1 -1
  117. package/dist/utils/git.js +64 -5
  118. package/dist/utils/git.js.map +1 -1
  119. package/dist/utils/git.test.js +46 -8
  120. package/dist/utils/git.test.js.map +1 -1
  121. package/dist/utils/multi-git.d.ts +40 -0
  122. package/dist/utils/multi-git.d.ts.map +1 -1
  123. package/dist/utils/multi-git.js +80 -0
  124. package/dist/utils/multi-git.js.map +1 -1
  125. package/dist/utils/multi-git.test.js +54 -1
  126. package/dist/utils/multi-git.test.js.map +1 -1
  127. package/dist/utils/open-editor.d.ts +20 -0
  128. package/dist/utils/open-editor.d.ts.map +1 -0
  129. package/dist/utils/open-editor.js +44 -0
  130. package/dist/utils/open-editor.js.map +1 -0
  131. package/dist/utils/pr.d.ts +50 -0
  132. package/dist/utils/pr.d.ts.map +1 -0
  133. package/dist/utils/pr.js +144 -0
  134. package/dist/utils/pr.js.map +1 -0
  135. package/dist/utils/pr.test.d.ts +2 -0
  136. package/dist/utils/pr.test.d.ts.map +1 -0
  137. package/dist/utils/pr.test.js +47 -0
  138. package/dist/utils/pr.test.js.map +1 -0
  139. package/dist/utils/resolve-workspace.d.ts +30 -0
  140. package/dist/utils/resolve-workspace.d.ts.map +1 -0
  141. package/dist/utils/resolve-workspace.js +77 -0
  142. package/dist/utils/resolve-workspace.js.map +1 -0
  143. package/package.json +11 -11
@@ -5,7 +5,40 @@
5
5
  import * as fs from 'node:fs/promises';
6
6
  import * as path from 'node:path';
7
7
  import * as os from 'node:os';
8
+ import chalk from 'chalk';
8
9
  import { getStorageProvider, setActiveStorageProvider } from './adapters/registry.js';
10
+ import { debugLog } from '../utils/debug.js';
11
+ /**
12
+ * Activates the configured storage provider, falling back to local storage on
13
+ * failure. Unless `quiet`, a failure prints a visible warning (a silent
14
+ * fallback from e.g. the Obsidian adapter to local is a nasty surprise). The
15
+ * quiet path exists for bootstrap, where plugin-provided adapters are not yet
16
+ * registered and a warning would be a false alarm.
17
+ */
18
+ function activateStorageProvider(config, quiet) {
19
+ const providerName = config.storageProvider || 'local';
20
+ try {
21
+ const provider = getStorageProvider(providerName);
22
+ const adapterSettings = config.adapterConfig?.[providerName] ?? {};
23
+ if (provider.configure) {
24
+ provider.configure(adapterSettings);
25
+ }
26
+ setActiveStorageProvider(provider);
27
+ }
28
+ catch (error) {
29
+ if (!quiet) {
30
+ console.warn(chalk.yellow(`⚠ Storage adapter "${providerName}" failed to activate — falling back to local storage.`));
31
+ }
32
+ debugLog('storage', `activate "${providerName}"`, error);
33
+ // Deterministic fallback rather than relying on the registry's implicit default.
34
+ try {
35
+ setActiveStorageProvider(getStorageProvider('local'));
36
+ }
37
+ catch (fallbackError) {
38
+ debugLog('storage', 'local fallback failed', fallbackError);
39
+ }
40
+ }
41
+ }
9
42
  /** Name of the config directory under the user's home folder. */
10
43
  const CONFIG_DIR_NAME = '.nexusflow';
11
44
  /** Name of the config file. */
@@ -72,34 +105,38 @@ export async function ensureConfigDir() {
72
105
  *
73
106
  * @returns The loaded or default configuration.
74
107
  */
75
- export async function loadConfig() {
108
+ export async function loadConfig(options = {}) {
76
109
  const configPath = path.join(getConfigDir(), CONFIG_FILE_NAME);
77
- let merged;
110
+ const quiet = options.quiet ?? false;
111
+ let merged = getDefaultConfig();
112
+ let raw = null;
78
113
  try {
79
- const raw = await fs.readFile(configPath, 'utf-8');
80
- const parsed = JSON.parse(raw);
81
- // Merge with defaults so newly-added keys are always present.
82
- merged = { ...getDefaultConfig(), ...parsed };
83
- if (parsed.localLlm) {
84
- merged.localLlm = { ...getDefaultConfig().localLlm, ...parsed.localLlm };
85
- }
114
+ raw = await fs.readFile(configPath, 'utf-8');
86
115
  }
87
116
  catch {
88
- // File doesn't exist or is unreadable — return defaults.
89
- merged = getDefaultConfig();
117
+ // File doesn't exist (first run) or is unreadable — defaults are correct.
118
+ raw = null;
90
119
  }
91
- // Set the active storage provider based on configuration
92
- try {
93
- const providerName = merged.storageProvider || 'local';
94
- const provider = getStorageProvider(providerName);
95
- // Pass per-adapter settings if available
96
- const adapterSettings = merged.adapterConfig?.[providerName] ?? {};
97
- if (provider.configure) {
98
- provider.configure(adapterSettings);
120
+ if (raw !== null) {
121
+ try {
122
+ const parsed = JSON.parse(raw);
123
+ // Merge with defaults so newly-added keys are always present.
124
+ merged = { ...getDefaultConfig(), ...parsed };
125
+ if (parsed.localLlm) {
126
+ merged.localLlm = { ...getDefaultConfig().localLlm, ...parsed.localLlm };
127
+ }
128
+ }
129
+ catch (error) {
130
+ // A corrupted config is worth surfacing — silently reverting devDir /
131
+ // workspacesDir / storageProvider to defaults is a nasty failure mode.
132
+ if (!quiet) {
133
+ console.warn(chalk.yellow('⚠ ~/.nexusflow/config.json is invalid JSON — using defaults for this run.'));
134
+ }
135
+ debugLog('config', 'parse config.json', error);
136
+ merged = getDefaultConfig();
99
137
  }
100
- setActiveStorageProvider(provider);
101
138
  }
102
- catch { }
139
+ activateStorageProvider(merged, quiet);
103
140
  return merged;
104
141
  }
105
142
  /**
@@ -113,16 +150,7 @@ export async function saveConfig(config) {
113
150
  const configPath = path.join(getConfigDir(), CONFIG_FILE_NAME);
114
151
  const data = JSON.stringify(config, null, 2) + '\n';
115
152
  await fs.writeFile(configPath, data, 'utf-8');
116
- // Set the active storage provider based on configuration
117
- try {
118
- const providerName = config.storageProvider || 'local';
119
- const provider = getStorageProvider(providerName);
120
- const adapterSettings = config.adapterConfig?.[providerName] ?? {};
121
- if (provider.configure) {
122
- provider.configure(adapterSettings);
123
- }
124
- setActiveStorageProvider(provider);
125
- }
126
- catch { }
153
+ // Re-activate the storage provider based on the saved configuration.
154
+ activateStorageProvider(config, false);
127
155
  }
128
156
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,30 @@ describe('config core module', () => {
59
59
  expect(config.version).toBe('1.0.0');
60
60
  expect(config.localLlm?.enabled).toBe(false);
61
61
  });
62
+ it('warns and falls back to local on an unknown storage provider', async () => {
63
+ vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify({ storageProvider: 'bogus' }));
64
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => { });
65
+ const config = await loadConfig();
66
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining('bogus'));
67
+ expect(config.storageProvider).toBe('bogus');
68
+ warn.mockRestore();
69
+ });
70
+ it('suppresses the storage-fallback warning when quiet', async () => {
71
+ vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify({ storageProvider: 'bogus' }));
72
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => { });
73
+ await loadConfig({ quiet: true });
74
+ expect(warn).not.toHaveBeenCalled();
75
+ warn.mockRestore();
76
+ });
77
+ it('warns and returns defaults on invalid JSON', async () => {
78
+ vi.mocked(fs.readFile).mockResolvedValue('{ this is not valid json ');
79
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => { });
80
+ const config = await loadConfig();
81
+ expect(warn).toHaveBeenCalledWith(expect.stringContaining('invalid JSON'));
82
+ expect(config.version).toBe('1.0.0');
83
+ expect(config.localLlm?.enabled).toBe(false);
84
+ warn.mockRestore();
85
+ });
62
86
  });
63
87
  describe('saveConfig', () => {
64
88
  it('should create directory and save configuration', async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/core/config.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/core/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @module core/diff
3
+ * Headless cross-repo diff report shared by the CLI `diff` command, the
4
+ * dashboard server, and the MCP `get_workspace_diff` tool. Returns structured
5
+ * data; rendering is the caller's concern.
6
+ */
7
+ /** Diff summary for a single repo that has changes or unpushed commits. */
8
+ export interface RepoDiffReport {
9
+ name: string;
10
+ filesChanged: number;
11
+ additions: number;
12
+ deletions: number;
13
+ /** Commits ahead of origin, or `null` when the branch was never pushed. */
14
+ unpushed: number | null;
15
+ summary: string;
16
+ }
17
+ /**
18
+ * Builds a diff report for every repo in the workspace that has working-tree
19
+ * changes or local commits that have not been pushed.
20
+ *
21
+ * @param workspacePath - Absolute path to the workspace directory.
22
+ * @param repos - Optional repo-name filter.
23
+ * @returns One entry per repo with changes; clean+pushed repos are omitted.
24
+ * @throws If `repos` names a repo not in the workspace.
25
+ */
26
+ export declare function getWorkspaceDiffReport(workspacePath: string, repos?: string[]): Promise<RepoDiffReport[]>;
27
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,cAAc,EAAE,CAAC,CAyC3B"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @module core/diff
3
+ * Headless cross-repo diff report shared by the CLI `diff` command, the
4
+ * dashboard server, and the MCP `get_workspace_diff` tool. Returns structured
5
+ * data; rendering is the caller's concern.
6
+ */
7
+ import { getWorkspaceRepos, getRepoStatus, getDiffSummary, getUnpushedCount, } from '../utils/multi-git.js';
8
+ /**
9
+ * Builds a diff report for every repo in the workspace that has working-tree
10
+ * changes or local commits that have not been pushed.
11
+ *
12
+ * @param workspacePath - Absolute path to the workspace directory.
13
+ * @param repos - Optional repo-name filter.
14
+ * @returns One entry per repo with changes; clean+pushed repos are omitted.
15
+ * @throws If `repos` names a repo not in the workspace.
16
+ */
17
+ export async function getWorkspaceDiffReport(workspacePath, repos) {
18
+ let workspaceRepos = await getWorkspaceRepos(workspacePath);
19
+ if (repos && repos.length > 0) {
20
+ const unknown = repos.filter((name) => !workspaceRepos.some((r) => r.name === name));
21
+ if (unknown.length > 0) {
22
+ throw new Error(`Repositor${unknown.length === 1 ? 'y' : 'ies'} not in this workspace: ${unknown.join(', ')}. ` +
23
+ `Available: ${workspaceRepos.map((r) => r.name).join(', ')}`);
24
+ }
25
+ workspaceRepos = workspaceRepos.filter((r) => repos.includes(r.name));
26
+ }
27
+ const results = [];
28
+ for (const repo of workspaceRepos) {
29
+ const status = await getRepoStatus(repo.path);
30
+ const unpushed = await getUnpushedCount(repo.path, repo.branchName);
31
+ // A repo with no working-tree changes still matters when it has local
32
+ // commits that were never pushed — otherwise "all clean" hides them.
33
+ if (!status.hasChanges && !(unpushed && unpushed > 0)) {
34
+ continue;
35
+ }
36
+ const diff = status.hasChanges
37
+ ? await getDiffSummary(repo.path)
38
+ : { summary: 'No working-tree changes', additions: 0, deletions: 0 };
39
+ results.push({
40
+ name: repo.name,
41
+ filesChanged: status.changedFiles.length,
42
+ additions: diff.additions,
43
+ deletions: diff.deletions,
44
+ unpushed,
45
+ summary: diff.summary,
46
+ });
47
+ }
48
+ return results;
49
+ }
50
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAa/B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,aAAqB,EACrB,KAAgB;IAEhB,IAAI,cAAc,GAAG,MAAM,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAE5D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;QACrF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,YAAY,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,2BAA2B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAC7F,cAAc,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;QACJ,CAAC;QACD,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpE,sEAAsE;QACtE,qEAAqE;QACrE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;YACtD,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU;YAC5B,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;YACjC,CAAC,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QAEvE,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;YACxC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ;YACR,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -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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"}