snow-flow 8.37.27 → 8.38.1
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/.snow-code/agent/deployment-specialist.md +346 -0
- package/.snow-code/agent/orchestrator.md +286 -0
- package/.snow-code/agent/risk-assessor.md +454 -0
- package/.snow-code/agent/solution-architect.md +582 -0
- package/.snow-code/agent/validator.md +503 -0
- package/.snow-code/opencode.json +49 -0
- package/README.md +16 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +104 -266
- package/dist/cli.js.map +1 -1
- package/dist/utils/config-cache.js +6 -6
- package/dist/utils/config-cache.js.map +1 -1
- package/dist/utils/sync-mcp-configs.d.ts +7 -5
- package/dist/utils/sync-mcp-configs.d.ts.map +1 -1
- package/dist/utils/sync-mcp-configs.js +19 -74
- package/dist/utils/sync-mcp-configs.js.map +1 -1
- package/package.json +2 -3
- package/scripts/check-binary-updates.js +0 -169
- package/scripts/check-npm-version.js +0 -92
- package/scripts/classify-all-tools.ts +0 -446
- package/scripts/classify-edge-cases.ts +0 -275
- package/scripts/classify-operations-tools.sh +0 -96
- package/scripts/cleanup-mcp-servers.js +0 -115
- package/scripts/diagnose-mcp.js +0 -299
- package/scripts/generate-mcp-config.js +0 -45
- package/scripts/mcp-server-manager.sh +0 -320
- package/scripts/postinstall.js +0 -75
- package/scripts/reset-mcp-servers.js +0 -266
- package/scripts/safe-mcp-cleanup.js +0 -151
- package/scripts/setup-mcp.js +0 -106
- package/scripts/start-mcp-proper.js +0 -76
- package/scripts/start-snowcode.sh +0 -123
- package/scripts/start-sysprops-mcp.js +0 -43
- package/scripts/sync-snow-code-version.js +0 -74
- package/scripts/test-auth-flow.js +0 -172
- package/scripts/test-auth-location-fix.js +0 -84
- package/scripts/test-mcp-manual.js +0 -140
- package/scripts/test-todowrite-timeout.js +0 -108
- package/scripts/update-dependencies.js +0 -90
- package/scripts/update-mcp-config.js +0 -96
- package/scripts/update-snow-code.js +0 -146
- package/scripts/verify-snowcode-fork.sh +0 -141
- package/templates/snow-code-package.json +0 -3
package/dist/cli.js
CHANGED
|
@@ -574,9 +574,10 @@ async function executeSnowCode(objective, options) {
|
|
|
574
574
|
cliLogger.error('SnowCode CLI not found - install: npm install -g @groeimetai/snow-code');
|
|
575
575
|
return false;
|
|
576
576
|
}
|
|
577
|
-
// Check for SnowCode config (.snow-code/snow-code.json)
|
|
578
|
-
const snowcodeConfigPath = (0, path_1.join)(process.cwd(), '.snow-code', '
|
|
579
|
-
|
|
577
|
+
// Check for SnowCode config (.snow-code/config.json OR .snow-code/snow-code.json)
|
|
578
|
+
const snowcodeConfigPath = (0, path_1.join)(process.cwd(), '.snow-code', 'config.json');
|
|
579
|
+
const snowcodeConfigPathAlt = (0, path_1.join)(process.cwd(), '.snow-code', 'snow-code.json');
|
|
580
|
+
if (!(0, fs_2.existsSync)(snowcodeConfigPath) && !(0, fs_2.existsSync)(snowcodeConfigPathAlt)) {
|
|
580
581
|
cliLogger.error('SnowCode config not found - run: snow-flow init');
|
|
581
582
|
return false;
|
|
582
583
|
}
|
|
@@ -1552,7 +1553,7 @@ program
|
|
|
1552
1553
|
await copySnowCodeConfig(targetDir, options.force);
|
|
1553
1554
|
await copySnowCodeThemes(targetDir, options.force);
|
|
1554
1555
|
await copySnowCodePackageJson(targetDir, options.force);
|
|
1555
|
-
|
|
1556
|
+
// copyMCPServerScripts removed - scripts/ directory no longer needed for snow-code
|
|
1556
1557
|
setupSpinner.stop('Project configured');
|
|
1557
1558
|
// Verify MCP servers
|
|
1558
1559
|
if (!options.skipMcp) {
|
|
@@ -1561,8 +1562,8 @@ program
|
|
|
1561
1562
|
await verifyMCPServers(targetDir);
|
|
1562
1563
|
mcpSpinner.stop('MCP servers verified');
|
|
1563
1564
|
}
|
|
1564
|
-
//
|
|
1565
|
-
// This ensures
|
|
1565
|
+
// Sync .mcp.json to .snow-code/config.json
|
|
1566
|
+
// This ensures snow-code discovers all MCP servers
|
|
1566
1567
|
try {
|
|
1567
1568
|
const syncSpinner = prompts.spinner();
|
|
1568
1569
|
syncSpinner.start('Syncing MCP configurations');
|
|
@@ -1739,46 +1740,20 @@ async function checkAndInstallSnowCode() {
|
|
|
1739
1740
|
return false;
|
|
1740
1741
|
}
|
|
1741
1742
|
async function createDirectoryStructure(targetDir, force = false) {
|
|
1743
|
+
// Minimal directory structure for snow-code
|
|
1744
|
+
// Legacy directories (.claude, .swarm, .snow-flow, memory, coordination, servicenow, templates, scripts) removed
|
|
1742
1745
|
const directories = [
|
|
1743
|
-
'.
|
|
1744
|
-
'.
|
|
1745
|
-
'.snow-
|
|
1746
|
-
'
|
|
1747
|
-
'coordination', 'coordination/memory_bank', 'coordination/subtasks',
|
|
1748
|
-
'servicenow', 'servicenow/widgets', 'servicenow/workflows', 'servicenow/scripts',
|
|
1749
|
-
'templates', 'templates/widgets', 'templates/workflows',
|
|
1750
|
-
'scripts'
|
|
1746
|
+
'.snow-code',
|
|
1747
|
+
'.snow-code/agent',
|
|
1748
|
+
'.snow-code/command',
|
|
1749
|
+
'.snow-code/plugin'
|
|
1751
1750
|
];
|
|
1752
1751
|
for (const dir of directories) {
|
|
1753
1752
|
const dirPath = (0, path_1.join)(targetDir, dir);
|
|
1754
1753
|
await fs_1.promises.mkdir(dirPath, { recursive: true });
|
|
1755
1754
|
}
|
|
1756
1755
|
}
|
|
1757
|
-
|
|
1758
|
-
const claudeConfig = {
|
|
1759
|
-
version: version_js_1.VERSION,
|
|
1760
|
-
name: 'snow-flow',
|
|
1761
|
-
description: 'ServiceNow Multi-Agent Development Framework',
|
|
1762
|
-
created: new Date().toISOString(),
|
|
1763
|
-
features: {
|
|
1764
|
-
swarmCoordination: true,
|
|
1765
|
-
persistentMemory: true, // Queen uses JSON files, MCP tools use in-memory
|
|
1766
|
-
serviceNowIntegration: true,
|
|
1767
|
-
sparcModes: true
|
|
1768
|
-
}
|
|
1769
|
-
};
|
|
1770
|
-
const swarmConfig = {
|
|
1771
|
-
version: version_js_1.VERSION,
|
|
1772
|
-
topology: 'hierarchical',
|
|
1773
|
-
maxAgents: 8,
|
|
1774
|
-
memory: {
|
|
1775
|
-
path: '.swarm/memory',
|
|
1776
|
-
namespace: 'snow-flow'
|
|
1777
|
-
}
|
|
1778
|
-
};
|
|
1779
|
-
await fs_1.promises.writeFile((0, path_1.join)(targetDir, '.claude/config.json'), JSON.stringify(claudeConfig, null, 2));
|
|
1780
|
-
await fs_1.promises.writeFile((0, path_1.join)(targetDir, '.swarm/config.json'), JSON.stringify(swarmConfig, null, 2));
|
|
1781
|
-
}
|
|
1756
|
+
// createBasicConfig removed - legacy .claude and .swarm configs no longer needed
|
|
1782
1757
|
async function createReadmeFiles(targetDir, force = false) {
|
|
1783
1758
|
// Only create README.md if it doesn't exist already
|
|
1784
1759
|
const readmePath = (0, path_1.join)(targetDir, 'README.md');
|
|
@@ -1787,9 +1762,7 @@ async function createReadmeFiles(targetDir, force = false) {
|
|
|
1787
1762
|
const { README_TEMPLATE } = await Promise.resolve().then(() => __importStar(require('./templates/readme-template.js')));
|
|
1788
1763
|
await fs_1.promises.writeFile(readmePath, README_TEMPLATE);
|
|
1789
1764
|
}
|
|
1790
|
-
//
|
|
1791
|
-
await fs_1.promises.writeFile((0, path_1.join)(targetDir, 'memory/agents/README.md'), '# Agent Memory\n\nThis directory contains persistent memory for ServiceNow agents.');
|
|
1792
|
-
await fs_1.promises.writeFile((0, path_1.join)(targetDir, 'servicenow/README.md'), '# ServiceNow Artifacts\n\nThis directory contains generated ServiceNow development artifacts.');
|
|
1765
|
+
// Legacy sub-directory READMEs removed (memory/, servicenow/ directories no longer created)
|
|
1793
1766
|
}
|
|
1794
1767
|
// Helper functions
|
|
1795
1768
|
async function copySnowCodeConfig(targetDir, force = false) {
|
|
@@ -2038,16 +2011,16 @@ async function verifyMCPServers(targetDir) {
|
|
|
2038
2011
|
const path = require('path');
|
|
2039
2012
|
const fs = require('fs').promises;
|
|
2040
2013
|
try {
|
|
2041
|
-
// Read SnowCode configuration - try
|
|
2042
|
-
const snowCodeJsonPath = path.join(targetDir, '.snow-code', 'snow-code.json');
|
|
2014
|
+
// Read SnowCode configuration - try config.json first (primary), then snow-code.json (fallback for legacy)
|
|
2043
2015
|
const configJsonPath = path.join(targetDir, '.snow-code', 'config.json');
|
|
2016
|
+
const snowCodeJsonPath = path.join(targetDir, '.snow-code', 'snow-code.json');
|
|
2044
2017
|
let configContent;
|
|
2045
2018
|
try {
|
|
2046
|
-
configContent = await fs.readFile(
|
|
2019
|
+
configContent = await fs.readFile(configJsonPath, 'utf-8');
|
|
2047
2020
|
}
|
|
2048
2021
|
catch {
|
|
2049
|
-
// Fallback to
|
|
2050
|
-
configContent = await fs.readFile(
|
|
2022
|
+
// Fallback to snow-code.json for legacy projects
|
|
2023
|
+
configContent = await fs.readFile(snowCodeJsonPath, 'utf-8');
|
|
2051
2024
|
}
|
|
2052
2025
|
const config = JSON.parse(configContent);
|
|
2053
2026
|
if (!config.mcp) {
|
|
@@ -2138,96 +2111,10 @@ async function verifyMCPServers(targetDir) {
|
|
|
2138
2111
|
// Silent error handling
|
|
2139
2112
|
}
|
|
2140
2113
|
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
// Determine the snow-flow installation directory (same logic as other copy functions)
|
|
2144
|
-
let snowFlowRoot;
|
|
2145
|
-
const isGlobalInstall = __dirname.includes('node_modules/snow-flow') ||
|
|
2146
|
-
__dirname.includes('node_modules/.pnpm') ||
|
|
2147
|
-
__dirname.includes('npm/snow-flow');
|
|
2148
|
-
if (isGlobalInstall) {
|
|
2149
|
-
const parts = __dirname.split(/node_modules[\/\\]/);
|
|
2150
|
-
snowFlowRoot = parts[0] + 'node_modules/snow-flow';
|
|
2151
|
-
}
|
|
2152
|
-
else {
|
|
2153
|
-
let currentDir = __dirname;
|
|
2154
|
-
while (currentDir !== '/') {
|
|
2155
|
-
try {
|
|
2156
|
-
const packageJsonPath = (0, path_1.join)(currentDir, 'package.json');
|
|
2157
|
-
const packageJson = JSON.parse(await fs_1.promises.readFile(packageJsonPath, 'utf-8'));
|
|
2158
|
-
if (packageJson.name === 'snow-flow') {
|
|
2159
|
-
snowFlowRoot = currentDir;
|
|
2160
|
-
break;
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
catch {
|
|
2164
|
-
// Continue searching up
|
|
2165
|
-
}
|
|
2166
|
-
currentDir = (0, path_1.dirname)(currentDir);
|
|
2167
|
-
}
|
|
2168
|
-
if (!snowFlowRoot) {
|
|
2169
|
-
throw new Error('Could not find snow-flow project root');
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
// Find scripts directory
|
|
2173
|
-
const scriptsSourcePaths = [
|
|
2174
|
-
(0, path_1.join)(snowFlowRoot, 'scripts'),
|
|
2175
|
-
(0, path_1.join)(__dirname, '..', 'scripts'),
|
|
2176
|
-
(0, path_1.join)(__dirname, 'scripts')
|
|
2177
|
-
];
|
|
2178
|
-
let scriptsSourceDir = null;
|
|
2179
|
-
for (const sourcePath of scriptsSourcePaths) {
|
|
2180
|
-
try {
|
|
2181
|
-
await fs_1.promises.access(sourcePath);
|
|
2182
|
-
scriptsSourceDir = sourcePath;
|
|
2183
|
-
break;
|
|
2184
|
-
}
|
|
2185
|
-
catch {
|
|
2186
|
-
// Continue to next path
|
|
2187
|
-
}
|
|
2188
|
-
}
|
|
2189
|
-
if (!scriptsSourceDir) {
|
|
2190
|
-
return;
|
|
2191
|
-
}
|
|
2192
|
-
// Create target scripts directory
|
|
2193
|
-
const scriptsTargetDir = (0, path_1.join)(targetDir, 'scripts');
|
|
2194
|
-
await fs_1.promises.mkdir(scriptsTargetDir, { recursive: true });
|
|
2195
|
-
// Copy specific scripts
|
|
2196
|
-
const scriptFiles = [
|
|
2197
|
-
// 'mcp-server-manager.sh', // REMOVED: MCP servers auto-start via .mcp.json, this script is for dev only
|
|
2198
|
-
'start-snowcode.sh'
|
|
2199
|
-
];
|
|
2200
|
-
let copiedCount = 0;
|
|
2201
|
-
for (const scriptFile of scriptFiles) {
|
|
2202
|
-
const sourcePath = (0, path_1.join)(scriptsSourceDir, scriptFile);
|
|
2203
|
-
const targetPath = (0, path_1.join)(scriptsTargetDir, scriptFile);
|
|
2204
|
-
try {
|
|
2205
|
-
// Check if file already exists
|
|
2206
|
-
try {
|
|
2207
|
-
await fs_1.promises.access(targetPath);
|
|
2208
|
-
if (!force) {
|
|
2209
|
-
continue;
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
catch {
|
|
2213
|
-
// File doesn't exist, continue with copy
|
|
2214
|
-
}
|
|
2215
|
-
const content = await fs_1.promises.readFile(sourcePath, 'utf8');
|
|
2216
|
-
await fs_1.promises.writeFile(targetPath, content, { mode: 0o755 }); // Make executable
|
|
2217
|
-
copiedCount++;
|
|
2218
|
-
}
|
|
2219
|
-
catch (error) {
|
|
2220
|
-
// Silent error handling
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
}
|
|
2224
|
-
catch (error) {
|
|
2225
|
-
// Silent error handling
|
|
2226
|
-
}
|
|
2227
|
-
}
|
|
2114
|
+
// copyMCPServerScripts removed - scripts/ directory no longer needed for snow-code
|
|
2115
|
+
// snow-code auto-manages MCP servers via .mcp.json and .snow-code/config.json
|
|
2228
2116
|
async function copyCLAUDEmd(targetDir, force = false) {
|
|
2229
2117
|
let claudeMdContent = '';
|
|
2230
|
-
let agentsMdContent = '';
|
|
2231
2118
|
// Determine the snow-flow installation directory for absolute MCP paths
|
|
2232
2119
|
let snowFlowRoot;
|
|
2233
2120
|
const isGlobalInstall = __dirname.includes('node_modules/snow-flow') ||
|
|
@@ -2260,14 +2147,10 @@ async function copyCLAUDEmd(targetDir, force = false) {
|
|
|
2260
2147
|
try {
|
|
2261
2148
|
// First try to find the CLAUDE.md in the source directory (for global installs)
|
|
2262
2149
|
const sourceClaudeFiles = [
|
|
2263
|
-
// Try the project root (when running from dist/)
|
|
2264
2150
|
(0, path_1.join)(__dirname, '..', 'CLAUDE.md'),
|
|
2265
|
-
// Try when running directly from src/
|
|
2266
2151
|
(0, path_1.join)(__dirname, 'CLAUDE.md'),
|
|
2267
|
-
// Try npm global installation paths
|
|
2268
2152
|
(0, path_1.join)(__dirname, '..', '..', '..', 'CLAUDE.md'),
|
|
2269
2153
|
(0, path_1.join)(__dirname, '..', '..', '..', '..', 'CLAUDE.md'),
|
|
2270
|
-
// Try current working directory as fallback
|
|
2271
2154
|
(0, path_1.join)(process.cwd(), 'CLAUDE.md')
|
|
2272
2155
|
];
|
|
2273
2156
|
let foundSource = false;
|
|
@@ -2282,145 +2165,104 @@ async function copyCLAUDEmd(targetDir, force = false) {
|
|
|
2282
2165
|
}
|
|
2283
2166
|
}
|
|
2284
2167
|
if (!foundSource) {
|
|
2285
|
-
// Import the template from the dedicated file
|
|
2286
2168
|
const { CLAUDE_MD_TEMPLATE } = await Promise.resolve().then(() => __importStar(require('./templates/claude-md-template.js')));
|
|
2287
2169
|
claudeMdContent = CLAUDE_MD_TEMPLATE;
|
|
2288
2170
|
}
|
|
2289
|
-
//
|
|
2290
|
-
agentsMdContent = claudeMdContent;
|
|
2291
|
-
// Create CLAUDE.md (primary instructions for Claude Code)
|
|
2292
|
-
const claudeMdPath = (0, path_1.join)(targetDir, 'CLAUDE.md');
|
|
2293
|
-
try {
|
|
2294
|
-
await fs_1.promises.access(claudeMdPath);
|
|
2295
|
-
if (force) {
|
|
2296
|
-
await fs_1.promises.writeFile(claudeMdPath, claudeMdContent);
|
|
2297
|
-
}
|
|
2298
|
-
}
|
|
2299
|
-
catch {
|
|
2300
|
-
await fs_1.promises.writeFile(claudeMdPath, claudeMdContent);
|
|
2301
|
-
}
|
|
2302
|
-
// Create AGENTS.md (identical copy for SnowCode compatibility)
|
|
2171
|
+
// Create AGENTS.md in root (snow-code searches for AGENTS.md or CLAUDE.md)
|
|
2303
2172
|
const agentsMdPath = (0, path_1.join)(targetDir, 'AGENTS.md');
|
|
2304
2173
|
try {
|
|
2305
2174
|
await fs_1.promises.access(agentsMdPath);
|
|
2306
2175
|
if (force) {
|
|
2307
|
-
await fs_1.promises.writeFile(agentsMdPath,
|
|
2176
|
+
await fs_1.promises.writeFile(agentsMdPath, claudeMdContent);
|
|
2308
2177
|
}
|
|
2309
2178
|
}
|
|
2310
2179
|
catch {
|
|
2311
|
-
await fs_1.promises.writeFile(agentsMdPath,
|
|
2180
|
+
await fs_1.promises.writeFile(agentsMdPath, claudeMdContent);
|
|
2312
2181
|
}
|
|
2313
|
-
//
|
|
2182
|
+
// Setup .snow-code/ directory (directories already created by createDirectoryStructure)
|
|
2314
2183
|
const snowcodeDir = (0, path_1.join)(targetDir, '.snow-code');
|
|
2315
|
-
const agentsDir = (0, path_1.join)(snowcodeDir, 'agent');
|
|
2316
|
-
|
|
2184
|
+
const agentsDir = (0, path_1.join)(snowcodeDir, 'agent');
|
|
2185
|
+
// Copy agent files from .snow-code/agent/ in snow-flow package
|
|
2186
|
+
const sourceAgentsDir = (0, path_1.join)(snowFlowRoot, '.snow-code', 'agent');
|
|
2317
2187
|
try {
|
|
2318
|
-
await fs_1.promises.
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2188
|
+
const agentFiles = await fs_1.promises.readdir(sourceAgentsDir);
|
|
2189
|
+
for (const file of agentFiles) {
|
|
2190
|
+
if (file.endsWith('.md')) {
|
|
2191
|
+
const sourceFile = (0, path_1.join)(sourceAgentsDir, file);
|
|
2192
|
+
const targetFile = (0, path_1.join)(agentsDir, file);
|
|
2193
|
+
try {
|
|
2194
|
+
await fs_1.promises.access(targetFile);
|
|
2195
|
+
if (force) {
|
|
2196
|
+
const content = await fs_1.promises.readFile(sourceFile, 'utf-8');
|
|
2197
|
+
await fs_1.promises.writeFile(targetFile, content);
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
catch {
|
|
2329
2201
|
const content = await fs_1.promises.readFile(sourceFile, 'utf-8');
|
|
2330
2202
|
await fs_1.promises.writeFile(targetFile, content);
|
|
2331
2203
|
}
|
|
2332
2204
|
}
|
|
2333
2205
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
const
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
var value = line.substring(equalIndex + 1).trim();
|
|
2356
|
-
// Remove quotes if present
|
|
2357
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
2358
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
2359
|
-
value = value.substring(1, value.length - 1);
|
|
2360
|
-
}
|
|
2361
|
-
envValues[key] = value;
|
|
2206
|
+
}
|
|
2207
|
+
catch (err) {
|
|
2208
|
+
// Silently continue - agent files are optional
|
|
2209
|
+
}
|
|
2210
|
+
// Create .snow-code/config.json from .mcp.json.template
|
|
2211
|
+
const envPath = (0, path_1.join)(targetDir, '.env');
|
|
2212
|
+
const envValues = {};
|
|
2213
|
+
try {
|
|
2214
|
+
const envContent = await fs_1.promises.readFile(envPath, 'utf-8');
|
|
2215
|
+
const lines = envContent.split('\n');
|
|
2216
|
+
for (var line of lines) {
|
|
2217
|
+
line = line.trim();
|
|
2218
|
+
if (!line || line.startsWith('#'))
|
|
2219
|
+
continue;
|
|
2220
|
+
var equalIndex = line.indexOf('=');
|
|
2221
|
+
if (equalIndex > 0) {
|
|
2222
|
+
var key = line.substring(0, equalIndex).trim();
|
|
2223
|
+
var value = line.substring(equalIndex + 1).trim();
|
|
2224
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
2225
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
2226
|
+
value = value.substring(1, value.length - 1);
|
|
2362
2227
|
}
|
|
2228
|
+
envValues[key] = value;
|
|
2363
2229
|
}
|
|
2364
2230
|
}
|
|
2365
|
-
catch (error) {
|
|
2366
|
-
// Silent error handling
|
|
2367
|
-
}
|
|
2368
|
-
// Helper function to get env value with proper URL formatting
|
|
2369
|
-
function getEnvValue(key, defaultValue = '') {
|
|
2370
|
-
var value = envValues[key] || process.env[key] || defaultValue;
|
|
2371
|
-
// Special handling for SNOW_INSTANCE - ensure it's a full URL
|
|
2372
|
-
if (key === 'SNOW_INSTANCE' && value && !value.startsWith('http')) {
|
|
2373
|
-
value = 'https://' + value.replace(/^https?:\/\//, '');
|
|
2374
|
-
}
|
|
2375
|
-
return value;
|
|
2376
|
-
}
|
|
2377
|
-
// Read .mcp.json.template (single source of truth for MCP servers)
|
|
2378
|
-
const mcpTemplatePath = (0, path_1.join)(snowFlowRoot, '.mcp.json.template');
|
|
2379
|
-
let mcpTemplateContent;
|
|
2380
|
-
try {
|
|
2381
|
-
mcpTemplateContent = await fs_1.promises.readFile(mcpTemplatePath, 'utf-8');
|
|
2382
|
-
}
|
|
2383
|
-
catch (error) {
|
|
2384
|
-
throw error;
|
|
2385
|
-
}
|
|
2386
|
-
// Replace placeholders with ACTUAL values from .env (not ${...} syntax!)
|
|
2387
|
-
const mcpConfigContent = mcpTemplateContent
|
|
2388
|
-
.replace(/{{PROJECT_ROOT}}/g, snowFlowRoot)
|
|
2389
|
-
.replace(/{{SNOW_INSTANCE}}/g, getEnvValue('SNOW_INSTANCE'))
|
|
2390
|
-
.replace(/{{SNOW_CLIENT_ID}}/g, getEnvValue('SNOW_CLIENT_ID'))
|
|
2391
|
-
.replace(/{{SNOW_CLIENT_SECRET}}/g, getEnvValue('SNOW_CLIENT_SECRET'))
|
|
2392
|
-
.replace(/{{SNOW_FLOW_ENV}}/g, getEnvValue('SNOW_FLOW_ENV', 'development'));
|
|
2393
|
-
const claudeConfig = JSON.parse(mcpConfigContent);
|
|
2394
|
-
// Convert Claude Desktop format to SnowCode format
|
|
2395
|
-
const snowcodeConfig = convertToSnowCodeFormat(claudeConfig);
|
|
2396
|
-
// Write snow-code.json (SnowCode searches for this name!)
|
|
2397
|
-
// ✅ PROJECT-SCOPED: Only write to project .snow-code/ directory
|
|
2398
|
-
const snowCodeJsonPath = (0, path_1.join)(snowcodeDir, 'snow-code.json');
|
|
2399
|
-
const configJsonPath = (0, path_1.join)(snowcodeDir, 'config.json');
|
|
2400
|
-
await fs_1.promises.writeFile(snowCodeJsonPath, JSON.stringify(snowcodeConfig, null, 2));
|
|
2401
|
-
await fs_1.promises.writeFile(configJsonPath, JSON.stringify(snowcodeConfig, null, 2));
|
|
2402
|
-
// ❌ REMOVED: Global config write
|
|
2403
|
-
// We do NOT write to ~/.config/snow-code/ anymore
|
|
2404
|
-
// Each snow-flow project maintains its own isolated SnowCode configuration
|
|
2405
|
-
// SnowCode will automatically discover and use the project-level .snow-code/ config
|
|
2406
|
-
// Also create AGENTS.md in .snow-code/
|
|
2407
|
-
const snowcodeAgentsMdPath = (0, path_1.join)(snowcodeDir, 'AGENTS.md');
|
|
2408
|
-
await fs_1.promises.writeFile(snowcodeAgentsMdPath, agentsMdContent);
|
|
2409
2231
|
}
|
|
2410
2232
|
catch (error) {
|
|
2411
2233
|
// Silent error handling
|
|
2412
2234
|
}
|
|
2235
|
+
function getEnvValue(key, defaultValue = '') {
|
|
2236
|
+
var value = envValues[key] || process.env[key] || defaultValue;
|
|
2237
|
+
if (key === 'SNOW_INSTANCE' && value && !value.startsWith('http')) {
|
|
2238
|
+
value = 'https://' + value.replace(/^https?:\/\//, '');
|
|
2239
|
+
}
|
|
2240
|
+
return value;
|
|
2241
|
+
}
|
|
2242
|
+
const mcpTemplatePath = (0, path_1.join)(snowFlowRoot, '.mcp.json.template');
|
|
2243
|
+
let mcpTemplateContent;
|
|
2244
|
+
try {
|
|
2245
|
+
mcpTemplateContent = await fs_1.promises.readFile(mcpTemplatePath, 'utf-8');
|
|
2246
|
+
}
|
|
2247
|
+
catch (error) {
|
|
2248
|
+
throw error;
|
|
2249
|
+
}
|
|
2250
|
+
const mcpConfigContent = mcpTemplateContent
|
|
2251
|
+
.replace(/{{PROJECT_ROOT}}/g, snowFlowRoot)
|
|
2252
|
+
.replace(/{{SNOW_INSTANCE}}/g, getEnvValue('SNOW_INSTANCE'))
|
|
2253
|
+
.replace(/{{SNOW_CLIENT_ID}}/g, getEnvValue('SNOW_CLIENT_ID'))
|
|
2254
|
+
.replace(/{{SNOW_CLIENT_SECRET}}/g, getEnvValue('SNOW_CLIENT_SECRET'))
|
|
2255
|
+
.replace(/{{SNOW_FLOW_ENV}}/g, getEnvValue('SNOW_FLOW_ENV', 'development'));
|
|
2256
|
+
const mcpConfig = JSON.parse(mcpConfigContent);
|
|
2257
|
+
const snowcodeConfig = convertToSnowCodeFormat(mcpConfig);
|
|
2258
|
+
// Write only config.json (snow-code reads this)
|
|
2259
|
+
const configJsonPath = (0, path_1.join)(snowcodeDir, 'config.json');
|
|
2260
|
+
await fs_1.promises.writeFile(configJsonPath, JSON.stringify(snowcodeConfig, null, 2));
|
|
2413
2261
|
}
|
|
2414
2262
|
catch (error) {
|
|
2415
|
-
//
|
|
2416
|
-
// Import the template as fallback
|
|
2263
|
+
// Fallback: create minimal AGENTS.md
|
|
2417
2264
|
const { CLAUDE_MD_TEMPLATE } = await Promise.resolve().then(() => __importStar(require('./templates/claude-md-template.js')));
|
|
2418
|
-
const claudeMdPath = (0, path_1.join)(targetDir, 'CLAUDE.md');
|
|
2419
2265
|
const agentsMdPath = (0, path_1.join)(targetDir, 'AGENTS.md');
|
|
2420
|
-
if (force || !(0, fs_2.existsSync)(claudeMdPath)) {
|
|
2421
|
-
await fs_1.promises.writeFile(claudeMdPath, CLAUDE_MD_TEMPLATE);
|
|
2422
|
-
}
|
|
2423
|
-
// Use same content for AGENTS.md (they should be identical)
|
|
2424
2266
|
if (force || !(0, fs_2.existsSync)(agentsMdPath)) {
|
|
2425
2267
|
await fs_1.promises.writeFile(agentsMdPath, CLAUDE_MD_TEMPLATE);
|
|
2426
2268
|
}
|
|
@@ -2524,7 +2366,7 @@ async function appendToEnvFile(targetDir, content) {
|
|
|
2524
2366
|
}
|
|
2525
2367
|
/**
|
|
2526
2368
|
* Converts Claude Desktop MCP config format to SnowCode/OpenCode format
|
|
2527
|
-
* Single source of truth: .mcp.json.template → both .mcp.json and .snow-code/
|
|
2369
|
+
* Single source of truth: .mcp.json.template → both .mcp.json and .snow-code/config.json
|
|
2528
2370
|
*/
|
|
2529
2371
|
function convertToSnowCodeFormat(claudeConfig) {
|
|
2530
2372
|
const snowcodeConfig = {
|
|
@@ -2670,7 +2512,7 @@ async function createMCPConfig(targetDir, force = false) {
|
|
|
2670
2512
|
// Keep the standard MCP structure that snow-code expects
|
|
2671
2513
|
// Use the snow-code MCP structure directly from template (mcp key)
|
|
2672
2514
|
const finalConfig = mcpConfig;
|
|
2673
|
-
// Create .mcp.json in project root
|
|
2515
|
+
// Create .mcp.json in project root (snow-code reads this directly)
|
|
2674
2516
|
const mcpConfigPath = (0, path_1.join)(targetDir, '.mcp.json');
|
|
2675
2517
|
try {
|
|
2676
2518
|
await fs_1.promises.access(mcpConfigPath);
|
|
@@ -2685,13 +2527,10 @@ async function createMCPConfig(targetDir, force = false) {
|
|
|
2685
2527
|
catch {
|
|
2686
2528
|
await fs_1.promises.writeFile(mcpConfigPath, JSON.stringify(finalConfig, null, 2));
|
|
2687
2529
|
}
|
|
2688
|
-
//
|
|
2689
|
-
const legacyConfigPath = (0, path_1.join)(targetDir, '.claude/mcp-config.json');
|
|
2690
|
-
await fs_1.promises.writeFile(legacyConfigPath, JSON.stringify(finalConfig, null, 2));
|
|
2530
|
+
// .claude/mcp-config.json removed - snow-code is the only supported client
|
|
2691
2531
|
// ✅ PROJECT-SCOPED MCP CONFIG ONLY
|
|
2692
|
-
// We do NOT modify global Snow-Code config (~/.snow-code/snow-code.json)
|
|
2693
2532
|
// Each project maintains its own isolated MCP configuration in .mcp.json
|
|
2694
|
-
//
|
|
2533
|
+
// snow-code automatically discovers and uses the project-level .mcp.json
|
|
2695
2534
|
// Create comprehensive Claude Code settings file
|
|
2696
2535
|
// NOTE: Only include properties that Claude Code actually accepts
|
|
2697
2536
|
// Valid properties: apiKeyHelper, cleanupPeriodDays, env, includeCoAuthoredBy,
|
|
@@ -2889,8 +2728,10 @@ async function createMCPConfig(targetDir, force = false) {
|
|
|
2889
2728
|
// Snow-Flow v3.5.13+ optimized settings with servicenow-local-development
|
|
2890
2729
|
// Comprehensive permissions for Snow-Flow development workflow
|
|
2891
2730
|
};
|
|
2892
|
-
|
|
2893
|
-
|
|
2731
|
+
// .claude/settings.json removed - snow-code doesn't use this format
|
|
2732
|
+
// snow-code uses .snow-code/config.json for all configuration
|
|
2733
|
+
// Keeping claudeSettings object for potential future snow-code config migration
|
|
2734
|
+
void claudeSettings; // Suppress unused variable warning
|
|
2894
2735
|
}
|
|
2895
2736
|
// Setup MCP configuration function
|
|
2896
2737
|
async function setupMCPConfig(targetDir, instanceUrl, clientId, clientSecret, force = false) {
|
|
@@ -3054,13 +2895,10 @@ async function setupMCPConfig(targetDir, instanceUrl, clientId, clientSecret, fo
|
|
|
3054
2895
|
catch {
|
|
3055
2896
|
await fs_1.promises.writeFile(mcpConfigPath, JSON.stringify(finalConfig, null, 2));
|
|
3056
2897
|
}
|
|
3057
|
-
//
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
// SnowCode/OpenCode reads from ~/.snowcode/snowcode.json
|
|
3062
|
-
const snowcodeConfigPath = (0, path_1.join)(process.env.HOME || '', '.snow-code', 'snow-code.json');
|
|
3063
|
-
const snowcodeConfigDirPath = (0, path_1.join)(process.env.HOME || '', '.snow-code');
|
|
2898
|
+
// .claude/mcp-config.json removed - snow-code is the only supported client
|
|
2899
|
+
// Update project-level .snow-code/config.json
|
|
2900
|
+
const snowcodeConfigPath = (0, path_1.join)(targetDir, '.snow-code', 'config.json');
|
|
2901
|
+
const snowcodeConfigDirPath = (0, path_1.join)(targetDir, '.snow-code');
|
|
3064
2902
|
try {
|
|
3065
2903
|
// Ensure directory exists
|
|
3066
2904
|
try {
|
|
@@ -3157,7 +2995,7 @@ async function setupMCPConfig(targetDir, instanceUrl, clientId, clientSecret, fo
|
|
|
3157
2995
|
prompts.log.message(` Servers: ${Object.keys(snowcodeConfig.mcp).join(', ')}`);
|
|
3158
2996
|
// 🔥 ALSO write LOCAL config (takes priority!)
|
|
3159
2997
|
const localSnowcodeDir = (0, path_1.join)(targetDir, '.snow-code');
|
|
3160
|
-
const localSnowcodePath = (0, path_1.join)(localSnowcodeDir, '
|
|
2998
|
+
const localSnowcodePath = (0, path_1.join)(localSnowcodeDir, 'config.json');
|
|
3161
2999
|
try {
|
|
3162
3000
|
// Ensure local .snow-code directory exists
|
|
3163
3001
|
await fs_1.promises.mkdir(localSnowcodeDir, { recursive: true });
|