@mrpatronz/nexusflow 0.2.11 → 0.2.13
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/dist/commands/add-repo.d.ts.map +1 -1
- package/dist/commands/add-repo.js +24 -14
- package/dist/commands/add-repo.js.map +1 -1
- package/dist/commands/commit.js +1 -1
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +9 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/diff.js +1 -1
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/handoff.js +1 -1
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/logs.js +1 -1
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +21 -9
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/pack.js +1 -1
- package/dist/commands/pack.js.map +1 -1
- package/dist/commands/refresh.js +13 -8
- package/dist/commands/refresh.js.map +1 -1
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +12 -7
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/start.js +1 -1
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/stop.js +1 -1
- package/dist/commands/stop.js.map +1 -1
- package/dist/commands/sync.js +13 -8
- package/dist/commands/sync.js.map +1 -1
- package/dist/core/workspace.d.ts +7 -0
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +45 -1
- package/dist/core/workspace.js.map +1 -1
- package/dist/generators/antigravity.d.ts +15 -0
- package/dist/generators/antigravity.d.ts.map +1 -0
- package/dist/generators/antigravity.js +27 -0
- package/dist/generators/antigravity.js.map +1 -0
- package/dist/generators/index.d.ts +1 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +17 -1
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/skills-generator.d.ts.map +1 -1
- package/dist/generators/skills-generator.js +6 -1
- package/dist/generators/skills-generator.js.map +1 -1
- package/dist/gui/assets/index-CFWwqFux.js +23 -0
- package/dist/gui/assets/index-Dvc9QMvl.css +2 -0
- package/dist/gui/index.html +2 -2
- package/dist/orchestration/runner.d.ts +5 -6
- package/dist/orchestration/runner.d.ts.map +1 -1
- package/dist/orchestration/runner.js +105 -102
- package/dist/orchestration/runner.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +57 -2
- package/dist/server.js.map +1 -1
- package/dist/utils/detect-ai.d.ts.map +1 -1
- package/dist/utils/detect-ai.js +4 -1
- package/dist/utils/detect-ai.js.map +1 -1
- package/dist/utils/detect-editors.d.ts.map +1 -1
- package/dist/utils/detect-editors.js +5 -2
- package/dist/utils/detect-editors.js.map +1 -1
- package/dist/utils/detect-editors.test.js +7 -6
- package/dist/utils/detect-editors.test.js.map +1 -1
- package/dist/utils/prompts.d.ts +1 -0
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +77 -15
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/update-check.d.ts.map +1 -1
- package/dist/utils/update-check.js +16 -4
- package/dist/utils/update-check.js.map +1 -1
- package/extension/package.json +9 -0
- package/extension/src/extension.ts +37 -1
- package/gui/eslint.config.js +4 -0
- package/gui/src/App.tsx +375 -151
- package/gui/src/features/changes/ChangesViewer.tsx +246 -70
- package/gui/src/features/services/ServiceConsole.tsx +162 -71
- package/gui/src/features/workspace/WorkspaceList.tsx +184 -32
- package/gui/src/index.css +95 -2
- package/package.json +3 -2
- package/src/commands/add-repo.ts +30 -14
- package/src/commands/commit.ts +1 -1
- package/src/commands/create.ts +9 -2
- package/src/commands/diff.ts +1 -1
- package/src/commands/doctor.ts +1 -1
- package/src/commands/handoff.ts +1 -1
- package/src/commands/logs.ts +1 -1
- package/src/commands/open.ts +24 -9
- package/src/commands/pack.ts +1 -1
- package/src/commands/refresh.ts +16 -8
- package/src/commands/remove.ts +15 -7
- package/src/commands/start.ts +1 -1
- package/src/commands/status.ts +1 -1
- package/src/commands/stop.ts +1 -1
- package/src/commands/sync.ts +16 -8
- package/src/core/workspace.ts +48 -1
- package/src/generators/antigravity.ts +32 -0
- package/src/generators/index.ts +23 -1
- package/src/generators/skills-generator.ts +5 -1
- package/src/orchestration/runner.ts +112 -108
- package/src/server.ts +62 -2
- package/src/utils/detect-ai.ts +4 -1
- package/src/utils/detect-editors.test.ts +7 -6
- package/src/utils/detect-editors.ts +5 -2
- package/src/utils/prompts.ts +88 -14
- package/src/utils/update-check.ts +16 -4
- package/dist/gui/assets/index-Ca2VRMrQ.js +0 -22
- package/dist/gui/assets/index-fj0RJiOb.css +0 -2
package/src/commands/open.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { execa } from 'execa';
|
|
8
|
-
import { select, confirm } from '@inquirer/prompts';
|
|
8
|
+
import { select, confirm, search } from '@inquirer/prompts';
|
|
9
9
|
|
|
10
10
|
import { loadConfig } from '../core/config.js';
|
|
11
11
|
import { listWorkspaces } from '../core/workspace.js';
|
|
@@ -29,12 +29,20 @@ export async function openCommand(): Promise<void> {
|
|
|
29
29
|
console.log(chalk.bold.cyan('\n📂 Open Workspace\n'));
|
|
30
30
|
|
|
31
31
|
// Let user pick a workspace
|
|
32
|
-
const selected = await
|
|
33
|
-
message: '
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
const selected = await search({
|
|
33
|
+
message: 'Search and select a workspace to open:',
|
|
34
|
+
source: async (input) => {
|
|
35
|
+
const query = (input || '').toLowerCase();
|
|
36
|
+
const filtered = workspaces.filter(
|
|
37
|
+
(ws) =>
|
|
38
|
+
ws.branchName.toLowerCase().includes(query) ||
|
|
39
|
+
ws.workspacePath.toLowerCase().includes(query)
|
|
40
|
+
);
|
|
41
|
+
return filtered.map((ws) => ({
|
|
42
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos, ${ws.assistants.join(', ')})`)}`,
|
|
43
|
+
value: ws.workspacePath,
|
|
44
|
+
}));
|
|
45
|
+
},
|
|
38
46
|
});
|
|
39
47
|
|
|
40
48
|
// Let user pick an editor
|
|
@@ -43,7 +51,10 @@ export async function openCommand(): Promise<void> {
|
|
|
43
51
|
|
|
44
52
|
if (editor) {
|
|
45
53
|
try {
|
|
46
|
-
await execa(editor.command, [selected], {
|
|
54
|
+
await execa(editor.command, [selected], {
|
|
55
|
+
stdio: 'ignore',
|
|
56
|
+
shell: process.platform === 'win32',
|
|
57
|
+
});
|
|
47
58
|
console.log(chalk.green(`\n✅ Opened ${selected} in ${editor.name}\n`));
|
|
48
59
|
} catch {
|
|
49
60
|
console.log(chalk.yellow(`\n⚠️ Could not open editor. Navigate manually:`));
|
|
@@ -101,7 +112,11 @@ export async function openCommand(): Promise<void> {
|
|
|
101
112
|
}
|
|
102
113
|
|
|
103
114
|
try {
|
|
104
|
-
await execa(cmdName, cmdArgs, {
|
|
115
|
+
await execa(cmdName, cmdArgs, {
|
|
116
|
+
cwd: selected,
|
|
117
|
+
stdio: 'inherit',
|
|
118
|
+
shell: process.platform === 'win32',
|
|
119
|
+
});
|
|
105
120
|
console.log(chalk.green(`\n👋 Exited ${assistant} session.`));
|
|
106
121
|
} catch {
|
|
107
122
|
const fullCmd = [cmdName, ...cmdArgs].join(' ');
|
package/src/commands/pack.ts
CHANGED
|
@@ -51,7 +51,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
54
|
-
if (cwdFeature) return
|
|
54
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
55
55
|
|
|
56
56
|
const config = await loadConfig();
|
|
57
57
|
const workspaces = await listWorkspaces(config.workspacesDir);
|
package/src/commands/refresh.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { select } from '@inquirer/prompts';
|
|
2
|
+
import { select, search } from '@inquirer/prompts';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import * as fs from 'node:fs/promises';
|
|
5
5
|
|
|
@@ -117,7 +117,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
120
|
-
if (cwdFeature) return
|
|
120
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
121
121
|
|
|
122
122
|
const config = await loadConfig();
|
|
123
123
|
const workspaces = await listWorkspaces(config.workspacesDir);
|
|
@@ -127,12 +127,20 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
127
127
|
return null;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
const selected = await
|
|
131
|
-
message: '
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
const selected = await search({
|
|
131
|
+
message: 'Search and select a workspace to refresh:',
|
|
132
|
+
source: async (input) => {
|
|
133
|
+
const query = (input || '').toLowerCase();
|
|
134
|
+
const filtered = workspaces.filter(
|
|
135
|
+
(ws) =>
|
|
136
|
+
ws.branchName.toLowerCase().includes(query) ||
|
|
137
|
+
ws.workspacePath.toLowerCase().includes(query)
|
|
138
|
+
);
|
|
139
|
+
return filtered.map((ws) => ({
|
|
140
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
|
|
141
|
+
value: ws.workspacePath,
|
|
142
|
+
}));
|
|
143
|
+
},
|
|
136
144
|
});
|
|
137
145
|
|
|
138
146
|
return selected;
|
package/src/commands/remove.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import ora from 'ora';
|
|
8
|
-
import { select, confirm } from '@inquirer/prompts';
|
|
8
|
+
import { select, confirm, search } from '@inquirer/prompts';
|
|
9
9
|
import * as path from 'node:path';
|
|
10
10
|
import * as fs from 'node:fs/promises';
|
|
11
11
|
|
|
@@ -52,12 +52,20 @@ export async function removeCommand(workspaceArg?: string): Promise<void> {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const selected = await
|
|
56
|
-
message: '
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const selected = await search({
|
|
56
|
+
message: 'Search and select a workspace to delete:',
|
|
57
|
+
source: async (input) => {
|
|
58
|
+
const query = (input || '').toLowerCase();
|
|
59
|
+
const filtered = workspaces.filter(
|
|
60
|
+
(ws) =>
|
|
61
|
+
ws.branchName.toLowerCase().includes(query) ||
|
|
62
|
+
ws.workspacePath.toLowerCase().includes(query)
|
|
63
|
+
);
|
|
64
|
+
return filtered.map((ws) => ({
|
|
65
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
|
|
66
|
+
value: ws,
|
|
67
|
+
}));
|
|
68
|
+
},
|
|
61
69
|
});
|
|
62
70
|
|
|
63
71
|
workspacePath = selected.workspacePath;
|
package/src/commands/start.ts
CHANGED
|
@@ -93,7 +93,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
93
93
|
|
|
94
94
|
// Check if CWD is a workspace
|
|
95
95
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
96
|
-
if (cwdFeature) return
|
|
96
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
97
97
|
|
|
98
98
|
// Otherwise, list workspaces and let user pick
|
|
99
99
|
const config = await loadConfig();
|
package/src/commands/status.ts
CHANGED
|
@@ -32,7 +32,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
32
32
|
if (workspaceArg) return workspaceArg;
|
|
33
33
|
|
|
34
34
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
35
|
-
if (cwdFeature) return
|
|
35
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
36
36
|
|
|
37
37
|
const config = await loadConfig();
|
|
38
38
|
const workspaces = await listWorkspaces(config.workspacesDir);
|
package/src/commands/stop.ts
CHANGED
|
@@ -33,7 +33,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
33
33
|
if (workspaceArg) return workspaceArg;
|
|
34
34
|
|
|
35
35
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
36
|
-
if (cwdFeature) return
|
|
36
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
37
37
|
|
|
38
38
|
const config = await loadConfig();
|
|
39
39
|
const workspaces = await listWorkspaces(config.workspacesDir);
|
package/src/commands/sync.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
-
import { select } from '@inquirer/prompts';
|
|
7
|
+
import { select, search } from '@inquirer/prompts';
|
|
8
8
|
import * as path from 'node:path';
|
|
9
9
|
import * as fs from 'node:fs/promises';
|
|
10
10
|
|
|
@@ -123,7 +123,7 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const cwdFeature = await loadFeatureConfig(process.cwd());
|
|
126
|
-
if (cwdFeature) return
|
|
126
|
+
if (cwdFeature) return cwdFeature.workspacePath;
|
|
127
127
|
|
|
128
128
|
const config = await loadConfig();
|
|
129
129
|
const workspaces = await listWorkspaces(config.workspacesDir);
|
|
@@ -133,12 +133,20 @@ async function resolveWorkspace(workspaceArg?: string): Promise<string | null> {
|
|
|
133
133
|
return null;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
const selected = await
|
|
137
|
-
message: '
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
136
|
+
const selected = await search({
|
|
137
|
+
message: 'Search and select a workspace to sync:',
|
|
138
|
+
source: async (input) => {
|
|
139
|
+
const query = (input || '').toLowerCase();
|
|
140
|
+
const filtered = workspaces.filter(
|
|
141
|
+
(ws) =>
|
|
142
|
+
ws.branchName.toLowerCase().includes(query) ||
|
|
143
|
+
ws.workspacePath.toLowerCase().includes(query)
|
|
144
|
+
);
|
|
145
|
+
return filtered.map((ws) => ({
|
|
146
|
+
name: `${ws.branchName} ${chalk.dim(`(${ws.repos.length} repos)`)}`,
|
|
147
|
+
value: ws.workspacePath,
|
|
148
|
+
}));
|
|
149
|
+
},
|
|
142
150
|
});
|
|
143
151
|
|
|
144
152
|
return selected;
|
package/src/core/workspace.ts
CHANGED
|
@@ -82,6 +82,27 @@ export async function createWorkspace(
|
|
|
82
82
|
console.warn('Warning: Failed to create .vscode/settings.json:', error);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
// Create .cursor/mcp.json for workspace-local Cursor MCP configuration
|
|
86
|
+
try {
|
|
87
|
+
const cursorDir = path.join(workspacePath, '.cursor');
|
|
88
|
+
await fs.mkdir(cursorDir, { recursive: true });
|
|
89
|
+
const cursorMcp = {
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"nexusflow": {
|
|
92
|
+
"command": "npx",
|
|
93
|
+
"args": ["-y", "@mrpatronz/nexusflow", "mcp", "run", workspacePath]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
await fs.writeFile(
|
|
98
|
+
path.join(cursorDir, 'mcp.json'),
|
|
99
|
+
JSON.stringify(cursorMcp, null, 2) + '\n',
|
|
100
|
+
'utf-8'
|
|
101
|
+
);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.warn('Warning: Failed to create .cursor/mcp.json:', error);
|
|
104
|
+
}
|
|
105
|
+
|
|
85
106
|
// Create a worktree for each repo inside the workspace.
|
|
86
107
|
for (const repo of repos) {
|
|
87
108
|
const worktreeTarget = path.join(workspacePath, repo.name);
|
|
@@ -173,8 +194,10 @@ export async function saveFeatureConfig(
|
|
|
173
194
|
export async function loadFeatureConfig(
|
|
174
195
|
workspacePath: string,
|
|
175
196
|
): Promise<Feature | null> {
|
|
176
|
-
const
|
|
197
|
+
const rootDir = await findWorkspaceRoot(workspacePath);
|
|
198
|
+
if (!rootDir) return null;
|
|
177
199
|
|
|
200
|
+
const manifestPath = path.join(rootDir, MANIFEST_FILE);
|
|
178
201
|
try {
|
|
179
202
|
const raw = await fs.readFile(manifestPath, 'utf-8');
|
|
180
203
|
return JSON.parse(raw) as Feature;
|
|
@@ -183,6 +206,30 @@ export async function loadFeatureConfig(
|
|
|
183
206
|
}
|
|
184
207
|
}
|
|
185
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Traverses up parent directories to find a directory containing `nexusflow.json`.
|
|
211
|
+
*
|
|
212
|
+
* @param startPath - Path to start searching from.
|
|
213
|
+
* @returns Absolute path to the workspace root directory, or null if not found.
|
|
214
|
+
*/
|
|
215
|
+
export async function findWorkspaceRoot(startPath: string): Promise<string | null> {
|
|
216
|
+
let current = path.resolve(startPath);
|
|
217
|
+
while (true) {
|
|
218
|
+
const manifestPath = path.join(current, MANIFEST_FILE);
|
|
219
|
+
try {
|
|
220
|
+
await fs.access(manifestPath);
|
|
221
|
+
return current;
|
|
222
|
+
} catch {
|
|
223
|
+
const parent = path.dirname(current);
|
|
224
|
+
if (parent === current) {
|
|
225
|
+
break; // Reached root directory
|
|
226
|
+
}
|
|
227
|
+
current = parent;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
186
233
|
/**
|
|
187
234
|
* Resolves a repo path to a full RepoInfo object.
|
|
188
235
|
*
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module generators/antigravity
|
|
3
|
+
* Generates an AGENTS.md file for Antigravity.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import fse from 'fs-extra';
|
|
8
|
+
import type { WorkspaceContext } from '../types.js';
|
|
9
|
+
import { buildContextContent } from './base.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Generates an `AGENTS.md` file at the workspace root.
|
|
13
|
+
*
|
|
14
|
+
* Antigravity reads this file for persistent context about the workspace.
|
|
15
|
+
*
|
|
16
|
+
* @param ctx - The workspace context (feature + repos + analysis).
|
|
17
|
+
* @param workspacePath - Absolute path to the workspace root directory.
|
|
18
|
+
*/
|
|
19
|
+
export async function generateAntigravityConfig(
|
|
20
|
+
ctx: WorkspaceContext,
|
|
21
|
+
workspacePath: string,
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
const content = buildContextContent(ctx);
|
|
24
|
+
const filePath = path.join(workspacePath, 'AGENTS.md');
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
await fse.writeFile(filePath, content, 'utf-8');
|
|
28
|
+
} catch (error) {
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
throw new Error(`Failed to write AGENTS.md: ${message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/generators/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import fse from 'fs-extra';
|
|
4
4
|
import type { AIAssistant, WorkspaceContext } from '../types.js';
|
|
5
5
|
import { generateClaudeConfig } from './claude.js';
|
|
6
|
+
import { generateAntigravityConfig } from './antigravity.js';
|
|
6
7
|
import { generateCodexConfig } from './codex.js';
|
|
7
8
|
import { generateCopilotConfig } from './copilot.js';
|
|
8
9
|
import { generateCursorConfig } from './cursor.js';
|
|
@@ -19,7 +20,7 @@ const GENERATORS: Record<
|
|
|
19
20
|
}
|
|
20
21
|
> = {
|
|
21
22
|
claude: { generate: generateClaudeConfig, outputFile: 'CLAUDE.md' },
|
|
22
|
-
antigravity: { generate:
|
|
23
|
+
antigravity: { generate: generateAntigravityConfig, outputFile: 'AGENTS.md' },
|
|
23
24
|
codex: { generate: generateCodexConfig, outputFile: 'AGENTS.md' },
|
|
24
25
|
copilot: { generate: generateCopilotConfig, outputFile: '.github/copilot-instructions.md' },
|
|
25
26
|
cursor: { generate: generateCursorConfig, outputFile: '.cursor/rules/nexusflow.mdc' },
|
|
@@ -177,6 +178,7 @@ export async function generateContextFiles(
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
// Generate configuration for each selected assistant
|
|
180
182
|
for (const assistant of assistants) {
|
|
181
183
|
const entry = GENERATORS[assistant];
|
|
182
184
|
|
|
@@ -195,6 +197,25 @@ export async function generateContextFiles(
|
|
|
195
197
|
}
|
|
196
198
|
}
|
|
197
199
|
|
|
200
|
+
// Ensure AGENTS.md is always generated if it is not already generated as a primary assistant file,
|
|
201
|
+
// since it is the universal standard for AI coding agents.
|
|
202
|
+
const hasAgentsGen = assistants.includes('antigravity') || assistants.includes('codex');
|
|
203
|
+
if (!hasAgentsGen) {
|
|
204
|
+
try {
|
|
205
|
+
await generateAntigravityConfig(ctx, workspacePath);
|
|
206
|
+
console.log(
|
|
207
|
+
chalk.green(' ✔'),
|
|
208
|
+
`Generated fallback ${chalk.bold('AGENTS.md')} for harness context`,
|
|
209
|
+
);
|
|
210
|
+
} catch (error) {
|
|
211
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
212
|
+
console.error(
|
|
213
|
+
chalk.red(' ✖'),
|
|
214
|
+
`Failed to generate fallback AGENTS.md: ${message}`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
198
219
|
|
|
199
220
|
// Generate implementation plan from dependency analysis (if analysis data available)
|
|
200
221
|
try {
|
|
@@ -221,6 +242,7 @@ export async function generateContextFiles(
|
|
|
221
242
|
|
|
222
243
|
// Re-export individual generators for direct use
|
|
223
244
|
export { generateClaudeConfig } from './claude.js';
|
|
245
|
+
export { generateAntigravityConfig } from './antigravity.js';
|
|
224
246
|
export { generateCodexConfig } from './codex.js';
|
|
225
247
|
export { generateCopilotConfig } from './copilot.js';
|
|
226
248
|
export { generateCursorConfig } from './cursor.js';
|
|
@@ -175,10 +175,14 @@ async function deploySkill(
|
|
|
175
175
|
};
|
|
176
176
|
const title = titleMap[skillName] || skillName;
|
|
177
177
|
|
|
178
|
-
if (assistant === 'claude'
|
|
178
|
+
if (assistant === 'claude') {
|
|
179
179
|
const skillDir = path.join(workspacePath, '.claude', 'skills', skillName);
|
|
180
180
|
await fse.ensureDir(skillDir);
|
|
181
181
|
await fse.writeFile(path.join(skillDir, 'SKILL.md'), content, 'utf-8');
|
|
182
|
+
} else if (assistant === 'antigravity') {
|
|
183
|
+
const skillDir = path.join(workspacePath, '.agents', 'skills', skillName);
|
|
184
|
+
await fse.ensureDir(skillDir);
|
|
185
|
+
await fse.writeFile(path.join(skillDir, 'SKILL.md'), content, 'utf-8');
|
|
182
186
|
} else if (assistant === 'cursor') {
|
|
183
187
|
const ruleDir = path.join(workspacePath, '.cursor', 'rules');
|
|
184
188
|
await fse.ensureDir(ruleDir);
|