claudes-office
Version:
CLI tool to initialize Claude's office in your project
226 lines • 8.03 kB
JavaScript
;
/**
* Project type detection utilities
* These utilities help detect the type of project in a directory
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectType = void 0;
exports.detectProjectType = detectProjectType;
exports.getTemplatesForProjectType = getTemplatesForProjectType;
// Using import syntax that works with glob v10+
const globModule = __importStar(require("glob"));
const glob = globModule.glob;
/**
* Project type enumeration
*/
var ProjectType;
(function (ProjectType) {
ProjectType["NODE"] = "node";
ProjectType["PYTHON"] = "python";
ProjectType["JAVA"] = "java";
ProjectType["GO"] = "go";
ProjectType["RUST"] = "rust";
ProjectType["RUBY"] = "ruby";
ProjectType["PHP"] = "php";
ProjectType["DOTNET"] = "dotnet";
ProjectType["UNKNOWN"] = "unknown";
})(ProjectType || (exports.ProjectType = ProjectType = {}));
/**
* Project type signatures for detection
*/
const PROJECT_SIGNATURES = [
{
type: ProjectType.NODE,
patterns: ['package.json', 'node_modules/'],
required: ['package.json'],
weight: 10
},
{
type: ProjectType.PYTHON,
patterns: ['requirements.txt', 'setup.py', 'pyproject.toml', '*.py', 'venv/', '.venv/'],
required: ['requirements.txt', 'setup.py', 'pyproject.toml', '*.py'],
weight: 8
},
{
type: ProjectType.JAVA,
patterns: ['pom.xml', 'build.gradle', 'build.gradle.kts', '.java', 'src/main/java/'],
required: ['pom.xml', 'build.gradle', 'build.gradle.kts', '*.java'],
weight: 7
},
{
type: ProjectType.GO,
patterns: ['go.mod', 'go.sum', '*.go'],
required: ['go.mod', '*.go'],
weight: 7
},
{
type: ProjectType.RUST,
patterns: ['Cargo.toml', 'Cargo.lock', '*.rs', 'src/main.rs', 'src/lib.rs'],
required: ['Cargo.toml', '*.rs'],
weight: 7
},
{
type: ProjectType.RUBY,
patterns: ['Gemfile', 'Gemfile.lock', '*.rb', 'config/application.rb'],
required: ['Gemfile', '*.rb'],
weight: 6
},
{
type: ProjectType.PHP,
patterns: ['composer.json', 'composer.lock', '*.php', 'vendor/'],
required: ['composer.json', '*.php'],
weight: 6
},
{
type: ProjectType.DOTNET,
patterns: ['*.csproj', '*.fsproj', '*.vbproj', '*.sln', 'Program.cs', 'Startup.cs'],
required: ['*.csproj', '*.fsproj', '*.vbproj', '*.sln'],
weight: 6
}
];
/**
* Detect the project type in a directory
* @param dirPath - Path to the directory
* @returns Detection result
*/
async function detectProjectType(dirPath) {
// Initialize result with unknown project type
const result = {
type: ProjectType.UNKNOWN,
confidence: 0,
details: {
matchedFiles: [],
info: 'No project type detected'
}
};
// Store detection results for each project type
const detections = [];
// Try each project signature
for (const signature of PROJECT_SIGNATURES) {
let matchedFiles = [];
let anyRequiredFound = false;
// Check for required files
if (signature.required) {
for (const pattern of signature.required) {
const matches = await findMatchingFiles(dirPath, pattern);
if (matches.length > 0) {
anyRequiredFound = true;
matchedFiles = [...matchedFiles, ...matches];
}
}
// Skip this signature if no required files were found
if (!anyRequiredFound) {
continue;
}
}
// Check for all pattern matches
for (const pattern of signature.patterns) {
const matches = await findMatchingFiles(dirPath, pattern);
matchedFiles = [...matchedFiles, ...matches];
}
// Calculate score based on number of matches and weight
const weight = signature.weight || 1;
const score = matchedFiles.length * weight;
if (score > 0) {
detections.push({
type: signature.type,
score,
matchedFiles: [...new Set(matchedFiles)] // Deduplicate
});
}
}
// Sort detections by score in descending order
detections.sort((a, b) => b.score - a.score);
// Return the highest scoring detection
if (detections.length > 0) {
const bestDetection = detections[0];
result.type = bestDetection.type;
// Calculate confidence (normalized score between 0 and 1)
const totalScore = detections.reduce((sum, detection) => sum + detection.score, 0);
result.confidence = totalScore > 0 ? bestDetection.score / totalScore : 0;
result.details = {
matchedFiles: bestDetection.matchedFiles,
info: `Detected ${bestDetection.type} project with ${bestDetection.matchedFiles.length} matching files`
};
}
return result;
}
/**
* Find files matching a glob pattern
* @param dirPath - Base directory for search
* @param pattern - Glob pattern to match
* @returns Array of matching file paths
*/
async function findMatchingFiles(dirPath, pattern) {
try {
// Use glob to find files matching the pattern
const options = { cwd: dirPath, absolute: false, nodir: true };
const matches = await glob(pattern, options);
return matches;
}
catch (error) {
console.error(`Error finding files matching pattern "${pattern}":`, error);
return [];
}
}
/**
* Get suggested templates based on project type
* @param projectType - Detected project type
* @returns Suggested template directories
*/
function getTemplatesForProjectType(projectType) {
switch (projectType) {
case ProjectType.NODE:
return ['roles/frontend', 'roles/backend/express', 'roles/backend/nestjs'];
case ProjectType.PYTHON:
return ['roles/backend/django', 'roles/backend/flask', 'roles/backend/fastapi', 'roles/data'];
case ProjectType.JAVA:
return ['roles/backend/spring'];
case ProjectType.GO:
return ['roles/backend'];
case ProjectType.RUST:
return ['roles/backend'];
case ProjectType.RUBY:
return ['roles/backend/rails'];
case ProjectType.PHP:
return ['roles/backend'];
case ProjectType.DOTNET:
return ['roles/backend'];
default:
return ['roles/generic'];
}
}
//# sourceMappingURL=projectDetector.js.map