@lousy-agents/cli 2.5.3 → 2.6.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/api/copilot-with-fastify/.vscode/mcp.json +1 -1
- package/cli/copilot-with-citty/.vscode/mcp.json +1 -1
- package/dist/index.js +199 -362
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +497 -0
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
- package/ui/copilot-with-react/.github/workflows/ci.yml +67 -0
- package/ui/copilot-with-react/.vscode/mcp.json +19 -0
- package/ui/copilot-with-react/{biome.json → biome.template.json} +1 -1
- package/ui/copilot-with-react/gitignore.template +5 -0
package/dist/mcp-server.js
CHANGED
|
@@ -42587,6 +42587,60 @@ var yaml_dist = __webpack_require__(1198);
|
|
|
42587
42587
|
return new FileSystemAgentFileGateway();
|
|
42588
42588
|
}
|
|
42589
42589
|
|
|
42590
|
+
;// CONCATENATED MODULE: ./src/gateways/claude-file-gateway.ts
|
|
42591
|
+
/**
|
|
42592
|
+
* Gateway interface for Claude Code file operations.
|
|
42593
|
+
* Handles reading and writing .claude/settings.json and CLAUDE.md files.
|
|
42594
|
+
*/
|
|
42595
|
+
|
|
42596
|
+
|
|
42597
|
+
/**
|
|
42598
|
+
* File system implementation of ClaudeFileGateway
|
|
42599
|
+
*/ class FileSystemClaudeFileGateway {
|
|
42600
|
+
async readSettings(targetDir) {
|
|
42601
|
+
const settingsPath = (0,external_node_path_.join)(targetDir, ".claude", "settings.json");
|
|
42602
|
+
if (!await file_system_utils_fileExists(settingsPath)) {
|
|
42603
|
+
return null;
|
|
42604
|
+
}
|
|
42605
|
+
try {
|
|
42606
|
+
const content = await (0,promises_.readFile)(settingsPath, "utf-8");
|
|
42607
|
+
return JSON.parse(content);
|
|
42608
|
+
} catch {
|
|
42609
|
+
// If JSON parsing fails, treat as if file doesn't exist
|
|
42610
|
+
return null;
|
|
42611
|
+
}
|
|
42612
|
+
}
|
|
42613
|
+
async writeSettings(targetDir, settings) {
|
|
42614
|
+
const claudeDir = (0,external_node_path_.join)(targetDir, ".claude");
|
|
42615
|
+
const settingsPath = (0,external_node_path_.join)(claudeDir, "settings.json");
|
|
42616
|
+
// Ensure .claude directory exists
|
|
42617
|
+
await (0,promises_.mkdir)(claudeDir, {
|
|
42618
|
+
recursive: true
|
|
42619
|
+
});
|
|
42620
|
+
// Write with 2-space indentation and trailing newline
|
|
42621
|
+
const content = `${JSON.stringify(settings, null, 2)}\n`;
|
|
42622
|
+
await (0,promises_.writeFile)(settingsPath, content, "utf-8");
|
|
42623
|
+
}
|
|
42624
|
+
async readDocumentation(targetDir) {
|
|
42625
|
+
const docPath = (0,external_node_path_.join)(targetDir, "CLAUDE.md");
|
|
42626
|
+
if (!await file_system_utils_fileExists(docPath)) {
|
|
42627
|
+
return null;
|
|
42628
|
+
}
|
|
42629
|
+
return (0,promises_.readFile)(docPath, "utf-8");
|
|
42630
|
+
}
|
|
42631
|
+
async writeDocumentation(targetDir, content) {
|
|
42632
|
+
const docPath = (0,external_node_path_.join)(targetDir, "CLAUDE.md");
|
|
42633
|
+
// Ensure content has trailing newline
|
|
42634
|
+
const normalizedContent = content.endsWith("\n") ? content : `${content}\n`;
|
|
42635
|
+
await (0,promises_.writeFile)(docPath, normalizedContent, "utf-8");
|
|
42636
|
+
}
|
|
42637
|
+
}
|
|
42638
|
+
/**
|
|
42639
|
+
* Factory function to create a Claude file gateway
|
|
42640
|
+
*/ function createClaudeFileGateway() {
|
|
42641
|
+
return new FileSystemClaudeFileGateway();
|
|
42642
|
+
}
|
|
42643
|
+
|
|
42590
42644
|
;// CONCATENATED MODULE: ./src/entities/copilot-setup.ts
|
|
42591
42645
|
/**
|
|
42592
42646
|
* Core domain entities for the Copilot Setup Steps feature.
|
|
@@ -45979,6 +46033,7 @@ async function watchConfig(options) {
|
|
|
45979
46033
|
|
|
45980
46034
|
|
|
45981
46035
|
|
|
46036
|
+
|
|
45982
46037
|
;// CONCATENATED MODULE: ./src/mcp/tools/types.ts
|
|
45983
46038
|
/**
|
|
45984
46039
|
* Shared types and utilities for MCP tool handlers.
|
|
@@ -46091,6 +46146,441 @@ async function watchConfig(options) {
|
|
|
46091
46146
|
});
|
|
46092
46147
|
};
|
|
46093
46148
|
|
|
46149
|
+
;// CONCATENATED MODULE: ./src/use-cases/claude-setup.ts
|
|
46150
|
+
/**
|
|
46151
|
+
* Use cases for Claude Code Web Environment Setup feature.
|
|
46152
|
+
* This module handles the logic of building SessionStart hooks from environment detection,
|
|
46153
|
+
* merging settings, and generating documentation.
|
|
46154
|
+
*/
|
|
46155
|
+
/**
|
|
46156
|
+
* List of allowed version filenames.
|
|
46157
|
+
* Using a hardcoded allowlist prevents command injection via malicious filenames
|
|
46158
|
+
* in user-customizable config files.
|
|
46159
|
+
*/ const ALLOWED_VERSION_FILENAMES = [
|
|
46160
|
+
".nvmrc",
|
|
46161
|
+
".node-version",
|
|
46162
|
+
".python-version",
|
|
46163
|
+
".java-version",
|
|
46164
|
+
".ruby-version",
|
|
46165
|
+
".go-version"
|
|
46166
|
+
];
|
|
46167
|
+
/**
|
|
46168
|
+
* Validates that a filename is in the allowlist of known version files.
|
|
46169
|
+
* Prevents command injection by only allowing hardcoded safe filenames.
|
|
46170
|
+
*
|
|
46171
|
+
* @param filename The filename to validate
|
|
46172
|
+
* @returns true if filename is in the allowlist
|
|
46173
|
+
*/ function isValidVersionFilename(filename) {
|
|
46174
|
+
return ALLOWED_VERSION_FILENAMES.includes(filename);
|
|
46175
|
+
}
|
|
46176
|
+
/**
|
|
46177
|
+
* Builds SessionStart hooks from detected environment.
|
|
46178
|
+
* Transforms environment configuration into Claude Code SessionStart commands.
|
|
46179
|
+
*
|
|
46180
|
+
* @param environment The detected environment configuration
|
|
46181
|
+
* @param config Optional copilot-setup configuration (for package manager mappings)
|
|
46182
|
+
* @returns Array of SessionStart hooks
|
|
46183
|
+
*/ async function buildSessionStartHooks(environment, config) {
|
|
46184
|
+
const loadedConfig = config || await loadCopilotSetupConfig();
|
|
46185
|
+
const hooks = [];
|
|
46186
|
+
// If mise.toml is present, add mise install
|
|
46187
|
+
if (environment.hasMise) {
|
|
46188
|
+
hooks.push({
|
|
46189
|
+
command: "mise install",
|
|
46190
|
+
description: "Install runtimes from mise.toml"
|
|
46191
|
+
});
|
|
46192
|
+
// After mise install, add package manager install hooks
|
|
46193
|
+
const packageManagerHooks = buildPackageManagerHooks(environment.packageManagers, loadedConfig);
|
|
46194
|
+
hooks.push(...packageManagerHooks);
|
|
46195
|
+
return hooks;
|
|
46196
|
+
}
|
|
46197
|
+
// Otherwise, add runtime installation hooks for each version file
|
|
46198
|
+
const runtimeHooks = buildRuntimeHooks(environment.versionFiles);
|
|
46199
|
+
hooks.push(...runtimeHooks);
|
|
46200
|
+
// Add package manager install hooks
|
|
46201
|
+
const packageManagerHooks = buildPackageManagerHooks(environment.packageManagers, loadedConfig);
|
|
46202
|
+
hooks.push(...packageManagerHooks);
|
|
46203
|
+
return hooks;
|
|
46204
|
+
}
|
|
46205
|
+
/**
|
|
46206
|
+
* Builds runtime installation hooks from version files.
|
|
46207
|
+
* Maps version files to appropriate runtime manager commands (nvm, pyenv, etc.)
|
|
46208
|
+
*
|
|
46209
|
+
* @param versionFiles Array of detected version files
|
|
46210
|
+
* @returns Array of runtime installation hooks
|
|
46211
|
+
*/ function buildRuntimeHooks(versionFiles) {
|
|
46212
|
+
const hooks = [];
|
|
46213
|
+
const addedTypes = new Set();
|
|
46214
|
+
for (const versionFile of versionFiles){
|
|
46215
|
+
// Deduplicate by type (e.g., .nvmrc and .node-version both use nvm)
|
|
46216
|
+
if (addedTypes.has(versionFile.type)) {
|
|
46217
|
+
continue;
|
|
46218
|
+
}
|
|
46219
|
+
addedTypes.add(versionFile.type);
|
|
46220
|
+
const hook = getRuntimeHookForType(versionFile.type, versionFile);
|
|
46221
|
+
if (hook) {
|
|
46222
|
+
hooks.push(hook);
|
|
46223
|
+
}
|
|
46224
|
+
}
|
|
46225
|
+
return hooks;
|
|
46226
|
+
}
|
|
46227
|
+
/**
|
|
46228
|
+
* Gets the runtime installation hook for a specific version file type.
|
|
46229
|
+
*
|
|
46230
|
+
* @param type The version file type
|
|
46231
|
+
* @param versionFile The version file metadata
|
|
46232
|
+
* @returns SessionStart hook or null if not supported
|
|
46233
|
+
*/ function getRuntimeHookForType(type, versionFile) {
|
|
46234
|
+
const versionInfo = versionFile.version ? ` (${versionFile.version})` : "";
|
|
46235
|
+
if (!isValidVersionFilename(versionFile.filename)) {
|
|
46236
|
+
return null;
|
|
46237
|
+
}
|
|
46238
|
+
switch(type){
|
|
46239
|
+
case "node":
|
|
46240
|
+
return {
|
|
46241
|
+
command: "nvm install",
|
|
46242
|
+
description: `Install Node.js from ${versionFile.filename}${versionInfo}`
|
|
46243
|
+
};
|
|
46244
|
+
case "python":
|
|
46245
|
+
return {
|
|
46246
|
+
command: `pyenv install -s $(cat ${versionFile.filename})`,
|
|
46247
|
+
description: `Install Python from ${versionFile.filename}${versionInfo}`
|
|
46248
|
+
};
|
|
46249
|
+
case "ruby":
|
|
46250
|
+
return {
|
|
46251
|
+
command: `rbenv install -s $(cat ${versionFile.filename})`,
|
|
46252
|
+
description: `Install Ruby from ${versionFile.filename}${versionInfo}`
|
|
46253
|
+
};
|
|
46254
|
+
case "java":
|
|
46255
|
+
return null;
|
|
46256
|
+
case "go":
|
|
46257
|
+
// Go version management typically handled by asdf or gvm
|
|
46258
|
+
// For now, document but don't generate command as it's environment-specific
|
|
46259
|
+
return null;
|
|
46260
|
+
default:
|
|
46261
|
+
return null;
|
|
46262
|
+
}
|
|
46263
|
+
}
|
|
46264
|
+
/**
|
|
46265
|
+
* Builds package manager installation hooks from detected package managers.
|
|
46266
|
+
*
|
|
46267
|
+
* @param packageManagers Array of detected package managers
|
|
46268
|
+
* @param config Configuration for package manager mappings
|
|
46269
|
+
* @returns Array of package manager installation hooks
|
|
46270
|
+
*/ function buildPackageManagerHooks(packageManagers, config) {
|
|
46271
|
+
const hooks = [];
|
|
46272
|
+
const addedTypes = new Set();
|
|
46273
|
+
for (const pm of packageManagers){
|
|
46274
|
+
// Skip if we've already added this package manager type
|
|
46275
|
+
if (addedTypes.has(pm.type)) {
|
|
46276
|
+
continue;
|
|
46277
|
+
}
|
|
46278
|
+
addedTypes.add(pm.type);
|
|
46279
|
+
// Find the config for this package manager
|
|
46280
|
+
const pmConfig = config.packageManagers.find((c)=>c.type === pm.type);
|
|
46281
|
+
if (!pmConfig) {
|
|
46282
|
+
continue;
|
|
46283
|
+
}
|
|
46284
|
+
const description = getPackageManagerDescription(pm.type, pm);
|
|
46285
|
+
hooks.push({
|
|
46286
|
+
command: pmConfig.installCommand,
|
|
46287
|
+
description
|
|
46288
|
+
});
|
|
46289
|
+
}
|
|
46290
|
+
return hooks;
|
|
46291
|
+
}
|
|
46292
|
+
/**
|
|
46293
|
+
* Gets a description for a package manager hook.
|
|
46294
|
+
*/ function getPackageManagerDescription(packageManagerType, pm) {
|
|
46295
|
+
const lockfileInfo = pm.lockfile ? ` with ${pm.lockfile}` : "";
|
|
46296
|
+
const descriptions = {
|
|
46297
|
+
npm: `Install Node.js dependencies${lockfileInfo}`,
|
|
46298
|
+
yarn: `Install Node.js dependencies${lockfileInfo}`,
|
|
46299
|
+
pnpm: `Install Node.js dependencies${lockfileInfo}`,
|
|
46300
|
+
pip: `Install Python dependencies from ${pm.filename}`,
|
|
46301
|
+
pipenv: `Install Python dependencies${lockfileInfo}`,
|
|
46302
|
+
poetry: `Install Python dependencies${lockfileInfo}`,
|
|
46303
|
+
bundler: `Install Ruby dependencies${lockfileInfo}`,
|
|
46304
|
+
cargo: `Build Rust project`,
|
|
46305
|
+
composer: `Install PHP dependencies${lockfileInfo}`,
|
|
46306
|
+
maven: `Install Java dependencies`,
|
|
46307
|
+
gradle: `Build Gradle project`,
|
|
46308
|
+
gomod: `Download Go dependencies`,
|
|
46309
|
+
pub: `Install Dart dependencies`
|
|
46310
|
+
};
|
|
46311
|
+
return descriptions[packageManagerType] || `Install dependencies from ${pm.filename}`;
|
|
46312
|
+
}
|
|
46313
|
+
/**
|
|
46314
|
+
* Merges SessionStart hooks into existing Claude settings.
|
|
46315
|
+
* Preserves existing settings while adding or updating hooks without duplication.
|
|
46316
|
+
*
|
|
46317
|
+
* @param existing Existing Claude settings or null if none exist
|
|
46318
|
+
* @param hooks Array of SessionStart hooks to merge
|
|
46319
|
+
* @returns Merged Claude settings
|
|
46320
|
+
*/ function mergeClaudeSettings(existing, hooks) {
|
|
46321
|
+
// If no existing settings, create new with hooks
|
|
46322
|
+
if (!existing) {
|
|
46323
|
+
return {
|
|
46324
|
+
// biome-ignore lint/style/useNamingConvention: SessionStart is the Claude Code API property name
|
|
46325
|
+
SessionStart: hooks.map((h)=>h.command)
|
|
46326
|
+
};
|
|
46327
|
+
}
|
|
46328
|
+
// Preserve all existing settings
|
|
46329
|
+
const merged = {
|
|
46330
|
+
...existing
|
|
46331
|
+
};
|
|
46332
|
+
// Get existing SessionStart commands or empty array
|
|
46333
|
+
const existingCommands = existing.SessionStart || [];
|
|
46334
|
+
// Merge new hooks with existing commands in deterministic order:
|
|
46335
|
+
// 1) tool-generated commands (from hooks) in their original order
|
|
46336
|
+
// 2) any existing commands not already included, preserving their order
|
|
46337
|
+
const newCommands = hooks.map((h)=>h.command);
|
|
46338
|
+
const mergedCommands = [];
|
|
46339
|
+
for (const command of newCommands){
|
|
46340
|
+
if (!mergedCommands.includes(command)) {
|
|
46341
|
+
mergedCommands.push(command);
|
|
46342
|
+
}
|
|
46343
|
+
}
|
|
46344
|
+
for (const command of existingCommands){
|
|
46345
|
+
if (!mergedCommands.includes(command)) {
|
|
46346
|
+
mergedCommands.push(command);
|
|
46347
|
+
}
|
|
46348
|
+
}
|
|
46349
|
+
merged.SessionStart = mergedCommands;
|
|
46350
|
+
return merged;
|
|
46351
|
+
}
|
|
46352
|
+
/**
|
|
46353
|
+
* Generates an Environment Setup section for CLAUDE.md documentation.
|
|
46354
|
+
* Creates markdown documenting the detected environment and SessionStart hooks.
|
|
46355
|
+
*
|
|
46356
|
+
* @param environment The detected environment configuration
|
|
46357
|
+
* @param hooks Array of SessionStart hooks
|
|
46358
|
+
* @returns Markdown content for Environment Setup section
|
|
46359
|
+
*/ function generateEnvironmentSetupSection(environment, hooks) {
|
|
46360
|
+
const lines = [];
|
|
46361
|
+
lines.push("## Environment Setup");
|
|
46362
|
+
lines.push("");
|
|
46363
|
+
// Document detected configuration
|
|
46364
|
+
if (environment.hasMise) {
|
|
46365
|
+
lines.push("This project uses [mise](https://mise.jdx.dev/) for runtime management.");
|
|
46366
|
+
lines.push("");
|
|
46367
|
+
}
|
|
46368
|
+
if (environment.versionFiles.length > 0) {
|
|
46369
|
+
lines.push("### Detected Runtimes");
|
|
46370
|
+
lines.push("");
|
|
46371
|
+
for (const vf of environment.versionFiles){
|
|
46372
|
+
const versionInfo = vf.version ? ` (${vf.version})` : "";
|
|
46373
|
+
lines.push(`- **${vf.type}**: ${vf.filename}${versionInfo}`);
|
|
46374
|
+
}
|
|
46375
|
+
lines.push("");
|
|
46376
|
+
}
|
|
46377
|
+
if (environment.packageManagers.length > 0) {
|
|
46378
|
+
lines.push("### Package Managers");
|
|
46379
|
+
lines.push("");
|
|
46380
|
+
for (const pm of environment.packageManagers){
|
|
46381
|
+
const lockfileInfo = pm.lockfile ? ` with ${pm.lockfile}` : "";
|
|
46382
|
+
lines.push(`- **${pm.type}**: ${pm.filename}${lockfileInfo}`);
|
|
46383
|
+
}
|
|
46384
|
+
lines.push("");
|
|
46385
|
+
}
|
|
46386
|
+
// Document SessionStart hooks
|
|
46387
|
+
if (hooks.length > 0) {
|
|
46388
|
+
lines.push("### SessionStart Hooks");
|
|
46389
|
+
lines.push("");
|
|
46390
|
+
lines.push("The following commands run automatically when a Claude Code session starts:");
|
|
46391
|
+
lines.push("");
|
|
46392
|
+
for (const hook of hooks){
|
|
46393
|
+
lines.push("```bash");
|
|
46394
|
+
lines.push(hook.command);
|
|
46395
|
+
lines.push("```");
|
|
46396
|
+
if (hook.description) {
|
|
46397
|
+
lines.push(`*${hook.description}*`);
|
|
46398
|
+
}
|
|
46399
|
+
lines.push("");
|
|
46400
|
+
}
|
|
46401
|
+
} else {
|
|
46402
|
+
lines.push("No environment-specific configuration detected. If this project requires specific runtimes or dependencies, add version files (e.g., `.nvmrc`, `.python-version`) or dependency manifests (e.g., `package.json`, `requirements.txt`) to enable automated setup.");
|
|
46403
|
+
lines.push("");
|
|
46404
|
+
}
|
|
46405
|
+
return lines.join("\n");
|
|
46406
|
+
}
|
|
46407
|
+
/**
|
|
46408
|
+
* Merges an Environment Setup section into existing CLAUDE.md documentation.
|
|
46409
|
+
* Replaces existing section if found, or appends if not present.
|
|
46410
|
+
*
|
|
46411
|
+
* @param existing Existing CLAUDE.md content or null if file doesn't exist
|
|
46412
|
+
* @param setupSection The Environment Setup section content
|
|
46413
|
+
* @returns Updated CLAUDE.md content
|
|
46414
|
+
*/ function mergeClaudeDocumentation(existing, setupSection) {
|
|
46415
|
+
// If no existing documentation, create new with setup section
|
|
46416
|
+
if (!existing) {
|
|
46417
|
+
return `# Claude Code Environment\n\n${setupSection}`;
|
|
46418
|
+
}
|
|
46419
|
+
// Split content into lines and find Environment Setup section
|
|
46420
|
+
const lines = existing.split("\n");
|
|
46421
|
+
let inEnvSetup = false;
|
|
46422
|
+
let envSetupStartLine = -1;
|
|
46423
|
+
let envSetupEndLine = -1;
|
|
46424
|
+
for(let i = 0; i < lines.length; i++){
|
|
46425
|
+
const line = lines[i];
|
|
46426
|
+
if (line === "## Environment Setup") {
|
|
46427
|
+
inEnvSetup = true;
|
|
46428
|
+
envSetupStartLine = i;
|
|
46429
|
+
continue;
|
|
46430
|
+
}
|
|
46431
|
+
if (inEnvSetup && (line.startsWith("## ") || line.startsWith("# "))) {
|
|
46432
|
+
// Found next section
|
|
46433
|
+
envSetupEndLine = i;
|
|
46434
|
+
break;
|
|
46435
|
+
}
|
|
46436
|
+
}
|
|
46437
|
+
// If we found Environment Setup section
|
|
46438
|
+
if (envSetupStartLine >= 0) {
|
|
46439
|
+
// If we didn't find an end, it goes to the end of file
|
|
46440
|
+
if (envSetupEndLine === -1) {
|
|
46441
|
+
envSetupEndLine = lines.length;
|
|
46442
|
+
}
|
|
46443
|
+
// Replace the section
|
|
46444
|
+
const before = lines.slice(0, envSetupStartLine).join("\n");
|
|
46445
|
+
const after = lines.slice(envSetupEndLine).join("\n");
|
|
46446
|
+
const parts = [
|
|
46447
|
+
before.trimEnd()
|
|
46448
|
+
];
|
|
46449
|
+
if (before.trim()) {
|
|
46450
|
+
parts.push("\n\n");
|
|
46451
|
+
}
|
|
46452
|
+
parts.push(setupSection.trimEnd());
|
|
46453
|
+
if (after.trim()) {
|
|
46454
|
+
parts.push("\n\n");
|
|
46455
|
+
parts.push(after);
|
|
46456
|
+
}
|
|
46457
|
+
return parts.join("");
|
|
46458
|
+
}
|
|
46459
|
+
// Append section to end
|
|
46460
|
+
const trimmedExisting = existing.trimEnd();
|
|
46461
|
+
return `${trimmedExisting}\n\n${setupSection}`;
|
|
46462
|
+
}
|
|
46463
|
+
|
|
46464
|
+
;// CONCATENATED MODULE: ./src/mcp/tools/create-claude-code-web-setup.ts
|
|
46465
|
+
/**
|
|
46466
|
+
* MCP tool handler for creating or updating Claude Code Web Environment Setup.
|
|
46467
|
+
*/
|
|
46468
|
+
|
|
46469
|
+
|
|
46470
|
+
|
|
46471
|
+
/**
|
|
46472
|
+
* Creates or updates Claude Code web environment setup files.
|
|
46473
|
+
*/ const createClaudeCodeWebSetupHandler = async (args)=>{
|
|
46474
|
+
const dir = args.targetDir || process.cwd();
|
|
46475
|
+
if (!await file_system_utils_fileExists(dir)) {
|
|
46476
|
+
return types_errorResponse(`Target directory does not exist: ${dir}`);
|
|
46477
|
+
}
|
|
46478
|
+
const environmentGateway = createEnvironmentGateway();
|
|
46479
|
+
const claudeGateway = createClaudeFileGateway();
|
|
46480
|
+
// Detect environment configuration
|
|
46481
|
+
const environment = await environmentGateway.detectEnvironment(dir);
|
|
46482
|
+
// Build SessionStart hooks from environment
|
|
46483
|
+
const hooks = await buildSessionStartHooks(environment);
|
|
46484
|
+
// Read existing settings
|
|
46485
|
+
const existingSettings = await claudeGateway.readSettings(dir);
|
|
46486
|
+
// Merge settings
|
|
46487
|
+
const mergedSettings = mergeClaudeSettings(existingSettings, hooks);
|
|
46488
|
+
// Check if settings changed (normalize JSON for comparison)
|
|
46489
|
+
const settingsChanged = JSON.stringify(existingSettings, null, 2) !== JSON.stringify(mergedSettings, null, 2);
|
|
46490
|
+
// Read existing documentation
|
|
46491
|
+
const existingDocs = await claudeGateway.readDocumentation(dir);
|
|
46492
|
+
// Generate environment setup section
|
|
46493
|
+
const setupSection = generateEnvironmentSetupSection(environment, hooks);
|
|
46494
|
+
// Merge documentation
|
|
46495
|
+
const mergedDocs = mergeClaudeDocumentation(existingDocs, setupSection);
|
|
46496
|
+
// Check if documentation changed (normalize for comparison - trim and ensure trailing newline)
|
|
46497
|
+
const normalizeDoc = (doc)=>doc ? `${doc.trimEnd()}\n` : null;
|
|
46498
|
+
const docsChanged = normalizeDoc(existingDocs) !== normalizeDoc(mergedDocs);
|
|
46499
|
+
// Determine action before writing
|
|
46500
|
+
let action;
|
|
46501
|
+
if (!settingsChanged && !docsChanged) {
|
|
46502
|
+
action = "no_changes_needed";
|
|
46503
|
+
} else if (!existingSettings && !existingDocs) {
|
|
46504
|
+
action = "created";
|
|
46505
|
+
} else {
|
|
46506
|
+
action = "updated";
|
|
46507
|
+
}
|
|
46508
|
+
// Only write if there are changes
|
|
46509
|
+
if (settingsChanged) {
|
|
46510
|
+
await claudeGateway.writeSettings(dir, mergedSettings);
|
|
46511
|
+
}
|
|
46512
|
+
if (docsChanged) {
|
|
46513
|
+
await claudeGateway.writeDocumentation(dir, mergedDocs);
|
|
46514
|
+
}
|
|
46515
|
+
const settingsPath = (0,external_node_path_.join)(dir, ".claude", "settings.json");
|
|
46516
|
+
const documentationPath = (0,external_node_path_.join)(dir, "CLAUDE.md");
|
|
46517
|
+
// Build result
|
|
46518
|
+
const result = {
|
|
46519
|
+
hooks,
|
|
46520
|
+
environment,
|
|
46521
|
+
settingsPath,
|
|
46522
|
+
documentationPath,
|
|
46523
|
+
action,
|
|
46524
|
+
recommendations: buildRecommendations(environment)
|
|
46525
|
+
};
|
|
46526
|
+
// Format message
|
|
46527
|
+
const message = buildResultMessage(result);
|
|
46528
|
+
return successResponse({
|
|
46529
|
+
...result,
|
|
46530
|
+
message,
|
|
46531
|
+
// Make hooks serializable for JSON response
|
|
46532
|
+
hooks: hooks.map((h)=>({
|
|
46533
|
+
command: h.command,
|
|
46534
|
+
description: h.description
|
|
46535
|
+
}))
|
|
46536
|
+
});
|
|
46537
|
+
};
|
|
46538
|
+
/**
|
|
46539
|
+
* Builds recommendations for UI-level environment configuration.
|
|
46540
|
+
*/ function buildRecommendations(environment) {
|
|
46541
|
+
const recommendations = [];
|
|
46542
|
+
// If package managers detected, recommend network access
|
|
46543
|
+
if (environment.packageManagers && environment.packageManagers.length > 0) {
|
|
46544
|
+
recommendations.push({
|
|
46545
|
+
type: "network_access",
|
|
46546
|
+
description: "Enable internet access in Claude Code environment settings to allow package installation"
|
|
46547
|
+
});
|
|
46548
|
+
}
|
|
46549
|
+
return recommendations.length > 0 ? recommendations : undefined;
|
|
46550
|
+
}
|
|
46551
|
+
/**
|
|
46552
|
+
* Builds a human-readable result message.
|
|
46553
|
+
*/ function buildResultMessage(result) {
|
|
46554
|
+
const lines = [];
|
|
46555
|
+
if (result.action === "created") {
|
|
46556
|
+
lines.push(`Created Claude Code environment setup with ${result.hooks.length} SessionStart hook(s)`);
|
|
46557
|
+
} else if (result.action === "updated") {
|
|
46558
|
+
lines.push(`Updated Claude Code environment setup with ${result.hooks.length} SessionStart hook(s)`);
|
|
46559
|
+
} else {
|
|
46560
|
+
lines.push("No changes needed - environment setup is already current");
|
|
46561
|
+
}
|
|
46562
|
+
if (result.hooks.length > 0) {
|
|
46563
|
+
lines.push("");
|
|
46564
|
+
lines.push("SessionStart hooks:");
|
|
46565
|
+
for (const hook of result.hooks){
|
|
46566
|
+
lines.push(` - ${hook.command}`);
|
|
46567
|
+
if (hook.description) {
|
|
46568
|
+
lines.push(` ${hook.description}`);
|
|
46569
|
+
}
|
|
46570
|
+
}
|
|
46571
|
+
}
|
|
46572
|
+
if (result.recommendations && result.recommendations.length > 0) {
|
|
46573
|
+
lines.push("");
|
|
46574
|
+
lines.push("Recommendations:");
|
|
46575
|
+
for (const rec of result.recommendations){
|
|
46576
|
+
lines.push(` - ${rec.description}`);
|
|
46577
|
+
}
|
|
46578
|
+
}
|
|
46579
|
+
lines.push("");
|
|
46580
|
+
lines.push(`Files: ${result.settingsPath}, ${result.documentationPath}`);
|
|
46581
|
+
return lines.join("\n");
|
|
46582
|
+
}
|
|
46583
|
+
|
|
46094
46584
|
;// CONCATENATED MODULE: ./src/use-cases/action-resolution.ts
|
|
46095
46585
|
/**
|
|
46096
46586
|
* Use case for building action resolution metadata.
|
|
@@ -47476,6 +47966,7 @@ function getGlobalWacContext() {
|
|
|
47476
47966
|
|
|
47477
47967
|
|
|
47478
47968
|
|
|
47969
|
+
|
|
47479
47970
|
;// CONCATENATED MODULE: ./src/mcp/server.ts
|
|
47480
47971
|
/**
|
|
47481
47972
|
* MCP Server for Copilot Setup Steps workflow management.
|
|
@@ -47551,6 +48042,12 @@ function getGlobalWacContext() {
|
|
|
47551
48042
|
handler: createCopilotSetupWorkflowHandler,
|
|
47552
48043
|
inputSchema: createWorkflowInputSchema
|
|
47553
48044
|
},
|
|
48045
|
+
{
|
|
48046
|
+
name: "create_claude_code_web_setup",
|
|
48047
|
+
description: "Create or update Claude Code web environment setup (.claude/settings.json with SessionStart hooks and CLAUDE.md documentation) based on detected environment configuration.",
|
|
48048
|
+
handler: createClaudeCodeWebSetupHandler,
|
|
48049
|
+
inputSchema: targetDirInputSchema
|
|
48050
|
+
},
|
|
47554
48051
|
{
|
|
47555
48052
|
name: "analyze_action_versions",
|
|
47556
48053
|
description: "Analyze GitHub Action versions used across all workflow files in a target directory",
|