@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
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @module utils/pr
3
+ * Pull-request helpers: detect the GitHub CLI, parse a git remote URL into its
4
+ * host/owner/repo, and construct a "create PR / MR" compare URL for the common
5
+ * forges. Pure functions (`parseRemoteUrl`, `buildCompareUrl`) are unit-tested;
6
+ * `detectGh`/`createPrWithGh` shell out to `gh`.
7
+ */
8
+ import { execa } from 'execa';
9
+ /** Determines the forge kind from a hostname. */
10
+ function forgeKind(host) {
11
+ const h = host.toLowerCase();
12
+ if (h.includes('github'))
13
+ return 'github';
14
+ if (h.includes('gitlab'))
15
+ return 'gitlab';
16
+ if (h.includes('dev.azure.com') || h.includes('visualstudio.com') || h.includes('azure'))
17
+ return 'azure';
18
+ if (h.includes('bitbucket'))
19
+ return 'bitbucket';
20
+ return 'unknown';
21
+ }
22
+ function stripGitSuffix(s) {
23
+ return s.replace(/\.git$/, '');
24
+ }
25
+ /**
26
+ * Parses a git remote URL (https, ssh://, scp-style `git@host:path`, and Azure
27
+ * DevOps variants) into structured parts, or `null` when it cannot be parsed.
28
+ */
29
+ export function parseRemoteUrl(url) {
30
+ if (!url)
31
+ return null;
32
+ const raw = url.trim();
33
+ // Azure DevOps SSH: git@ssh.dev.azure.com:v3/{org}/{project}/{repo}
34
+ // or: {org}@vs-ssh.visualstudio.com:v3/{org}/{project}/{repo}
35
+ const azureSsh = raw.match(/@(?:ssh\.dev\.azure\.com|[^:@]*vs-ssh\.visualstudio\.com):v3\/([^/]+)\/([^/]+)\/([^/]+)/i);
36
+ if (azureSsh) {
37
+ return {
38
+ host: 'dev.azure.com',
39
+ owner: azureSsh[1],
40
+ project: azureSsh[2],
41
+ repo: stripGitSuffix(azureSsh[3]),
42
+ kind: 'azure',
43
+ };
44
+ }
45
+ // Normalize into a URL we can parse with the WHATWG URL class.
46
+ let normalized = raw;
47
+ const scp = raw.match(/^([^@]+)@([^:]+):(.+)$/); // git@host:owner/repo(.git)
48
+ if (scp && !raw.includes('://')) {
49
+ normalized = `ssh://${scp[1]}@${scp[2]}/${scp[3]}`;
50
+ }
51
+ let parsed;
52
+ try {
53
+ parsed = new URL(normalized);
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ const host = parsed.hostname;
59
+ const kind = forgeKind(host);
60
+ const segments = parsed.pathname.split('/').filter(Boolean).map((s) => decodeURIComponent(s));
61
+ if (segments.length < 2)
62
+ return null;
63
+ // Azure HTTPS: /{org}/{project}/_git/{repo} (org may be a leading path segment)
64
+ const gitIdx = segments.indexOf('_git');
65
+ if (kind === 'azure' && gitIdx >= 1) {
66
+ const repo = segments[gitIdx + 1];
67
+ const project = segments[gitIdx - 1];
68
+ // The org is whatever precedes the project (Azure hosts it at /{org}/...).
69
+ const org = segments.slice(0, gitIdx - 1).join('/') || project;
70
+ if (repo) {
71
+ return { host: 'dev.azure.com', owner: org, project, repo: stripGitSuffix(repo), kind: 'azure' };
72
+ }
73
+ }
74
+ // Generic: owner(/subgroups)/repo — repo is the last segment.
75
+ const repo = stripGitSuffix(segments[segments.length - 1]);
76
+ const owner = segments.slice(0, segments.length - 1).join('/');
77
+ if (!owner || !repo)
78
+ return null;
79
+ return { host, owner, repo, kind };
80
+ }
81
+ /**
82
+ * Builds a "create a PR/MR" URL for a base←head comparison, or `null` for an
83
+ * unknown forge (the caller should then print the remote URL + branch instead).
84
+ */
85
+ export function buildCompareUrl(remote, baseBranch, headBranch) {
86
+ const enc = encodeURIComponent;
87
+ switch (remote.kind) {
88
+ case 'github':
89
+ // GitHub accepts raw slashes in the compare segment (feature/x is fine).
90
+ return `https://${remote.host}/${remote.owner}/${remote.repo}/compare/${baseBranch}...${headBranch}?expand=1`;
91
+ case 'gitlab':
92
+ return (`https://${remote.host}/${remote.owner}/${remote.repo}/-/merge_requests/new` +
93
+ `?merge_request%5Bsource_branch%5D=${enc(headBranch)}` +
94
+ `&merge_request%5Btarget_branch%5D=${enc(baseBranch)}`);
95
+ case 'azure':
96
+ return (`https://dev.azure.com/${remote.owner}/${remote.project ?? ''}/_git/${remote.repo}/pullrequestcreate` +
97
+ `?sourceRef=${enc(headBranch)}&targetRef=${enc(baseBranch)}`);
98
+ case 'bitbucket':
99
+ return `https://${remote.host}/${remote.owner}/${remote.repo}/pull-requests/new?source=${enc(headBranch)}&dest=${enc(baseBranch)}`;
100
+ default:
101
+ return null;
102
+ }
103
+ }
104
+ /** Detects whether the GitHub CLI is installed and authenticated. */
105
+ export async function detectGh() {
106
+ let installed = false;
107
+ try {
108
+ const v = await execa('gh', ['--version'], { reject: false });
109
+ installed = v.exitCode === 0;
110
+ }
111
+ catch {
112
+ installed = false;
113
+ }
114
+ if (!installed)
115
+ return { installed: false, authenticated: false };
116
+ let authenticated = false;
117
+ try {
118
+ const a = await execa('gh', ['auth', 'status'], { reject: false });
119
+ authenticated = a.exitCode === 0;
120
+ }
121
+ catch {
122
+ authenticated = false;
123
+ }
124
+ return { installed, authenticated };
125
+ }
126
+ /**
127
+ * Creates a PR with the GitHub CLI. Never throws — returns `{ url }` on success
128
+ * or `{ url: null, error }` so the caller can fall back to a compare URL.
129
+ */
130
+ export async function createPrWithGh(repoPath, opts) {
131
+ try {
132
+ const result = await execa('gh', ['pr', 'create', '--base', opts.base, '--head', opts.head, '--title', opts.title, '--body', opts.body], { cwd: repoPath, reject: false });
133
+ if (result.exitCode === 0) {
134
+ const lines = result.stdout.split('\n').map((l) => l.trim()).filter(Boolean);
135
+ const url = lines.reverse().find((l) => l.startsWith('http')) ?? null;
136
+ return { url };
137
+ }
138
+ return { url: null, error: (result.stderr || result.stdout || 'gh pr create failed').split('\n')[0] };
139
+ }
140
+ catch (error) {
141
+ return { url: null, error: error instanceof Error ? error.message : String(error) };
142
+ }
143
+ }
144
+ //# sourceMappingURL=pr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.js","sourceRoot":"","sources":["../../src/utils/pr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pr.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.test.d.ts","sourceRoot":"","sources":["../../src/utils/pr.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,47 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseRemoteUrl, buildCompareUrl } from './pr.js';
3
+ describe('parseRemoteUrl', () => {
4
+ const cases = [
5
+ ['https://github.com/owner/repo.git', { host: 'github.com', owner: 'owner', repo: 'repo', kind: 'github' }],
6
+ ['https://github.com/owner/repo', { host: 'github.com', owner: 'owner', repo: 'repo', kind: 'github' }],
7
+ ['git@github.com:owner/repo.git', { host: 'github.com', owner: 'owner', repo: 'repo', kind: 'github' }],
8
+ ['ssh://git@github.com/owner/repo.git', { host: 'github.com', owner: 'owner', repo: 'repo', kind: 'github' }],
9
+ ['https://gitlab.com/group/subgroup/repo.git', { host: 'gitlab.com', owner: 'group/subgroup', repo: 'repo', kind: 'gitlab' }],
10
+ ['git@bitbucket.org:team/repo.git', { host: 'bitbucket.org', owner: 'team', repo: 'repo', kind: 'bitbucket' }],
11
+ ['https://dev.azure.com/myorg/myproject/_git/myrepo', { host: 'dev.azure.com', owner: 'myorg', project: 'myproject', repo: 'myrepo', kind: 'azure' }],
12
+ ['git@ssh.dev.azure.com:v3/myorg/myproject/myrepo', { host: 'dev.azure.com', owner: 'myorg', project: 'myproject', repo: 'myrepo', kind: 'azure' }],
13
+ ];
14
+ it.each(cases)('parses %s', (url, expected) => {
15
+ expect(parseRemoteUrl(url)).toMatchObject(expected);
16
+ });
17
+ it('returns null for junk', () => {
18
+ expect(parseRemoteUrl('not a url')).toBeNull();
19
+ expect(parseRemoteUrl('')).toBeNull();
20
+ });
21
+ it('classifies an unknown self-hosted host', () => {
22
+ const r = parseRemoteUrl('https://git.internal.corp/team/repo.git');
23
+ expect(r).toMatchObject({ host: 'git.internal.corp', owner: 'team', repo: 'repo', kind: 'unknown' });
24
+ });
25
+ });
26
+ describe('buildCompareUrl', () => {
27
+ it('builds a GitHub compare URL preserving slashes in branch names', () => {
28
+ const r = parseRemoteUrl('https://github.com/owner/repo.git');
29
+ expect(buildCompareUrl(r, 'main', 'feature/x')).toBe('https://github.com/owner/repo/compare/main...feature/x?expand=1');
30
+ });
31
+ it('builds a GitLab MR URL with encoded branch params', () => {
32
+ const r = parseRemoteUrl('https://gitlab.com/group/sub/repo.git');
33
+ const url = buildCompareUrl(r, 'main', 'feature/x');
34
+ expect(url).toContain('/group/sub/repo/-/merge_requests/new');
35
+ expect(url).toContain('source_branch%5D=feature%2Fx');
36
+ expect(url).toContain('target_branch%5D=main');
37
+ });
38
+ it('builds an Azure DevOps PR-create URL', () => {
39
+ const r = parseRemoteUrl('https://dev.azure.com/myorg/myproject/_git/myrepo');
40
+ expect(buildCompareUrl(r, 'main', 'feature/x')).toBe('https://dev.azure.com/myorg/myproject/_git/myrepo/pullrequestcreate?sourceRef=feature%2Fx&targetRef=main');
41
+ });
42
+ it('returns null for an unknown forge', () => {
43
+ const r = parseRemoteUrl('https://git.internal.corp/team/repo.git');
44
+ expect(buildCompareUrl(r, 'main', 'feature/x')).toBeNull();
45
+ });
46
+ });
47
+ //# sourceMappingURL=pr.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr.test.js","sourceRoot":"","sources":["../../src/utils/pr.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @module utils/resolve-workspace
3
+ * Shared workspace-path resolution used by commands. Replaces the near-identical
4
+ * private `resolveWorkspace` helpers previously copied across commit/diff/finish
5
+ * and other commands.
6
+ */
7
+ /**
8
+ * Resolves a workspace path without any interactive prompts.
9
+ *
10
+ * Resolution order: explicit argument → workspace detected from the current
11
+ * working directory → `null`.
12
+ *
13
+ * @param workspaceArg - Optional explicit workspace path.
14
+ * @returns Absolute workspace path, or `null` when none can be determined.
15
+ * @throws If an explicit `workspaceArg` is given but has no `nexusflow.json`.
16
+ */
17
+ export declare function resolveWorkspaceQuiet(workspaceArg?: string): Promise<string | null>;
18
+ /**
19
+ * Resolves a workspace path, falling back to an interactive picker when it
20
+ * cannot be determined from the argument or the current directory.
21
+ *
22
+ * Prints friendly errors (and returns `null`) rather than throwing, so callers
23
+ * can simply `return` when the result is `null`.
24
+ *
25
+ * @param workspaceArg - Optional explicit workspace path.
26
+ * @param promptMessage - Prompt shown when picking from the workspace list.
27
+ * @returns Absolute workspace path, or `null` when unavailable/none selected.
28
+ */
29
+ export declare function resolveWorkspaceInteractive(workspaceArg: string | undefined, promptMessage: string): Promise<string | null>;
30
+ //# sourceMappingURL=resolve-workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-workspace.d.ts","sourceRoot":"","sources":["../../src/utils/resolve-workspace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBzF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA4BxB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @module utils/resolve-workspace
3
+ * Shared workspace-path resolution used by commands. Replaces the near-identical
4
+ * private `resolveWorkspace` helpers previously copied across commit/diff/finish
5
+ * and other commands.
6
+ */
7
+ import chalk from 'chalk';
8
+ import { select } from '@inquirer/prompts';
9
+ import * as path from 'node:path';
10
+ import * as fs from 'node:fs/promises';
11
+ import { loadConfig } from '../core/config.js';
12
+ import { listWorkspaces, loadFeatureConfig } from '../core/workspace.js';
13
+ /**
14
+ * Resolves a workspace path without any interactive prompts.
15
+ *
16
+ * Resolution order: explicit argument → workspace detected from the current
17
+ * working directory → `null`.
18
+ *
19
+ * @param workspaceArg - Optional explicit workspace path.
20
+ * @returns Absolute workspace path, or `null` when none can be determined.
21
+ * @throws If an explicit `workspaceArg` is given but has no `nexusflow.json`.
22
+ */
23
+ export async function resolveWorkspaceQuiet(workspaceArg) {
24
+ if (workspaceArg) {
25
+ const absolutePath = path.resolve(workspaceArg);
26
+ try {
27
+ await fs.access(path.join(absolutePath, 'nexusflow.json'));
28
+ return absolutePath;
29
+ }
30
+ catch {
31
+ throw new Error(`Invalid workspace: No nexusflow.json found at ${absolutePath}`);
32
+ }
33
+ }
34
+ const cwdFeature = await loadFeatureConfig(process.cwd());
35
+ if (cwdFeature) {
36
+ return cwdFeature.workspacePath;
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Resolves a workspace path, falling back to an interactive picker when it
42
+ * cannot be determined from the argument or the current directory.
43
+ *
44
+ * Prints friendly errors (and returns `null`) rather than throwing, so callers
45
+ * can simply `return` when the result is `null`.
46
+ *
47
+ * @param workspaceArg - Optional explicit workspace path.
48
+ * @param promptMessage - Prompt shown when picking from the workspace list.
49
+ * @returns Absolute workspace path, or `null` when unavailable/none selected.
50
+ */
51
+ export async function resolveWorkspaceInteractive(workspaceArg, promptMessage) {
52
+ try {
53
+ const quiet = await resolveWorkspaceQuiet(workspaceArg);
54
+ if (quiet) {
55
+ return quiet;
56
+ }
57
+ }
58
+ catch (error) {
59
+ console.error(chalk.red(`✖ ${error instanceof Error ? error.message : String(error)}`));
60
+ return null;
61
+ }
62
+ const config = await loadConfig();
63
+ const workspaces = await listWorkspaces(config.workspacesDir);
64
+ if (workspaces.length === 0) {
65
+ console.log(chalk.yellow('No workspaces found.\n'));
66
+ return null;
67
+ }
68
+ const selected = await select({
69
+ message: promptMessage,
70
+ choices: workspaces.map((ws) => ({
71
+ name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
72
+ value: ws.workspacePath,
73
+ })),
74
+ });
75
+ return selected;
76
+ }
77
+ //# sourceMappingURL=resolve-workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-workspace.js","sourceRoot":"","sources":["../../src/utils/resolve-workspace.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAqB;IAC/D,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;YAC3D,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,iDAAiD,YAAY,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1D,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,aAAa,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,YAAgC,EAChC,aAAqB;IAErB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,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,aAAa;QACtB,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrpatronz/nexusflow",
3
- "version": "1.3.2",
3
+ "version": "1.5.0",
4
4
  "description": "Combine multiple repos into a workspace with rich AI assistant context",
5
5
  "type": "module",
6
6
  "repository": {
@@ -45,23 +45,23 @@
45
45
  "author": "",
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
- "@hono/node-server": "^2.0.4",
48
+ "@hono/node-server": "^2.0.8",
49
49
  "@inquirer/prompts": "^8.5.2",
50
50
  "@modelcontextprotocol/sdk": "^1.29.0",
51
- "chalk": "^5.3.0",
51
+ "chalk": "^5.6.2",
52
52
  "commander": "^15.0.0",
53
- "execa": "^9.5.0",
54
- "fs-extra": "^11.2.0",
53
+ "execa": "^9.6.1",
54
+ "fs-extra": "^11.3.6",
55
55
  "globby": "^16.2.0",
56
- "hono": "^4.12.25",
57
- "ora": "^9.4.0",
58
- "pm2": "^7.0.1"
56
+ "hono": "^4.12.27",
57
+ "ora": "^9.4.1",
58
+ "pm2": "^7.0.3"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@types/fs-extra": "^11.0.4",
62
- "@types/node": "^25.9.3",
63
- "rimraf": "^6.0.0",
62
+ "@types/node": "^26.1.0",
63
+ "rimraf": "^6.1.3",
64
64
  "typescript": "^6.0.3",
65
- "vitest": "^4.1.8"
65
+ "vitest": "^4.1.9"
66
66
  }
67
67
  }