@syntesseraai/opencode-feature-factory 0.2.20 ā 0.2.22
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/bin/ff-deploy.js +11 -112
- package/package.json +1 -1
package/bin/ff-deploy.js
CHANGED
|
@@ -4,17 +4,13 @@
|
|
|
4
4
|
* Feature Factory Deployment Script
|
|
5
5
|
*
|
|
6
6
|
* Deploys skills and agents to the global OpenCode configuration directory.
|
|
7
|
-
* Run manually with: npx @syntesseraai/opencode-feature-factory
|
|
8
|
-
* With MCP update: npx @syntesseraai/opencode-feature-factory install --mcp
|
|
9
|
-
*
|
|
10
|
-
* Non-interactive mode: Automatically deploys without prompts when no TTY detected
|
|
7
|
+
* Run manually with: npx @syntesseraai/opencode-feature-factory
|
|
11
8
|
*/
|
|
12
9
|
|
|
13
10
|
import { promises as fs } from 'fs';
|
|
14
11
|
import { join, dirname } from 'path';
|
|
15
12
|
import { fileURLToPath } from 'url';
|
|
16
13
|
import { homedir } from 'os';
|
|
17
|
-
import { createInterface } from 'readline';
|
|
18
14
|
|
|
19
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
20
16
|
const __dirname = dirname(__filename);
|
|
@@ -28,6 +24,9 @@ const PACKAGE_ROOT = join(__dirname, '..');
|
|
|
28
24
|
const SOURCE_SKILLS_DIR = join(PACKAGE_ROOT, 'skills');
|
|
29
25
|
const SOURCE_AGENTS_DIR = join(PACKAGE_ROOT, 'agents');
|
|
30
26
|
|
|
27
|
+
// Check if running in interactive mode (has TTY)
|
|
28
|
+
const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
|
|
29
|
+
|
|
31
30
|
// Default MCP configuration
|
|
32
31
|
const DEFAULT_MCP_SERVERS = {
|
|
33
32
|
'jina-ai': {
|
|
@@ -50,9 +49,6 @@ const DEFAULT_MCP_SERVERS = {
|
|
|
50
49
|
},
|
|
51
50
|
};
|
|
52
51
|
|
|
53
|
-
// Check if running in interactive mode (has TTY)
|
|
54
|
-
const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
|
|
55
|
-
|
|
56
52
|
async function ensureDir(dir) {
|
|
57
53
|
try {
|
|
58
54
|
await fs.mkdir(dir, { recursive: true });
|
|
@@ -100,24 +96,10 @@ async function getFileNames(dir) {
|
|
|
100
96
|
}
|
|
101
97
|
}
|
|
102
98
|
|
|
103
|
-
function
|
|
104
|
-
const rl = createInterface({
|
|
105
|
-
input: process.stdin,
|
|
106
|
-
output: process.stdout,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return new Promise((resolve) => {
|
|
110
|
-
rl.question(question, (answer) => {
|
|
111
|
-
rl.close();
|
|
112
|
-
resolve(answer.trim().toLowerCase());
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async function updateMCPConfigNonInteractive() {
|
|
99
|
+
async function updateMCPConfig() {
|
|
118
100
|
if (isInteractive) {
|
|
119
|
-
console.log('\nš§ MCP Configuration Update
|
|
120
|
-
console.log('
|
|
101
|
+
console.log('\nš§ MCP Configuration Update');
|
|
102
|
+
console.log('============================\n');
|
|
121
103
|
}
|
|
122
104
|
|
|
123
105
|
try {
|
|
@@ -198,78 +180,7 @@ async function updateMCPConfigNonInteractive() {
|
|
|
198
180
|
}
|
|
199
181
|
}
|
|
200
182
|
|
|
201
|
-
async function
|
|
202
|
-
console.log('\nš§ MCP Configuration Update');
|
|
203
|
-
console.log('============================\n');
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
// Check if config file exists
|
|
207
|
-
let existingConfig = {};
|
|
208
|
-
let configExists = false;
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
const configContent = await fs.readFile(GLOBAL_CONFIG_FILE, 'utf8');
|
|
212
|
-
existingConfig = JSON.parse(configContent);
|
|
213
|
-
configExists = true;
|
|
214
|
-
console.log(`š Found existing config: ${GLOBAL_CONFIG_FILE}`);
|
|
215
|
-
} catch {
|
|
216
|
-
console.log(`š No existing config found. Will create new file.`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Show current MCP config if exists
|
|
220
|
-
if (existingConfig.mcp) {
|
|
221
|
-
console.log('\nš Current MCP Configuration:');
|
|
222
|
-
console.log(JSON.stringify(existingConfig.mcp, null, 2));
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Show proposed MCP config
|
|
226
|
-
console.log('\nš Proposed MCP Configuration:');
|
|
227
|
-
console.log(JSON.stringify(DEFAULT_MCP_SERVERS, null, 2));
|
|
228
|
-
|
|
229
|
-
// Prompt user
|
|
230
|
-
const answer = await promptUser('\nā Update MCP configuration? (y/n): ');
|
|
231
|
-
|
|
232
|
-
if (answer !== 'y' && answer !== 'yes') {
|
|
233
|
-
console.log('āļø Skipping MCP configuration update.');
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// Backup existing config if it exists
|
|
238
|
-
if (configExists) {
|
|
239
|
-
const timestamp = new Date().toISOString().split('T')[0].replace(/-/g, '');
|
|
240
|
-
const backupFile = `${GLOBAL_CONFIG_FILE}.backup.${timestamp}`;
|
|
241
|
-
await fs.copyFile(GLOBAL_CONFIG_FILE, backupFile);
|
|
242
|
-
console.log(`\nš¾ Backed up existing config to: ${backupFile}`);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Merge MCP config into existing config
|
|
246
|
-
const updatedConfig = {
|
|
247
|
-
...existingConfig,
|
|
248
|
-
mcp: {
|
|
249
|
-
...(existingConfig.mcp || {}),
|
|
250
|
-
...DEFAULT_MCP_SERVERS,
|
|
251
|
-
},
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
// Write updated config
|
|
255
|
-
await fs.writeFile(GLOBAL_CONFIG_FILE, JSON.stringify(updatedConfig, null, 2));
|
|
256
|
-
console.log(`ā
Updated MCP configuration in: ${GLOBAL_CONFIG_FILE}`);
|
|
257
|
-
console.log('\nš Note: Restart OpenCode to load new MCP configuration');
|
|
258
|
-
} catch (error) {
|
|
259
|
-
console.error(`\nā Failed to update MCP config: ${error.message}`);
|
|
260
|
-
throw error;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
async function updateMCPConfig() {
|
|
265
|
-
if (isInteractive) {
|
|
266
|
-
await updateMCPConfigInteractive();
|
|
267
|
-
} else {
|
|
268
|
-
await updateMCPConfigNonInteractive();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async function deploy(updateMCP) {
|
|
183
|
+
async function deploy() {
|
|
273
184
|
if (isInteractive) {
|
|
274
185
|
console.log('š Feature Factory OpenCode Plugin - Deployment');
|
|
275
186
|
console.log('================================================\n');
|
|
@@ -337,10 +248,8 @@ async function deploy(updateMCP) {
|
|
|
337
248
|
console.log(' - Use @ff-research to investigate external topics');
|
|
338
249
|
}
|
|
339
250
|
|
|
340
|
-
//
|
|
341
|
-
|
|
342
|
-
await updateMCPConfig();
|
|
343
|
-
}
|
|
251
|
+
// Always update MCP config (no flag needed, no prompts)
|
|
252
|
+
await updateMCPConfig();
|
|
344
253
|
} catch (error) {
|
|
345
254
|
if (isInteractive) {
|
|
346
255
|
console.error('\nā Deployment failed:', error.message);
|
|
@@ -349,15 +258,5 @@ async function deploy(updateMCP) {
|
|
|
349
258
|
}
|
|
350
259
|
}
|
|
351
260
|
|
|
352
|
-
// Parse command line arguments
|
|
353
|
-
const args = process.argv.slice(2);
|
|
354
|
-
|
|
355
|
-
// Check if running install command
|
|
356
|
-
const isInstall = args[0] === 'install' || args.length === 0;
|
|
357
|
-
|
|
358
|
-
// Always update MCP config when installing (no flag required)
|
|
359
|
-
const skipMCP = args.includes('--no-mcp');
|
|
360
|
-
const updateMCP = isInstall && !skipMCP;
|
|
361
|
-
|
|
362
261
|
// Run deployment
|
|
363
|
-
deploy(
|
|
262
|
+
deploy();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@syntesseraai/opencode-feature-factory",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.22",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "OpenCode plugin for Feature Factory agents - provides sub-agents and skills for validation, review, security, and architecture assessment",
|
|
7
7
|
"license": "MIT",
|